Image-Text-to-Text
Transformers
Safetensors
English
qwen3_5
gamescaling
game-agent
embodied-agent
keyboard-mouse
continued-pretraining
conversational
Instructions to use THUSI-Lab/GameScaling-0.8B-S3 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use THUSI-Lab/GameScaling-0.8B-S3 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="THUSI-Lab/GameScaling-0.8B-S3") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("THUSI-Lab/GameScaling-0.8B-S3") model = AutoModelForMultimodalLM.from_pretrained("THUSI-Lab/GameScaling-0.8B-S3", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use THUSI-Lab/GameScaling-0.8B-S3 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "THUSI-Lab/GameScaling-0.8B-S3" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "THUSI-Lab/GameScaling-0.8B-S3", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/THUSI-Lab/GameScaling-0.8B-S3
- SGLang
How to use THUSI-Lab/GameScaling-0.8B-S3 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "THUSI-Lab/GameScaling-0.8B-S3" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "THUSI-Lab/GameScaling-0.8B-S3", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "THUSI-Lab/GameScaling-0.8B-S3" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "THUSI-Lab/GameScaling-0.8B-S3", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use THUSI-Lab/GameScaling-0.8B-S3 with Docker Model Runner:
docker model run hf.co/THUSI-Lab/GameScaling-0.8B-S3
Card: aligned with THUSI-Lab/GameScaling
Browse files
LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
Apache License
|
| 3 |
+
Version 2.0, January 2004
|
| 4 |
+
http://www.apache.org/licenses/
|
| 5 |
+
|
| 6 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 7 |
+
|
| 8 |
+
1. Definitions.
|
| 9 |
+
|
| 10 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 11 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 12 |
+
|
| 13 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 14 |
+
the copyright owner that is granting the License.
|
| 15 |
+
|
| 16 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 17 |
+
other entities that control, are controlled by, or are under common
|
| 18 |
+
control with that entity. For the purposes of this definition,
|
| 19 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 20 |
+
direction or management of such entity, whether by contract or
|
| 21 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 22 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 23 |
+
|
| 24 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 25 |
+
exercising permissions granted by this License.
|
| 26 |
+
|
| 27 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 28 |
+
including but not limited to software source code, documentation
|
| 29 |
+
source, and configuration files.
|
| 30 |
+
|
| 31 |
+
"Object" form shall mean any form resulting from mechanical
|
| 32 |
+
transformation or translation of a Source form, including but
|
| 33 |
+
not limited to compiled object code, generated documentation,
|
| 34 |
+
and conversions to other media types.
|
| 35 |
+
|
| 36 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 37 |
+
Object form, made available under the License, as indicated by a
|
| 38 |
+
copyright notice that is included in or attached to the work
|
| 39 |
+
(an example is provided in the Appendix below).
|
| 40 |
+
|
| 41 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 42 |
+
form, that is based on (or derived from) the Work and for which the
|
| 43 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 44 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 45 |
+
of this License, Derivative Works shall not include works that remain
|
| 46 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 47 |
+
the Work and Derivative Works thereof.
|
| 48 |
+
|
| 49 |
+
"Contribution" shall mean any work of authorship, including
|
| 50 |
+
the original version of the Work and any modifications or additions
|
| 51 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 52 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 53 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 54 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 55 |
+
means any form of electronic, verbal, or written communication sent
|
| 56 |
+
to the Licensor or its representatives, including but not limited to
|
| 57 |
+
communication on electronic mailing lists, source code control systems,
|
| 58 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 59 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 60 |
+
excluding communication that is conspicuously marked or otherwise
|
| 61 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 62 |
+
|
| 63 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 64 |
+
on behalf of whom a Contribution has been received by Licensor and
|
| 65 |
+
subsequently incorporated within the Work.
|
| 66 |
+
|
| 67 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 68 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 69 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 70 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 71 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 72 |
+
Work and such Derivative Works in Source or Object form.
|
| 73 |
+
|
| 74 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 75 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 76 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 77 |
+
(except as stated in this section) patent license to make, have made,
|
| 78 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 79 |
+
where such license applies only to those patent claims licensable
|
| 80 |
+
by such Contributor that are necessarily infringed by their
|
| 81 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 82 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 83 |
+
institute patent litigation against any entity (including a
|
| 84 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 85 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 86 |
+
or contributory patent infringement, then any patent licenses
|
| 87 |
+
granted to You under this License for that Work shall terminate
|
| 88 |
+
as of the date such litigation is filed.
|
| 89 |
+
|
| 90 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 91 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 92 |
+
modifications, and in Source or Object form, provided that You
|
| 93 |
+
meet the following conditions:
|
| 94 |
+
|
| 95 |
+
(a) You must give any other recipients of the Work or
|
| 96 |
+
Derivative Works a copy of this License; and
|
| 97 |
+
|
| 98 |
+
(b) You must cause any modified files to carry prominent notices
|
| 99 |
+
stating that You changed the files; and
|
| 100 |
+
|
| 101 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 102 |
+
that You distribute, all copyright, patent, trademark, and
|
| 103 |
+
attribution notices from the Source form of the Work,
|
| 104 |
+
excluding those notices that do not pertain to any part of
|
| 105 |
+
the Derivative Works; and
|
| 106 |
+
|
| 107 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 108 |
+
distribution, then any Derivative Works that You distribute must
|
| 109 |
+
include a readable copy of the attribution notices contained
|
| 110 |
+
within such NOTICE file, excluding those notices that do not
|
| 111 |
+
pertain to any part of the Derivative Works, in at least one
|
| 112 |
+
of the following places: within a NOTICE text file distributed
|
| 113 |
+
as part of the Derivative Works; within the Source form or
|
| 114 |
+
documentation, if provided along with the Derivative Works; or,
|
| 115 |
+
within a display generated by the Derivative Works, if and
|
| 116 |
+
wherever such third-party notices normally appear. The contents
|
| 117 |
+
of the NOTICE file are for informational purposes only and
|
| 118 |
+
do not modify the License. You may add Your own attribution
|
| 119 |
+
notices within Derivative Works that You distribute, alongside
|
| 120 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 121 |
+
that such additional attribution notices cannot be construed
|
| 122 |
+
as modifying the License.
|
| 123 |
+
|
| 124 |
+
You may add Your own copyright statement to Your modifications and
|
| 125 |
+
may provide additional or different license terms and conditions
|
| 126 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 127 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 128 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 129 |
+
the conditions stated in this License.
|
| 130 |
+
|
| 131 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 132 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 133 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 134 |
+
this License, without any additional terms or conditions.
|
| 135 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 136 |
+
the terms of any separate license agreement you may have executed
|
| 137 |
+
with Licensor regarding such Contributions.
|
| 138 |
+
|
| 139 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 140 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 141 |
+
except as required for reasonable and customary use in describing the
|
| 142 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 143 |
+
|
| 144 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 145 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 146 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 147 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 148 |
+
implied, including, without limitation, any warranties or conditions
|
| 149 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 150 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 151 |
+
appropriateness of using or redistributing the Work and assume any
|
| 152 |
+
risks associated with Your exercise of permissions under this License.
|
| 153 |
+
|
| 154 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 155 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 156 |
+
unless required by applicable law (such as deliberate and grossly
|
| 157 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 158 |
+
liable to You for damages, including any direct, indirect, special,
|
| 159 |
+
incidental, or consequential damages of any character arising as a
|
| 160 |
+
result of this License or out of the use or inability to use the
|
| 161 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 162 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 163 |
+
other commercial damages or losses), even if such Contributor
|
| 164 |
+
has been advised of the possibility of such damages.
|
| 165 |
+
|
| 166 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 167 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 168 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 169 |
+
or other liability obligations and/or rights consistent with this
|
| 170 |
+
License. However, in accepting such obligations, You may act only
|
| 171 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 172 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 173 |
+
defend, and hold each Contributor harmless for any liability
|
| 174 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 175 |
+
of your accepting any such warranty or additional liability.
|
| 176 |
+
|
| 177 |
+
END OF TERMS AND CONDITIONS
|
| 178 |
+
|
| 179 |
+
APPENDIX: How to apply the Apache License to your work.
|
| 180 |
+
|
| 181 |
+
To apply the Apache License to your work, attach the following
|
| 182 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 183 |
+
replaced with your own identifying information. (Don't include
|
| 184 |
+
the brackets!) The text should be enclosed in the appropriate
|
| 185 |
+
comment syntax for the file format. We also recommend that a
|
| 186 |
+
file or class name and description of purpose be included on the
|
| 187 |
+
same "printed page" as the copyright notice for easier
|
| 188 |
+
identification within third-party archives.
|
| 189 |
+
|
| 190 |
+
Copyright [yyyy] [name of copyright owner]
|
| 191 |
+
|
| 192 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 193 |
+
you may not use this file except in compliance with the License.
|
| 194 |
+
You may obtain a copy of the License at
|
| 195 |
+
|
| 196 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 197 |
+
|
| 198 |
+
Unless required by applicable law or agreed to in writing, software
|
| 199 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 200 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 201 |
+
See the License for the specific language governing permissions and
|
| 202 |
+
limitations under the License.
|
README.md
CHANGED
|
@@ -15,46 +15,428 @@ tags:
|
|
| 15 |
- qwen3_5
|
| 16 |
---
|
| 17 |
|
|
|
|
|
|
|
| 18 |
<p align="center">
|
| 19 |
<img src="https://huggingface.co/THUSI-Lab/GameScaling/resolve/main/assets/logos/affiliations.png" alt="miHoYo · Tsinghua University · University of Chinese Academy of Sciences · The University of Hong Kong" width="100%" style="width:100%;max-width:100%;">
|
| 20 |
</p>
|
| 21 |
|
| 22 |
-
|
| 23 |
|
| 24 |
-
|
| 25 |
-
Diverse Virtual Worlds**. Qwen3.5-0.8B with continued pre-training on a balanced mixture: 27% Minecraft, the rest from other games, 1,600 h of
|
| 26 |
-
keyboard-and-mouse gameplay, 6,760 training steps. Each call takes the current game frame (plus
|
| 27 |
-
a short history) and returns the next 200 ms of keyboard and mouse actions.
|
| 28 |
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
```bash
|
| 44 |
-
|
|
|
|
| 45 |
cd GameScaling
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
pip install "vllm>=0.17"
|
| 47 |
-
bash scripts/serve_vllm.sh THUSI-Lab/GameScaling-0.8B-
|
|
|
|
| 48 |
```
|
| 49 |
|
| 50 |
-
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
## License
|
| 54 |
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
## Citation
|
| 60 |
|
|
|
|
| 15 |
- qwen3_5
|
| 16 |
---
|
| 17 |
|
| 18 |
+
<div align="center">
|
| 19 |
+
|
| 20 |
<p align="center">
|
| 21 |
<img src="https://huggingface.co/THUSI-Lab/GameScaling/resolve/main/assets/logos/affiliations.png" alt="miHoYo · Tsinghua University · University of Chinese Academy of Sciences · The University of Hong Kong" width="100%" style="width:100%;max-width:100%;">
|
| 22 |
</p>
|
| 23 |
|
| 24 |
+
<h1 align="center" style="font-size:3.2em;line-height:1.1;margin:0.2em 0 0.15em;">Scaling in Games</h1>
|
| 25 |
|
| 26 |
+
<h2 align="center" style="font-size:1.1em;line-height:1.3;font-weight:600;margin:0 0 0.9em;border:none;white-space:nowrap;">Continued Pre-Training for Embodied Agents in Diverse Virtual Worlds</h2>
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
+
<p align="center" style="line-height:1.5;margin:0.4em 0 0.3em;">
|
| 29 |
+
<span style="white-space:nowrap;"><b>Kuan Zhang</b><sup>1,2,*,‡</sup></span>, <span style="white-space:nowrap;"><b>Yukun Chen</b><sup>1,3,*,‡</sup></span>, <span style="white-space:nowrap;"><b>Zhihao Yang</b><sup>1,3,*,‡</sup></span>, <span style="white-space:nowrap;">Yue Su<sup>4</sup></span>, <span style="white-space:nowrap;">Xiangnan Wu<sup>3</sup></span>, <span style="white-space:nowrap;">Zirong Chen<sup>2</sup></span>, <span style="white-space:nowrap;">Run Luo<sup>1,5,‡</sup></span>, <span style="white-space:nowrap;">Jinkun Hou<sup>6</sup></span>, <span style="white-space:nowrap;">Tao Tan<sup>1</sup></span>, <span style="white-space:nowrap;"><b>Yinhe Zheng</b><sup>1,†</sup></span>, <span style="white-space:nowrap;"><b>Yiming Li</b><sup>2,†</sup></span>
|
| 30 |
+
</p>
|
| 31 |
|
| 32 |
+
<p align="center" style="font-size:0.85em;line-height:1.5;margin:0 0 0.6em;">
|
| 33 |
+
<span style="white-space:nowrap;"><sup>1</sup>miHoYo Honkai AI R&D Team</span> <span style="white-space:nowrap;"><sup>2</sup>College AI, Tsinghua University</span> <span style="white-space:nowrap;"><sup>3</sup>University of Chinese Academy of Sciences</span> <span style="white-space:nowrap;"><sup>4</sup>MMLab, The University of Hong Kong</span> <span style="white-space:nowrap;"><sup>5</sup>National University of Singapore</span> <span style="white-space:nowrap;"><sup>6</sup>Peking University</span><br>
|
| 34 |
+
<span style="white-space:nowrap;"><sup>*</sup>Equal contribution</span> <span style="white-space:nowrap;"><sup>†</sup>Corresponding author</span> <span style="white-space:nowrap;"><sup>‡</sup>Work done while interning at miHoYo</span>
|
| 35 |
+
</p>
|
| 36 |
+
|
| 37 |
+
<p align="center">
|
| 38 |
+
<a href="https://gamescaling.github.io" style="display:inline-block;margin:2px;"><img src="https://img.shields.io/badge/Project-Page-1f6feb?style=for-the-badge&logo=googlechrome&logoColor=white" alt="Project Page" style="display:inline-block;vertical-align:middle;margin:0;"></a>
|
| 39 |
+
<a href="https://gamescaling.github.io" style="display:inline-block;margin:2px;"><img src="https://img.shields.io/badge/arXiv-coming%20soon-lightgrey?style=for-the-badge&logo=arxiv&logoColor=white" alt="arXiv (coming soon)" style="display:inline-block;vertical-align:middle;margin:0;"></a>
|
| 40 |
+
<a href="https://github.com/THUSI-Lab/GameScaling" style="display:inline-block;margin:2px;"><img src="https://img.shields.io/badge/Code-GitHub-181717?style=for-the-badge&logo=github&logoColor=white" alt="Code" style="display:inline-block;vertical-align:middle;margin:0;"></a>
|
| 41 |
+
<a href="https://huggingface.co/collections/THUSI-Lab/gamescaling-model-6acf7c0c6500ebee61a7f872" style="display:inline-block;margin:2px;"><img src="https://img.shields.io/badge/%F0%9F%A4%97%20Models-GameScaling%20collection-ffcc4d?style=for-the-badge" alt="Models" style="display:inline-block;vertical-align:middle;margin:0;"></a>
|
| 42 |
+
<a href="https://www.apache.org/licenses/LICENSE-2.0" style="display:inline-block;margin:2px;"><img src="https://img.shields.io/badge/License-Apache%202.0-2ea44f?style=for-the-badge" alt="License: Apache 2.0" style="display:inline-block;vertical-align:middle;margin:0;"></a>
|
| 43 |
+
</p>
|
| 44 |
+
|
| 45 |
+
</div>
|
| 46 |
+
|
| 47 |
+
<p align="center">
|
| 48 |
+
<img src="https://huggingface.co/THUSI-Lab/GameScaling/resolve/main/assets/teaser.jpg" alt="From one physical world to diverse virtual worlds" width="100%">
|
| 49 |
+
</p>
|
| 50 |
+
|
| 51 |
+
> **This repository: GameScaling-0.8B-S3.** Qwen3.5-0.8B continued pre-trained on a balanced mixture of 27% Minecraft and other games
|
| 52 |
+
> (S3), 1,600 h of gameplay, 6,760 training steps; 2.2 GB of bfloat16 weights on
|
| 53 |
+
> 1 GPU. Serve it with
|
| 54 |
+
> `bash scripts/serve_vllm.sh THUSI-Lab/GameScaling-0.8B-S3 8000` (§1). The inference client, prompts and
|
| 55 |
+
> scripts are in [THUSI-Lab/GameScaling](https://huggingface.co/THUSI-Lab/GameScaling); all eight checkpoints are in the
|
| 56 |
+
> [GameScaling collection](https://huggingface.co/collections/THUSI-Lab/gamescaling-model-6acf7c0c6500ebee61a7f872).
|
| 57 |
+
|
| 58 |
+
## Overview
|
| 59 |
+
|
| 60 |
+
GameScaling models are Qwen3.5 vision-language models with continued pre-training on
|
| 61 |
+
keyboard-and-mouse gameplay. Each call takes the current game frame (plus a short history of past
|
| 62 |
+
frames and actions) and returns the next **200 ms of keyboard and mouse actions**: 6 steps of
|
| 63 |
+
33 ms each, plus one mouse movement and scroll for the whole chunk. The model may think before it
|
| 64 |
+
acts.
|
| 65 |
|
| 66 |
+
This repository holds the GameScaling-0.8B-S3 weights. The inference client and the standard system-prompt
|
| 67 |
+
template are in [THUSI-Lab/GameScaling](https://huggingface.co/THUSI-Lab/GameScaling); each of the eight checkpoints is its own repository (below, and in the [GameScaling collection](https://huggingface.co/collections/THUSI-Lab/gamescaling-model-6acf7c0c6500ebee61a7f872)). Together they are everything needed to serve a
|
| 68 |
+
checkpoint and run it in a game; there is no training code. Paper results and analysis are on the [project page](https://gamescaling.github.io).
|
| 69 |
+
|
| 70 |
+
## Checkpoints
|
| 71 |
+
|
| 72 |
+
| Model | Training steps | Weights | GPUs (bf16) |
|
| 73 |
+
|---|---:|---:|:---:|
|
| 74 |
+
| [GameScaling-0.8B-S1](https://huggingface.co/THUSI-Lab/GameScaling-0.8B-S1) | 6,736 | 2.2 GB | 1 |
|
| 75 |
+
| **[GameScaling-0.8B-S3](https://huggingface.co/THUSI-Lab/GameScaling-0.8B-S3)** | **6,760** | **2.2 GB** | **1** |
|
| 76 |
+
| [GameScaling-2B-S1](https://huggingface.co/THUSI-Lab/GameScaling-2B-S1) | 6,736 | 5.4 GB | 1 |
|
| 77 |
+
| [GameScaling-2B-S3](https://huggingface.co/THUSI-Lab/GameScaling-2B-S3) | 6,760 | 5.4 GB | 1 |
|
| 78 |
+
| [GameScaling-9B-S1](https://huggingface.co/THUSI-Lab/GameScaling-9B-S1) | 6,736 | 18.8 GB | 1 |
|
| 79 |
+
| [GameScaling-9B-S3](https://huggingface.co/THUSI-Lab/GameScaling-9B-S3) | 6,760 | 18.8 GB | 1 |
|
| 80 |
+
| [GameScaling-27B-S1](https://huggingface.co/THUSI-Lab/GameScaling-27B-S1) | 6,995 | 54.7 GB | 2 (tensor parallel) |
|
| 81 |
+
| [GameScaling-27B-S3](https://huggingface.co/THUSI-Lab/GameScaling-27B-S3) | 7,020 | 54.7 GB | 2 (tensor parallel) |
|
| 82 |
+
|
| 83 |
+
- **S1** is trained on Minecraft gameplay only. **S3** is a balanced mixture: 27% Minecraft, the
|
| 84 |
+
rest from other games. All checkpoints use 1,600 h of gameplay.
|
| 85 |
+
- Weights are bfloat16, from the Qwen3.5-0.8B / 2B / 9B / 27B backbones.
|
| 86 |
+
|
| 87 |
+
## File tree
|
| 88 |
+
|
| 89 |
+
```text
|
| 90 |
+
THUSI-Lab/GameScaling-<size>-<mixture> one repository per checkpoint
|
| 91 |
+
├── config.json Qwen3.5 architecture, bfloat16
|
| 92 |
+
├── model.safetensors weights (27B: 2 shards + index)
|
| 93 |
+
├── chat_template.jinja required, renders history turns
|
| 94 |
+
├── tokenizer.json
|
| 95 |
+
├── tokenizer_config.json
|
| 96 |
+
├── generation_config.json
|
| 97 |
+
├── preprocessor_config.json
|
| 98 |
+
├── processor_config.json
|
| 99 |
+
└── video_preprocessor_config.json
|
| 100 |
+
|
| 101 |
+
THUSI-Lab/GameScaling
|
| 102 |
+
├── config.json index of the eight checkpoint repositories (no weights)
|
| 103 |
+
├── prompts/
|
| 104 |
+
│ ├── system_prompt_template.txt standard prompt, 3 slots (§2)
|
| 105 |
+
│ └── example_doom_battle1.txt complete Doom prompt (§2)
|
| 106 |
+
├── examples/
|
| 107 |
+
│ ├── doom_battle1.jpg test frame (1280x720)
|
| 108 |
+
│ ├── doom_battle1_action.txt the model's reply on that frame
|
| 109 |
+
│ └── run_example.py frame in, action out (§3)
|
| 110 |
+
├── gamescaling/ inference client
|
| 111 |
+
│ ├── prompt.py system prompt builders
|
| 112 |
+
│ ├── policy.py client and request body
|
| 113 |
+
│ ├── action.py action format and parser
|
| 114 |
+
│ └── keymaps.py key names <-> browser keys
|
| 115 |
+
├── scripts/serve_vllm.sh start a vLLM server
|
| 116 |
+
├── tests/test_core.py offline tests (no GPU)
|
| 117 |
+
├── assets/ images for this card
|
| 118 |
+
├── requirements.txt client deps: requests, Pillow
|
| 119 |
+
└── LICENSE Apache 2.0
|
| 120 |
+
```
|
| 121 |
+
|
| 122 |
+
## 1. Download and serve
|
| 123 |
+
|
| 124 |
+
Download the client and scripts from [THUSI-Lab/GameScaling](https://huggingface.co/THUSI-Lab/GameScaling):
|
| 125 |
|
| 126 |
```bash
|
| 127 |
+
pip install -U huggingface_hub
|
| 128 |
+
huggingface-cli download THUSI-Lab/GameScaling --exclude "assets/*" --local-dir ./GameScaling
|
| 129 |
cd GameScaling
|
| 130 |
+
```
|
| 131 |
+
|
| 132 |
+
Serve a checkpoint with vLLM (tested with 0.17.0); vLLM fetches the weights from its repository:
|
| 133 |
+
|
| 134 |
+
```bash
|
| 135 |
pip install "vllm>=0.17"
|
| 136 |
+
bash scripts/serve_vllm.sh THUSI-Lab/GameScaling-9B-S1 8000 # 0.8B-9B fit on one GPU
|
| 137 |
+
bash scripts/serve_vllm.sh THUSI-Lab/GameScaling-27B-S1 8000 2 # 27B: tensor parallel 2
|
| 138 |
```
|
| 139 |
|
| 140 |
+
To keep the weights in a local folder instead, download the checkpoint repository and pass its path:
|
| 141 |
+
|
| 142 |
+
```bash
|
| 143 |
+
huggingface-cli download THUSI-Lab/GameScaling-9B-S1 --local-dir ./GameScaling-9B-S1
|
| 144 |
+
bash scripts/serve_vllm.sh ./GameScaling-9B-S1 8000
|
| 145 |
+
```
|
| 146 |
+
|
| 147 |
+
`serve_vllm.sh CKPT [PORT] [TP]` starts vLLM with `--served-model-name gamescaling`, bfloat16,
|
| 148 |
+
`--max-model-len 32768` (system prompt + 5 history frames + reasoning budget) and
|
| 149 |
+
`--limit-mm-per-prompt '{"image": 8}'` (5 history frames + the current one, with headroom). Set
|
| 150 |
+
`GPU_MEM_UTIL` to change the memory fraction (default 0.85).
|
| 151 |
+
|
| 152 |
+
Check that the server is up and the client can reach it:
|
| 153 |
+
|
| 154 |
+
```bash
|
| 155 |
+
curl -s http://127.0.0.1:8000/v1/models # should list "gamescaling"
|
| 156 |
+
pip install -r requirements.txt
|
| 157 |
+
python tests/test_core.py # offline checks, no server needed
|
| 158 |
+
```
|
| 159 |
+
|
| 160 |
+
Things to keep as shipped:
|
| 161 |
+
|
| 162 |
+
- **Chat template.** Use the `chat_template.jinja` in the checkpoint repository (vLLM loads it by
|
| 163 |
+
default). Do not replace it with the stock Qwen template: this one renders past turns without
|
| 164 |
+
reasoning as `<think>\n\n</think>\n\n<|action_start|>...`, token-for-token as in training.
|
| 165 |
+
- **Special tokens.** Requests must set `skip_special_tokens: false`, or the server strips the
|
| 166 |
+
`<|action_start|>` / `<|action_end|>` tags. `build_request` already does this.
|
| 167 |
+
- **One server per GPU group.** One vLLM replica can serve several games at once, but long
|
| 168 |
+
prefills (one image per history turn) make each step slower when many games share it.
|
| 169 |
+
|
| 170 |
+
## 2. System prompt
|
| 171 |
+
|
| 172 |
+
`prompts/system_prompt_template.txt` is the standard system prompt. Fill in three placeholders
|
| 173 |
+
and keep everything else exactly as written: the model decides its output tags from the exact
|
| 174 |
+
text of the Output Format section.
|
| 175 |
+
|
| 176 |
+
| Placeholder | What to write |
|
| 177 |
+
|---|---|
|
| 178 |
+
| `{GAME_NAME}` | The game's name. It appears twice: in the opening and in the key-list heading. |
|
| 179 |
+
| `{GAME_RULES}` | What the game is, what is on screen, the goal and how it is scored. Plain text; several lines are fine. |
|
| 180 |
+
| `{KEY_BINDINGS}` | One `- <key> -> <effect>` line per key, in training key names (§5). End with the mouse line below if the mouse turns the camera. |
|
| 181 |
+
|
| 182 |
+
The mouse line, copied verbatim:
|
| 183 |
+
|
| 184 |
+
```text
|
| 185 |
+
- Mouse X Y -> aim / rotate the camera (X>0 right, Y>0 down)
|
| 186 |
+
```
|
| 187 |
+
|
| 188 |
+
**Note.** Lines such as `**Game Rules**`, `**Output Format**` and
|
| 189 |
+
`**Explanation**` are plain-text section headers that the model saw in training. They are part
|
| 190 |
+
of the prompt, not Markdown formatting: send them to the model unchanged, including the
|
| 191 |
+
asterisks.
|
| 192 |
+
|
| 193 |
+
### Complete example: Doom Battle-1
|
| 194 |
+
|
| 195 |
+
This is the full system prompt for the ViZDoom Battle-1 map, as in
|
| 196 |
+
`prompts/example_doom_battle1.txt`. It is the same text in both reasoning modes (§4). Long
|
| 197 |
+
lines scroll horizontally; each line break below is a real `\n` in the prompt.
|
| 198 |
+
|
| 199 |
+
```text
|
| 200 |
+
You are a gaming expert, and you are currently playing Doom Battle-1. You are proficient in keyboard and mouse operations. You understand game mechanics and combat pacing, can quickly extract key information from the current screen, and can think and make precise decisions at critical moments. Based on the current screen, plan the next 200ms of actions, consisting of 6 steps spaced 33ms apart. Each step lasts 33ms, until the next step begins. If the current situation continues the previous strategy, output the action directly. Think only when the situation changes significantly, the previous analysis is no longer valid, or a new objective appears.
|
| 201 |
+
**Game Rules**
|
| 202 |
+
You are playing Doom, a first-person shooter, in an arena full of monsters. Survive and kill as many monsters as you can.
|
| 203 |
+
|
| 204 |
+
## What you see on screen
|
| 205 |
+
- First-person view.
|
| 206 |
+
- The crosshair at screen centre marks where shots land.
|
| 207 |
+
- The status bar along the bottom shows HEALTH on the left and AMMO on the right.
|
| 208 |
+
- Monsters keep arriving for the whole episode; some throw fireballs from range.
|
| 209 |
+
|
| 210 |
+
## Rules
|
| 211 |
+
- Score is the number of monsters you kill in the episode.
|
| 212 |
+
- Firing costs ammo, and the episode ends as soon as your health reaches 0, so dodging matters as much as shooting: standing still in the open is how most episodes end early.
|
| 213 |
+
- Health packs and ammo boxes lie around the map; walk over one to pick it up. Running out of either is fatal, so collect them while fighting.
|
| 214 |
+
- A target is hit when it is under the crosshair, so turn with the mouse until the monster is centred before firing.
|
| 215 |
+
- The map is one large open arena, so monsters can close in from any direction.
|
| 216 |
+
**Common Keys in Doom Battle-1**
|
| 217 |
+
- W -> Move forward
|
| 218 |
+
- A -> Strafe left
|
| 219 |
+
- S -> Move backward
|
| 220 |
+
- D -> Strafe right
|
| 221 |
+
- LB -> Fire weapon
|
| 222 |
+
- Ctrl -> Fire weapon (keyboard alternative)
|
| 223 |
+
- Shift -> Run
|
| 224 |
+
- Space -> Open doors / use switches
|
| 225 |
+
- one -> Select weapon slot 1
|
| 226 |
+
- two -> Select weapon slot 2
|
| 227 |
+
- three -> Select weapon slot 3
|
| 228 |
+
- Mouse X Y -> aim / rotate the camera (X>0 right, Y>0 down)
|
| 229 |
+
**Output Format**
|
| 230 |
+
**Action only (usual)**
|
| 231 |
+
<think></think><|action_start|>X Y Z ; k1 k2 k3 ; k4 k5 ; k6 ; k7 ; k8 ; k9 k10<|action_end|>
|
| 232 |
+
**Thinking + action (when necessary)**
|
| 233 |
+
<think>reasoning</think><|action_start|>X Y Z ; k1 k2 k3 ; k4 k5 ; k6 ; k7 ; k8 ; k9 k10<|action_end|>
|
| 234 |
+
**Explanation**
|
| 235 |
+
1. **Mouse Movement**: First, specify the relative displacement X, Y (X>0 means move right, Y>0 means move down) and scroll amount Z (Z>0 means scroll up).
|
| 236 |
+
2. **Key Sequence**: Then list 6 groups of keys; within each group, keys are separated by spaces, and groups are separated by semicolons.
|
| 237 |
+
- Each group can contain up to 4 keys.
|
| 238 |
+
- If a group has no keys, leave it empty but keep the `;`.
|
| 239 |
+
3. Only output a plain string that conforms to the above format — no line breaks and no quotation marks.
|
| 240 |
+
**Key Naming Rules**
|
| 241 |
+
- Number keys `0-9`: use lowercase English words, e.g., `zero` for `0`, `one` for `1`, ... `nine` for `9`.
|
| 242 |
+
- Function keys `F1-F12`: use capitalized English words, e.g., `One` represents `F1`, `Two` represents `F2`, and so on.
|
| 243 |
+
- Mouse buttons: use `LB`, `RB`, `MB` for the left, right, and middle mouse button.
|
| 244 |
+
- Letters: use the uppercase letter, e.g., `A`, `D`, `W`, `S`.
|
| 245 |
+
- Arrow keys: use `Up`, `Down`, `Left`, `Right`.
|
| 246 |
+
- Modifier/special keys: `Shift`, `Ctrl`, `Alt`, `Tab`, `Caps`, `Esc`, `Space`, `Enter`, `Back` (backspace), `Delete`, `Insert`, `Home`, `End`, `Pause`.
|
| 247 |
+
```
|
| 248 |
+
|
| 249 |
+
The same prompt from code (`tests/test_core.py` checks that it matches the file byte for byte):
|
| 250 |
+
|
| 251 |
+
```python
|
| 252 |
+
from gamescaling import build_system_prompt
|
| 253 |
+
|
| 254 |
+
DOOM_RULES = open("prompts/example_doom_battle1.txt").read() \
|
| 255 |
+
.split("**Game Rules**\n", 1)[1].split("\n**Common Keys in", 1)[0]
|
| 256 |
+
|
| 257 |
+
system = build_system_prompt(
|
| 258 |
+
"Doom Battle-1",
|
| 259 |
+
rules=DOOM_RULES,
|
| 260 |
+
key_bindings=[
|
| 261 |
+
("W", "Move forward"), ("A", "Strafe left"), ("S", "Move backward"), ("D", "Strafe right"),
|
| 262 |
+
("LB", "Fire weapon"), ("Ctrl", "Fire weapon (keyboard alternative)"), ("Shift", "Run"),
|
| 263 |
+
("Space", "Open doors / use switches"), ("one", "Select weapon slot 1"),
|
| 264 |
+
("two", "Select weapon slot 2"), ("three", "Select weapon slot 3"),
|
| 265 |
+
],
|
| 266 |
+
mouse_aim=True, # appends the "Mouse X Y -> ..." line
|
| 267 |
+
)
|
| 268 |
+
```
|
| 269 |
+
|
| 270 |
+
Filling the text file directly gives the same result:
|
| 271 |
+
|
| 272 |
+
```python
|
| 273 |
+
tpl = open("prompts/system_prompt_template.txt").read().rstrip("\n")
|
| 274 |
+
system = (tpl.replace("{GAME_NAME}", "Doom Battle-1")
|
| 275 |
+
.replace("{GAME_RULES}", DOOM_RULES)
|
| 276 |
+
.replace("{KEY_BINDINGS}", "- W -> Move forward\n- A -> Strafe left\n..."
|
| 277 |
+
"\n- Mouse X Y -> aim / rotate the camera (X>0 right, Y>0 down)"))
|
| 278 |
+
```
|
| 279 |
+
|
| 280 |
+
## 3. Minimal usage
|
| 281 |
+
|
| 282 |
+
```python
|
| 283 |
+
from PIL import Image
|
| 284 |
+
from gamescaling import GameScalingPolicy, PolicyConfig
|
| 285 |
+
|
| 286 |
+
policy = GameScalingPolicy(system, PolicyConfig()) # system prompt from §2; prefills <think>
|
| 287 |
+
policy.reset() # call at the start of every episode
|
| 288 |
+
decision = policy.act(Image.open("frame.png")) # one call = one 200 ms decision
|
| 289 |
+
a = decision.action
|
| 290 |
+
a.mouse # (X, Y, Z): mouse movement for this chunk (per-mille of the screen) + scroll
|
| 291 |
+
a.steps # 6 groups: the keys held during each 33 ms step
|
| 292 |
+
a.parsed # False = could not be parsed; execute as a no-op
|
| 293 |
+
decision.reasoning # the model's thinking for this step ("" if it acted directly)
|
| 294 |
+
```
|
| 295 |
+
|
| 296 |
+
Pass `a` to your executor. Run 6 steps of 33 ms, holding that step's keys during each one. Keys
|
| 297 |
+
that appear in two consecutive groups stay held rather than being pressed again. Mouse movement
|
| 298 |
+
is `X/1000 * screen width` and `Y/1000 * screen height`. You can spread it over the 200 ms or
|
| 299 |
+
send it at once. The frame is sent at its native size; set `PolicyConfig(image_size=(w, h))` to
|
| 300 |
+
resize it first.
|
| 301 |
+
|
| 302 |
+
### Test frame
|
| 303 |
+
|
| 304 |
+
`examples/doom_battle1.jpg` is a frame from a Doom Battle-1 episode played by GameScaling-9B-S3.
|
| 305 |
+
A monster stands just left of the crosshair.
|
| 306 |
+
|
| 307 |
+
<p align="center">
|
| 308 |
+
<img src="https://huggingface.co/THUSI-Lab/GameScaling/resolve/main/examples/doom_battle1.jpg" alt="Doom Battle-1 test frame" width="100%">
|
| 309 |
+
</p>
|
| 310 |
+
|
| 311 |
+
The model's reply on this frame (`examples/doom_battle1_action.txt`), with the system prompt from
|
| 312 |
+
§2:
|
| 313 |
+
|
| 314 |
+
```text
|
| 315 |
+
<think>
|
| 316 |
+
|
| 317 |
+
</think>
|
| 318 |
+
|
| 319 |
+
<|action_start|>-37 -3 0 ; LB S ; LB ; LB ; LB ; LB ; LB<|action_end|>
|
| 320 |
+
```
|
| 321 |
+
|
| 322 |
+
It acts without thinking, turns left by 37/1000 of the screen width, and holds fire for the
|
| 323 |
+
whole 200 ms (with a short step back in the first 33 ms). The shot killed the monster.
|
| 324 |
+
|
| 325 |
+
Run the same frame against your server:
|
| 326 |
+
|
| 327 |
+
```bash
|
| 328 |
+
python examples/run_example.py --offline # no server
|
| 329 |
+
python examples/run_example.py # prefill <think>
|
| 330 |
+
python examples/run_example.py --no-reasoning # no thinking
|
| 331 |
+
```
|
| 332 |
+
|
| 333 |
+
Each reply should parse into a valid action chunk (`parsed=True`); the script exits non-zero
|
| 334 |
+
otherwise. Sampling is at temperature 1.0 and the reference reply had five earlier frames in
|
| 335 |
+
context, so live replies differ in detail.
|
| 336 |
+
|
| 337 |
+
## 4. Reasoning modes and message structure
|
| 338 |
+
|
| 339 |
+
The assistant turn is always prefilled, and the request continues it
|
| 340 |
+
(`continue_final_message=True`). The system prompt is the same in both modes.
|
| 341 |
+
|
| 342 |
+
| Mode | Prefill | What the model does |
|
| 343 |
+
|---|---|---|
|
| 344 |
+
| `PolicyConfig()` (default, `reasoning=True`) | `<think>` | Decides whether and how long to think, closes `</think>`, then outputs the action |
|
| 345 |
+
| `PolicyConfig(reasoning=False)` | `<think>\n\n</think>` | Thinking is closed and empty; the model outputs the action chunk directly |
|
| 346 |
+
|
| 347 |
+
`<think>\n\n</think>` is exactly how the chat template renders a turn without reasoning, so the
|
| 348 |
+
no-reasoning mode stays in the training format. Do not send the request without a prefill.
|
| 349 |
+
|
| 350 |
+
Each user turn is the text `current game screen` followed by the frame. Multi-turn messages
|
| 351 |
+
(`policy.py`):
|
| 352 |
+
|
| 353 |
+
```text
|
| 354 |
+
system system prompt (§2)
|
| 355 |
+
user "current game screen" + frame t-k
|
| 356 |
+
assistant action taken at t-k (no reasoning)
|
| 357 |
+
... (last history_len turns, default 5)
|
| 358 |
+
user "current game screen" + current frame
|
| 359 |
+
assistant "<think>" or "<think>\n\n</think>"
|
| 360 |
+
```
|
| 361 |
+
|
| 362 |
+
Past turns keep only the action (`history_think=0`). A turn that failed to parse is stored as an
|
| 363 |
+
explicit no-op, `<|action_start|>0 0 0 ; ; ; ; ; ; <|action_end|>`, not as the raw bad output.
|
| 364 |
+
|
| 365 |
+
Client defaults: `temperature=1.0`, `max_tokens=2048`, `stop=["<|action_end|>"]`,
|
| 366 |
+
`skip_special_tokens=false`, JPEG frames (quality 90) at native resolution.
|
| 367 |
+
|
| 368 |
+
## 5. Action format
|
| 369 |
+
|
| 370 |
+
```text
|
| 371 |
+
<|action_start|>X Y Z ; g1 ; g2 ; g3 ; g4 ; g5 ; g6<|action_end|>
|
| 372 |
+
```
|
| 373 |
+
|
| 374 |
+
- `X Y`: mouse movement over the whole 200 ms, in per-mille of the screen
|
| 375 |
+
(`X = Σdx / screen width × 1000`), clipped to ±1000. X>0 is right, Y>0 is down.
|
| 376 |
+
- `Z`: scroll notches, clipped to ±5. Z>0 is up.
|
| 377 |
+
- `g1..g6`: six 33 ms steps. Each group lists the keys held during that step, at most 4. An
|
| 378 |
+
empty group releases all keys, but the `;` must stay.
|
| 379 |
+
- `<|action_start|>` / `<|action_end|>` are special tokens. Requests must set
|
| 380 |
+
`skip_special_tokens: false` (`build_request` does), or the server strips the tags.
|
| 381 |
+
`parse_action` also accepts a bare `X Y Z ; ...` as a fallback.
|
| 382 |
+
- The action is read only after the last `</think>`: a model that thinks often quotes the format
|
| 383 |
+
inside its reasoning. An unclosed `<think>` means the generation was cut off; it is executed as
|
| 384 |
+
a no-op (`Action.truncated=True`).
|
| 385 |
+
|
| 386 |
+
Training key vocabulary (74 tokens, case-sensitive, `gamescaling.action.KEY_VOCAB`):
|
| 387 |
+
|
| 388 |
+
| Group | Tokens |
|
| 389 |
+
|---|---|
|
| 390 |
+
| Letters | `A`..`Z` |
|
| 391 |
+
| Number row | `zero` `one` .. `nine` |
|
| 392 |
+
| F1-F12 | `One` `Two` .. `Twelve` (capitalized = function key) |
|
| 393 |
+
| Mouse buttons | `LB` `RB` `MB` |
|
| 394 |
+
| Arrows | `Up` `Down` `Left` `Right` |
|
| 395 |
+
| Other | `Shift` `Ctrl` `Alt` `Tab` `Caps` `Esc` `Space` `Enter` `Back` `Delete` `Insert` `Home` `End` `Pause` `Equal` `Minus` `Period` `Slash` `Quote` |
|
| 396 |
+
|
| 397 |
+
Tokens outside the vocabulary are dropped and recorded in `Action.dropped`.
|
| 398 |
+
`keymaps.TO_PLAYWRIGHT` and `keymaps.TO_UE5` map them to browser and Unreal Engine key names;
|
| 399 |
+
`translate_controls` rewrites browser key names in a text into training tokens.
|
| 400 |
+
|
| 401 |
+
## 6. Running it in a game
|
| 402 |
+
|
| 403 |
+
1. Write the system prompt for your game (§2).
|
| 404 |
+
2. Capture the current frame and call `policy.act(frame)` once per decision.
|
| 405 |
+
3. Execute the returned `Action` as in §5: held keys for 6 steps of 33 ms, plus mouse movement
|
| 406 |
+
and scroll.
|
| 407 |
+
4. Call `policy.reset()` when an episode ends.
|
| 408 |
+
|
| 409 |
+
Before trusting the results, check:
|
| 410 |
+
|
| 411 |
+
- **Parse rate.** `Decision.action.parsed` should almost always be `True`. Many failures, or many
|
| 412 |
+
`Action.truncated`, usually mean a replaced chat template, stripped special tokens, a missing
|
| 413 |
+
prefill, or a too-small `max_tokens`.
|
| 414 |
+
- **Actions take effect.** Each chunk runs in wall-clock time (6 × 33 ms). If the game renders
|
| 415 |
+
slowly, for example several game instances sharing one GPU, held keys barely move the
|
| 416 |
+
character and nothing reports an error. Watch a recording before reading any numbers.
|
| 417 |
+
- **Several episodes.** Single episodes vary a lot at `temperature=1.0`.
|
| 418 |
+
|
| 419 |
+
## 7. Tests
|
| 420 |
+
|
| 421 |
+
```bash
|
| 422 |
+
python tests/test_core.py # or: python -m pytest tests/
|
| 423 |
+
```
|
| 424 |
+
|
| 425 |
+
Offline checks of prompts, request bodies and action parsing; no GPU or server needed.
|
| 426 |
|
| 427 |
## License
|
| 428 |
|
| 429 |
+
GameScaling is a **purely scientific research** project. We carry out **no commercial activity** of
|
| 430 |
+
any kind with it: nothing here is sold, licensed for a fee, or used in any product or service.
|
| 431 |
+
|
| 432 |
+
- **Models and code: Apache-2.0.** The weights and the inference code are released under the
|
| 433 |
+
[Apache License 2.0](LICENSE). The models are continued pre-trained from
|
| 434 |
+
[Qwen3.5](https://huggingface.co/Qwen/Qwen3.5-9B), which is also Apache 2.0.
|
| 435 |
+
- **Gameplay data is not released.** The training corpus stays private; game frames in
|
| 436 |
+
[THUSI-Lab/GameScaling](https://huggingface.co/THUSI-Lab/GameScaling) (e.g. `examples/doom_battle1.jpg`) only illustrate how to use the model.
|
| 437 |
+
- **Game copyright belongs to the publishers.** All game titles, footage, copyrights, trademarks and
|
| 438 |
+
other game assets referenced here belong to their respective publishers and owners. The Apache
|
| 439 |
+
2.0 licence covers our weights and code only and grants no right to any game content.
|
| 440 |
|
| 441 |
## Citation
|
| 442 |
|