dongqianyu99 commited on
Commit
ba7e4f3
·
verified ·
1 Parent(s): 3ad793d

Publish completed Intercept H1 RTX3090 mean-profile teacher

Browse files
latency-aware/mikasa-intercept-grab-fast/small-policy/ppo-qwenoft-rtx3090-mean-h1-s123-v1/README.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # InterceptGrabFast mean-profile PPO teacher
2
+
3
+ Completed the original 150M configured budget: 2441 full iterations (149,975,040 environment steps), seed123, H1, no DAgger. Fixed99.05021289731565ms latency from archived RTX3090 QwenOFT profile at20Hz; training used RTX PRO6000 Blackwell.
4
+
5
+ `checkpoint.pt` contains only the selected policy tensors. Selection uses native periodic `success_at_end`; the16-episode selection score is not an independent benchmark result. Full optimizer recovery states remain local. See train.yaml, training.args.json, provenance.json, best_evaluation.json and code/.
latency-aware/mikasa-intercept-grab-fast/small-policy/ppo-qwenoft-rtx3090-mean-h1-s123-v1/best_evaluation.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "global_step": 32256000,
3
+ "checkpoint_iteration": 525,
4
+ "episodes": 16,
5
+ "metrics": {
6
+ "success_once": 1.0,
7
+ "return": 24.58411407470703,
8
+ "episode_len": 60.0,
9
+ "reward": 0.40973520278930664,
10
+ "success_at_end": 1.0
11
+ }
12
+ }
latency-aware/mikasa-intercept-grab-fast/small-policy/ppo-qwenoft-rtx3090-mean-h1-s123-v1/checkpoint.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e47526f03fad3ed251dd78f3cacfba8aa8b60bd1578f40bd7a1393e17298e973
3
+ size 1169653
latency-aware/mikasa-intercept-grab-fast/small-policy/ppo-qwenoft-rtx3090-mean-h1-s123-v1/code/get_dataset_collectors_ckpt.py ADDED
@@ -0,0 +1,2132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ! List of environments
2
+ """
3
+ 1. ShellGameTouch-v0
4
+ 2. ShellGamePush-v0
5
+ 3. ShellGamePick-v0
6
+ 4. InterceptSlow-v0
7
+ 5. InterceptMedium-v0
8
+ 6. InterceptFast-v0
9
+ 7. InterceptGrabSlow-v0
10
+ 8. InterceptGrabMedium-v0
11
+ 9. InterceptGrabFast-v0
12
+ 10. RotateLenientPos-v0
13
+ 11. RotateLenientPosNeg-v0
14
+ 12. RotateStrictPos-v0
15
+ 13. RotateStrictPosNeg-v0
16
+ 14. TakeItBack-v0
17
+ 15. RememberColor3-v0
18
+ 16. RememberColor5-v0
19
+ 17. RememberColor9-v0
20
+ 18. RememberShape3-v0
21
+ 19. RememberShape5-v0
22
+ 20. RememberShape9-v0
23
+ 21. RememberShapeAndColor3x2-v0
24
+ 22. RememberShapeAndColor3x3-v0
25
+ 23. RememberShapeAndColor5x3-v0
26
+ 24. BunchOfColors3-v0
27
+ 25. BunchOfColors5-v0
28
+ 26. BunchOfColors7-v0
29
+ 27. SeqOfColors3-v0
30
+ 28. SeqOfColors5-v0
31
+ 29. SeqOfColors7-v0
32
+ 30. ChainOfColors3-v0
33
+ 31. ChainOfColors5-v0
34
+ 32. ChainOfColors7-v0
35
+ 33. BlinkCountButtonPress-VLA-v0
36
+ 34. ShellGameShuffleColorLampTouch-VLA-v0
37
+ 35. ShellGameColorLampTouch-VLA-v0
38
+ """
39
+
40
+ ENVS_CONFIG = {
41
+ # * id: [env_id, success_once_threshold, parameters]
42
+ 0: [
43
+ "ShellGameTouch-v0",
44
+ 0.95,
45
+ {
46
+ "exp_name": "ppo-mlp-state-dense-shell-game-touch-v0",
47
+ "num_steps": 90,
48
+ "num_eval_steps": 90,
49
+ },
50
+ ],
51
+ 1: [
52
+ "ShellGamePush-v0",
53
+ 0.95,
54
+ {"exp_name": "ppo-mlp-state-dense-shell-game-push-v0", "num_steps": 90, "num_eval_steps": 90},
55
+ ],
56
+ 2: [
57
+ "ShellGamePick-v0",
58
+ 0.95,
59
+ {"exp_name": "ppo-mlp-state-dense-shell-game-pick-v0", "num_steps": 90, "num_eval_steps": 90},
60
+ ],
61
+ 3: [
62
+ "InterceptSlow-v0",
63
+ 0.95,
64
+ {"exp_name": "ppo-mlp-state-dense-intercept-slow-v0", "num_steps": 90, "num_eval_steps": 90},
65
+ ],
66
+ 4: [
67
+ "InterceptMedium-v0",
68
+ 0.95,
69
+ {"exp_name": "ppo-mlp-state-dense-intercept-medium-v0", "num_steps": 90, "num_eval_steps": 90},
70
+ ],
71
+ 5: [
72
+ "InterceptFast-v0",
73
+ 0.95,
74
+ {"exp_name": "ppo-mlp-state-dense-intercept-fast-v0", "num_steps": 90, "num_eval_steps": 90},
75
+ ],
76
+ 6: [
77
+ "InterceptGrabSlow-v0",
78
+ 0.95,
79
+ {"exp_name": "ppo-mlp-state-dense-intercept-grab-slow-v0", "num_steps": 90, "num_eval_steps": 90},
80
+ ],
81
+ 7: [
82
+ "InterceptGrabMedium-v0",
83
+ 0.95,
84
+ {"exp_name": "ppo-mlp-state-dense-intercept-grab-medium-v0", "num_steps": 90, "num_eval_steps": 90},
85
+ ],
86
+ 8: [
87
+ "InterceptGrabFast-v0",
88
+ 0.95,
89
+ {"exp_name": "ppo-mlp-state-dense-intercept-grab-fast-v0", "num_steps": 90, "num_eval_steps": 90},
90
+ ],
91
+ 9: [
92
+ "RotateLenientPos-v0",
93
+ 0.95,
94
+ {"exp_name": "ppo-mlp-state-dense-rotate-lenient-pos-v0", "num_steps": 90, "num_eval_steps": 90},
95
+ ],
96
+ 10: [
97
+ "RotateLenientPosNeg-v0",
98
+ 0.95,
99
+ {"exp_name": "ppo-mlp-state-dense-rotate-lenient-pos-neg-v0", "num_steps": 90, "num_eval_steps": 90},
100
+ ],
101
+ 11: [
102
+ "RotateStrictPos-v0",
103
+ 0.95,
104
+ {"exp_name": "ppo-mlp-state-dense-rotate-strict-pos-v0", "num_steps": 90, "num_eval_steps": 90},
105
+ ],
106
+ 12: [
107
+ "RotateStrictPosNeg-v0",
108
+ 0.95,
109
+ {"exp_name": "ppo-mlp-state-dense-rotate-strict-pos-neg-v0", "num_steps": 90, "num_eval_steps": 90},
110
+ ],
111
+ 13: [
112
+ "TakeItBack-v0",
113
+ 0.95,
114
+ {"exp_name": "ppo-mlp-state-dense-take-it-back-v0", "num_steps": 180, "num_eval_steps": 180},
115
+ ],
116
+ 14: [
117
+ "RememberColor3-v0",
118
+ 0.95,
119
+ {
120
+ "exp_name": "ppo-mlp-state-dense-remember-color-3-v0",
121
+ "num_steps": 60,
122
+ "num_eval_steps": 60,
123
+ "gae_lambda": 0.9,
124
+ "gamma": 0.8,
125
+ },
126
+ ],
127
+ 15: [
128
+ "RememberColor5-v0",
129
+ 0.95,
130
+ {
131
+ "exp_name": "ppo-mlp-state-dense-remember-color-5-v0",
132
+ "num_steps": 60,
133
+ "num_eval_steps": 60,
134
+ "gae_lambda": 0.9,
135
+ "gamma": 0.8,
136
+ },
137
+ ],
138
+ 16: [
139
+ "RememberColor9-v0",
140
+ 0.95,
141
+ {
142
+ "exp_name": "ppo-mlp-state-dense-remember-color-9-v0",
143
+ "num_steps": 60,
144
+ "num_eval_steps": 60,
145
+ "gae_lambda": 0.9,
146
+ "gamma": 0.8,
147
+ },
148
+ ],
149
+ 17: [
150
+ "RememberShape3-v0",
151
+ 0.95,
152
+ {
153
+ "exp_name": "ppo-mlp-state-dense-remember-shape-3-v0",
154
+ "num_steps": 60,
155
+ "num_eval_steps": 60,
156
+ "gae_lambda": 0.9,
157
+ "gamma": 0.8,
158
+ },
159
+ ],
160
+ 18: [
161
+ "RememberShape5-v0",
162
+ 0.95,
163
+ {
164
+ "exp_name": "ppo-mlp-state-dense-remember-shape-5-v0",
165
+ "num_steps": 60,
166
+ "num_eval_steps": 60,
167
+ "gae_lambda": 0.9,
168
+ "gamma": 0.8,
169
+ },
170
+ ],
171
+ 19: [
172
+ "RememberShape9-v0",
173
+ 0.95,
174
+ {
175
+ "exp_name": "ppo-mlp-state-dense-remember-shape-9-v0",
176
+ "num_steps": 60,
177
+ "num_eval_steps": 60,
178
+ "gae_lambda": 0.9,
179
+ "gamma": 0.8,
180
+ },
181
+ ],
182
+ 20: [
183
+ "RememberShapeAndColor3x2-v0",
184
+ 0.95,
185
+ {
186
+ "exp_name": "ppo-mlp-state-dense-remember-shape-and-color-3x2-v0",
187
+ "num_steps": 60,
188
+ "num_eval_steps": 60,
189
+ "gae_lambda": 0.9,
190
+ "gamma": 0.8,
191
+ },
192
+ ],
193
+ 21: [
194
+ "RememberShapeAndColor3x3-v0",
195
+ 0.95,
196
+ {
197
+ "exp_name": "ppo-mlp-state-dense-remember-shape-and-color-3x3-v0",
198
+ "num_steps": 60,
199
+ "num_eval_steps": 60,
200
+ "gae_lambda": 0.9,
201
+ "gamma": 0.8,
202
+ },
203
+ ],
204
+ 22: [
205
+ "RememberShapeAndColor5x3-v0",
206
+ 0.95,
207
+ {
208
+ "exp_name": "ppo-mlp-state-dense-remember-shape-and-color-5x3-v0",
209
+ "num_steps": 60,
210
+ "num_eval_steps": 60,
211
+ "gae_lambda": 0.9,
212
+ "gamma": 0.8,
213
+ },
214
+ ],
215
+ 23: [
216
+ "BunchOfColors3-v0",
217
+ 0.95,
218
+ {
219
+ "exp_name": "ppo-mlp-state-dense-bunch-of-colors-3-v0",
220
+ "num_steps": 120,
221
+ "num_eval_steps": 120,
222
+ "gae_lambda": 0.95,
223
+ "gamma": 0.9,
224
+ },
225
+ ],
226
+ 24: [
227
+ "BunchOfColors5-v0",
228
+ 0.95,
229
+ {
230
+ "exp_name": "ppo-mlp-state-dense-bunch-of-colors-5-v0",
231
+ "num_steps": 120,
232
+ "num_eval_steps": 120,
233
+ "gae_lambda": 0.95,
234
+ "gamma": 0.9,
235
+ },
236
+ ],
237
+ 25: [
238
+ "BunchOfColors7-v0",
239
+ 0.95,
240
+ {
241
+ "exp_name": "ppo-mlp-state-dense-bunch-of-colors-7-v0",
242
+ "num_steps": 120,
243
+ "num_eval_steps": 120,
244
+ "gae_lambda": 0.95,
245
+ "gamma": 0.9,
246
+ },
247
+ ],
248
+ 26: [
249
+ "SeqOfColors3-v0",
250
+ 0.95,
251
+ {
252
+ "exp_name": "ppo-mlp-state-dense-seq-of-colors-3-v0",
253
+ "num_steps": 120,
254
+ "num_eval_steps": 120,
255
+ "gae_lambda": 0.95,
256
+ "gamma": 0.9,
257
+ },
258
+ ],
259
+ 27: [
260
+ "SeqOfColors5-v0",
261
+ 0.95,
262
+ {
263
+ "exp_name": "ppo-mlp-state-dense-seq-of-colors-5-v0",
264
+ "num_steps": 120,
265
+ "num_eval_steps": 120,
266
+ "gae_lambda": 0.95,
267
+ "gamma": 0.9,
268
+ },
269
+ ],
270
+ 28: [
271
+ "SeqOfColors7-v0",
272
+ 0.95,
273
+ {
274
+ "exp_name": "ppo-mlp-state-dense-seq-of-colors-7-v0",
275
+ "num_steps": 120,
276
+ "num_eval_steps": 120,
277
+ "gae_lambda": 0.95,
278
+ "gamma": 0.9,
279
+ },
280
+ ],
281
+ 29: [
282
+ "ChainOfColors3-v0",
283
+ 0.95,
284
+ {
285
+ "exp_name": "ppo-mlp-state-dense-chain-of-colors-3-v0",
286
+ "num_steps": 120,
287
+ "num_eval_steps": 120,
288
+ "gae_lambda": 0.95,
289
+ "gamma": 0.9,
290
+ },
291
+ ],
292
+ 30: [
293
+ "ChainOfColors5-v0",
294
+ 0.95,
295
+ {
296
+ "exp_name": "ppo-mlp-state-dense-chain-of-colors-5-v0",
297
+ "num_steps": 120,
298
+ "num_eval_steps": 120,
299
+ "gae_lambda": 0.95,
300
+ "gamma": 0.9,
301
+ },
302
+ ],
303
+ 31: [
304
+ "ChainOfColors7-v0",
305
+ 0.95,
306
+ {
307
+ "exp_name": "ppo-mlp-state-dense-chain-of-colors-7-v0",
308
+ "num_steps": 120,
309
+ "num_eval_steps": 120,
310
+ "gae_lambda": 0.95,
311
+ "gamma": 0.9,
312
+ },
313
+ ],
314
+ # ******* NEW *******
315
+ 32: [
316
+ "RememberColor3-VLA-v0",
317
+ 0.95,
318
+ {
319
+ "exp_name": "ppo-mlp-state-dense-remember-color-3-vla-v0",
320
+ "num_steps": 25,
321
+ "num_eval_steps": 25,
322
+ "gae_lambda": 0.9,
323
+ "gamma": 0.8,
324
+ },
325
+ ],
326
+ 33: [
327
+ "RememberColor5-VLA-v0",
328
+ 0.95,
329
+ {
330
+ "exp_name": "ppo-mlp-state-dense-remember-color-5-vla-v0",
331
+ "num_steps": 25,
332
+ "num_eval_steps": 25,
333
+ "gae_lambda": 0.9,
334
+ "gamma": 0.8,
335
+ },
336
+ ],
337
+ 34: [
338
+ "RememberColor9-VLA-v0",
339
+ 0.95,
340
+ {
341
+ "exp_name": "ppo-mlp-state-dense-remember-color-9-vla-v0",
342
+ "num_steps": 25,
343
+ "num_eval_steps": 25,
344
+ "gae_lambda": 0.9,
345
+ "gamma": 0.8,
346
+ },
347
+ ],
348
+ 35: [
349
+ "RememberShape3-VLA-v0",
350
+ 0.95,
351
+ {
352
+ "exp_name": "ppo-mlp-state-dense-remember-shape-3-vla-v0",
353
+ "num_steps": 25,
354
+ "num_eval_steps": 25,
355
+ "gae_lambda": 0.9,
356
+ "gamma": 0.8,
357
+ },
358
+ ],
359
+ 36: [
360
+ "RememberShape5-VLA-v0",
361
+ 0.95,
362
+ {
363
+ "exp_name": "ppo-mlp-state-dense-remember-shape-5-vla-v0",
364
+ "num_steps": 25,
365
+ "num_eval_steps": 25,
366
+ "gae_lambda": 0.9,
367
+ "gamma": 0.8,
368
+ },
369
+ ],
370
+ 37: [
371
+ "RememberShape9-VLA-v0",
372
+ 0.95,
373
+ {
374
+ "exp_name": "ppo-mlp-state-dense-remember-shape-9-vla-v0",
375
+ "num_steps": 25,
376
+ "num_eval_steps": 25,
377
+ "gae_lambda": 0.9,
378
+ "gamma": 0.8,
379
+ },
380
+ ],
381
+ 38: [
382
+ "RememberShapeAndColor3x2-VLA-v0",
383
+ 0.95,
384
+ {
385
+ "exp_name": "ppo-mlp-state-dense-remember-shape-and-color-3x2-vla-v0",
386
+ "num_steps": 25,
387
+ "num_eval_steps": 25,
388
+ "gae_lambda": 0.9,
389
+ "gamma": 0.8,
390
+ },
391
+ ],
392
+ 39: [
393
+ "RememberShapeAndColor3x3-VLA-v0",
394
+ 0.95,
395
+ {
396
+ "exp_name": "ppo-mlp-state-dense-remember-shape-and-color-3x3-vla-v0",
397
+ "num_steps": 25,
398
+ "num_eval_steps": 25,
399
+ "gae_lambda": 0.9,
400
+ "gamma": 0.8,
401
+ },
402
+ ],
403
+ 40: [
404
+ "RememberShapeAndColor5x3-VLA-v0",
405
+ 0.95,
406
+ {
407
+ "exp_name": "ppo-mlp-state-dense-remember-shape-and-color-5x3-vla-v0",
408
+ "num_steps": 25,
409
+ "num_eval_steps": 25,
410
+ "gae_lambda": 0.9,
411
+ "gamma": 0.8,
412
+ },
413
+ ],
414
+ 41: [
415
+ "ShellGameTouch-VLA-v0",
416
+ 0.95,
417
+ {
418
+ "exp_name": "ppo-mlp-state-dense-shell-game-touch-vla-v0",
419
+ "num_steps": 30,
420
+ "num_eval_steps": 30,
421
+ "gae_lambda": 0.9,
422
+ "gamma": 0.8,
423
+ },
424
+ ],
425
+ 42: [
426
+ "ShellGamePick-VLA-v0",
427
+ 0.95,
428
+ {
429
+ "exp_name": "ppo-mlp-state-dense-shell-game-pick-vla-v0",
430
+ "num_steps": 30,
431
+ "num_eval_steps": 30,
432
+ "gae_lambda": 0.9,
433
+ "gamma": 0.8,
434
+ },
435
+ ],
436
+ 43: [
437
+ "ShellGamePush-VLA-v0",
438
+ 0.95,
439
+ {
440
+ "exp_name": "ppo-mlp-state-dense-shell-game-push-vla-v0",
441
+ "num_steps": 30,
442
+ "num_eval_steps": 30,
443
+ "gae_lambda": 0.9,
444
+ "gamma": 0.8,
445
+ },
446
+ ],
447
+ 44: [
448
+ "InterceptSlow-VLA-v0",
449
+ 0.95,
450
+ {
451
+ "exp_name": "ppo-mlp-state-dense-intercept-slow-vla-v0",
452
+ "num_steps": 60,
453
+ "num_eval_steps": 60,
454
+ },
455
+ ],
456
+ 45: [
457
+ "InterceptMedium-VLA-v0",
458
+ 0.95,
459
+ {
460
+ "exp_name": "ppo-mlp-state-dense-intercept-medium-vla-v0",
461
+ "num_steps": 60,
462
+ "num_eval_steps": 60,
463
+ },
464
+ ],
465
+ 46: [
466
+ "InterceptFast-VLA-v0",
467
+ 0.95,
468
+ {
469
+ "exp_name": "ppo-mlp-state-dense-intercept-fast-vla-v0",
470
+ "num_steps": 60,
471
+ "num_eval_steps": 60,
472
+ },
473
+ ],
474
+ 47: [
475
+ "InterceptGrabSlow-VLA-v0",
476
+ 0.95,
477
+ {
478
+ "exp_name": "ppo-mlp-state-dense-intercept-grab-slow-vla-v0",
479
+ "num_steps": 60,
480
+ "num_eval_steps": 60,
481
+ },
482
+ ],
483
+ 48: [
484
+ "InterceptGrabMedium-VLA-v0",
485
+ 0.95,
486
+ {
487
+ "exp_name": "ppo-mlp-state-dense-intercept-grab-medium-vla-v0",
488
+ "num_steps": 60,
489
+ "num_eval_steps": 60,
490
+ },
491
+ ],
492
+ 49: [
493
+ "InterceptGrabFast-VLA-v0",
494
+ 0.95,
495
+ {
496
+ "exp_name": "ppo-mlp-state-dense-intercept-grab-fast-vla-v0",
497
+ "num_steps": 60,
498
+ "num_eval_steps": 60,
499
+ },
500
+ ],
501
+ 50: [
502
+ "RotateLenientPos-VLA-v0",
503
+ 0.95,
504
+ {
505
+ "exp_name": "ppo-mlp-state-dense-rotate-lenient-pos-vla-v0",
506
+ "num_steps": 60,
507
+ "num_eval_steps": 60,
508
+ },
509
+ ],
510
+ 51: [
511
+ "RotateLenientPosNeg-VLA-v0",
512
+ 0.95,
513
+ {
514
+ "exp_name": "ppo-mlp-state-dense-rotate-lenient-pos-neg-vla-v0",
515
+ "num_steps": 60,
516
+ "num_eval_steps": 60,
517
+ },
518
+ ],
519
+ 52: [
520
+ "RotateStrictPos-VLA-v0",
521
+ 0.95,
522
+ {
523
+ "exp_name": "ppo-mlp-state-dense-rotate-strict-pos-vla-v0",
524
+ "num_steps": 90,
525
+ "num_eval_steps": 90,
526
+ },
527
+ ],
528
+ 53: [
529
+ "RotateStrictPosNeg-VLA-v0",
530
+ 0.95,
531
+ {
532
+ "exp_name": "ppo-mlp-state-dense-rotate-strict-pos-neg-vla-v0",
533
+ "num_steps": 90,
534
+ "num_eval_steps": 90,
535
+ },
536
+ ],
537
+ 54: [
538
+ "TakeItBack-VLA-v0",
539
+ 0.95,
540
+ {
541
+ "exp_name": "ppo-mlp-state-dense-take-it-back-vla-v0",
542
+ "num_steps": 60,
543
+ "num_eval_steps": 60,
544
+ },
545
+ ],
546
+ 55: [
547
+ "SeqOfColors3-VLA-v0",
548
+ 0.95,
549
+ {
550
+ "exp_name": "ppo-mlp-state-dense-seq-of-colors-3-vla-v0",
551
+ "num_steps": 100,
552
+ "num_eval_steps": 100,
553
+ },
554
+ ],
555
+ 56: [
556
+ "SeqOfColors5-VLA-v0",
557
+ 0.95,
558
+ {
559
+ "exp_name": "ppo-mlp-state-dense-seq-of-colors-5-vla-v0",
560
+ "num_steps": 100,
561
+ "num_eval_steps": 100,
562
+ },
563
+ ],
564
+ 57: [
565
+ "SeqOfColors7-VLA-v0",
566
+ 0.95,
567
+ {
568
+ "exp_name": "ppo-mlp-state-dense-seq-of-colors-7-vla-v0",
569
+ "num_steps": 100,
570
+ "num_eval_steps": 100,
571
+ },
572
+ ],
573
+ 58: [
574
+ "ChainOfColors3-VLA-v0",
575
+ 0.95,
576
+ {
577
+ "exp_name": "ppo-mlp-state-dense-chain-of-colors-3-vla-v0",
578
+ "num_steps": 100,
579
+ "num_eval_steps": 100,
580
+ },
581
+ ],
582
+ 59: [
583
+ "ChainOfColors5-VLA-v0",
584
+ 0.95,
585
+ {
586
+ "exp_name": "ppo-mlp-state-dense-chain-of-colors-5-vla-v0",
587
+ "num_steps": 100,
588
+ "num_eval_steps": 100,
589
+ },
590
+ ],
591
+ 60: [
592
+ "ChainOfColors7-VLA-v0",
593
+ 0.95,
594
+ {
595
+ "exp_name": "ppo-mlp-state-dense-chain-of-colors-7-vla-v0",
596
+ "num_steps": 100,
597
+ "num_eval_steps": 100,
598
+ },
599
+ ],
600
+ 61: [
601
+ "BunchOfColors3-VLA-v0",
602
+ 0.95,
603
+ {
604
+ "exp_name": "ppo-mlp-state-dense-bunch-of-colors-3-vla-v0",
605
+ "num_steps": 100,
606
+ "num_eval_steps": 100,
607
+ },
608
+ ],
609
+ 62: [
610
+ "BunchOfColors5-VLA-v0",
611
+ 0.95,
612
+ {
613
+ "exp_name": "ppo-mlp-state-dense-bunch-of-colors-5-vla-v0",
614
+ "num_steps": 100,
615
+ "num_eval_steps": 100,
616
+ },
617
+ ],
618
+ 63: [
619
+ "BunchOfColors7-VLA-v0",
620
+ 0.95,
621
+ {
622
+ "exp_name": "ppo-mlp-state-dense-bunch-of-colors-7-vla-v0",
623
+ "num_steps": 100,
624
+ "num_eval_steps": 100,
625
+ },
626
+ ],
627
+ 64: [
628
+ "ShellGameShuffleTouch-VLA-v0",
629
+ 0.95,
630
+ {
631
+ "exp_name": "ppo-mlp-state-dense-shell-game-shuffle-touch-vla-v0",
632
+ "num_steps": 60,
633
+ "num_eval_steps": 60,
634
+ "gae_lambda": 0.9,
635
+ "gamma": 0.8,
636
+ },
637
+ ],
638
+ 65: [
639
+ "BlinkCountButtonPress-VLA-v0",
640
+ 0.95,
641
+ {
642
+ "exp_name": "ppo-mlp-state-dense-blink-count-button-press-vla-v0",
643
+ "num_steps": 180,
644
+ "num_eval_steps": 180,
645
+ "gae_lambda": 0.9,
646
+ "gamma": 0.8,
647
+ },
648
+ ],
649
+ 66: [
650
+ "ShellGameShuffleColorLampTouch-VLA-v0",
651
+ 0.95,
652
+ {
653
+ "exp_name": "ppo-mlp-state-dense-shell-game-shuffle-color-lamp-touch-vla-v0",
654
+ "num_steps": 60,
655
+ "num_eval_steps": 60,
656
+ "gae_lambda": 0.9,
657
+ "gamma": 0.8,
658
+ },
659
+ ],
660
+ 67: [
661
+ "ShellGameColorLampTouch-VLA-v0",
662
+ 0.95,
663
+ {
664
+ "exp_name": "ppo-mlp-state-dense-shell-game-color-lamp-touch-vla-v0",
665
+ "num_steps": 30,
666
+ "num_eval_steps": 30,
667
+ "gae_lambda": 0.9,
668
+ "gamma": 0.8,
669
+ },
670
+ ],
671
+ }
672
+
673
+
674
+ def get_env_config(env_id):
675
+ """
676
+ Get environment configuration by env_id.
677
+
678
+ Now instead of config = ENVS_CONFIG[0]
679
+ we use config = get_env_config(env_id)
680
+ """
681
+ for config in ENVS_CONFIG.values():
682
+ if config[0] == env_id:
683
+ return config
684
+ raise ValueError(f"Environment {env_id} not found in ENVS_CONFIG")
685
+
686
+
687
+ import json
688
+ import os
689
+ import random
690
+ import time
691
+ from collections import defaultdict
692
+ from dataclasses import dataclass
693
+ from typing import Optional
694
+
695
+ import gymnasium as gym
696
+ import numpy as np
697
+ import torch
698
+ import torch.nn as nn
699
+ import torch.optim as optim
700
+ import tyro
701
+ from colorama import Fore, Style
702
+ from torch.distributions.normal import Normal
703
+ from torch.utils.tensorboard import SummaryWriter
704
+
705
+ if os.path.exists("wandb_config.yaml"):
706
+ import yaml
707
+
708
+ with open("wandb_config.yaml") as f:
709
+ wandb_config = yaml.load(f, Loader=yaml.FullLoader)
710
+ os.environ["WANDB_API_KEY"] = wandb_config["wandb_api"]
711
+
712
+ import sys
713
+ import warnings
714
+ from typing import Dict
715
+
716
+ from mani_skill.envs.sapien_env import BaseEnv
717
+ from mani_skill.utils import common, gym_utils
718
+ from mani_skill.utils.wrappers.flatten import FlattenActionSpaceWrapper
719
+ from mani_skill.utils.wrappers.record import RecordEpisode
720
+ from mani_skill.vector.wrappers.gymnasium import ManiSkillVectorEnv
721
+ from tqdm import tqdm
722
+
723
+ import mikasa_robo_suite.vla.memory_envs # noqa: F401
724
+ from mikasa_robo_suite.vla.utils.wrappers import *
725
+
726
+ warnings.filterwarnings("ignore", message=".*env\\.\\w+ to get variables from other wrappers is deprecated.*")
727
+
728
+ # from baselines.ppo.ppo_memtasks import *
729
+
730
+ from dataclasses import asdict
731
+ from pprint import pprint
732
+
733
+ # pprint(self.config, indent=2, width=80)
734
+
735
+
736
+ class FlattenRGBDObservationWrapper(gym.ObservationWrapper):
737
+ """
738
+ Flattens the rgbd mode observations into a dictionary with two keys, "rgbd" and "state"
739
+
740
+ Args:
741
+ rgb (bool): Whether to include rgb images in the observation
742
+ depth (bool): Whether to include depth images in the observation
743
+ state (bool): Whether to include state data in the observation
744
+ """
745
+
746
+ def __init__(self, env, rgb=True, depth=True, state=True, oracle=False, joints=False) -> None:
747
+ self.base_env: BaseEnv = StateOnlyTensorToDictWrapper(env.unwrapped)
748
+ super().__init__(env)
749
+ self.include_rgb = rgb
750
+ self.include_depth = depth
751
+ self.include_state = state
752
+ self.include_oracle = oracle
753
+ self.include_joints = joints
754
+
755
+ sample_obs, _ = env.reset()
756
+ new_obs = self.observation(sample_obs)
757
+ self.base_env.update_obs_space(new_obs)
758
+
759
+ def observation(self, observation: Dict):
760
+ ret = dict()
761
+
762
+ if self.include_rgb or self.include_depth:
763
+ ret["oracle_info"] = observation["oracle_info"]
764
+ ret["task_cue"] = observation["task_cue"]
765
+ sensor_data = observation.pop("sensor_data")
766
+
767
+ del observation["sensor_param"]
768
+ images = []
769
+ for cam_data in sensor_data.values():
770
+ if self.include_rgb:
771
+ images.append(cam_data["rgb"])
772
+ if self.include_depth:
773
+ images.append(cam_data["depth"])
774
+
775
+ if len(images) > 0:
776
+ images = torch.concat(images, axis=-1)
777
+
778
+ # flatten the rest of the data which should just be state data
779
+ if self.include_state and not (self.include_rgb or self.include_depth):
780
+ if not self.include_oracle:
781
+ observation.pop("oracle_info")
782
+ else:
783
+ observation = observation
784
+ else:
785
+ if not self.include_joints:
786
+ filtered_obs = {k: v for k, v in observation.items() if k not in ["task_cue", "oracle_info"]}
787
+ else:
788
+ # Create extra_agent dict with 'extra' and 'agent' keys
789
+ extra_agent = {}
790
+ for key in ["extra", "agent"]:
791
+ if key in observation:
792
+ extra_agent[key] = observation.pop(key)
793
+
794
+ # Flatten the extra_agent dict
795
+ extra_agent_flat = common.flatten_state_dict(extra_agent, use_torch=True, device=self.base_env.device)
796
+ ret["proprio"] = extra_agent_flat
797
+
798
+ filtered_obs = {k: v for k, v in observation.items() if k not in ["task_cue", "oracle_info", "extra"]}
799
+
800
+ observation = common.flatten_state_dict(filtered_obs, use_torch=True, device=self.base_env.device)
801
+
802
+ if self.include_state and not (self.include_rgb or self.include_depth):
803
+ ret = observation
804
+ else:
805
+ ret["state"] = observation
806
+ if self.include_rgb and not self.include_depth:
807
+ ret["rgb"] = images
808
+ elif self.include_rgb and self.include_depth:
809
+ ret["rgbd"] = images
810
+ elif self.include_depth and not self.include_rgb:
811
+ ret["depth"] = images
812
+
813
+ if "state" in ret.keys() and not self.include_state:
814
+ ret.pop("state")
815
+
816
+ if "oracle_info" in ret.keys() and not self.include_oracle and ret["oracle_info"] is not None:
817
+ ret.pop("oracle_info")
818
+
819
+ if "oracle_info" in ret.keys() and (ret["oracle_info"] == 4242424242).any().item():
820
+ ret.pop("oracle_info")
821
+
822
+ if "task_cue" in ret.keys() and (ret["task_cue"] == 4242424242).any().item():
823
+ ret.pop("task_cue")
824
+
825
+ if "proprio" in ret.keys() and not self.include_joints:
826
+ ret.pop("proprio")
827
+
828
+ return ret
829
+
830
+
831
+ @dataclass
832
+ class Args:
833
+ exp_name: Optional[str] = None
834
+ """the name of this experiment"""
835
+ seed: int = 123
836
+ """seed of the experiment"""
837
+ torch_deterministic: bool = True
838
+ """if toggled, `torch.backends.cudnn.deterministic=False`"""
839
+ cuda: bool = True
840
+ """if toggled, cuda will be enabled by default"""
841
+ track: bool = False
842
+ """if toggled, this experiment will be tracked with Weights and Biases"""
843
+ wandb_project_name: str = "MIKASA-Robo-dataset-collectors"
844
+ """the wandb's project name"""
845
+ wandb_entity: Optional[str] = None
846
+ """the entity (team) of wandb's project"""
847
+ capture_video: bool = False
848
+ """whether to capture videos of the agent performances (check out `videos` folder)"""
849
+ save_model: bool = True
850
+ """whether to save model into the `checkpoints/ppo_memtasks/runs/{run_name}/{TIME}` folder"""
851
+ evaluate: bool = False
852
+ """if toggled, only runs evaluation with the given model checkpoint and saves the evaluation trajectories"""
853
+ checkpoint: Optional[str] = None
854
+ """path to a pretrained checkpoint file to start evaluation/training from"""
855
+ latency_config: Optional[str] = None
856
+ """latency-bench command transport config for training and evaluation"""
857
+ resume: Optional[str] = None
858
+ """latency training bundle, including optimizer and progress"""
859
+ latency_output_dir: Optional[str] = None
860
+ """explicit output directory for the latency run"""
861
+ render_mode: str = "all"
862
+ """the environment rendering mode"""
863
+
864
+ # Algorithm specific arguments
865
+ env_id: str = "ShellGamePush-v1"
866
+ """the id of the environment"""
867
+ include_state: bool = True
868
+ """whether to include state information in observations"""
869
+ total_timesteps: int = 50_000_000
870
+ """total timesteps of the experiments"""
871
+ learning_rate: float = 3e-4
872
+ """the learning rate of the optimizer"""
873
+ num_envs: int = 1024 # 512 | *256
874
+ """the number of parallel environments"""
875
+ num_eval_envs: int = 16
876
+ """the number of parallel evaluation environments"""
877
+ partial_reset: bool = False # True
878
+ """whether to let parallel environments reset upon termination instead of truncation"""
879
+ eval_partial_reset: bool = False
880
+ """whether to let parallel evaluation environments reset upon termination instead of truncation"""
881
+ num_steps: int = 90
882
+ """the number of steps to run in each environment per policy rollout"""
883
+ num_eval_steps: int = 270
884
+ """the number of steps to run in each evaluation environment during evaluation"""
885
+ reconfiguration_freq: Optional[int] = None
886
+ """how often to reconfigure the environment during training"""
887
+ eval_reconfiguration_freq: Optional[int] = 1
888
+ """for benchmarking purposes we want to reconfigure the eval environment each reset to ensure objects are randomized in some tasks"""
889
+ anneal_lr: bool = False
890
+ """Toggle learning rate annealing for policy and value networks"""
891
+ gamma: float = 0.99 # ! 0.8 !
892
+ """the discount factor gamma"""
893
+ gae_lambda: float = 0.95 # ! 0.9 !
894
+ """the lambda for the general advantage estimation"""
895
+ num_minibatches: int = 32 # 32 | *8
896
+ """the number of mini-batches"""
897
+ update_epochs: int = 4 # 4 | *8
898
+ """the K epochs to update the policy"""
899
+ norm_adv: bool = True
900
+ """Toggles advantages normalization"""
901
+ clip_coef: float = 0.2
902
+ """the surrogate clipping coefficient"""
903
+ clip_vloss: bool = False # ! False !
904
+ """Toggles whether or not to use a clipped loss for the value function, as per the paper."""
905
+ ent_coef: float = 0.0
906
+ """coefficient of the entropy"""
907
+ vf_coef: float = 0.5
908
+ """coefficient of the value function"""
909
+ max_grad_norm: float = 0.5
910
+ """the maximum norm for the gradient clipping"""
911
+ target_kl: float = 0.2
912
+ """the target KL divergence threshold"""
913
+ reward_scale: float = 1.0
914
+ """Scale the reward by this factor"""
915
+ eval_freq: int = 25
916
+ """evaluation frequency in terms of iterations"""
917
+ save_train_video_freq: Optional[int] = None
918
+ """frequency to save training videos in terms of iterations"""
919
+ finite_horizon_gae: bool = True
920
+
921
+ # to be filled in runtime
922
+ batch_size: int = 0
923
+ """the batch size (computed in runtime)"""
924
+ minibatch_size: int = 0
925
+ """the mini-batch size (computed in runtime)"""
926
+ num_iterations: int = 0
927
+ """the number of iterations (computed in runtime)"""
928
+
929
+ include_oracle: bool = False
930
+ """if toggled, oracle info (such as cup_with_ball_number in ShellGamePush-v0) will be used during the training, i.e. reducing memory task to MDP"""
931
+ noop_steps: int = 1
932
+ """if = 1, then no noops, if > 1, then noops for t ~ [0, noop_steps-1]"""
933
+ include_rgb: bool = False
934
+ """if toggled, rgb images will be included in the observation space"""
935
+ include_joints: bool = False
936
+ """[works only with include_rgb=True] if toggled, joints will be included in the observation space"""
937
+ reward_mode: str = "normalized_dense" # sparse | normalized_dense
938
+ """the mode of the reward function"""
939
+
940
+
941
+ def layer_init(layer, std=np.sqrt(2), bias_const=0.0):
942
+ torch.nn.init.orthogonal_(layer.weight, std)
943
+ torch.nn.init.constant_(layer.bias, bias_const)
944
+ return layer
945
+
946
+
947
+ def print_tensor_shapes(d, prefix=""):
948
+ for k, v in d.items():
949
+ if isinstance(v, dict):
950
+ print_tensor_shapes(v, prefix=f"{prefix}{k}.")
951
+ elif isinstance(v, torch.Tensor):
952
+ print(f"{prefix}{k}: {v.shape}")
953
+
954
+
955
+ class DictArray(object):
956
+ def __init__(self, buffer_shape, element_space, data_dict=None, device=None):
957
+ self.buffer_shape = buffer_shape
958
+ if data_dict:
959
+ self.data = data_dict
960
+ else:
961
+ assert isinstance(element_space, gym.spaces.dict.Dict)
962
+ self.data = {}
963
+ for k, v in element_space.items():
964
+ if isinstance(v, gym.spaces.dict.Dict):
965
+ self.data[k] = DictArray(buffer_shape, v)
966
+ else:
967
+ self.data[k] = torch.zeros(buffer_shape + v.shape).to(device)
968
+
969
+ def keys(self):
970
+ return self.data.keys()
971
+
972
+ def __getitem__(self, index):
973
+ if isinstance(index, str):
974
+ return self.data[index]
975
+ return {k: v[index] for k, v in self.data.items()}
976
+
977
+ def __setitem__(self, index, value):
978
+ if isinstance(index, str):
979
+ self.data[index] = value
980
+ for k, v in value.items():
981
+ self.data[k][index] = v
982
+
983
+ @property
984
+ def shape(self):
985
+ return self.buffer_shape
986
+
987
+ def reshape(self, shape):
988
+ t = len(self.buffer_shape)
989
+ new_dict = {}
990
+ for k, v in self.data.items():
991
+ if isinstance(v, DictArray):
992
+ new_dict[k] = v.reshape(shape)
993
+ else:
994
+ new_dict[k] = v.reshape(shape + v.shape[t:])
995
+ new_buffer_shape = next(iter(new_dict.values())).shape[: len(shape)]
996
+ return DictArray(new_buffer_shape, None, data_dict=new_dict)
997
+
998
+
999
+ class NatureCNN(nn.Module):
1000
+ def __init__(self, sample_obs):
1001
+ """
1002
+ oracle_info: dict with keys: "cup_with_ball_number" for ShellGame
1003
+ include_oracle: bool, if True, oracle_info will be used during the training, i.e. reducing memory task to MDP
1004
+ """
1005
+ super().__init__()
1006
+
1007
+ extractors = {}
1008
+
1009
+ self.out_features = 0
1010
+ feature_size = 256
1011
+
1012
+ self.list_of_obs_keys = list(sample_obs.keys()) # 'oracle_info', 'task_cue', 'state', 'rgb'
1013
+
1014
+ if "rgb" in self.list_of_obs_keys:
1015
+ in_channels = sample_obs["rgb"].shape[-1]
1016
+ (sample_obs["rgb"].shape[1], sample_obs["rgb"].shape[2])
1017
+
1018
+ # here we use a NatureCNN architecture to process images, but any architecture is permissble here
1019
+ cnn = nn.Sequential(
1020
+ nn.Conv2d(
1021
+ in_channels=in_channels,
1022
+ out_channels=32,
1023
+ kernel_size=8,
1024
+ stride=4,
1025
+ padding=0,
1026
+ ),
1027
+ nn.ReLU(),
1028
+ nn.Conv2d(in_channels=32, out_channels=64, kernel_size=4, stride=2, padding=0),
1029
+ nn.ReLU(),
1030
+ nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, stride=1, padding=0),
1031
+ nn.ReLU(),
1032
+ nn.Flatten(),
1033
+ )
1034
+
1035
+ # to easily figure out the dimensions after flattening, we pass a test tensor
1036
+ with torch.no_grad():
1037
+ n_flatten = cnn(sample_obs["rgb"].float().permute(0, 3, 1, 2).cpu()).shape[1]
1038
+ fc = nn.Sequential(nn.Linear(n_flatten, feature_size), nn.ReLU())
1039
+ extractors["rgb"] = nn.Sequential(cnn, fc)
1040
+ self.out_features += feature_size
1041
+
1042
+ for key in self.list_of_obs_keys:
1043
+ if key in ["oracle_info", "task_cue"]:
1044
+ extractors[key] = nn.Sequential(nn.Linear(sample_obs[key].shape[-1], 64), nn.ReLU())
1045
+ self.out_features += 64
1046
+ elif key == "proprio":
1047
+ extractors[key] = nn.Sequential(nn.Linear(sample_obs[key].shape[-1], 128), nn.ReLU())
1048
+ self.out_features += 128
1049
+
1050
+ print(f"{sample_obs.keys()=}")
1051
+ print_tensor_shapes(sample_obs)
1052
+ print("\n")
1053
+
1054
+ # for state data we simply pass it through a single linear layer
1055
+ if "state" in sample_obs.keys():
1056
+ state_size = sample_obs["state"].shape[-1]
1057
+ extractors["state"] = nn.Linear(state_size, 256)
1058
+ self.out_features += 256
1059
+
1060
+ self.extractors = nn.ModuleDict(extractors)
1061
+
1062
+ def forward(self, observations) -> torch.Tensor:
1063
+ encoded_tensor_list = []
1064
+ # self.extractors contain nn.Modules that do all the processing.
1065
+ for key, extractor in self.extractors.items():
1066
+ obs = observations[key]
1067
+ if key == "rgb" and "rgb" in self.list_of_obs_keys:
1068
+ obs = obs.float().permute(0, 3, 1, 2) # (N, H, W, C) -> (N, C, H, W)
1069
+ obs = obs / 255
1070
+ elif key in ["oracle_info", "task_cue", "proprio"]:
1071
+ obs = obs.float()
1072
+
1073
+ encoded_tensor_list.append(extractor(obs))
1074
+ return torch.cat(encoded_tensor_list, dim=1)
1075
+
1076
+
1077
+ class Agent(nn.Module):
1078
+ def __init__(self, envs, sample_obs):
1079
+ super().__init__()
1080
+ self.feature_net = NatureCNN(sample_obs=sample_obs)
1081
+ # latent_size = np.array(envs.unwrapped.single_observation_space.shape).prod()
1082
+ latent_size = self.feature_net.out_features
1083
+ self.critic = nn.Sequential(
1084
+ layer_init(nn.Linear(latent_size, 512)),
1085
+ nn.ReLU(inplace=True),
1086
+ layer_init(nn.Linear(512, 1)),
1087
+ )
1088
+ self.actor_mean = nn.Sequential(
1089
+ layer_init(nn.Linear(latent_size, 512)),
1090
+ nn.ReLU(inplace=True),
1091
+ layer_init(nn.Linear(512, np.prod(envs.unwrapped.single_action_space.shape)), std=0.01 * np.sqrt(2)),
1092
+ )
1093
+ self.actor_logstd = nn.Parameter(torch.ones(1, np.prod(envs.unwrapped.single_action_space.shape)) * -0.5)
1094
+
1095
+ def get_features(self, x):
1096
+ return self.feature_net(x)
1097
+
1098
+ def get_value(self, x):
1099
+ x = self.feature_net(x)
1100
+ return self.critic(x)
1101
+
1102
+ def get_action(self, x, deterministic=False):
1103
+ x = self.feature_net(x)
1104
+ action_mean = self.actor_mean(x)
1105
+ if deterministic:
1106
+ return action_mean
1107
+ action_logstd = self.actor_logstd.expand_as(action_mean)
1108
+ action_std = torch.exp(action_logstd)
1109
+ probs = Normal(action_mean, action_std)
1110
+ return probs.sample()
1111
+
1112
+ def get_action_and_value(self, x, action=None):
1113
+ x = self.feature_net(x)
1114
+ action_mean = self.actor_mean(x)
1115
+ action_logstd = self.actor_logstd.expand_as(action_mean)
1116
+ action_std = torch.exp(action_logstd)
1117
+ probs = Normal(action_mean, action_std)
1118
+ if action is None:
1119
+ action = probs.sample()
1120
+ return action, probs.log_prob(action).sum(1), probs.entropy().sum(1), self.critic(x)
1121
+
1122
+
1123
+ class AgentStateOnly(nn.Module):
1124
+ def __init__(self, envs):
1125
+ super().__init__()
1126
+
1127
+ self.list_of_obs_keys = list(envs.single_observation_space.keys())
1128
+ print(f"{self.list_of_obs_keys=}")
1129
+
1130
+ length = 0
1131
+ for key in self.list_of_obs_keys:
1132
+ l_ = np.array(envs.single_observation_space[key].shape).prod()
1133
+ print(f"{key}: {l_}")
1134
+ length += l_
1135
+
1136
+ print(f"Total length: {length}")
1137
+
1138
+ self.critic = nn.Sequential(
1139
+ layer_init(nn.Linear(length, 256)),
1140
+ nn.Tanh(),
1141
+ layer_init(nn.Linear(256, 256)),
1142
+ nn.Tanh(),
1143
+ layer_init(nn.Linear(256, 256)),
1144
+ nn.Tanh(),
1145
+ layer_init(nn.Linear(256, 1)),
1146
+ )
1147
+ self.actor_mean = nn.Sequential(
1148
+ layer_init(nn.Linear(length, 256)),
1149
+ nn.Tanh(),
1150
+ layer_init(nn.Linear(256, 256)),
1151
+ nn.Tanh(),
1152
+ layer_init(nn.Linear(256, 256)),
1153
+ nn.Tanh(),
1154
+ layer_init(nn.Linear(256, np.prod(envs.single_action_space.shape)), std=0.01 * np.sqrt(2)),
1155
+ )
1156
+ self.actor_logstd = nn.Parameter(torch.ones(1, np.prod(envs.single_action_space.shape)) * -0.5)
1157
+
1158
+ print(f"{envs.single_observation_space=}")
1159
+
1160
+ def add_task_cue_to_state(self, x):
1161
+ # Concatenate all observation tensors in order of self.list_of_obs_keys
1162
+ tensors = [x[key] for key in self.list_of_obs_keys]
1163
+ return torch.cat(tensors, dim=-1)
1164
+
1165
+ def get_value(self, x):
1166
+ x = self.add_task_cue_to_state(x)
1167
+ return self.critic(x)
1168
+
1169
+ def get_action(self, x, deterministic=False):
1170
+ x = self.add_task_cue_to_state(x)
1171
+ action_mean = self.actor_mean(x)
1172
+ if deterministic:
1173
+ return action_mean
1174
+ action_logstd = self.actor_logstd.expand_as(action_mean)
1175
+ action_std = torch.exp(action_logstd)
1176
+ probs = Normal(action_mean, action_std)
1177
+ return probs.sample()
1178
+
1179
+ def get_action_and_value(self, x, action=None):
1180
+ x = self.add_task_cue_to_state(x)
1181
+ action_mean = self.actor_mean(x)
1182
+ action_logstd = self.actor_logstd.expand_as(action_mean)
1183
+ action_std = torch.exp(action_logstd)
1184
+ probs = Normal(action_mean, action_std)
1185
+ if action is None:
1186
+ action = probs.sample()
1187
+ return action, probs.log_prob(action).sum(1), probs.entropy().sum(1), self.critic(x)
1188
+
1189
+
1190
+ class Logger:
1191
+ def __init__(self, log_wandb=False, tensorboard: SummaryWriter = None) -> None:
1192
+ self.writer = tensorboard
1193
+ self.log_wandb = log_wandb
1194
+
1195
+ def add_scalar(self, tag, scalar_value, step):
1196
+ if self.log_wandb:
1197
+ wandb.log({tag: scalar_value}, step=step)
1198
+ self.writer.add_scalar(tag, scalar_value, step)
1199
+
1200
+ def close(self):
1201
+ self.writer.close()
1202
+
1203
+
1204
+ def ppo_losses(args, newlogprob, entropy, newvalue, logprobs, advantages, returns, values, admitted):
1205
+ """Fit values on every control step and policy terms on admitted commands."""
1206
+ newvalue = newvalue.view(-1)
1207
+ if args.clip_vloss:
1208
+ v_clipped = values + torch.clamp(newvalue - values, -args.clip_coef, args.clip_coef)
1209
+ v_loss = 0.5 * torch.maximum((newvalue - returns) ** 2, (v_clipped - returns) ** 2).mean()
1210
+ else:
1211
+ v_loss = 0.5 * ((newvalue - returns) ** 2).mean()
1212
+
1213
+ # A worker may be busy for the whole minibatch; those states still train
1214
+ # the critic, while no policy decision contributes an actor gradient.
1215
+ if not admitted.any():
1216
+ zero = newvalue.new_zeros(())
1217
+ return zero, v_loss, zero, zero, zero, zero
1218
+
1219
+ logratio = newlogprob[admitted] - logprobs[admitted]
1220
+ ratio = logratio.exp()
1221
+ advantages = advantages[admitted]
1222
+ if args.norm_adv:
1223
+ advantages = (advantages - advantages.mean()) / (
1224
+ advantages.std(unbiased=advantages.numel() > 1) + 1e-8
1225
+ )
1226
+ pg_loss = torch.maximum(
1227
+ -advantages * ratio,
1228
+ -advantages * torch.clamp(ratio, 1 - args.clip_coef, 1 + args.clip_coef),
1229
+ ).mean()
1230
+ with torch.no_grad():
1231
+ old_approx_kl = (-logratio).mean()
1232
+ approx_kl = ((ratio - 1) - logratio).mean()
1233
+ clipfrac = ((ratio - 1).abs() > args.clip_coef).float().mean()
1234
+ return pg_loss, v_loss, entropy[admitted].mean(), old_approx_kl, approx_kl, clipfrac
1235
+
1236
+
1237
+ if __name__ == "__main__":
1238
+ args = tyro.cli(Args)
1239
+
1240
+ # Get pre-defined environment configuration
1241
+ env_oracle_config = get_env_config(args.env_id)
1242
+ env_params = env_oracle_config[2] # get dict of parameters
1243
+ success_once_threshold = env_oracle_config[1]
1244
+
1245
+ for param_name, param_value in env_params.items():
1246
+ if hasattr(args, param_name):
1247
+ setattr(args, param_name, param_value)
1248
+
1249
+ if args.latency_config is not None:
1250
+ from latency_bench.core.config import load_config
1251
+
1252
+ latency_config = load_config(args.latency_config)
1253
+ for param_name, param_value in latency_config["training"].items():
1254
+ setattr(args, param_name, param_value)
1255
+
1256
+ args.batch_size = int(args.num_envs * args.num_steps)
1257
+ args.minibatch_size = int(args.batch_size // args.num_minibatches)
1258
+ args.num_iterations = args.total_timesteps // args.batch_size
1259
+
1260
+ print("\nConfiguration:")
1261
+ pprint(asdict(args), indent=2, width=80)
1262
+ print("\n")
1263
+
1264
+ TIME = time.strftime("%Y%m%d_%H%M%S")
1265
+
1266
+ if args.env_id in ["ShellGamePush-v0", "ShellGamePick-v0", "ShellGameTouch-v0"]:
1267
+ wrappers_list = [
1268
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1269
+ (RenderStepInfoWrapper, {}),
1270
+ (ShellGameRenderCupInfoWrapper, {}),
1271
+ (RenderRewardInfoWrapper, {}),
1272
+ (DebugRewardWrapper, {}),
1273
+ ]
1274
+ oracle_info = "cup_with_ball_number"
1275
+ task_cue_info = None
1276
+ elif args.env_id in [
1277
+ "InterceptSlow-v0",
1278
+ "InterceptMedium-v0",
1279
+ "InterceptFast-v0",
1280
+ "InterceptGrabSlow-v0",
1281
+ "InterceptGrabMedium-v0",
1282
+ "InterceptGrabFast-v0",
1283
+ ]:
1284
+ wrappers_list = [
1285
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1286
+ (RenderStepInfoWrapper, {}),
1287
+ (RenderRewardInfoWrapper, {}),
1288
+ (DebugRewardWrapper, {}),
1289
+ ]
1290
+ oracle_info = None
1291
+ task_cue_info = None
1292
+ elif args.env_id in [
1293
+ "RotateLenientPos-v0",
1294
+ "RotateLenientPosNeg-v0",
1295
+ "RotateStrictPos-v0",
1296
+ "RotateStrictPosNeg-v0",
1297
+ ]:
1298
+ wrappers_list = [
1299
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1300
+ (RenderStepInfoWrapper, {}),
1301
+ (RenderRewardInfoWrapper, {}),
1302
+ (RotateRenderAngleInfoWrapper, {}),
1303
+ (DebugRewardWrapper, {}),
1304
+ ]
1305
+ oracle_info = "angle_diff"
1306
+ task_cue_info = "target_angle"
1307
+ elif args.env_id in ["CameraShutdownPush-v0", "CameraShutdownPick-v0"]:
1308
+ wrappers_list = [
1309
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1310
+ (CameraShutdownWrapper, {"n_initial_steps": 19}), # camera works only for t ~ [0, 19]
1311
+ (RenderStepInfoWrapper, {}),
1312
+ (RenderRewardInfoWrapper, {}),
1313
+ ]
1314
+ oracle_info = None
1315
+ task_cue_info = None
1316
+ elif args.env_id in ["TakeItBack-v0"]:
1317
+ wrappers_list = [
1318
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1319
+ (RenderStepInfoWrapper, {}),
1320
+ (RenderRewardInfoWrapper, {}),
1321
+ (DebugRewardWrapper, {}),
1322
+ ]
1323
+ oracle_info = None
1324
+ task_cue_info = None
1325
+ elif args.env_id in ["RememberColor3-v0", "RememberColor5-v0", "RememberColor9-v0"]:
1326
+ wrappers_list = [
1327
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1328
+ (RememberColorInfoWrapper, {}),
1329
+ (RenderStepInfoWrapper, {}),
1330
+ (RenderRewardInfoWrapper, {}),
1331
+ (DebugRewardWrapper, {}),
1332
+ ]
1333
+ oracle_info = None
1334
+ task_cue_info = None
1335
+ elif args.env_id in ["RememberShape3-v0", "RememberShape5-v0", "RememberShape9-v0"]:
1336
+ wrappers_list = [
1337
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1338
+ (RememberShapeInfoWrapper, {}),
1339
+ (RenderStepInfoWrapper, {}),
1340
+ (RenderRewardInfoWrapper, {}),
1341
+ (DebugRewardWrapper, {}),
1342
+ ]
1343
+ oracle_info = None
1344
+ task_cue_info = None
1345
+ elif args.env_id in ["RememberShapeAndColor3x2-v0", "RememberShapeAndColor3x3-v0", "RememberShapeAndColor5x3-v0"]:
1346
+ wrappers_list = [
1347
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1348
+ (RememberShapeAndColorInfoWrapper, {}),
1349
+ (RenderStepInfoWrapper, {}),
1350
+ (RenderRewardInfoWrapper, {}),
1351
+ (DebugRewardWrapper, {}),
1352
+ ]
1353
+ oracle_info = None
1354
+ task_cue_info = None
1355
+ elif args.env_id in ["BunchOfColors3-v0", "BunchOfColors5-v0", "BunchOfColors7-v0"]:
1356
+ wrappers_list = [
1357
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1358
+ (MemoryCapacityInfoWrapper, {}),
1359
+ (RenderStepInfoWrapper, {}),
1360
+ (RenderRewardInfoWrapper, {}),
1361
+ (DebugRewardWrapper, {}),
1362
+ ]
1363
+ oracle_info = None
1364
+ task_cue_info = None
1365
+ elif args.env_id in ["SeqOfColors3-v0", "SeqOfColors5-v0", "SeqOfColors7-v0"]:
1366
+ wrappers_list = [
1367
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1368
+ (MemoryCapacityInfoWrapper, {}),
1369
+ (RenderStepInfoWrapper, {}),
1370
+ (RenderRewardInfoWrapper, {}),
1371
+ (DebugRewardWrapper, {}),
1372
+ ]
1373
+ oracle_info = None
1374
+ task_cue_info = None
1375
+ elif args.env_id in ["ChainOfColors3-v0", "ChainOfColors5-v0", "ChainOfColors7-v0"]:
1376
+ wrappers_list = [
1377
+ (InitialZeroActionWrapper, {"n_initial_steps": args.noop_steps - 1}),
1378
+ (MemoryCapacityInfoWrapper, {}),
1379
+ (RenderStepInfoWrapper, {}),
1380
+ (RenderRewardInfoWrapper, {}),
1381
+ (DebugRewardWrapper, {}),
1382
+ ]
1383
+ oracle_info = None
1384
+ task_cue_info = None
1385
+
1386
+ # ******* NEW *******
1387
+ elif args.env_id in ["RememberColor3-VLA-v0", "RememberColor5-VLA-v0", "RememberColor9-VLA-v0"]:
1388
+ wrappers_list = [
1389
+ (CurriculumPhaseNoopActionWrapper, {}),
1390
+ (RememberColorInfoWrapper, {}),
1391
+ (RenderStepInfoWrapper, {}),
1392
+ (RenderRewardInfoWrapper, {}),
1393
+ (DebugRewardWrapper, {}),
1394
+ ]
1395
+ oracle_info = None
1396
+ task_cue_info = None
1397
+ elif args.env_id in ["RememberShape3-VLA-v0", "RememberShape5-VLA-v0", "RememberShape9-VLA-v0"]:
1398
+ wrappers_list = [
1399
+ (CurriculumPhaseNoopActionWrapper, {}),
1400
+ (RememberShapeInfoWrapper, {}),
1401
+ (RenderStepInfoWrapper, {}),
1402
+ (RenderRewardInfoWrapper, {}),
1403
+ (DebugRewardWrapper, {}),
1404
+ ]
1405
+ oracle_info = None
1406
+ task_cue_info = None
1407
+ elif args.env_id in [
1408
+ "RememberShapeAndColor3x2-VLA-v0",
1409
+ "RememberShapeAndColor3x3-VLA-v0",
1410
+ "RememberShapeAndColor5x3-VLA-v0",
1411
+ ]:
1412
+ wrappers_list = [
1413
+ (CurriculumPhaseNoopActionWrapper, {}),
1414
+ (RememberShapeAndColorInfoWrapper, {}),
1415
+ (RenderStepInfoWrapper, {}),
1416
+ (RenderRewardInfoWrapper, {}),
1417
+ (DebugRewardWrapper, {}),
1418
+ ]
1419
+ oracle_info = None
1420
+ task_cue_info = None
1421
+ elif args.env_id in ["ShellGameShuffleTouch-VLA-v0"]:
1422
+ wrappers_list = [
1423
+ (CurriculumPhaseNoopActionWrapper, {}),
1424
+ (RenderStepInfoWrapper, {}),
1425
+ (ShellGameRenderCupInfoWrapper, {}),
1426
+ (RenderRewardInfoWrapper, {}),
1427
+ (DebugRewardWrapper, {}),
1428
+ ]
1429
+ oracle_info = "cup_with_ball_number"
1430
+ task_cue_info = None
1431
+ elif args.env_id in ["BlinkCountButtonPress-VLA-v0"]:
1432
+ wrappers_list = [
1433
+ (CurriculumPhaseNoopActionWrapper, {}),
1434
+ (RenderPressProgressInfoWrapper, {}),
1435
+ (RenderStepInfoWrapper, {}),
1436
+ (RenderRewardInfoWrapper, {}),
1437
+ (DebugRewardWrapper, {}),
1438
+ ]
1439
+ oracle_info = "target_blinks"
1440
+ task_cue_info = None
1441
+ elif args.env_id in ["ShellGameTouch-VLA-v0", "ShellGamePick-VLA-v0", "ShellGamePush-VLA-v0"]:
1442
+ wrappers_list = [
1443
+ (CurriculumPhaseNoopActionWrapper, {}),
1444
+ (RenderStepInfoWrapper, {}),
1445
+ (ShellGameRenderCupInfoWrapper, {}),
1446
+ (RenderRewardInfoWrapper, {}),
1447
+ (DebugRewardWrapper, {}),
1448
+ ]
1449
+ oracle_info = "cup_with_ball_number"
1450
+ task_cue_info = None
1451
+ elif args.env_id in ["ShellGameShuffleColorLampTouch-VLA-v0", "ShellGameColorLampTouch-VLA-v0"]:
1452
+ wrappers_list = [
1453
+ (CurriculumPhaseNoopActionWrapper, {}),
1454
+ (RenderStepInfoWrapper, {}),
1455
+ (ShellGameRenderCupInfoWrapper, {}),
1456
+ (RenderRewardInfoWrapper, {}),
1457
+ (DebugRewardWrapper, {}),
1458
+ ]
1459
+ oracle_info = "oracle_info"
1460
+ task_cue_info = "task_cue"
1461
+ elif args.env_id in [
1462
+ "InterceptSlow-VLA-v0",
1463
+ "InterceptMedium-VLA-v0",
1464
+ "InterceptFast-VLA-v0",
1465
+ "InterceptGrabSlow-VLA-v0",
1466
+ "InterceptGrabMedium-VLA-v0",
1467
+ "InterceptGrabFast-VLA-v0",
1468
+ ]:
1469
+ wrappers_list = [
1470
+ (RenderStepInfoWrapper, {}),
1471
+ (RenderRewardInfoWrapper, {}),
1472
+ (DebugRewardWrapper, {}),
1473
+ ]
1474
+ oracle_info = None
1475
+ task_cue_info = None
1476
+ elif args.env_id in [
1477
+ "RotateLenientPos-VLA-v0",
1478
+ "RotateLenientPosNeg-VLA-v0",
1479
+ "RotateStrictPos-VLA-v0",
1480
+ "RotateStrictPosNeg-VLA-v0",
1481
+ ]:
1482
+ wrappers_list = [
1483
+ (RenderStepInfoWrapper, {}),
1484
+ (RenderRewardInfoWrapper, {}),
1485
+ (RotateRenderAngleInfoWrapper, {}),
1486
+ (DebugRewardWrapper, {}),
1487
+ ]
1488
+ oracle_info = "angle_diff"
1489
+ task_cue_info = "target_angle"
1490
+ elif args.env_id in ["TakeItBack-VLA-v0"]:
1491
+ wrappers_list = [
1492
+ (RenderStepInfoWrapper, {}),
1493
+ (RenderRewardInfoWrapper, {}),
1494
+ (DebugRewardWrapper, {}),
1495
+ ]
1496
+ oracle_info = None
1497
+ task_cue_info = None
1498
+ elif args.env_id in [
1499
+ "SeqOfColors3-VLA-v0",
1500
+ "SeqOfColors5-VLA-v0",
1501
+ "SeqOfColors7-VLA-v0",
1502
+ "ChainOfColors3-VLA-v0",
1503
+ "ChainOfColors5-VLA-v0",
1504
+ "ChainOfColors7-VLA-v0",
1505
+ "BunchOfColors3-VLA-v0",
1506
+ "BunchOfColors5-VLA-v0",
1507
+ "BunchOfColors7-VLA-v0",
1508
+ ]:
1509
+ wrappers_list = [
1510
+ (CurriculumPhaseNoopActionWrapper, {}),
1511
+ (MemoryCapacityInfoWrapper, {}),
1512
+ (RenderStepInfoWrapper, {}),
1513
+ (RenderRewardInfoWrapper, {}),
1514
+ (DebugRewardWrapper, {}),
1515
+ ]
1516
+ oracle_info = None
1517
+ task_cue_info = None
1518
+ else:
1519
+ raise ValueError(f"Unknown environment: {args.env_id}")
1520
+
1521
+ print("\n" + "=" * 75)
1522
+ print("║" + " " * 24 + "Environment Configuration" + " " * 24 + "║")
1523
+ print("=" * 75)
1524
+ print("║" + f" Environment ID: {args.env_id}".ljust(73) + "║")
1525
+ print("║" + f" Oracle Info: {oracle_info}".ljust(73) + "║")
1526
+ print("║ Wrappers:".ljust(74) + "║")
1527
+ for wrapper, kwargs in wrappers_list:
1528
+ print("║ ├─ " + wrapper.__name__.ljust(65) + "║")
1529
+ if kwargs:
1530
+ print("║ │ └─ " + str(kwargs).ljust(65) + "║")
1531
+ print("║" + "-" * 73 + "║")
1532
+
1533
+ state_msg = "state will be used" if args.include_state else "state will not be used"
1534
+ print("║" + f" include_state: {str(args.include_state):<5} │ {state_msg}".ljust(68) + "║")
1535
+
1536
+ rgb_msg = "rgb images will be used" if args.include_rgb else "rgb images will not be used"
1537
+ print("║" + f" include_rgb: {str(args.include_rgb):<5} │ {rgb_msg}".ljust(68) + "║")
1538
+
1539
+ oracle_msg = "oracle info will be used" if args.include_oracle else "oracle info will not be used"
1540
+ print("║" + f" include_oracle: {str(args.include_oracle):<5} │ {oracle_msg}".ljust(68) + "║")
1541
+
1542
+ joints_msg = "joints will be used" if args.include_joints else "joints will not be used"
1543
+ print("║" + f" include_joints: {str(args.include_joints):<5} │ {joints_msg}".ljust(68) + "║")
1544
+ print("=" * 75 + "\n")
1545
+
1546
+ assert any([args.include_state, args.include_rgb]), "At least one of include_state or include_rgb must be True."
1547
+ assert not (args.include_joints and not args.include_rgb), (
1548
+ "include_joints can only be True when include_rgb is True"
1549
+ )
1550
+
1551
+ if args.include_state and not args.include_rgb and not args.include_oracle and not args.include_joints:
1552
+ MODE = "state"
1553
+ elif args.include_state and args.include_rgb and not args.include_oracle and not args.include_joints:
1554
+ raise NotImplementedError(
1555
+ "state_rgb is not implemented and does not make sense, since any environment can be solved only by using state"
1556
+ )
1557
+ MODE = "state_rgb"
1558
+ elif args.include_state and not args.include_rgb and args.include_oracle and not args.include_joints:
1559
+ raise NotImplementedError(
1560
+ "state_oracle is not implemented and does not make sense, since the state already contains oracle information"
1561
+ )
1562
+ MODE = "state_oracle"
1563
+ elif args.include_state and args.include_rgb and args.include_oracle and not args.include_joints:
1564
+ raise NotImplementedError(
1565
+ "state_rgb_oracle is not implemented and does not make sense, since any environment can be solved only by using state"
1566
+ )
1567
+ MODE = "state_rgb_oracle"
1568
+ elif not args.include_state and args.include_rgb and not args.include_oracle and not args.include_joints:
1569
+ MODE = "rgb"
1570
+ elif not args.include_state and args.include_rgb and args.include_oracle and not args.include_joints:
1571
+ MODE = "rgb_oracle"
1572
+ elif not args.include_state and args.include_rgb and args.include_joints and args.include_oracle:
1573
+ MODE = "rgb_joints_oracle" # TODO: check if this is correct
1574
+ elif not args.include_state and args.include_rgb and args.include_joints and not args.include_oracle:
1575
+ MODE = "rgb_joints"
1576
+ else:
1577
+ raise NotImplementedError(
1578
+ f"Unknown mode: {args.include_state=} {args.include_rgb=} {args.include_oracle=} {args.include_joints=}"
1579
+ )
1580
+
1581
+ SAVE_DIR = f"oracle_checkpoints/ppo_memtasks/{MODE}/{args.reward_mode}/{args.env_id}"
1582
+
1583
+ print(f"{MODE=}")
1584
+ print(f"{task_cue_info=}")
1585
+
1586
+ wrappers_list.insert(
1587
+ 0, (StateOnlyTensorToDictWrapper, {})
1588
+ ) # obs=torch.tensor -> dict with keys: state: obs, task_cue: task_cue, oracle_info: oracle_info
1589
+
1590
+ if args.exp_name is None:
1591
+ args.exp_name = os.path.basename(__file__)[: -len(".py")]
1592
+ run_name = f"{args.env_id}__{args.exp_name}__{args.seed}__{MODE}__{TIME}"
1593
+ else:
1594
+ # run_name = args.exp_name
1595
+ run_name = f"{args.exp_name}__{args.seed}__{MODE}__{TIME}"
1596
+
1597
+ # TRY NOT TO MODIFY: seeding
1598
+ random.seed(args.seed)
1599
+ np.random.seed(args.seed)
1600
+ torch.manual_seed(args.seed)
1601
+ torch.backends.cudnn.deterministic = args.torch_deterministic
1602
+
1603
+ device = torch.device("cuda" if torch.cuda.is_available() and args.cuda else "cpu")
1604
+
1605
+ # env setup
1606
+ if MODE not in ["state", "state_oracle"]:
1607
+ env_kwargs = dict(
1608
+ obs_mode="rgb",
1609
+ control_mode="pd_ee_delta_pose",
1610
+ render_mode=args.render_mode,
1611
+ sim_backend="gpu",
1612
+ reward_mode=args.reward_mode,
1613
+ )
1614
+ else:
1615
+ env_kwargs = dict(
1616
+ obs_mode="state",
1617
+ control_mode="pd_ee_delta_pose",
1618
+ render_mode=args.render_mode,
1619
+ sim_backend="gpu",
1620
+ reward_mode=args.reward_mode,
1621
+ ) # render_mode="rgb_array",
1622
+
1623
+ eval_envs = gym.make(
1624
+ args.env_id, num_envs=args.num_eval_envs, reconfiguration_freq=args.eval_reconfiguration_freq, **env_kwargs
1625
+ ) # , reconfigure_freq=args.eval_reconfiguration_freq
1626
+ envs = gym.make(
1627
+ args.env_id,
1628
+ num_envs=args.num_envs if not args.evaluate else 1,
1629
+ reconfiguration_freq=args.reconfiguration_freq,
1630
+ **env_kwargs,
1631
+ )
1632
+
1633
+ for wrapper_class, wrapper_kwargs in wrappers_list:
1634
+ eval_envs = wrapper_class(eval_envs, **wrapper_kwargs)
1635
+ envs = wrapper_class(envs, **wrapper_kwargs)
1636
+
1637
+ envs = FlattenRGBDObservationWrapper(
1638
+ envs,
1639
+ rgb=args.include_rgb,
1640
+ depth=False,
1641
+ state=args.include_state,
1642
+ oracle=args.include_oracle,
1643
+ joints=args.include_joints,
1644
+ )
1645
+ eval_envs = FlattenRGBDObservationWrapper(
1646
+ eval_envs,
1647
+ rgb=args.include_rgb,
1648
+ depth=False,
1649
+ state=args.include_state,
1650
+ oracle=args.include_oracle,
1651
+ joints=args.include_joints,
1652
+ )
1653
+
1654
+ if isinstance(envs.action_space, gym.spaces.Dict):
1655
+ envs = FlattenActionSpaceWrapper(envs)
1656
+ eval_envs = FlattenActionSpaceWrapper(eval_envs)
1657
+ if args.capture_video:
1658
+ eval_output_dir = f"{SAVE_DIR}/{run_name}/{TIME}/videos"
1659
+ if args.evaluate:
1660
+ eval_output_dir = f"{os.path.dirname(args.checkpoint)}/test_videos"
1661
+ print(f"Saving eval videos to {eval_output_dir}")
1662
+ if args.save_train_video_freq is not None:
1663
+ def save_video_trigger(x):
1664
+ return (x // args.num_steps) % args.save_train_video_freq == 0
1665
+ envs = RecordEpisode(
1666
+ envs,
1667
+ output_dir=f"{SAVE_DIR}/{run_name}/{TIME}/train_videos",
1668
+ save_trajectory=False,
1669
+ save_video_trigger=save_video_trigger,
1670
+ max_steps_per_video=args.num_steps,
1671
+ video_fps=30,
1672
+ )
1673
+ eval_envs = RecordEpisode(
1674
+ eval_envs,
1675
+ output_dir=eval_output_dir,
1676
+ save_trajectory=args.evaluate,
1677
+ trajectory_name="trajectory",
1678
+ max_steps_per_video=args.num_eval_steps,
1679
+ video_fps=30,
1680
+ )
1681
+ envs = ManiSkillVectorEnv(envs, args.num_envs, ignore_terminations=not args.partial_reset, record_metrics=True)
1682
+ eval_envs = ManiSkillVectorEnv(
1683
+ eval_envs, args.num_eval_envs, ignore_terminations=not args.eval_partial_reset, record_metrics=True
1684
+ )
1685
+ if args.latency_config is not None:
1686
+ # latency_bench is optional for the standalone upstream trainer.
1687
+ from training.common.checkpoints import atomic_torch_save, capture_rng_state, restore_rng_state
1688
+ from training.common.action_latency import TorchActionLatencyWrapper
1689
+
1690
+ envs = TorchActionLatencyWrapper(
1691
+ envs, latency_config, num_envs=args.num_envs, device=device,
1692
+ noop_command=latency_config["env"]["noop_action"],
1693
+ )
1694
+ eval_envs = TorchActionLatencyWrapper(
1695
+ eval_envs, latency_config, num_envs=args.num_eval_envs, device=device,
1696
+ noop_command=latency_config["env"]["noop_action"],
1697
+ )
1698
+ assert isinstance(envs.single_action_space, gym.spaces.Box), "only continuous action space is supported"
1699
+
1700
+ max_episode_steps = gym_utils.find_max_episode_steps_value(envs._env)
1701
+ print("=" * 70)
1702
+ print(f"Max Episode Steps: {max_episode_steps}")
1703
+ print("=" * 70 + "\n")
1704
+ logger = None
1705
+ if not args.evaluate:
1706
+ print("Running training")
1707
+ if args.track:
1708
+ import wandb
1709
+
1710
+ config = asdict(args)
1711
+ if args.latency_config is not None:
1712
+ config["latency_config_resolved"] = latency_config
1713
+ if latency_config["latency"]["method"] in ("iid", "temporal"):
1714
+ with open(latency_config["latency"]["profile_path"]) as stream:
1715
+ config["latency_profile"] = json.load(stream)
1716
+ config["env_cfg"] = dict(
1717
+ **env_kwargs,
1718
+ num_envs=args.num_envs,
1719
+ env_id=args.env_id,
1720
+ env_horizon=max_episode_steps,
1721
+ partial_reset=args.partial_reset,
1722
+ )
1723
+ config["eval_env_cfg"] = dict(
1724
+ **env_kwargs,
1725
+ num_envs=args.num_eval_envs,
1726
+ env_id=args.env_id,
1727
+ env_horizon=max_episode_steps,
1728
+ partial_reset=args.partial_reset,
1729
+ )
1730
+ wandb.init(
1731
+ project=args.wandb_project_name,
1732
+ entity=args.wandb_entity,
1733
+ sync_tensorboard=False,
1734
+ config=config,
1735
+ name=run_name,
1736
+ save_code=True,
1737
+ group="PPO",
1738
+ tags=["ppo", "walltime_efficient"],
1739
+ )
1740
+ writer = SummaryWriter(f"{SAVE_DIR}/{run_name}/{TIME}")
1741
+ writer.add_text(
1742
+ "hyperparameters",
1743
+ "|param|value|\n|-|-|\n%s" % ("\n".join([f"|{key}|{value}|" for key, value in vars(args).items()])),
1744
+ )
1745
+ logger = Logger(log_wandb=args.track, tensorboard=writer)
1746
+ else:
1747
+ print("Running evaluation")
1748
+
1749
+ # ALGO Logic: Storage setup
1750
+ obs = DictArray((args.num_steps, args.num_envs), envs.single_observation_space, device=device)
1751
+ actions = torch.zeros((args.num_steps, args.num_envs) + envs.single_action_space.shape).to(device)
1752
+ logprobs = torch.zeros((args.num_steps, args.num_envs)).to(device)
1753
+ command_admitted = torch.ones((args.num_steps, args.num_envs), dtype=torch.bool, device=device)
1754
+ rewards = torch.zeros((args.num_steps, args.num_envs)).to(device)
1755
+ dones = torch.zeros((args.num_steps, args.num_envs)).to(device)
1756
+ values = torch.zeros((args.num_steps, args.num_envs)).to(device)
1757
+
1758
+ # TRY NOT TO MODIFY: start the game
1759
+ global_step = 0
1760
+ start_time = time.time()
1761
+ next_obs, _ = envs.reset(seed=args.seed)
1762
+ eval_obs, _ = eval_envs.reset(seed=args.seed)
1763
+ next_done = torch.zeros(args.num_envs, device=device)
1764
+ eps_returns = torch.zeros(args.num_envs, dtype=torch.float, device=device)
1765
+ print("\n####")
1766
+ print(
1767
+ f"args.num_iterations={args.num_iterations} args.num_envs={args.num_envs} args.num_eval_envs={args.num_eval_envs}"
1768
+ )
1769
+ print(
1770
+ f"args.minibatch_size={args.minibatch_size} args.batch_size={args.batch_size} args.update_epochs={args.update_epochs}"
1771
+ )
1772
+ print("####\n")
1773
+
1774
+ if MODE not in ["state", "state_oracle"]:
1775
+ agent = Agent(envs, sample_obs=next_obs).to(device)
1776
+ else:
1777
+ agent = AgentStateOnly(envs).to(device)
1778
+
1779
+ optimizer = optim.Adam(agent.parameters(), lr=args.learning_rate, eps=1e-5)
1780
+
1781
+ if args.checkpoint:
1782
+ agent.load_state_dict(torch.load(args.checkpoint))
1783
+
1784
+ start_iteration = 1
1785
+ best_success_at_end = -1.0
1786
+ if args.resume is not None:
1787
+ saved = torch.load(args.resume, map_location=device, weights_only=False)
1788
+ agent.load_state_dict(saved["policy"])
1789
+ optimizer.load_state_dict(saved["optimizer"])
1790
+ global_step = saved["global_step"]
1791
+ start_iteration = saved["iteration"] + 1
1792
+ best_success_at_end = saved["best_success_at_end"]
1793
+ envs.latency.load_state_dict(saved["latency"])
1794
+ restore_rng_state(saved)
1795
+
1796
+ def save_latency_checkpoint(completed_iteration):
1797
+ if args.latency_config is None:
1798
+ return
1799
+ os.makedirs(args.latency_output_dir, exist_ok=True)
1800
+ checkpoint = {
1801
+ "policy": agent.state_dict(), "optimizer": optimizer.state_dict(),
1802
+ "iteration": completed_iteration, "global_step": global_step,
1803
+ "best_success_at_end": best_success_at_end,
1804
+ "latency": envs.latency.state_dict(), "config": latency_config,
1805
+ "args": asdict(args),
1806
+ **capture_rng_state(),
1807
+ }
1808
+ # The resume bundle is authoritative; each completed file is replaced
1809
+ # atomically so a failed write cannot truncate the preceding checkpoint.
1810
+ for filename, payload in (("training.pt", checkpoint), ("teacher.pt", checkpoint["policy"])):
1811
+ path = os.path.join(args.latency_output_dir, filename)
1812
+ atomic_torch_save(payload, path)
1813
+
1814
+ delayed_early_stop_env_ids = {
1815
+ "RememberColor3-VLA-v0",
1816
+ "RememberColor5-VLA-v0",
1817
+ "RememberColor9-VLA-v0",
1818
+ "RememberShape3-VLA-v0",
1819
+ "RememberShape5-VLA-v0",
1820
+ "RememberShape9-VLA-v0",
1821
+ "RememberShapeAndColor3x2-VLA-v0",
1822
+ "RememberShapeAndColor3x3-VLA-v0",
1823
+ "RememberShapeAndColor5x3-VLA-v0",
1824
+ "SeqOfColors3-VLA-v0",
1825
+ "SeqOfColors5-VLA-v0",
1826
+ "SeqOfColors7-VLA-v0",
1827
+ "ChainOfColors3-VLA-v0",
1828
+ "ChainOfColors5-VLA-v0",
1829
+ "ChainOfColors7-VLA-v0",
1830
+ "BunchOfColors3-VLA-v0",
1831
+ "BunchOfColors5-VLA-v0",
1832
+ "BunchOfColors7-VLA-v0",
1833
+ "ShellGameShuffleTouch-VLA-v0",
1834
+ "BlinkCountButtonPress-VLA-v0",
1835
+ "InterceptSlow-VLA-v0",
1836
+ "InterceptMedium-VLA-v0",
1837
+ "InterceptFast-VLA-v0",
1838
+ "InterceptGrabSlow-VLA-v0",
1839
+ "InterceptGrabMedium-VLA-v0",
1840
+ # "InterceptGrabFast-VLA-v0",
1841
+ }
1842
+ post_threshold_evals_remaining = None
1843
+
1844
+ for iteration in tqdm(range(start_iteration, args.num_iterations + 1), total=args.num_iterations, desc="Training"):
1845
+ print(f"Epoch: {iteration}, global_step={global_step}")
1846
+ final_values = torch.zeros((args.num_steps, args.num_envs), device=device)
1847
+ agent.eval()
1848
+ if (iteration - 1) % args.eval_freq == 0:
1849
+ print("Evaluating")
1850
+ if args.save_model and not args.evaluate:
1851
+ torch.save(
1852
+ agent.state_dict(),
1853
+ f"{SAVE_DIR}/{run_name}/{TIME}/ckpt_{iteration - 1}.pt",
1854
+ )
1855
+ eval_obs, _ = eval_envs.reset()
1856
+ eval_metrics = defaultdict(list)
1857
+ num_episodes = 0
1858
+ eval_start = time.perf_counter()
1859
+ admitted_count = dropped_count = 0
1860
+ for _ in range(args.num_eval_steps):
1861
+ with torch.no_grad():
1862
+ eval_obs, eval_rew, eval_terminations, eval_truncations, eval_infos = eval_envs.step(
1863
+ agent.get_action(eval_obs, deterministic=True)
1864
+ )
1865
+ if args.latency_config is not None:
1866
+ admitted_count += eval_infos["command_admitted"].sum().item()
1867
+ dropped_count += eval_infos["command_dropped"].sum().item()
1868
+ if "final_info" in eval_infos:
1869
+ mask = eval_infos["_final_info"]
1870
+ num_episodes += mask.sum()
1871
+ for k, v in eval_infos["final_info"]["episode"].items():
1872
+ eval_metrics[k].append(v)
1873
+ print(f"Evaluated {args.num_eval_steps * args.num_eval_envs} steps resulting in {num_episodes} episodes")
1874
+ if args.latency_config is not None and not args.evaluate:
1875
+ logger.add_scalar("eval/admitted_commands", admitted_count, global_step)
1876
+ logger.add_scalar("eval/dropped_commands", dropped_count, global_step)
1877
+ score = torch.cat(eval_metrics["success_at_end"]).float().mean().item()
1878
+ if score > best_success_at_end:
1879
+ best_success_at_end = score
1880
+ os.makedirs(args.latency_output_dir, exist_ok=True)
1881
+ atomic_torch_save(agent.state_dict(), os.path.join(args.latency_output_dir, "best_policy.pt"))
1882
+ with open(os.path.join(args.latency_output_dir, "best_evaluation.json"), "w") as stream:
1883
+ json.dump({
1884
+ "global_step": global_step,
1885
+ "checkpoint_iteration": iteration - 1,
1886
+ "episodes": num_episodes.item(),
1887
+ "metrics": {k: torch.cat(v).float().mean().item() for k, v in eval_metrics.items()},
1888
+ }, stream, indent=2)
1889
+ logger.add_scalar("eval/best_success_at_end", best_success_at_end, global_step)
1890
+ for k, v in eval_metrics.items():
1891
+ mean = torch.stack(v).float().mean()
1892
+ if logger is not None:
1893
+ logger.add_scalar(f"eval/{k}", mean, global_step)
1894
+ print(
1895
+ f"{Fore.GREEN}Evaluation Metric: {k}{Style.RESET_ALL} | {Fore.CYAN}Mean: {mean:.4f}{Style.RESET_ALL}"
1896
+ )
1897
+
1898
+ # !!!!!!!!!!!!!!!!
1899
+
1900
+ # Check if success_once reached threshold and stop training.
1901
+ if k == "success_once" and args.latency_config is None:
1902
+ should_stop = False
1903
+ stop_message = None
1904
+
1905
+ if args.env_id in delayed_early_stop_env_ids:
1906
+ if post_threshold_evals_remaining is None and mean >= success_once_threshold:
1907
+ post_threshold_evals_remaining = 3
1908
+ print(
1909
+ f"\n{Fore.GREEN}Success rate threshold reached for {args.env_id}. "
1910
+ f"Continuing training for {post_threshold_evals_remaining} "
1911
+ f"more validation cycles before stopping.{Style.RESET_ALL}"
1912
+ )
1913
+ elif post_threshold_evals_remaining is not None:
1914
+ post_threshold_evals_remaining -= 1
1915
+ if post_threshold_evals_remaining > 0:
1916
+ print(
1917
+ f"{Fore.YELLOW}Post-threshold validation cycles remaining: "
1918
+ f"{post_threshold_evals_remaining}{Style.RESET_ALL}"
1919
+ )
1920
+ else:
1921
+ should_stop = True
1922
+ stop_message = (
1923
+ f"\n{Fore.GREEN}Completed 3 extra validation cycles after threshold for "
1924
+ f"{args.env_id}. Stopping training...{Style.RESET_ALL}"
1925
+ )
1926
+ elif mean >= success_once_threshold:
1927
+ should_stop = True
1928
+ stop_message = (
1929
+ f"\n{Fore.GREEN}Success rate threshold reached! Stopping training...{Style.RESET_ALL}"
1930
+ )
1931
+
1932
+ if should_stop:
1933
+ print(stop_message)
1934
+ save_latency_checkpoint(iteration - 1)
1935
+ # Save final checkpoint
1936
+ if args.save_model:
1937
+ model_path = f"{SAVE_DIR}/{run_name}/{TIME}/final_success_ckpt.pt"
1938
+ torch.save(agent.state_dict(), model_path)
1939
+ print(f"Final successful model saved to {model_path}")
1940
+ if logger is not None:
1941
+ logger.close()
1942
+ # Add explicit cleanup
1943
+ envs.close()
1944
+ eval_envs.close()
1945
+ sys.exit(0) # Exit the script with success status
1946
+
1947
+ # !!!!!!!!!!!!!!!!
1948
+
1949
+ if args.evaluate:
1950
+ if args.latency_config is not None:
1951
+ elapsed = time.perf_counter() - eval_start
1952
+ os.makedirs(args.latency_output_dir, exist_ok=True)
1953
+ with open(os.path.join(args.latency_output_dir, "evaluation.json"), "w") as f:
1954
+ json.dump({
1955
+ "checkpoint": args.checkpoint,
1956
+ "config": latency_config,
1957
+ "episodes": num_episodes.item(),
1958
+ "metrics": {k: torch.stack(v).float().mean().item() for k, v in eval_metrics.items()},
1959
+ "admitted_count": admitted_count,
1960
+ "dropped_count": dropped_count,
1961
+ "elapsed_seconds": elapsed,
1962
+ "raw_frames_per_second": args.num_eval_steps * args.num_eval_envs / elapsed,
1963
+ }, f, indent=2)
1964
+ break
1965
+
1966
+ # Annealing the rate if instructed to do so.
1967
+ if args.anneal_lr:
1968
+ frac = 1.0 - (iteration - 1.0) / args.num_iterations
1969
+ lrnow = frac * args.learning_rate
1970
+ optimizer.param_groups[0]["lr"] = lrnow
1971
+
1972
+ rollout_time = time.time()
1973
+ for step in range(0, args.num_steps):
1974
+ global_step += args.num_envs
1975
+ obs[step] = next_obs
1976
+ dones[step] = next_done
1977
+
1978
+ # ALGO LOGIC: action logic
1979
+ with torch.no_grad():
1980
+ action, logprob, _, value = agent.get_action_and_value(next_obs)
1981
+ values[step] = value.flatten()
1982
+ actions[step] = action
1983
+ logprobs[step] = logprob
1984
+
1985
+ # TRY NOT TO MODIFY: execute the game and log data.
1986
+ next_obs, reward, terminations, truncations, infos = envs.step(action)
1987
+ if args.latency_config is not None:
1988
+ command_admitted[step] = infos["command_admitted"]
1989
+ next_done = torch.logical_or(terminations, truncations).to(torch.float32)
1990
+ rewards[step] = reward.view(-1) * args.reward_scale
1991
+
1992
+ if "final_info" in infos:
1993
+ final_info = infos["final_info"]
1994
+ done_mask = infos["_final_info"]
1995
+ for k, v in final_info["episode"].items():
1996
+ logger.add_scalar(f"train/{k}", v[done_mask].float().mean(), global_step)
1997
+ for k in infos["final_observation"]:
1998
+ infos["final_observation"][k] = infos["final_observation"][k][done_mask]
1999
+ with torch.no_grad():
2000
+ final_values[step, torch.arange(args.num_envs, device=device)[done_mask]] = agent.get_value(
2001
+ infos["final_observation"]
2002
+ ).view(-1)
2003
+ rollout_time = time.time() - rollout_time
2004
+
2005
+ # bootstrap value according to termination and truncation
2006
+ with torch.no_grad():
2007
+ next_value = agent.get_value(next_obs).reshape(1, -1)
2008
+ advantages = torch.zeros_like(rewards).to(device)
2009
+ lastgaelam = 0
2010
+ for t in reversed(range(args.num_steps)):
2011
+ if t == args.num_steps - 1:
2012
+ next_not_done = 1.0 - next_done
2013
+ nextvalues = next_value
2014
+ else:
2015
+ next_not_done = 1.0 - dones[t + 1]
2016
+ nextvalues = values[t + 1]
2017
+ real_next_values = next_not_done * nextvalues + final_values[t]
2018
+
2019
+ if args.finite_horizon_gae:
2020
+ """
2021
+ See GAE paper equation(16) line 1, we will compute the GAE based on this line only
2022
+ 1 *( -V(s_t) + r_t + gamma * V(s_{t+1}) )
2023
+ lambda *( -V(s_t) + r_t + gamma * r_{t+1} + gamma^2 * V(s_{t+2}) )
2024
+ lambda^2 *( -V(s_t) + r_t + gamma * r_{t+1} + gamma^2 * r_{t+2} + ... )
2025
+ lambda^3 *( -V(s_t) + r_t + gamma * r_{t+1} + gamma^2 * r_{t+2} + gamma^3 * r_{t+3}
2026
+ We then normalize it by the sum of the lambda^i (instead of 1-lambda)
2027
+ """
2028
+ if t == args.num_steps - 1: # initialize
2029
+ lam_coef_sum = 0.0
2030
+ reward_term_sum = 0.0 # the sum of the second term
2031
+ value_term_sum = 0.0 # the sum of the third term
2032
+ lam_coef_sum = lam_coef_sum * next_not_done
2033
+ reward_term_sum = reward_term_sum * next_not_done
2034
+ value_term_sum = value_term_sum * next_not_done
2035
+
2036
+ lam_coef_sum = 1 + args.gae_lambda * lam_coef_sum
2037
+ reward_term_sum = args.gae_lambda * args.gamma * reward_term_sum + lam_coef_sum * rewards[t]
2038
+ value_term_sum = args.gae_lambda * args.gamma * value_term_sum + args.gamma * real_next_values
2039
+
2040
+ advantages[t] = (reward_term_sum + value_term_sum) / lam_coef_sum - values[t]
2041
+ else:
2042
+ delta = rewards[t] + args.gamma * real_next_values - values[t]
2043
+ advantages[t] = lastgaelam = (
2044
+ delta + args.gamma * args.gae_lambda * next_not_done * lastgaelam
2045
+ ) # Here actually we should use next_not_terminated, but we don't have lastgamlam if terminated
2046
+ returns = advantages + values
2047
+
2048
+ # flatten the batch
2049
+ b_obs = obs.reshape((-1,))
2050
+ b_logprobs = logprobs.reshape(-1)
2051
+ b_actions = actions.reshape((-1,) + envs.single_action_space.shape)
2052
+ b_advantages = advantages.reshape(-1)
2053
+ b_returns = returns.reshape(-1)
2054
+ b_values = values.reshape(-1)
2055
+
2056
+ # Optimizing the policy and value network
2057
+ b_admitted = command_admitted.flatten()
2058
+ b_inds = np.arange(args.batch_size)
2059
+ logger.add_scalar("charts/admitted_commands", b_admitted.sum().item(), global_step)
2060
+ logger.add_scalar("charts/admission_rate", b_admitted.float().mean().item(), global_step)
2061
+ agent.train()
2062
+ actor_updates = 0
2063
+ update_time = time.time()
2064
+ for epoch in range(args.update_epochs):
2065
+ np.random.shuffle(b_inds)
2066
+ for start in range(0, len(b_inds), args.minibatch_size):
2067
+ end = start + args.minibatch_size
2068
+ mb_inds = b_inds[start:end]
2069
+
2070
+ _, newlogprob, entropy, newvalue = agent.get_action_and_value(b_obs[mb_inds], b_actions[mb_inds])
2071
+ pg_loss, v_loss, entropy_loss, old_approx_kl, approx_kl, clipfrac = ppo_losses(
2072
+ args, newlogprob, entropy, newvalue, b_logprobs[mb_inds],
2073
+ b_advantages[mb_inds], b_returns[mb_inds], b_values[mb_inds], b_admitted[mb_inds],
2074
+ )
2075
+ if args.target_kl is not None and approx_kl > args.target_kl:
2076
+ break
2077
+ loss = pg_loss - args.ent_coef * entropy_loss + v_loss * args.vf_coef
2078
+ actor_updates += b_admitted[mb_inds].any().item()
2079
+
2080
+ optimizer.zero_grad()
2081
+ loss.backward()
2082
+ nn.utils.clip_grad_norm_(agent.parameters(), args.max_grad_norm)
2083
+ optimizer.step()
2084
+
2085
+ if args.target_kl is not None and approx_kl > args.target_kl:
2086
+ break
2087
+
2088
+ update_time = time.time() - update_time
2089
+
2090
+ # Report the complete admitted rollout after the update; the last
2091
+ # minibatch alone can hide a policy jump or contain no decisions.
2092
+ with torch.no_grad():
2093
+ _, newlogprob, entropy, newvalue = agent.get_action_and_value(b_obs, b_actions)
2094
+ pg_loss, v_loss, entropy_loss, old_approx_kl, approx_kl, clipfrac = ppo_losses(
2095
+ args, newlogprob, entropy, newvalue, b_logprobs,
2096
+ b_advantages, b_returns, b_values, b_admitted,
2097
+ )
2098
+
2099
+ y_pred, y_true = b_values.cpu().numpy(), b_returns.cpu().numpy()
2100
+ var_y = np.var(y_true)
2101
+ explained_var = np.nan if var_y == 0 else 1 - np.var(y_true - y_pred) / var_y
2102
+
2103
+ logger.add_scalar("charts/learning_rate", optimizer.param_groups[0]["lr"], global_step)
2104
+ logger.add_scalar("charts/global_step", global_step, global_step)
2105
+ logger.add_scalar("losses/value_loss", v_loss.item(), global_step)
2106
+ logger.add_scalar("losses/policy_loss", pg_loss.item(), global_step)
2107
+ logger.add_scalar("losses/entropy", entropy_loss.item(), global_step)
2108
+ logger.add_scalar("losses/old_approx_kl", old_approx_kl.item(), global_step)
2109
+ logger.add_scalar("losses/approx_kl", approx_kl.item(), global_step)
2110
+ logger.add_scalar("losses/clipfrac", clipfrac.item(), global_step)
2111
+ logger.add_scalar("charts/actor_updates", actor_updates, global_step)
2112
+ logger.add_scalar("losses/explained_variance", explained_var, global_step)
2113
+ print("SPS:", int(global_step / (time.time() - start_time)))
2114
+ logger.add_scalar("charts/SPS", int(global_step / (time.time() - start_time)), global_step)
2115
+ logger.add_scalar("time/step", global_step, global_step)
2116
+ logger.add_scalar("time/update_time", update_time, global_step)
2117
+ logger.add_scalar("time/rollout_time", rollout_time, global_step)
2118
+ logger.add_scalar("time/rollout_fps", args.num_envs * args.num_steps / rollout_time, global_step)
2119
+ del newlogprob, entropy, newvalue
2120
+ save_latency_checkpoint(iteration)
2121
+ if torch.cuda.is_available():
2122
+ torch.cuda.empty_cache()
2123
+
2124
+ if args.save_model and not args.evaluate:
2125
+ model_path = f"{SAVE_DIR}/{run_name}/{TIME}/final_ckpt.pt"
2126
+ torch.save(agent.state_dict(), model_path)
2127
+ print(f"model saved to {model_path}")
2128
+
2129
+ envs.close()
2130
+ eval_envs.close()
2131
+ if logger is not None:
2132
+ logger.close()
latency-aware/mikasa-intercept-grab-fast/small-policy/ppo-qwenoft-rtx3090-mean-h1-s123-v1/files.sha256.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "train.yaml": {
3
+ "bytes": 801,
4
+ "sha256": "68e4f5d7733e603b0caf55e3b914c3e941eaed7bce73385c5854c717de5c1250"
5
+ },
6
+ "checkpoint.pt": {
7
+ "bytes": 1169653,
8
+ "sha256": "e47526f03fad3ed251dd78f3cacfba8aa8b60bd1578f40bd7a1393e17298e973"
9
+ },
10
+ "training.args.json": {
11
+ "bytes": 1447,
12
+ "sha256": "30902a6dde68c9345c6298bfa4ce2a42a60d95d340862beaaf2fea716b138abd"
13
+ },
14
+ "provenance.json": {
15
+ "bytes": 1753,
16
+ "sha256": "33f61eba8c8c793a08ac8b23d8e3f9d46b1996870b22740005c7ae26f61adde0"
17
+ },
18
+ "best_evaluation.json": {
19
+ "bytes": 242,
20
+ "sha256": "06b6d6ee2f5aca153afcc28cf2785c53ac1072daf5b93e5f3934bbfee3c8db6b"
21
+ },
22
+ "README.md": {
23
+ "bytes": 596,
24
+ "sha256": "0cd76badd8fdda994a4ddb55d32f9881d21264c7e50685a59d9cf0b03f0eb153"
25
+ },
26
+ "profile.source.json": {
27
+ "bytes": 2190,
28
+ "sha256": "31a9b15d6b04182439934f0b377cb3d09be16ce21f3cf95c1049918f8a5d4984"
29
+ },
30
+ "runtime-provenance.json": {
31
+ "bytes": 655,
32
+ "sha256": "a37de08c39c16b5c176572876b40fb53285a78b92036b9023ec907aeeeefdff1"
33
+ },
34
+ "code/get_dataset_collectors_ckpt.py": {
35
+ "bytes": 79896,
36
+ "sha256": "7a77707715a63a2a244a06b7c7b8f7a01e9c4122b58daca93ffd543f30d46965"
37
+ }
38
+ }
latency-aware/mikasa-intercept-grab-fast/small-policy/ppo-qwenoft-rtx3090-mean-h1-s123-v1/profile.source.json ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "burst_model_path": "latency_burst_model.json",
3
+ "distribution_path": "latency_distribution.json",
4
+ "env_fps": 20,
5
+ "frame_ms": 50.0,
6
+ "gpu_class": "1x-rtx3090",
7
+ "instance_id": "instance_3a0d42681a03715c",
8
+ "latency_kind": "observation_to_action_latency",
9
+ "latency_method": "temporal",
10
+ "model_id": "qwenoft",
11
+ "n_admitted_observations": 7505,
12
+ "n_capacity_drops": 7495,
13
+ "n_observation_attempts": 15000,
14
+ "per_slot_summary": {
15
+ "0": {
16
+ "admitted_count": 7505,
17
+ "mean_observation_to_action_latency_ms": 99.05021289731565,
18
+ "mean_worker_service_time_ms": 98.55270653801072,
19
+ "p95_observation_to_action_latency_ms": 100.32732703685761,
20
+ "p95_worker_service_time_ms": 99.84762226343155,
21
+ "p99_worker_service_time_ms": 100.37557450771331
22
+ }
23
+ },
24
+ "provenance": {
25
+ "base_config": "configs/examples/mikasa/official_starvla_profile.yaml",
26
+ "checkpoint_kind": "best",
27
+ "model_artifact": {
28
+ "checkpoint": "checkpoints/model.pt",
29
+ "model_config": "config.yaml",
30
+ "path_in_repo": "zero-latency/mikasa-intercept-grab-fast/vla/starvla-qwenoft-h1/mikasa_intercept_grab_fast_qwenoft_formal_latest_r8gpu8_20260907T082154Z",
31
+ "repo_id": "latency-sensitive-bench/benchmark-models",
32
+ "source": "hf"
33
+ },
34
+ "session_ids": [
35
+ 0,
36
+ 1,
37
+ 2,
38
+ 3,
39
+ 4
40
+ ]
41
+ },
42
+ "sample_model_type": "hidden_regime",
43
+ "source_run_id": "20260909T044501695676Z",
44
+ "summary": {
45
+ "frame_ms": 50.0,
46
+ "max_ms": 101.19136601686478,
47
+ "mean_effective_frames": 1.981004257946313,
48
+ "mean_ms": 99.05021289731565,
49
+ "min_ms": 57.612886011600494,
50
+ "n_samples": 7505,
51
+ "p50_frames": 1.9978350806236267,
52
+ "p50_ms": 99.89175403118134,
53
+ "p90_frames": 2.0040290887355803,
54
+ "p90_ms": 100.20145443677902,
55
+ "p95_frames": 2.006546540737152,
56
+ "p95_ms": 100.32732703685761,
57
+ "p99_frames": 2.0128874400138854,
58
+ "p99_ms": 100.64437200069428,
59
+ "prob_latency_gt_1_frame": 1.0,
60
+ "prob_latency_gt_2_frames": 0.2139906728847435,
61
+ "prob_latency_gt_3_frames": 0.0,
62
+ "std_ms": 4.583189247461202
63
+ },
64
+ "visualization_path": "latency_profile.png",
65
+ "workload_id": "mikasa_intercept_grab_fast"
66
+ }
latency-aware/mikasa-intercept-grab-fast/small-policy/ppo-qwenoft-rtx3090-mean-h1-s123-v1/provenance.json ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "task": "mikasa-intercept-grab-fast",
3
+ "model": "ppo-mlp-state",
4
+ "training_status": "complete",
5
+ "configured_total_timesteps": 150000000,
6
+ "completed_iterations": 2441,
7
+ "completed_env_steps": 149975040,
8
+ "original_floor_batch_rule": "150000000 // (1024*60) = 2441 iterations",
9
+ "selection_metric": "eval/success_at_end",
10
+ "checkpoint_global_step": 32256000,
11
+ "checkpoint_iteration": 525,
12
+ "selection_evaluation": {
13
+ "global_step": 32256000,
14
+ "checkpoint_iteration": 525,
15
+ "episodes": 16,
16
+ "metrics": {
17
+ "success_once": 1.0,
18
+ "return": 24.58411407470703,
19
+ "episode_len": 60.0,
20
+ "reward": 0.40973520278930664,
21
+ "success_at_end": 1.0
22
+ }
23
+ },
24
+ "selection_evaluation_is_independent_benchmark": false,
25
+ "initialization": "from_scratch",
26
+ "training_seed": 123,
27
+ "horizon": 1,
28
+ "dagger_updates": 0,
29
+ "checkpoint": "checkpoint.pt",
30
+ "weights_only_export": true,
31
+ "tensor_equality_verified": true,
32
+ "tensor_count": 17,
33
+ "checkpoint_sha256": "e47526f03fad3ed251dd78f3cacfba8aa8b60bd1578f40bd7a1393e17298e973",
34
+ "selected_source_sha256": "32de174043b87d58a62659af389a939396911db03645ec8e1746f950933992ca",
35
+ "profile": {
36
+ "mean_ms": 99.05021289731565,
37
+ "profile": "/home/ubuntu/lzj/profiles/intercept-published/profiles/qwenoft/1x-rtx3090/mikasa_intercept_grab_fast/instance_3a0d42681a03715c/profile.json",
38
+ "sha256": "31a9b15d6b04182439934f0b377cb3d09be16ce21f3cf95c1049918f8a5d4984"
39
+ },
40
+ "fixed_latency_ms": 99.05021289731565,
41
+ "env_fps": 20,
42
+ "obs_fps": 20,
43
+ "training_hardware": "RTX PRO6000 Blackwell physicalGPU0",
44
+ "wandb_url": "https://wandb.ai/dongqianyu99-zhejiang-university/MIKASA-Robo-dataset-collectors/runs/fvonmqca",
45
+ "closed_loop_benchmark_evaluation": "pending"
46
+ }
latency-aware/mikasa-intercept-grab-fast/small-policy/ppo-qwenoft-rtx3090-mean-h1-s123-v1/runtime-provenance.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "repo": "c3c6a39365a151e9b7a5e215452fd64e957c2b29",
3
+ "starvla": "ccca13c5177fe3d3c884b6e2de4965d916016649",
4
+ "runtime_fixes": [
5
+ "mean-profile-preparation.patch",
6
+ "gym-language-contract.patch",
7
+ "loader-spawn-cache.patch",
8
+ "loader-spawn-test.patch",
9
+ "doom-mean-reset.patch"
10
+ ],
11
+ "pytorch3d": {
12
+ "revision": "33824be3cbc87a7dd1db0f6a9a9de9ac81b2d0ba",
13
+ "build": "transforms-only, no native render extension; QwenOFT uses transforms only"
14
+ },
15
+ "decord": {
16
+ "version": "0.6.0",
17
+ "build": "official source CPU decoder CP310",
18
+ "wheel_sha256": "e193b356b1e984b4eff08d23b62e482c2c9e5037a6efdc0b1af47079ae2e4c47"
19
+ }
20
+ }
latency-aware/mikasa-intercept-grab-fast/small-policy/ppo-qwenoft-rtx3090-mean-h1-s123-v1/train.yaml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ env:
2
+ env_fps: 20
3
+ obs_fps: 20
4
+ noop_action:
5
+ - 0
6
+ - 0
7
+ - 0
8
+ - 0
9
+ - 0
10
+ - 0
11
+ - 0
12
+ executor:
13
+ simulated_worker_capacity: 1
14
+ latency:
15
+ method: fixed
16
+ fixed_latency_ms: 99.05021289731565
17
+ seed: 0
18
+ scheduler:
19
+ ordering_policy: latest_ready
20
+ hold_policy: hold
21
+ training:
22
+ num_envs: 1024
23
+ num_eval_envs: 16
24
+ num_steps: 60
25
+ num_minibatches: 32
26
+ update_epochs: 8
27
+ total_timesteps: 150000000
28
+ eval_freq: 25
29
+ track: true
30
+ exp_name: small-ppo-intercept-qwenoft-mean-rtx3090-h1-s123
31
+ checkpoint: null
32
+ resume: null
33
+ seed: 123
34
+ num_eval_steps: 60
35
+ learning_rate: 0.0001
36
+ target_kl: 0.2
37
+ profile_source:
38
+ repo_id: latency-sensitive-bench/profiles
39
+ revision: 66414463f2a609316da63935941a79abf0a73ce9
40
+ path: profiles/qwenoft/1x-rtx3090/mikasa_intercept_grab_fast/instance_3a0d42681a03715c
latency-aware/mikasa-intercept-grab-fast/small-policy/ppo-qwenoft-rtx3090-mean-h1-s123-v1/training.args.json ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "exp_name": "small-ppo-intercept-qwenoft-mean-rtx3090-h1-s123",
3
+ "seed": 123,
4
+ "torch_deterministic": true,
5
+ "cuda": true,
6
+ "track": true,
7
+ "wandb_project_name": "MIKASA-Robo-dataset-collectors",
8
+ "wandb_entity": "dongqianyu99-zhejiang-university",
9
+ "capture_video": false,
10
+ "save_model": true,
11
+ "evaluate": false,
12
+ "checkpoint": null,
13
+ "latency_config": "/home/ubuntu/lzj/mean-profiling/intercept/teacher.yaml",
14
+ "resume": null,
15
+ "latency_output_dir": "/home/ubuntu/lzj/mean-profiling/intercept/teacher",
16
+ "render_mode": "all",
17
+ "env_id": "InterceptGrabFast-VLA-v0",
18
+ "include_state": true,
19
+ "total_timesteps": 150000000,
20
+ "learning_rate": 0.0001,
21
+ "num_envs": 1024,
22
+ "num_eval_envs": 16,
23
+ "partial_reset": false,
24
+ "eval_partial_reset": false,
25
+ "num_steps": 60,
26
+ "num_eval_steps": 60,
27
+ "reconfiguration_freq": null,
28
+ "eval_reconfiguration_freq": 1,
29
+ "anneal_lr": false,
30
+ "gamma": 0.99,
31
+ "gae_lambda": 0.95,
32
+ "num_minibatches": 32,
33
+ "update_epochs": 8,
34
+ "norm_adv": true,
35
+ "clip_coef": 0.2,
36
+ "clip_vloss": false,
37
+ "ent_coef": 0.0,
38
+ "vf_coef": 0.5,
39
+ "max_grad_norm": 0.5,
40
+ "target_kl": 0.2,
41
+ "reward_scale": 1.0,
42
+ "eval_freq": 25,
43
+ "save_train_video_freq": null,
44
+ "finite_horizon_gae": true,
45
+ "batch_size": 61440,
46
+ "minibatch_size": 1920,
47
+ "num_iterations": 2441,
48
+ "include_oracle": false,
49
+ "noop_steps": 1,
50
+ "include_rgb": false,
51
+ "include_joints": false,
52
+ "reward_mode": "normalized_dense"
53
+ }