kissin42 commited on
Commit
75304e5
·
verified ·
1 Parent(s): 3649fca

Publish Pyramids-only Unity policy

Browse files
README.md CHANGED
@@ -7,266 +7,91 @@ tags:
7
  - unity-ml-agents
8
  - onnx
9
  - causal-gpt-rl
 
10
  ---
11
 
12
- # Causal GPT-RL — Unity ML-Agents (ONNX)
13
 
14
- GPT-style transformers (GPT-2, Llama) running as RL policies inside Unity
15
- ML-Agents scenes.
16
 
17
- Both LLM generation and RL interaction are autoregressive:
18
 
19
  ```text
20
- token → next token (LLM generation)
21
- (state, action) → (next state from env, next action) (RL rollout)
22
  ```
23
 
24
- Causal GPT-RL policies act stably under their own rollouts long-horizon control
25
- without the drift that has historically kept transformers from being usable as RL
26
- agents. A single autoregressive model drives full-episode rollouts — no critic, no
27
- auxiliary networks at inference.
28
 
29
- This repo holds ready-to-run Unity policies as single self-contained ONNX graphs.
30
- They run with any ONNX runtime — `onnxruntime` (Python) or Unity
31
- Sentis (C# / native) — with **no Python runtime, no PyTorch, and no ML-Agents
32
- Python stack required**. Observations go in raw; state normalization is baked into
33
- the graph. It is the Unity companion to the Gymnasium / MuJoCo policies at
34
- [ccnets/causal-gpt-rl](https://huggingface.co/ccnets/causal-gpt-rl).
35
 
36
- **Companion repos**
37
- - Unity build to run it against:
38
- [ccnets/causal-gpt-rl-unity-envs](https://huggingface.co/datasets/ccnets/causal-gpt-rl-unity-envs)
39
- - Recorded trajectories + reproduction recipe:
40
- [ccnets/causal-gpt-rl-unity-datasets](https://huggingface.co/datasets/ccnets/causal-gpt-rl-unity-datasets)
41
 
42
- **Links**
43
- - **Code (GitHub):** [ccnets-team/causal-gpt-rl](https://github.com/ccnets-team/causal-gpt-rl)
44
- - **Run logs (W&B, public):** [wandb.ai/junhopark/Causal GPT-RL](https://wandb.ai/junhopark/Causal%20GPT-RL)
45
- - **Hugging Face org:** https://huggingface.co/ccnets
46
- - Website: https://ccnets.org
47
- - LinkedIn: https://www.linkedin.com/company/ccnets
48
 
49
- ## What's in this repo
 
50
 
51
- ```text
52
- ccnets/causal-gpt-rl-unity/
53
- pushblock.onnx
54
- dungeon-escape/
55
- dungeonescape-b36.onnx
56
- pyramids/
57
- pyramids-b16.onnx
58
- soccer-twos/
59
- soccertwos-b16.onnx
60
- README.md
61
- ```
62
-
63
- ## ONNX I/O contract
64
-
65
- Every graph uses the same named windowed-policy interface; dimensions are
66
- model-specific:
67
-
68
- | Input | Shape | Meaning |
69
- |---|---|---|
70
- | `states` | `[B, T, state_size]` | last `T` **raw** observations |
71
- | `actions` | `[B, T, action_size]` | previous actions in model representation |
72
- | `is_bos` | `[B, T, 1]` | begin-of-sequence flag per window step |
73
- | `mask` | `[B, T]` | valid-step mask for the window |
74
-
75
- Output: `action` → `[B, action_size]`.
76
-
77
- - **Raw observations in.** State normalization is inside the graph — feed the
78
- build's observations unchanged.
79
- - **Maintain a 32-step rolling window.** On reset, push `(s0, zero-action,
80
- is_bos=1, mask=1)`; each step push `(s_next, previous raw action, is_bos=0,
81
- mask=1)`; the window rolls.
82
- - **Decode.** The environment action is `clip(raw, -1, 1)`. Feed the **raw**
83
- action back into the window (autoregressive feedback), not the clipped one.
84
- - **One context per agent.** A batch-1 graph is called once per agent; a fixed
85
- full-scene batch evaluates all agents in one call.
86
-
87
- ## Quick Start (onnxruntime)
88
-
89
- A single forward call:
90
-
91
- ```python
92
- import numpy as np
93
- import onnxruntime as ort
94
-
95
- sess = ort.InferenceSession("pyramids/pyramids-b16.onnx", providers=["CPUExecutionProvider"])
96
- action = sess.run(
97
- ["action"],
98
- {
99
- "states": states, # [16, 32, 172] float32, raw observations
100
- "actions": actions, # [16, 32, 5] float32, one-hot feedback
101
- "is_bos": is_bos, # [16, 32, 1] float32
102
- "mask": mask, # [16, 32] float32
103
- },
104
- )[0] # -> [16, 5] logits
105
- env_action = np.argmax(action, axis=-1)
106
- ```
107
-
108
- A ready-made closed-loop evaluator downloads no training/runtime code, manages
109
- one rolling window per agent, supports continuous/discrete/hybrid actions, and
110
- reports agent and cooperative-group returns:
111
- [`examples/unity/evaluate_onnx.py`](https://github.com/ccnets-team/causal-gpt-rl/blob/main/examples/unity/evaluate_onnx.py).
112
-
113
- The accompanying
114
- [`DungeonEscape notebook`](https://github.com/ccnets-team/causal-gpt-rl/blob/main/examples/unity/dungeon_escape_hf.ipynb)
115
- shows the Hugging Face download and evaluation workflow.
116
-
117
- ## SoccerTwos
118
-
119
- | Policy | Ctx | Batch | Obs | Action | Side-swapped W/D/L | Win rate |
120
- |---|---:|---:|---:|---|---:|---:|
121
- | `soccer-twos/soccertwos-b16.onnx` | 32 | 16 | 336 | `MultiDiscrete([3,3,3])` logits | 4/0/12 | 25.00% |
122
-
123
- This is the **completed training-run checkpoint**. The corrected smoke result
124
- uses the bundle's `bos_cache_mode=discard` serving convention and one
125
- side-swapped run against the release-23 stock policy: 4 wins, 0 draws, and 12
126
- losses (**25.00% win rate**). `--seed 0` seeded stock-policy action sampling;
127
- the current Unity wrapper used its deterministic launch seeds 100 and 101, so
128
- this is not a multi-environment-seed benchmark.
129
-
130
- The original `config.json` + `model.safetensors` bundle, evaluated through the
131
- cached `PolicyRunner` with BOS discard, produced the same 4/0/12 result. This
132
- validates the published ONNX at the closed-loop W/D/L level. Small numeric
133
- differences changed episode tick counts, so this is not a claim of bit-identical
134
- trajectories.
135
-
136
- One release-23 scene contains eight independent 2-vs-2 fields. The Causal graph
137
- controls both players on one team (`8 fields x 2 agents = 16` independent context
138
- rows) while the stock ML-Agents ONNX controls the opponent team. Side swapping
139
- reduces team-0/team-1 placement bias. The sample is still a smoke comparison,
140
- not a statistically complete benchmark; comparisons should report the exact
141
- environment build, opponent policy, action sampling, and number of seeds.
142
 
143
- Public offline datasets were collected from release-23 self-play:
144
-
145
- | Dataset | Policy generation | Matches | Ego episodes | Transitions |
146
- |---|---|---:|---:|---:|
147
- | `unity/soccer-twos/expert-v0` | stock ONNX self-play | 3,647 | 14,588 | 1,000,816 |
148
- | `unity/soccer-twos/medium-v0` | team epsilon in `{0.08, 0.09, 0.10}` | 3,260 | 13,040 | 1,001,776 |
149
- | `unity/soccer-twos/simple-v0` | team epsilon in `{0.08, 0.10, 0.15}` | 3,215 | 12,860 | 1,003,048 |
150
-
151
- For each noisy-policy match, each team independently samples one epsilon value.
152
- Both teammates share that noise level, while random action replacement is
153
- sampled independently for each agent. Unity's individual and group rewards are
154
- stored without reshaping or reward engineering. Each 2-vs-2 match becomes four
155
- ego-agent trajectories linked by `match_id`.
156
-
157
- The tiers were selected by side-swapped calibration against the fixed stock
158
- policy, not by mean dataset return: adversarial self-play naturally contains
159
- both winning and losing trajectories, so its mean agent return remains near
160
- zero. As a direct separation check, the medium policy pool scored `0.795`
161
- against the simple pool over 200 side-swapped matches.
162
-
163
- SoccerTwos ONNX contract:
164
-
165
- | Input/output | Shape |
166
- |---|---|
167
- | `states` | `[16, 32, 336]` |
168
- | `actions` | `[16, 32, 9]` (three one-hot branches) |
169
- | `is_bos` | `[16, 32, 1]` |
170
- | `mask` | `[16, 32]` |
171
- | `action` | `[16, 9]` (three groups of three logits; `argmax` per branch) |
172
-
173
- The public side-swapped evaluator and notebook are in
174
- [`examples/unity`](https://github.com/ccnets-team/causal-gpt-rl/tree/main/examples/unity).
175
- Batching is computational only; teammates do not cross-attend or share hidden
176
- state.
177
-
178
- ## Pyramids
179
-
180
- | Policy | Ctx | Batch | Obs | Action | Return | Completion |
181
  |---|---:|---:|---:|---|---:|---:|
182
- | `pyramids/pyramids-b16.onnx` | 32 | 16 | 172 | `Discrete(5)` logits | **1.7738 ± 0.1278** | **128/128** |
183
 
184
- The return is mean ± population standard deviation over 128 first-agent
185
- episodes: 16 independent agents in each of eight fresh Unity launches, using
186
- environment seeds `100..107`. The matching model-removed release-23 build was
187
- run headless with `time_scale=40`; each launch used a separate worker ID.
188
- Every measured ONNX episode completed successfully.
189
 
190
- The four observation sensors are preserved by the dataset as
191
- `Tuple(Box(56), Box(56), Box(56), Box(4))` and concatenated in that order for
192
- the graph. The discrete output contains five logits; use `argmax` and feed its
193
- five-way one-hot representation back into the next action window. The graph
194
- uses the bundle's `bos_cache_mode=discard` convention.
195
 
196
- Public one-million-transition dataset references:
197
 
198
- | Dataset | Episodes | Return |
199
- |---|---:|---:|
200
- | `unity/pyramids/simple-v0` | 3,040 | 1.6339 ± 0.3822 |
201
- | `unity/pyramids/medium-v0` | 4,267 | 1.7498 ± 0.2528 |
202
- | `unity/pyramids/expert-v0` | 5,348 | 1.7953 ± 0.2661 |
203
 
204
- The published ONNX is above the simple and medium dataset means and 1.2% below
205
- the expert mean on this protocol. Dataset returns are sums of the recorded
206
- per-step rewards for each Minari episode.
207
 
208
- The original `config.json` + `model.safetensors` checkpoint was also measured
209
- with the cached `PolicyRunner`, BOS discard, cache length 32, and the same eight
210
- Unity seeds. It scored approximately `1.6425 ± 0.5076`, with 124/128 successful
211
- episodes. This is a real closed-loop runtime difference despite the exporter's
212
- single-window numerical check (`max_abs_error=9.537e-07`); the published metric
213
- therefore describes the stateless rolling-window ONNX artifact in this repo,
214
- not the cached PyTorch serving path.
215
 
216
- Pyramids ONNX contract:
217
 
218
  | Input/output | Shape |
219
  |---|---|
220
  | `states` | `[16, 32, 172]` |
221
- | `actions` | `[16, 32, 5]` (one-hot feedback) |
222
  | `is_bos` | `[16, 32, 1]` |
223
  | `mask` | `[16, 32]` |
224
- | `action` | `[16, 5]` (logits; `argmax` per row) |
225
-
226
- ## DungeonEscape
227
-
228
- | Policy | Ctx | Batch | Obs | Action | Agent return | Group success |
229
- |---|---:|---:|---:|---|---:|---:|
230
- | `dungeon-escape/dungeonescape-b36.onnx` | 32 | 36 | 371 | `Discrete(7)` logits | 0.2222 | 41.67% |
231
 
232
- This is an **intermediate training checkpoint** published to validate the
233
- end-to-end download and evaluation workflow. Its reported performance is
234
- provisional and does not represent the final trained policy. The artifact and
235
- metrics will be updated after training completes. The measurement above is one
236
- deterministic first-episode pass over the 36-agent scene (12 independent arenas
237
- × three cooperative agents), using a compatible local release-23 build. The
238
- matching model-removed build is published separately in the environment repo.
239
 
240
- DungeonEscape is decentralized cooperative control. Each three-agent match is
241
- stored as three linked ego-agent trajectories, and the same shared policy is
242
- applied independently to every row. Batch inference is computational batching,
243
- not cross-agent attention or hidden-state communication. Cooperation comes from
244
- ego observations and demonstrations generated under the group reward.
245
-
246
- Dataset reference (`unity/dungeon-escape/expert-v0`): mean agent return
247
- 0.606589; mean summed three-agent group return 1.819767; group success 95.32%.
248
- An agent can terminate with zero return before its teammates succeed, so agent
249
- zero is not equivalent to group failure.
250
 
251
- DungeonEscape ONNX contract:
 
 
252
 
253
- | Input/output | Shape |
254
- |---|---|
255
- | `states` | `[36, 32, 371]` |
256
- | `actions` | `[36, 32, 7]` (one-hot feedback) |
257
- | `is_bos` | `[36, 32, 1]` |
258
- | `mask` | `[36, 32]` |
259
- | `action` | `[36, 7]` (logits; `argmax` per row) |
260
 
261
- ## Requirements
262
 
263
- - A matching model-removed Unity ML-Agents build (`.exe`) — see the
264
- [envs repo](https://huggingface.co/datasets/ccnets/causal-gpt-rl-unity-envs).
265
- - Any ONNX runtime: `onnxruntime` (Python) or Unity Sentis (C# / native).
266
- - For the Python runner: the ML-Agents step wrapper (`unity_env.py`) on
267
- `PYTHONPATH` (see the example script header).
268
 
269
  ## License
270
 
271
  Released under PolyForm Noncommercial License 1.0.0. See `LICENSE` for details.
272
- For commercial licensing, contact the maintainers via ccnets.org.
 
 
7
  - unity-ml-agents
8
  - onnx
9
  - causal-gpt-rl
10
+ - pyramids
11
  ---
12
 
13
+ # Causal GPT-RL — Pyramids
14
 
15
+ A Causal GPT-RL policy trained for the Unity ML-Agents release-23 Pyramids
16
+ environment.
17
 
18
+ This repository contains one self-contained ONNX policy:
19
 
20
  ```text
21
+ pyramids/pyramids-b16.onnx
 
22
  ```
23
 
24
+ The graph includes observation normalization and can run with ONNX Runtime or
25
+ Unity Sentis without PyTorch at inference time.
 
 
26
 
27
+ ## Training data
 
 
 
 
 
28
 
29
+ This policy was trained using:
 
 
 
 
30
 
31
+ - `unity/pyramids/simple-v0`
32
+ - `unity/pyramids/medium-v0`
 
 
 
 
33
 
34
+ The `unity/pyramids/expert-v0` dataset was not used for training and is included
35
+ below only as an evaluation reference.
36
 
37
+ ## Evaluation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
+ | Policy | Context | Batch | Observation | Action | Return | Completed |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  |---|---:|---:|---:|---|---:|---:|
41
+ | `pyramids/pyramids-b16.onnx` | 32 | 16 | 172 | `Discrete(5)` | **1.7738 ± 0.1278** | **128/128** |
42
 
43
+ The result is the mean ± population standard deviation over 128 episodes:
44
+ 16 agents across eight fresh Unity launches using environment seeds `100..107`.
 
 
 
45
 
46
+ All episodes completed successfully on the matching model-removed ML-Agents
47
+ release-23 Pyramids build.
 
 
 
48
 
49
+ ## Dataset reference
50
 
51
+ | Dataset | Episodes | Mean return | Training use |
52
+ |---|---:|---:|---|
53
+ | `unity/pyramids/simple-v0` | 3,040 | 1.6339 ± 0.3822 | Used |
54
+ | `unity/pyramids/medium-v0` | 4,267 | 1.7498 ± 0.2528 | Used |
55
+ | `unity/pyramids/expert-v0` | 5,348 | 1.7953 ± 0.2661 | Not used |
56
 
57
+ The ONNX policy exceeds the mean returns of both training datasets. It is also
58
+ approximately 1.2% below the expert dataset mean, despite never being trained
59
+ on the expert dataset.
60
 
61
+ Dataset returns are sums of the recorded per-step rewards for each Minari
62
+ episode.
 
 
 
 
 
63
 
64
+ ## ONNX interface
65
 
66
  | Input/output | Shape |
67
  |---|---|
68
  | `states` | `[16, 32, 172]` |
69
+ | `actions` | `[16, 32, 5]` |
70
  | `is_bos` | `[16, 32, 1]` |
71
  | `mask` | `[16, 32]` |
72
+ | `action` | `[16, 5]` |
 
 
 
 
 
 
73
 
74
+ The four observation sensors must be concatenated in this order:
 
 
 
 
 
 
75
 
76
+ ```text
77
+ 56 + 56 + 56 + 4
78
+ ```
 
 
 
 
 
 
 
79
 
80
+ `action` contains five logits. Select the environment action with `argmax`, then
81
+ feed its five-way one-hot representation into the next action window. Maintain
82
+ one independent 32-step rolling context per agent.
83
 
84
+ The graph uses the checkpoint's `bos_cache_mode=discard` serving convention.
 
 
 
 
 
 
85
 
86
+ ## Companion resources
87
 
88
+ - [Unity environment build](https://huggingface.co/datasets/ccnets/causal-gpt-rl-unity-envs)
89
+ - [Recorded datasets](https://huggingface.co/datasets/ccnets/causal-gpt-rl-unity-datasets)
90
+ - [Evaluation code](https://github.com/ccnets-team/causal-gpt-rl/tree/main/examples/unity)
91
+ - [Causal GPT-RL models for Gymnasium and MuJoCo](https://huggingface.co/ccnets/causal-gpt-rl)
 
92
 
93
  ## License
94
 
95
  Released under PolyForm Noncommercial License 1.0.0. See `LICENSE` for details.
96
+ For commercial licensing, contact the maintainers via
97
+ [ccnets.org](https://ccnets.org).
dungeon-escape/dungeonescape-b36.onnx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:9e5592ee5ee856417c518291bd127350a42a89da794b424fa856cc90b0ad90a7
3
- size 18005378
 
 
 
 
pushblock.onnx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:e97d9dbc1b2d907c7d057d086a62d353c5fa4d93f719f03c02fb4422efab577b
3
- size 17807710
 
 
 
 
soccer-twos/soccertwos-b16.onnx DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:17cac9c9fba7ef1a769bdc344b5bfad4074a3403b03999e6ff5a6ffd8cf118ab
3
- size 17974556