dongqianyu99 commited on
Commit
525b3bc
·
verified ·
1 Parent(s): d4825bb

Archive four mean-trained QwenOFT profile-simulation evaluations, 100 episodes each

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/REPORT.md +20 -0
  2. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/all_episodes.csv +401 -0
  3. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/comparison.csv +5 -0
  4. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/comparison.json +205 -0
  5. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/episodes.csv +101 -0
  6. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/eval_config.yaml +203 -0
  7. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/batched_simulated.py +702 -0
  8. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/deadly-compatibility.patch +99 -0
  9. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/deadly_corridor.py +455 -0
  10. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/decision_action_history.py +60 -0
  11. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/eval_driver.py +216 -0
  12. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/mikasa_evaluate.py +341 -0
  13. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/starvla.py +1207 -0
  14. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/starvla_tasks.py +92 -0
  15. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-plan.json +105 -0
  16. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/execution_audit.json +12 -0
  17. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/files.sha256.json +130 -0
  18. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/profile/latency_burst_model.json +1336 -0
  19. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/profile/latency_distribution.json +1027 -0
  20. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/profile/profile.json +66 -0
  21. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/provenance.json +97 -0
  22. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/queue_eval_latency_profile_sample.json +217 -0
  23. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/actions.jsonl.gz +3 -0
  24. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/e2e_latencies.jsonl.gz +3 -0
  25. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/episode_metrics.jsonl.gz +3 -0
  26. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/infer_latencies.jsonl.gz +3 -0
  27. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/latencies.jsonl.gz +3 -0
  28. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/observation_attempts.jsonl.gz +3 -0
  29. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/queue_eval_results.jsonl.gz +3 -0
  30. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/steps.jsonl.gz +3 -0
  31. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/resolved_config.yaml +206 -0
  32. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/statistics.json +36 -0
  33. latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/stdout.log +405 -0
  34. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/REPORT.md +20 -0
  35. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/all_episodes.csv +401 -0
  36. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/comparison.csv +5 -0
  37. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/comparison.json +205 -0
  38. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/episodes.csv +101 -0
  39. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/eval_config.yaml +164 -0
  40. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/batched_simulated.py +702 -0
  41. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/deadly-compatibility.patch +99 -0
  42. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/deadly_corridor.py +455 -0
  43. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/decision_action_history.py +60 -0
  44. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/eval_driver.py +216 -0
  45. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/mikasa_evaluate.py +341 -0
  46. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/starvla.py +1207 -0
  47. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/starvla_tasks.py +92 -0
  48. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-plan.json +105 -0
  49. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/execution_audit.json +12 -0
  50. latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/files.sha256.json +130 -0
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/REPORT.md ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # QwenOFT mean-trained checkpoints under profile simulation
2
+
3
+ Four final step-5000 H1 checkpoints; two rounds, one evaluation per physical GPU2/3,100 episodes each (400 total).
4
+
5
+ The training latency was fixed mean; this evaluation samples the complete archived RTX3090 temporal hidden-regime profile. Simulator FPS, seeds, horizon, limits and model/profile identities are in evaluation-plan.json. Standard deviations below use ddof=0. Returns have task-specific scales. Startup checks are separate and excluded.
6
+
7
+ | Task | Episodes | Return mean +/- SD | Length mean +/- SD | Success | Invalid |
8
+ |---|---:|---:|---:|---:|---:|
9
+ | flappy | 100 | 384.824005 +/- 116.787774 | 3119.31 +/- 939.87 | not provided by task | 0 |
10
+ | deadly_corridor | 100 | 1620.798776 +/- 913.624278 | 148.53 +/- 49.46 | not provided by task | 0 |
11
+ | ant | 100 | 1453.844064 +/- 693.727520 | 803.85 +/- 328.81 | not provided by task | 0 |
12
+ | intercept | 100 | 3.544349 +/- 7.071923 | 60.00 +/- 0.00 | 9/100 | 0 |
13
+
14
+ No success metric is invented for Flappy/Deadly/Ant. Intercept reports the native accumulated success flag. No policy-quality acceptance gate is claimed.
15
+
16
+ Compatibility repairs: portable robot_type copied from each actual training manifest (weights unchanged); official ViZDoom1.2.4 VizdoomCorridor-v0 uses the same deadly_corridor WAD as SF, preserves render contract and semantic seven-button ordering; public action space is equivalent MultiBinary7. Existing native render/button/history tests passed. Full eval source/patch and original profile assets are archived.
17
+
18
+ Flappy/Deadly seeds1000000..1000099; Ant42..141; Intercept4242424242..4242424341. Latency seed271828. Flappy10/10Hz, Deadly35/8.75Hz, Ant10/10Hz, Intercept20/20Hz. Max raw frames3600/3600/1000/60; capacities1. MIKASA H1 holds last chunk action; no prefix, no DAgger. Ant keeps its training prompt label1 while execution latency is sampled.
19
+
20
+ Raw JSONL logs are losslessly gzip-compressed for distribution; original uncompressed records remain on the experiment host. Empty observation_attempts files are retained; admission/drop evidence is in steps/actions. Per-task CSV and full400 episode CSV are provided.
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/all_episodes.csv ADDED
@@ -0,0 +1,401 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task,episode_id,seed,return_env,length,mean_latency_ms,success
2
+ flappy,0,1000000,444.6000052243471,3600,76.02271694866694,
3
+ flappy,1,1000001,444.6000052243471,3600,76.14445348705047,
4
+ flappy,2,1000002,444.6000052243471,3600,75.83047266244563,
5
+ flappy,3,1000003,444.6000052243471,3600,76.04121221698036,
6
+ flappy,4,1000004,444.6000052243471,3600,75.7789115791707,
7
+ flappy,5,1000005,228.2000027000904,1861,76.22757676162651,
8
+ flappy,6,1000006,444.6000052243471,3600,75.98373978309758,
9
+ flappy,7,1000007,444.6000052243471,3600,75.85552109823348,
10
+ flappy,8,1000008,444.6000052243471,3600,75.9782303085917,
11
+ flappy,9,1000009,444.6000052243471,3600,75.94667987356688,
12
+ flappy,10,1000010,444.6000052243471,3600,75.66396359484234,
13
+ flappy,11,1000011,444.6000052243471,3600,75.7794525026407,
14
+ flappy,12,1000012,444.6000052243471,3600,75.90110110734818,
15
+ flappy,13,1000013,444.6000052243471,3600,76.01870178237883,
16
+ flappy,14,1000014,444.6000052243471,3600,75.75567207010911,
17
+ flappy,15,1000015,444.6000052243471,3600,75.83026036637241,
18
+ flappy,16,1000016,444.6000052243471,3600,75.74502908171665,
19
+ flappy,17,1000017,444.6000052243471,3600,75.84316844302293,
20
+ flappy,18,1000018,444.6000052243471,3600,75.85876738771161,
21
+ flappy,19,1000019,265.50000313669443,2162,75.89492798135642,
22
+ flappy,20,1000020,444.6000052243471,3600,75.90859756288593,
23
+ flappy,21,1000021,444.6000052243471,3600,75.93474621914784,
24
+ flappy,22,1000022,444.6000052243471,3600,75.77022360156529,
25
+ flappy,23,1000023,444.6000052243471,3600,75.8506098974935,
26
+ flappy,24,1000024,444.6000052243471,3600,75.80511776716725,
27
+ flappy,25,1000025,116.00000138580799,955,76.07937915327228,
28
+ flappy,26,1000026,444.6000052243471,3600,75.77409482659607,
29
+ flappy,27,1000027,444.6000052243471,3600,75.82354466933252,
30
+ flappy,28,1000028,444.6000052243471,3600,75.92578714415393,
31
+ flappy,29,1000029,444.6000052243471,3600,75.77326038618416,
32
+ flappy,30,1000030,256.0000030249357,2085,75.8461606092662,
33
+ flappy,31,1000031,444.6000052243471,3600,75.87053786258159,
34
+ flappy,32,1000032,444.6000052243471,3600,75.90930861144982,
35
+ flappy,33,1000033,444.6000052243471,3600,75.80530422686525,
36
+ flappy,34,1000034,444.6000052243471,3600,76.05997569829616,
37
+ flappy,35,1000035,444.6000052243471,3600,75.67579907153437,
38
+ flappy,36,1000036,444.6000052243471,3600,76.07561842170198,
39
+ flappy,37,1000037,444.6000052243471,3600,75.87459102177027,
40
+ flappy,38,1000038,55.60000067949295,468,75.8887188983619,
41
+ flappy,39,1000039,444.6000052243471,3600,75.86536772802552,
42
+ flappy,40,1000040,432.900005094707,3512,76.00355652525975,
43
+ flappy,41,1000041,274.8000032454729,2237,75.7658282850597,
44
+ flappy,42,1000042,264.90000312775373,2156,75.95264956954799,
45
+ flappy,43,1000043,265.4000031352043,2161,75.82748305801191,
46
+ flappy,44,1000044,444.6000052243471,3600,75.9295822845668,
47
+ flappy,45,1000045,143.90000171214342,1180,75.94310218110371,
48
+ flappy,46,1000046,444.6000052243471,3600,75.69568531179425,
49
+ flappy,47,1000047,93.1000011190772,771,76.0527875505066,
50
+ flappy,48,1000048,56.10000068694353,473,76.20882901957174,
51
+ flappy,49,1000049,265.2000031322241,2159,76.05401077635972,
52
+ flappy,50,1000050,444.6000052243471,3600,75.89333271844873,
53
+ flappy,51,1000051,444.6000052243471,3600,75.89090159365671,
54
+ flappy,52,1000052,398.80000469088554,3234,75.91218218803246,
55
+ flappy,53,1000053,444.6000052243471,3600,75.86400590251726,
56
+ flappy,54,1000054,270.2000031918287,2200,76.01590238337654,
57
+ flappy,55,1000055,69.70000084489584,582,75.68422480575155,
58
+ flappy,56,1000056,444.6000052243471,3600,75.87884524455251,
59
+ flappy,57,1000057,444.6000052243471,3600,75.96981187494319,
60
+ flappy,58,1000058,444.6000052243471,3600,76.03772455115222,
61
+ flappy,59,1000059,437.90000515431166,3553,76.04088529786887,
62
+ flappy,60,1000060,348.9000041112304,2834,75.79422825165413,
63
+ flappy,61,1000061,444.6000052243471,3600,75.87728099437057,
64
+ flappy,62,1000062,78.9000009521842,656,75.96352981662133,
65
+ flappy,63,1000063,444.6000052243471,3600,75.80269270184165,
66
+ flappy,64,1000064,444.6000052243471,3600,75.88518180564401,
67
+ flappy,65,1000065,444.6000052243471,3600,75.87533034544981,
68
+ flappy,66,1000066,444.6000052243471,3600,75.94241138050401,
69
+ flappy,67,1000067,444.6000052243471,3600,75.95312277771471,
70
+ flappy,68,1000068,444.6000052243471,3600,75.8998829764233,
71
+ flappy,69,1000069,444.6000052243471,3600,75.98564617573034,
72
+ flappy,70,1000070,444.6000052243471,3600,75.68328575087021,
73
+ flappy,71,1000071,135.0000016093254,1109,75.99546963217229,
74
+ flappy,72,1000072,444.6000052243471,3600,75.9923106611263,
75
+ flappy,73,1000073,444.6000052243471,3600,75.80422251719546,
76
+ flappy,74,1000074,444.6000052243471,3600,75.95469853250815,
77
+ flappy,75,1000075,444.6000052243471,3600,75.74551875442629,
78
+ flappy,76,1000076,444.6000052243471,3600,75.93301571087362,
79
+ flappy,77,1000077,444.6000052243471,3600,75.98384926019328,
80
+ flappy,78,1000078,444.6000052243471,3600,75.85055115368883,
81
+ flappy,79,1000079,444.6000052243471,3600,75.97142616222317,
82
+ flappy,80,1000080,444.6000052243471,3600,75.97039764106849,
83
+ flappy,81,1000081,444.6000052243471,3600,75.74469321422862,
84
+ flappy,82,1000082,116.20000138878822,957,76.0366526049804,
85
+ flappy,83,1000083,444.6000052243471,3600,75.95924386190674,
86
+ flappy,84,1000084,444.6000052243471,3600,76.0310580385874,
87
+ flappy,85,1000085,36.60000045597553,314,75.8634823847272,
88
+ flappy,86,1000086,260.90000308305025,2125,75.91783880059099,
89
+ flappy,87,1000087,444.6000052243471,3600,76.16752514785735,
90
+ flappy,88,1000088,444.6000052243471,3600,75.83331254385584,
91
+ flappy,89,1000089,444.6000052243471,3600,76.2113387300584,
92
+ flappy,90,1000090,444.6000052243471,3600,75.8334932097261,
93
+ flappy,91,1000091,225.20000265538692,1831,75.75618859671614,
94
+ flappy,92,1000092,444.6000052243471,3600,75.79683788505955,
95
+ flappy,93,1000093,180.9000021442771,1478,75.96465307644473,
96
+ flappy,94,1000094,305.2000035941601,2478,75.86565754734926,
97
+ flappy,95,1000095,444.6000052243471,3600,75.74523644464854,
98
+ flappy,96,1000096,444.6000052243471,3600,75.94353591524424,
99
+ flappy,97,1000097,444.6000052243471,3600,75.81927739599219,
100
+ flappy,98,1000098,444.6000052243471,3600,75.96229410618645,
101
+ flappy,99,1000099,444.6000052243471,3600,75.94512877548694,
102
+ deadly_corridor,0,1000000,337.47547912597656,72,71.90727374040254,
103
+ deadly_corridor,1,1000001,819.0284423828125,143,73.84762082340946,
104
+ deadly_corridor,2,1000002,2284.857650756836,182,72.79171012339609,
105
+ deadly_corridor,3,1000003,2276.2068634033203,189,76.345275285376,
106
+ deadly_corridor,4,1000004,805.2153015136719,150,73.86282581373551,
107
+ deadly_corridor,5,1000005,621.8231658935547,115,74.31105893586228,
108
+ deadly_corridor,6,1000006,2276.414749145508,176,74.2226331369995,
109
+ deadly_corridor,7,1000007,2284.310989379883,176,72.9072057957754,
110
+ deadly_corridor,8,1000008,81.07798767089844,49,73.20258272646697,
111
+ deadly_corridor,9,1000009,317.2351837158203,75,72.54774919154028,
112
+ deadly_corridor,10,1000010,2282.7608489990234,176,72.78293151689127,
113
+ deadly_corridor,11,1000011,88.11907958984375,45,72.60486105128022,
114
+ deadly_corridor,12,1000012,2281.468536376953,176,72.29193331603048,
115
+ deadly_corridor,13,1000013,2276.6868591308594,178,72.73330265771509,
116
+ deadly_corridor,14,1000014,2276.1705932617188,178,73.30067987408609,
117
+ deadly_corridor,15,1000015,2282.6631622314453,177,72.49405489224537,
118
+ deadly_corridor,16,1000016,2280.300033569336,172,72.80884970803692,
119
+ deadly_corridor,17,1000017,2280.4182891845703,182,73.03539182090206,
120
+ deadly_corridor,18,1000018,2281.2594451904297,177,72.50972089313564,
121
+ deadly_corridor,19,1000019,479.8523712158203,99,72.58046231642126,
122
+ deadly_corridor,20,1000020,2279.7379455566406,181,72.47468246266928,
123
+ deadly_corridor,21,1000021,2284.9097442626953,197,83.18983231769475,
124
+ deadly_corridor,22,1000022,2286.2730407714844,172,72.84281562147524,
125
+ deadly_corridor,23,1000023,244.51919555664062,74,76.23461799191558,
126
+ deadly_corridor,24,1000024,2279.957275390625,195,72.94927214021655,
127
+ deadly_corridor,25,1000025,2283.952178955078,179,73.18968843008061,
128
+ deadly_corridor,26,1000026,2276.701370239258,178,72.87702909462648,
129
+ deadly_corridor,27,1000027,2277.142562866211,190,72.45412386128042,
130
+ deadly_corridor,28,1000028,2279.025634765625,177,74.11102172804317,
131
+ deadly_corridor,29,1000029,2285.7152099609375,177,71.63189230597281,
132
+ deadly_corridor,30,1000030,53.374298095703125,44,72.51418721312025,
133
+ deadly_corridor,31,1000031,2279.8080444335938,183,72.72702656843174,
134
+ deadly_corridor,32,1000032,2282.307357788086,178,74.33584751930213,
135
+ deadly_corridor,33,1000033,2282.834014892578,192,73.95005063555192,
136
+ deadly_corridor,34,1000034,2284.200241088867,188,76.29368894499888,
137
+ deadly_corridor,35,1000035,2287.2159118652344,179,72.81890806090988,
138
+ deadly_corridor,36,1000036,2284.693832397461,183,76.28284599973325,
139
+ deadly_corridor,37,1000037,2283.2066650390625,178,72.1797344044525,
140
+ deadly_corridor,38,1000038,2281.032196044922,178,73.74343783824916,
141
+ deadly_corridor,39,1000039,2282.960678100586,190,73.24816830891406,
142
+ deadly_corridor,40,1000040,2287.094253540039,185,72.35711232966574,
143
+ deadly_corridor,41,1000041,2279.3030853271484,179,72.42125368367608,
144
+ deadly_corridor,42,1000042,440.0892791748047,104,73.92064892672727,
145
+ deadly_corridor,43,1000043,2280.8592529296875,177,72.36020918178356,
146
+ deadly_corridor,44,1000044,2283.4308471679688,189,75.93658060557208,
147
+ deadly_corridor,45,1000045,2282.324264526367,181,73.54224681770178,
148
+ deadly_corridor,46,1000046,326.0184631347656,74,73.1983876441008,
149
+ deadly_corridor,47,1000047,2279.086135864258,182,73.00958120503027,
150
+ deadly_corridor,48,1000048,2280.3804626464844,179,73.17268244992928,
151
+ deadly_corridor,49,1000049,2276.215301513672,189,75.47590644230628,
152
+ deadly_corridor,50,1000050,2278.132034301758,182,74.50495464842548,
153
+ deadly_corridor,51,1000051,2285.6056518554688,181,73.41699294418743,
154
+ deadly_corridor,52,1000052,2287.240921020508,173,73.22110809114655,
155
+ deadly_corridor,53,1000053,310.81517028808594,73,74.09003681120738,
156
+ deadly_corridor,54,1000054,2276.6219787597656,175,72.98605010243534,
157
+ deadly_corridor,55,1000055,2276.2769470214844,194,75.17704077845171,
158
+ deadly_corridor,56,1000056,2278.861602783203,178,72.97353037051572,
159
+ deadly_corridor,57,1000057,2279.728561401367,181,73.96913002154926,
160
+ deadly_corridor,58,1000058,2280.544464111328,176,73.02432805290651,
161
+ deadly_corridor,59,1000059,487.829833984375,108,78.89398217393664,
162
+ deadly_corridor,60,1000060,567.0655517578125,113,72.64874721482185,
163
+ deadly_corridor,61,1000061,2278.210220336914,177,72.96068484971086,
164
+ deadly_corridor,62,1000062,2281.436721801758,186,75.46710866924751,
165
+ deadly_corridor,63,1000063,382.2119903564453,89,81.21157315209366,
166
+ deadly_corridor,64,1000064,246.2946014404297,70,73.9736408486285,
167
+ deadly_corridor,65,1000065,285.21240234375,76,73.13661133681993,
168
+ deadly_corridor,66,1000066,310.6737365722656,75,73.40468658737086,
169
+ deadly_corridor,67,1000067,346.1162872314453,75,72.1929723632303,
170
+ deadly_corridor,68,1000068,804.7056121826172,150,73.76397959753224,
171
+ deadly_corridor,69,1000069,2285.6442108154297,184,75.13255757158333,
172
+ deadly_corridor,70,1000070,730.5995788574219,132,73.25446825350764,
173
+ deadly_corridor,71,1000071,86.91796875,47,76.28335745963689,
174
+ deadly_corridor,72,1000072,60.30122375488281,44,76.83513093208644,
175
+ deadly_corridor,73,1000073,768.6264343261719,141,77.27057350071598,
176
+ deadly_corridor,74,1000074,2280.1071166992188,172,74.16699734355548,
177
+ deadly_corridor,75,1000075,860.9334106445312,151,73.15118478347584,
178
+ deadly_corridor,76,1000076,722.9459228515625,143,75.5655785931314,
179
+ deadly_corridor,77,1000077,2276.8687438964844,182,72.95102474014934,
180
+ deadly_corridor,78,1000078,368.3357238769531,79,71.51096709276341,
181
+ deadly_corridor,79,1000079,-76.45918273925781,17,72.24888432102617,
182
+ deadly_corridor,80,1000080,2281.5543823242188,183,73.32589540463356,
183
+ deadly_corridor,81,1000081,2281.6688842773438,171,73.10600900440717,
184
+ deadly_corridor,82,1000082,2277.5223083496094,178,73.55648700566698,
185
+ deadly_corridor,83,1000083,42.30937194824219,41,73.52700344736942,
186
+ deadly_corridor,84,1000084,2285.8980407714844,176,71.98655161011203,
187
+ deadly_corridor,85,1000085,68.90191650390625,45,72.84773487604696,
188
+ deadly_corridor,86,1000086,2286.2190551757812,171,72.82303966497733,
189
+ deadly_corridor,87,1000087,281.1173553466797,76,72.26983276661764,
190
+ deadly_corridor,88,1000088,2283.1607971191406,175,73.49638264342678,
191
+ deadly_corridor,89,1000089,2277.888946533203,177,73.44736473371472,
192
+ deadly_corridor,90,1000090,429.36326599121094,93,71.86172378947977,
193
+ deadly_corridor,91,1000091,252.0751953125,70,72.26459581736903,
194
+ deadly_corridor,92,1000092,2278.306442260742,192,80.97328482778371,
195
+ deadly_corridor,93,1000093,2285.236801147461,175,74.02717585214627,
196
+ deadly_corridor,94,1000094,857.2727355957031,152,85.59110000526613,
197
+ deadly_corridor,95,1000095,2275.9288024902344,199,73.62958803645523,
198
+ deadly_corridor,96,1000096,2286.8704833984375,179,72.31519682456816,
199
+ deadly_corridor,97,1000097,2278.048355102539,181,73.50330330803081,
200
+ deadly_corridor,98,1000098,2277.4480743408203,178,76.78472725777,
201
+ deadly_corridor,99,1000099,2276.9671478271484,178,77.9678189026336,
202
+ ant,0,42,1846.1103431567394,1000,89.89614608291177,
203
+ ant,1,43,2415.720790707953,1000,90.00308114332259,
204
+ ant,2,44,457.34421085068755,177,89.83716885697598,
205
+ ant,3,45,1421.7952163289683,1000,89.87909631338808,
206
+ ant,4,46,2037.7234409469488,937,89.82685347370092,
207
+ ant,5,47,2330.630175869275,1000,90.47193606091501,
208
+ ant,6,48,1161.643572255748,429,89.84194070141322,
209
+ ant,7,49,2351.1524624990343,1000,89.92640891799017,
210
+ ant,8,50,513.2964809479813,210,89.88895656571908,
211
+ ant,9,51,1126.8652528911032,660,89.91361550654544,
212
+ ant,10,52,1693.436933192597,1000,89.84960962337662,
213
+ ant,11,53,948.3780972955639,1000,89.94678527711802,
214
+ ant,12,54,2322.052445211472,1000,90.11873818885832,
215
+ ant,13,55,960.4026770814776,1000,90.93377411320307,
216
+ ant,14,56,1464.564005196777,1000,89.80893705661644,
217
+ ant,15,57,1110.548792782156,1000,89.99466844889166,
218
+ ant,16,58,2246.207900740156,1000,90.1624262080728,
219
+ ant,17,59,85.64836938561511,60,89.87005518664785,
220
+ ant,18,60,340.54799067574436,143,89.94240076131771,
221
+ ant,19,61,2457.088748930458,1000,89.92054036086635,
222
+ ant,20,62,2166.2512677098603,1000,89.95452553058773,
223
+ ant,21,63,2357.957592244385,1000,89.86780458600198,
224
+ ant,22,64,1654.8780938737275,871,90.08433827425095,
225
+ ant,23,65,1499.367100151414,1000,89.89663615668341,
226
+ ant,24,66,2297.4032619179525,1000,90.09818426014289,
227
+ ant,25,67,1253.360764666355,543,89.9390124443734,
228
+ ant,26,68,1221.270312709775,1000,89.84986177450952,
229
+ ant,27,69,2389.2476464763376,1000,89.95772586857817,
230
+ ant,28,70,1682.5290233886233,707,89.76145439054764,
231
+ ant,29,71,2474.676425615127,1000,89.82093759631324,
232
+ ant,30,72,382.9231146443659,256,90.69916524888657,
233
+ ant,31,73,1837.8126619276347,1000,90.03642087221974,
234
+ ant,32,74,227.19436616673684,101,89.8553742761573,
235
+ ant,33,75,1700.6312067622644,1000,89.80097198453268,
236
+ ant,34,76,960.9452812639541,372,89.8420903148968,
237
+ ant,35,77,2290.6720141359438,1000,89.91770573449698,
238
+ ant,36,78,328.5729178056416,162,90.01187187392946,
239
+ ant,37,79,1180.073938772476,1000,89.81938304804656,
240
+ ant,38,80,817.4190215442345,363,89.85140773938038,
241
+ ant,39,81,1651.2255208727013,1000,91.17610023451576,
242
+ ant,40,82,1428.174672693164,1000,89.8551155619885,
243
+ ant,41,83,1627.3838925098842,1000,90.55986754698809,
244
+ ant,42,84,1079.756369746183,680,90.17098553312343,
245
+ ant,43,85,2173.9447393037276,1000,89.84319301261918,
246
+ ant,44,86,409.90633829945847,160,89.66802828269809,
247
+ ant,45,87,2467.2636019929073,1000,89.90844708827387,
248
+ ant,46,88,657.4084558813478,248,89.86487149424892,
249
+ ant,47,89,974.7436031610902,1000,89.76305094278182,
250
+ ant,48,90,1510.5184342975385,1000,90.24355118464125,
251
+ ant,49,91,602.2339441184535,260,89.7103209703719,
252
+ ant,50,92,760.9784375126189,316,89.8206829517188,
253
+ ant,51,93,1941.172113330597,1000,90.30785204408768,
254
+ ant,52,94,624.3590446196446,281,89.94582387208622,
255
+ ant,53,95,2163.4347041279893,1000,89.84848132390947,
256
+ ant,54,96,1126.9957963444238,1000,89.84637728060243,
257
+ ant,55,97,1405.131632695366,1000,90.18855922596491,
258
+ ant,56,98,1206.2916757636292,1000,89.78065539051504,
259
+ ant,57,99,2392.7980761515178,1000,89.76388668266138,
260
+ ant,58,100,964.0216541467705,1000,89.82618651237911,
261
+ ant,59,101,2252.192880003706,1000,89.8197082349776,
262
+ ant,60,102,2471.9158497657563,1000,89.96642568195992,
263
+ ant,61,103,1902.8491241623092,1000,89.87542708971246,
264
+ ant,62,104,1435.6661382989703,1000,90.28644124851098,
265
+ ant,63,105,1668.3237703695809,1000,89.86433221097877,
266
+ ant,64,106,1813.291243529155,1000,89.85118001877315,
267
+ ant,65,107,446.72353548541076,189,89.8309544306309,
268
+ ant,66,108,130.84194814079504,74,89.82416773165995,
269
+ ant,67,109,2315.857153770824,1000,90.25959750757508,
270
+ ant,68,110,288.3915792961347,116,90.09271984792927,
271
+ ant,69,111,894.0228631227924,1000,89.89663691508213,
272
+ ant,70,112,2030.322535823717,1000,89.84028619017428,
273
+ ant,71,113,507.9449555916754,215,90.57267432538549,
274
+ ant,72,114,2377.7373967468293,1000,89.84919425782105,
275
+ ant,73,115,897.3077114027096,1000,89.90431472264346,
276
+ ant,74,116,1454.612590266188,1000,91.19515970740413,
277
+ ant,75,117,2292.457960175467,1000,89.8333901030839,
278
+ ant,76,118,1424.378337790017,1000,89.88029014661089,
279
+ ant,77,119,1441.1111023164538,1000,89.79844243631413,
280
+ ant,78,120,1265.4771503717611,1000,89.86009503143968,
281
+ ant,79,121,1662.8808067819505,1000,90.5661722205243,
282
+ ant,80,122,2508.917122342891,1000,89.87403626041336,
283
+ ant,81,123,1655.3510139158748,1000,90.05039760075688,
284
+ ant,82,124,1387.3843721247736,821,90.10235730111886,
285
+ ant,83,125,646.4356689469432,271,89.7559653760994,
286
+ ant,84,126,2172.801064037805,1000,89.84602989356796,
287
+ ant,85,127,165.9213897970373,72,89.66756877688618,
288
+ ant,86,128,1063.1483912161111,1000,89.77409215132576,
289
+ ant,87,129,1000.135342286622,1000,89.81900933661238,
290
+ ant,88,130,1977.2359176146426,1000,89.77653862908736,
291
+ ant,89,131,1937.1674235355138,1000,90.12773943823525,
292
+ ant,90,132,1344.7729257831547,1000,90.39620143170467,
293
+ ant,91,133,786.3379828975102,441,89.82893206036925,
294
+ ant,92,134,1391.060299752017,1000,89.86676880070257,
295
+ ant,93,135,503.300235688713,250,89.94819176115624,
296
+ ant,94,136,2446.7482357041768,1000,89.84848658183878,
297
+ ant,95,137,1171.9102336514923,1000,89.92785850220504,
298
+ ant,96,138,2356.7311711183065,1000,90.42933754946152,
299
+ ant,97,139,2356.12199478712,1000,89.82049779117614,
300
+ ant,98,140,1389.2987977192308,1000,90.82209581044775,
301
+ ant,99,141,967.2335383727841,1000,89.80016695371027,
302
+ intercept,0,4242424242,0.7267571190313902,60,99.89614420497905,0.0
303
+ intercept,1,4242424243,2.9096362272975966,60,99.91707940536706,0.0
304
+ intercept,2,4242424244,3.2060351513209753,60,97.78809018716221,0.0
305
+ intercept,3,4242424245,0.7574528902187012,60,98.54894447730877,0.0
306
+ intercept,4,4242424246,0.6827895979695313,60,99.11745353519741,0.0
307
+ intercept,5,4242424247,29.923812823486514,60,99.04064156549293,1.0
308
+ intercept,6,4242424248,0.7661087726592086,60,98.25342313549518,0.0
309
+ intercept,7,4242424249,0.8284444468154106,60,97.98431264506286,0.0
310
+ intercept,8,4242424250,0.9707721562881488,60,99.10671115977826,0.0
311
+ intercept,9,4242424251,1.0944434545235708,60,99.10142489904808,0.0
312
+ intercept,10,4242424252,0.7526731102407211,60,98.24263629181895,0.0
313
+ intercept,11,4242424253,1.0327306617691647,60,99.90610126116793,0.0
314
+ intercept,12,4242424254,24.08529434411321,60,99.04964452767656,1.0
315
+ intercept,13,4242424255,0.8258126199943945,60,99.06333184347895,0.0
316
+ intercept,14,4242424256,0.6465023508935701,60,99.96017435988418,0.0
317
+ intercept,15,4242424257,1.2059930491086561,60,99.07293754243183,0.0
318
+ intercept,16,4242424258,0.8975468523567542,60,99.10975490804557,0.0
319
+ intercept,17,4242424259,0.638558203499997,60,99.9008234011206,0.0
320
+ intercept,18,4242424260,2.473904824233614,60,99.1007534285042,0.0
321
+ intercept,19,4242424261,0.8594156300532632,60,98.2804424689215,0.0
322
+ intercept,20,4242424262,0.7127419076277874,60,97.42140552034121,0.0
323
+ intercept,21,4242424263,1.1195833964738995,60,99.05356389575846,0.0
324
+ intercept,22,4242424264,1.4589147588121705,60,99.10476263429966,0.0
325
+ intercept,23,4242424265,22.348254217096837,60,98.14243140713285,1.0
326
+ intercept,24,4242424266,27.43761277961312,60,99.03063235183511,1.0
327
+ intercept,25,4242424267,0.797963114338927,60,98.95851806063928,0.0
328
+ intercept,26,4242424268,0.6415987604705151,60,99.1202532952496,0.0
329
+ intercept,27,4242424269,1.502438226743834,60,99.8369766656745,0.0
330
+ intercept,28,4242424270,1.277322537265718,60,99.13638822823135,0.0
331
+ intercept,29,4242424271,0.6413188653605175,60,99.8165233572777,0.0
332
+ intercept,30,4242424272,26.015227647672873,60,99.93359984997578,1.0
333
+ intercept,31,4242424273,0.7568511647114065,60,98.29798580223347,0.0
334
+ intercept,32,4242424274,0.7758818510046694,60,95.9119617819155,0.0
335
+ intercept,33,4242424275,0.743274000211386,60,99.16579733811342,0.0
336
+ intercept,34,4242424276,0.9812663898337632,60,99.96913332715677,0.0
337
+ intercept,35,4242424277,0.7364500367548317,60,98.4144170848438,0.0
338
+ intercept,36,4242424278,0.7676261149172205,60,99.87913624991887,0.0
339
+ intercept,37,4242424279,2.6105462690466084,60,99.0124647390605,0.0
340
+ intercept,38,4242424280,0.8922563010128215,60,99.49582641131909,0.0
341
+ intercept,39,4242424281,0.7909053032053635,60,99.95776157301488,0.0
342
+ intercept,40,4242424282,27.747763212013524,60,99.89232705853966,1.0
343
+ intercept,41,4242424283,2.830903574009426,60,99.11182141335861,0.0
344
+ intercept,42,4242424284,3.749473527306691,60,99.89401411987875,0.0
345
+ intercept,43,4242424285,3.2371535471174866,60,98.58941395009701,0.0
346
+ intercept,44,4242424286,1.141169616690604,60,98.95023432158384,0.0
347
+ intercept,45,4242424287,1.2504711685760412,60,99.8783128676535,0.0
348
+ intercept,46,4242424288,1.1401455145678483,60,99.09364640302553,0.0
349
+ intercept,47,4242424289,1.1743367564631626,60,98.24703755640672,0.0
350
+ intercept,48,4242424290,0.6911400489043444,60,98.98847807253395,0.0
351
+ intercept,49,4242424291,0.966755291854497,60,98.31297463384391,0.0
352
+ intercept,50,4242424292,3.7725237559643574,60,98.1307167401627,0.0
353
+ intercept,51,4242424293,0.7292428385990206,60,99.08520847604322,0.0
354
+ intercept,52,4242424294,2.733719722367823,60,99.8949988335446,0.0
355
+ intercept,53,4242424295,2.7277548569836654,60,99.16542541107671,0.0
356
+ intercept,54,4242424296,0.8013565168366767,60,98.2801475641182,0.0
357
+ intercept,55,4242424297,0.9918300381395966,60,98.74883429246843,0.0
358
+ intercept,56,4242424298,3.8384227409260347,60,98.30485570834159,0.0
359
+ intercept,57,4242424299,2.525593837024644,60,99.08211861473346,0.0
360
+ intercept,58,4242424300,1.1939986812940333,60,99.95562586586023,0.0
361
+ intercept,59,4242424301,1.1946645161951892,60,99.11887142756973,0.0
362
+ intercept,60,4242424302,0.6632764584392135,60,99.92733404817194,0.0
363
+ intercept,61,4242424303,0.7345126099826302,60,99.61093201950378,0.0
364
+ intercept,62,4242424304,1.1547945403144695,60,98.88382479344455,0.0
365
+ intercept,63,4242424305,1.0395031699445099,60,99.10455669644611,0.0
366
+ intercept,64,4242424306,2.7713681719324086,60,99.99607387713222,0.0
367
+ intercept,65,4242424307,3.8083399715833366,60,99.90908449191997,0.0
368
+ intercept,66,4242424308,3.1245881704380736,60,99.86388390473627,0.0
369
+ intercept,67,4242424309,0.9936205917911138,60,99.06530098425861,0.0
370
+ intercept,68,4242424310,0.6479002644773573,60,97.31661851374615,0.0
371
+ intercept,69,4242424311,1.09404552471824,60,99.06482130667098,0.0
372
+ intercept,70,4242424312,0.725047086874838,60,99.39714496924636,0.0
373
+ intercept,71,4242424313,2.085218493710272,60,99.91926924929075,0.0
374
+ intercept,72,4242424314,25.112157980707707,60,99.89495984140663,1.0
375
+ intercept,73,4242424315,0.7960666966973804,60,99.91315720008677,0.0
376
+ intercept,74,4242424316,1.8899870013119653,60,99.8635479883608,0.0
377
+ intercept,75,4242424317,24.77215793245705,60,99.08978442272605,1.0
378
+ intercept,76,4242424318,0.763190906640375,60,99.1181927131107,0.0
379
+ intercept,77,4242424319,0.8356004936795216,60,98.87472332915829,0.0
380
+ intercept,78,4242424320,24.543561146681895,60,98.85109478338812,1.0
381
+ intercept,79,4242424321,0.7962639288743958,60,96.64267992061197,0.0
382
+ intercept,80,4242424322,0.6807828926102957,60,98.70551839611774,0.0
383
+ intercept,81,4242424323,1.1704122956143692,60,99.1162675413269,0.0
384
+ intercept,82,4242424324,0.8024117537715938,60,99.10984056283594,0.0
385
+ intercept,83,4242424325,1.0154686415335163,60,99.90653765962175,0.0
386
+ intercept,84,4242424326,0.6267238368745893,60,99.14313411902761,0.0
387
+ intercept,85,4242424327,1.1180786813492887,60,99.87378109642233,0.0
388
+ intercept,86,4242424328,1.0531825890648179,60,99.90759275984404,0.0
389
+ intercept,87,4242424329,0.7319892354425974,60,99.07934787032669,0.0
390
+ intercept,88,4242424330,1.1460731038823724,60,98.32584786308246,0.0
391
+ intercept,89,4242424331,1.145515855285339,60,99.853580446333,0.0
392
+ intercept,90,4242424332,3.1438898412743583,60,98.23875463665809,0.0
393
+ intercept,91,4242424333,1.1678254807484336,60,99.94300368083988,0.0
394
+ intercept,92,4242424334,1.1468605129048228,60,98.28856657896678,0.0
395
+ intercept,93,4242424335,2.816772125195712,60,99.10609232867152,0.0
396
+ intercept,94,4242424336,1.1577836629003286,60,99.93574594730708,0.0
397
+ intercept,95,4242424337,1.0533778404060286,60,99.92123883389186,0.0
398
+ intercept,96,4242424338,0.8533297177054919,60,99.06174133027585,0.0
399
+ intercept,97,4242424339,0.7617567333800253,60,99.95316521359209,0.0
400
+ intercept,98,4242424340,0.9895546428160742,60,99.11385213912092,0.0
401
+ intercept,99,4242424341,0.770722996792756,60,99.44169788411487,0.0
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/comparison.csv ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ task,episodes,return_mean,return_sd,length_mean,length_sd,success_count,success_rate,invalid_actions,dropped_actions
2
+ flappy,100,384.8240045265853,116.78777394316903,3119.31,939.8693174585497,,,0,64
3
+ deadly_corridor,100,1620.7987757873534,913.6242782186637,148.53,49.455930888013825,,,0,0
4
+ ant,100,1453.844063807972,693.7275200567642,803.85,328.8088312378486,,,0,0
5
+ intercept,100,3.5443485127069287,7.07192296411853,60.0,0.0,9,0.09,0,10
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/comparison.json ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "condition": "profile-latency",
3
+ "executor_mode": "simulated",
4
+ "latency_method": "temporal/profile_sample",
5
+ "episodes_per_checkpoint": 100,
6
+ "total_episodes": 400,
7
+ "checkpoints_metadata_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
8
+ "results": {
9
+ "flappy": {
10
+ "n_episodes": 100,
11
+ "mean_return": 384.8240045265853,
12
+ "std_return": 116.78777394316903,
13
+ "min_return": 36.60000045597553,
14
+ "max_return": 444.6000052243471,
15
+ "mean_length": 3119.31,
16
+ "std_length": 939.8693174585497,
17
+ "min_length": 314.0,
18
+ "max_length": 3600.0,
19
+ "return_field": "episode_return_env",
20
+ "length_field": "survival_steps",
21
+ "mode": "simulated",
22
+ "policy_id": "starvla",
23
+ "env_id": "flappy",
24
+ "model_id": "openvla",
25
+ "gpu_class": "1x-rtx3090",
26
+ "workload_id": "flappy",
27
+ "instance_id": "instance_a5037b165aa0cedc",
28
+ "source_run_id": "20260914T122201421825Z",
29
+ "profile_ref": null,
30
+ "env_fps": 10.0,
31
+ "obs_fps": 10.0,
32
+ "frame_ms": 100.0,
33
+ "latency_type": "profile_sample",
34
+ "task": "flappy",
35
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
36
+ "checkpoint_path": "latency-aware/flappy/vla/starvla-qwenoft-h1/flappy-qwenoft-mean-3090-s42",
37
+ "profile_sha256": "c266cba7ebac05c7e37bc83f1f16fe4b27dab97942ff43290e6c41514f6e39fc",
38
+ "condition": "profile-latency",
39
+ "invalid_actions": 0,
40
+ "dropped_actions": 64,
41
+ "unique_seeds": 100,
42
+ "physical_gpu": 2,
43
+ "eval_config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/flappy.yaml",
44
+ "execution_audit": {
45
+ "issued_action_records": 311075,
46
+ "applied_action_records": 310911,
47
+ "dropped_action_records": 64,
48
+ "nonnoop_issued_records": 30817,
49
+ "finite_action_values": true,
50
+ "latency_sample_count": 311075,
51
+ "latency_mean_ms": 75.89784633675906,
52
+ "latency_std_ms": 3.799946378622932,
53
+ "latency_p95_ms": 81.3960393048375,
54
+ "latency_p99_ms": 87.23844517488543
55
+ }
56
+ },
57
+ "deadly_corridor": {
58
+ "n_episodes": 100,
59
+ "mean_return": 1620.7987757873534,
60
+ "std_return": 913.6242782186637,
61
+ "min_return": -76.45918273925781,
62
+ "max_return": 2287.240921020508,
63
+ "mean_length": 148.53,
64
+ "std_length": 49.455930888013825,
65
+ "min_length": 17.0,
66
+ "max_length": 199.0,
67
+ "return_field": "episode_return_env",
68
+ "length_field": "survival_steps",
69
+ "mode": "simulated",
70
+ "policy_id": "starvla",
71
+ "env_id": "doom_deadly_corridor",
72
+ "model_id": "openvla",
73
+ "gpu_class": "1x-rtx3090",
74
+ "workload_id": "deadly_corridor",
75
+ "instance_id": "instance_a5037b165aa0cedc",
76
+ "source_run_id": "20260914T171446047509Z",
77
+ "profile_ref": null,
78
+ "env_fps": 35.0,
79
+ "obs_fps": 8.75,
80
+ "frame_ms": 28.571428571428573,
81
+ "latency_type": "profile_sample",
82
+ "task": "deadly_corridor",
83
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
84
+ "checkpoint_path": "latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42",
85
+ "profile_sha256": "bbfb93cef9f63750a9a159ec10a93a9fc6c25e4cb0cac3b39532663b4dc11eba",
86
+ "condition": "profile-latency",
87
+ "invalid_actions": 0,
88
+ "dropped_actions": 0,
89
+ "unique_seeds": 100,
90
+ "physical_gpu": 3,
91
+ "eval_config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/deadly_corridor.yaml",
92
+ "execution_audit": {
93
+ "issued_action_records": 3753,
94
+ "applied_action_records": 3673,
95
+ "dropped_action_records": 0,
96
+ "nonnoop_issued_records": 3753,
97
+ "finite_action_values": true,
98
+ "latency_sample_count": 3753,
99
+ "latency_mean_ms": 74.01999621872471,
100
+ "latency_std_ms": 5.5537519652567635,
101
+ "latency_p95_ms": 89.54825982614612,
102
+ "latency_p99_ms": 95.97310052501227
103
+ }
104
+ },
105
+ "ant": {
106
+ "n_episodes": 100,
107
+ "mean_return": 1453.844063807972,
108
+ "std_return": 693.7275200567642,
109
+ "min_return": 85.64836938561511,
110
+ "max_return": 2508.917122342891,
111
+ "mean_length": 803.85,
112
+ "std_length": 328.8088312378486,
113
+ "min_length": 60.0,
114
+ "max_length": 1000.0,
115
+ "return_field": "episode_return_env",
116
+ "length_field": "survival_steps",
117
+ "mode": "simulated",
118
+ "policy_id": "starvla",
119
+ "env_id": "LatencyBench/AntContinuous-v0",
120
+ "model_id": "qwenoft",
121
+ "gpu_class": "1x-rtx3090",
122
+ "workload_id": "ant",
123
+ "instance_id": "instance_859cf1e47bca6046",
124
+ "source_run_id": "20260911T033037730561Z",
125
+ "profile_ref": null,
126
+ "env_fps": 10.0,
127
+ "obs_fps": 10.0,
128
+ "frame_ms": 100.0,
129
+ "latency_type": "profile_sample",
130
+ "task": "ant",
131
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
132
+ "checkpoint_path": "latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42",
133
+ "profile_sha256": "0e49f72ec05ac600a54e07bbca5af3143708444d606167f33fa21788a9fefe50",
134
+ "condition": "profile-latency",
135
+ "invalid_actions": 0,
136
+ "dropped_actions": 0,
137
+ "unique_seeds": 100,
138
+ "physical_gpu": 2,
139
+ "eval_config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant.yaml",
140
+ "execution_audit": {
141
+ "issued_action_records": 79573,
142
+ "applied_action_records": 79465,
143
+ "dropped_action_records": 0,
144
+ "nonnoop_issued_records": 79573,
145
+ "finite_action_values": true,
146
+ "latency_sample_count": 79573,
147
+ "latency_mean_ms": 90.00919554158884,
148
+ "latency_std_ms": 2.514492574433973,
149
+ "latency_p95_ms": 91.11971585797141,
150
+ "latency_p99_ms": 102.67108120995428
151
+ }
152
+ },
153
+ "intercept": {
154
+ "n_episodes": 100,
155
+ "mean_return": 3.5443485127069287,
156
+ "std_return": 7.07192296411853,
157
+ "min_return": 0.6267238368745893,
158
+ "max_return": 29.923812823486514,
159
+ "mean_length": 60.0,
160
+ "std_length": 0.0,
161
+ "min_length": 60.0,
162
+ "max_length": 60.0,
163
+ "return_field": "episode_return_env",
164
+ "length_field": "survival_steps",
165
+ "mode": "simulated",
166
+ "policy_id": "starvla",
167
+ "env_id": "mikasa_intercept_grab_fast",
168
+ "model_id": "qwenoft",
169
+ "gpu_class": "1x-rtx3090",
170
+ "workload_id": "mikasa_intercept_grab_fast",
171
+ "instance_id": "instance_3a0d42681a03715c",
172
+ "source_run_id": "20260909T044501695676Z",
173
+ "profile_ref": null,
174
+ "env_fps": 20.0,
175
+ "obs_fps": 20.0,
176
+ "frame_ms": 50.0,
177
+ "latency_type": "profile_sample",
178
+ "task": "intercept",
179
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
180
+ "checkpoint_path": "latency-aware/mikasa-intercept-grab-fast/vla/starvla-qwenoft-h1/intercept-qwenoft-mean-3090-h1-s0",
181
+ "profile_sha256": "31a9b15d6b04182439934f0b377cb3d09be16ce21f3cf95c1049918f8a5d4984",
182
+ "condition": "profile-latency",
183
+ "invalid_actions": 0,
184
+ "dropped_actions": 10,
185
+ "unique_seeds": 100,
186
+ "physical_gpu": 3,
187
+ "eval_config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/intercept.yaml",
188
+ "success_count": 9,
189
+ "success_rate": 0.09,
190
+ "execution_audit": {
191
+ "issued_action_records": 2974,
192
+ "applied_action_records": 2864,
193
+ "dropped_action_records": 10,
194
+ "nonnoop_issued_records": 2974,
195
+ "finite_action_values": true,
196
+ "latency_sample_count": 2974,
197
+ "latency_mean_ms": 99.11060319379854,
198
+ "latency_std_ms": 4.301543980874005,
199
+ "latency_p95_ms": 100.2889407458356,
200
+ "latency_p99_ms": 100.64616770379737
201
+ }
202
+ }
203
+ },
204
+ "quality_acceptance": "not inferred; observed statistics only"
205
+ }
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/episodes.csv ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ episode_id,seed,return_env,length,mean_latency_ms,invalid_actions,dropped_actions
2
+ 0,42,1846.1103431567394,1000,89.89614608291177,0,0
3
+ 1,43,2415.720790707953,1000,90.00308114332259,0,0
4
+ 2,44,457.34421085068755,177,89.83716885697598,0,0
5
+ 3,45,1421.7952163289683,1000,89.87909631338808,0,0
6
+ 4,46,2037.7234409469488,937,89.82685347370092,0,0
7
+ 5,47,2330.630175869275,1000,90.47193606091501,0,0
8
+ 6,48,1161.643572255748,429,89.84194070141322,0,0
9
+ 7,49,2351.1524624990343,1000,89.92640891799017,0,0
10
+ 8,50,513.2964809479813,210,89.88895656571908,0,0
11
+ 9,51,1126.8652528911032,660,89.91361550654544,0,0
12
+ 10,52,1693.436933192597,1000,89.84960962337662,0,0
13
+ 11,53,948.3780972955639,1000,89.94678527711802,0,0
14
+ 12,54,2322.052445211472,1000,90.11873818885832,0,0
15
+ 13,55,960.4026770814776,1000,90.93377411320307,0,0
16
+ 14,56,1464.564005196777,1000,89.80893705661644,0,0
17
+ 15,57,1110.548792782156,1000,89.99466844889166,0,0
18
+ 16,58,2246.207900740156,1000,90.1624262080728,0,0
19
+ 17,59,85.64836938561511,60,89.87005518664785,0,0
20
+ 18,60,340.54799067574436,143,89.94240076131771,0,0
21
+ 19,61,2457.088748930458,1000,89.92054036086635,0,0
22
+ 20,62,2166.2512677098603,1000,89.95452553058773,0,0
23
+ 21,63,2357.957592244385,1000,89.86780458600198,0,0
24
+ 22,64,1654.8780938737275,871,90.08433827425095,0,0
25
+ 23,65,1499.367100151414,1000,89.89663615668341,0,0
26
+ 24,66,2297.4032619179525,1000,90.09818426014289,0,0
27
+ 25,67,1253.360764666355,543,89.9390124443734,0,0
28
+ 26,68,1221.270312709775,1000,89.84986177450952,0,0
29
+ 27,69,2389.2476464763376,1000,89.95772586857817,0,0
30
+ 28,70,1682.5290233886233,707,89.76145439054764,0,0
31
+ 29,71,2474.676425615127,1000,89.82093759631324,0,0
32
+ 30,72,382.9231146443659,256,90.69916524888657,0,0
33
+ 31,73,1837.8126619276347,1000,90.03642087221974,0,0
34
+ 32,74,227.19436616673684,101,89.8553742761573,0,0
35
+ 33,75,1700.6312067622644,1000,89.80097198453268,0,0
36
+ 34,76,960.9452812639541,372,89.8420903148968,0,0
37
+ 35,77,2290.6720141359438,1000,89.91770573449698,0,0
38
+ 36,78,328.5729178056416,162,90.01187187392946,0,0
39
+ 37,79,1180.073938772476,1000,89.81938304804656,0,0
40
+ 38,80,817.4190215442345,363,89.85140773938038,0,0
41
+ 39,81,1651.2255208727013,1000,91.17610023451576,0,0
42
+ 40,82,1428.174672693164,1000,89.8551155619885,0,0
43
+ 41,83,1627.3838925098842,1000,90.55986754698809,0,0
44
+ 42,84,1079.756369746183,680,90.17098553312343,0,0
45
+ 43,85,2173.9447393037276,1000,89.84319301261918,0,0
46
+ 44,86,409.90633829945847,160,89.66802828269809,0,0
47
+ 45,87,2467.2636019929073,1000,89.90844708827387,0,0
48
+ 46,88,657.4084558813478,248,89.86487149424892,0,0
49
+ 47,89,974.7436031610902,1000,89.76305094278182,0,0
50
+ 48,90,1510.5184342975385,1000,90.24355118464125,0,0
51
+ 49,91,602.2339441184535,260,89.7103209703719,0,0
52
+ 50,92,760.9784375126189,316,89.8206829517188,0,0
53
+ 51,93,1941.172113330597,1000,90.30785204408768,0,0
54
+ 52,94,624.3590446196446,281,89.94582387208622,0,0
55
+ 53,95,2163.4347041279893,1000,89.84848132390947,0,0
56
+ 54,96,1126.9957963444238,1000,89.84637728060243,0,0
57
+ 55,97,1405.131632695366,1000,90.18855922596491,0,0
58
+ 56,98,1206.2916757636292,1000,89.78065539051504,0,0
59
+ 57,99,2392.7980761515178,1000,89.76388668266138,0,0
60
+ 58,100,964.0216541467705,1000,89.82618651237911,0,0
61
+ 59,101,2252.192880003706,1000,89.8197082349776,0,0
62
+ 60,102,2471.9158497657563,1000,89.96642568195992,0,0
63
+ 61,103,1902.8491241623092,1000,89.87542708971246,0,0
64
+ 62,104,1435.6661382989703,1000,90.28644124851098,0,0
65
+ 63,105,1668.3237703695809,1000,89.86433221097877,0,0
66
+ 64,106,1813.291243529155,1000,89.85118001877315,0,0
67
+ 65,107,446.72353548541076,189,89.8309544306309,0,0
68
+ 66,108,130.84194814079504,74,89.82416773165995,0,0
69
+ 67,109,2315.857153770824,1000,90.25959750757508,0,0
70
+ 68,110,288.3915792961347,116,90.09271984792927,0,0
71
+ 69,111,894.0228631227924,1000,89.89663691508213,0,0
72
+ 70,112,2030.322535823717,1000,89.84028619017428,0,0
73
+ 71,113,507.9449555916754,215,90.57267432538549,0,0
74
+ 72,114,2377.7373967468293,1000,89.84919425782105,0,0
75
+ 73,115,897.3077114027096,1000,89.90431472264346,0,0
76
+ 74,116,1454.612590266188,1000,91.19515970740413,0,0
77
+ 75,117,2292.457960175467,1000,89.8333901030839,0,0
78
+ 76,118,1424.378337790017,1000,89.88029014661089,0,0
79
+ 77,119,1441.1111023164538,1000,89.79844243631413,0,0
80
+ 78,120,1265.4771503717611,1000,89.86009503143968,0,0
81
+ 79,121,1662.8808067819505,1000,90.5661722205243,0,0
82
+ 80,122,2508.917122342891,1000,89.87403626041336,0,0
83
+ 81,123,1655.3510139158748,1000,90.05039760075688,0,0
84
+ 82,124,1387.3843721247736,821,90.10235730111886,0,0
85
+ 83,125,646.4356689469432,271,89.7559653760994,0,0
86
+ 84,126,2172.801064037805,1000,89.84602989356796,0,0
87
+ 85,127,165.9213897970373,72,89.66756877688618,0,0
88
+ 86,128,1063.1483912161111,1000,89.77409215132576,0,0
89
+ 87,129,1000.135342286622,1000,89.81900933661238,0,0
90
+ 88,130,1977.2359176146426,1000,89.77653862908736,0,0
91
+ 89,131,1937.1674235355138,1000,90.12773943823525,0,0
92
+ 90,132,1344.7729257831547,1000,90.39620143170467,0,0
93
+ 91,133,786.3379828975102,441,89.82893206036925,0,0
94
+ 92,134,1391.060299752017,1000,89.86676880070257,0,0
95
+ 93,135,503.300235688713,250,89.94819176115624,0,0
96
+ 94,136,2446.7482357041768,1000,89.84848658183878,0,0
97
+ 95,137,1171.9102336514923,1000,89.92785850220504,0,0
98
+ 96,138,2356.7311711183065,1000,90.42933754946152,0,0
99
+ 97,139,2356.12199478712,1000,89.82049779117614,0,0
100
+ 98,140,1389.2987977192308,1000,90.82209581044775,0,0
101
+ 99,141,967.2335383727841,1000,89.80016695371027,0,0
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/eval_config.yaml ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ experiment:
2
+ name: ant-mean5000-profile-simulation-100ep
3
+ seed: 42
4
+ backend:
5
+ type: sample_factory
6
+ algo: APPO
7
+ device: cuda
8
+ train_dir: /mnt/checkpoints/latency-sensitive-bench/small_models/ant
9
+ restart_behavior: overwrite
10
+ run_mode: eval
11
+ executor:
12
+ mode: simulated
13
+ simulated_worker_capacity: 1
14
+ simulated_inference_pool: true
15
+ inference_devices:
16
+ - cuda:0
17
+ inference_batch_size: 16
18
+ env:
19
+ action_space:
20
+ dtype: float32
21
+ high:
22
+ - 1.0
23
+ - 1.0
24
+ - 1.0
25
+ - 1.0
26
+ - 1.0
27
+ - 1.0
28
+ - 1.0
29
+ - 1.0
30
+ labels:
31
+ - back_right_hip_torque
32
+ - back_right_ankle_torque
33
+ - front_left_hip_torque
34
+ - front_left_ankle_torque
35
+ - front_right_hip_torque
36
+ - front_right_ankle_torque
37
+ - back_left_hip_torque
38
+ - back_left_ankle_torque
39
+ low:
40
+ - -1.0
41
+ - -1.0
42
+ - -1.0
43
+ - -1.0
44
+ - -1.0
45
+ - -1.0
46
+ - -1.0
47
+ - -1.0
48
+ type: box
49
+ base_prompt: Make the Ant move forward as fast as possible without falling. Predict
50
+ eight continuous torques in [-1, 1] ordered as back right hip, back right ankle,
51
+ front left hip, front left ankle, front right hip, front right ankle, back left
52
+ hip, and back left ankle.
53
+ env_fps: 10.0
54
+ env_id: LatencyBench/AntContinuous-v0
55
+ frame_stack: 1
56
+ make_kwargs:
57
+ base_env_id: Ant-v4
58
+ base_make_kwargs:
59
+ exclude_current_positions_from_observation: true
60
+ use_contact_forces: false
61
+ render_mode: rgb_array
62
+ noop_action:
63
+ - 0.0
64
+ - 0.0
65
+ - 0.0
66
+ - 0.0
67
+ - 0.0
68
+ - 0.0
69
+ - 0.0
70
+ - 0.0
71
+ obs_fps: 10.0
72
+ registration_imports:
73
+ - latency_bench.envs.gymnasium_ant
74
+ state_space:
75
+ labels:
76
+ - torso_z
77
+ - torso_quaternion_w
78
+ - torso_quaternion_x
79
+ - torso_quaternion_y
80
+ - torso_quaternion_z
81
+ - front_left_hip_angle
82
+ - front_left_ankle_angle
83
+ - front_right_hip_angle
84
+ - front_right_ankle_angle
85
+ - back_left_hip_angle
86
+ - back_left_ankle_angle
87
+ - back_right_hip_angle
88
+ - back_right_ankle_angle
89
+ - torso_x_velocity
90
+ - torso_y_velocity
91
+ - torso_z_velocity
92
+ - torso_angular_velocity_x
93
+ - torso_angular_velocity_y
94
+ - torso_angular_velocity_z
95
+ - front_left_hip_angular_velocity
96
+ - front_left_ankle_angular_velocity
97
+ - front_right_hip_angular_velocity
98
+ - front_right_ankle_angular_velocity
99
+ - back_left_hip_angular_velocity
100
+ - back_left_ankle_angular_velocity
101
+ - back_right_hip_angular_velocity
102
+ - back_right_ankle_angular_velocity
103
+ task_name: ant_rgb_state
104
+ name: gymnasium
105
+ obs_resize:
106
+ - 224
107
+ - 224
108
+ latency:
109
+ method: temporal
110
+ profile_path: /home/ubuntu/lzj/mean-profiling/reference/checkpoint-configs/latency-aware/ant/small-policy/sample-factory-qwenoft-rtx3090-v1/profile/profile.json
111
+ profile_worker_slot: 0
112
+ seed: 271828
113
+ add_latency_info: false
114
+ scheduler:
115
+ hold_policy: hold
116
+ ordering_policy: issue_order_fifo
117
+ policy:
118
+ type: starvla
119
+ checkpoint_path: /home/ubuntu/lzj/mean-profiling/ant/vla-publication/checkpoints/model.pt
120
+ model_config_path: /home/ubuntu/lzj/mean-profiling/ant/vla-publication/config.full.yaml
121
+ task_manifest_path: /home/ubuntu/lzj/mean-profiling/ant/vla-publication/manifest.json
122
+ device: cuda:0
123
+ latency_prompt_map_path: /home/ubuntu/lzj/mean-profiling/ant/vla-publication/latency_prompt_map.json
124
+ latency_prompt_key: 1
125
+ prompt_mode: raw
126
+ unnorm_key: new_embodiment
127
+ backbone_path: /home/ubuntu/lzj/models/Qwen3-VL-4B-Instruct
128
+ worker_python_executable: /home/ubuntu/lzj/conda/envs/qwenoft/bin/python
129
+ training:
130
+ train_for_env_steps: 10000000
131
+ num_workers: 8
132
+ num_envs_per_worker: 8
133
+ worker_num_splits: 2
134
+ num_policies: 1
135
+ batch_size: 1024
136
+ rollout: 64
137
+ recurrence: 1
138
+ num_epochs: 2
139
+ num_batches_per_epoch: 4
140
+ num_batches_to_accumulate: 2
141
+ policy_workers_per_policy: 1
142
+ max_policy_lag: 10000
143
+ learning_rate: 0.00295
144
+ lr_schedule: linear_decay
145
+ lr_schedule_kl_threshold: 0.008
146
+ gamma: 0.99
147
+ gae_lambda: 0.95
148
+ ppo_clip_ratio: 0.2
149
+ ppo_clip_value: 1.0
150
+ value_loss_coeff: 1.3
151
+ max_grad_norm: 3.5
152
+ exploration_loss: entropy
153
+ exploration_loss_coeff: 0.0
154
+ kl_loss_coeff: 0.1
155
+ reward_scale: 1.0
156
+ reward_clip: 1000.0
157
+ async_rl: false
158
+ serial_mode: false
159
+ batched_sampling: false
160
+ with_vtrace: false
161
+ use_rnn: false
162
+ encoder_mlp_layers:
163
+ - 64
164
+ - 64
165
+ nonlinearity: tanh
166
+ adaptive_stddev: false
167
+ policy_initialization: torch_default
168
+ initial_stddev: 1.0
169
+ actor_critic_share_weights: true
170
+ shuffle_minibatches: false
171
+ value_bootstrap: true
172
+ normalize_input: true
173
+ normalize_returns: true
174
+ decorrelate_experience_max_seconds: 10
175
+ decorrelate_envs_on_one_worker: true
176
+ set_workers_cpu_affinity: true
177
+ force_envs_single_thread: true
178
+ save_every_sec: 600
179
+ keep_checkpoints: 3
180
+ save_best_every_sec: 60
181
+ save_best_after: 100000
182
+ evaluation:
183
+ eval_interval_steps: null
184
+ eval_episodes: 100
185
+ eval_parallel_envs: 16
186
+ eval_max_steps: 1000
187
+ eval_deterministic: true
188
+ eval_latency_values: null
189
+ eval_raw_reward: true
190
+ eval_suites:
191
+ fixed: []
192
+ normal: []
193
+ uniform: []
194
+ logging:
195
+ output_dir: /home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant
196
+ video:
197
+ enabled: false
198
+ save_step_records: true
199
+ save_action_records: true
200
+ save_latency_records: true
201
+ wandb_project: null
202
+ wandb_group: null
203
+ wandb_job_type: null
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/batched_simulated.py ADDED
@@ -0,0 +1,702 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import time
4
+ from collections.abc import Callable, Mapping, Sequence
5
+ from dataclasses import dataclass, field
6
+ from pathlib import Path
7
+
8
+ import numpy as np
9
+
10
+ from latency_bench.core.clock import EnvClock
11
+ from latency_bench.core.decision_action_history import DecisionActionHistory
12
+ from latency_bench.core.timing import StageProfiler, profiler_scope
13
+ from latency_bench.core.types import ActionEvent, EpisodeMetrics, LatencyRecord, Observation, StepRecord
14
+ from latency_bench.envs.atari import TRUE_EPISODE_END_INFO_KEY
15
+ from latency_bench.envs.base import EnvAdapter
16
+ from latency_bench.executors._simulated_timeline import (
17
+ SimulatedResultTimeline,
18
+ SimulatedWorkerCapacity,
19
+ build_simulated_action_event,
20
+ )
21
+ from latency_bench.executors.base import BatchedExecutor
22
+ from latency_bench.executors.env_step_backend import EnvStepBackend, env_action_space
23
+ from latency_bench.latency.sample import LatencySample
24
+ from latency_bench.latency.samplers import LatencySampler
25
+ from latency_bench.logging.metrics import (
26
+ compute_episode_metrics,
27
+ compute_episode_metrics_from_aggregates,
28
+ episode_raw_fact_metadata,
29
+ latency_type_from_source,
30
+ profile_metadata_from_source,
31
+ )
32
+ from latency_bench.logging.records import build_step_record
33
+ from latency_bench.logging.trajectory_logger import TrajectoryLogger
34
+ from latency_bench.policy.action_prefix import with_action_prefix
35
+ from latency_bench.policy.base import PolicyRunner
36
+ from latency_bench.scheduler.action_queue import ActionScheduler
37
+ from latency_bench.scheduler.decision import DecisionScheduler
38
+ from latency_bench.utils.io import write_json
39
+ from latency_bench.utils.stats import series_stats
40
+
41
+
42
+ @dataclass
43
+ class _EpisodeBuffers:
44
+ step_records: list[StepRecord] | None = None
45
+ action_events: list[ActionEvent] | None = None
46
+ latency_records: list[LatencyRecord] | None = None
47
+ latency_values_ms: list[float] = field(default_factory=list)
48
+ episode_return_env: float = 0.0
49
+ survival_steps: int = 0
50
+ game_score: float | None = None
51
+ return_raw: float | None = None
52
+ num_actions: int = 0
53
+ num_dropped_actions: int = 0
54
+ num_invalid_actions: int = 0
55
+ submitted_observation_frames: int = 0
56
+ dropped_observation_count: int = 0
57
+ soft_reset_count: int = 0
58
+ final_lives: int | None = None
59
+ final_is_true_episode_end: bool | None = None
60
+ task_metrics: dict | None = None
61
+ task_metric_moments: dict | None = None
62
+
63
+ def record_step(self, *, reward: float, info: dict) -> None:
64
+ self.episode_return_env += float(reward)
65
+ self.survival_steps += 1
66
+ if "invalid_action" in info and info["invalid_action"]:
67
+ self.num_invalid_actions += 1
68
+ if "soft_reset" in info and info["soft_reset"]:
69
+ self.soft_reset_count += 1
70
+ if "lives" in info:
71
+ self.final_lives = info["lives"]
72
+ if TRUE_EPISODE_END_INFO_KEY in info:
73
+ self.final_is_true_episode_end = info[TRUE_EPISODE_END_INFO_KEY]
74
+ if "game_score" in info:
75
+ self.game_score = float(info["game_score"])
76
+ if "score" in info:
77
+ self.game_score = float(info["score"])
78
+ if "task_metrics" in info:
79
+ self.task_metrics = info["task_metrics"]
80
+ if "task_metric_moments" in info:
81
+ self.task_metric_moments = info["task_metric_moments"]
82
+ self._update_return_raw(info)
83
+ extra_stats = info["episode_extra_stats"] if "episode_extra_stats" in info else None
84
+ if isinstance(extra_stats, dict):
85
+ self._update_return_raw(extra_stats)
86
+
87
+ def _update_return_raw(self, stats: dict) -> None:
88
+ for key in ("return_raw", "raw_return", "episodic_raw_return", "episode/raw_return"):
89
+ if key in stats and stats[key] is not None:
90
+ self.return_raw = float(stats[key])
91
+
92
+
93
+ @dataclass
94
+ class _SlotState:
95
+ slot_id: int
96
+ env: EnvAdapter
97
+ latency_source: LatencySampler
98
+ action_scheduler: ActionScheduler
99
+ result_timeline: SimulatedResultTimeline
100
+ active: bool = False
101
+ episode_id: int | None = None
102
+ episode_seed: int | None = None
103
+ env_step: int = 0
104
+ recent_drop_count: int = 0
105
+ decision_action_history: DecisionActionHistory | None = None
106
+ decision_admitted: bool = False
107
+ decision_issued_action: object = None
108
+ buffers: _EpisodeBuffers = field(default_factory=_EpisodeBuffers)
109
+ worker_capacity: SimulatedWorkerCapacity = field(
110
+ default_factory=lambda: SimulatedWorkerCapacity(capacity=None, busy_until_by_worker={})
111
+ )
112
+
113
+
114
+ @dataclass
115
+ class _PendingPolicyObservation:
116
+ slot: _SlotState
117
+ observation: Observation
118
+ obs_id: int
119
+ latency_sample: LatencySample
120
+ worker_slot: int
121
+
122
+
123
+ class BatchedSimulatedLatencyExecutor(BatchedExecutor):
124
+ """Run multiple simulated episodes concurrently with independent slot state.
125
+
126
+ The main process owns policy inference, latency scheduling, episode accounting,
127
+ and logging. Env stepping can be serial in-process or delegated to worker
128
+ subprocesses through env_backend.
129
+ """
130
+
131
+ def __init__(
132
+ self,
133
+ *,
134
+ env_backend: EnvStepBackend,
135
+ policy: PolicyRunner,
136
+ decision_scheduler: DecisionScheduler,
137
+ latency_sources: Sequence[LatencySampler],
138
+ action_schedulers: Sequence[ActionScheduler],
139
+ clock: EnvClock,
140
+ logger: TrajectoryLogger | None = None,
141
+ episode_latency_source_factory: Callable[[int], LatencySampler] | None = None,
142
+ simulated_worker_capacity: int | None = None,
143
+ profile_pipeline: bool = False,
144
+ inference_pool=None,
145
+ action_prefix=None,
146
+ action_history_decisions: int | None = None,
147
+ ):
148
+ slot_count = env_backend.num_slots
149
+ self.env_backend = env_backend
150
+ self.envs = list(env_backend.slot_handles)
151
+ self.policy = policy
152
+ self.decision_scheduler = decision_scheduler
153
+ self.clock = clock
154
+ self.logger = logger
155
+ self.profile_pipeline = bool(profile_pipeline)
156
+ self.inference_pool = inference_pool
157
+ self.action_prefix = action_prefix
158
+ self._pipeline_profile_rows: list[dict[str, float]] = []
159
+ self.simulated_worker_capacity = simulated_worker_capacity
160
+ self._collect_step_records = bool(logger is not None and logger.save_step_records)
161
+ self._collect_action_records = bool(logger is not None and logger.save_action_records)
162
+ self._collect_latency_records = bool(logger is not None and logger.save_latency_records)
163
+ self.episode_latency_source_factory = episode_latency_source_factory
164
+ self.slots = [
165
+ _SlotState(
166
+ slot_id=slot_id,
167
+ env=self.envs[slot_id],
168
+ latency_source=latency_sources[slot_id],
169
+ action_scheduler=action_schedulers[slot_id],
170
+ result_timeline=SimulatedResultTimeline(
171
+ ordering_policy=action_schedulers[slot_id].ordering_policy
172
+ ),
173
+ decision_action_history=(
174
+ DecisionActionHistory(
175
+ env_action_space(self.envs[slot_id]), num_envs=1, decisions=action_history_decisions
176
+ ) if action_history_decisions is not None else None
177
+ ),
178
+ buffers=self._new_episode_buffers(),
179
+ worker_capacity=SimulatedWorkerCapacity(
180
+ capacity=simulated_worker_capacity,
181
+ busy_until_by_worker={},
182
+ ),
183
+ )
184
+ for slot_id in range(slot_count)
185
+ ]
186
+ self._next_obs_id = 0
187
+ self._next_action_id = 0
188
+ self.started_episodes = 0
189
+ self.completed_episodes = 0
190
+ self._completed_metrics: dict[int, EpisodeMetrics] = {}
191
+ self._completed_buffers: dict[int, _EpisodeBuffers] = {}
192
+ self._episode_log_order: list[int] = []
193
+ self._next_episode_log_index = 0
194
+
195
+ @property
196
+ def num_slots(self) -> int:
197
+ return len(self.slots)
198
+
199
+ def close(self) -> None:
200
+ if self.inference_pool is not None:
201
+ self.inference_pool.close()
202
+ self.env_backend.close()
203
+
204
+ def run_episodes(
205
+ self,
206
+ *,
207
+ episode_ids: Sequence[int],
208
+ seeds: Sequence[int | None],
209
+ eval_max_steps: int = 10000,
210
+ on_episode_complete: Callable[[EpisodeMetrics], None] | None = None,
211
+ ) -> list[EpisodeMetrics]:
212
+ if eval_max_steps < 0:
213
+ raise ValueError("eval_max_steps must be non-negative")
214
+ episode_ids = [int(episode_id) for episode_id in episode_ids]
215
+ if len(seeds) != len(episode_ids):
216
+ raise ValueError("seeds length must match episode_ids length")
217
+
218
+ self._reset_run_state(episode_ids)
219
+ if not episode_ids:
220
+ return []
221
+
222
+ next_episode_index = 0
223
+ initial_slots = min(self.num_slots, len(episode_ids))
224
+ for slot in self.slots[:initial_slots]:
225
+ self._start_slot(
226
+ slot,
227
+ episode_id=episode_ids[next_episode_index],
228
+ seed=seeds[next_episode_index],
229
+ )
230
+ next_episode_index += 1
231
+
232
+ while self.completed_episodes < len(episode_ids):
233
+ active_slots = self._active_slots()
234
+ if eval_max_steps == 0:
235
+ for slot in active_slots:
236
+ self._complete_slot(slot, on_episode_complete=on_episode_complete)
237
+ if next_episode_index < len(episode_ids):
238
+ self._start_slot(
239
+ slot,
240
+ episode_id=episode_ids[next_episode_index],
241
+ seed=seeds[next_episode_index],
242
+ )
243
+ next_episode_index += 1
244
+ continue
245
+
246
+ observations = []
247
+ observation_slots: list[_SlotState] = []
248
+ step_capacity_info: dict[int, dict[str, int | bool | None]] = {}
249
+ for slot in active_slots:
250
+ current_time_ms = self.clock.step_to_time_ms(slot.env_step)
251
+ slot.worker_capacity.release_ready(slot.env_step)
252
+ self._deliver_arrived_results(slot, raw_frame=slot.env_step)
253
+ observation_submitted = False
254
+ observation_dropped = False
255
+ if self.decision_scheduler.should_observe(slot.env_step, current_time_ms):
256
+ prefix_request_pending = (
257
+ self.action_prefix is not None
258
+ and self.action_prefix["mode"] != "none"
259
+ and slot.result_timeline.pending_observation_count > 0
260
+ )
261
+ if slot.worker_capacity.can_submit() and not prefix_request_pending:
262
+ observation_slots.append(slot)
263
+ observation_submitted = True
264
+ else:
265
+ slot.buffers.dropped_observation_count += 1
266
+ observation_dropped = True
267
+ slot.recent_drop_count += 1
268
+ if self.simulated_worker_capacity is not None:
269
+ step_capacity_info[slot.slot_id] = {
270
+ "observation_submitted": observation_submitted,
271
+ "observation_dropped": observation_dropped,
272
+ }
273
+ if slot.decision_action_history is not None and slot.env_step % self.clock.obs_stride_raw_frames == 0:
274
+ slot.decision_admitted = observation_submitted
275
+ slot.decision_issued_action = slot.action_scheduler.noop_action.value
276
+
277
+ observe_ms = 0.0
278
+ if observation_slots:
279
+ observe_start = time.perf_counter()
280
+ observations_by_slot = self.env_backend.observe_slots([slot.slot_id for slot in observation_slots])
281
+ observe_ms = (time.perf_counter() - observe_start) * 1000.0
282
+ pending_observations = [
283
+ self._sample_policy_observation(
284
+ slot,
285
+ self._policy_observation(
286
+ slot,
287
+ observations_by_slot[slot.slot_id],
288
+ transport=(
289
+ slot.decision_action_history.observation()[0]
290
+ if slot.decision_action_history is not None else None
291
+ ),
292
+ ),
293
+ )
294
+ for slot in observation_slots
295
+ ]
296
+ observations = [pending.observation for pending in pending_observations]
297
+
298
+ profile_row = None
299
+ if observations:
300
+ profiler = StageProfiler(enabled=self.profile_pipeline)
301
+ with profiler_scope(profiler):
302
+ policy_outputs = (
303
+ self.inference_pool.predict_batch(observations)
304
+ if self.inference_pool is not None
305
+ else self.policy.predict_batch(observations)
306
+ )
307
+ if len(policy_outputs) != len(observations):
308
+ raise RuntimeError("policy.predict_batch returned the wrong number of outputs")
309
+ if self.profile_pipeline:
310
+ profile_row = {
311
+ "active_slots": float(len(active_slots)),
312
+ "batch_size": float(len(observations)),
313
+ "observe_slots_ms": observe_ms,
314
+ **{key: float(value) for key, value in profiler.timings.items()},
315
+ }
316
+ for pending, policy_output in zip(pending_observations, policy_outputs):
317
+ if pending.slot.decision_action_history is not None:
318
+ pending.slot.decision_issued_action = policy_output.action.value
319
+ self._enqueue_policy_output(
320
+ pending.slot,
321
+ pending.observation,
322
+ policy_output,
323
+ obs_id=pending.obs_id,
324
+ latency_sample=pending.latency_sample,
325
+ worker_slot=pending.worker_slot,
326
+ )
327
+
328
+ actions_by_slot = {}
329
+ for slot in active_slots:
330
+ current_time_ms = self.clock.step_to_time_ms(slot.env_step)
331
+ self._deliver_arrived_results(slot, raw_frame=slot.env_step)
332
+ active_action = slot.action_scheduler.update(slot.env_step, current_time_ms)
333
+ actions_by_slot[slot.slot_id] = active_action
334
+
335
+ env_step_start = time.perf_counter()
336
+ step_responses = self.env_backend.step_slots(actions_by_slot)
337
+ if profile_row is not None:
338
+ profile_row["env_step_ms"] = (time.perf_counter() - env_step_start) * 1000.0
339
+ self._pipeline_profile_rows.append(profile_row)
340
+ for slot in active_slots:
341
+ current_time_ms = self.clock.step_to_time_ms(slot.env_step)
342
+ active_action = actions_by_slot[slot.slot_id]
343
+ if (
344
+ slot.decision_action_history is not None
345
+ and (slot.env_step + 1) % self.clock.obs_stride_raw_frames == 0
346
+ ):
347
+ slot.decision_action_history.append(
348
+ [0], [slot.decision_admitted],
349
+ [slot.decision_issued_action], [active_action.value],
350
+ )
351
+ result = step_responses[slot.slot_id].result
352
+ soft_reset = bool(result.info.get("soft_reset")) if isinstance(result.info, dict) else False
353
+ episode_done = bool(result.done or result.truncated) and not soft_reset
354
+ if slot.buffers.step_records is not None:
355
+ record = build_step_record(
356
+ episode_id=int(slot.episode_id),
357
+ env_step=slot.env_step,
358
+ scheduled_time_ms=current_time_ms,
359
+ active_action=active_action,
360
+ reward=result.reward,
361
+ done=episode_done,
362
+ info=result.info,
363
+ active_event=slot.action_scheduler.latest_applied_event,
364
+ frame_ms=self.clock.frame_ms,
365
+ latency_type=latency_type_from_source(slot.latency_source),
366
+ )
367
+ slot.buffers.step_records.append(record)
368
+ slot.buffers.record_step(reward=float(result.reward), info=record.info)
369
+ else:
370
+ slot.buffers.record_step(reward=float(result.reward), info=result.info)
371
+ if self.simulated_worker_capacity is not None and slot.buffers.step_records is not None:
372
+ slot.buffers.step_records[-1].info.update(
373
+ {
374
+ **step_capacity_info[slot.slot_id],
375
+ "in_flight_count": slot.worker_capacity.in_flight_count,
376
+ "idle_worker_count": slot.worker_capacity.idle_worker_count,
377
+ }
378
+ )
379
+ if soft_reset:
380
+ slot.buffers.num_dropped_actions += slot.action_scheduler.dropped_events_count
381
+ slot.action_scheduler.reset()
382
+ slot.result_timeline.reset()
383
+ self._reset_policy_state(slot.slot_id)
384
+ slot.worker_capacity.reset()
385
+ if slot.decision_action_history is not None:
386
+ slot.decision_action_history.reset()
387
+ slot.recent_drop_count = 0
388
+
389
+ slot.env_step += 1
390
+ if episode_done or slot.env_step >= eval_max_steps:
391
+ self._complete_slot(slot, on_episode_complete=on_episode_complete)
392
+ if next_episode_index < len(episode_ids):
393
+ self._start_slot(
394
+ slot,
395
+ episode_id=episode_ids[next_episode_index],
396
+ seed=seeds[next_episode_index],
397
+ )
398
+ next_episode_index += 1
399
+
400
+ self._write_pipeline_profile_summary()
401
+ return self._ordered_metrics(episode_ids)
402
+
403
+ def _policy_observation(
404
+ self,
405
+ slot: _SlotState,
406
+ observation: Observation,
407
+ transport: np.ndarray | None = None,
408
+ ) -> Observation:
409
+ observation = with_action_prefix(observation, slot.action_scheduler, self.action_prefix)
410
+ metadata = dict(observation.metadata)
411
+ metadata["slot_id"] = slot.slot_id
412
+ metadata["episode_id"] = int(slot.episode_id)
413
+ metadata["action_noise_seed"] = slot.episode_seed
414
+ data = observation.data
415
+ if transport is not None:
416
+ data = {**data, "transport": transport} if isinstance(data, Mapping) else {"obs": data, "transport": transport}
417
+ return Observation(
418
+ data=data,
419
+ env_step=observation.env_step,
420
+ sim_time_ms=observation.sim_time_ms,
421
+ metadata=metadata,
422
+ )
423
+
424
+ def _sample_policy_observation(
425
+ self,
426
+ slot: _SlotState,
427
+ observation: Observation,
428
+ ) -> _PendingPolicyObservation:
429
+ obs_id = self._next_obs_id
430
+ self._next_obs_id += 1
431
+ raw_frame = int(slot.env_step)
432
+ current_time_ms = self.clock.step_to_time_ms(raw_frame)
433
+ worker_slot = slot.worker_capacity.assign_worker()
434
+ latency_context = {
435
+ "observation": observation,
436
+ "obs_id": obs_id,
437
+ "env_step": raw_frame,
438
+ "raw_frame": raw_frame,
439
+ "sim_time_ms": current_time_ms,
440
+ "episode_id": slot.episode_id,
441
+ "slot_id": slot.slot_id,
442
+ "worker_slot": worker_slot,
443
+ "recent_drop_count": slot.recent_drop_count,
444
+ "in_flight_count": slot.worker_capacity.in_flight_count,
445
+ "idle_worker_count": slot.worker_capacity.idle_worker_count,
446
+ }
447
+ latency_sample = slot.latency_source.sample(latency_context)
448
+ metadata = dict(observation.metadata)
449
+ metadata["obs_id"] = obs_id
450
+ policy_observation = Observation(
451
+ data=observation.data,
452
+ env_step=observation.env_step,
453
+ sim_time_ms=observation.sim_time_ms,
454
+ metadata=metadata,
455
+ )
456
+ slot.worker_capacity.submit(
457
+ worker_slot, raw_frame + latency_sample.worker_service_raw_frames
458
+ )
459
+ return _PendingPolicyObservation(
460
+ slot=slot,
461
+ obs_id=obs_id,
462
+ latency_sample=latency_sample,
463
+ worker_slot=worker_slot,
464
+ observation=policy_observation,
465
+ )
466
+
467
+ def _reset_run_state(self, episode_ids: Sequence[int]) -> None:
468
+ self.started_episodes = 0
469
+ self.completed_episodes = 0
470
+ self._pipeline_profile_rows.clear()
471
+ self._completed_metrics.clear()
472
+ self._completed_buffers.clear()
473
+ self._episode_log_order = [int(episode_id) for episode_id in episode_ids]
474
+ self._next_episode_log_index = 0
475
+ for slot in self.slots:
476
+ slot.active = False
477
+ slot.episode_id = None
478
+ slot.episode_seed = None
479
+ slot.env_step = 0
480
+ slot.recent_drop_count = 0
481
+ slot.buffers = self._new_episode_buffers()
482
+ slot.action_scheduler.reset()
483
+ slot.result_timeline.reset()
484
+ slot.worker_capacity.reset()
485
+ if slot.decision_action_history is not None:
486
+ slot.decision_action_history.reset()
487
+
488
+ def _active_slots(self) -> list[_SlotState]:
489
+ return [slot for slot in self.slots if slot.active]
490
+
491
+ def _deliver_arrived_results(self, slot: _SlotState, *, raw_frame: int | None) -> None:
492
+ released, dropped = slot.result_timeline.release_arrived(raw_frame)
493
+ slot.buffers.num_dropped_actions += len(dropped)
494
+ for event in released:
495
+ slot.action_scheduler.enqueue(event)
496
+
497
+ def _start_slot(self, slot: _SlotState, *, episode_id: int, seed: int | None) -> None:
498
+ if self.episode_latency_source_factory is not None:
499
+ slot.latency_source = self.episode_latency_source_factory(episode_id)
500
+ slot.active = True
501
+ slot.episode_id = int(episode_id)
502
+ slot.episode_seed = None if seed is None else int(seed)
503
+ slot.env_step = 0
504
+ slot.recent_drop_count = 0
505
+ slot.buffers = self._new_episode_buffers()
506
+ slot.action_scheduler.reset()
507
+ slot.result_timeline.reset()
508
+ slot.worker_capacity.reset()
509
+ if slot.decision_action_history is not None:
510
+ slot.decision_action_history.reset()
511
+ self._reset_policy_state(slot.slot_id)
512
+ self.env_backend.reset_slot(slot.slot_id, episode_id=episode_id, seed=seed)
513
+ self.started_episodes += 1
514
+
515
+ def _reset_policy_state(self, slot_id: int) -> None:
516
+ if self.inference_pool is not None:
517
+ self.inference_pool.reset_state(slot_id)
518
+ else:
519
+ self.policy.reset_state(slot_id=slot_id)
520
+
521
+ def _complete_slot(
522
+ self,
523
+ slot: _SlotState,
524
+ *,
525
+ on_episode_complete: Callable[[EpisodeMetrics], None] | None = None,
526
+ ) -> None:
527
+ if not slot.active or slot.episode_id is None:
528
+ return
529
+ episode_id = int(slot.episode_id)
530
+ self._deliver_arrived_results(slot, raw_frame=None)
531
+ slot.buffers.num_dropped_actions += slot.action_scheduler.dropped_events_count
532
+ metrics = self._compute_episode_metrics(
533
+ episode_id=episode_id,
534
+ buffers=slot.buffers,
535
+ metadata=episode_raw_fact_metadata(
536
+ mode="simulated",
537
+ episode_seed=slot.episode_seed,
538
+ env_fps=self.clock.env_fps,
539
+ obs_fps=self.clock.obs_fps,
540
+ frame_ms=self.clock.frame_ms,
541
+ latency_type=latency_type_from_source(slot.latency_source),
542
+ latency_source=slot.latency_source,
543
+ )
544
+ | slot.action_scheduler.chunk_metrics()
545
+ | (
546
+ {
547
+ "submitted_observation_frames": slot.buffers.submitted_observation_frames,
548
+ "dropped_observation_count": slot.buffers.dropped_observation_count,
549
+ "simulated_worker_capacity": self.simulated_worker_capacity,
550
+ "inference_worker_count": self.simulated_worker_capacity,
551
+ "in_flight_count": slot.worker_capacity.in_flight_count,
552
+ "idle_worker_count": slot.worker_capacity.idle_worker_count,
553
+ }
554
+ if self.simulated_worker_capacity is not None
555
+ else {}
556
+ ),
557
+ )
558
+ self._completed_metrics[episode_id] = metrics
559
+ self._completed_buffers[episode_id] = slot.buffers
560
+ self.completed_episodes += 1
561
+ slot.active = False
562
+ slot.episode_id = None
563
+ slot.episode_seed = None
564
+ slot.env_step = 0
565
+ slot.recent_drop_count = 0
566
+ slot.buffers = self._new_episode_buffers()
567
+ slot.action_scheduler.reset()
568
+ slot.result_timeline.reset()
569
+ slot.worker_capacity.reset()
570
+ if slot.decision_action_history is not None:
571
+ slot.decision_action_history.reset()
572
+ self._flush_completed_in_episode_order()
573
+ if on_episode_complete is not None:
574
+ on_episode_complete(metrics)
575
+
576
+ def _enqueue_policy_output(
577
+ self,
578
+ slot: _SlotState,
579
+ observation,
580
+ policy_output,
581
+ *,
582
+ obs_id: int,
583
+ latency_sample: LatencySample,
584
+ worker_slot: int,
585
+ ) -> None:
586
+ raw_frame = int(slot.env_step)
587
+ latency_ms = latency_sample.latency_ms
588
+ ready_raw_frame = raw_frame + latency_sample.action_ready_raw_frames
589
+ ready_time_ms = self.clock.step_to_time_ms(ready_raw_frame)
590
+ latency_type = latency_type_from_source(slot.latency_source)
591
+ profile_metadata = profile_metadata_from_source(slot.latency_source)
592
+ slot_metadata = {
593
+ "episode_id": int(slot.episode_id),
594
+ "slot_id": int(slot.slot_id),
595
+ "worker_id": int(worker_slot),
596
+ }
597
+ latency_record, event = build_simulated_action_event(
598
+ action_id=self._next_action_id,
599
+ obs_id=obs_id,
600
+ policy_output=policy_output,
601
+ raw_frame=raw_frame,
602
+ ready_raw_frame=ready_raw_frame,
603
+ ready_time_ms=ready_time_ms,
604
+ latency_sample=latency_sample,
605
+ frame_ms=self.clock.frame_ms,
606
+ latency_type=latency_type,
607
+ profile_metadata=profile_metadata,
608
+ latency_record_metadata=slot_metadata,
609
+ extra_event_metadata=slot_metadata,
610
+ )
611
+ self._next_action_id += 1
612
+ slot.result_timeline.submit(obs_id=obs_id, ready_raw_frame=ready_raw_frame, event=event)
613
+ slot.buffers.submitted_observation_frames += 1
614
+ slot.recent_drop_count = 0
615
+ slot.buffers.num_actions += 1
616
+ if slot.buffers.action_events is not None:
617
+ slot.buffers.action_events.append(event)
618
+ slot.buffers.latency_values_ms.append(latency_ms)
619
+ if slot.buffers.latency_records is not None:
620
+ slot.buffers.latency_records.append(latency_record)
621
+
622
+ def _flush_completed_in_episode_order(self) -> None:
623
+ if self.logger is None:
624
+ return
625
+ while self._next_episode_log_index < len(self._episode_log_order):
626
+ episode_id = self._episode_log_order[self._next_episode_log_index]
627
+ if episode_id not in self._completed_metrics:
628
+ break
629
+ buffers = self._completed_buffers[episode_id]
630
+ metrics = self._completed_metrics[episode_id]
631
+ if buffers.step_records is not None:
632
+ for record in buffers.step_records:
633
+ self.logger.log_step(record)
634
+ if buffers.action_events is not None:
635
+ for event in buffers.action_events:
636
+ self.logger.log_action_event(event)
637
+ if buffers.latency_records is not None:
638
+ for latency_record in buffers.latency_records:
639
+ self.logger.log_latency(latency_record)
640
+ self.logger.log_episode_metrics(metrics)
641
+ self._next_episode_log_index += 1
642
+
643
+ def _ordered_metrics(self, episode_ids: Sequence[int]) -> list[EpisodeMetrics]:
644
+ return [self._completed_metrics[int(episode_id)] for episode_id in episode_ids]
645
+
646
+ def _new_episode_buffers(self) -> _EpisodeBuffers:
647
+ return _EpisodeBuffers(
648
+ step_records=[] if self._collect_step_records else None,
649
+ action_events=[] if self._collect_action_records else None,
650
+ latency_records=[] if self._collect_latency_records else None,
651
+ )
652
+
653
+ def _write_pipeline_profile_summary(self) -> None:
654
+ if not self.profile_pipeline or self.logger is None or not self._pipeline_profile_rows:
655
+ return
656
+ keys = sorted({key for row in self._pipeline_profile_rows for key in row})
657
+ summary = {
658
+ "num_profiled_batches": len(self._pipeline_profile_rows),
659
+ **{
660
+ key: series_stats([float(row[key]) for row in self._pipeline_profile_rows if key in row])
661
+ for key in keys
662
+ },
663
+ }
664
+ write_json(Path(self.logger.output_dir) / "simulated_pipeline_summary.json", summary)
665
+
666
+ def _compute_episode_metrics(
667
+ self,
668
+ *,
669
+ episode_id: int,
670
+ buffers: _EpisodeBuffers,
671
+ metadata: dict,
672
+ ) -> EpisodeMetrics:
673
+ if buffers.task_metrics is not None:
674
+ metadata["task_metrics"] = buffers.task_metrics
675
+ if buffers.task_metric_moments is not None:
676
+ metadata["task_metric_moments"] = buffers.task_metric_moments
677
+ if buffers.final_lives is not None:
678
+ metadata["final_lives"] = buffers.final_lives
679
+ if buffers.final_is_true_episode_end is not None:
680
+ metadata["final_is_true_episode_end"] = buffers.final_is_true_episode_end
681
+ metadata["soft_reset_count"] = buffers.soft_reset_count
682
+ if buffers.step_records is not None and buffers.action_events is not None:
683
+ return compute_episode_metrics(
684
+ episode_id=episode_id,
685
+ step_records=buffers.step_records,
686
+ action_events=buffers.action_events,
687
+ latency_values_ms=buffers.latency_values_ms,
688
+ metadata=metadata,
689
+ frame_ms=self.clock.frame_ms,
690
+ )
691
+ return compute_episode_metrics_from_aggregates(
692
+ episode_id=episode_id,
693
+ episode_return_env=buffers.episode_return_env,
694
+ survival_steps=buffers.survival_steps,
695
+ return_raw=buffers.return_raw,
696
+ game_score=buffers.game_score,
697
+ latency_values_ms=buffers.latency_values_ms,
698
+ num_actions=buffers.num_actions,
699
+ num_dropped_actions=buffers.num_dropped_actions,
700
+ num_invalid_actions=buffers.num_invalid_actions,
701
+ metadata=metadata,
702
+ )
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/deadly-compatibility.patch ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ diff --git a/latency_bench/envs/deadly_corridor.py b/latency_bench/envs/deadly_corridor.py
2
+ index 4dcaa48c..dc4d1186 100644
3
+ --- a/latency_bench/envs/deadly_corridor.py
4
+ +++ b/latency_bench/envs/deadly_corridor.py
5
+ @@ -5,7 +5,7 @@ from collections import deque
6
+ from typing import Any
7
+
8
+ import numpy as np
9
+ -from gymnasium.spaces import Box, Tuple
10
+ +from gymnasium.spaces import Box, MultiBinary, Tuple
11
+
12
+ from latency_bench.core.types import Action, Observation, StepResult
13
+ from latency_bench.envs.base import EnvAdapter
14
+ @@ -346,6 +346,7 @@ class DeadlyCorridorVlaEnvAdapter(EnvAdapter):
15
+ export_env_raw_rgb_frames: bool = True,
16
+ ):
17
+ import gymnasium as gym
18
+ + import vizdoom
19
+ import vizdoom.gymnasium_wrapper # noqa: F401 (registers the env ids)
20
+
21
+ env_cfg = config["env"]
22
+ @@ -360,30 +361,27 @@ class DeadlyCorridorVlaEnvAdapter(EnvAdapter):
23
+ )
24
+ if key in env_cfg
25
+ }
26
+ - attempts = [
27
+ - ("VizdoomDeadlyCorridor-MultiBinary-v1", {}),
28
+ - ("VizdoomDeadlyCorridor-MultiBinary-v0", {}),
29
+ - ("VizdoomDeadlyCorridor-v1", {"max_buttons_pressed": 0}),
30
+ - ("VizdoomDeadlyCorridor-v0", {"max_buttons_pressed": 0}),
31
+ - ]
32
+ - last_exc: Exception | None = None
33
+ - self.gym_env = None
34
+ - for env_id, kwargs in attempts:
35
+ - try:
36
+ - # frame_skip=1: the latency_bench scheduler advances obs_stride raw
37
+ - # frames per decision and holds the action between observations.
38
+ - self.gym_env = gym.make(
39
+ - env_id, render_mode="rgb_array", frame_skip=1, **render_options, **kwargs
40
+ - )
41
+ - self.env_id = env_id
42
+ - break
43
+ - except (gym.error.NameNotFound, gym.error.VersionNotFound, gym.error.NamespaceNotFound) as exc:
44
+ - last_exc = exc
45
+ - if self.gym_env is None:
46
+ - raise RuntimeError(f"Failed to create Deadly Corridor MultiBinary env: {last_exc}")
47
+ + # ViZDoom registers deadly_corridor.cfg under this official Gym ID.
48
+ + self.env_id = "VizdoomCorridor-v0"
49
+ + self.gym_env = gym.make(
50
+ + self.env_id, render_mode="rgb_array", frame_skip=1, max_buttons_pressed=0,
51
+ + )
52
+ + game = self.gym_env.unwrapped.game
53
+ + game.close()
54
+ + for key, value in render_options.items():
55
+ + if key == "screen_resolution":
56
+ + value = getattr(vizdoom.ScreenResolution, value)
57
+ + getattr(game, f"set_{key}")(value)
58
+ + game.init()
59
+ + self.gym_env.unwrapped.observation_space.spaces["screen"] = Box(
60
+ + 0, 255,
61
+ + shape=(game.get_screen_height(), game.get_screen_width(), game.get_screen_channels()),
62
+ + dtype=np.uint8,
63
+ + )
64
+
65
+ self._runtime_button_order = _deadly_runtime_button_names(self.gym_env)
66
+ self._num_buttons = len(self._runtime_button_order)
67
+ + self.gym_env.unwrapped.action_space = MultiBinary(self._num_buttons)
68
+ self.noop_action = noop_action or Action(
69
+ value=[0] * self._num_buttons, name="NOOP", is_noop=True
70
+ )
71
+ diff --git a/tests/integration/test_deadly_render_contract.py b/tests/integration/test_deadly_render_contract.py
72
+ index 535db22a..09894b1b 100644
73
+ --- a/tests/integration/test_deadly_render_contract.py
74
+ +++ b/tests/integration/test_deadly_render_contract.py
75
+ @@ -5,11 +5,13 @@ import json
76
+ import numpy as np
77
+ import pytest
78
+
79
+ -pytest.importorskip("vizdoom", minversion="1.3.0")
80
+ +pytest.importorskip("vizdoom", minversion="1.2.4")
81
+ pytest.importorskip("sample_factory")
82
+
83
+ from latency_bench.envs.deadly_corridor import DeadlyCorridorEnvAdapter, DeadlyCorridorVlaEnvAdapter
84
+ from latency_bench.envs.raw_rgb import ENV_RAW_RGB_FRAME_STACK_INFO_KEY
85
+ +from latency_bench.core.types import Action
86
+ +from gymnasium.spaces import MultiBinary
87
+ from scripts.tasks.decision_history.eval_vla_hist8 import evaluation_config
88
+
89
+
90
+ @@ -33,6 +35,9 @@ def test_hist8_deadly_vla_uses_the_teacher_resolution_and_hud(tmp_path):
91
+ # The health/ammo panel is stable across the two engine reset paths;
92
+ # the animated face and enemies can differ with their RNG streams.
93
+ np.testing.assert_array_equal(teacher_frame[-20:, :64], student_frame[-20:, :64])
94
+ + assert isinstance(student.gym_env.action_space, MultiBinary)
95
+ + step = student.step(Action(value=[1, 0, 0, 0, 0, 0, 1], name="forward_attack"))
96
+ + assert np.isfinite(step.reward)
97
+ finally:
98
+ teacher.close()
99
+ student.close()
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/deadly_corridor.py ADDED
@@ -0,0 +1,455 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import copy
4
+ from collections import deque
5
+ from typing import Any
6
+
7
+ import numpy as np
8
+ from gymnasium.spaces import Box, MultiBinary, Tuple
9
+
10
+ from latency_bench.core.types import Action, Observation, StepResult
11
+ from latency_bench.envs.base import EnvAdapter
12
+ from latency_bench.utils.array import looks_chw
13
+ from latency_bench.envs.raw_rgb import RawRgbFrameStackBuffer
14
+
15
+
16
+ def _noop_action_from_space(space) -> Any:
17
+ n = getattr(space, "n", None)
18
+ if n is not None:
19
+ return 0
20
+ if isinstance(space, Tuple):
21
+ return tuple(_noop_action_from_space(subspace) for subspace in space.spaces)
22
+ if isinstance(space, Box):
23
+ import numpy as np
24
+
25
+ return np.zeros(space.shape, dtype=space.dtype)
26
+ raise TypeError(f"Unsupported action space for Deadly Corridor no-op action: {space}")
27
+
28
+
29
+ def _coerce_noop_action_for_space(value: Any, space) -> Any:
30
+ if isinstance(space, Tuple):
31
+ if isinstance(value, (list, tuple)):
32
+ if len(value) != len(space.spaces):
33
+ raise ValueError(
34
+ f"Deadly Corridor no-op action length {len(value)} does not match action space {space}"
35
+ )
36
+ return tuple(
37
+ _coerce_noop_action_for_space(item, subspace)
38
+ for item, subspace in zip(value, space.spaces)
39
+ )
40
+ if value == 0:
41
+ return _noop_action_from_space(space)
42
+ return value
43
+
44
+
45
+ def _spec_with_reward_scaling(spec: Any, disable_reward_scaling: bool) -> Any:
46
+ if not disable_reward_scaling:
47
+ return spec
48
+ spec_to_use = copy.copy(spec)
49
+ spec_to_use.reward_scaling = 1.0
50
+ return spec_to_use
51
+
52
+
53
+ def _synchronous_eval_fps_from_config(config: dict[str, Any], default: int = 35) -> int:
54
+ env_cfg = config.get("env", {})
55
+ try:
56
+ fps = int(float(env_cfg.get("env_fps", default)))
57
+ except (TypeError, ValueError) as exc:
58
+ raise ValueError("env_fps must be positive") from exc
59
+ if fps <= 0:
60
+ raise ValueError("env_fps must be positive")
61
+ return fps
62
+
63
+
64
+ def _build_sample_factory_eval_cfg(config: dict[str, Any]) -> Any:
65
+ from training.deadly_corridor_sf import integration
66
+ from training.common.utils import maybe_set_cli_override
67
+
68
+ integration.register_deadly_corridor_components()
69
+ base_cfg = integration.SAMPLE_FACTORY_CONFIG_PARSER.parse_eval(
70
+ integration.build_cli_args_from_config(config)
71
+ )
72
+ eval_fps = _synchronous_eval_fps_from_config(config)
73
+ cfg = copy.deepcopy(base_cfg)
74
+ if _requires_sample_factory_checkpoint_config(config):
75
+ from sample_factory.cfg.arguments import load_from_checkpoint
76
+
77
+ cfg = load_from_checkpoint(cfg)
78
+
79
+ for key in (
80
+ "seed",
81
+ "res_w",
82
+ "res_h",
83
+ "wide_aspect_ratio",
84
+ ):
85
+ if hasattr(base_cfg, key):
86
+ maybe_set_cli_override(cfg, key, getattr(base_cfg, key))
87
+ maybe_set_cli_override(cfg, "frame_stack", 1)
88
+ explicit_max_episode_steps = int(getattr(base_cfg, "max_episode_steps", 0) or 0)
89
+ if explicit_max_episode_steps > 0:
90
+ maybe_set_cli_override(cfg, "max_episode_steps", explicit_max_episode_steps)
91
+ else:
92
+ eval_max_steps = int(getattr(base_cfg, "eval_max_steps", 0) or 0)
93
+ if eval_max_steps > 0:
94
+ maybe_set_cli_override(cfg, "max_episode_steps", eval_max_steps)
95
+
96
+ maybe_set_cli_override(cfg, "mode", "eval")
97
+ maybe_set_cli_override(cfg, "latency_type", "zero")
98
+ maybe_set_cli_override(cfg, "fixed_latency_ms", 0.0)
99
+ maybe_set_cli_override(cfg, "env_frameskip", 1)
100
+ maybe_set_cli_override(cfg, "eval_env_frameskip", 1)
101
+ maybe_set_cli_override(cfg, "num_envs", 1)
102
+ maybe_set_cli_override(cfg, "no_render", True)
103
+ maybe_set_cli_override(cfg, "save_video", False)
104
+ maybe_set_cli_override(cfg, "fps", eval_fps)
105
+ maybe_set_cli_override(cfg, "eval_deterministic", bool(getattr(base_cfg, "eval_deterministic", True)))
106
+ maybe_set_cli_override(cfg, "disable_reward_scaling", bool(getattr(base_cfg, "eval_raw_reward", False)))
107
+ return cfg
108
+
109
+
110
+ def _requires_sample_factory_checkpoint_config(config: dict[str, Any]) -> bool:
111
+ policy_type = str(config.get("policy", {}).get("type", "")).strip().lower()
112
+ return policy_type == "deadly_corridor_sf"
113
+
114
+
115
+ def _seed_initialized_vizdoom_game(env: Any, seed: int) -> bool:
116
+ unwrapped = getattr(env, "unwrapped", env)
117
+ game = getattr(unwrapped, "game", None)
118
+ if game is None:
119
+ return False
120
+ unwrapped.seed(int(seed))
121
+ game.set_seed(int(unwrapped.curr_seed))
122
+ return True
123
+
124
+
125
+ class DeadlyCorridorEnvAdapter(EnvAdapter):
126
+ """Latency-bench adapter for ViZDoom Deadly Corridor using the SF Doom env stack."""
127
+ OBSERVATION_TYPE = "vizdoom_frame_v1"
128
+
129
+ def __init__(
130
+ self,
131
+ *,
132
+ config: dict[str, Any],
133
+ noop_action: Action | None = None,
134
+ export_env_raw_rgb_frames: bool = False,
135
+ ):
136
+ env_cfg = config["env"]
137
+ env_id = str(env_cfg.get("env_id", "doom_deadly_corridor"))
138
+ env_fps = float(env_cfg.get("env_fps", 35))
139
+ self.frame_stack = int(env_cfg.get("frame_stack", 1) or 1)
140
+
141
+ from sample_factory.utils.attr_dict import AttrDict
142
+ from sf_examples.vizdoom.doom.doom_utils import DOOM_ENVS, make_doom_env_from_spec
143
+
144
+ cfg = _build_sample_factory_eval_cfg(config)
145
+ spec = next((item for item in DOOM_ENVS if item.name == str(env_id)), None)
146
+ if spec is None:
147
+ raise ValueError(f"Unknown ViZDoom env spec: {env_id}")
148
+ spec_to_use = _spec_with_reward_scaling(
149
+ spec,
150
+ disable_reward_scaling=bool(getattr(cfg, "disable_reward_scaling", False)),
151
+ )
152
+ self.gym_env = make_doom_env_from_spec(
153
+ spec_to_use,
154
+ str(env_id),
155
+ cfg,
156
+ AttrDict(worker_index=0, vector_index=0, env_id=0),
157
+ render_mode=None,
158
+ )
159
+ self.cfg = cfg
160
+ self.env_id = env_id
161
+ self.env_fps = float(env_fps)
162
+ action_space = self.gym_env.action_space
163
+ noop_value = _noop_action_from_space(action_space)
164
+ if noop_action is None:
165
+ self.noop_action = Action(value=noop_value, name=str(noop_value), is_noop=True)
166
+ else:
167
+ coerced_noop_value = _coerce_noop_action_for_space(noop_action.value, action_space)
168
+ self.noop_action = Action(
169
+ value=coerced_noop_value,
170
+ name=str(coerced_noop_value),
171
+ is_noop=True,
172
+ is_oneshot=noop_action.is_oneshot,
173
+ )
174
+ self.env_step = 0
175
+ self.export_env_raw_rgb_frames = bool(export_env_raw_rgb_frames)
176
+ self._last_info: dict[str, Any] = {}
177
+ self._last_frame: Any = None
178
+ self._observed_frames: deque[np.ndarray] = deque(maxlen=self.frame_stack)
179
+ self._raw_rgb_frames = RawRgbFrameStackBuffer(num_frames=self.frame_stack)
180
+
181
+ def reset(self, seed: int | None = None) -> Observation:
182
+ self.env_step = 0
183
+ self._observed_frames.clear()
184
+ if seed is not None:
185
+ if _seed_initialized_vizdoom_game(self.gym_env, int(seed)):
186
+ obs, info = self.gym_env.reset()
187
+ else:
188
+ try:
189
+ obs, info = self.gym_env.reset(seed=seed)
190
+ except TypeError:
191
+ obs, info = self.gym_env.reset()
192
+ else:
193
+ obs, info = self.gym_env.reset()
194
+ self._last_frame = obs
195
+ self._last_info = dict(info or {})
196
+ self._reset_frame_stack(obs)
197
+ if self.export_env_raw_rgb_frames:
198
+ self._reset_raw_rgb_frame_stack()
199
+ return self._make_observation(info=self._last_info)
200
+
201
+ def step(self, action: Action) -> StepResult:
202
+ gym_action = action.value
203
+ obs, reward, terminated, truncated, info = self.gym_env.step(gym_action)
204
+ self.env_step += 1
205
+ self._last_frame = obs
206
+ self._last_info = dict(info or {})
207
+ self._append_frame(obs)
208
+ if self.export_env_raw_rgb_frames and not bool(terminated or truncated):
209
+ self._append_raw_rgb_frame()
210
+ observation = self._make_observation(info=self._last_info)
211
+ step_info = dict(self._last_info)
212
+ step_info.update(
213
+ {
214
+ "env_step": self.env_step,
215
+ "sim_time_ms": self.env_step * self.frame_ms,
216
+ "applied_action": gym_action,
217
+ "applied_action_name": action.name,
218
+ "observation": "vizdoom_frame_v1",
219
+ }
220
+ )
221
+ return StepResult(
222
+ observation=observation,
223
+ reward=float(reward),
224
+ done=bool(terminated),
225
+ truncated=bool(truncated),
226
+ info=step_info,
227
+ )
228
+
229
+ def observe(self) -> Observation:
230
+ if self._last_frame is None:
231
+ raise RuntimeError("DeadlyCorridorEnvAdapter has no current observation; call reset() first")
232
+ metadata = self._metadata(self._last_info)
233
+ return Observation(
234
+ data=self._policy_frame_stack(),
235
+ env_step=self.env_step,
236
+ sim_time_ms=self.env_step * self.frame_ms,
237
+ metadata=metadata,
238
+ )
239
+
240
+ def render_game_frame(self) -> np.ndarray:
241
+ return np.transpose(self.gym_env.unwrapped.game.get_state().screen_buffer, (1, 2, 0))
242
+
243
+ def close(self) -> None:
244
+ self.gym_env.close()
245
+
246
+ def _reset_frame_stack(self, frame: Any) -> None:
247
+ self._observed_frames.clear()
248
+ self._append_frame(frame)
249
+
250
+ def _append_frame(self, frame: Any) -> None:
251
+ self._observed_frames.append(_single_frame_data(frame))
252
+
253
+ def _policy_frame_stack(self) -> np.ndarray:
254
+ frames = list(self._observed_frames)
255
+ if not frames:
256
+ raise RuntimeError("Deadly Corridor observe() has no current frame; call reset() first")
257
+ if len(frames) < self.frame_stack:
258
+ frames = [frames[0]] * (self.frame_stack - len(frames)) + frames
259
+ frames = [np.asarray(frame, dtype=np.uint8) for frame in frames[-self.frame_stack :]]
260
+ if self.frame_stack == 1:
261
+ return frames[-1]
262
+ axis = 0 if looks_chw(frames[0]) else -1
263
+ return np.concatenate(frames, axis=axis)
264
+
265
+
266
+ def _single_frame_data(frame: Any) -> np.ndarray:
267
+ value = frame.get("obs") if isinstance(frame, dict) else frame
268
+ arr = np.asarray(value, dtype=np.uint8)
269
+ if arr.ndim == 2:
270
+ return arr[..., None]
271
+ if arr.ndim != 3:
272
+ raise ValueError(f"Expected Deadly Corridor image frame with 2 or 3 dims, got {arr.shape!r}")
273
+ return arr
274
+
275
+
276
+ # Fixed semantic button order the StarVLA multibinary head is trained against.
277
+ # Mirrors starVLA.training.rl_games.eval_core._semantic_to_runtime_multibinary.
278
+ DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER = (
279
+ "MOVE_FORWARD",
280
+ "MOVE_BACKWARD",
281
+ "MOVE_LEFT",
282
+ "MOVE_RIGHT",
283
+ "TURN_LEFT",
284
+ "TURN_RIGHT",
285
+ "ATTACK",
286
+ )
287
+
288
+
289
+ def _deadly_runtime_button_names(gym_env: Any) -> list[str]:
290
+ """Return the live ViZDoom action-button order (ports eval_core helper).
291
+
292
+ The MultiBinary action vector is indexed by the game's available-button
293
+ order, which is not guaranteed to equal the semantic order the head emits.
294
+ """
295
+
296
+ def _button_name(button: Any) -> str:
297
+ name = getattr(button, "name", None)
298
+ if name is not None:
299
+ return str(name)
300
+ text = str(button)
301
+ return text.split(".")[-1] if "." in text else text
302
+
303
+ for candidate in (gym_env, getattr(gym_env, "unwrapped", None)):
304
+ if candidate is None:
305
+ continue
306
+ for attr_name in ("game", "_game"):
307
+ game = getattr(candidate, attr_name, None)
308
+ if game is None:
309
+ continue
310
+ getter = getattr(game, "get_available_buttons", None)
311
+ if getter is None:
312
+ continue
313
+ names = [_button_name(button) for button in getter()]
314
+ if names:
315
+ return names
316
+ return list(DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER)
317
+
318
+
319
+ def _semantic_to_runtime_multibinary(semantic_values: list[int], runtime_order: list[str]) -> list[int]:
320
+ semantic_map = {
321
+ name: int(semantic_values[idx])
322
+ for idx, name in enumerate(DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER)
323
+ if idx < len(semantic_values)
324
+ }
325
+ return [semantic_map.get(name, 0) for name in runtime_order]
326
+
327
+
328
+ class DeadlyCorridorVlaEnvAdapter(EnvAdapter):
329
+ """Deadly Corridor adapter for StarVLA eval, matching eval_core's env.
330
+
331
+ Unlike :class:`DeadlyCorridorEnvAdapter` (sample_factory, factorised action
332
+ tuple), this uses the gymnasium ``VizdoomDeadlyCorridor-MultiBinary`` env so
333
+ the model's multibinary head can fire arbitrary button subsets, exactly like
334
+ ``starVLA.training.rl_games.eval_core``. Native ``frame_skip=1`` is used so
335
+ latency_bench's observation-cadence scheduler owns the obs_stride stepping
336
+ (see ObservationCadenceDecisionScheduler); setting a native skip would
337
+ double-count it.
338
+ """
339
+
340
+ OBSERVATION_TYPE = "vizdoom_frame_v1"
341
+
342
+ def __init__(
343
+ self,
344
+ *,
345
+ config: dict[str, Any],
346
+ noop_action: Action | None = None,
347
+ export_env_raw_rgb_frames: bool = True,
348
+ ):
349
+ import gymnasium as gym
350
+ import vizdoom
351
+ import vizdoom.gymnasium_wrapper # noqa: F401 (registers the env ids)
352
+
353
+ env_cfg = config["env"]
354
+ self.env_fps = float(env_cfg.get("env_fps", 35))
355
+ self.frame_stack = int(env_cfg.get("frame_stack", 1) or 1)
356
+ # The raw teacher view is part of the policy's observation contract.
357
+ render_options = {
358
+ key: env_cfg[key]
359
+ for key in (
360
+ "screen_resolution", "render_hud", "render_crosshair",
361
+ "render_weapon", "render_decals", "render_particles",
362
+ )
363
+ if key in env_cfg
364
+ }
365
+ # ViZDoom registers deadly_corridor.cfg under this official Gym ID.
366
+ self.env_id = "VizdoomCorridor-v0"
367
+ self.gym_env = gym.make(
368
+ self.env_id, render_mode="rgb_array", frame_skip=1, max_buttons_pressed=0,
369
+ )
370
+ game = self.gym_env.unwrapped.game
371
+ game.close()
372
+ for key, value in render_options.items():
373
+ if key == "screen_resolution":
374
+ value = getattr(vizdoom.ScreenResolution, value)
375
+ getattr(game, f"set_{key}")(value)
376
+ game.init()
377
+ self.gym_env.unwrapped.observation_space.spaces["screen"] = Box(
378
+ 0, 255,
379
+ shape=(game.get_screen_height(), game.get_screen_width(), game.get_screen_channels()),
380
+ dtype=np.uint8,
381
+ )
382
+
383
+ self._runtime_button_order = _deadly_runtime_button_names(self.gym_env)
384
+ self._num_buttons = len(self._runtime_button_order)
385
+ self.gym_env.unwrapped.action_space = MultiBinary(self._num_buttons)
386
+ self.noop_action = noop_action or Action(
387
+ value=[0] * self._num_buttons, name="NOOP", is_noop=True
388
+ )
389
+ self.export_env_raw_rgb_frames = bool(export_env_raw_rgb_frames)
390
+ self.env_step = 0
391
+ self._last_info: dict[str, Any] = {}
392
+ self._last_frame: Any = None
393
+ self._raw_rgb_frames = RawRgbFrameStackBuffer(num_frames=self.frame_stack)
394
+
395
+ def reset(self, seed: int | None = None) -> Observation:
396
+ self.env_step = 0
397
+ try:
398
+ obs, info = self.gym_env.reset(seed=seed)
399
+ except TypeError:
400
+ obs, info = self.gym_env.reset()
401
+ self._last_frame = obs
402
+ self._last_info = dict(info or {})
403
+ if self.export_env_raw_rgb_frames:
404
+ self._reset_raw_rgb_frame_stack()
405
+ return self._make_observation(info=self._last_info)
406
+
407
+ def step(self, action: Action) -> StepResult:
408
+ # action.value is a 7-dim multibinary vector in semantic order; re-order
409
+ # to the live game's button layout before stepping the MultiBinary env.
410
+ semantic = [int(v) for v in np.asarray(action.value).reshape(-1).tolist()]
411
+ expected = len(DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER)
412
+ if len(semantic) != expected:
413
+ raise ValueError(
414
+ "DeadlyCorridorVlaEnvAdapter expects a "
415
+ f"{expected}-dim multibinary action in semantic order, got "
416
+ f"{len(semantic)} values ({action.value!r}). This usually means the "
417
+ "policy decoded a non-multibinary layout; ensure the deadly head is "
418
+ "action_layout=multibinary_7 and reached the multibinary decode path."
419
+ )
420
+ runtime_buttons = _semantic_to_runtime_multibinary(semantic, self._runtime_button_order)
421
+ gym_action = np.asarray(runtime_buttons, dtype=np.int8)
422
+ obs, reward, terminated, truncated, info = self.gym_env.step(gym_action)
423
+ self.env_step += 1
424
+ self._last_frame = obs
425
+ self._last_info = dict(info or {})
426
+ if self.export_env_raw_rgb_frames and not bool(terminated or truncated):
427
+ self._append_raw_rgb_frame()
428
+ observation = self._make_observation(info=self._last_info)
429
+ step_info = dict(self._last_info)
430
+ step_info.update(
431
+ {
432
+ "env_step": self.env_step,
433
+ "sim_time_ms": self.env_step * self.frame_ms,
434
+ "applied_action": runtime_buttons,
435
+ "applied_action_name": action.name,
436
+ "observation": self.OBSERVATION_TYPE,
437
+ }
438
+ )
439
+ return StepResult(
440
+ observation=observation,
441
+ reward=float(reward),
442
+ done=bool(terminated),
443
+ truncated=bool(truncated),
444
+ info=step_info,
445
+ )
446
+
447
+ def observe(self) -> Observation:
448
+ return self._make_observation(info=self._last_info)
449
+
450
+ def render_game_frame(self) -> np.ndarray:
451
+ frame = self.gym_env.render()
452
+ return np.asarray(frame, dtype=np.uint8)
453
+
454
+ def close(self) -> None:
455
+ self.gym_env.close()
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/decision_action_history.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Causal action history sampled at completed decision boundaries."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import numpy as np
6
+ from gymnasium.spaces import Discrete, MultiBinary, Tuple
7
+
8
+
9
+ class DecisionActionHistory:
10
+ """Encode admission, admitted command, and last applied action for each decision."""
11
+
12
+ def __init__(self, action_space, *, num_envs: int, decisions: int):
13
+ self._multibinary = isinstance(action_space, MultiBinary)
14
+ if isinstance(action_space, Discrete):
15
+ self.action_sizes = (action_space.n,)
16
+ elif isinstance(action_space, Tuple) and all(isinstance(space, Discrete) for space in action_space.spaces):
17
+ self.action_sizes = tuple(space.n for space in action_space.spaces)
18
+ elif self._multibinary and action_space.shape == (7,):
19
+ self.action_sizes = (3, 3, 3, 2)
20
+ else:
21
+ raise NotImplementedError(f"Decision action history does not support {action_space!r}")
22
+ self.decisions = decisions
23
+ self.action_dim = sum(size - 1 for size in self.action_sizes)
24
+ self.step_dim = 1 + 2 * self.action_dim
25
+ self.data = np.zeros((num_envs, decisions, self.step_dim), dtype=np.float32)
26
+ self._basis = tuple(np.eye(size, dtype=np.float32)[:, 1:] for size in self.action_sizes)
27
+
28
+ @property
29
+ def observation_dim(self) -> int:
30
+ return self.decisions * self.step_dim
31
+
32
+ def reset(self, indices=None) -> None:
33
+ if indices is None:
34
+ self.data.fill(0)
35
+ else:
36
+ self.data[indices] = 0
37
+
38
+ def append(self, indices, admitted, issued_actions, applied_actions) -> None:
39
+ admitted = np.asarray(admitted, dtype=np.float32).reshape(-1)
40
+ issued = self._encode(issued_actions) * admitted[:, None]
41
+ applied = self._encode(applied_actions)
42
+ rows = self.data[indices].copy()
43
+ rows[:, :-1] = rows[:, 1:]
44
+ rows[:, -1, 0] = admitted
45
+ rows[:, -1, 1 : 1 + self.action_dim] = issued
46
+ rows[:, -1, 1 + self.action_dim :] = applied
47
+ self.data[indices] = rows
48
+
49
+ def observation(self) -> np.ndarray:
50
+ return self.data.reshape(self.data.shape[0], self.observation_dim).copy()
51
+
52
+ def _encode(self, actions) -> np.ndarray:
53
+ if self._multibinary:
54
+ # The VLA button order is move, strafe, turn, attack; teacher history
55
+ # encodes turn, move, strafe, attack. Keep both opposing bits if issued.
56
+ return np.asarray(actions, dtype=np.float32).reshape(-1, 7)[:, [4, 5, 0, 1, 2, 3, 6]]
57
+ values = np.asarray(actions, dtype=np.int64).reshape(-1, len(self.action_sizes))
58
+ return np.concatenate(
59
+ [basis[values[:, index]] for index, basis in enumerate(self._basis)], axis=1
60
+ )
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/eval_driver.py ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Single evaluation driver: run one config's episodes and attach metadata.
2
+
3
+ This is the core ``run_from_config`` and its episode-side helpers. Sweep/suite
4
+ orchestration lives in :mod:`latency_bench.eval.sweeps`; the CLI in
5
+ :mod:`latency_bench.run`.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from collections.abc import Callable, Sequence
10
+ from pathlib import Path
11
+ from typing import Any
12
+
13
+ import yaml
14
+
15
+ from training.common.utils import seed_everything
16
+ from latency_bench.core.types import EpisodeMetrics, ExecutorMode
17
+ from latency_bench.eval.config import (
18
+ _episode_seed,
19
+ _eval_episodes,
20
+ _eval_max_steps,
21
+ _evaluation_seed,
22
+ resolve_evaluation_config,
23
+ )
24
+ from latency_bench.eval.reporting import _write_non_sweep_summary
25
+ from latency_bench.envs.base import EnvAdapter
26
+ from latency_bench.executors.base import BatchedExecutor
27
+ from latency_bench.executors.factory import build_executor
28
+ from latency_bench.executors.realtime_warmup import plot_realtime_eval_latency
29
+ from latency_bench.latency.config import latency_type_from_config
30
+ from latency_bench.logging.action_trace_replay import record_videos_from_action_trace
31
+ from latency_bench.logging.video import select_episode_return_stratified
32
+
33
+
34
+ def run_from_config(
35
+ config: dict[str, Any],
36
+ extra_metadata: dict[str, Any] | None = None,
37
+ *,
38
+ write_summary: bool = True,
39
+ on_episode_complete: Callable[[EpisodeMetrics], None] | None = None,
40
+ episode_ids: Sequence[int] | None = None,
41
+ policy: Any | None = None,
42
+ env: EnvAdapter | None = None,
43
+ env_backend: Any | None = None,
44
+ inference_devices: list[str] | None = None,
45
+ ) -> list[EpisodeMetrics]:
46
+ eval_max_steps = _eval_max_steps(config)
47
+ resolve_evaluation_config(config)
48
+ if (
49
+ policy is None
50
+ and env is None
51
+ and env_backend is None
52
+ and config["policy"]["type"] == "starvla"
53
+ ):
54
+ from latency_bench.policy.starvla import prepare_starvla_checkpoint_input_config
55
+
56
+ prepare_starvla_checkpoint_input_config(config)
57
+
58
+ experiment_cfg = config["experiment"]
59
+ policy_cfg = config["policy"]
60
+ logging_cfg = config["logging"]
61
+ seed = _evaluation_seed(config)
62
+ configured_num_episodes = _eval_episodes(config)
63
+ selected_episode_ids = list(range(configured_num_episodes)) if episode_ids is None else list(episode_ids)
64
+ seed_everything(seed)
65
+
66
+ executor_kwargs = {}
67
+ if policy is not None:
68
+ executor_kwargs["policy"] = policy
69
+ if env is not None:
70
+ executor_kwargs["env"] = env
71
+ if env_backend is not None:
72
+ executor_kwargs["env_backend"] = env_backend
73
+ if inference_devices is not None:
74
+ executor_kwargs["inference_devices"] = inference_devices
75
+ executor = build_executor(config, **executor_kwargs)
76
+ metrics = []
77
+ warmup_metadata_by_episode: dict[int, dict[str, Any]] = {}
78
+ try:
79
+ output_dir = Path(logging_cfg["output_dir"])
80
+ output_dir.mkdir(parents=True, exist_ok=True)
81
+ (output_dir / "resolved_config.yaml").write_text(
82
+ yaml.safe_dump(config, sort_keys=False), encoding="utf-8"
83
+ )
84
+ if isinstance(executor, BatchedExecutor):
85
+ warmup_metadata = executor.run_warmup()
86
+ run_episodes_kwargs: dict[str, Any] = {
87
+ "episode_ids": selected_episode_ids,
88
+ "seeds": [_episode_seed(config, episode_id) for episode_id in selected_episode_ids],
89
+ "eval_max_steps": eval_max_steps,
90
+ }
91
+ if on_episode_complete is not None:
92
+ run_episodes_kwargs["on_episode_complete"] = on_episode_complete
93
+ metrics = list(executor.run_episodes(**run_episodes_kwargs))
94
+ warmup_metadata_by_episode.update(
95
+ (episode_id, warmup_metadata) for episode_id in selected_episode_ids
96
+ )
97
+ else:
98
+ warmup_metadata = executor.run_warmup()
99
+ for episode_id in selected_episode_ids:
100
+ warmup_metadata_by_episode[episode_id] = warmup_metadata
101
+ episode_metrics = executor.run_episode(
102
+ episode_id=episode_id,
103
+ seed=_episode_seed(config, episode_id),
104
+ eval_max_steps=eval_max_steps,
105
+ )
106
+ metrics.append(episode_metrics)
107
+ if on_episode_complete is not None:
108
+ on_episode_complete(episode_metrics)
109
+ metrics.sort(key=lambda item: int(item.episode_id))
110
+ for episode_metrics in metrics:
111
+ for key, value in _evaluation_raw_fact_metadata(config, int(episode_metrics.episode_id)).items():
112
+ if episode_metrics.metadata.get(key) is None:
113
+ episode_metrics.metadata[key] = value
114
+ episode_metrics.metadata.update(warmup_metadata_by_episode[int(episode_metrics.episode_id)])
115
+ if "measurement" in config:
116
+ episode_metrics.metadata["measurement"] = config["measurement"]
117
+ episode_metrics.metadata["config_name"] = experiment_cfg.get("name")
118
+ episode_metrics.metadata["run_name"] = experiment_cfg.get("name")
119
+ if "checkpoint_path" in policy_cfg:
120
+ episode_metrics.metadata["checkpoint_path"] = policy_cfg["checkpoint_path"]
121
+ if "profile_path" in config["latency"]:
122
+ episode_metrics.metadata["source_profile_path"] = config["latency"]["profile_path"]
123
+ if "checkpoint_kind" in policy_cfg:
124
+ episode_metrics.metadata["checkpoint_kind"] = str(policy_cfg["checkpoint_kind"])
125
+ episode_metrics.metadata["output_dir"] = str(logging_cfg["output_dir"])
126
+ if "action_prefix" in policy_cfg:
127
+ episode_metrics.metadata["action_prefix"] = policy_cfg["action_prefix"]
128
+ if extra_metadata:
129
+ episode_metrics.metadata.update(extra_metadata)
130
+ if executor.logger is not None:
131
+ executor.logger.flush()
132
+ _record_realtime_eval_latency_plot(config, executor)
133
+ if write_summary:
134
+ _write_non_sweep_summary(config, metrics)
135
+ _record_stratified_replay_videos(config, metrics, seed=seed)
136
+ finally:
137
+ executor.close()
138
+ return metrics
139
+
140
+
141
+ def _record_realtime_eval_latency_plot(config: dict[str, Any], executor: Any) -> None:
142
+ if ExecutorMode(config["executor"]["mode"]) != ExecutorMode.REALTIME:
143
+ return
144
+ if not config["logging"]["save_latency_records"]:
145
+ return
146
+
147
+ latency_values = list(executor.logger.latency_ms_values)
148
+ plot_realtime_eval_latency(
149
+ latency_values,
150
+ Path(config["logging"]["output_dir"]) / "eval_latency_trace.png",
151
+ )
152
+
153
+
154
+ def _record_stratified_replay_videos(
155
+ config: dict[str, Any],
156
+ metrics: list[EpisodeMetrics],
157
+ *,
158
+ seed: int,
159
+ ) -> None:
160
+ if "video" not in config["logging"]:
161
+ return
162
+ video_cfg = config["logging"]["video"]
163
+ if not video_cfg["enabled"]:
164
+ return
165
+ if not config["logging"]["save_step_records"]:
166
+ # Replay reads steps.jsonl, which is only written when save_step_records is on.
167
+ # Without it (e.g. factor-sweep evals) skip video instead of crashing on a missing file.
168
+ return
169
+ if ExecutorMode(config["executor"]["mode"]) == ExecutorMode.REALTIME:
170
+ return
171
+ selections = select_episode_return_stratified(
172
+ metrics,
173
+ num_bins=video_cfg["num_bins"],
174
+ seed=seed,
175
+ )
176
+ record_videos_from_action_trace(config, selections=selections, metrics=metrics)
177
+
178
+
179
+ def _evaluation_raw_fact_metadata(config: dict[str, Any], episode_id: int) -> dict[str, Any]:
180
+ env_cfg = config.get("env", {})
181
+ policy_cfg = config.get("policy", {})
182
+ latency_cfg = config.get("latency", {})
183
+ executor_cfg = config.get("executor", {})
184
+ env_fps = float(env_cfg["env_fps"]) if "env_fps" in env_cfg else None
185
+ obs_fps = float(env_cfg["obs_fps"]) if "obs_fps" in env_cfg else None
186
+ frame_ms = None if env_fps is None or env_fps <= 0 else 1000.0 / env_fps
187
+ executor_mode = str(executor_cfg.get("mode", "")).strip().lower()
188
+ latency_type = latency_type_from_config(latency_cfg)
189
+ if executor_mode == "paused":
190
+ latency_type = "zero"
191
+ elif executor_mode == "realtime":
192
+ latency_type = "measured"
193
+ return {
194
+ "mode": executor_cfg.get("mode"),
195
+ "episode_seed": _episode_seed(config, episode_id),
196
+ "policy_id": _metadata_id(policy_cfg, "policy_id", "id", "type"),
197
+ "env_id": _metadata_id(env_cfg, "env_id", "id", "name"),
198
+ "model_id": latency_cfg.get("model_id"),
199
+ "gpu_class": latency_cfg.get("gpu_class"),
200
+ "workload_id": latency_cfg.get("workload_id"),
201
+ "instance_id": latency_cfg.get("instance_id"),
202
+ "source_run_id": latency_cfg.get("source_run_id"),
203
+ "profile_ref": latency_cfg.get("profile_ref"),
204
+ "env_fps": env_fps,
205
+ "obs_fps": obs_fps,
206
+ "frame_ms": frame_ms,
207
+ "latency_type": latency_type,
208
+ }
209
+
210
+
211
+ def _metadata_id(config: dict[str, Any], *keys: str) -> str | None:
212
+ for key in keys:
213
+ value = config.get(key)
214
+ if value is not None:
215
+ return str(value)
216
+ return None
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/mikasa_evaluate.py ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import json
6
+ import sys
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ import gymnasium as gym
11
+ import numpy as np
12
+ import torch
13
+ import yaml
14
+
15
+
16
+ ROOT = Path(__file__).resolve().parents[2]
17
+ sys.path.insert(0, str(ROOT))
18
+ sys.path.insert(0, str(ROOT / "third_party" / "MIKASA-Robo"))
19
+
20
+ from latency_bench.core.types import Action, Observation # noqa: E402
21
+ from latency_bench.executors.gpu_batched_env_step_backend import ( # noqa: E402
22
+ GpuBatchedEnvStepBackendBase,
23
+ SlotStepOutcome,
24
+ )
25
+ from mikasa_robo_suite.seed_reset import ( # noqa: E402
26
+ reset_seeded_slot as _reset_seeded_slot,
27
+ reset_seeded_slots as _reset_seeded_slots,
28
+ )
29
+
30
+
31
+ ENV_ID = "InterceptGrabFast-VLA-v0"
32
+ INSTRUCTION = "Intercept the rolling ball and grasp it to stop it."
33
+ START_SEED = 4242424242
34
+ MIKASA_IMAGE_VIEWS_INFO_KEY = "mikasa_image_views"
35
+ MIKASA_STATE_INFO_KEY = "mikasa_proprio"
36
+
37
+
38
+ def _scalar(value: Any) -> Any:
39
+ if torch.is_tensor(value):
40
+ return value.detach().reshape(-1)[0].cpu().item()
41
+ return np.asarray(value).reshape(-1)[0].item()
42
+
43
+
44
+ def _make_raw_env(
45
+ obs_mode: str,
46
+ num_envs: int = 1,
47
+ simulator_device: str = "gpu",
48
+ ):
49
+ import mikasa_robo_suite.vla.memory_envs # noqa: F401
50
+
51
+ return gym.make(
52
+ ENV_ID,
53
+ num_envs=num_envs,
54
+ obs_mode=obs_mode,
55
+ control_mode="pd_ee_delta_pose",
56
+ render_mode="all",
57
+ sim_backend=simulator_device,
58
+ render_backend=simulator_device,
59
+ reward_mode="normalized_dense",
60
+ )
61
+
62
+
63
+ def _make_ppo_env(num_envs: int = 1, simulator_device: str = "gpu"):
64
+ from baselines.ppo.ppo_memtasks import FlattenRGBDObservationWrapper
65
+ from mani_skill.vector.wrappers.gymnasium import ManiSkillVectorEnv
66
+ from mikasa_robo_suite.vla.dataset_collectors.get_mikasa_robo_datasets import (
67
+ env_info,
68
+ )
69
+
70
+ env = _make_raw_env(
71
+ "state",
72
+ num_envs=num_envs,
73
+ simulator_device=simulator_device,
74
+ )
75
+ wrappers, _ = env_info(ENV_ID)
76
+ for wrapper, kwargs in wrappers:
77
+ env = wrapper(env, **kwargs)
78
+ env = FlattenRGBDObservationWrapper(env, rgb=False, depth=False, state=True)
79
+ return ManiSkillVectorEnv(
80
+ env,
81
+ num_envs,
82
+ ignore_terminations=True,
83
+ record_metrics=True,
84
+ )
85
+
86
+
87
+ def _make_vla_env(num_envs: int = 1, simulator_device: str = "gpu"):
88
+ from mikasa_robo_suite.vla.utils.apply_wrappers import apply_mikasa_vla_wrappers
89
+
90
+ return apply_mikasa_vla_wrappers(
91
+ _make_raw_env(
92
+ "rgb",
93
+ num_envs=num_envs,
94
+ simulator_device=simulator_device,
95
+ ),
96
+ include_overlays=False,
97
+ )
98
+
99
+
100
+ class _PpoPolicy:
101
+ def __init__(self, env, checkpoint: Path):
102
+ from baselines.ppo.ppo_memtasks import AgentStateOnly
103
+
104
+ self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
105
+ self.agent = AgentStateOnly(env).to(self.device)
106
+ self.agent.load_state_dict(torch.load(checkpoint, map_location=self.device))
107
+ self.agent.eval()
108
+
109
+ def forward(self, observation):
110
+ with torch.no_grad():
111
+ return self.agent.get_action(
112
+ {key: value.to(self.device) for key, value in observation.items()},
113
+ deterministic=True,
114
+ )
115
+
116
+
117
+ class MikasaEnvStepBackend(GpuBatchedEnvStepBackendBase):
118
+ """Own the native MIKASA simulator and its 7D action contract."""
119
+
120
+ backend_name = "mikasa_gpu_batched"
121
+
122
+ def __init__(self, *, config: dict[str, Any], num_slots: int, env=None):
123
+ noop_action = Action(
124
+ value=np.asarray(config["env"]["noop_action"], dtype=np.float32),
125
+ name="noop",
126
+ is_noop=True,
127
+ )
128
+ super().__init__(
129
+ config=config,
130
+ noop_action=noop_action,
131
+ num_slots=num_slots,
132
+ action_space=gym.spaces.Box(-1.0, 1.0, shape=(7,), dtype=np.float32),
133
+ )
134
+ self.env = (
135
+ _make_vla_env(
136
+ num_envs=num_slots,
137
+ simulator_device=config["env"]["simulator_device"],
138
+ )
139
+ if env is None
140
+ else env
141
+ )
142
+ self._episode_seeds = [0] * num_slots
143
+ self._success = np.zeros(num_slots, dtype=np.bool_)
144
+ self._observation, _ = self.env.reset(seed=self._episode_seeds)
145
+
146
+ def _reset_slot_observation(self, slot_id: int, *, seed: int | None) -> Observation:
147
+ if seed is not None:
148
+ self._episode_seeds[slot_id] = int(seed)
149
+ self._observation, _ = _reset_seeded_slot(
150
+ self.env,
151
+ slot_id=slot_id,
152
+ seed=self._episode_seeds[slot_id],
153
+ )
154
+ self._env_steps[slot_id] = 0
155
+ self._success[slot_id] = False
156
+ return self._observation_for_slot(slot_id)
157
+
158
+ def _observe_slot_observations(
159
+ self,
160
+ slot_ids: list[int],
161
+ ) -> dict[int, Observation]:
162
+ return {slot_id: self._observation_for_slot(slot_id) for slot_id in slot_ids}
163
+
164
+ def _step_cores(
165
+ self,
166
+ slot_ids: list[int],
167
+ *,
168
+ actions: np.ndarray,
169
+ active_mask: np.ndarray,
170
+ ) -> Any:
171
+ del slot_ids, active_mask
172
+ tensor_actions = torch.as_tensor(
173
+ actions,
174
+ dtype=torch.float32,
175
+ device=self.env.unwrapped.device,
176
+ )
177
+ self._observation, reward, terminated, truncated, info = self.env.step(
178
+ tensor_actions
179
+ )
180
+ return reward, terminated, truncated, info
181
+
182
+ def _slot_step_outcome(self, state: Any, slot_id: int) -> SlotStepOutcome:
183
+ reward, terminated, truncated, info = state
184
+ success = bool(_slot_value(info["success"], slot_id))
185
+ self._success[slot_id] |= success
186
+ return SlotStepOutcome(
187
+ reward=float(_slot_value(reward, slot_id)),
188
+ done=bool(_slot_value(terminated, slot_id)),
189
+ truncated=bool(_slot_value(truncated, slot_id)),
190
+ info={
191
+ "success": success,
192
+ "task_metrics": {"success": float(self._success[slot_id])},
193
+ },
194
+ )
195
+
196
+ def _observation_for_slot(self, slot_id: int) -> Observation:
197
+ rgb = self._observation["rgb"]
198
+ if torch.is_tensor(rgb):
199
+ rgb = rgb.detach().cpu().numpy()
200
+ rgb = np.asarray(rgb)
201
+ views = np.stack(
202
+ [
203
+ np.asarray(rgb[slot_id, :, :, :3], dtype=np.uint8),
204
+ np.asarray(rgb[slot_id, :, :, 3:6], dtype=np.uint8),
205
+ ]
206
+ )
207
+ metadata = {
208
+ MIKASA_IMAGE_VIEWS_INFO_KEY: views,
209
+ MIKASA_STATE_INFO_KEY: self._observation["proprio"][slot_id].detach().cpu().numpy(),
210
+ "slot_id": slot_id,
211
+ }
212
+ if "action_prefix_state_key" in self.config["env"]:
213
+ metadata["action_prefix_state_key"] = self.config["env"]["action_prefix_state_key"]
214
+ if "returned_action_context" in self.config["env"]:
215
+ context = self.config["env"]["returned_action_context"]
216
+ metadata["returned_action_context"] = {
217
+ **context,
218
+ "order": np.asarray(context["order"]),
219
+ "low": np.asarray(context["low"], dtype=np.float32),
220
+ "high": np.asarray(context["high"], dtype=np.float32),
221
+ }
222
+ return Observation(
223
+ data=None,
224
+ env_step=int(self._env_steps[slot_id]),
225
+ sim_time_ms=float(self._env_steps[slot_id]) * self._frame_ms,
226
+ metadata=metadata,
227
+ )
228
+
229
+ def close(self) -> None:
230
+ if not self.closed:
231
+ self.env.close()
232
+ super().close()
233
+
234
+
235
+ def _slot_value(value: Any, slot_id: int) -> Any:
236
+ if torch.is_tensor(value):
237
+ return value.detach().reshape(-1)[slot_id].cpu().item()
238
+ return np.asarray(value).reshape(-1)[slot_id].item()
239
+
240
+
241
+ def _evaluate(args: argparse.Namespace) -> dict[str, Any]:
242
+ env = _make_ppo_env()
243
+ policy = _PpoPolicy(env, args.checkpoint)
244
+ seeds = []
245
+ successes = []
246
+ returns = []
247
+ lengths = []
248
+ try:
249
+ for episode_index in range(args.episodes):
250
+ seed = START_SEED + episode_index
251
+ observation, _ = env.reset(seed=seed)
252
+ success_once = False
253
+ episode_return = 0.0
254
+ for step in range(60):
255
+ action = policy.forward(observation)
256
+ observation, reward, terminated, truncated, info = env.step(action)
257
+ success_once = success_once or bool(_scalar(info["success"]))
258
+ episode_return += float(_scalar(reward))
259
+ if bool(_scalar(terminated)) or bool(_scalar(truncated)):
260
+ break
261
+ seeds.append(seed)
262
+ successes.append(success_once)
263
+ returns.append(episode_return)
264
+ lengths.append(step + 1)
265
+ finally:
266
+ env.close()
267
+ summary = {
268
+ "seeds": seeds,
269
+ "successes": successes,
270
+ "success_rate": float(np.mean(successes)),
271
+ "returns": returns,
272
+ "lengths": lengths,
273
+ }
274
+ (args.output_dir / "summary.json").write_text(
275
+ json.dumps(summary, indent=2) + "\n", encoding="utf-8"
276
+ )
277
+ return summary
278
+
279
+
280
+ def _latency_eval(argv: list[str]) -> None:
281
+ from latency_bench.core.config import load_config
282
+ from latency_bench.eval.config import apply_runtime_overrides
283
+ from latency_bench.eval.driver import run_from_config
284
+
285
+ parser = argparse.ArgumentParser()
286
+ parser.add_argument("--eval-config", type=Path, required=True)
287
+ parser.add_argument("--checkpoint-path", type=Path)
288
+ parser.add_argument("--model-config-path", type=Path)
289
+ parser.add_argument("--task-contract-path", type=Path)
290
+ parser.add_argument("--run-name")
291
+ parser.add_argument("--output-dir", type=Path)
292
+ parser.add_argument("--latency-method", choices=("zero", "temporal"))
293
+ parser.add_argument("--profile-path", type=Path)
294
+ parser.add_argument("--latency-seed", type=int)
295
+ args = parser.parse_args(argv)
296
+ config = load_config(args.eval_config)
297
+ apply_runtime_overrides(
298
+ config,
299
+ checkpoint_path=args.checkpoint_path,
300
+ model_config_path=args.model_config_path,
301
+ task_contract_path=args.task_contract_path,
302
+ run_name=args.run_name,
303
+ output_dir=args.output_dir,
304
+ latency_method=args.latency_method,
305
+ latency_profile_path=args.profile_path,
306
+ latency_seed=args.latency_seed,
307
+ )
308
+ output_dir = Path(config["logging"]["output_dir"])
309
+ output_dir.mkdir(parents=True, exist_ok=True)
310
+ (output_dir / "eval_config.yaml").write_text(
311
+ yaml.safe_dump(config, sort_keys=False), encoding="utf-8"
312
+ )
313
+ backend = MikasaEnvStepBackend(
314
+ config=config,
315
+ num_slots=int(config["evaluation"]["eval_parallel_envs"]),
316
+ )
317
+ run_from_config(
318
+ config,
319
+ env_backend=backend,
320
+ inference_devices=config["executor"]["inference_devices"],
321
+ )
322
+
323
+
324
+ def main() -> None:
325
+ if sys.argv[1:2] == ["latency-eval"]:
326
+ _latency_eval(sys.argv[2:])
327
+ return
328
+
329
+ parser = argparse.ArgumentParser()
330
+ parser.add_argument("--policy", choices=("ppo",), required=True)
331
+ parser.add_argument("--checkpoint", type=Path)
332
+ parser.add_argument("--episodes", type=int, default=50)
333
+ parser.add_argument("--output-dir", type=Path, required=True)
334
+ args = parser.parse_args()
335
+ args.output_dir.mkdir(parents=True, exist_ok=True)
336
+
337
+ _evaluate(args)
338
+
339
+
340
+ if __name__ == "__main__":
341
+ main()
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/starvla.py ADDED
@@ -0,0 +1,1207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import sys
5
+ from collections.abc import Mapping, Sequence
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ import numpy as np
10
+ import numpy.typing as npt
11
+ from PIL import Image
12
+
13
+ from latency_bench.core.actions import ActionResolver
14
+ from latency_bench.core.clock import EnvClock
15
+ from latency_bench.core.timing import current_profiler
16
+ from latency_bench.core.types import Action, Observation, PolicyOutput
17
+ from latency_bench.data.ghost_trail import GhostTrailConfig, build_flappy_ghost_trail_window
18
+ from latency_bench.data.state_normalization import min_max_normalize_state
19
+ from latency_bench.envs.raw_rgb import ENV_RAW_RGB_FRAME_STACK_INFO_KEY
20
+ from latency_bench.envs.gymnasium_task import (
21
+ gymnasium_action_space_contract,
22
+ gymnasium_task_contract,
23
+ )
24
+ from latency_bench.policy.base import PolicyRunner
25
+ from latency_bench.policy.starvla_prompts import load_latency_prompt_map, resolve_starvla_prompt
26
+
27
+ from latency_bench.utils.paths import REPO_ROOT
28
+
29
+
30
+ STARVLA_ROOT = REPO_ROOT / "third_party" / "starVLA"
31
+ STATEFUL_STARVLA_MODEL_IDS: tuple[str, ...] = (
32
+ "pi0",
33
+ "pi-0",
34
+ "pi05",
35
+ "pi-0.5",
36
+ "gr00t",
37
+ "qwenpi",
38
+ "qwenpi_v3",
39
+ "qwengr00t",
40
+ )
41
+ STATELESS_STARVLA_MODEL_IDS: tuple[str, ...] = (
42
+ "openvla",
43
+ "qwenoft",
44
+ )
45
+
46
+ DEMON_ATTACK_ACTION_LABELS: tuple[str, ...] = (
47
+ "NOOP",
48
+ "FIRE",
49
+ "RIGHT",
50
+ "LEFT",
51
+ "RIGHTFIRE",
52
+ "LEFTFIRE",
53
+ )
54
+ DEADLY_CORRIDOR_TURN_LABELS: tuple[str, ...] = (
55
+ "TURN_NOOP",
56
+ "TURN_LEFT",
57
+ "TURN_RIGHT",
58
+ )
59
+ DEADLY_CORRIDOR_MOVE_LABELS: tuple[str, ...] = (
60
+ "MOVE_NOOP",
61
+ "MOVE_FORWARD",
62
+ "MOVE_BACKWARD",
63
+ )
64
+ DEADLY_CORRIDOR_STRAFE_LABELS: tuple[str, ...] = (
65
+ "STRAFE_NOOP",
66
+ "MOVE_LEFT",
67
+ "MOVE_RIGHT",
68
+ )
69
+ DEADLY_CORRIDOR_ATTACK_LABELS: tuple[str, ...] = (
70
+ "ATTACK_NOOP",
71
+ "ATTACK",
72
+ )
73
+
74
+
75
+ class StarVlaPolicyRunner(PolicyRunner):
76
+ """Translate observations and model outputs using the task action contract."""
77
+
78
+ def __init__(
79
+ self,
80
+ *,
81
+ wrapper: Any,
82
+ checkpoint_path: str,
83
+ device: str,
84
+ unnorm_key: str | None,
85
+ env_name: str,
86
+ action_resolver: ActionResolver,
87
+ action_refs: Sequence[Any],
88
+ latency_prompt_map: dict[str, Any] | None = None,
89
+ base_prompt: str | None = None,
90
+ latency_prompt_key: int | str | None = None,
91
+ prompt_mode: str | None = None,
92
+ obs_resize: tuple[int, int] | None = None,
93
+ image_transform_config: Mapping[str, Any] | None = None,
94
+ observation_stride_raw_frames: int,
95
+ model_cfg: Mapping[str, Any] | None = None,
96
+ state_normalization: Mapping[str, Any] | None = None,
97
+ state_source: str | None = None,
98
+ image_views_info_key: str | None = None,
99
+ action_output_type: str | None = None,
100
+ ) -> None:
101
+ self._wrapper = wrapper
102
+ self._obs_resize = tuple(obs_resize) if obs_resize else None
103
+ self._checkpoint_path = checkpoint_path
104
+ self._device = device
105
+ self._unnorm_key = unnorm_key
106
+ self._env_name = env_name
107
+ self._action_by_raw_id = {
108
+ raw_action_id: action_resolver.resolve(action_ref)
109
+ for raw_action_id, action_ref in enumerate(action_refs)
110
+ }
111
+ self._latency_prompt_map = latency_prompt_map
112
+ self._base_prompt = base_prompt
113
+ self._latency_prompt_key = latency_prompt_key
114
+ self._prompt_mode = str(prompt_mode or "default").strip().lower()
115
+ self._image_transform_config = dict(image_transform_config or {"image_transform": "raw_rgb"})
116
+ self._image_transform = str(
117
+ self._image_transform_config.get("image_transform", "raw_rgb") or "raw_rgb"
118
+ ).strip().lower()
119
+ model_cfg = (
120
+ _normalized_model_cfg_from_wrapper(wrapper)
121
+ if model_cfg is None
122
+ else _normalized_model_cfg(model_cfg)
123
+ )
124
+ self._include_state = _include_state_from_model_cfg(model_cfg)
125
+ self._state_dim = _state_dim_from_model_cfg(model_cfg) if self._include_state else None
126
+ self._state_normalization = dict(state_normalization or {})
127
+ self._state_source = state_source
128
+ self._image_views_info_key = image_views_info_key
129
+ self._action_output_type = action_output_type
130
+ vla_data = (model_cfg.get("datasets", {}) or {}).get("vla_data", {}) or {}
131
+ self._pack_image_sequence = (
132
+ bool(vla_data["pack_image_sequence"])
133
+ if "pack_image_sequence" in vla_data
134
+ else False
135
+ )
136
+ self._image_sequence_length = (
137
+ int(vla_data["image_sequence_length"])
138
+ if self._pack_image_sequence
139
+ else 1
140
+ )
141
+ self._observation_stride_raw_frames = int(observation_stride_raw_frames)
142
+ self._image_sequence_raw_span = (
143
+ 1
144
+ + (self._image_sequence_length - 1)
145
+ * self._observation_stride_raw_frames
146
+ )
147
+ self._num_obs_frames = int(vla_data.get("num_obs_frames", 1) or 1)
148
+ self._image_mode = str(vla_data.get("image_mode", "single"))
149
+ self._stitch_grid = tuple(vla_data.get("stitch_grid", [2, 2]))
150
+ framework_cfg = model_cfg["framework"]
151
+ kv_cfg = framework_cfg["kv_memory"] if "kv_memory" in framework_cfg else {}
152
+ self._kv_memory_enabled = bool(kv_cfg["enabled"]) if "enabled" in kv_cfg else False
153
+
154
+ def reset_state(self, slot_id: int | None = None) -> None:
155
+ # Clears the model's per-slot KV memory at episode boundaries (req3).
156
+ # No-op unless the framework maintains KV memory.
157
+ reset = getattr(self._wrapper, "reset_memory", None)
158
+ if callable(reset):
159
+ reset(slot_id)
160
+
161
+ def predict(self, observation: Observation) -> PolicyOutput:
162
+ return self.predict_batch([observation])[0]
163
+
164
+ def predict_batch(self, observations: Sequence[Observation]) -> list[PolicyOutput]:
165
+ profiler = current_profiler()
166
+ with profiler.time("policy_build_example_ms"):
167
+ examples = [self._build_example(observation) for observation in observations]
168
+ with profiler.time("policy_wrapper_predict_action_ms"):
169
+ prediction = self._wrapper.predict_action(
170
+ examples=examples, unnorm_key=self._unnorm_key, profiler=profiler
171
+ )
172
+ with profiler.time("policy_decode_ms"):
173
+ outputs = [
174
+ self._decode_prediction(
175
+ prediction=prediction,
176
+ index=index,
177
+ observation=observation,
178
+ example=example,
179
+ )
180
+ for index, (observation, example) in enumerate(zip(observations, examples))
181
+ ]
182
+ return outputs
183
+
184
+ def _decode_prediction(
185
+ self,
186
+ *,
187
+ prediction: dict[str, Any],
188
+ index: int,
189
+ observation: Observation,
190
+ example: dict[str, Any],
191
+ ) -> PolicyOutput:
192
+ actions = np.asarray(prediction["actions"])
193
+ raw_action_scores = (
194
+ np.asarray(prediction["raw_action_scores"])
195
+ if "raw_action_scores" in prediction
196
+ else None
197
+ )
198
+ return self._policy_output(
199
+ observation=observation,
200
+ example=example,
201
+ action_payload=actions[index, 0],
202
+ action_output_type=(
203
+ prediction["action_output_type"]
204
+ if self._action_output_type is None
205
+ else self._action_output_type
206
+ ),
207
+ raw_action_scores=None if raw_action_scores is None else raw_action_scores[index, 0],
208
+ )
209
+
210
+ def _build_example(self, observation: Observation) -> dict[str, Any]:
211
+ frame_source = observation.metadata[
212
+ ENV_RAW_RGB_FRAME_STACK_INFO_KEY
213
+ if self._image_views_info_key is None
214
+ else self._image_views_info_key
215
+ ]
216
+ frames = observation_data_to_hwc_uint8_frames(frame_source) # oldest .. newest
217
+ transformed = self._transformed_frame(frames=frames, observation=observation)
218
+
219
+ if self._image_views_info_key is not None:
220
+ pass
221
+ elif self._pack_image_sequence:
222
+ if transformed is not None:
223
+ raise ValueError(
224
+ "WanOFT packed image sequences require image_transform=raw_rgb"
225
+ )
226
+ if len(frames) < self._image_sequence_raw_span:
227
+ raise ValueError(
228
+ "WanOFT packed image sequence requires "
229
+ f"{self._image_sequence_raw_span} raw frames for "
230
+ f"{self._image_sequence_length} decision observations at stride "
231
+ f"{self._observation_stride_raw_frames}, got {len(frames)}"
232
+ )
233
+ frames = frames[
234
+ -self._image_sequence_raw_span
235
+ :: self._observation_stride_raw_frames
236
+ ]
237
+ elif transformed is not None:
238
+ frames = [transformed]
239
+ elif self._image_mode == "single" or self._kv_memory_enabled:
240
+ frames = frames[-1:]
241
+ else:
242
+ # Select the temporal observation window to match training (_pack_sample).
243
+ raw_span = 1 + (self._num_obs_frames - 1) * self._observation_stride_raw_frames
244
+ frames = frames[-raw_span :: self._observation_stride_raw_frames]
245
+
246
+ prompt = resolve_starvla_prompt(
247
+ env_name=self._env_name,
248
+ observation_metadata=observation.metadata,
249
+ latency_prompt_map=self._latency_prompt_map,
250
+ base_prompt=self._base_prompt,
251
+ latency_prompt_key=self._latency_prompt_key,
252
+ prompt_mode=self._prompt_mode,
253
+ )
254
+
255
+ if self._image_mode == "stitch":
256
+ if transformed is not None:
257
+ raise ValueError("image_transform is not compatible with image_mode=stitch")
258
+ # Tile the window into one image; matches _pack_sample's stitch branch
259
+ # (raw frames passed to stitch_frames, which resizes each cell to 224).
260
+ images = [_get_stitch_frames()(frames, grid=self._stitch_grid, size=(224, 224))]
261
+ else:
262
+ if self._obs_resize is not None:
263
+ height, width = self._obs_resize
264
+ # match training preprocessing exactly: gr00t LeRobotSingleDataset._pack_sample
265
+ # does `Image.fromarray(image).resize((224, 224))` (PIL default resample = BICUBIC).
266
+ frames = [
267
+ np.asarray(Image.fromarray(frame).resize((width, height)), dtype=np.uint8)
268
+ for frame in frames
269
+ ]
270
+ images = [Image.fromarray(frame) for frame in frames]
271
+
272
+ example = {
273
+ "image": images,
274
+ "lang": prompt,
275
+ }
276
+ if self._kv_memory_enabled:
277
+ example["slot_id"] = observation.metadata["slot_id"]
278
+ elif "slot_id" in observation.metadata:
279
+ example["slot_id"] = observation.metadata["slot_id"]
280
+ if self._include_state:
281
+ if self._state_source == "transport":
282
+ state = np.asarray(observation.data["transport"], dtype=np.float32)
283
+ example["state"] = state.reshape(1, self._state_dim)
284
+ elif self._state_normalization:
285
+ state = np.asarray(
286
+ observation.metadata["gymnasium_state"], dtype=np.float32
287
+ )
288
+ state_min = np.asarray(self._state_normalization["min"], dtype=np.float32)
289
+ state_max = np.asarray(self._state_normalization["max"], dtype=np.float32)
290
+ state = min_max_normalize_state(state, state_min, state_max)
291
+ example["state"] = state.reshape(1, self._state_dim)
292
+ else:
293
+ example["state"] = np.zeros((1, self._state_dim), dtype=np.float32)
294
+ return example
295
+
296
+ def _transformed_frame(
297
+ self,
298
+ *,
299
+ frames: Sequence[npt.NDArray[np.uint8]],
300
+ observation: Observation,
301
+ ) -> npt.NDArray[np.uint8] | None:
302
+ if self._image_transform in {"", "none", "raw", "raw_rgb"}:
303
+ return None
304
+ if self._image_transform not in {"flappy_ghost_trail", "demon_attack_ghost_trail"}:
305
+ raise ValueError(f"Unsupported StarVLA image_transform={self._image_transform!r}")
306
+ if self._image_transform == "flappy_ghost_trail" and self._env_name != "flappy":
307
+ raise ValueError("image_transform=flappy_ghost_trail is only supported for env_name=flappy")
308
+ if self._image_transform == "demon_attack_ghost_trail" and self._env_name != "demon_attack":
309
+ raise ValueError("image_transform=demon_attack_ghost_trail is only supported for env_name=demon_attack")
310
+
311
+ config = GhostTrailConfig(
312
+ image_transform=self._image_transform,
313
+ history_frames=int(self._image_transform_config.get("history_frames", 5)),
314
+ gamma=float(self._image_transform_config.get("gamma", 1.3)),
315
+ min_alpha=int(self._image_transform_config.get("min_alpha", 35)),
316
+ ground_fraction=float(self._image_transform_config.get("ground_fraction", 0.22)),
317
+ scroll_px_per_step=float(self._image_transform_config.get("scroll_px_per_step", 4.0)),
318
+ )
319
+ if self._image_transform == "demon_attack_ghost_trail":
320
+ # env_step counts raw ALE frames (buffer updated 4× per decision step).
321
+ # frames[-0:] == frames, so env_step=0 falls back to the full reset-fill buffer.
322
+ valid_count = min(len(frames), int(observation.env_step))
323
+ else:
324
+ max_frames = max(1, int(config.history_frames) + 1)
325
+ valid_count = min(len(frames), max(1, int(observation.env_step) + 1), max_frames)
326
+ window = [np.asarray(frame, dtype=np.uint8) for frame in frames[-valid_count:]]
327
+
328
+ if self._image_transform == "demon_attack_ghost_trail":
329
+ from latency_bench.data.ghost_trail_demon import build_demon_attack_ghost_trail_window
330
+ steps_arg = list(range(len(window)))
331
+ return build_demon_attack_ghost_trail_window(window, steps_arg, config=config)
332
+
333
+ current_step = int(observation.env_step)
334
+ start_step = current_step - valid_count + 1
335
+ steps = list(range(start_step, current_step + 1))
336
+ return build_flappy_ghost_trail_window(window, steps, config=config)
337
+
338
+ def _policy_output(
339
+ self,
340
+ *,
341
+ observation: Observation,
342
+ example: dict[str, Any],
343
+ action_payload: npt.NDArray[Any],
344
+ action_output_type: str,
345
+ raw_action_scores: npt.NDArray[Any] | None,
346
+ ) -> PolicyOutput:
347
+ payload = np.asarray(action_payload)
348
+ action, action_metadata = action_from_starvla_payload(
349
+ payload=payload,
350
+ env_name=self._env_name,
351
+ action_by_raw_id=self._action_by_raw_id,
352
+ action_output_type=action_output_type,
353
+ )
354
+ metadata = {
355
+ "policy_type": "starvla",
356
+ "prompt_source": "latency_prompt_map" if self._latency_prompt_map is not None else "base",
357
+ "checkpoint_path": self._checkpoint_path,
358
+ "unnorm_key": self._unnorm_key,
359
+ "device": self._device,
360
+ "input_frame_count": len(example["image"]),
361
+ "image_transform": self._image_transform,
362
+ "action_output_type": action_output_type,
363
+ "action_payload": to_jsonable_action_payload(payload),
364
+ "kv_memory_enabled": self._kv_memory_enabled,
365
+ **action_metadata,
366
+ }
367
+ if self._pack_image_sequence:
368
+ metadata["image_sequence_length"] = self._image_sequence_length
369
+ metadata["input_frame_raw_stride"] = self._observation_stride_raw_frames
370
+ metadata["input_frame_raw_span"] = self._image_sequence_raw_span
371
+ if "slot_id" in example:
372
+ metadata["slot_id"] = example["slot_id"]
373
+ if raw_action_scores is not None:
374
+ metadata["raw_action_scores"] = [
375
+ float(item) for item in np.asarray(raw_action_scores, dtype=np.float32).tolist()
376
+ ]
377
+ if "latency_raw_frames" in observation.metadata:
378
+ metadata["latency_raw_frames"] = observation.metadata["latency_raw_frames"]
379
+ if "latency_ms" in observation.metadata:
380
+ metadata["latency_ms"] = observation.metadata["latency_ms"]
381
+ if self._latency_prompt_key is not None:
382
+ metadata["latency_prompt_key"] = self._latency_prompt_key
383
+ return PolicyOutput(
384
+ action=action,
385
+ raw_output=metadata["action_payload"],
386
+ metadata=metadata,
387
+ )
388
+
389
+
390
+ def observation_data_to_hwc_uint8_frames(data: Any) -> list[npt.NDArray[np.uint8]]:
391
+ frame = _extract_observation_array(data)
392
+ if frame.ndim == 4 and frame.shape[-1] == 3:
393
+ return [_as_uint8_image(item) for item in frame]
394
+ if frame.ndim == 4 and frame.shape[1] == 3:
395
+ return [_as_uint8_image(np.transpose(item, (1, 2, 0))) for item in frame]
396
+ if frame.ndim == 3 and frame.shape[-1] == 3:
397
+ return [_as_uint8_image(frame)]
398
+ if frame.ndim == 3 and frame.shape[0] == 3:
399
+ return [_as_uint8_image(np.transpose(frame, (1, 2, 0)))]
400
+ if (
401
+ frame.ndim == 3
402
+ and frame.shape[0] % 3 == 0
403
+ and frame.shape[0] < frame.shape[1]
404
+ and frame.shape[0] < frame.shape[2]
405
+ ):
406
+ return [
407
+ _as_uint8_image(np.transpose(frame[start : start + 3, :, :], (1, 2, 0)))
408
+ for start in range(0, frame.shape[0], 3)
409
+ ]
410
+ if frame.ndim == 3 and frame.shape[-1] % 3 == 0:
411
+ return [
412
+ _as_uint8_image(frame[:, :, start : start + 3])
413
+ for start in range(0, frame.shape[-1], 3)
414
+ ]
415
+ if frame.ndim == 3 and frame.shape[0] % 3 == 0:
416
+ return [
417
+ _as_uint8_image(np.transpose(frame[start : start + 3, :, :], (1, 2, 0)))
418
+ for start in range(0, frame.shape[0], 3)
419
+ ]
420
+ return [_as_uint8_image(frame)]
421
+
422
+
423
+ def decode_starvla_action(
424
+ *,
425
+ vector: npt.NDArray[Any],
426
+ env_name: str,
427
+ action_by_raw_id: Mapping[int, Action],
428
+ action_layout: str | None = None,
429
+ ) -> tuple[Action, dict[str, Any]]:
430
+ deadly_layout = None
431
+ if str(env_name) == "deadly_corridor":
432
+ action_dim = int(np.asarray(vector).shape[-1])
433
+ deadly_layouts = {
434
+ 7: "deadly_corridor_semantic_7",
435
+ 11: "deadly_corridor_factorized_11",
436
+ 54: "deadly_corridor_joint_54",
437
+ }
438
+ if action_dim not in deadly_layouts:
439
+ raise ValueError(
440
+ "Deadly Corridor StarVLA action vector expected 7, 11, or 54 "
441
+ f"values, got {action_dim}"
442
+ )
443
+ deadly_layout = deadly_layouts[action_dim]
444
+ asterix_layout = None
445
+ if str(env_name) == "asterix":
446
+ action_dim = int(np.asarray(vector).shape[-1])
447
+ if action_layout is not None:
448
+ asterix_layout = str(action_layout).strip().lower()
449
+ else:
450
+ asterix_layout = "factorized_6" if action_dim < 9 else "discrete_9"
451
+
452
+ decode_rl_games_actions, _, _ = _load_rl_games_action_decode()
453
+ prediction = decode_rl_games_actions(
454
+ normalized_actions=np.asarray(vector),
455
+ env_name=str(env_name),
456
+ deadly_action_layout=(deadly_layout.removeprefix("deadly_corridor_") if deadly_layout is not None else None),
457
+ asterix_action_layout=asterix_layout,
458
+ )
459
+ action, metadata = action_from_starvla_payload(
460
+ payload=np.asarray(prediction["actions"]),
461
+ env_name=env_name,
462
+ action_by_raw_id=action_by_raw_id,
463
+ action_output_type=prediction["action_output_type"],
464
+ )
465
+ if deadly_layout is not None:
466
+ metadata["action_layout"] = deadly_layout
467
+ if deadly_layout == "deadly_corridor_joint_54":
468
+ turn, move, strafe, attack = action.value
469
+ metadata["raw_action_id"] = turn * 18 + move * 6 + strafe * 2 + attack
470
+ elif deadly_layout == "deadly_corridor_semantic_7":
471
+ semantic_actions = (
472
+ [0, 1, 0, 0],
473
+ [0, 2, 0, 0],
474
+ [0, 0, 1, 0],
475
+ [0, 0, 2, 0],
476
+ [1, 0, 0, 0],
477
+ [2, 0, 0, 0],
478
+ [0, 0, 0, 1],
479
+ )
480
+ metadata["raw_action_id"] = semantic_actions.index(action.value)
481
+ if asterix_layout is not None:
482
+ metadata["action_layout"] = asterix_layout
483
+ return action, metadata
484
+
485
+
486
+ # Fixed semantic button order the StarVLA multibinary head is trained against.
487
+ # Mirrors starVLA.training.rl_games.eval_core._semantic_to_runtime_multibinary;
488
+ # the env adapter re-orders this to the live ViZDoom button layout.
489
+ DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER = (
490
+ "MOVE_FORWARD",
491
+ "MOVE_BACKWARD",
492
+ "MOVE_LEFT",
493
+ "MOVE_RIGHT",
494
+ "TURN_LEFT",
495
+ "TURN_RIGHT",
496
+ "ATTACK",
497
+ )
498
+
499
+
500
+ def action_from_starvla_payload(
501
+ *,
502
+ payload: npt.NDArray[Any],
503
+ env_name: str,
504
+ action_by_raw_id: Mapping[int, Action],
505
+ action_output_type: str = "",
506
+ ) -> tuple[Action, dict[str, Any]]:
507
+ if str(action_output_type) == "rl_games_continuous":
508
+ values = [float(item) for item in np.asarray(payload).reshape(-1).tolist()]
509
+ return Action(
510
+ value=values,
511
+ name="continuous_torque",
512
+ is_noop=all(value == 0.0 for value in values),
513
+ is_oneshot=False,
514
+ ), {"continuous_action": values}
515
+ if str(env_name) == "demon_attack":
516
+ return demon_attack_action_from_id(int(np.asarray(payload).reshape(-1)[0]))
517
+ if str(env_name) == "deadly_corridor":
518
+ # Multibinary heads emit an already-thresholded 7-dim button vector in
519
+ # fixed semantic order; the env adapter re-orders it to the live ViZDoom
520
+ # button layout. Keep it as-is rather than reinterpreting it as a
521
+ # [turn, move, strafe, attack] categorical tuple.
522
+ if str(action_output_type) == "rl_games_deadly_corridor_multibinary":
523
+ buttons = [int(item) for item in np.asarray(payload).reshape(-1).tolist()]
524
+ active = [
525
+ DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER[idx]
526
+ for idx, pressed in enumerate(buttons)
527
+ if idx < len(DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER) and pressed
528
+ ]
529
+ action_name = "+".join(active) if active else "NOOP"
530
+ return Action(
531
+ value=buttons,
532
+ name=action_name,
533
+ is_noop=not any(buttons),
534
+ is_oneshot=False,
535
+ ), {
536
+ "decoded_multibinary_buttons": buttons,
537
+ "action_label": action_name,
538
+ "action_layout": "deadly_corridor_multibinary_7",
539
+ }
540
+ return deadly_corridor_action_from_tuple(
541
+ action_value=[int(item) for item in np.asarray(payload).reshape(-1).tolist()],
542
+ metadata={"action_layout": "deadly_corridor_tuple"},
543
+ )
544
+ raw_action_id = int(np.asarray(payload).reshape(-1)[0])
545
+ return action_by_raw_id[raw_action_id], {"raw_action_id": raw_action_id}
546
+
547
+
548
+ def to_jsonable_action_payload(payload: npt.NDArray[Any]) -> Any:
549
+ value = np.asarray(payload).tolist()
550
+ if isinstance(value, list) and len(value) == 1:
551
+ return value[0]
552
+ return value
553
+
554
+
555
+ def demon_attack_action_from_id(action_id: int) -> tuple[Action, dict[str, Any]]:
556
+ action = Action(
557
+ value=action_id,
558
+ name=DEMON_ATTACK_ACTION_LABELS[action_id],
559
+ is_noop=action_id == 0,
560
+ is_oneshot=False,
561
+ )
562
+ return action, {"raw_action_id": action_id, "action_label": action.name}
563
+
564
+
565
+ def deadly_corridor_action_from_tuple(
566
+ *,
567
+ action_value: list[int],
568
+ metadata: dict[str, Any],
569
+ ) -> tuple[Action, dict[str, Any]]:
570
+ turn, move, strafe, attack = action_value
571
+ action_value = [turn, move, strafe, attack]
572
+ turn_label = DEADLY_CORRIDOR_TURN_LABELS[turn]
573
+ move_label = DEADLY_CORRIDOR_MOVE_LABELS[move]
574
+ strafe_label = DEADLY_CORRIDOR_STRAFE_LABELS[strafe]
575
+ attack_label = DEADLY_CORRIDOR_ATTACK_LABELS[attack]
576
+ active_labels = [
577
+ label
578
+ for label in (turn_label, move_label, strafe_label, attack_label)
579
+ if not label.endswith("_NOOP")
580
+ ]
581
+ action_name = "+".join(active_labels) if active_labels else "NOOP"
582
+ return Action(
583
+ value=action_value,
584
+ name=action_name,
585
+ is_noop=action_value == [0, 0, 0, 0],
586
+ is_oneshot=False,
587
+ ), {
588
+ "decoded_action_tuple": action_value,
589
+ "turn_label": turn_label,
590
+ "move_label": move_label,
591
+ "strafe_label": strafe_label,
592
+ "attack_label": attack_label,
593
+ "action_label": action_name,
594
+ **metadata,
595
+ }
596
+
597
+
598
+ def _extract_observation_array(data: Any) -> npt.NDArray[Any]:
599
+ if isinstance(data, Mapping):
600
+ return np.asarray(data["observation"])
601
+ return np.asarray(data)
602
+
603
+
604
+ def _as_uint8_image(frame: npt.NDArray[Any]) -> npt.NDArray[np.uint8]:
605
+ return np.ascontiguousarray(frame, dtype=np.uint8)
606
+
607
+
608
+ def _normalized_model_cfg(model_cfg: Mapping[str, Any]) -> dict[str, Any]:
609
+ _ensure_starvla_path()
610
+ from omegaconf import OmegaConf
611
+ from starVLA.model.framework.share_tools import apply_config_compat
612
+
613
+ cfg = OmegaConf.create(model_cfg)
614
+ apply_config_compat(cfg)
615
+ _apply_model_family_include_state_compat(cfg)
616
+ return OmegaConf.to_container(cfg, resolve=True)
617
+
618
+
619
+ def _normalized_model_cfg_from_wrapper(wrapper: Any) -> dict[str, Any]:
620
+ return _normalized_model_cfg(wrapper._model_cfg)
621
+
622
+
623
+ def _load_starvla_model_config(path: str | Path) -> dict[str, Any]:
624
+ from omegaconf import OmegaConf
625
+
626
+ return _normalized_model_cfg(OmegaConf.load(path))
627
+
628
+
629
+ def _apply_model_family_include_state_compat(cfg: Any) -> None:
630
+ from omegaconf import OmegaConf
631
+
632
+ if OmegaConf.select(cfg, "datasets.vla_data.include_state") is not None:
633
+ return
634
+
635
+ model_ids = (
636
+ _normalized_optional_config_string(cfg, ("model",)),
637
+ _normalized_optional_config_string(cfg, ("rl_games", "model_alias")),
638
+ _normalized_optional_config_string(cfg, ("framework", "name")),
639
+ )
640
+ if any(model_id in STATEFUL_STARVLA_MODEL_IDS for model_id in model_ids if model_id is not None):
641
+ OmegaConf.update(cfg, "datasets.vla_data.include_state", True, force_add=True)
642
+ return
643
+ if any(model_id in STATELESS_STARVLA_MODEL_IDS for model_id in model_ids if model_id is not None):
644
+ OmegaConf.update(cfg, "datasets.vla_data.include_state", False, force_add=True)
645
+
646
+
647
+ def _normalized_optional_config_string(cfg: Any, path: tuple[str, ...]) -> str | None:
648
+ from omegaconf import OmegaConf
649
+
650
+ value = OmegaConf.select(cfg, ".".join(path))
651
+ if value is None:
652
+ return None
653
+ return str(value).strip().lower()
654
+
655
+
656
+ def _state_dim_from_model_cfg(model_cfg: dict[str, Any]) -> int:
657
+ return model_cfg["framework"]["action_model"]["state_dim"]
658
+
659
+
660
+ def _include_state_from_model_cfg(model_cfg: dict[str, Any]) -> bool:
661
+ return model_cfg["datasets"]["vla_data"]["include_state"]
662
+
663
+
664
+ _STITCH_FRAMES = None
665
+
666
+
667
+ def _get_stitch_frames():
668
+ """Lazily import starVLA's stitch_frames (starVLA path is added at runtime)."""
669
+ global _STITCH_FRAMES
670
+ if _STITCH_FRAMES is None:
671
+ _ensure_starvla_path()
672
+ from starVLA.training.trainer_utils.trainer_tools import stitch_frames
673
+
674
+ _STITCH_FRAMES = stitch_frames
675
+ return _STITCH_FRAMES
676
+
677
+
678
+ def _ensure_starvla_path() -> None:
679
+ starvla_root = str(STARVLA_ROOT)
680
+ if starvla_root not in sys.path:
681
+ sys.path.insert(0, starvla_root)
682
+
683
+
684
+ def _observation_stride_raw_frames(config: Mapping[str, Any]) -> int:
685
+ env_cfg = config["env"]
686
+ return EnvClock(
687
+ env_fps=float(env_cfg["env_fps"]),
688
+ obs_fps=float(env_cfg["obs_fps"]),
689
+ ).obs_stride_raw_frames
690
+
691
+
692
+ def apply_starvla_model_input_config(
693
+ config: dict[str, Any],
694
+ *,
695
+ model_cfg: Mapping[str, Any],
696
+ image_transform: str = "raw_rgb",
697
+ ) -> None:
698
+ """Match latency_bench's raw frame stack to a saved StarVLA input contract."""
699
+ vla_data = model_cfg["datasets"]["vla_data"]
700
+ pack_image_sequence = (
701
+ bool(vla_data["pack_image_sequence"])
702
+ if "pack_image_sequence" in vla_data
703
+ else False
704
+ )
705
+ normalized_transform = str(image_transform).strip().lower()
706
+ raw_image_transform = normalized_transform in {"", "none", "raw", "raw_rgb"}
707
+ if pack_image_sequence:
708
+ if not raw_image_transform:
709
+ raise ValueError(
710
+ "WanOFT packed image sequences require image_transform=raw_rgb"
711
+ )
712
+ input_frame_count = int(vla_data["image_sequence_length"])
713
+ else:
714
+ if not raw_image_transform:
715
+ return
716
+ framework_cfg = model_cfg["framework"]
717
+ kv_cfg = framework_cfg["kv_memory"] if "kv_memory" in framework_cfg else {}
718
+ kv_memory_enabled = bool(kv_cfg["enabled"]) if "enabled" in kv_cfg else False
719
+ if kv_memory_enabled:
720
+ return
721
+ image_mode = str(vla_data["image_mode"]) if "image_mode" in vla_data else "single"
722
+ if image_mode == "single":
723
+ return
724
+ input_frame_count = int(vla_data["num_obs_frames"])
725
+
726
+ observation_stride = _observation_stride_raw_frames(config)
727
+ required_raw_frames = 1 + (input_frame_count - 1) * observation_stride
728
+ config["env"]["frame_stack"] = max(
729
+ int(config["env"]["frame_stack"]),
730
+ required_raw_frames,
731
+ )
732
+
733
+
734
+ def prepare_starvla_checkpoint_input_config(config: dict[str, Any]) -> None:
735
+ """Apply the saved checkpoint input contract before env construction."""
736
+ if config["policy"]["type"] != "starvla":
737
+ return
738
+
739
+ policy_cfg = config["policy"]
740
+ if "task_contract_path" in policy_cfg:
741
+ if config["env"]["name"] == "gymnasium":
742
+ contract = json.loads(
743
+ Path(policy_cfg["task_contract_path"]).read_text(encoding="utf-8")
744
+ )
745
+ config["env"]["state_space"] = {"labels": contract["state_labels"]}
746
+ if contract["robot_type"] in ("latency_balance_profile_h8", "latency_balance_profile_h16"):
747
+ config["env"]["name"] = "balance_profile"
748
+ config["env"]["action_context_horizon"] = contract["action_horizon"]
749
+ config["env"]["frame_stack"] = 1
750
+ return
751
+ if "model_config_path" in policy_cfg:
752
+ model_cfg = _load_starvla_model_config(policy_cfg["model_config_path"])
753
+ else:
754
+ _ensure_starvla_path()
755
+ from starVLA.model.framework.share_tools import read_mode_config
756
+
757
+ saved_model_cfg, _norm_stats = read_mode_config(policy_cfg["checkpoint_path"])
758
+ model_cfg = _normalized_model_cfg(saved_model_cfg)
759
+ if config["env"]["name"] == "gymnasium":
760
+ image_size = model_cfg["rl_games"]["env_eval"]["image_size"]
761
+ config["env"]["obs_resize"] = [image_size, image_size]
762
+ image_transform_cfg = (
763
+ policy_cfg["image_transform_config"]
764
+ if "image_transform_config" in policy_cfg
765
+ else {}
766
+ )
767
+ image_transform = (
768
+ image_transform_cfg["image_transform"]
769
+ if "image_transform" in image_transform_cfg
770
+ else "raw_rgb"
771
+ )
772
+ apply_starvla_model_input_config(
773
+ config,
774
+ model_cfg=model_cfg,
775
+ image_transform=image_transform,
776
+ )
777
+
778
+
779
+ def _load_policy_wrapper_class() -> Any:
780
+ _ensure_starvla_path()
781
+ from deployment.model_server.policy_wrapper import PolicyServerWrapper
782
+
783
+ return PolicyServerWrapper
784
+
785
+
786
+ def _profiler_stage(profiler: Any, name: str) -> Any:
787
+ from contextlib import nullcontext
788
+
789
+ return profiler.time(name) if profiler is not None else nullcontext()
790
+
791
+
792
+ def _load_rl_games_action_decode() -> tuple[Any, Any, Any]:
793
+ _ensure_starvla_path()
794
+ from deployment.model_server.rl_games_action_decode import (
795
+ decode_rl_games_actions,
796
+ resolve_asterix_action_decode_spec,
797
+ resolve_deadly_action_decode_spec,
798
+ )
799
+
800
+ return decode_rl_games_actions, resolve_deadly_action_decode_spec, resolve_asterix_action_decode_spec
801
+
802
+
803
+ class LiveStarVlaWrapper:
804
+ """In-process stand-in for ``PolicyServerWrapper`` over a *live* framework.
805
+
806
+ During training the trainer already holds the model in memory
807
+ (``accelerator.unwrap_model(self.model)`` — the same object eval_core calls).
808
+ This wrapper exposes only the rl_games-mode surface ``StarVlaPolicyRunner``
809
+ uses — ``predict_action`` (framework forward + rl_games decode),
810
+ ``reset_memory`` passthrough, and the ``_model_cfg`` attribute — so no
811
+ checkpoint reload is needed. The disk-backed ``PolicyNormProcessor`` is never
812
+ built because rl_games decoding ignores un-normalization stats.
813
+ """
814
+
815
+ def __init__(
816
+ self,
817
+ *,
818
+ framework: Any,
819
+ model_cfg: dict[str, Any],
820
+ env_name: str,
821
+ rl_games_action_env_dim: int | None = None,
822
+ gymnasium_action_space_type: str = "discrete",
823
+ action_layout: str | None = None,
824
+ multibinary_threshold: float | None = None,
825
+ ) -> None:
826
+ self._framework = framework
827
+ self._model_cfg = model_cfg
828
+ self._rl_games_env_name = str(env_name)
829
+ self._rl_games_action_env_dim = rl_games_action_env_dim
830
+ self._gymnasium_action_space_type = gymnasium_action_space_type
831
+ (
832
+ self._decode_rl_games_actions,
833
+ resolve_deadly_action_decode_spec,
834
+ resolve_asterix_action_decode_spec,
835
+ ) = _load_rl_games_action_decode()
836
+ self._action_layout = action_layout
837
+ self._multibinary_threshold = multibinary_threshold
838
+ if self._rl_games_env_name == "deadly_corridor":
839
+ self._action_layout, self._multibinary_threshold = resolve_deadly_action_decode_spec(
840
+ model_cfg,
841
+ action_layout=action_layout,
842
+ multibinary_threshold=multibinary_threshold,
843
+ )
844
+ elif self._rl_games_env_name == "asterix":
845
+ self._action_layout = resolve_asterix_action_decode_spec(
846
+ model_cfg,
847
+ action_layout=action_layout,
848
+ )
849
+
850
+ def reset_memory(self, slot_id: int | None = None) -> None:
851
+ reset = getattr(self._framework, "reset_memory", None)
852
+ if callable(reset):
853
+ reset(slot_id)
854
+
855
+ def predict_action(
856
+ self,
857
+ examples: list[dict[str, Any]],
858
+ unnorm_key: str | None = None,
859
+ **kwargs: Any,
860
+ ) -> dict[str, Any]:
861
+ # unnorm_key is unused in rl_games mode; kept for interface parity.
862
+ del unnorm_key
863
+ profiler = kwargs["profiler"] if "profiler" in kwargs else None
864
+ out = self._framework.predict_action(examples=examples, **kwargs)
865
+ normalized = np.asarray(out["normalized_actions"]) # (B, T, D)
866
+ decode_kwargs: dict[str, Any] = {}
867
+ if self._rl_games_env_name == "gymnasium":
868
+ decode_kwargs["action_env_dim"] = self._rl_games_action_env_dim
869
+ if self._gymnasium_action_space_type == "box":
870
+ decode_kwargs["gymnasium_action_space_type"] = "box"
871
+ with _profiler_stage(profiler, "starvla_wrapper_rl_games_decode_ms"):
872
+ return self._decode_rl_games_actions(
873
+ normalized_actions=normalized,
874
+ env_name=self._rl_games_env_name,
875
+ deadly_action_layout=(
876
+ self._action_layout
877
+ if self._rl_games_env_name == "deadly_corridor"
878
+ else None
879
+ ),
880
+ deadly_multibinary_threshold=(
881
+ self._multibinary_threshold
882
+ if self._rl_games_env_name == "deadly_corridor"
883
+ else None
884
+ ),
885
+ asterix_action_layout=(
886
+ self._action_layout
887
+ if self._rl_games_env_name == "asterix"
888
+ else None
889
+ ),
890
+ **decode_kwargs,
891
+ )
892
+
893
+
894
+ _LEGACY_GYMNASIUM_TASK_NAMES = {
895
+ "ant_rgb_state": "ant",
896
+ "half_cheetah_rgb_state": "half_cheetah",
897
+ "hopper_rgb_state": "hopper",
898
+ "humanoid_rgb_state": "humanoid",
899
+ "inverted_pendulum_rgb_state": "inverted_pendulum",
900
+ "swimmer_rgb_state": "swimmer",
901
+ "walker2d_rgb_state": "walker2d",
902
+ }
903
+
904
+
905
+ def _canonical_gymnasium_contract_namespace(
906
+ contract: Mapping[str, Any],
907
+ ) -> dict[str, Any]:
908
+ canonical = dict(contract)
909
+ task_name = canonical["task_name"]
910
+ if task_name in _LEGACY_GYMNASIUM_TASK_NAMES:
911
+ canonical["task_name"] = _LEGACY_GYMNASIUM_TASK_NAMES[task_name]
912
+ if canonical["env_id"] == "LatencyBench/HopperRgbState-v0":
913
+ canonical["env_id"] = "LatencyBench/Hopper-v0"
914
+ canonical["registration_imports"] = [
915
+ "latency_bench.envs.gymnasium_hopper"
916
+ if module == "latency_bench.envs.gymnasium_hopper_rgb_state"
917
+ else module
918
+ for module in canonical["registration_imports"]
919
+ ]
920
+ return canonical
921
+
922
+
923
+ def _validate_gymnasium_starvla_contract(
924
+ *,
925
+ env_cfg: Mapping[str, Any],
926
+ policy_cfg: Mapping[str, Any],
927
+ model_cfg: Mapping[str, Any],
928
+ manifest: Mapping[str, Any],
929
+ ) -> None:
930
+ eval_contract = gymnasium_task_contract(env_cfg)
931
+ manifest_task = manifest.get("gymnasium_task")
932
+ expected = policy_cfg.get(
933
+ "gymnasium_training_task_contract", manifest_task or eval_contract
934
+ )
935
+ comparable_eval_contract = {**eval_contract, "make_kwargs": expected["make_kwargs"]}
936
+ if _canonical_gymnasium_contract_namespace(
937
+ comparable_eval_contract
938
+ ) != _canonical_gymnasium_contract_namespace(expected):
939
+ raise ValueError(
940
+ "Evaluation Gymnasium task contract does not match the StarVLA training contract or dataset manifest"
941
+ )
942
+ if manifest.get("integration_name", "gymnasium") != "gymnasium":
943
+ raise ValueError("StarVLA task manifest is not a Gymnasium handoff")
944
+ if manifest_task is not None:
945
+ if _canonical_gymnasium_contract_namespace(
946
+ manifest_task
947
+ ) != _canonical_gymnasium_contract_namespace(expected):
948
+ raise ValueError(
949
+ "Evaluation Gymnasium task contract does not match the StarVLA dataset manifest"
950
+ )
951
+ model_contract = model_cfg["datasets"]["vla_data"].get("gymnasium_task_contract")
952
+ if model_contract is not None:
953
+ if _canonical_gymnasium_contract_namespace(
954
+ model_contract
955
+ ) != _canonical_gymnasium_contract_namespace(expected):
956
+ raise ValueError(
957
+ "Evaluation Gymnasium task contract does not match the StarVLA model config"
958
+ )
959
+ action_space = gymnasium_action_space_contract(env_cfg)
960
+ action_layout = str(policy_cfg.get("action_layout", "") or "").strip().lower()
961
+ is_asterix_factorized = (
962
+ str(env_cfg.get("task_name", "")) == "asterix"
963
+ and action_layout in {"factorized_6", "factorized6", "asterix_factorized_6", "asterix_factorized6"}
964
+ )
965
+ if not is_asterix_factorized and manifest["active_action_dim"] != len(action_space["labels"]):
966
+ raise ValueError(
967
+ "StarVLA dataset active_action_dim does not match its Gymnasium action catalog"
968
+ )
969
+ if (
970
+ model_cfg["framework"]["action_model"]["action_env_dim"]
971
+ != manifest["active_action_dim"]
972
+ ):
973
+ raise ValueError(
974
+ "StarVLA model action_env_dim does not match the dataset manifest"
975
+ )
976
+ model_uses_state = bool(model_cfg["datasets"]["vla_data"]["include_state"])
977
+ manifest_has_state_metadata = (
978
+ "uses_state" in manifest or "state_labels" in manifest
979
+ )
980
+ manifest_uses_state = bool(manifest.get("uses_state", model_uses_state))
981
+ if manifest_has_state_metadata:
982
+ if policy_cfg.get("state_source") != "transport" and manifest_uses_state != ("state_space" in expected):
983
+ raise ValueError(
984
+ "StarVLA dataset uses_state does not match the Gymnasium state space"
985
+ )
986
+ if manifest_uses_state != model_uses_state:
987
+ raise ValueError(
988
+ "StarVLA dataset uses_state does not match the model include_state"
989
+ )
990
+ if manifest_has_state_metadata and manifest_uses_state:
991
+ state_labels = manifest["state_labels"]
992
+ expected_state_labels = expected["state_space"]["labels"] if policy_cfg.get("state_source") != "transport" else state_labels
993
+ if state_labels != expected_state_labels:
994
+ raise ValueError(
995
+ "StarVLA dataset state_labels do not match the Gymnasium state space"
996
+ )
997
+ if manifest["state_dim"] != len(state_labels):
998
+ raise ValueError(
999
+ "StarVLA dataset state_dim does not match its state_labels"
1000
+ )
1001
+ if (
1002
+ model_cfg["framework"]["action_model"]["state_dim"]
1003
+ != manifest["state_dim"]
1004
+ ):
1005
+ raise ValueError(
1006
+ "StarVLA model state_dim does not match the dataset manifest"
1007
+ )
1008
+ if not manifest["state_normalization"]:
1009
+ raise ValueError(
1010
+ "StarVLA state-enabled dataset manifest is missing state_normalization"
1011
+ )
1012
+
1013
+
1014
+ def _starvla_runner_kwargs(
1015
+ config: dict[str, Any],
1016
+ action_resolver: ActionResolver,
1017
+ model_cfg: Mapping[str, Any] | None,
1018
+ *,
1019
+ base_prompt: str | None,
1020
+ ) -> dict[str, Any]:
1021
+ """Resolve task and input settings shared by checkpoint and resident models."""
1022
+ env_cfg = config["env"]
1023
+ policy_cfg = config["policy"]
1024
+ if env_cfg["name"] == "gymnasium":
1025
+ task_manifest = json.loads(
1026
+ Path(policy_cfg["task_manifest_path"]).read_text(encoding="utf-8")
1027
+ )
1028
+ _validate_gymnasium_starvla_contract(
1029
+ env_cfg=env_cfg,
1030
+ policy_cfg=policy_cfg,
1031
+ model_cfg=model_cfg,
1032
+ manifest=task_manifest,
1033
+ )
1034
+ semantic_env_name = env_cfg["task_name"]
1035
+ action_refs = env_cfg.get("action_order", [])
1036
+ base_prompt = env_cfg["base_prompt"]
1037
+ state_normalization = task_manifest.get("state_normalization")
1038
+ else:
1039
+ semantic_env_name = env_cfg["name"]
1040
+ action_refs = policy_cfg.get("actions", action_resolver.default_action_refs())
1041
+ state_normalization = policy_cfg["state_normalization"] if "state_normalization" in policy_cfg else None
1042
+ return dict(
1043
+ unnorm_key=policy_cfg.get("unnorm_key"),
1044
+ env_name=semantic_env_name,
1045
+ action_resolver=action_resolver,
1046
+ action_refs=action_refs,
1047
+ latency_prompt_map=(
1048
+ load_latency_prompt_map(policy_cfg["latency_prompt_map_path"])
1049
+ if "latency_prompt_map_path" in policy_cfg
1050
+ else None
1051
+ ),
1052
+ base_prompt=base_prompt,
1053
+ latency_prompt_key=policy_cfg.get("latency_prompt_key"),
1054
+ prompt_mode=policy_cfg.get("prompt_mode"),
1055
+ obs_resize=tuple(env_cfg["obs_resize"]) if env_cfg.get("obs_resize") else None,
1056
+ image_transform_config=policy_cfg.get("image_transform_config"),
1057
+ observation_stride_raw_frames=_observation_stride_raw_frames(config),
1058
+ model_cfg=model_cfg,
1059
+ state_normalization=state_normalization,
1060
+ state_source=policy_cfg["state_source"] if "state_source" in policy_cfg else None,
1061
+ )
1062
+
1063
+
1064
+ def build_starvla_policy(
1065
+ config: dict[str, Any],
1066
+ action_resolver: ActionResolver,
1067
+ ) -> PolicyRunner:
1068
+ policy_cfg = config["policy"]
1069
+ if "task_contract_path" in policy_cfg:
1070
+ _ensure_starvla_path()
1071
+ from latency_bench.policy.starvla_tasks import build_task_starvla_policy
1072
+
1073
+ return build_task_starvla_policy(config)
1074
+ env_cfg = config["env"]
1075
+ integration_env_name = env_cfg["name"]
1076
+ model_cfg = (
1077
+ _load_starvla_model_config(policy_cfg["model_config_path"])
1078
+ if integration_env_name == "gymnasium" or "model_config_path" in policy_cfg
1079
+ else None
1080
+ )
1081
+ runner_kwargs = _starvla_runner_kwargs(
1082
+ config, action_resolver, model_cfg, base_prompt=env_cfg.get("base_prompt")
1083
+ )
1084
+ wrapper_cls = _load_policy_wrapper_class()
1085
+ wrapper_kwargs: dict[str, Any] = dict(
1086
+ ckpt_path=policy_cfg["checkpoint_path"],
1087
+ device=policy_cfg["device"],
1088
+ use_bf16=True,
1089
+ unnorm_key=runner_kwargs["unnorm_key"],
1090
+ action_output_mode=(
1091
+ policy_cfg["action_output_mode"]
1092
+ if "action_output_mode" in policy_cfg
1093
+ else "rl_games"
1094
+ ),
1095
+ rl_games_env_name=integration_env_name,
1096
+ rl_games_action_layout=(
1097
+ policy_cfg["action_layout"] if "action_layout" in policy_cfg else None
1098
+ ),
1099
+ rl_games_multibinary_threshold=(
1100
+ policy_cfg["multibinary_threshold"]
1101
+ if "multibinary_threshold" in policy_cfg
1102
+ else None
1103
+ ),
1104
+ )
1105
+ if "backbone_path" in policy_cfg:
1106
+ wrapper_kwargs["backbone_path"] = policy_cfg["backbone_path"]
1107
+ if integration_env_name == "gymnasium":
1108
+ action_space = gymnasium_action_space_contract(env_cfg)
1109
+ wrapper_kwargs["rl_games_action_env_dim"] = len(action_space["labels"])
1110
+ if action_space["type"] == "box":
1111
+ wrapper_kwargs["rl_games_gymnasium_action_space_type"] = "box"
1112
+ wrapper_kwargs["rl_games_env_name"] = integration_env_name
1113
+ wrapper = wrapper_cls(**wrapper_kwargs)
1114
+ return StarVlaPolicyRunner(
1115
+ wrapper=wrapper,
1116
+ checkpoint_path=policy_cfg["checkpoint_path"],
1117
+ device=policy_cfg["device"],
1118
+ **runner_kwargs,
1119
+ image_views_info_key=(
1120
+ policy_cfg["image_views_info_key"]
1121
+ if "image_views_info_key" in policy_cfg
1122
+ else None
1123
+ ),
1124
+ action_output_type=(
1125
+ policy_cfg["action_output_type"]
1126
+ if "action_output_type" in policy_cfg
1127
+ else None
1128
+ ),
1129
+ )
1130
+
1131
+
1132
+ def build_live_starvla_policy(
1133
+ *,
1134
+ framework: Any,
1135
+ model_cfg: dict[str, Any],
1136
+ config: dict[str, Any],
1137
+ action_resolver: ActionResolver | None = None,
1138
+ ) -> PolicyRunner:
1139
+ """Build a StarVLA policy around a *live* in-memory framework (no reload).
1140
+
1141
+ Mirrors ``build_starvla_policy`` but swaps the ckpt-loading
1142
+ ``PolicyServerWrapper`` for :class:`LiveStarVlaWrapper`, so the trainer's
1143
+ resident model is evaluated directly. ``model_cfg`` is the in-memory model
1144
+ config (e.g. ``read_mode_config`` output) the wrapper would otherwise read
1145
+ from disk.
1146
+ """
1147
+ policy_cfg = config["policy"]
1148
+ if "task_contract_path" in policy_cfg:
1149
+ from latency_bench.policy.starvla_tasks import TaskStarVlaPolicyRunner
1150
+
1151
+ contract = json.loads(
1152
+ Path(policy_cfg["task_contract_path"]).read_text(encoding="utf-8")
1153
+ )
1154
+ return TaskStarVlaPolicyRunner(
1155
+ framework,
1156
+ policy_config=policy_cfg,
1157
+ model_config=model_cfg,
1158
+ contract=contract,
1159
+ )
1160
+
1161
+ env_cfg = config["env"]
1162
+ integration_env_name = env_cfg["name"]
1163
+ normalized_model_cfg = (
1164
+ _normalized_model_cfg(model_cfg)
1165
+ if integration_env_name == "gymnasium"
1166
+ else None
1167
+ )
1168
+ # Resident evaluation historically takes non-Gymnasium prompts from the map.
1169
+ runner_kwargs = _starvla_runner_kwargs(
1170
+ config, action_resolver, normalized_model_cfg, base_prompt=None
1171
+ )
1172
+ wrapper_kwargs: dict[str, Any] = dict(
1173
+ framework=framework,
1174
+ model_cfg=model_cfg,
1175
+ env_name=integration_env_name,
1176
+ action_layout=policy_cfg["action_layout"] if "action_layout" in policy_cfg else None,
1177
+ multibinary_threshold=(
1178
+ policy_cfg["multibinary_threshold"]
1179
+ if "multibinary_threshold" in policy_cfg
1180
+ else None
1181
+ ),
1182
+ )
1183
+ if integration_env_name == "gymnasium":
1184
+ action_space = gymnasium_action_space_contract(env_cfg)
1185
+ wrapper_kwargs["rl_games_action_env_dim"] = len(action_space["labels"])
1186
+ if action_space["type"] == "box":
1187
+ wrapper_kwargs["gymnasium_action_space_type"] = "box"
1188
+ wrapper_kwargs["env_name"] = integration_env_name
1189
+ wrapper = LiveStarVlaWrapper(**wrapper_kwargs)
1190
+ return StarVlaPolicyRunner(
1191
+ wrapper=wrapper,
1192
+ checkpoint_path=policy_cfg.get("checkpoint_path", ""),
1193
+ device=policy_cfg.get("device", "cuda"),
1194
+ **runner_kwargs,
1195
+ )
1196
+
1197
+
1198
+ __all__ = [
1199
+ "LiveStarVlaWrapper",
1200
+ "StarVlaPolicyRunner",
1201
+ "apply_starvla_model_input_config",
1202
+ "build_live_starvla_policy",
1203
+ "build_starvla_policy",
1204
+ "decode_starvla_action",
1205
+ "observation_data_to_hwc_uint8_frames",
1206
+ "prepare_starvla_checkpoint_input_config",
1207
+ ]
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/starvla_tasks.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """StarVLA inference using the task's training observation/action contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from pathlib import Path
7
+
8
+ import numpy as np
9
+ from PIL import Image
10
+
11
+ from latency_bench.core.types import Action, Observation, PolicyOutput
12
+ from latency_bench.data.starvla_tasks import denormalize, normalize
13
+ from latency_bench.policy.base import PolicyRunner
14
+
15
+
16
+ class TaskStarVlaPolicyRunner(PolicyRunner):
17
+ """Map task RGB/state into a StarVLA model and decode its action chunk."""
18
+
19
+ def __init__(self, framework, *, policy_config: dict, model_config: dict, contract: dict):
20
+ self.framework = framework
21
+ self.policy_config = policy_config
22
+ self.model_config = model_config
23
+ self.contract = contract
24
+
25
+ def _example(self, observation: Observation) -> dict:
26
+ cfg = self.policy_config
27
+ state = normalize(
28
+ observation.metadata[cfg["state_info_key"]],
29
+ self.contract["normalization"]["state"],
30
+ ).reshape(1, self.contract["state_dim"])
31
+ data_cfg = self.model_config["datasets"]["vla_data"]
32
+ height, width = data_cfg["obs_image_size"]
33
+ images = [
34
+ Image.fromarray(frame).resize((width, height))
35
+ for frame in observation.metadata[cfg["image_views_info_key"]]
36
+ ]
37
+ if data_cfg["image_mode"] == "stitch_views":
38
+ from starVLA.training.trainer_utils.trainer_tools import stitch_frames
39
+
40
+ # MIKASA's two simultaneous views form one Wan observation, not a video.
41
+ images = [stitch_frames(images, grid=data_cfg["stitch_grid"], size=(width, height))]
42
+ example = {"image": images, "state": state, "lang": self.contract["prompt"]}
43
+ if "action_prefix" in observation.metadata:
44
+ example["action_prefix"] = normalize(
45
+ observation.metadata["action_prefix"],
46
+ self.contract["normalization"]["action"],
47
+ )
48
+ example["action_prefix_mask"] = observation.metadata["action_prefix_mask"]
49
+ return example
50
+
51
+ def predict(self, observation: Observation) -> PolicyOutput:
52
+ return self.predict_batch([observation])[0]
53
+
54
+ def predict_batch(self, observations: list[Observation]) -> list[PolicyOutput]:
55
+ prediction = self.framework.predict_action(
56
+ examples=[self._example(observation) for observation in observations]
57
+ )
58
+ actions = denormalize(
59
+ prediction["normalized_actions"], self.contract["normalization"]["action"]
60
+ )
61
+ # Prefix heads were excluded from the loss; retain the frozen controller plan.
62
+ for chunk, observation in zip(actions, observations):
63
+ if "action_prefix" in observation.metadata:
64
+ mask = observation.metadata["action_prefix_mask"]
65
+ chunk[mask] = observation.metadata["action_prefix"][mask]
66
+ return [
67
+ PolicyOutput(
68
+ action=Action(value=chunk[0].tolist(), name="task_command"),
69
+ action_chunk=chunk,
70
+ raw_output=chunk.tolist(),
71
+ metadata={"policy_type": "starvla", "task": self.contract["task"]},
72
+ )
73
+ for chunk in actions
74
+ ]
75
+
76
+
77
+ def build_task_starvla_policy(config: dict) -> TaskStarVlaPolicyRunner:
78
+ # StarVLA and torch are optional in the simulator process; workers own them.
79
+ import torch
80
+ from starVLA.model.framework.base_framework import baseframework
81
+ from starVLA.model.framework.share_tools import read_mode_config
82
+
83
+ cfg = config["policy"]
84
+ model_config, _ = read_mode_config(cfg["checkpoint_path"])
85
+ framework = baseframework.from_pretrained(
86
+ cfg["checkpoint_path"], backbone_path=cfg["backbone_path"]
87
+ )
88
+ framework = framework.to(device=cfg["device"], dtype=torch.bfloat16).eval()
89
+ contract = json.loads(Path(cfg["task_contract_path"]).read_text(encoding="utf-8"))
90
+ return TaskStarVlaPolicyRunner(
91
+ framework, policy_config=cfg, model_config=model_config, contract=contract
92
+ )
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-plan.json ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "condition": "profile-latency",
3
+ "executor_mode": "simulated",
4
+ "latency_method": "temporal",
5
+ "profile_source": "originalRTX3090immutableprofiles",
6
+ "episodes_per_checkpoint": 100,
7
+ "total_episodes": 400,
8
+ "rounds": [
9
+ [
10
+ "flappy",
11
+ "deadly_corridor"
12
+ ],
13
+ [
14
+ "ant",
15
+ "intercept"
16
+ ]
17
+ ],
18
+ "physical_gpu_assignments": {
19
+ "flappy": 2,
20
+ "deadly_corridor": 3,
21
+ "ant": 2,
22
+ "intercept": 3
23
+ },
24
+ "single_gpu_per_job": true,
25
+ "round2_requires_both_round1_complete": true,
26
+ "latency_seed": 271828,
27
+ "tasks": {
28
+ "flappy": {
29
+ "gpu": 2,
30
+ "seed_start": 1000000,
31
+ "seed_end": 1000099,
32
+ "env_fps": 10,
33
+ "obs_fps": 10,
34
+ "max_raw_steps": 3600,
35
+ "parallel_envs": 32,
36
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
37
+ "checkpoint_path": "latency-aware/flappy/vla/starvla-qwenoft-h1/flappy-qwenoft-mean-3090-s42",
38
+ "profile": {
39
+ "mean_ms": 75.87417450998383,
40
+ "profile": "/home/ubuntu/lzj/profiles/published/profiles/openvla/1x-rtx3090/flappy/instance_a5037b165aa0cedc/profile.json",
41
+ "sha256": "c266cba7ebac05c7e37bc83f1f16fe4b27dab97942ff43290e6c41514f6e39fc"
42
+ },
43
+ "config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/flappy.yaml",
44
+ "output": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/flappy",
45
+ "metrics": "return mean/std/min/max;length mean/std;success where nativeprovided;latency/drops/invalid/action audits;100 episode vectors"
46
+ },
47
+ "deadly_corridor": {
48
+ "gpu": 3,
49
+ "seed_start": 1000000,
50
+ "seed_end": 1000099,
51
+ "env_fps": 35,
52
+ "obs_fps": 8.75,
53
+ "max_raw_steps": 3600,
54
+ "parallel_envs": 32,
55
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
56
+ "checkpoint_path": "latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42",
57
+ "profile": {
58
+ "mean_ms": 73.69250777493353,
59
+ "profile": "/home/ubuntu/lzj/profiles/published/profiles/openvla/1x-rtx3090/deadly_corridor/instance_a5037b165aa0cedc/profile.json",
60
+ "sha256": "bbfb93cef9f63750a9a159ec10a93a9fc6c25e4cb0cac3b39532663b4dc11eba"
61
+ },
62
+ "config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/deadly_corridor.yaml",
63
+ "output": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/deadly_corridor",
64
+ "metrics": "return mean/std/min/max;length mean/std;success where nativeprovided;latency/drops/invalid/action audits;100 episode vectors"
65
+ },
66
+ "ant": {
67
+ "gpu": 2,
68
+ "seed_start": 42,
69
+ "seed_end": 141,
70
+ "env_fps": 10,
71
+ "obs_fps": 10,
72
+ "max_raw_steps": 1000,
73
+ "parallel_envs": 16,
74
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
75
+ "checkpoint_path": "latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42",
76
+ "profile": {
77
+ "mean_ms": 90.56460638563993,
78
+ "profile": "/home/ubuntu/lzj/mean-profiling/reference/checkpoint-configs/latency-aware/ant/small-policy/sample-factory-qwenoft-rtx3090-v1/profile/profile.json",
79
+ "sha256": "0e49f72ec05ac600a54e07bbca5af3143708444d606167f33fa21788a9fefe50"
80
+ },
81
+ "config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant.yaml",
82
+ "output": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant",
83
+ "metrics": "return mean/std/min/max;length mean/std;success where nativeprovided;latency/drops/invalid/action audits;100 episode vectors"
84
+ },
85
+ "intercept": {
86
+ "gpu": 3,
87
+ "seed_start": 4242424242,
88
+ "seed_end": 4242424341,
89
+ "env_fps": 20,
90
+ "obs_fps": 20,
91
+ "max_raw_steps": 60,
92
+ "parallel_envs": 32,
93
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
94
+ "checkpoint_path": "latency-aware/mikasa-intercept-grab-fast/vla/starvla-qwenoft-h1/intercept-qwenoft-mean-3090-h1-s0",
95
+ "profile": {
96
+ "mean_ms": 99.05021289731565,
97
+ "profile": "/home/ubuntu/lzj/profiles/intercept-published/profiles/qwenoft/1x-rtx3090/mikasa_intercept_grab_fast/instance_3a0d42681a03715c/profile.json",
98
+ "sha256": "31a9b15d6b04182439934f0b377cb3d09be16ce21f3cf95c1049918f8a5d4984"
99
+ },
100
+ "config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/intercept.yaml",
101
+ "output": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/intercept",
102
+ "metrics": "return mean/std/min/max;length mean/std;success where nativeprovided;latency/drops/invalid/action audits;100 episode vectors"
103
+ }
104
+ }
105
+ }
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/execution_audit.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "issued_action_records": 79573,
3
+ "applied_action_records": 79465,
4
+ "dropped_action_records": 0,
5
+ "nonnoop_issued_records": 79573,
6
+ "finite_action_values": true,
7
+ "latency_sample_count": 79573,
8
+ "latency_mean_ms": 90.00919554158884,
9
+ "latency_std_ms": 2.514492574433973,
10
+ "latency_p95_ms": 91.11971585797141,
11
+ "latency_p99_ms": 102.67108120995428
12
+ }
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/files.sha256.json ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "REPORT.md": {
3
+ "bytes": 2163,
4
+ "sha256": "b2fd63b1cde2a415b2d77daf0184ce5ec3b6ada1aa199c21941fb04031f77db6"
5
+ },
6
+ "all_episodes.csv": {
7
+ "bytes": 25198,
8
+ "sha256": "bd41f35a464250ed6f9bc16e466aa9f1b55a48ac29072bb0ec3559a24129edac"
9
+ },
10
+ "comparison.csv": {
11
+ "bytes": 438,
12
+ "sha256": "a0c7cf191395dd851bd6222bdf61427f15782fea2db4416ddc072a5f5dc8a861"
13
+ },
14
+ "comparison.json": {
15
+ "bytes": 7826,
16
+ "sha256": "0d5dd042439466aee84cd0d96c31a27a951e57965a7e468cb73ec07883f1f751"
17
+ },
18
+ "episodes.csv": {
19
+ "bytes": 5314,
20
+ "sha256": "50f01becf2fc32fc3051b84314ae9c6494bf356b8cee8bf9ad4108b5bd9b9188"
21
+ },
22
+ "eval_config.yaml": {
23
+ "bytes": 5217,
24
+ "sha256": "ecbfbe6a7642142e6ec5941eb8a9545d2d49d0d54bba649be7e4faf1824ce36e"
25
+ },
26
+ "evaluation-code/batched_simulated.py": {
27
+ "bytes": 31282,
28
+ "sha256": "b901f966d911feab7962a32f21095cb90f7880121811f2b4eab2193afe1381db"
29
+ },
30
+ "evaluation-code/deadly-compatibility.patch": {
31
+ "bytes": 4570,
32
+ "sha256": "623676cc4542b1eab6c9395b163b369ddc605353c1de02d17d8f713167ee07fa"
33
+ },
34
+ "evaluation-code/deadly_corridor.py": {
35
+ "bytes": 17902,
36
+ "sha256": "47f7bc65cba9853e66d79ed2a28f844bd2a094f1285458be166045f2db1690dc"
37
+ },
38
+ "evaluation-code/decision_action_history.py": {
39
+ "bytes": 2746,
40
+ "sha256": "14a9d223e775745b6c402dbce9e2a50a1c3f7b5b9fe528150ef8689126fe97cf"
41
+ },
42
+ "evaluation-code/eval_driver.py": {
43
+ "bytes": 9133,
44
+ "sha256": "330030270fbb695bc5f14037ef7349650bd20c53c881c1159ee55ea066408d9e"
45
+ },
46
+ "evaluation-code/mikasa_evaluate.py": {
47
+ "bytes": 11466,
48
+ "sha256": "6cf9ffee25fcfd6f3255c520fc544c48ff2c8f8912e5369c2410a709820c4ffd"
49
+ },
50
+ "evaluation-code/starvla.py": {
51
+ "bytes": 48378,
52
+ "sha256": "6d9988f3a28d39e46c2f6e80da85edebc42cafa629a2b9f75000414324c1065a"
53
+ },
54
+ "evaluation-code/starvla_tasks.py": {
55
+ "bytes": 4029,
56
+ "sha256": "3fc74169d1554d9dc3358ed85e450cca75eb69bc1fff85284c1054a605633a52"
57
+ },
58
+ "evaluation-plan.json": {
59
+ "bytes": 4698,
60
+ "sha256": "b758a5fb72dcdef49d025e2fd168d024ebd8b18b2b00125145b3cde38b16a318"
61
+ },
62
+ "execution_audit.json": {
63
+ "bytes": 361,
64
+ "sha256": "6e5794d7a4456ff19b474e542e5ac03e569e26680ea7cde76b4544fa97394f1c"
65
+ },
66
+ "profile/latency_burst_model.json": {
67
+ "bytes": 26859,
68
+ "sha256": "3d41d58e5b4a51390f1984f69066b72831ef0b95b113577f37a4f0dfde65214f"
69
+ },
70
+ "profile/latency_distribution.json": {
71
+ "bytes": 25092,
72
+ "sha256": "58b144f743a58073234a29f53355aa19b41851cae47686904c38847def37bb94"
73
+ },
74
+ "profile/profile.json": {
75
+ "bytes": 2148,
76
+ "sha256": "0e49f72ec05ac600a54e07bbca5af3143708444d606167f33fa21788a9fefe50"
77
+ },
78
+ "provenance.json": {
79
+ "bytes": 3751,
80
+ "sha256": "990ab3236a0247b51f73e61555fd30bf3d408c8724713d28c7d9a64a55e0c55b"
81
+ },
82
+ "queue_eval_latency_profile_sample.json": {
83
+ "bytes": 3953,
84
+ "sha256": "32ff1a934595711c9e5bfe9cc4d033bcf9778187e83c837affb3418d0f2dd853"
85
+ },
86
+ "raw-records/actions.jsonl.gz": {
87
+ "bytes": 12313765,
88
+ "sha256": "c1354df8561fbd24c78158553cb997343065983d33497883dac41e2177a421cf"
89
+ },
90
+ "raw-records/e2e_latencies.jsonl.gz": {
91
+ "bytes": 1639178,
92
+ "sha256": "c43d7986e0bd8cfa33d1fb30dd48832c1c48df9a557aa5d97d3b11bb7be4986a"
93
+ },
94
+ "raw-records/episode_metrics.jsonl.gz": {
95
+ "bytes": 7869,
96
+ "sha256": "1c791b0600f8690f8d3f36f2656417e4cab6a368173a6f08adb5f23ad71028f9"
97
+ },
98
+ "raw-records/infer_latencies.jsonl.gz": {
99
+ "bytes": 1162241,
100
+ "sha256": "eaa49aa3fbce55063a9c3037d18a6b9ff3bd327981b4a4f35799a99c434189df"
101
+ },
102
+ "raw-records/latencies.jsonl.gz": {
103
+ "bytes": 1162235,
104
+ "sha256": "0c09425581b2ad7d7786b9489ce88bfc64eecd577fec18aa66280c27e08b8f18"
105
+ },
106
+ "raw-records/observation_attempts.jsonl.gz": {
107
+ "bytes": 47,
108
+ "sha256": "b1a7d5db5a150efea2d3bb76abaa4d5328c50ae0918a01e1e891509155994759"
109
+ },
110
+ "raw-records/queue_eval_results.jsonl.gz": {
111
+ "bytes": 1548,
112
+ "sha256": "163339eb50d2c2964191177ea5918ce97b681f08c2efb4694c9279cddb37854e"
113
+ },
114
+ "raw-records/steps.jsonl.gz": {
115
+ "bytes": 16329224,
116
+ "sha256": "0ffffd6f5f47d90c8a79ffbafddbca7c98c15fe48b10563a3a5fd7d5bc5d7db3"
117
+ },
118
+ "resolved_config.yaml": {
119
+ "bytes": 5285,
120
+ "sha256": "1c10ee3785bbf188e4a406e7e6cc934fdf637cf00b006a1792b24410b95d233a"
121
+ },
122
+ "statistics.json": {
123
+ "bytes": 1222,
124
+ "sha256": "694b29fddd346892c7559f611fcba1949fd377dc14ea751c52e28e89809d0ff9"
125
+ },
126
+ "stdout.log": {
127
+ "bytes": 27591,
128
+ "sha256": "f5c6dff29aacd92ac3a83c5d6df326b98145332af60278c69a3a75a34a541b77"
129
+ }
130
+ }
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/profile/latency_burst_model.json ADDED
@@ -0,0 +1,1336 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "burst_dwell_distribution": {
3
+ "distribution_type": "inverse_cdf",
4
+ "latency_ms": [
5
+ 21.0,
6
+ 21.0,
7
+ 21.0,
8
+ 21.0,
9
+ 21.0,
10
+ 21.0,
11
+ 21.0,
12
+ 21.0,
13
+ 21.0,
14
+ 21.0,
15
+ 21.0,
16
+ 21.0,
17
+ 21.0,
18
+ 21.0,
19
+ 21.0,
20
+ 21.0,
21
+ 21.0,
22
+ 21.0,
23
+ 21.0,
24
+ 21.0,
25
+ 21.0,
26
+ 21.0,
27
+ 21.15,
28
+ 21.3,
29
+ 21.45,
30
+ 21.6,
31
+ 21.75,
32
+ 21.9,
33
+ 22.05,
34
+ 22.2,
35
+ 22.35,
36
+ 22.5,
37
+ 22.65,
38
+ 22.8,
39
+ 22.95,
40
+ 23.1,
41
+ 23.25,
42
+ 23.4,
43
+ 23.55,
44
+ 23.7,
45
+ 23.85,
46
+ 24.0,
47
+ 25.0,
48
+ 26.0,
49
+ 27.000000000000004,
50
+ 28.000000000000004,
51
+ 29.0,
52
+ 29.999999999999996,
53
+ 31.0,
54
+ 32.0,
55
+ 33.0,
56
+ 34.0,
57
+ 35.0,
58
+ 36.0,
59
+ 37.0,
60
+ 38.0,
61
+ 39.0,
62
+ 40.00000000000001,
63
+ 40.99999999999999,
64
+ 42.0,
65
+ 43.0,
66
+ 44.0,
67
+ 44.949999999999996,
68
+ 45.9,
69
+ 46.85000000000001,
70
+ 47.800000000000004,
71
+ 48.75,
72
+ 49.7,
73
+ 50.64999999999999,
74
+ 51.599999999999994,
75
+ 52.55,
76
+ 53.5,
77
+ 54.449999999999996,
78
+ 55.400000000000006,
79
+ 56.349999999999994,
80
+ 57.300000000000004,
81
+ 58.25,
82
+ 59.2,
83
+ 60.150000000000006,
84
+ 61.10000000000001,
85
+ 62.05,
86
+ 63.0,
87
+ 65.64999999999999,
88
+ 68.29999999999998,
89
+ 70.94999999999999,
90
+ 73.60000000000001,
91
+ 76.25,
92
+ 78.89999999999999,
93
+ 81.55000000000001,
94
+ 84.20000000000002,
95
+ 86.85000000000001,
96
+ 89.5,
97
+ 92.15000000000003,
98
+ 94.79999999999998,
99
+ 97.44999999999997,
100
+ 100.10000000000001,
101
+ 102.75,
102
+ 105.39999999999999,
103
+ 108.04999999999998,
104
+ 110.70000000000002,
105
+ 113.35000000000001,
106
+ 116.0,
107
+ 116.0,
108
+ 116.0,
109
+ 116.0,
110
+ 116.0,
111
+ 116.0,
112
+ 116.0,
113
+ 116.0,
114
+ 116.0,
115
+ 116.0,
116
+ 116.0,
117
+ 116.0,
118
+ 116.0,
119
+ 116.0,
120
+ 116.0,
121
+ 116.0,
122
+ 116.0,
123
+ 116.0,
124
+ 116.0,
125
+ 116.0,
126
+ 116.0,
127
+ 116.0
128
+ ],
129
+ "quantile_levels": [
130
+ 0.0,
131
+ 0.0001,
132
+ 0.0005,
133
+ 0.001,
134
+ 0.002,
135
+ 0.003,
136
+ 0.004,
137
+ 0.005,
138
+ 0.006,
139
+ 0.007,
140
+ 0.008,
141
+ 0.009,
142
+ 0.01,
143
+ 0.02,
144
+ 0.03,
145
+ 0.04,
146
+ 0.05,
147
+ 0.06,
148
+ 0.07,
149
+ 0.08,
150
+ 0.09,
151
+ 0.1,
152
+ 0.11,
153
+ 0.12,
154
+ 0.13,
155
+ 0.14,
156
+ 0.15,
157
+ 0.16,
158
+ 0.17,
159
+ 0.18,
160
+ 0.19,
161
+ 0.2,
162
+ 0.21,
163
+ 0.22,
164
+ 0.23,
165
+ 0.24,
166
+ 0.25,
167
+ 0.26,
168
+ 0.27,
169
+ 0.28,
170
+ 0.29,
171
+ 0.3,
172
+ 0.31,
173
+ 0.32,
174
+ 0.33,
175
+ 0.34,
176
+ 0.35,
177
+ 0.36,
178
+ 0.37,
179
+ 0.38,
180
+ 0.39,
181
+ 0.4,
182
+ 0.41,
183
+ 0.42,
184
+ 0.43,
185
+ 0.44,
186
+ 0.45,
187
+ 0.46,
188
+ 0.47,
189
+ 0.48,
190
+ 0.49,
191
+ 0.5,
192
+ 0.51,
193
+ 0.52,
194
+ 0.53,
195
+ 0.54,
196
+ 0.55,
197
+ 0.56,
198
+ 0.57,
199
+ 0.58,
200
+ 0.59,
201
+ 0.6,
202
+ 0.61,
203
+ 0.62,
204
+ 0.63,
205
+ 0.64,
206
+ 0.65,
207
+ 0.66,
208
+ 0.67,
209
+ 0.68,
210
+ 0.69,
211
+ 0.7,
212
+ 0.71,
213
+ 0.72,
214
+ 0.73,
215
+ 0.74,
216
+ 0.75,
217
+ 0.76,
218
+ 0.77,
219
+ 0.78,
220
+ 0.79,
221
+ 0.8,
222
+ 0.81,
223
+ 0.82,
224
+ 0.83,
225
+ 0.84,
226
+ 0.85,
227
+ 0.86,
228
+ 0.87,
229
+ 0.88,
230
+ 0.89,
231
+ 0.9,
232
+ 0.91,
233
+ 0.92,
234
+ 0.93,
235
+ 0.94,
236
+ 0.95,
237
+ 0.96,
238
+ 0.97,
239
+ 0.98,
240
+ 0.99,
241
+ 0.991,
242
+ 0.992,
243
+ 0.993,
244
+ 0.994,
245
+ 0.995,
246
+ 0.996,
247
+ 0.997,
248
+ 0.998,
249
+ 0.999,
250
+ 0.9995,
251
+ 0.9999,
252
+ 1.0
253
+ ]
254
+ },
255
+ "burst_dwell_lengths": [
256
+ 21,
257
+ 24,
258
+ 44,
259
+ 63,
260
+ 116
261
+ ],
262
+ "burst_merge_gap_records": 30,
263
+ "burst_rank_processes": [
264
+ {
265
+ "draw_count": 268,
266
+ "dwell_length_spearman_rho": 0.6,
267
+ "level_ms": {
268
+ "distribution_type": "inverse_cdf",
269
+ "latency_ms": [
270
+ 111.76014185945193,
271
+ 111.76014185945193,
272
+ 111.76014185945193,
273
+ 111.76014185945193,
274
+ 111.76014185945193,
275
+ 111.76014185945193,
276
+ 111.76014185945193,
277
+ 111.76014185945193,
278
+ 111.76014185945193,
279
+ 111.76014185945193,
280
+ 111.76014185945193,
281
+ 111.76014185945193,
282
+ 111.76014185945193,
283
+ 111.76014185945193,
284
+ 111.76014185945193,
285
+ 111.76014185945193,
286
+ 111.76014185945193,
287
+ 111.76014185945193,
288
+ 111.76014185945193,
289
+ 111.76014185945193,
290
+ 111.76014185945193,
291
+ 111.76014185945193,
292
+ 111.76312052955231,
293
+ 111.76609919965267,
294
+ 111.76907786975305,
295
+ 111.77205653985342,
296
+ 111.77503520995378,
297
+ 111.77801388005416,
298
+ 111.78099255015454,
299
+ 111.7839712202549,
300
+ 111.78694989035527,
301
+ 111.78992856045565,
302
+ 111.79290723055601,
303
+ 111.79588590065639,
304
+ 111.79886457075675,
305
+ 111.80184324085712,
306
+ 111.8048219109575,
307
+ 111.80780058105786,
308
+ 111.81077925115824,
309
+ 111.81375792125861,
310
+ 111.81673659135897,
311
+ 111.81971526145935,
312
+ 111.88049919903278,
313
+ 111.94128313660622,
314
+ 112.00206707417965,
315
+ 112.06285101175308,
316
+ 112.12363494932652,
317
+ 112.18441888689995,
318
+ 112.24520282447338,
319
+ 112.30598676204681,
320
+ 112.36677069962025,
321
+ 112.42755463719368,
322
+ 112.48833857476711,
323
+ 112.54912251234055,
324
+ 112.60990644991398,
325
+ 112.67069038748741,
326
+ 112.73147432506084,
327
+ 112.79225826263428,
328
+ 112.85304220020771,
329
+ 112.91382613778114,
330
+ 112.97461007535458,
331
+ 113.03539401292801,
332
+ 113.24575516482194,
333
+ 113.45611631671588,
334
+ 113.66647746860981,
335
+ 113.87683862050375,
336
+ 114.08719977239768,
337
+ 114.29756092429162,
338
+ 114.50792207618555,
339
+ 114.71828322807949,
340
+ 114.9286443799734,
341
+ 115.13900553186735,
342
+ 115.34936668376127,
343
+ 115.55972783565521,
344
+ 115.77008898754914,
345
+ 115.98045013944308,
346
+ 116.19081129133701,
347
+ 116.40117244323095,
348
+ 116.61153359512488,
349
+ 116.82189474701882,
350
+ 117.03225589891275,
351
+ 117.24261705080669,
352
+ 117.25980174541473,
353
+ 117.2769864400228,
354
+ 117.29417113463084,
355
+ 117.31135582923889,
356
+ 117.32854052384695,
357
+ 117.345725218455,
358
+ 117.36290991306305,
359
+ 117.3800946076711,
360
+ 117.39727930227916,
361
+ 117.4144639968872,
362
+ 117.43164869149525,
363
+ 117.44883338610332,
364
+ 117.46601808071136,
365
+ 117.48320277531941,
366
+ 117.50038746992746,
367
+ 117.51757216453552,
368
+ 117.53475685914357,
369
+ 117.55194155375162,
370
+ 117.56912624835968,
371
+ 117.58631094296773,
372
+ 117.58631094296773,
373
+ 117.58631094296773,
374
+ 117.58631094296773,
375
+ 117.58631094296773,
376
+ 117.58631094296773,
377
+ 117.58631094296773,
378
+ 117.58631094296773,
379
+ 117.58631094296773,
380
+ 117.58631094296773,
381
+ 117.58631094296773,
382
+ 117.58631094296773,
383
+ 117.58631094296773,
384
+ 117.58631094296773,
385
+ 117.58631094296773,
386
+ 117.58631094296773,
387
+ 117.58631094296773,
388
+ 117.58631094296773,
389
+ 117.58631094296773,
390
+ 117.58631094296773,
391
+ 117.58631094296773,
392
+ 117.58631094296773
393
+ ],
394
+ "quantile_levels": [
395
+ 0.0,
396
+ 0.0001,
397
+ 0.0005,
398
+ 0.001,
399
+ 0.002,
400
+ 0.003,
401
+ 0.004,
402
+ 0.005,
403
+ 0.006,
404
+ 0.007,
405
+ 0.008,
406
+ 0.009,
407
+ 0.01,
408
+ 0.02,
409
+ 0.03,
410
+ 0.04,
411
+ 0.05,
412
+ 0.06,
413
+ 0.07,
414
+ 0.08,
415
+ 0.09,
416
+ 0.1,
417
+ 0.11,
418
+ 0.12,
419
+ 0.13,
420
+ 0.14,
421
+ 0.15,
422
+ 0.16,
423
+ 0.17,
424
+ 0.18,
425
+ 0.19,
426
+ 0.2,
427
+ 0.21,
428
+ 0.22,
429
+ 0.23,
430
+ 0.24,
431
+ 0.25,
432
+ 0.26,
433
+ 0.27,
434
+ 0.28,
435
+ 0.29,
436
+ 0.3,
437
+ 0.31,
438
+ 0.32,
439
+ 0.33,
440
+ 0.34,
441
+ 0.35,
442
+ 0.36,
443
+ 0.37,
444
+ 0.38,
445
+ 0.39,
446
+ 0.4,
447
+ 0.41,
448
+ 0.42,
449
+ 0.43,
450
+ 0.44,
451
+ 0.45,
452
+ 0.46,
453
+ 0.47,
454
+ 0.48,
455
+ 0.49,
456
+ 0.5,
457
+ 0.51,
458
+ 0.52,
459
+ 0.53,
460
+ 0.54,
461
+ 0.55,
462
+ 0.56,
463
+ 0.57,
464
+ 0.58,
465
+ 0.59,
466
+ 0.6,
467
+ 0.61,
468
+ 0.62,
469
+ 0.63,
470
+ 0.64,
471
+ 0.65,
472
+ 0.66,
473
+ 0.67,
474
+ 0.68,
475
+ 0.69,
476
+ 0.7,
477
+ 0.71,
478
+ 0.72,
479
+ 0.73,
480
+ 0.74,
481
+ 0.75,
482
+ 0.76,
483
+ 0.77,
484
+ 0.78,
485
+ 0.79,
486
+ 0.8,
487
+ 0.81,
488
+ 0.82,
489
+ 0.83,
490
+ 0.84,
491
+ 0.85,
492
+ 0.86,
493
+ 0.87,
494
+ 0.88,
495
+ 0.89,
496
+ 0.9,
497
+ 0.91,
498
+ 0.92,
499
+ 0.93,
500
+ 0.94,
501
+ 0.95,
502
+ 0.96,
503
+ 0.97,
504
+ 0.98,
505
+ 0.99,
506
+ 0.991,
507
+ 0.992,
508
+ 0.993,
509
+ 0.994,
510
+ 0.995,
511
+ 0.996,
512
+ 0.997,
513
+ 0.998,
514
+ 0.999,
515
+ 0.9995,
516
+ 0.9999,
517
+ 1.0
518
+ ]
519
+ },
520
+ "level_residual_ms": {
521
+ "distribution_type": "inverse_cdf",
522
+ "latency_ms": [
523
+ -6.34056695302327,
524
+ -6.34056695302327,
525
+ -6.34056695302327,
526
+ -6.34056695302327,
527
+ -6.34056695302327,
528
+ -6.34056695302327,
529
+ -6.34056695302327,
530
+ -6.34056695302327,
531
+ -6.34056695302327,
532
+ -6.34056695302327,
533
+ -6.34056695302327,
534
+ -6.34056695302327,
535
+ -6.332754473686213,
536
+ -6.12963001092275,
537
+ -5.934426395098373,
538
+ -5.799949272473652,
539
+ -5.680410925547278,
540
+ -5.623615436553957,
541
+ -5.049422933657966,
542
+ -3.070867107311886,
543
+ -1.7738834404945374,
544
+ -1.764313852787018,
545
+ -1.7532525277137756,
546
+ -1.740157015323639,
547
+ -1.6828855347633362,
548
+ -1.5814380860328672,
549
+ -1.4429068446159363,
550
+ -1.2771808218955993,
551
+ -1.16335510969162,
552
+ -1.0770060324668886,
553
+ -0.977082860469818,
554
+ -0.8721587061882018,
555
+ -0.7349506437778474,
556
+ -0.590055936574936,
557
+ -0.5727308547496796,
558
+ -0.5720452892780304,
559
+ -0.5142639031012877,
560
+ -0.45617564717929043,
561
+ -0.4475114683310238,
562
+ -0.4395893094937051,
563
+ -0.4373559707403203,
564
+ -0.4331851969162628,
565
+ -0.42087719579538,
566
+ -0.40994842906793366,
567
+ -0.40276329855124315,
568
+ -0.394058796763421,
569
+ -0.3824843714634611,
570
+ -0.3737770799795834,
571
+ -0.36897951642672694,
572
+ -0.36016353984674165,
573
+ -0.34732915023962757,
574
+ -0.33729381263256214,
575
+ -0.3293111131588657,
576
+ -0.30667495767275965,
577
+ -0.2762810901800839,
578
+ -0.26342058698336757,
579
+ -0.25701974431674157,
580
+ -0.25447803537051356,
581
+ -0.2528551677862851,
582
+ -0.2522101406256405,
583
+ -0.25169265786807216,
584
+ -0.2242364039023741,
585
+ -0.19644585728645325,
586
+ -0.18723676562309266,
587
+ -0.17905045092105895,
588
+ -0.17870542625586466,
589
+ -0.1779036621252743,
590
+ -0.1751835922400204,
591
+ -0.16621431390444927,
592
+ -0.14028289834658797,
593
+ -0.10150121072928503,
594
+ -0.038446786999703955,
595
+ 0.00013522148132323088,
596
+ 0.005345754623413106,
597
+ 0.012373673717179623,
598
+ 0.02121897876262297,
599
+ 0.05395132501919632,
600
+ 0.1042008348305973,
601
+ 0.12717157800991863,
602
+ 0.1357006212075504,
603
+ 0.15964065512020884,
604
+ 0.1892584224541934,
605
+ 0.19996284385521934,
606
+ 0.20616408765315977,
607
+ 0.20962504406769852,
608
+ 0.21272857169309786,
609
+ 0.24325262506802403,
610
+ 0.27453822116056625,
611
+ 0.2974418594439802,
612
+ 0.3181665986776349,
613
+ 0.3221864451964669,
614
+ 0.32762383421261637,
615
+ 0.3390149017174992,
616
+ 0.37237897018591165,
617
+ 0.465384041269618,
618
+ 0.5267693853378296,
619
+ 0.52842857837677,
620
+ 0.5617947413523979,
621
+ 0.6383976815144189,
622
+ 0.6814763828118594,
623
+ 0.6910308452447208,
624
+ 0.7474897046883862,
625
+ 0.8383451219399723,
626
+ 0.9931568259000759,
627
+ 1.1818277404705675,
628
+ 4.4926970267295445,
629
+ 8.953849923610676,
630
+ 10.534285777807236,
631
+ 11.428836621840787,
632
+ 11.76198321501414,
633
+ 12.021903166770938,
634
+ 12.031900087992355,
635
+ 12.031900087992355,
636
+ 12.031900087992355,
637
+ 12.031900087992355,
638
+ 12.031900087992355,
639
+ 12.031900087992355,
640
+ 12.031900087992355,
641
+ 12.031900087992355,
642
+ 12.031900087992355,
643
+ 12.031900087992355,
644
+ 12.031900087992355,
645
+ 12.031900087992355
646
+ ],
647
+ "quantile_levels": [
648
+ 0.0,
649
+ 0.0001,
650
+ 0.0005,
651
+ 0.001,
652
+ 0.002,
653
+ 0.003,
654
+ 0.004,
655
+ 0.005,
656
+ 0.006,
657
+ 0.007,
658
+ 0.008,
659
+ 0.009,
660
+ 0.01,
661
+ 0.02,
662
+ 0.03,
663
+ 0.04,
664
+ 0.05,
665
+ 0.06,
666
+ 0.07,
667
+ 0.08,
668
+ 0.09,
669
+ 0.1,
670
+ 0.11,
671
+ 0.12,
672
+ 0.13,
673
+ 0.14,
674
+ 0.15,
675
+ 0.16,
676
+ 0.17,
677
+ 0.18,
678
+ 0.19,
679
+ 0.2,
680
+ 0.21,
681
+ 0.22,
682
+ 0.23,
683
+ 0.24,
684
+ 0.25,
685
+ 0.26,
686
+ 0.27,
687
+ 0.28,
688
+ 0.29,
689
+ 0.3,
690
+ 0.31,
691
+ 0.32,
692
+ 0.33,
693
+ 0.34,
694
+ 0.35,
695
+ 0.36,
696
+ 0.37,
697
+ 0.38,
698
+ 0.39,
699
+ 0.4,
700
+ 0.41,
701
+ 0.42,
702
+ 0.43,
703
+ 0.44,
704
+ 0.45,
705
+ 0.46,
706
+ 0.47,
707
+ 0.48,
708
+ 0.49,
709
+ 0.5,
710
+ 0.51,
711
+ 0.52,
712
+ 0.53,
713
+ 0.54,
714
+ 0.55,
715
+ 0.56,
716
+ 0.57,
717
+ 0.58,
718
+ 0.59,
719
+ 0.6,
720
+ 0.61,
721
+ 0.62,
722
+ 0.63,
723
+ 0.64,
724
+ 0.65,
725
+ 0.66,
726
+ 0.67,
727
+ 0.68,
728
+ 0.69,
729
+ 0.7,
730
+ 0.71,
731
+ 0.72,
732
+ 0.73,
733
+ 0.74,
734
+ 0.75,
735
+ 0.76,
736
+ 0.77,
737
+ 0.78,
738
+ 0.79,
739
+ 0.8,
740
+ 0.81,
741
+ 0.82,
742
+ 0.83,
743
+ 0.84,
744
+ 0.85,
745
+ 0.86,
746
+ 0.87,
747
+ 0.88,
748
+ 0.89,
749
+ 0.9,
750
+ 0.91,
751
+ 0.92,
752
+ 0.93,
753
+ 0.94,
754
+ 0.95,
755
+ 0.96,
756
+ 0.97,
757
+ 0.98,
758
+ 0.99,
759
+ 0.991,
760
+ 0.992,
761
+ 0.993,
762
+ 0.994,
763
+ 0.995,
764
+ 0.996,
765
+ 0.997,
766
+ 0.998,
767
+ 0.999,
768
+ 0.9995,
769
+ 0.9999,
770
+ 1.0
771
+ ]
772
+ },
773
+ "severity": {
774
+ "distribution_type": "inverse_cdf",
775
+ "latency_ms": [
776
+ 0.125,
777
+ 0.125,
778
+ 0.125,
779
+ 0.125,
780
+ 0.125,
781
+ 0.125,
782
+ 0.125,
783
+ 0.125,
784
+ 0.125,
785
+ 0.125,
786
+ 0.125,
787
+ 0.125,
788
+ 0.125,
789
+ 0.125,
790
+ 0.125,
791
+ 0.125,
792
+ 0.125,
793
+ 0.125,
794
+ 0.125,
795
+ 0.125,
796
+ 0.125,
797
+ 0.125,
798
+ 0.12589285714285714,
799
+ 0.12678571428571428,
800
+ 0.12767857142857142,
801
+ 0.12857142857142856,
802
+ 0.1294642857142857,
803
+ 0.13035714285714287,
804
+ 0.13125,
805
+ 0.13214285714285715,
806
+ 0.13303571428571428,
807
+ 0.13392857142857142,
808
+ 0.13482142857142856,
809
+ 0.1357142857142857,
810
+ 0.13660714285714284,
811
+ 0.13749999999999998,
812
+ 0.13839285714285715,
813
+ 0.1392857142857143,
814
+ 0.14017857142857143,
815
+ 0.14107142857142857,
816
+ 0.1419642857142857,
817
+ 0.14285714285714285,
818
+ 0.14523809523809522,
819
+ 0.14761904761904762,
820
+ 0.15,
821
+ 0.1523809523809524,
822
+ 0.15476190476190477,
823
+ 0.15714285714285714,
824
+ 0.1595238095238095,
825
+ 0.16190476190476188,
826
+ 0.16428571428571428,
827
+ 0.16666666666666666,
828
+ 0.16904761904761903,
829
+ 0.17142857142857143,
830
+ 0.1738095238095238,
831
+ 0.17619047619047618,
832
+ 0.17857142857142855,
833
+ 0.18095238095238095,
834
+ 0.1833333333333333,
835
+ 0.1857142857142857,
836
+ 0.1880952380952381,
837
+ 0.19047619047619047,
838
+ 0.19129720853858784,
839
+ 0.1921182266009852,
840
+ 0.19293924466338258,
841
+ 0.19376026272577995,
842
+ 0.19458128078817732,
843
+ 0.1954022988505747,
844
+ 0.19622331691297207,
845
+ 0.19704433497536944,
846
+ 0.1978653530377668,
847
+ 0.19868637110016418,
848
+ 0.19950738916256155,
849
+ 0.20032840722495895,
850
+ 0.20114942528735633,
851
+ 0.2019704433497537,
852
+ 0.20279146141215107,
853
+ 0.20361247947454844,
854
+ 0.2044334975369458,
855
+ 0.20525451559934318,
856
+ 0.20607553366174056,
857
+ 0.20689655172413793,
858
+ 0.2079153605015674,
859
+ 0.20893416927899686,
860
+ 0.20995297805642632,
861
+ 0.2109717868338558,
862
+ 0.21199059561128525,
863
+ 0.2130094043887147,
864
+ 0.2140282131661442,
865
+ 0.21504702194357367,
866
+ 0.21606583072100313,
867
+ 0.2170846394984326,
868
+ 0.2181034482758621,
869
+ 0.21912225705329152,
870
+ 0.220141065830721,
871
+ 0.22115987460815045,
872
+ 0.22217868338557994,
873
+ 0.22319749216300938,
874
+ 0.22421630094043887,
875
+ 0.22523510971786834,
876
+ 0.2262539184952978,
877
+ 0.22727272727272727,
878
+ 0.22727272727272727,
879
+ 0.22727272727272727,
880
+ 0.22727272727272727,
881
+ 0.22727272727272727,
882
+ 0.22727272727272727,
883
+ 0.22727272727272727,
884
+ 0.22727272727272727,
885
+ 0.22727272727272727,
886
+ 0.22727272727272727,
887
+ 0.22727272727272727,
888
+ 0.22727272727272727,
889
+ 0.22727272727272727,
890
+ 0.22727272727272727,
891
+ 0.22727272727272727,
892
+ 0.22727272727272727,
893
+ 0.22727272727272727,
894
+ 0.22727272727272727,
895
+ 0.22727272727272727,
896
+ 0.22727272727272727,
897
+ 0.22727272727272727,
898
+ 0.22727272727272727
899
+ ],
900
+ "quantile_levels": [
901
+ 0.0,
902
+ 0.0001,
903
+ 0.0005,
904
+ 0.001,
905
+ 0.002,
906
+ 0.003,
907
+ 0.004,
908
+ 0.005,
909
+ 0.006,
910
+ 0.007,
911
+ 0.008,
912
+ 0.009,
913
+ 0.01,
914
+ 0.02,
915
+ 0.03,
916
+ 0.04,
917
+ 0.05,
918
+ 0.06,
919
+ 0.07,
920
+ 0.08,
921
+ 0.09,
922
+ 0.1,
923
+ 0.11,
924
+ 0.12,
925
+ 0.13,
926
+ 0.14,
927
+ 0.15,
928
+ 0.16,
929
+ 0.17,
930
+ 0.18,
931
+ 0.19,
932
+ 0.2,
933
+ 0.21,
934
+ 0.22,
935
+ 0.23,
936
+ 0.24,
937
+ 0.25,
938
+ 0.26,
939
+ 0.27,
940
+ 0.28,
941
+ 0.29,
942
+ 0.3,
943
+ 0.31,
944
+ 0.32,
945
+ 0.33,
946
+ 0.34,
947
+ 0.35,
948
+ 0.36,
949
+ 0.37,
950
+ 0.38,
951
+ 0.39,
952
+ 0.4,
953
+ 0.41,
954
+ 0.42,
955
+ 0.43,
956
+ 0.44,
957
+ 0.45,
958
+ 0.46,
959
+ 0.47,
960
+ 0.48,
961
+ 0.49,
962
+ 0.5,
963
+ 0.51,
964
+ 0.52,
965
+ 0.53,
966
+ 0.54,
967
+ 0.55,
968
+ 0.56,
969
+ 0.57,
970
+ 0.58,
971
+ 0.59,
972
+ 0.6,
973
+ 0.61,
974
+ 0.62,
975
+ 0.63,
976
+ 0.64,
977
+ 0.65,
978
+ 0.66,
979
+ 0.67,
980
+ 0.68,
981
+ 0.69,
982
+ 0.7,
983
+ 0.71,
984
+ 0.72,
985
+ 0.73,
986
+ 0.74,
987
+ 0.75,
988
+ 0.76,
989
+ 0.77,
990
+ 0.78,
991
+ 0.79,
992
+ 0.8,
993
+ 0.81,
994
+ 0.82,
995
+ 0.83,
996
+ 0.84,
997
+ 0.85,
998
+ 0.86,
999
+ 0.87,
1000
+ 0.88,
1001
+ 0.89,
1002
+ 0.9,
1003
+ 0.91,
1004
+ 0.92,
1005
+ 0.93,
1006
+ 0.94,
1007
+ 0.95,
1008
+ 0.96,
1009
+ 0.97,
1010
+ 0.98,
1011
+ 0.99,
1012
+ 0.991,
1013
+ 0.992,
1014
+ 0.993,
1015
+ 0.994,
1016
+ 0.995,
1017
+ 0.996,
1018
+ 0.997,
1019
+ 0.998,
1020
+ 0.999,
1021
+ 0.9995,
1022
+ 0.9999,
1023
+ 1.0
1024
+ ]
1025
+ },
1026
+ "spike_count": 52
1027
+ }
1028
+ ],
1029
+ "burst_slot_rank_templates": [
1030
+ {
1031
+ "dwell_length": 116,
1032
+ "slot_to_rank": {
1033
+ "0": 0
1034
+ }
1035
+ },
1036
+ {
1037
+ "dwell_length": 44,
1038
+ "slot_to_rank": {
1039
+ "0": 0
1040
+ }
1041
+ },
1042
+ {
1043
+ "dwell_length": 63,
1044
+ "slot_to_rank": {
1045
+ "0": 0
1046
+ }
1047
+ },
1048
+ {
1049
+ "dwell_length": 21,
1050
+ "slot_to_rank": {
1051
+ "0": 0
1052
+ }
1053
+ },
1054
+ {
1055
+ "dwell_length": 24,
1056
+ "slot_to_rank": {
1057
+ "0": 0
1058
+ }
1059
+ }
1060
+ ],
1061
+ "model_type": "hidden_regime",
1062
+ "pre_worker_time_ms": {
1063
+ "distribution_type": "inverse_cdf",
1064
+ "latency_ms": [
1065
+ 0.2572758197784424,
1066
+ 0.25763754005432127,
1067
+ 0.25947027969360353,
1068
+ 0.2603460645675659,
1069
+ 0.2612747564315796,
1070
+ 0.2622022571563721,
1071
+ 0.26243807792663576,
1072
+ 0.2626762580871582,
1073
+ 0.2632839403152466,
1074
+ 0.26363272762298584,
1075
+ 0.2637669315338135,
1076
+ 0.26404299354553223,
1077
+ 0.2643587684631348,
1078
+ 0.2657140350341797,
1079
+ 0.26658174514770505,
1080
+ 0.26738574981689456,
1081
+ 0.2681525468826294,
1082
+ 0.26886218070983886,
1083
+ 0.26952486515045165,
1084
+ 0.27005916118621826,
1085
+ 0.2706614589691162,
1086
+ 0.2714514255523682,
1087
+ 0.27218435287475584,
1088
+ 0.27285959720611574,
1089
+ 0.27350028038024904,
1090
+ 0.2743678092956543,
1091
+ 0.2750845909118652,
1092
+ 0.2760720920562744,
1093
+ 0.2770882177352905,
1094
+ 0.27842949867248534,
1095
+ 0.27990328788757324,
1096
+ 0.28201286792755126,
1097
+ 0.28431395053863523,
1098
+ 0.28664437294006345,
1099
+ 0.28922285556793215,
1100
+ 0.29165172576904297,
1101
+ 0.29378581047058105,
1102
+ 0.2955480146408081,
1103
+ 0.2971444034576416,
1104
+ 0.29853535175323487,
1105
+ 0.2998380756378174,
1106
+ 0.3010571956634521,
1107
+ 0.3020807981491089,
1108
+ 0.30305158138275146,
1109
+ 0.3037783861160278,
1110
+ 0.3045779085159302,
1111
+ 0.3050941705703735,
1112
+ 0.3056695747375488,
1113
+ 0.30616676330566406,
1114
+ 0.3065678071975708,
1115
+ 0.30704905033111574,
1116
+ 0.3073734760284424,
1117
+ 0.3076727342605591,
1118
+ 0.30795797348022463,
1119
+ 0.308273024559021,
1120
+ 0.3085658121109009,
1121
+ 0.308845591545105,
1122
+ 0.3091064405441284,
1123
+ 0.30933346748352053,
1124
+ 0.30958592891693115,
1125
+ 0.3098057985305786,
1126
+ 0.3100399971008301,
1127
+ 0.3102893924713135,
1128
+ 0.31050017833709714,
1129
+ 0.3107223749160767,
1130
+ 0.31094244956970213,
1131
+ 0.3111721992492676,
1132
+ 0.31139523029327393,
1133
+ 0.31161237239837647,
1134
+ 0.31180827140808104,
1135
+ 0.3120582962036133,
1136
+ 0.31228928565979003,
1137
+ 0.31247793197631835,
1138
+ 0.31274282455444335,
1139
+ 0.3129736089706421,
1140
+ 0.3132426595687866,
1141
+ 0.3134938716888428,
1142
+ 0.31373076915740966,
1143
+ 0.31396267890930174,
1144
+ 0.31422226905822753,
1145
+ 0.31449563026428223,
1146
+ 0.3147676229476929,
1147
+ 0.3149920606613159,
1148
+ 0.3153657913208008,
1149
+ 0.31567907333374023,
1150
+ 0.3159314775466919,
1151
+ 0.31631767749786377,
1152
+ 0.31666929721832277,
1153
+ 0.3170040273666382,
1154
+ 0.3174827384948731,
1155
+ 0.31792099952697755,
1156
+ 0.31836187839508057,
1157
+ 0.31882681846618655,
1158
+ 0.31948143005371094,
1159
+ 0.3199909162521362,
1160
+ 0.3205808925628662,
1161
+ 0.3213667631149292,
1162
+ 0.3224719858169556,
1163
+ 0.3236453628540039,
1164
+ 0.3248334980010986,
1165
+ 0.32641579151153566,
1166
+ 0.3288518667221069,
1167
+ 0.3317467498779297,
1168
+ 0.3364091396331787,
1169
+ 0.34346031188964843,
1170
+ 0.35033455848693845,
1171
+ 0.3815898180007932,
1172
+ 0.6752684497833252,
1173
+ 1.2073634576797472,
1174
+ 1.278598713874817,
1175
+ 1.302369451522827,
1176
+ 1.3093395385742188,
1177
+ 1.3129376239776611,
1178
+ 1.3175906381607052,
1179
+ 1.3359725713729873,
1180
+ 1.3516274499893188,
1181
+ 1.3746464385986326,
1182
+ 1.3949562454223634,
1183
+ 1.4172659616470336,
1184
+ 1.4342637987136844,
1185
+ 1.4602041645050134,
1186
+ 1.4875035186767591,
1187
+ 1.49049711227417
1188
+ ],
1189
+ "quantile_levels": [
1190
+ 0.0,
1191
+ 0.0001,
1192
+ 0.0005,
1193
+ 0.001,
1194
+ 0.002,
1195
+ 0.003,
1196
+ 0.004,
1197
+ 0.005,
1198
+ 0.006,
1199
+ 0.007,
1200
+ 0.008,
1201
+ 0.009,
1202
+ 0.01,
1203
+ 0.02,
1204
+ 0.03,
1205
+ 0.04,
1206
+ 0.05,
1207
+ 0.06,
1208
+ 0.07,
1209
+ 0.08,
1210
+ 0.09,
1211
+ 0.1,
1212
+ 0.11,
1213
+ 0.12,
1214
+ 0.13,
1215
+ 0.14,
1216
+ 0.15,
1217
+ 0.16,
1218
+ 0.17,
1219
+ 0.18,
1220
+ 0.19,
1221
+ 0.2,
1222
+ 0.21,
1223
+ 0.22,
1224
+ 0.23,
1225
+ 0.24,
1226
+ 0.25,
1227
+ 0.26,
1228
+ 0.27,
1229
+ 0.28,
1230
+ 0.29,
1231
+ 0.3,
1232
+ 0.31,
1233
+ 0.32,
1234
+ 0.33,
1235
+ 0.34,
1236
+ 0.35,
1237
+ 0.36,
1238
+ 0.37,
1239
+ 0.38,
1240
+ 0.39,
1241
+ 0.4,
1242
+ 0.41,
1243
+ 0.42,
1244
+ 0.43,
1245
+ 0.44,
1246
+ 0.45,
1247
+ 0.46,
1248
+ 0.47,
1249
+ 0.48,
1250
+ 0.49,
1251
+ 0.5,
1252
+ 0.51,
1253
+ 0.52,
1254
+ 0.53,
1255
+ 0.54,
1256
+ 0.55,
1257
+ 0.56,
1258
+ 0.57,
1259
+ 0.58,
1260
+ 0.59,
1261
+ 0.6,
1262
+ 0.61,
1263
+ 0.62,
1264
+ 0.63,
1265
+ 0.64,
1266
+ 0.65,
1267
+ 0.66,
1268
+ 0.67,
1269
+ 0.68,
1270
+ 0.69,
1271
+ 0.7,
1272
+ 0.71,
1273
+ 0.72,
1274
+ 0.73,
1275
+ 0.74,
1276
+ 0.75,
1277
+ 0.76,
1278
+ 0.77,
1279
+ 0.78,
1280
+ 0.79,
1281
+ 0.8,
1282
+ 0.81,
1283
+ 0.82,
1284
+ 0.83,
1285
+ 0.84,
1286
+ 0.85,
1287
+ 0.86,
1288
+ 0.87,
1289
+ 0.88,
1290
+ 0.89,
1291
+ 0.9,
1292
+ 0.91,
1293
+ 0.92,
1294
+ 0.93,
1295
+ 0.94,
1296
+ 0.95,
1297
+ 0.96,
1298
+ 0.97,
1299
+ 0.98,
1300
+ 0.99,
1301
+ 0.991,
1302
+ 0.992,
1303
+ 0.993,
1304
+ 0.994,
1305
+ 0.995,
1306
+ 0.996,
1307
+ 0.997,
1308
+ 0.998,
1309
+ 0.999,
1310
+ 0.9995,
1311
+ 0.9999,
1312
+ 1.0
1313
+ ]
1314
+ },
1315
+ "regime_step_counts": {
1316
+ "burst": 268,
1317
+ "calm": 7708
1318
+ },
1319
+ "regime_transition_counts": {
1320
+ "burst": {
1321
+ "burst": 263,
1322
+ "calm": 5
1323
+ },
1324
+ "calm": {
1325
+ "burst": 5,
1326
+ "calm": 7698
1327
+ }
1328
+ },
1329
+ "reset_scope": "session",
1330
+ "schema_version": 12,
1331
+ "spike_median_multiplier": 1.25,
1332
+ "spike_threshold_ms_by_worker_slot": {
1333
+ "0": 111.23815685510635
1334
+ },
1335
+ "worker_count": 1
1336
+ }
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/profile/latency_distribution.json ADDED
@@ -0,0 +1,1027 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "schema_version": 3,
3
+ "worker_slots": {
4
+ "0": {
5
+ "all": {
6
+ "count": 7976,
7
+ "observation_to_action_latency_ms": {
8
+ "distribution_type": "inverse_cdf",
9
+ "latency_ms": [
10
+ 87.98952293395996,
11
+ 88.00625395126343,
12
+ 88.19498282814025,
13
+ 88.31266105270386,
14
+ 88.42687071514129,
15
+ 88.47465879440307,
16
+ 88.50693488693237,
17
+ 88.53092688083649,
18
+ 88.54779446983338,
19
+ 88.55876398563385,
20
+ 88.56488679409027,
21
+ 88.57280330657959,
22
+ 88.59264374256134,
23
+ 88.67249797344208,
24
+ 88.724377617836,
25
+ 88.79207693576812,
26
+ 88.84999904632568,
27
+ 88.89409097194671,
28
+ 88.92342544078826,
29
+ 88.96823967933655,
30
+ 88.99946705818176,
31
+ 89.02508285045624,
32
+ 89.04901226520538,
33
+ 89.07655789375305,
34
+ 89.10013774871827,
35
+ 89.13031135559082,
36
+ 89.15370976924896,
37
+ 89.17447654724121,
38
+ 89.19607995033265,
39
+ 89.21466581344605,
40
+ 89.23746184825897,
41
+ 89.25717034339905,
42
+ 89.2771969127655,
43
+ 89.29832275390625,
44
+ 89.31721762657166,
45
+ 89.33869683265686,
46
+ 89.35448241233826,
47
+ 89.37088777542114,
48
+ 89.387730717659,
49
+ 89.40454774379731,
50
+ 89.42069890975952,
51
+ 89.43555467128753,
52
+ 89.45022724151612,
53
+ 89.46291656017303,
54
+ 89.47820586681365,
55
+ 89.49225774765014,
56
+ 89.50589845180511,
57
+ 89.52021051883698,
58
+ 89.53634333610535,
59
+ 89.5502944946289,
60
+ 89.56533065795898,
61
+ 89.57548904418945,
62
+ 89.58862001419067,
63
+ 89.59958215236664,
64
+ 89.6106701040268,
65
+ 89.6255473279953,
66
+ 89.63833825588226,
67
+ 89.65307829856873,
68
+ 89.66765783309937,
69
+ 89.68132509231567,
70
+ 89.69334455490112,
71
+ 89.70676946640015,
72
+ 89.72026408195495,
73
+ 89.73473812103272,
74
+ 89.74919620037079,
75
+ 89.76378743171692,
76
+ 89.77904286384583,
77
+ 89.79202803611756,
78
+ 89.80719444274902,
79
+ 89.82152740478516,
80
+ 89.83681576728821,
81
+ 89.85403666496276,
82
+ 89.87273532867431,
83
+ 89.88893761634827,
84
+ 89.91062943458557,
85
+ 89.92647359848023,
86
+ 89.94606273174286,
87
+ 89.96231405735016,
88
+ 89.97694365501404,
89
+ 89.99286030292511,
90
+ 90.0110937833786,
91
+ 90.02730028629303,
92
+ 90.04637926101685,
93
+ 90.06258551597595,
94
+ 90.07847352981567,
95
+ 90.09652791976929,
96
+ 90.11794292926788,
97
+ 90.13743216991425,
98
+ 90.15522152900697,
99
+ 90.18199282169343,
100
+ 90.20373028278351,
101
+ 90.2253544807434,
102
+ 90.25468337535858,
103
+ 90.28829836368561,
104
+ 90.32118947029113,
105
+ 90.35554928779602,
106
+ 90.3950603723526,
107
+ 90.44660758495331,
108
+ 90.51204998970032,
109
+ 90.56736985683442,
110
+ 90.64274927139282,
111
+ 90.74715027809142,
112
+ 90.87436978340149,
113
+ 91.05810060977936,
114
+ 91.26494856357574,
115
+ 91.56088218212128,
116
+ 92.13188321590424,
117
+ 93.51960658550263,
118
+ 110.3865959215164,
119
+ 111.56080113887786,
120
+ 112.18723976135253,
121
+ 112.27797777271272,
122
+ 112.3118753566742,
123
+ 112.38298761463165,
124
+ 112.55841102600098,
125
+ 112.6685480260849,
126
+ 112.81127831363678,
127
+ 113.11438784122467,
128
+ 113.30635335445405,
129
+ 113.64114878845216,
130
+ 114.79401259803862,
131
+ 130.04163708992016,
132
+ 130.29119229316711
133
+ ],
134
+ "quantile_levels": [
135
+ 0.0,
136
+ 0.0001,
137
+ 0.0005,
138
+ 0.001,
139
+ 0.002,
140
+ 0.003,
141
+ 0.004,
142
+ 0.005,
143
+ 0.006,
144
+ 0.007,
145
+ 0.008,
146
+ 0.009,
147
+ 0.01,
148
+ 0.02,
149
+ 0.03,
150
+ 0.04,
151
+ 0.05,
152
+ 0.06,
153
+ 0.07,
154
+ 0.08,
155
+ 0.09,
156
+ 0.1,
157
+ 0.11,
158
+ 0.12,
159
+ 0.13,
160
+ 0.14,
161
+ 0.15,
162
+ 0.16,
163
+ 0.17,
164
+ 0.18,
165
+ 0.19,
166
+ 0.2,
167
+ 0.21,
168
+ 0.22,
169
+ 0.23,
170
+ 0.24,
171
+ 0.25,
172
+ 0.26,
173
+ 0.27,
174
+ 0.28,
175
+ 0.29,
176
+ 0.3,
177
+ 0.31,
178
+ 0.32,
179
+ 0.33,
180
+ 0.34,
181
+ 0.35,
182
+ 0.36,
183
+ 0.37,
184
+ 0.38,
185
+ 0.39,
186
+ 0.4,
187
+ 0.41,
188
+ 0.42,
189
+ 0.43,
190
+ 0.44,
191
+ 0.45,
192
+ 0.46,
193
+ 0.47,
194
+ 0.48,
195
+ 0.49,
196
+ 0.5,
197
+ 0.51,
198
+ 0.52,
199
+ 0.53,
200
+ 0.54,
201
+ 0.55,
202
+ 0.56,
203
+ 0.57,
204
+ 0.58,
205
+ 0.59,
206
+ 0.6,
207
+ 0.61,
208
+ 0.62,
209
+ 0.63,
210
+ 0.64,
211
+ 0.65,
212
+ 0.66,
213
+ 0.67,
214
+ 0.68,
215
+ 0.69,
216
+ 0.7,
217
+ 0.71,
218
+ 0.72,
219
+ 0.73,
220
+ 0.74,
221
+ 0.75,
222
+ 0.76,
223
+ 0.77,
224
+ 0.78,
225
+ 0.79,
226
+ 0.8,
227
+ 0.81,
228
+ 0.82,
229
+ 0.83,
230
+ 0.84,
231
+ 0.85,
232
+ 0.86,
233
+ 0.87,
234
+ 0.88,
235
+ 0.89,
236
+ 0.9,
237
+ 0.91,
238
+ 0.92,
239
+ 0.93,
240
+ 0.94,
241
+ 0.95,
242
+ 0.96,
243
+ 0.97,
244
+ 0.98,
245
+ 0.99,
246
+ 0.991,
247
+ 0.992,
248
+ 0.993,
249
+ 0.994,
250
+ 0.995,
251
+ 0.996,
252
+ 0.997,
253
+ 0.998,
254
+ 0.999,
255
+ 0.9995,
256
+ 0.9999,
257
+ 1.0
258
+ ]
259
+ },
260
+ "spearman_rho": 0.999288082060808,
261
+ "worker_service_time_ms": {
262
+ "distribution_type": "inverse_cdf",
263
+ "latency_ms": [
264
+ 87.72087597846985,
265
+ 87.72505484809875,
266
+ 87.91075664138793,
267
+ 88.00112848186492,
268
+ 88.12835392475128,
269
+ 88.16585436820984,
270
+ 88.20216335296631,
271
+ 88.22228655815124,
272
+ 88.23629946613312,
273
+ 88.25117263317108,
274
+ 88.26306705760956,
275
+ 88.27515149116516,
276
+ 88.29007994651795,
277
+ 88.37461434841155,
278
+ 88.42467656612396,
279
+ 88.48697556972503,
280
+ 88.54574456214905,
281
+ 88.59064786434173,
282
+ 88.6260237455368,
283
+ 88.66484241485595,
284
+ 88.69925922870635,
285
+ 88.72065505981445,
286
+ 88.74581295013428,
287
+ 88.77460636615753,
288
+ 88.80257711410522,
289
+ 88.82836333751679,
290
+ 88.85065879821778,
291
+ 88.86961028575897,
292
+ 88.89002092838287,
293
+ 88.91101721286773,
294
+ 88.93179827690125,
295
+ 88.95344092845917,
296
+ 88.97252882957459,
297
+ 88.99404806137085,
298
+ 89.01403583049775,
299
+ 89.03331364154816,
300
+ 89.05015802383423,
301
+ 89.06947086334229,
302
+ 89.08563427448273,
303
+ 89.10351252555847,
304
+ 89.11768238544464,
305
+ 89.13144860267639,
306
+ 89.14576484203339,
307
+ 89.1602001285553,
308
+ 89.1763215970993,
309
+ 89.19063215255737,
310
+ 89.20418736934661,
311
+ 89.2187579345703,
312
+ 89.23084268569946,
313
+ 89.2456736755371,
314
+ 89.26038558959961,
315
+ 89.27289342880249,
316
+ 89.28322927474976,
317
+ 89.29450441837311,
318
+ 89.30719062805176,
319
+ 89.32086008548737,
320
+ 89.33541519641877,
321
+ 89.35248424530029,
322
+ 89.36700273036956,
323
+ 89.37777100563049,
324
+ 89.39082574367524,
325
+ 89.40557551383972,
326
+ 89.41941950321197,
327
+ 89.43248313426972,
328
+ 89.4482385969162,
329
+ 89.46083876609802,
330
+ 89.47424108982086,
331
+ 89.48949390888214,
332
+ 89.50253468036652,
333
+ 89.51752857208253,
334
+ 89.53237959384919,
335
+ 89.5501193523407,
336
+ 89.56644603252411,
337
+ 89.58779298782349,
338
+ 89.6055972623825,
339
+ 89.61994940757751,
340
+ 89.63657371997833,
341
+ 89.65447835445404,
342
+ 89.6701370716095,
343
+ 89.6889020872116,
344
+ 89.70479391098023,
345
+ 89.72396631240845,
346
+ 89.74089723587036,
347
+ 89.75628419399261,
348
+ 89.775436668396,
349
+ 89.79404658794402,
350
+ 89.81355702877045,
351
+ 89.832233710289,
352
+ 89.8513820886612,
353
+ 89.87316411018372,
354
+ 89.8954009437561,
355
+ 89.91825423240661,
356
+ 89.95083716869354,
357
+ 89.98068819999695,
358
+ 90.01347800254821,
359
+ 90.04942324638367,
360
+ 90.09265229701995,
361
+ 90.14444270133973,
362
+ 90.20294900894164,
363
+ 90.25911507606506,
364
+ 90.33128764629365,
365
+ 90.43725185394287,
366
+ 90.5703069114685,
367
+ 90.7431587934494,
368
+ 90.93199528217316,
369
+ 91.24273622989654,
370
+ 91.76115915775299,
371
+ 92.93062980651855,
372
+ 109.06819209098813,
373
+ 110.25691298007965,
374
+ 110.92635715007782,
375
+ 110.98662494850159,
376
+ 111.02695600032807,
377
+ 111.1557109861374,
378
+ 111.28695208072662,
379
+ 111.41097618579865,
380
+ 111.5848327255249,
381
+ 111.8585945930481,
382
+ 112.06217238235473,
383
+ 112.4594908771515,
384
+ 113.57045895004362,
385
+ 129.3671735408784,
386
+ 129.61821103096008
387
+ ],
388
+ "quantile_levels": [
389
+ 0.0,
390
+ 0.0001,
391
+ 0.0005,
392
+ 0.001,
393
+ 0.002,
394
+ 0.003,
395
+ 0.004,
396
+ 0.005,
397
+ 0.006,
398
+ 0.007,
399
+ 0.008,
400
+ 0.009,
401
+ 0.01,
402
+ 0.02,
403
+ 0.03,
404
+ 0.04,
405
+ 0.05,
406
+ 0.06,
407
+ 0.07,
408
+ 0.08,
409
+ 0.09,
410
+ 0.1,
411
+ 0.11,
412
+ 0.12,
413
+ 0.13,
414
+ 0.14,
415
+ 0.15,
416
+ 0.16,
417
+ 0.17,
418
+ 0.18,
419
+ 0.19,
420
+ 0.2,
421
+ 0.21,
422
+ 0.22,
423
+ 0.23,
424
+ 0.24,
425
+ 0.25,
426
+ 0.26,
427
+ 0.27,
428
+ 0.28,
429
+ 0.29,
430
+ 0.3,
431
+ 0.31,
432
+ 0.32,
433
+ 0.33,
434
+ 0.34,
435
+ 0.35,
436
+ 0.36,
437
+ 0.37,
438
+ 0.38,
439
+ 0.39,
440
+ 0.4,
441
+ 0.41,
442
+ 0.42,
443
+ 0.43,
444
+ 0.44,
445
+ 0.45,
446
+ 0.46,
447
+ 0.47,
448
+ 0.48,
449
+ 0.49,
450
+ 0.5,
451
+ 0.51,
452
+ 0.52,
453
+ 0.53,
454
+ 0.54,
455
+ 0.55,
456
+ 0.56,
457
+ 0.57,
458
+ 0.58,
459
+ 0.59,
460
+ 0.6,
461
+ 0.61,
462
+ 0.62,
463
+ 0.63,
464
+ 0.64,
465
+ 0.65,
466
+ 0.66,
467
+ 0.67,
468
+ 0.68,
469
+ 0.69,
470
+ 0.7,
471
+ 0.71,
472
+ 0.72,
473
+ 0.73,
474
+ 0.74,
475
+ 0.75,
476
+ 0.76,
477
+ 0.77,
478
+ 0.78,
479
+ 0.79,
480
+ 0.8,
481
+ 0.81,
482
+ 0.82,
483
+ 0.83,
484
+ 0.84,
485
+ 0.85,
486
+ 0.86,
487
+ 0.87,
488
+ 0.88,
489
+ 0.89,
490
+ 0.9,
491
+ 0.91,
492
+ 0.92,
493
+ 0.93,
494
+ 0.94,
495
+ 0.95,
496
+ 0.96,
497
+ 0.97,
498
+ 0.98,
499
+ 0.99,
500
+ 0.991,
501
+ 0.992,
502
+ 0.993,
503
+ 0.994,
504
+ 0.995,
505
+ 0.996,
506
+ 0.997,
507
+ 0.998,
508
+ 0.999,
509
+ 0.9995,
510
+ 0.9999,
511
+ 1.0
512
+ ]
513
+ }
514
+ },
515
+ "steady": {
516
+ "count": 7708,
517
+ "observation_to_action_latency_ms": {
518
+ "distribution_type": "inverse_cdf",
519
+ "latency_ms": [
520
+ 87.98952293395996,
521
+ 88.00474726018906,
522
+ 88.19305597496033,
523
+ 88.31169596481324,
524
+ 88.42505750274658,
525
+ 88.47302298545837,
526
+ 88.50544290447235,
527
+ 88.52511432647705,
528
+ 88.54508119392395,
529
+ 88.55763299179077,
530
+ 88.56368862724304,
531
+ 88.57163988304139,
532
+ 88.58391930580139,
533
+ 88.6713106393814,
534
+ 88.71694125175476,
535
+ 88.78470235347748,
536
+ 88.84136619567872,
537
+ 88.88592077732086,
538
+ 88.91770453929901,
539
+ 88.95671053886413,
540
+ 88.99107503414155,
541
+ 89.01632058620453,
542
+ 89.04142089366913,
543
+ 89.06427590847015,
544
+ 89.09112273216248,
545
+ 89.1197328710556,
546
+ 89.14090068340302,
547
+ 89.16389953613282,
548
+ 89.18336018562317,
549
+ 89.20432123661041,
550
+ 89.22178001880646,
551
+ 89.24455571174622,
552
+ 89.26285143375397,
553
+ 89.28278621196746,
554
+ 89.30259282112121,
555
+ 89.32047615528107,
556
+ 89.34048044681549,
557
+ 89.35656083106994,
558
+ 89.37347135066986,
559
+ 89.3890373134613,
560
+ 89.40507507801055,
561
+ 89.4206326007843,
562
+ 89.43527732372284,
563
+ 89.44985229969025,
564
+ 89.4615450334549,
565
+ 89.47571161746978,
566
+ 89.49060957431793,
567
+ 89.50358631610871,
568
+ 89.51721787452698,
569
+ 89.53188828468323,
570
+ 89.54624356746673,
571
+ 89.55934813022614,
572
+ 89.57238875865936,
573
+ 89.58399452209473,
574
+ 89.5950669336319,
575
+ 89.60552267551422,
576
+ 89.61853682994843,
577
+ 89.63070479393005,
578
+ 89.64368647098541,
579
+ 89.66024139881134,
580
+ 89.67300935745239,
581
+ 89.68450391292572,
582
+ 89.69663897037506,
583
+ 89.70963977336883,
584
+ 89.72322317123412,
585
+ 89.73775261878967,
586
+ 89.75136733055115,
587
+ 89.76614410877228,
588
+ 89.78024483203887,
589
+ 89.79339708805084,
590
+ 89.807336602211,
591
+ 89.82134807109833,
592
+ 89.8357172679901,
593
+ 89.85296149253845,
594
+ 89.8696624326706,
595
+ 89.8862680053711,
596
+ 89.9060546875,
597
+ 89.92375180721282,
598
+ 89.939760055542,
599
+ 89.95744044303893,
600
+ 89.97084111213684,
601
+ 89.98641595840454,
602
+ 90.00528963565826,
603
+ 90.02034323692322,
604
+ 90.03935966014862,
605
+ 90.05414157390595,
606
+ 90.07118356227875,
607
+ 90.08569293022155,
608
+ 90.10546464443206,
609
+ 90.1239938879013,
610
+ 90.14333739280701,
611
+ 90.16480300426483,
612
+ 90.18858228206635,
613
+ 90.20850865364075,
614
+ 90.23085282325745,
615
+ 90.26068212985993,
616
+ 90.29339134693146,
617
+ 90.32349193572998,
618
+ 90.35763807296753,
619
+ 90.39734611034393,
620
+ 90.44722507953644,
621
+ 90.51184470653534,
622
+ 90.56559889316559,
623
+ 90.64097036838531,
624
+ 90.73639919757844,
625
+ 90.85822832584381,
626
+ 91.0151937007904,
627
+ 91.20243098735808,
628
+ 91.45049385070801,
629
+ 91.88321811676025,
630
+ 92.989627699852,
631
+ 93.15146862792969,
632
+ 93.30333351707459,
633
+ 93.47491034889221,
634
+ 93.5772506389618,
635
+ 93.86473531723023,
636
+ 95.11389953041056,
637
+ 108.71966855239876,
638
+ 110.97717627239227,
639
+ 111.38316594314577,
640
+ 111.66655566310887,
641
+ 112.25149490270606,
642
+ 112.35095000267029
643
+ ],
644
+ "quantile_levels": [
645
+ 0.0,
646
+ 0.0001,
647
+ 0.0005,
648
+ 0.001,
649
+ 0.002,
650
+ 0.003,
651
+ 0.004,
652
+ 0.005,
653
+ 0.006,
654
+ 0.007,
655
+ 0.008,
656
+ 0.009,
657
+ 0.01,
658
+ 0.02,
659
+ 0.03,
660
+ 0.04,
661
+ 0.05,
662
+ 0.06,
663
+ 0.07,
664
+ 0.08,
665
+ 0.09,
666
+ 0.1,
667
+ 0.11,
668
+ 0.12,
669
+ 0.13,
670
+ 0.14,
671
+ 0.15,
672
+ 0.16,
673
+ 0.17,
674
+ 0.18,
675
+ 0.19,
676
+ 0.2,
677
+ 0.21,
678
+ 0.22,
679
+ 0.23,
680
+ 0.24,
681
+ 0.25,
682
+ 0.26,
683
+ 0.27,
684
+ 0.28,
685
+ 0.29,
686
+ 0.3,
687
+ 0.31,
688
+ 0.32,
689
+ 0.33,
690
+ 0.34,
691
+ 0.35,
692
+ 0.36,
693
+ 0.37,
694
+ 0.38,
695
+ 0.39,
696
+ 0.4,
697
+ 0.41,
698
+ 0.42,
699
+ 0.43,
700
+ 0.44,
701
+ 0.45,
702
+ 0.46,
703
+ 0.47,
704
+ 0.48,
705
+ 0.49,
706
+ 0.5,
707
+ 0.51,
708
+ 0.52,
709
+ 0.53,
710
+ 0.54,
711
+ 0.55,
712
+ 0.56,
713
+ 0.57,
714
+ 0.58,
715
+ 0.59,
716
+ 0.6,
717
+ 0.61,
718
+ 0.62,
719
+ 0.63,
720
+ 0.64,
721
+ 0.65,
722
+ 0.66,
723
+ 0.67,
724
+ 0.68,
725
+ 0.69,
726
+ 0.7,
727
+ 0.71,
728
+ 0.72,
729
+ 0.73,
730
+ 0.74,
731
+ 0.75,
732
+ 0.76,
733
+ 0.77,
734
+ 0.78,
735
+ 0.79,
736
+ 0.8,
737
+ 0.81,
738
+ 0.82,
739
+ 0.83,
740
+ 0.84,
741
+ 0.85,
742
+ 0.86,
743
+ 0.87,
744
+ 0.88,
745
+ 0.89,
746
+ 0.9,
747
+ 0.91,
748
+ 0.92,
749
+ 0.93,
750
+ 0.94,
751
+ 0.95,
752
+ 0.96,
753
+ 0.97,
754
+ 0.98,
755
+ 0.99,
756
+ 0.991,
757
+ 0.992,
758
+ 0.993,
759
+ 0.994,
760
+ 0.995,
761
+ 0.996,
762
+ 0.997,
763
+ 0.998,
764
+ 0.999,
765
+ 0.9995,
766
+ 0.9999,
767
+ 1.0
768
+ ]
769
+ },
770
+ "spearman_rho": 0.9992113218119626,
771
+ "worker_service_time_ms": {
772
+ "distribution_type": "inverse_cdf",
773
+ "latency_ms": [
774
+ 87.72087597846985,
775
+ 87.72467852516175,
776
+ 87.91030064630509,
777
+ 88.00015591812134,
778
+ 88.12767535018921,
779
+ 88.16078618812561,
780
+ 88.20027036190032,
781
+ 88.2218482208252,
782
+ 88.2316044626236,
783
+ 88.2494578113556,
784
+ 88.25887827968597,
785
+ 88.27183927154542,
786
+ 88.28763780593872,
787
+ 88.37063961029052,
788
+ 88.41736738204956,
789
+ 88.48253869056701,
790
+ 88.53538405895233,
791
+ 88.58251465797424,
792
+ 88.61692441940308,
793
+ 88.6526103067398,
794
+ 88.69219470977784,
795
+ 88.71518459320069,
796
+ 88.73541054725646,
797
+ 88.76436851501465,
798
+ 88.7882429409027,
799
+ 88.8153453207016,
800
+ 88.84055385589599,
801
+ 88.86013361930847,
802
+ 88.88090627670289,
803
+ 88.89949244976043,
804
+ 88.9193493270874,
805
+ 88.9378014087677,
806
+ 88.95896531105042,
807
+ 88.97797864437103,
808
+ 88.99964028835296,
809
+ 89.01831042766571,
810
+ 89.03623116016388,
811
+ 89.05389294624328,
812
+ 89.07155320167541,
813
+ 89.08649010658264,
814
+ 89.10401025772094,
815
+ 89.11759095191955,
816
+ 89.13092276096344,
817
+ 89.14472054004669,
818
+ 89.15695644378663,
819
+ 89.17383971691132,
820
+ 89.18826713562012,
821
+ 89.2024789762497,
822
+ 89.21522489070892,
823
+ 89.22818738937377,
824
+ 89.2410564661026,
825
+ 89.25574686527253,
826
+ 89.26698334217072,
827
+ 89.27876037597656,
828
+ 89.28845839977265,
829
+ 89.30029655456543,
830
+ 89.31337325572967,
831
+ 89.32795318126678,
832
+ 89.34285112380981,
833
+ 89.35806794166565,
834
+ 89.37013675689697,
835
+ 89.38430845737457,
836
+ 89.39552543163299,
837
+ 89.40971125602722,
838
+ 89.42204663753509,
839
+ 89.43564129829407,
840
+ 89.44992272853851,
841
+ 89.4627941942215,
842
+ 89.47512364387512,
843
+ 89.4904280757904,
844
+ 89.50267264842986,
845
+ 89.51706793308259,
846
+ 89.53111134052277,
847
+ 89.54835547924041,
848
+ 89.56463825702667,
849
+ 89.58519184112549,
850
+ 89.60270733833313,
851
+ 89.61832924365997,
852
+ 89.63192135810851,
853
+ 89.64982438087463,
854
+ 89.66651585578919,
855
+ 89.68272776603699,
856
+ 89.70003828048706,
857
+ 89.71646264076233,
858
+ 89.73325060844421,
859
+ 89.74732863903046,
860
+ 89.76466166973114,
861
+ 89.7842432308197,
862
+ 89.80248938560486,
863
+ 89.82193244457245,
864
+ 89.83790985107422,
865
+ 89.85878474712372,
866
+ 89.87975364208222,
867
+ 89.90125885009766,
868
+ 89.92823070526123,
869
+ 89.95628376960754,
870
+ 89.98322794437408,
871
+ 90.01770035743714,
872
+ 90.05196633815765,
873
+ 90.0945546579361,
874
+ 90.14471434116363,
875
+ 90.20198478698731,
876
+ 90.25720650196075,
877
+ 90.327011551857,
878
+ 90.41905149459839,
879
+ 90.55038662433624,
880
+ 90.70465857982636,
881
+ 90.87903607845307,
882
+ 91.12213365077973,
883
+ 91.56424148082733,
884
+ 92.54860488414765,
885
+ 92.65843725967407,
886
+ 92.76501456165313,
887
+ 92.8867836036682,
888
+ 93.04233510875703,
889
+ 93.24323705673218,
890
+ 94.55598453712442,
891
+ 107.64949651336671,
892
+ 109.727002286911,
893
+ 110.21494954109193,
894
+ 110.4879216728211,
895
+ 111.00118846521367,
896
+ 111.11597681045532
897
+ ],
898
+ "quantile_levels": [
899
+ 0.0,
900
+ 0.0001,
901
+ 0.0005,
902
+ 0.001,
903
+ 0.002,
904
+ 0.003,
905
+ 0.004,
906
+ 0.005,
907
+ 0.006,
908
+ 0.007,
909
+ 0.008,
910
+ 0.009,
911
+ 0.01,
912
+ 0.02,
913
+ 0.03,
914
+ 0.04,
915
+ 0.05,
916
+ 0.06,
917
+ 0.07,
918
+ 0.08,
919
+ 0.09,
920
+ 0.1,
921
+ 0.11,
922
+ 0.12,
923
+ 0.13,
924
+ 0.14,
925
+ 0.15,
926
+ 0.16,
927
+ 0.17,
928
+ 0.18,
929
+ 0.19,
930
+ 0.2,
931
+ 0.21,
932
+ 0.22,
933
+ 0.23,
934
+ 0.24,
935
+ 0.25,
936
+ 0.26,
937
+ 0.27,
938
+ 0.28,
939
+ 0.29,
940
+ 0.3,
941
+ 0.31,
942
+ 0.32,
943
+ 0.33,
944
+ 0.34,
945
+ 0.35,
946
+ 0.36,
947
+ 0.37,
948
+ 0.38,
949
+ 0.39,
950
+ 0.4,
951
+ 0.41,
952
+ 0.42,
953
+ 0.43,
954
+ 0.44,
955
+ 0.45,
956
+ 0.46,
957
+ 0.47,
958
+ 0.48,
959
+ 0.49,
960
+ 0.5,
961
+ 0.51,
962
+ 0.52,
963
+ 0.53,
964
+ 0.54,
965
+ 0.55,
966
+ 0.56,
967
+ 0.57,
968
+ 0.58,
969
+ 0.59,
970
+ 0.6,
971
+ 0.61,
972
+ 0.62,
973
+ 0.63,
974
+ 0.64,
975
+ 0.65,
976
+ 0.66,
977
+ 0.67,
978
+ 0.68,
979
+ 0.69,
980
+ 0.7,
981
+ 0.71,
982
+ 0.72,
983
+ 0.73,
984
+ 0.74,
985
+ 0.75,
986
+ 0.76,
987
+ 0.77,
988
+ 0.78,
989
+ 0.79,
990
+ 0.8,
991
+ 0.81,
992
+ 0.82,
993
+ 0.83,
994
+ 0.84,
995
+ 0.85,
996
+ 0.86,
997
+ 0.87,
998
+ 0.88,
999
+ 0.89,
1000
+ 0.9,
1001
+ 0.91,
1002
+ 0.92,
1003
+ 0.93,
1004
+ 0.94,
1005
+ 0.95,
1006
+ 0.96,
1007
+ 0.97,
1008
+ 0.98,
1009
+ 0.99,
1010
+ 0.991,
1011
+ 0.992,
1012
+ 0.993,
1013
+ 0.994,
1014
+ 0.995,
1015
+ 0.996,
1016
+ 0.997,
1017
+ 0.998,
1018
+ 0.999,
1019
+ 0.9995,
1020
+ 0.9999,
1021
+ 1.0
1022
+ ]
1023
+ }
1024
+ }
1025
+ }
1026
+ }
1027
+ }
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/profile/profile.json ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "burst_model_path": "latency_burst_model.json",
3
+ "distribution_path": "latency_distribution.json",
4
+ "env_fps": 10,
5
+ "frame_ms": 100.0,
6
+ "gpu_class": "1x-rtx3090",
7
+ "instance_id": "instance_859cf1e47bca6046",
8
+ "latency_kind": "observation_to_action_latency",
9
+ "latency_method": "temporal",
10
+ "model_id": "qwenoft",
11
+ "n_admitted_observations": 7976,
12
+ "n_capacity_drops": 294,
13
+ "n_observation_attempts": 8270,
14
+ "per_slot_summary": {
15
+ "0": {
16
+ "admitted_count": 7976,
17
+ "mean_observation_to_action_latency_ms": 90.56460638563993,
18
+ "mean_worker_service_time_ms": 90.22241150451042,
19
+ "p95_observation_to_action_latency_ms": 92.13036412000656,
20
+ "p95_worker_service_time_ms": 91.75596672296524,
21
+ "p99_worker_service_time_ms": 110.92562991380692
22
+ }
23
+ },
24
+ "provenance": {
25
+ "base_config": "/workspace/tasks/20260911T023128Z-p-only4/ant/profile.yaml",
26
+ "checkpoint_kind": "best",
27
+ "model_artifact": {
28
+ "checkpoint": "checkpoints/steps_5000_pytorch_model.pt",
29
+ "model_config": "config.full.yaml",
30
+ "path_in_repo": "OpenVLA/zero-latency/ant_rgb_state_l0_return_gt3000_100ep_openvla_native_sft_5k",
31
+ "repo_id": "latency-sensitive-bench/extra-envs-checkpoints",
32
+ "source": "local"
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": "20260911T033037730561Z",
44
+ "summary": {
45
+ "frame_ms": 100.0,
46
+ "max_ms": 130.29119229316711,
47
+ "mean_effective_frames": 0.9056460638563993,
48
+ "mean_ms": 90.56460638563993,
49
+ "min_ms": 87.98952293395996,
50
+ "n_samples": 7976,
51
+ "p50_frames": 0.8970676946640015,
52
+ "p50_ms": 89.70676946640015,
53
+ "p90_frames": 0.9074710392951966,
54
+ "p90_ms": 90.74710392951965,
55
+ "p95_frames": 0.9213036412000656,
56
+ "p95_ms": 92.13036412000656,
57
+ "p99_frames": 1.1217999053001404,
58
+ "p99_ms": 112.17999053001404,
59
+ "prob_latency_gt_1_frame": 0.03686058174523571,
60
+ "prob_latency_gt_2_frames": 0.0,
61
+ "prob_latency_gt_3_frames": 0.0,
62
+ "std_ms": 4.164609685850939
63
+ },
64
+ "visualization_path": "latency_profile.png",
65
+ "workload_id": "ant"
66
+ }
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/provenance.json ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "task": "ant",
3
+ "protocol": {
4
+ "gpu": 2,
5
+ "seed_start": 42,
6
+ "seed_end": 141,
7
+ "env_fps": 10,
8
+ "obs_fps": 10,
9
+ "max_raw_steps": 1000,
10
+ "parallel_envs": 16,
11
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
12
+ "checkpoint_path": "latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42",
13
+ "profile": {
14
+ "mean_ms": 90.56460638563993,
15
+ "profile": "/home/ubuntu/lzj/mean-profiling/reference/checkpoint-configs/latency-aware/ant/small-policy/sample-factory-qwenoft-rtx3090-v1/profile/profile.json",
16
+ "sha256": "0e49f72ec05ac600a54e07bbca5af3143708444d606167f33fa21788a9fefe50"
17
+ },
18
+ "config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant.yaml",
19
+ "output": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant",
20
+ "metrics": "return mean/std/min/max;length mean/std;success where nativeprovided;latency/drops/invalid/action audits;100 episode vectors"
21
+ },
22
+ "checkpoint_weights": {
23
+ "bytes": 9785070315,
24
+ "sha256": "afb954569065450b9b80a86ca96e3898e3fe8d2f8c38a06f63bf3b11c41163b3"
25
+ },
26
+ "evaluation": {
27
+ "n_episodes": 100,
28
+ "mean_return": 1453.844063807972,
29
+ "std_return": 693.7275200567642,
30
+ "min_return": 85.64836938561511,
31
+ "max_return": 2508.917122342891,
32
+ "mean_length": 803.85,
33
+ "std_length": 328.8088312378486,
34
+ "min_length": 60.0,
35
+ "max_length": 1000.0,
36
+ "return_field": "episode_return_env",
37
+ "length_field": "survival_steps",
38
+ "mode": "simulated",
39
+ "policy_id": "starvla",
40
+ "env_id": "LatencyBench/AntContinuous-v0",
41
+ "model_id": "qwenoft",
42
+ "gpu_class": "1x-rtx3090",
43
+ "workload_id": "ant",
44
+ "instance_id": "instance_859cf1e47bca6046",
45
+ "source_run_id": "20260911T033037730561Z",
46
+ "profile_ref": null,
47
+ "env_fps": 10.0,
48
+ "obs_fps": 10.0,
49
+ "frame_ms": 100.0,
50
+ "latency_type": "profile_sample",
51
+ "task": "ant",
52
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
53
+ "checkpoint_path": "latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42",
54
+ "profile_sha256": "0e49f72ec05ac600a54e07bbca5af3143708444d606167f33fa21788a9fefe50",
55
+ "condition": "profile-latency",
56
+ "invalid_actions": 0,
57
+ "dropped_actions": 0,
58
+ "unique_seeds": 100,
59
+ "physical_gpu": 2,
60
+ "eval_config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant.yaml",
61
+ "execution_audit": {
62
+ "issued_action_records": 79573,
63
+ "applied_action_records": 79465,
64
+ "dropped_action_records": 0,
65
+ "nonnoop_issued_records": 79573,
66
+ "finite_action_values": true,
67
+ "latency_sample_count": 79573,
68
+ "latency_mean_ms": 90.00919554158884,
69
+ "latency_std_ms": 2.514492574433973,
70
+ "latency_p95_ms": 91.11971585797141,
71
+ "latency_p99_ms": 102.67108120995428
72
+ }
73
+ },
74
+ "source_revision": {
75
+ "repo": "c3c6a39365a151e9b7a5e215452fd64e957c2b29",
76
+ "starvla": "ccca13c5177fe3d3c884b6e2de4965d916016649",
77
+ "runtime_fixes": [
78
+ "mean-profile-preparation.patch",
79
+ "gym-language-contract.patch",
80
+ "loader-spawn-cache.patch",
81
+ "loader-spawn-test.patch",
82
+ "doom-mean-reset.patch"
83
+ ],
84
+ "pytorch3d": {
85
+ "revision": "33824be3cbc87a7dd1db0f6a9a9de9ac81b2d0ba",
86
+ "build": "transforms-only, no native render extension; QwenOFT uses transforms only"
87
+ },
88
+ "decord": {
89
+ "version": "0.6.0",
90
+ "build": "official source CPU decoder CP310",
91
+ "wheel_sha256": "e193b356b1e984b4eff08d23b62e482c2c9e5037a6efdc0b1af47079ae2e4c47"
92
+ }
93
+ },
94
+ "raw_records_format": "gzip(JSONL), lossless",
95
+ "startup_checks_included_in_score": false,
96
+ "results_status": "evaluation_complete; acceptance_not_inferred"
97
+ }
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/queue_eval_latency_profile_sample.json ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "checkpoint_path": "/home/ubuntu/lzj/mean-profiling/ant/vla-publication/checkpoints/model.pt",
3
+ "experiment_name": "ant-mean5000-profile-simulation-100ep",
4
+ "latency": "profile_sample",
5
+ "latency_type": "profile_sample",
6
+ "lengths": [
7
+ 1000,
8
+ 1000,
9
+ 177,
10
+ 1000,
11
+ 937,
12
+ 1000,
13
+ 429,
14
+ 1000,
15
+ 210,
16
+ 660,
17
+ 1000,
18
+ 1000,
19
+ 1000,
20
+ 1000,
21
+ 1000,
22
+ 1000,
23
+ 1000,
24
+ 60,
25
+ 143,
26
+ 1000,
27
+ 1000,
28
+ 1000,
29
+ 871,
30
+ 1000,
31
+ 1000,
32
+ 543,
33
+ 1000,
34
+ 1000,
35
+ 707,
36
+ 1000,
37
+ 256,
38
+ 1000,
39
+ 101,
40
+ 1000,
41
+ 372,
42
+ 1000,
43
+ 162,
44
+ 1000,
45
+ 363,
46
+ 1000,
47
+ 1000,
48
+ 1000,
49
+ 680,
50
+ 1000,
51
+ 160,
52
+ 1000,
53
+ 248,
54
+ 1000,
55
+ 1000,
56
+ 260,
57
+ 316,
58
+ 1000,
59
+ 281,
60
+ 1000,
61
+ 1000,
62
+ 1000,
63
+ 1000,
64
+ 1000,
65
+ 1000,
66
+ 1000,
67
+ 1000,
68
+ 1000,
69
+ 1000,
70
+ 1000,
71
+ 1000,
72
+ 189,
73
+ 74,
74
+ 1000,
75
+ 116,
76
+ 1000,
77
+ 1000,
78
+ 215,
79
+ 1000,
80
+ 1000,
81
+ 1000,
82
+ 1000,
83
+ 1000,
84
+ 1000,
85
+ 1000,
86
+ 1000,
87
+ 1000,
88
+ 1000,
89
+ 821,
90
+ 271,
91
+ 1000,
92
+ 72,
93
+ 1000,
94
+ 1000,
95
+ 1000,
96
+ 1000,
97
+ 1000,
98
+ 441,
99
+ 1000,
100
+ 250,
101
+ 1000,
102
+ 1000,
103
+ 1000,
104
+ 1000,
105
+ 1000,
106
+ 1000
107
+ ],
108
+ "mean_length": 803.85,
109
+ "mean_return": 1453.8440638079721,
110
+ "returns": [
111
+ 1846.1103431567394,
112
+ 2415.720790707953,
113
+ 457.34421085068755,
114
+ 1421.7952163289683,
115
+ 2037.7234409469488,
116
+ 2330.630175869275,
117
+ 1161.643572255748,
118
+ 2351.1524624990343,
119
+ 513.2964809479813,
120
+ 1126.8652528911032,
121
+ 1693.436933192597,
122
+ 948.3780972955639,
123
+ 2322.052445211472,
124
+ 960.4026770814776,
125
+ 1464.564005196777,
126
+ 1110.548792782156,
127
+ 2246.207900740156,
128
+ 85.64836938561511,
129
+ 340.54799067574436,
130
+ 2457.088748930458,
131
+ 2166.2512677098603,
132
+ 2357.957592244385,
133
+ 1654.8780938737275,
134
+ 1499.367100151414,
135
+ 2297.4032619179525,
136
+ 1253.360764666355,
137
+ 1221.270312709775,
138
+ 2389.2476464763376,
139
+ 1682.5290233886233,
140
+ 2474.676425615127,
141
+ 382.9231146443659,
142
+ 1837.8126619276347,
143
+ 227.19436616673684,
144
+ 1700.6312067622644,
145
+ 960.9452812639541,
146
+ 2290.6720141359438,
147
+ 328.5729178056416,
148
+ 1180.073938772476,
149
+ 817.4190215442345,
150
+ 1651.2255208727013,
151
+ 1428.174672693164,
152
+ 1627.3838925098842,
153
+ 1079.756369746183,
154
+ 2173.9447393037276,
155
+ 409.90633829945847,
156
+ 2467.2636019929073,
157
+ 657.4084558813478,
158
+ 974.7436031610902,
159
+ 1510.5184342975385,
160
+ 602.2339441184535,
161
+ 760.9784375126189,
162
+ 1941.172113330597,
163
+ 624.3590446196446,
164
+ 2163.4347041279893,
165
+ 1126.9957963444238,
166
+ 1405.131632695366,
167
+ 1206.2916757636292,
168
+ 2392.7980761515178,
169
+ 964.0216541467705,
170
+ 2252.192880003706,
171
+ 2471.9158497657563,
172
+ 1902.8491241623092,
173
+ 1435.6661382989703,
174
+ 1668.3237703695809,
175
+ 1813.291243529155,
176
+ 446.72353548541076,
177
+ 130.84194814079504,
178
+ 2315.857153770824,
179
+ 288.3915792961347,
180
+ 894.0228631227924,
181
+ 2030.322535823717,
182
+ 507.9449555916754,
183
+ 2377.7373967468293,
184
+ 897.3077114027096,
185
+ 1454.612590266188,
186
+ 2292.457960175467,
187
+ 1424.378337790017,
188
+ 1441.1111023164538,
189
+ 1265.4771503717611,
190
+ 1662.8808067819505,
191
+ 2508.917122342891,
192
+ 1655.3510139158748,
193
+ 1387.3843721247736,
194
+ 646.4356689469432,
195
+ 2172.801064037805,
196
+ 165.9213897970373,
197
+ 1063.1483912161111,
198
+ 1000.135342286622,
199
+ 1977.2359176146426,
200
+ 1937.1674235355138,
201
+ 1344.7729257831547,
202
+ 786.3379828975102,
203
+ 1391.060299752017,
204
+ 503.300235688713,
205
+ 2446.7482357041768,
206
+ 1171.9102336514923,
207
+ 2356.7311711183065,
208
+ 2356.12199478712,
209
+ 1389.2987977192308,
210
+ 967.2335383727841
211
+ ],
212
+ "seed": 42,
213
+ "source_profile_path": "/home/ubuntu/lzj/mean-profiling/reference/checkpoint-configs/latency-aware/ant/small-policy/sample-factory-qwenoft-rtx3090-v1/profile/profile.json",
214
+ "std_return": 693.7275200567642,
215
+ "suite_name": "profile_sample",
216
+ "timestamp_utc": "2026-10-01T07:11:37.707856+00:00"
217
+ }
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/actions.jsonl.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c1354df8561fbd24c78158553cb997343065983d33497883dac41e2177a421cf
3
+ size 12313765
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/e2e_latencies.jsonl.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c43d7986e0bd8cfa33d1fb30dd48832c1c48df9a557aa5d97d3b11bb7be4986a
3
+ size 1639178
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/episode_metrics.jsonl.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1c791b0600f8690f8d3f36f2656417e4cab6a368173a6f08adb5f23ad71028f9
3
+ size 7869
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/infer_latencies.jsonl.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:eaa49aa3fbce55063a9c3037d18a6b9ff3bd327981b4a4f35799a99c434189df
3
+ size 1162241
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/latencies.jsonl.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0c09425581b2ad7d7786b9489ce88bfc64eecd577fec18aa66280c27e08b8f18
3
+ size 1162235
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/observation_attempts.jsonl.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b1a7d5db5a150efea2d3bb76abaa4d5328c50ae0918a01e1e891509155994759
3
+ size 47
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/queue_eval_results.jsonl.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:163339eb50d2c2964191177ea5918ce97b681f08c2efb4694c9279cddb37854e
3
+ size 1548
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/raw-records/steps.jsonl.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0ffffd6f5f47d90c8a79ffbafddbca7c98c15fe48b10563a3a5fd7d5bc5d7db3
3
+ size 16329224
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/resolved_config.yaml ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ experiment:
2
+ name: ant-mean5000-profile-simulation-100ep
3
+ seed: 42
4
+ backend:
5
+ type: sample_factory
6
+ algo: APPO
7
+ device: cuda
8
+ train_dir: /mnt/checkpoints/latency-sensitive-bench/small_models/ant
9
+ restart_behavior: overwrite
10
+ run_mode: eval
11
+ executor:
12
+ mode: simulated
13
+ simulated_worker_capacity: 1
14
+ simulated_inference_pool: true
15
+ inference_devices:
16
+ - cuda:0
17
+ inference_batch_size: 16
18
+ env:
19
+ action_space:
20
+ dtype: float32
21
+ high:
22
+ - 1.0
23
+ - 1.0
24
+ - 1.0
25
+ - 1.0
26
+ - 1.0
27
+ - 1.0
28
+ - 1.0
29
+ - 1.0
30
+ labels:
31
+ - back_right_hip_torque
32
+ - back_right_ankle_torque
33
+ - front_left_hip_torque
34
+ - front_left_ankle_torque
35
+ - front_right_hip_torque
36
+ - front_right_ankle_torque
37
+ - back_left_hip_torque
38
+ - back_left_ankle_torque
39
+ low:
40
+ - -1.0
41
+ - -1.0
42
+ - -1.0
43
+ - -1.0
44
+ - -1.0
45
+ - -1.0
46
+ - -1.0
47
+ - -1.0
48
+ type: box
49
+ base_prompt: Make the Ant move forward as fast as possible without falling. Predict
50
+ eight continuous torques in [-1, 1] ordered as back right hip, back right ankle,
51
+ front left hip, front left ankle, front right hip, front right ankle, back left
52
+ hip, and back left ankle.
53
+ env_fps: 10.0
54
+ env_id: LatencyBench/AntContinuous-v0
55
+ frame_stack: 1
56
+ make_kwargs:
57
+ base_env_id: Ant-v4
58
+ base_make_kwargs:
59
+ exclude_current_positions_from_observation: true
60
+ use_contact_forces: false
61
+ render_mode: rgb_array
62
+ noop_action:
63
+ - 0.0
64
+ - 0.0
65
+ - 0.0
66
+ - 0.0
67
+ - 0.0
68
+ - 0.0
69
+ - 0.0
70
+ - 0.0
71
+ obs_fps: 10.0
72
+ registration_imports:
73
+ - latency_bench.envs.gymnasium_ant
74
+ state_space:
75
+ labels:
76
+ - torso_z
77
+ - torso_quaternion_w
78
+ - torso_quaternion_x
79
+ - torso_quaternion_y
80
+ - torso_quaternion_z
81
+ - front_left_hip_angle
82
+ - front_left_ankle_angle
83
+ - front_right_hip_angle
84
+ - front_right_ankle_angle
85
+ - back_left_hip_angle
86
+ - back_left_ankle_angle
87
+ - back_right_hip_angle
88
+ - back_right_ankle_angle
89
+ - torso_x_velocity
90
+ - torso_y_velocity
91
+ - torso_z_velocity
92
+ - torso_angular_velocity_x
93
+ - torso_angular_velocity_y
94
+ - torso_angular_velocity_z
95
+ - front_left_hip_angular_velocity
96
+ - front_left_ankle_angular_velocity
97
+ - front_right_hip_angular_velocity
98
+ - front_right_ankle_angular_velocity
99
+ - back_left_hip_angular_velocity
100
+ - back_left_ankle_angular_velocity
101
+ - back_right_hip_angular_velocity
102
+ - back_right_ankle_angular_velocity
103
+ task_name: ant_rgb_state
104
+ name: gymnasium
105
+ obs_resize:
106
+ - 224
107
+ - 224
108
+ latency:
109
+ method: temporal
110
+ profile_path: /home/ubuntu/lzj/mean-profiling/reference/checkpoint-configs/latency-aware/ant/small-policy/sample-factory-qwenoft-rtx3090-v1/profile/profile.json
111
+ profile_worker_slot: 0
112
+ seed: 271828
113
+ add_latency_info: false
114
+ scheduler:
115
+ hold_policy: hold
116
+ ordering_policy: issue_order_fifo
117
+ policy:
118
+ type: starvla
119
+ checkpoint_path: /home/ubuntu/lzj/mean-profiling/ant/vla-publication/checkpoints/model.pt
120
+ model_config_path: /home/ubuntu/lzj/mean-profiling/ant/vla-publication/config.full.yaml
121
+ task_manifest_path: /home/ubuntu/lzj/mean-profiling/ant/vla-publication/manifest.json
122
+ device: cuda:0
123
+ latency_prompt_map_path: /home/ubuntu/lzj/mean-profiling/ant/vla-publication/latency_prompt_map.json
124
+ latency_prompt_key: 1
125
+ prompt_mode: raw
126
+ unnorm_key: new_embodiment
127
+ backbone_path: /home/ubuntu/lzj/models/Qwen3-VL-4B-Instruct
128
+ worker_python_executable: /home/ubuntu/lzj/conda/envs/qwenoft/bin/python
129
+ action_prefix:
130
+ mode: none
131
+ training:
132
+ train_for_env_steps: 10000000
133
+ num_workers: 8
134
+ num_envs_per_worker: 8
135
+ worker_num_splits: 2
136
+ num_policies: 1
137
+ batch_size: 1024
138
+ rollout: 64
139
+ recurrence: 1
140
+ num_epochs: 2
141
+ num_batches_per_epoch: 4
142
+ num_batches_to_accumulate: 2
143
+ policy_workers_per_policy: 1
144
+ max_policy_lag: 10000
145
+ learning_rate: 0.00295
146
+ lr_schedule: linear_decay
147
+ lr_schedule_kl_threshold: 0.008
148
+ gamma: 0.99
149
+ gae_lambda: 0.95
150
+ ppo_clip_ratio: 0.2
151
+ ppo_clip_value: 1.0
152
+ value_loss_coeff: 1.3
153
+ max_grad_norm: 3.5
154
+ exploration_loss: entropy
155
+ exploration_loss_coeff: 0.0
156
+ kl_loss_coeff: 0.1
157
+ reward_scale: 1.0
158
+ reward_clip: 1000.0
159
+ async_rl: false
160
+ serial_mode: false
161
+ batched_sampling: false
162
+ with_vtrace: false
163
+ use_rnn: false
164
+ encoder_mlp_layers:
165
+ - 64
166
+ - 64
167
+ nonlinearity: tanh
168
+ adaptive_stddev: false
169
+ policy_initialization: torch_default
170
+ initial_stddev: 1.0
171
+ actor_critic_share_weights: true
172
+ shuffle_minibatches: false
173
+ value_bootstrap: true
174
+ normalize_input: true
175
+ normalize_returns: true
176
+ decorrelate_experience_max_seconds: 10
177
+ decorrelate_envs_on_one_worker: true
178
+ set_workers_cpu_affinity: true
179
+ force_envs_single_thread: true
180
+ save_every_sec: 600
181
+ keep_checkpoints: 3
182
+ save_best_every_sec: 60
183
+ save_best_after: 100000
184
+ evaluation:
185
+ eval_interval_steps: null
186
+ eval_episodes: 100
187
+ eval_parallel_envs: 16
188
+ eval_max_steps: 1000
189
+ eval_deterministic: true
190
+ eval_latency_values: null
191
+ eval_raw_reward: true
192
+ eval_suites:
193
+ fixed: []
194
+ normal: []
195
+ uniform: []
196
+ logging:
197
+ output_dir: /home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant
198
+ video:
199
+ enabled: false
200
+ save_step_records: true
201
+ save_action_records: true
202
+ save_latency_records: true
203
+ wandb_project: null
204
+ wandb_group: null
205
+ wandb_job_type: null
206
+ simulated_pipeline_profile: false
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/statistics.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "n_episodes": 100,
3
+ "mean_return": 1453.844063807972,
4
+ "std_return": 693.7275200567642,
5
+ "min_return": 85.64836938561511,
6
+ "max_return": 2508.917122342891,
7
+ "mean_length": 803.85,
8
+ "std_length": 328.8088312378486,
9
+ "min_length": 60.0,
10
+ "max_length": 1000.0,
11
+ "return_field": "episode_return_env",
12
+ "length_field": "survival_steps",
13
+ "mode": "simulated",
14
+ "policy_id": "starvla",
15
+ "env_id": "LatencyBench/AntContinuous-v0",
16
+ "model_id": "qwenoft",
17
+ "gpu_class": "1x-rtx3090",
18
+ "workload_id": "ant",
19
+ "instance_id": "instance_859cf1e47bca6046",
20
+ "source_run_id": "20260911T033037730561Z",
21
+ "profile_ref": null,
22
+ "env_fps": 10.0,
23
+ "obs_fps": 10.0,
24
+ "frame_ms": 100.0,
25
+ "latency_type": "profile_sample",
26
+ "task": "ant",
27
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
28
+ "checkpoint_path": "latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42",
29
+ "profile_sha256": "0e49f72ec05ac600a54e07bbca5af3143708444d606167f33fa21788a9fefe50",
30
+ "condition": "profile-latency",
31
+ "invalid_actions": 0,
32
+ "dropped_actions": 0,
33
+ "unique_seeds": 100,
34
+ "physical_gpu": 2,
35
+ "eval_config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant.yaml"
36
+ }
latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/stdout.log ADDED
@@ -0,0 +1,405 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [bench] run=ant-mean5000-profile-simulation-100ep sweeps=1 episodes_per_sweep=100 total_episode_runs=100
2
+ [bench] sweep 1/1: eval_latency=profile_sample
3
+ 10/01 [06:50:55] INFO | >> Failed to load library ( ctypesloader.py:70
4
+ 'libOpenGL.so.0' ): libOpenGL.so.0:
5
+ cannot open shared object file: No
6
+ such file or directory
7
+ INFO | >> No OpenGL_accelerate acceleratesupport.py:24
8
+ module loaded: No module named
9
+ 'OpenGL_accelerate'
10
+ INFO | >> Failed to load library ( ctypesloader.py:70
11
+ 'libOpenGL.so.0' ): libOpenGL.so.0:
12
+ cannot open shared object file: No
13
+ such file or directory
14
+ 10/01 [06:50:58] INFO | >> Loaded mixtures from Behavior registry.py:113
15
+ (data_config): ['BEHAVIOR_challenge']
16
+ INFO | >> Loaded data_config from DOMINO: registry.py:107
17
+ ['robotwin']
18
+ INFO | >> Loaded embodiment_tags from registry.py:110
19
+ DOMINO (data_config): []
20
+ INFO | >> Loaded mixtures from DOMINO registry.py:113
21
+ (data_config): ['domino',
22
+ 'domino_clean', 'domino_random',
23
+ 'domino_cotrain']
24
+ INFO | >> Loaded data_config from Franka: registry.py:107
25
+ ['custom_robot_config',
26
+ 'demo_sim_franka_delta_joints',
27
+ 'SO101']
28
+ INFO | >> Loaded embodiment_tags from registry.py:110
29
+ Franka (data_config): []
30
+ INFO | >> Loaded mixtures from Franka registry.py:113
31
+ (data_config): ['custom_dataset',
32
+ 'custom_dataset_2',
33
+ 'demo_sim_pick_place', 'SO101_pick']
34
+ INFO | >> Loaded data_config from LIBERO: registry.py:107
35
+ ['libero_franka']
36
+ INFO | >> Loaded embodiment_tags from registry.py:110
37
+ LIBERO (data_config): []
38
+ INFO | >> Loaded mixtures from LIBERO registry.py:113
39
+ (data_config): ['libero_all',
40
+ 'libero_goal', 'multi_robot']
41
+ INFO | >> Loaded data_config from MIKASA: registry.py:107
42
+ ['mikasa_franka_h1']
43
+ INFO | >> Loaded embodiment_tags from registry.py:110
44
+ MIKASA (data_config):
45
+ ['mikasa_franka_h1']
46
+ INFO | >> Loaded mixtures from MIKASA registry.py:113
47
+ (data_config):
48
+ ['local/intercept_grab_fast_vla_v0_h1_
49
+ train']
50
+ INFO | >> Loaded data_config from registry.py:107
51
+ RoboChallenge_table30v2:
52
+ ['ur5_robochallenge',
53
+ 'arx5_robochallenge',
54
+ 'dosw1_robochallenge']
55
+ INFO | >> Loaded embodiment_tags from registry.py:110
56
+ RoboChallenge_table30v2 (data_config):
57
+ ['ur5_robochallenge',
58
+ 'arx5_robochallenge',
59
+ 'dosw1_robochallenge']
60
+ INFO | >> Loaded mixtures from registry.py:113
61
+ RoboChallenge_table30v2 (data_config):
62
+ ['robochallenge_table30v2_shred_paper'
63
+ , 'robochallenge_table30v2_ur5_all',
64
+ 'robochallenge_table30v2_arx5_all',
65
+ 'robochallenge_table30v2_dosw1_all']
66
+ INFO | >> Loaded data_config from registry.py:107
67
+ Robocasa_365:
68
+ ['panda_omron_robocasa365']
69
+ INFO | >> Loaded embodiment_tags from registry.py:110
70
+ Robocasa_365 (data_config): []
71
+ INFO | >> Loaded mixtures from registry.py:113
72
+ Robocasa_365 (data_config):
73
+ ['robocasa365_open_drawer_target_human
74
+ ',
75
+ 'robocasa365_atomic_target_human_all',
76
+ 'robocasa365_composite_target_human_al
77
+ l', 'robocasa365_target_human_all']
78
+ INFO | >> Loaded data_config from registry.py:107
79
+ Robocasa_tabletop:
80
+ ['fourier_gr1_arms_waist']
81
+ INFO | >> Loaded embodiment_tags from registry.py:110
82
+ Robocasa_tabletop (data_config): []
83
+ INFO | >> Loaded mixtures from registry.py:113
84
+ Robocasa_tabletop (data_config):
85
+ ['fourier_gr1_unified_1000']
86
+ INFO | >> Loaded data_config from registry.py:107
87
+ Robotwin: ['robotwin', 'robotwin50',
88
+ 'arx_x5']
89
+ INFO | >> Loaded embodiment_tags from registry.py:110
90
+ Robotwin (data_config): []
91
+ INFO | >> Loaded mixtures from Robotwin registry.py:113
92
+ (data_config): ['robotwin_all',
93
+ 'robotwin_all_50', 'robotwin',
94
+ 'robotwin_task1', 'robotwin_task2',
95
+ 'arx_x5']
96
+ INFO | >> Loaded data_config from registry.py:107
97
+ SimplerEnv: ['oxe_droid',
98
+ 'oxe_bridge', 'oxe_rt1']
99
+ INFO | >> Loaded embodiment_tags from registry.py:110
100
+ SimplerEnv (data_config): []
101
+ INFO | >> Loaded mixtures from SimplerEnv registry.py:113
102
+ (data_config): ['bridge',
103
+ 'bridge_rt_1']
104
+ INFO | >> Loaded data_config from registry.py:107
105
+ VLA-Arena: ['vla_arena_franka']
106
+ INFO | >> Loaded embodiment_tags from registry.py:110
107
+ VLA-Arena (data_config): []
108
+ INFO | >> Loaded mixtures from VLA-Arena registry.py:113
109
+ (data_config): ['vla_arena_L0_S',
110
+ 'vla_arena_L0_M', 'vla_arena_L0_L']
111
+ INFO | >> Loaded data_config from registry.py:107
112
+ rl_games: ['rl_games_flappy',
113
+ 'rl_games_demon_attack',
114
+ 'rl_games_defend_the_line',
115
+ 'rl_games_deadly_corridor',
116
+ 'rl_games_asterix',
117
+ 'rl_games_atlantis',
118
+ 'rl_games_gymnasium',
119
+ 'rl_games_gymnasium_discrete',
120
+ 'rl_games_gymnasium_native']
121
+ INFO | >> Loaded embodiment_tags from registry.py:110
122
+ rl_games (data_config):
123
+ ['rl_games_flappy',
124
+ 'rl_games_demon_attack',
125
+ 'rl_games_defend_the_line',
126
+ 'rl_games_deadly_corridor',
127
+ 'rl_games_asterix',
128
+ 'rl_games_atlantis',
129
+ 'rl_games_gymnasium',
130
+ 'rl_games_gymnasium_discrete',
131
+ 'rl_games_gymnasium_native']
132
+ INFO | >> Loaded mixtures from rl_games registry.py:113
133
+ (data_config): ['flappy_train',
134
+ 'flappy_train__bridge',
135
+ 'flappy_mixed_latency_train',
136
+ 'flappy_mixed_latency_train__bridge',
137
+ 'demon_attack_train',
138
+ 'demon_attack_train__bridge',
139
+ 'demon_attack_mixed_latency_train',
140
+ 'demon_attack_mixed_latency_train__bri
141
+ dge', 'defend_the_line_train',
142
+ 'defend_the_line_train__bridge',
143
+ 'defend_the_line_mixed_latency_train',
144
+ 'defend_the_line_mixed_latency_train__
145
+ bridge', 'deadly_corridor_train',
146
+ 'deadly_corridor_train__bridge',
147
+ 'deadly_corridor_mixed_latency_train',
148
+ 'deadly_corridor_mixed_latency_train__
149
+ bridge', 'asterix_train',
150
+ 'asterix_train__bridge',
151
+ 'asterix_mixed_latency_train',
152
+ 'asterix_mixed_latency_train__bridge',
153
+ 'atlantis_train',
154
+ 'atlantis_train__bridge',
155
+ 'atlantis_mixed_latency_train',
156
+ 'atlantis_mixed_latency_train__bridge'
157
+ , 'h1hand_balance_hard']
158
+ INFO | >> PolicyServerWrapper: loading policy_wrapper.py:73
159
+ framework from
160
+ /home/ubuntu/lzj/mean-profiling/a
161
+ nt/vla-publication/checkpoints/mo
162
+ del.pt
163
+ INFO | >> [*] Loading from local share_tools.py:418
164
+ checkpoint path
165
+ `/home/ubuntu/lzj/mean-profiling/an
166
+ t/vla-publication/checkpoints/model
167
+ .pt`
168
+ [QWen3] loading /home/ubuntu/lzj/models/Qwen3-VL-4B-Instruct with gradient_checkpointing=True
169
+
170
+ [QWen3] gradient_checkpointing ENABLED (use_reentrant=False, active=True, text_use_cache=False)
171
+ 10/01 [06:51:04] INFO | >> [*] Loading from local share_tools.py:418
172
+ checkpoint path
173
+ `/home/ubuntu/lzj/mean-profiling/an
174
+ t/vla-publication/checkpoints/model
175
+ .pt`
176
+ INFO | >> [*] Loading from local share_tools.py:418
177
+ checkpoint path
178
+ `/home/ubuntu/lzj/mean-profiling/an
179
+ t/vla-publication/checkpoints/model
180
+ .pt`
181
+ INFO | >> [*] Loading from local share_tools.py:418
182
+ checkpoint path
183
+ `/home/ubuntu/lzj/mean-profiling/an
184
+ t/vla-publication/checkpoints/model
185
+ .pt`
186
+ INFO | >> PolicyNormProcessor policy_norm_processor.py:333
187
+ ready:
188
+ robot_type=rl_games_gymna
189
+ sium,
190
+ unnorm_key=new_embodiment
191
+ ,
192
+ action_keys=['action.butt
193
+ on'] (dims=[8]),
194
+ state_keys=['state.game_s
195
+ tate']
196
+ INFO | >> PolicyServerWrapper ready: policy_wrapper.py:126
197
+ action_chunk_size=1,
198
+ default_unnorm_key=new_embodimen
199
+ t,
200
+ available_unnorm_keys=['new_embo
201
+ diment'],
202
+ action_keys=['action.button'],
203
+ state_keys=['state.game_state']
204
+ [bench] sweep 1/1 episode 1/100 done
205
+ [bench] sweep 1/1 episode 2/100 done
206
+ [bench] sweep 1/1 episode 3/100 done
207
+ [bench] sweep 1/1 episode 4/100 done
208
+ [bench] sweep 1/1 episode 5/100 done
209
+ [bench] sweep 1/1 episode 6/100 done
210
+ [bench] sweep 1/1 episode 7/100 done
211
+ [bench] sweep 1/1 episode 8/100 done
212
+ [bench] sweep 1/1 episode 9/100 done
213
+ [bench] sweep 1/1 episode 10/100 done
214
+ [bench] sweep 1/1 episode 11/100 done
215
+ [bench] sweep 1/1 episode 12/100 done
216
+ [bench] sweep 1/1 episode 13/100 done
217
+ [bench] sweep 1/1 episode 14/100 done
218
+ [bench] sweep 1/1 episode 15/100 done
219
+ [bench] sweep 1/1 episode 16/100 done
220
+ [bench] sweep 1/1 episode 17/100 done
221
+ [bench] sweep 1/1 episode 18/100 done
222
+ [bench] sweep 1/1 episode 19/100 done
223
+ [bench] sweep 1/1 episode 20/100 done
224
+ [bench] sweep 1/1 episode 21/100 done
225
+ [bench] sweep 1/1 episode 22/100 done
226
+ [bench] sweep 1/1 episode 23/100 done
227
+ [bench] sweep 1/1 episode 24/100 done
228
+ [bench] sweep 1/1 episode 25/100 done
229
+ [bench] sweep 1/1 episode 26/100 done
230
+ [bench] sweep 1/1 episode 27/100 done
231
+ [bench] sweep 1/1 episode 28/100 done
232
+ [bench] sweep 1/1 episode 29/100 done
233
+ [bench] sweep 1/1 episode 30/100 done
234
+ [bench] sweep 1/1 episode 31/100 done
235
+ [bench] sweep 1/1 episode 32/100 done
236
+ [bench] sweep 1/1 episode 33/100 done
237
+ [bench] sweep 1/1 episode 34/100 done
238
+ [bench] sweep 1/1 episode 35/100 done
239
+ [bench] sweep 1/1 episode 36/100 done
240
+ [bench] sweep 1/1 episode 37/100 done
241
+ [bench] sweep 1/1 episode 38/100 done
242
+ [bench] sweep 1/1 episode 39/100 done
243
+ [bench] sweep 1/1 episode 40/100 done
244
+ [bench] sweep 1/1 episode 41/100 done
245
+ [bench] sweep 1/1 episode 42/100 done
246
+ [bench] sweep 1/1 episode 43/100 done
247
+ [bench] sweep 1/1 episode 44/100 done
248
+ [bench] sweep 1/1 episode 45/100 done
249
+ [bench] sweep 1/1 episode 46/100 done
250
+ [bench] sweep 1/1 episode 47/100 done
251
+ [bench] sweep 1/1 episode 48/100 done
252
+ [bench] sweep 1/1 episode 49/100 done
253
+ [bench] sweep 1/1 episode 50/100 done
254
+ [bench] sweep 1/1 episode 51/100 done
255
+ [bench] sweep 1/1 episode 52/100 done
256
+ [bench] sweep 1/1 episode 53/100 done
257
+ [bench] sweep 1/1 episode 54/100 done
258
+ [bench] sweep 1/1 episode 55/100 done
259
+ [bench] sweep 1/1 episode 56/100 done
260
+ [bench] sweep 1/1 episode 57/100 done
261
+ [bench] sweep 1/1 episode 58/100 done
262
+ [bench] sweep 1/1 episode 59/100 done
263
+ [bench] sweep 1/1 episode 60/100 done
264
+ [bench] sweep 1/1 episode 61/100 done
265
+ [bench] sweep 1/1 episode 62/100 done
266
+ [bench] sweep 1/1 episode 63/100 done
267
+ [bench] sweep 1/1 episode 64/100 done
268
+ [bench] sweep 1/1 episode 65/100 done
269
+ [bench] sweep 1/1 episode 66/100 done
270
+ [bench] sweep 1/1 episode 67/100 done
271
+ [bench] sweep 1/1 episode 68/100 done
272
+ [bench] sweep 1/1 episode 69/100 done
273
+ [bench] sweep 1/1 episode 70/100 done
274
+ [bench] sweep 1/1 episode 71/100 done
275
+ [bench] sweep 1/1 episode 72/100 done
276
+ [bench] sweep 1/1 episode 73/100 done
277
+ [bench] sweep 1/1 episode 74/100 done
278
+ [bench] sweep 1/1 episode 75/100 done
279
+ [bench] sweep 1/1 episode 76/100 done
280
+ [bench] sweep 1/1 episode 77/100 done
281
+ [bench] sweep 1/1 episode 78/100 done
282
+ [bench] sweep 1/1 episode 79/100 done
283
+ [bench] sweep 1/1 episode 80/100 done
284
+ [bench] sweep 1/1 episode 81/100 done
285
+ [bench] sweep 1/1 episode 82/100 done
286
+ [bench] sweep 1/1 episode 83/100 done
287
+ [bench] sweep 1/1 episode 84/100 done
288
+ [bench] sweep 1/1 episode 85/100 done
289
+ [bench] sweep 1/1 episode 86/100 done
290
+ [bench] sweep 1/1 episode 87/100 done
291
+ [bench] sweep 1/1 episode 88/100 done
292
+ [bench] sweep 1/1 episode 89/100 done
293
+ [bench] sweep 1/1 episode 90/100 done
294
+ [bench] sweep 1/1 episode 91/100 done
295
+ [bench] sweep 1/1 episode 92/100 done
296
+ [bench] sweep 1/1 episode 93/100 done
297
+ [bench] sweep 1/1 episode 94/100 done
298
+ [bench] sweep 1/1 episode 95/100 done
299
+ [bench] sweep 1/1 episode 96/100 done
300
+ [bench] sweep 1/1 episode 97/100 done
301
+ [bench] sweep 1/1 episode 98/100 done
302
+ [bench] sweep 1/1 episode 99/100 done
303
+ [bench] sweep 1/1 episode 100/100 done
304
+ [bench] sweep 1/1 complete elapsed=1243.1s
305
+ episode=0 return=1846.110 steps=1000 mean_latency_ms=89.89614608291177
306
+ episode=1 return=2415.721 steps=1000 mean_latency_ms=90.00308114332259
307
+ episode=2 return=457.344 steps=177 mean_latency_ms=89.83716885697598
308
+ episode=3 return=1421.795 steps=1000 mean_latency_ms=89.87909631338808
309
+ episode=4 return=2037.723 steps=937 mean_latency_ms=89.82685347370092
310
+ episode=5 return=2330.630 steps=1000 mean_latency_ms=90.47193606091501
311
+ episode=6 return=1161.644 steps=429 mean_latency_ms=89.84194070141322
312
+ episode=7 return=2351.152 steps=1000 mean_latency_ms=89.92640891799017
313
+ episode=8 return=513.296 steps=210 mean_latency_ms=89.88895656571908
314
+ episode=9 return=1126.865 steps=660 mean_latency_ms=89.91361550654544
315
+ episode=10 return=1693.437 steps=1000 mean_latency_ms=89.84960962337662
316
+ episode=11 return=948.378 steps=1000 mean_latency_ms=89.94678527711802
317
+ episode=12 return=2322.052 steps=1000 mean_latency_ms=90.11873818885832
318
+ episode=13 return=960.403 steps=1000 mean_latency_ms=90.93377411320307
319
+ episode=14 return=1464.564 steps=1000 mean_latency_ms=89.80893705661644
320
+ episode=15 return=1110.549 steps=1000 mean_latency_ms=89.99466844889166
321
+ episode=16 return=2246.208 steps=1000 mean_latency_ms=90.1624262080728
322
+ episode=17 return=85.648 steps=60 mean_latency_ms=89.87005518664785
323
+ episode=18 return=340.548 steps=143 mean_latency_ms=89.94240076131771
324
+ episode=19 return=2457.089 steps=1000 mean_latency_ms=89.92054036086635
325
+ episode=20 return=2166.251 steps=1000 mean_latency_ms=89.95452553058773
326
+ episode=21 return=2357.958 steps=1000 mean_latency_ms=89.86780458600198
327
+ episode=22 return=1654.878 steps=871 mean_latency_ms=90.08433827425095
328
+ episode=23 return=1499.367 steps=1000 mean_latency_ms=89.89663615668341
329
+ episode=24 return=2297.403 steps=1000 mean_latency_ms=90.09818426014289
330
+ episode=25 return=1253.361 steps=543 mean_latency_ms=89.9390124443734
331
+ episode=26 return=1221.270 steps=1000 mean_latency_ms=89.84986177450952
332
+ episode=27 return=2389.248 steps=1000 mean_latency_ms=89.95772586857817
333
+ episode=28 return=1682.529 steps=707 mean_latency_ms=89.76145439054764
334
+ episode=29 return=2474.676 steps=1000 mean_latency_ms=89.82093759631324
335
+ episode=30 return=382.923 steps=256 mean_latency_ms=90.69916524888657
336
+ episode=31 return=1837.813 steps=1000 mean_latency_ms=90.03642087221974
337
+ episode=32 return=227.194 steps=101 mean_latency_ms=89.8553742761573
338
+ episode=33 return=1700.631 steps=1000 mean_latency_ms=89.80097198453268
339
+ episode=34 return=960.945 steps=372 mean_latency_ms=89.8420903148968
340
+ episode=35 return=2290.672 steps=1000 mean_latency_ms=89.91770573449698
341
+ episode=36 return=328.573 steps=162 mean_latency_ms=90.01187187392946
342
+ episode=37 return=1180.074 steps=1000 mean_latency_ms=89.81938304804656
343
+ episode=38 return=817.419 steps=363 mean_latency_ms=89.85140773938038
344
+ episode=39 return=1651.226 steps=1000 mean_latency_ms=91.17610023451576
345
+ episode=40 return=1428.175 steps=1000 mean_latency_ms=89.8551155619885
346
+ episode=41 return=1627.384 steps=1000 mean_latency_ms=90.55986754698809
347
+ episode=42 return=1079.756 steps=680 mean_latency_ms=90.17098553312343
348
+ episode=43 return=2173.945 steps=1000 mean_latency_ms=89.84319301261918
349
+ episode=44 return=409.906 steps=160 mean_latency_ms=89.66802828269809
350
+ episode=45 return=2467.264 steps=1000 mean_latency_ms=89.90844708827387
351
+ episode=46 return=657.408 steps=248 mean_latency_ms=89.86487149424892
352
+ episode=47 return=974.744 steps=1000 mean_latency_ms=89.76305094278182
353
+ episode=48 return=1510.518 steps=1000 mean_latency_ms=90.24355118464125
354
+ episode=49 return=602.234 steps=260 mean_latency_ms=89.7103209703719
355
+ episode=50 return=760.978 steps=316 mean_latency_ms=89.8206829517188
356
+ episode=51 return=1941.172 steps=1000 mean_latency_ms=90.30785204408768
357
+ episode=52 return=624.359 steps=281 mean_latency_ms=89.94582387208622
358
+ episode=53 return=2163.435 steps=1000 mean_latency_ms=89.84848132390947
359
+ episode=54 return=1126.996 steps=1000 mean_latency_ms=89.84637728060243
360
+ episode=55 return=1405.132 steps=1000 mean_latency_ms=90.18855922596491
361
+ episode=56 return=1206.292 steps=1000 mean_latency_ms=89.78065539051504
362
+ episode=57 return=2392.798 steps=1000 mean_latency_ms=89.76388668266138
363
+ episode=58 return=964.022 steps=1000 mean_latency_ms=89.82618651237911
364
+ episode=59 return=2252.193 steps=1000 mean_latency_ms=89.8197082349776
365
+ episode=60 return=2471.916 steps=1000 mean_latency_ms=89.96642568195992
366
+ episode=61 return=1902.849 steps=1000 mean_latency_ms=89.87542708971246
367
+ episode=62 return=1435.666 steps=1000 mean_latency_ms=90.28644124851098
368
+ episode=63 return=1668.324 steps=1000 mean_latency_ms=89.86433221097877
369
+ episode=64 return=1813.291 steps=1000 mean_latency_ms=89.85118001877315
370
+ episode=65 return=446.724 steps=189 mean_latency_ms=89.8309544306309
371
+ episode=66 return=130.842 steps=74 mean_latency_ms=89.82416773165995
372
+ episode=67 return=2315.857 steps=1000 mean_latency_ms=90.25959750757508
373
+ episode=68 return=288.392 steps=116 mean_latency_ms=90.09271984792927
374
+ episode=69 return=894.023 steps=1000 mean_latency_ms=89.89663691508213
375
+ episode=70 return=2030.323 steps=1000 mean_latency_ms=89.84028619017428
376
+ episode=71 return=507.945 steps=215 mean_latency_ms=90.57267432538549
377
+ episode=72 return=2377.737 steps=1000 mean_latency_ms=89.84919425782105
378
+ episode=73 return=897.308 steps=1000 mean_latency_ms=89.90431472264346
379
+ episode=74 return=1454.613 steps=1000 mean_latency_ms=91.19515970740413
380
+ episode=75 return=2292.458 steps=1000 mean_latency_ms=89.8333901030839
381
+ episode=76 return=1424.378 steps=1000 mean_latency_ms=89.88029014661089
382
+ episode=77 return=1441.111 steps=1000 mean_latency_ms=89.79844243631413
383
+ episode=78 return=1265.477 steps=1000 mean_latency_ms=89.86009503143968
384
+ episode=79 return=1662.881 steps=1000 mean_latency_ms=90.5661722205243
385
+ episode=80 return=2508.917 steps=1000 mean_latency_ms=89.87403626041336
386
+ episode=81 return=1655.351 steps=1000 mean_latency_ms=90.05039760075688
387
+ episode=82 return=1387.384 steps=821 mean_latency_ms=90.10235730111886
388
+ episode=83 return=646.436 steps=271 mean_latency_ms=89.7559653760994
389
+ episode=84 return=2172.801 steps=1000 mean_latency_ms=89.84602989356796
390
+ episode=85 return=165.921 steps=72 mean_latency_ms=89.66756877688618
391
+ episode=86 return=1063.148 steps=1000 mean_latency_ms=89.77409215132576
392
+ episode=87 return=1000.135 steps=1000 mean_latency_ms=89.81900933661238
393
+ episode=88 return=1977.236 steps=1000 mean_latency_ms=89.77653862908736
394
+ episode=89 return=1937.167 steps=1000 mean_latency_ms=90.12773943823525
395
+ episode=90 return=1344.773 steps=1000 mean_latency_ms=90.39620143170467
396
+ episode=91 return=786.338 steps=441 mean_latency_ms=89.82893206036925
397
+ episode=92 return=1391.060 steps=1000 mean_latency_ms=89.86676880070257
398
+ episode=93 return=503.300 steps=250 mean_latency_ms=89.94819176115624
399
+ episode=94 return=2446.748 steps=1000 mean_latency_ms=89.84848658183878
400
+ episode=95 return=1171.910 steps=1000 mean_latency_ms=89.92785850220504
401
+ episode=96 return=2356.731 steps=1000 mean_latency_ms=90.42933754946152
402
+ episode=97 return=2356.122 steps=1000 mean_latency_ms=89.82049779117614
403
+ episode=98 return=1389.299 steps=1000 mean_latency_ms=90.82209581044775
404
+ episode=99 return=967.234 steps=1000 mean_latency_ms=89.80016695371027
405
+ summary latency=profile_sample episodes=100 mean_return=1453.844 std_return=693.728 mean_length=803.9
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/REPORT.md ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # QwenOFT mean-trained checkpoints under profile simulation
2
+
3
+ Four final step-5000 H1 checkpoints; two rounds, one evaluation per physical GPU2/3,100 episodes each (400 total).
4
+
5
+ The training latency was fixed mean; this evaluation samples the complete archived RTX3090 temporal hidden-regime profile. Simulator FPS, seeds, horizon, limits and model/profile identities are in evaluation-plan.json. Standard deviations below use ddof=0. Returns have task-specific scales. Startup checks are separate and excluded.
6
+
7
+ | Task | Episodes | Return mean +/- SD | Length mean +/- SD | Success | Invalid |
8
+ |---|---:|---:|---:|---:|---:|
9
+ | flappy | 100 | 384.824005 +/- 116.787774 | 3119.31 +/- 939.87 | not provided by task | 0 |
10
+ | deadly_corridor | 100 | 1620.798776 +/- 913.624278 | 148.53 +/- 49.46 | not provided by task | 0 |
11
+ | ant | 100 | 1453.844064 +/- 693.727520 | 803.85 +/- 328.81 | not provided by task | 0 |
12
+ | intercept | 100 | 3.544349 +/- 7.071923 | 60.00 +/- 0.00 | 9/100 | 0 |
13
+
14
+ No success metric is invented for Flappy/Deadly/Ant. Intercept reports the native accumulated success flag. No policy-quality acceptance gate is claimed.
15
+
16
+ Compatibility repairs: portable robot_type copied from each actual training manifest (weights unchanged); official ViZDoom1.2.4 VizdoomCorridor-v0 uses the same deadly_corridor WAD as SF, preserves render contract and semantic seven-button ordering; public action space is equivalent MultiBinary7. Existing native render/button/history tests passed. Full eval source/patch and original profile assets are archived.
17
+
18
+ Flappy/Deadly seeds1000000..1000099; Ant42..141; Intercept4242424242..4242424341. Latency seed271828. Flappy10/10Hz, Deadly35/8.75Hz, Ant10/10Hz, Intercept20/20Hz. Max raw frames3600/3600/1000/60; capacities1. MIKASA H1 holds last chunk action; no prefix, no DAgger. Ant keeps its training prompt label1 while execution latency is sampled.
19
+
20
+ Raw JSONL logs are losslessly gzip-compressed for distribution; original uncompressed records remain on the experiment host. Empty observation_attempts files are retained; admission/drop evidence is in steps/actions. Per-task CSV and full400 episode CSV are provided.
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/all_episodes.csv ADDED
@@ -0,0 +1,401 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task,episode_id,seed,return_env,length,mean_latency_ms,success
2
+ flappy,0,1000000,444.6000052243471,3600,76.02271694866694,
3
+ flappy,1,1000001,444.6000052243471,3600,76.14445348705047,
4
+ flappy,2,1000002,444.6000052243471,3600,75.83047266244563,
5
+ flappy,3,1000003,444.6000052243471,3600,76.04121221698036,
6
+ flappy,4,1000004,444.6000052243471,3600,75.7789115791707,
7
+ flappy,5,1000005,228.2000027000904,1861,76.22757676162651,
8
+ flappy,6,1000006,444.6000052243471,3600,75.98373978309758,
9
+ flappy,7,1000007,444.6000052243471,3600,75.85552109823348,
10
+ flappy,8,1000008,444.6000052243471,3600,75.9782303085917,
11
+ flappy,9,1000009,444.6000052243471,3600,75.94667987356688,
12
+ flappy,10,1000010,444.6000052243471,3600,75.66396359484234,
13
+ flappy,11,1000011,444.6000052243471,3600,75.7794525026407,
14
+ flappy,12,1000012,444.6000052243471,3600,75.90110110734818,
15
+ flappy,13,1000013,444.6000052243471,3600,76.01870178237883,
16
+ flappy,14,1000014,444.6000052243471,3600,75.75567207010911,
17
+ flappy,15,1000015,444.6000052243471,3600,75.83026036637241,
18
+ flappy,16,1000016,444.6000052243471,3600,75.74502908171665,
19
+ flappy,17,1000017,444.6000052243471,3600,75.84316844302293,
20
+ flappy,18,1000018,444.6000052243471,3600,75.85876738771161,
21
+ flappy,19,1000019,265.50000313669443,2162,75.89492798135642,
22
+ flappy,20,1000020,444.6000052243471,3600,75.90859756288593,
23
+ flappy,21,1000021,444.6000052243471,3600,75.93474621914784,
24
+ flappy,22,1000022,444.6000052243471,3600,75.77022360156529,
25
+ flappy,23,1000023,444.6000052243471,3600,75.8506098974935,
26
+ flappy,24,1000024,444.6000052243471,3600,75.80511776716725,
27
+ flappy,25,1000025,116.00000138580799,955,76.07937915327228,
28
+ flappy,26,1000026,444.6000052243471,3600,75.77409482659607,
29
+ flappy,27,1000027,444.6000052243471,3600,75.82354466933252,
30
+ flappy,28,1000028,444.6000052243471,3600,75.92578714415393,
31
+ flappy,29,1000029,444.6000052243471,3600,75.77326038618416,
32
+ flappy,30,1000030,256.0000030249357,2085,75.8461606092662,
33
+ flappy,31,1000031,444.6000052243471,3600,75.87053786258159,
34
+ flappy,32,1000032,444.6000052243471,3600,75.90930861144982,
35
+ flappy,33,1000033,444.6000052243471,3600,75.80530422686525,
36
+ flappy,34,1000034,444.6000052243471,3600,76.05997569829616,
37
+ flappy,35,1000035,444.6000052243471,3600,75.67579907153437,
38
+ flappy,36,1000036,444.6000052243471,3600,76.07561842170198,
39
+ flappy,37,1000037,444.6000052243471,3600,75.87459102177027,
40
+ flappy,38,1000038,55.60000067949295,468,75.8887188983619,
41
+ flappy,39,1000039,444.6000052243471,3600,75.86536772802552,
42
+ flappy,40,1000040,432.900005094707,3512,76.00355652525975,
43
+ flappy,41,1000041,274.8000032454729,2237,75.7658282850597,
44
+ flappy,42,1000042,264.90000312775373,2156,75.95264956954799,
45
+ flappy,43,1000043,265.4000031352043,2161,75.82748305801191,
46
+ flappy,44,1000044,444.6000052243471,3600,75.9295822845668,
47
+ flappy,45,1000045,143.90000171214342,1180,75.94310218110371,
48
+ flappy,46,1000046,444.6000052243471,3600,75.69568531179425,
49
+ flappy,47,1000047,93.1000011190772,771,76.0527875505066,
50
+ flappy,48,1000048,56.10000068694353,473,76.20882901957174,
51
+ flappy,49,1000049,265.2000031322241,2159,76.05401077635972,
52
+ flappy,50,1000050,444.6000052243471,3600,75.89333271844873,
53
+ flappy,51,1000051,444.6000052243471,3600,75.89090159365671,
54
+ flappy,52,1000052,398.80000469088554,3234,75.91218218803246,
55
+ flappy,53,1000053,444.6000052243471,3600,75.86400590251726,
56
+ flappy,54,1000054,270.2000031918287,2200,76.01590238337654,
57
+ flappy,55,1000055,69.70000084489584,582,75.68422480575155,
58
+ flappy,56,1000056,444.6000052243471,3600,75.87884524455251,
59
+ flappy,57,1000057,444.6000052243471,3600,75.96981187494319,
60
+ flappy,58,1000058,444.6000052243471,3600,76.03772455115222,
61
+ flappy,59,1000059,437.90000515431166,3553,76.04088529786887,
62
+ flappy,60,1000060,348.9000041112304,2834,75.79422825165413,
63
+ flappy,61,1000061,444.6000052243471,3600,75.87728099437057,
64
+ flappy,62,1000062,78.9000009521842,656,75.96352981662133,
65
+ flappy,63,1000063,444.6000052243471,3600,75.80269270184165,
66
+ flappy,64,1000064,444.6000052243471,3600,75.88518180564401,
67
+ flappy,65,1000065,444.6000052243471,3600,75.87533034544981,
68
+ flappy,66,1000066,444.6000052243471,3600,75.94241138050401,
69
+ flappy,67,1000067,444.6000052243471,3600,75.95312277771471,
70
+ flappy,68,1000068,444.6000052243471,3600,75.8998829764233,
71
+ flappy,69,1000069,444.6000052243471,3600,75.98564617573034,
72
+ flappy,70,1000070,444.6000052243471,3600,75.68328575087021,
73
+ flappy,71,1000071,135.0000016093254,1109,75.99546963217229,
74
+ flappy,72,1000072,444.6000052243471,3600,75.9923106611263,
75
+ flappy,73,1000073,444.6000052243471,3600,75.80422251719546,
76
+ flappy,74,1000074,444.6000052243471,3600,75.95469853250815,
77
+ flappy,75,1000075,444.6000052243471,3600,75.74551875442629,
78
+ flappy,76,1000076,444.6000052243471,3600,75.93301571087362,
79
+ flappy,77,1000077,444.6000052243471,3600,75.98384926019328,
80
+ flappy,78,1000078,444.6000052243471,3600,75.85055115368883,
81
+ flappy,79,1000079,444.6000052243471,3600,75.97142616222317,
82
+ flappy,80,1000080,444.6000052243471,3600,75.97039764106849,
83
+ flappy,81,1000081,444.6000052243471,3600,75.74469321422862,
84
+ flappy,82,1000082,116.20000138878822,957,76.0366526049804,
85
+ flappy,83,1000083,444.6000052243471,3600,75.95924386190674,
86
+ flappy,84,1000084,444.6000052243471,3600,76.0310580385874,
87
+ flappy,85,1000085,36.60000045597553,314,75.8634823847272,
88
+ flappy,86,1000086,260.90000308305025,2125,75.91783880059099,
89
+ flappy,87,1000087,444.6000052243471,3600,76.16752514785735,
90
+ flappy,88,1000088,444.6000052243471,3600,75.83331254385584,
91
+ flappy,89,1000089,444.6000052243471,3600,76.2113387300584,
92
+ flappy,90,1000090,444.6000052243471,3600,75.8334932097261,
93
+ flappy,91,1000091,225.20000265538692,1831,75.75618859671614,
94
+ flappy,92,1000092,444.6000052243471,3600,75.79683788505955,
95
+ flappy,93,1000093,180.9000021442771,1478,75.96465307644473,
96
+ flappy,94,1000094,305.2000035941601,2478,75.86565754734926,
97
+ flappy,95,1000095,444.6000052243471,3600,75.74523644464854,
98
+ flappy,96,1000096,444.6000052243471,3600,75.94353591524424,
99
+ flappy,97,1000097,444.6000052243471,3600,75.81927739599219,
100
+ flappy,98,1000098,444.6000052243471,3600,75.96229410618645,
101
+ flappy,99,1000099,444.6000052243471,3600,75.94512877548694,
102
+ deadly_corridor,0,1000000,337.47547912597656,72,71.90727374040254,
103
+ deadly_corridor,1,1000001,819.0284423828125,143,73.84762082340946,
104
+ deadly_corridor,2,1000002,2284.857650756836,182,72.79171012339609,
105
+ deadly_corridor,3,1000003,2276.2068634033203,189,76.345275285376,
106
+ deadly_corridor,4,1000004,805.2153015136719,150,73.86282581373551,
107
+ deadly_corridor,5,1000005,621.8231658935547,115,74.31105893586228,
108
+ deadly_corridor,6,1000006,2276.414749145508,176,74.2226331369995,
109
+ deadly_corridor,7,1000007,2284.310989379883,176,72.9072057957754,
110
+ deadly_corridor,8,1000008,81.07798767089844,49,73.20258272646697,
111
+ deadly_corridor,9,1000009,317.2351837158203,75,72.54774919154028,
112
+ deadly_corridor,10,1000010,2282.7608489990234,176,72.78293151689127,
113
+ deadly_corridor,11,1000011,88.11907958984375,45,72.60486105128022,
114
+ deadly_corridor,12,1000012,2281.468536376953,176,72.29193331603048,
115
+ deadly_corridor,13,1000013,2276.6868591308594,178,72.73330265771509,
116
+ deadly_corridor,14,1000014,2276.1705932617188,178,73.30067987408609,
117
+ deadly_corridor,15,1000015,2282.6631622314453,177,72.49405489224537,
118
+ deadly_corridor,16,1000016,2280.300033569336,172,72.80884970803692,
119
+ deadly_corridor,17,1000017,2280.4182891845703,182,73.03539182090206,
120
+ deadly_corridor,18,1000018,2281.2594451904297,177,72.50972089313564,
121
+ deadly_corridor,19,1000019,479.8523712158203,99,72.58046231642126,
122
+ deadly_corridor,20,1000020,2279.7379455566406,181,72.47468246266928,
123
+ deadly_corridor,21,1000021,2284.9097442626953,197,83.18983231769475,
124
+ deadly_corridor,22,1000022,2286.2730407714844,172,72.84281562147524,
125
+ deadly_corridor,23,1000023,244.51919555664062,74,76.23461799191558,
126
+ deadly_corridor,24,1000024,2279.957275390625,195,72.94927214021655,
127
+ deadly_corridor,25,1000025,2283.952178955078,179,73.18968843008061,
128
+ deadly_corridor,26,1000026,2276.701370239258,178,72.87702909462648,
129
+ deadly_corridor,27,1000027,2277.142562866211,190,72.45412386128042,
130
+ deadly_corridor,28,1000028,2279.025634765625,177,74.11102172804317,
131
+ deadly_corridor,29,1000029,2285.7152099609375,177,71.63189230597281,
132
+ deadly_corridor,30,1000030,53.374298095703125,44,72.51418721312025,
133
+ deadly_corridor,31,1000031,2279.8080444335938,183,72.72702656843174,
134
+ deadly_corridor,32,1000032,2282.307357788086,178,74.33584751930213,
135
+ deadly_corridor,33,1000033,2282.834014892578,192,73.95005063555192,
136
+ deadly_corridor,34,1000034,2284.200241088867,188,76.29368894499888,
137
+ deadly_corridor,35,1000035,2287.2159118652344,179,72.81890806090988,
138
+ deadly_corridor,36,1000036,2284.693832397461,183,76.28284599973325,
139
+ deadly_corridor,37,1000037,2283.2066650390625,178,72.1797344044525,
140
+ deadly_corridor,38,1000038,2281.032196044922,178,73.74343783824916,
141
+ deadly_corridor,39,1000039,2282.960678100586,190,73.24816830891406,
142
+ deadly_corridor,40,1000040,2287.094253540039,185,72.35711232966574,
143
+ deadly_corridor,41,1000041,2279.3030853271484,179,72.42125368367608,
144
+ deadly_corridor,42,1000042,440.0892791748047,104,73.92064892672727,
145
+ deadly_corridor,43,1000043,2280.8592529296875,177,72.36020918178356,
146
+ deadly_corridor,44,1000044,2283.4308471679688,189,75.93658060557208,
147
+ deadly_corridor,45,1000045,2282.324264526367,181,73.54224681770178,
148
+ deadly_corridor,46,1000046,326.0184631347656,74,73.1983876441008,
149
+ deadly_corridor,47,1000047,2279.086135864258,182,73.00958120503027,
150
+ deadly_corridor,48,1000048,2280.3804626464844,179,73.17268244992928,
151
+ deadly_corridor,49,1000049,2276.215301513672,189,75.47590644230628,
152
+ deadly_corridor,50,1000050,2278.132034301758,182,74.50495464842548,
153
+ deadly_corridor,51,1000051,2285.6056518554688,181,73.41699294418743,
154
+ deadly_corridor,52,1000052,2287.240921020508,173,73.22110809114655,
155
+ deadly_corridor,53,1000053,310.81517028808594,73,74.09003681120738,
156
+ deadly_corridor,54,1000054,2276.6219787597656,175,72.98605010243534,
157
+ deadly_corridor,55,1000055,2276.2769470214844,194,75.17704077845171,
158
+ deadly_corridor,56,1000056,2278.861602783203,178,72.97353037051572,
159
+ deadly_corridor,57,1000057,2279.728561401367,181,73.96913002154926,
160
+ deadly_corridor,58,1000058,2280.544464111328,176,73.02432805290651,
161
+ deadly_corridor,59,1000059,487.829833984375,108,78.89398217393664,
162
+ deadly_corridor,60,1000060,567.0655517578125,113,72.64874721482185,
163
+ deadly_corridor,61,1000061,2278.210220336914,177,72.96068484971086,
164
+ deadly_corridor,62,1000062,2281.436721801758,186,75.46710866924751,
165
+ deadly_corridor,63,1000063,382.2119903564453,89,81.21157315209366,
166
+ deadly_corridor,64,1000064,246.2946014404297,70,73.9736408486285,
167
+ deadly_corridor,65,1000065,285.21240234375,76,73.13661133681993,
168
+ deadly_corridor,66,1000066,310.6737365722656,75,73.40468658737086,
169
+ deadly_corridor,67,1000067,346.1162872314453,75,72.1929723632303,
170
+ deadly_corridor,68,1000068,804.7056121826172,150,73.76397959753224,
171
+ deadly_corridor,69,1000069,2285.6442108154297,184,75.13255757158333,
172
+ deadly_corridor,70,1000070,730.5995788574219,132,73.25446825350764,
173
+ deadly_corridor,71,1000071,86.91796875,47,76.28335745963689,
174
+ deadly_corridor,72,1000072,60.30122375488281,44,76.83513093208644,
175
+ deadly_corridor,73,1000073,768.6264343261719,141,77.27057350071598,
176
+ deadly_corridor,74,1000074,2280.1071166992188,172,74.16699734355548,
177
+ deadly_corridor,75,1000075,860.9334106445312,151,73.15118478347584,
178
+ deadly_corridor,76,1000076,722.9459228515625,143,75.5655785931314,
179
+ deadly_corridor,77,1000077,2276.8687438964844,182,72.95102474014934,
180
+ deadly_corridor,78,1000078,368.3357238769531,79,71.51096709276341,
181
+ deadly_corridor,79,1000079,-76.45918273925781,17,72.24888432102617,
182
+ deadly_corridor,80,1000080,2281.5543823242188,183,73.32589540463356,
183
+ deadly_corridor,81,1000081,2281.6688842773438,171,73.10600900440717,
184
+ deadly_corridor,82,1000082,2277.5223083496094,178,73.55648700566698,
185
+ deadly_corridor,83,1000083,42.30937194824219,41,73.52700344736942,
186
+ deadly_corridor,84,1000084,2285.8980407714844,176,71.98655161011203,
187
+ deadly_corridor,85,1000085,68.90191650390625,45,72.84773487604696,
188
+ deadly_corridor,86,1000086,2286.2190551757812,171,72.82303966497733,
189
+ deadly_corridor,87,1000087,281.1173553466797,76,72.26983276661764,
190
+ deadly_corridor,88,1000088,2283.1607971191406,175,73.49638264342678,
191
+ deadly_corridor,89,1000089,2277.888946533203,177,73.44736473371472,
192
+ deadly_corridor,90,1000090,429.36326599121094,93,71.86172378947977,
193
+ deadly_corridor,91,1000091,252.0751953125,70,72.26459581736903,
194
+ deadly_corridor,92,1000092,2278.306442260742,192,80.97328482778371,
195
+ deadly_corridor,93,1000093,2285.236801147461,175,74.02717585214627,
196
+ deadly_corridor,94,1000094,857.2727355957031,152,85.59110000526613,
197
+ deadly_corridor,95,1000095,2275.9288024902344,199,73.62958803645523,
198
+ deadly_corridor,96,1000096,2286.8704833984375,179,72.31519682456816,
199
+ deadly_corridor,97,1000097,2278.048355102539,181,73.50330330803081,
200
+ deadly_corridor,98,1000098,2277.4480743408203,178,76.78472725777,
201
+ deadly_corridor,99,1000099,2276.9671478271484,178,77.9678189026336,
202
+ ant,0,42,1846.1103431567394,1000,89.89614608291177,
203
+ ant,1,43,2415.720790707953,1000,90.00308114332259,
204
+ ant,2,44,457.34421085068755,177,89.83716885697598,
205
+ ant,3,45,1421.7952163289683,1000,89.87909631338808,
206
+ ant,4,46,2037.7234409469488,937,89.82685347370092,
207
+ ant,5,47,2330.630175869275,1000,90.47193606091501,
208
+ ant,6,48,1161.643572255748,429,89.84194070141322,
209
+ ant,7,49,2351.1524624990343,1000,89.92640891799017,
210
+ ant,8,50,513.2964809479813,210,89.88895656571908,
211
+ ant,9,51,1126.8652528911032,660,89.91361550654544,
212
+ ant,10,52,1693.436933192597,1000,89.84960962337662,
213
+ ant,11,53,948.3780972955639,1000,89.94678527711802,
214
+ ant,12,54,2322.052445211472,1000,90.11873818885832,
215
+ ant,13,55,960.4026770814776,1000,90.93377411320307,
216
+ ant,14,56,1464.564005196777,1000,89.80893705661644,
217
+ ant,15,57,1110.548792782156,1000,89.99466844889166,
218
+ ant,16,58,2246.207900740156,1000,90.1624262080728,
219
+ ant,17,59,85.64836938561511,60,89.87005518664785,
220
+ ant,18,60,340.54799067574436,143,89.94240076131771,
221
+ ant,19,61,2457.088748930458,1000,89.92054036086635,
222
+ ant,20,62,2166.2512677098603,1000,89.95452553058773,
223
+ ant,21,63,2357.957592244385,1000,89.86780458600198,
224
+ ant,22,64,1654.8780938737275,871,90.08433827425095,
225
+ ant,23,65,1499.367100151414,1000,89.89663615668341,
226
+ ant,24,66,2297.4032619179525,1000,90.09818426014289,
227
+ ant,25,67,1253.360764666355,543,89.9390124443734,
228
+ ant,26,68,1221.270312709775,1000,89.84986177450952,
229
+ ant,27,69,2389.2476464763376,1000,89.95772586857817,
230
+ ant,28,70,1682.5290233886233,707,89.76145439054764,
231
+ ant,29,71,2474.676425615127,1000,89.82093759631324,
232
+ ant,30,72,382.9231146443659,256,90.69916524888657,
233
+ ant,31,73,1837.8126619276347,1000,90.03642087221974,
234
+ ant,32,74,227.19436616673684,101,89.8553742761573,
235
+ ant,33,75,1700.6312067622644,1000,89.80097198453268,
236
+ ant,34,76,960.9452812639541,372,89.8420903148968,
237
+ ant,35,77,2290.6720141359438,1000,89.91770573449698,
238
+ ant,36,78,328.5729178056416,162,90.01187187392946,
239
+ ant,37,79,1180.073938772476,1000,89.81938304804656,
240
+ ant,38,80,817.4190215442345,363,89.85140773938038,
241
+ ant,39,81,1651.2255208727013,1000,91.17610023451576,
242
+ ant,40,82,1428.174672693164,1000,89.8551155619885,
243
+ ant,41,83,1627.3838925098842,1000,90.55986754698809,
244
+ ant,42,84,1079.756369746183,680,90.17098553312343,
245
+ ant,43,85,2173.9447393037276,1000,89.84319301261918,
246
+ ant,44,86,409.90633829945847,160,89.66802828269809,
247
+ ant,45,87,2467.2636019929073,1000,89.90844708827387,
248
+ ant,46,88,657.4084558813478,248,89.86487149424892,
249
+ ant,47,89,974.7436031610902,1000,89.76305094278182,
250
+ ant,48,90,1510.5184342975385,1000,90.24355118464125,
251
+ ant,49,91,602.2339441184535,260,89.7103209703719,
252
+ ant,50,92,760.9784375126189,316,89.8206829517188,
253
+ ant,51,93,1941.172113330597,1000,90.30785204408768,
254
+ ant,52,94,624.3590446196446,281,89.94582387208622,
255
+ ant,53,95,2163.4347041279893,1000,89.84848132390947,
256
+ ant,54,96,1126.9957963444238,1000,89.84637728060243,
257
+ ant,55,97,1405.131632695366,1000,90.18855922596491,
258
+ ant,56,98,1206.2916757636292,1000,89.78065539051504,
259
+ ant,57,99,2392.7980761515178,1000,89.76388668266138,
260
+ ant,58,100,964.0216541467705,1000,89.82618651237911,
261
+ ant,59,101,2252.192880003706,1000,89.8197082349776,
262
+ ant,60,102,2471.9158497657563,1000,89.96642568195992,
263
+ ant,61,103,1902.8491241623092,1000,89.87542708971246,
264
+ ant,62,104,1435.6661382989703,1000,90.28644124851098,
265
+ ant,63,105,1668.3237703695809,1000,89.86433221097877,
266
+ ant,64,106,1813.291243529155,1000,89.85118001877315,
267
+ ant,65,107,446.72353548541076,189,89.8309544306309,
268
+ ant,66,108,130.84194814079504,74,89.82416773165995,
269
+ ant,67,109,2315.857153770824,1000,90.25959750757508,
270
+ ant,68,110,288.3915792961347,116,90.09271984792927,
271
+ ant,69,111,894.0228631227924,1000,89.89663691508213,
272
+ ant,70,112,2030.322535823717,1000,89.84028619017428,
273
+ ant,71,113,507.9449555916754,215,90.57267432538549,
274
+ ant,72,114,2377.7373967468293,1000,89.84919425782105,
275
+ ant,73,115,897.3077114027096,1000,89.90431472264346,
276
+ ant,74,116,1454.612590266188,1000,91.19515970740413,
277
+ ant,75,117,2292.457960175467,1000,89.8333901030839,
278
+ ant,76,118,1424.378337790017,1000,89.88029014661089,
279
+ ant,77,119,1441.1111023164538,1000,89.79844243631413,
280
+ ant,78,120,1265.4771503717611,1000,89.86009503143968,
281
+ ant,79,121,1662.8808067819505,1000,90.5661722205243,
282
+ ant,80,122,2508.917122342891,1000,89.87403626041336,
283
+ ant,81,123,1655.3510139158748,1000,90.05039760075688,
284
+ ant,82,124,1387.3843721247736,821,90.10235730111886,
285
+ ant,83,125,646.4356689469432,271,89.7559653760994,
286
+ ant,84,126,2172.801064037805,1000,89.84602989356796,
287
+ ant,85,127,165.9213897970373,72,89.66756877688618,
288
+ ant,86,128,1063.1483912161111,1000,89.77409215132576,
289
+ ant,87,129,1000.135342286622,1000,89.81900933661238,
290
+ ant,88,130,1977.2359176146426,1000,89.77653862908736,
291
+ ant,89,131,1937.1674235355138,1000,90.12773943823525,
292
+ ant,90,132,1344.7729257831547,1000,90.39620143170467,
293
+ ant,91,133,786.3379828975102,441,89.82893206036925,
294
+ ant,92,134,1391.060299752017,1000,89.86676880070257,
295
+ ant,93,135,503.300235688713,250,89.94819176115624,
296
+ ant,94,136,2446.7482357041768,1000,89.84848658183878,
297
+ ant,95,137,1171.9102336514923,1000,89.92785850220504,
298
+ ant,96,138,2356.7311711183065,1000,90.42933754946152,
299
+ ant,97,139,2356.12199478712,1000,89.82049779117614,
300
+ ant,98,140,1389.2987977192308,1000,90.82209581044775,
301
+ ant,99,141,967.2335383727841,1000,89.80016695371027,
302
+ intercept,0,4242424242,0.7267571190313902,60,99.89614420497905,0.0
303
+ intercept,1,4242424243,2.9096362272975966,60,99.91707940536706,0.0
304
+ intercept,2,4242424244,3.2060351513209753,60,97.78809018716221,0.0
305
+ intercept,3,4242424245,0.7574528902187012,60,98.54894447730877,0.0
306
+ intercept,4,4242424246,0.6827895979695313,60,99.11745353519741,0.0
307
+ intercept,5,4242424247,29.923812823486514,60,99.04064156549293,1.0
308
+ intercept,6,4242424248,0.7661087726592086,60,98.25342313549518,0.0
309
+ intercept,7,4242424249,0.8284444468154106,60,97.98431264506286,0.0
310
+ intercept,8,4242424250,0.9707721562881488,60,99.10671115977826,0.0
311
+ intercept,9,4242424251,1.0944434545235708,60,99.10142489904808,0.0
312
+ intercept,10,4242424252,0.7526731102407211,60,98.24263629181895,0.0
313
+ intercept,11,4242424253,1.0327306617691647,60,99.90610126116793,0.0
314
+ intercept,12,4242424254,24.08529434411321,60,99.04964452767656,1.0
315
+ intercept,13,4242424255,0.8258126199943945,60,99.06333184347895,0.0
316
+ intercept,14,4242424256,0.6465023508935701,60,99.96017435988418,0.0
317
+ intercept,15,4242424257,1.2059930491086561,60,99.07293754243183,0.0
318
+ intercept,16,4242424258,0.8975468523567542,60,99.10975490804557,0.0
319
+ intercept,17,4242424259,0.638558203499997,60,99.9008234011206,0.0
320
+ intercept,18,4242424260,2.473904824233614,60,99.1007534285042,0.0
321
+ intercept,19,4242424261,0.8594156300532632,60,98.2804424689215,0.0
322
+ intercept,20,4242424262,0.7127419076277874,60,97.42140552034121,0.0
323
+ intercept,21,4242424263,1.1195833964738995,60,99.05356389575846,0.0
324
+ intercept,22,4242424264,1.4589147588121705,60,99.10476263429966,0.0
325
+ intercept,23,4242424265,22.348254217096837,60,98.14243140713285,1.0
326
+ intercept,24,4242424266,27.43761277961312,60,99.03063235183511,1.0
327
+ intercept,25,4242424267,0.797963114338927,60,98.95851806063928,0.0
328
+ intercept,26,4242424268,0.6415987604705151,60,99.1202532952496,0.0
329
+ intercept,27,4242424269,1.502438226743834,60,99.8369766656745,0.0
330
+ intercept,28,4242424270,1.277322537265718,60,99.13638822823135,0.0
331
+ intercept,29,4242424271,0.6413188653605175,60,99.8165233572777,0.0
332
+ intercept,30,4242424272,26.015227647672873,60,99.93359984997578,1.0
333
+ intercept,31,4242424273,0.7568511647114065,60,98.29798580223347,0.0
334
+ intercept,32,4242424274,0.7758818510046694,60,95.9119617819155,0.0
335
+ intercept,33,4242424275,0.743274000211386,60,99.16579733811342,0.0
336
+ intercept,34,4242424276,0.9812663898337632,60,99.96913332715677,0.0
337
+ intercept,35,4242424277,0.7364500367548317,60,98.4144170848438,0.0
338
+ intercept,36,4242424278,0.7676261149172205,60,99.87913624991887,0.0
339
+ intercept,37,4242424279,2.6105462690466084,60,99.0124647390605,0.0
340
+ intercept,38,4242424280,0.8922563010128215,60,99.49582641131909,0.0
341
+ intercept,39,4242424281,0.7909053032053635,60,99.95776157301488,0.0
342
+ intercept,40,4242424282,27.747763212013524,60,99.89232705853966,1.0
343
+ intercept,41,4242424283,2.830903574009426,60,99.11182141335861,0.0
344
+ intercept,42,4242424284,3.749473527306691,60,99.89401411987875,0.0
345
+ intercept,43,4242424285,3.2371535471174866,60,98.58941395009701,0.0
346
+ intercept,44,4242424286,1.141169616690604,60,98.95023432158384,0.0
347
+ intercept,45,4242424287,1.2504711685760412,60,99.8783128676535,0.0
348
+ intercept,46,4242424288,1.1401455145678483,60,99.09364640302553,0.0
349
+ intercept,47,4242424289,1.1743367564631626,60,98.24703755640672,0.0
350
+ intercept,48,4242424290,0.6911400489043444,60,98.98847807253395,0.0
351
+ intercept,49,4242424291,0.966755291854497,60,98.31297463384391,0.0
352
+ intercept,50,4242424292,3.7725237559643574,60,98.1307167401627,0.0
353
+ intercept,51,4242424293,0.7292428385990206,60,99.08520847604322,0.0
354
+ intercept,52,4242424294,2.733719722367823,60,99.8949988335446,0.0
355
+ intercept,53,4242424295,2.7277548569836654,60,99.16542541107671,0.0
356
+ intercept,54,4242424296,0.8013565168366767,60,98.2801475641182,0.0
357
+ intercept,55,4242424297,0.9918300381395966,60,98.74883429246843,0.0
358
+ intercept,56,4242424298,3.8384227409260347,60,98.30485570834159,0.0
359
+ intercept,57,4242424299,2.525593837024644,60,99.08211861473346,0.0
360
+ intercept,58,4242424300,1.1939986812940333,60,99.95562586586023,0.0
361
+ intercept,59,4242424301,1.1946645161951892,60,99.11887142756973,0.0
362
+ intercept,60,4242424302,0.6632764584392135,60,99.92733404817194,0.0
363
+ intercept,61,4242424303,0.7345126099826302,60,99.61093201950378,0.0
364
+ intercept,62,4242424304,1.1547945403144695,60,98.88382479344455,0.0
365
+ intercept,63,4242424305,1.0395031699445099,60,99.10455669644611,0.0
366
+ intercept,64,4242424306,2.7713681719324086,60,99.99607387713222,0.0
367
+ intercept,65,4242424307,3.8083399715833366,60,99.90908449191997,0.0
368
+ intercept,66,4242424308,3.1245881704380736,60,99.86388390473627,0.0
369
+ intercept,67,4242424309,0.9936205917911138,60,99.06530098425861,0.0
370
+ intercept,68,4242424310,0.6479002644773573,60,97.31661851374615,0.0
371
+ intercept,69,4242424311,1.09404552471824,60,99.06482130667098,0.0
372
+ intercept,70,4242424312,0.725047086874838,60,99.39714496924636,0.0
373
+ intercept,71,4242424313,2.085218493710272,60,99.91926924929075,0.0
374
+ intercept,72,4242424314,25.112157980707707,60,99.89495984140663,1.0
375
+ intercept,73,4242424315,0.7960666966973804,60,99.91315720008677,0.0
376
+ intercept,74,4242424316,1.8899870013119653,60,99.8635479883608,0.0
377
+ intercept,75,4242424317,24.77215793245705,60,99.08978442272605,1.0
378
+ intercept,76,4242424318,0.763190906640375,60,99.1181927131107,0.0
379
+ intercept,77,4242424319,0.8356004936795216,60,98.87472332915829,0.0
380
+ intercept,78,4242424320,24.543561146681895,60,98.85109478338812,1.0
381
+ intercept,79,4242424321,0.7962639288743958,60,96.64267992061197,0.0
382
+ intercept,80,4242424322,0.6807828926102957,60,98.70551839611774,0.0
383
+ intercept,81,4242424323,1.1704122956143692,60,99.1162675413269,0.0
384
+ intercept,82,4242424324,0.8024117537715938,60,99.10984056283594,0.0
385
+ intercept,83,4242424325,1.0154686415335163,60,99.90653765962175,0.0
386
+ intercept,84,4242424326,0.6267238368745893,60,99.14313411902761,0.0
387
+ intercept,85,4242424327,1.1180786813492887,60,99.87378109642233,0.0
388
+ intercept,86,4242424328,1.0531825890648179,60,99.90759275984404,0.0
389
+ intercept,87,4242424329,0.7319892354425974,60,99.07934787032669,0.0
390
+ intercept,88,4242424330,1.1460731038823724,60,98.32584786308246,0.0
391
+ intercept,89,4242424331,1.145515855285339,60,99.853580446333,0.0
392
+ intercept,90,4242424332,3.1438898412743583,60,98.23875463665809,0.0
393
+ intercept,91,4242424333,1.1678254807484336,60,99.94300368083988,0.0
394
+ intercept,92,4242424334,1.1468605129048228,60,98.28856657896678,0.0
395
+ intercept,93,4242424335,2.816772125195712,60,99.10609232867152,0.0
396
+ intercept,94,4242424336,1.1577836629003286,60,99.93574594730708,0.0
397
+ intercept,95,4242424337,1.0533778404060286,60,99.92123883389186,0.0
398
+ intercept,96,4242424338,0.8533297177054919,60,99.06174133027585,0.0
399
+ intercept,97,4242424339,0.7617567333800253,60,99.95316521359209,0.0
400
+ intercept,98,4242424340,0.9895546428160742,60,99.11385213912092,0.0
401
+ intercept,99,4242424341,0.770722996792756,60,99.44169788411487,0.0
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/comparison.csv ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ task,episodes,return_mean,return_sd,length_mean,length_sd,success_count,success_rate,invalid_actions,dropped_actions
2
+ flappy,100,384.8240045265853,116.78777394316903,3119.31,939.8693174585497,,,0,64
3
+ deadly_corridor,100,1620.7987757873534,913.6242782186637,148.53,49.455930888013825,,,0,0
4
+ ant,100,1453.844063807972,693.7275200567642,803.85,328.8088312378486,,,0,0
5
+ intercept,100,3.5443485127069287,7.07192296411853,60.0,0.0,9,0.09,0,10
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/comparison.json ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "condition": "profile-latency",
3
+ "executor_mode": "simulated",
4
+ "latency_method": "temporal/profile_sample",
5
+ "episodes_per_checkpoint": 100,
6
+ "total_episodes": 400,
7
+ "checkpoints_metadata_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
8
+ "results": {
9
+ "flappy": {
10
+ "n_episodes": 100,
11
+ "mean_return": 384.8240045265853,
12
+ "std_return": 116.78777394316903,
13
+ "min_return": 36.60000045597553,
14
+ "max_return": 444.6000052243471,
15
+ "mean_length": 3119.31,
16
+ "std_length": 939.8693174585497,
17
+ "min_length": 314.0,
18
+ "max_length": 3600.0,
19
+ "return_field": "episode_return_env",
20
+ "length_field": "survival_steps",
21
+ "mode": "simulated",
22
+ "policy_id": "starvla",
23
+ "env_id": "flappy",
24
+ "model_id": "openvla",
25
+ "gpu_class": "1x-rtx3090",
26
+ "workload_id": "flappy",
27
+ "instance_id": "instance_a5037b165aa0cedc",
28
+ "source_run_id": "20260914T122201421825Z",
29
+ "profile_ref": null,
30
+ "env_fps": 10.0,
31
+ "obs_fps": 10.0,
32
+ "frame_ms": 100.0,
33
+ "latency_type": "profile_sample",
34
+ "task": "flappy",
35
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
36
+ "checkpoint_path": "latency-aware/flappy/vla/starvla-qwenoft-h1/flappy-qwenoft-mean-3090-s42",
37
+ "profile_sha256": "c266cba7ebac05c7e37bc83f1f16fe4b27dab97942ff43290e6c41514f6e39fc",
38
+ "condition": "profile-latency",
39
+ "invalid_actions": 0,
40
+ "dropped_actions": 64,
41
+ "unique_seeds": 100,
42
+ "physical_gpu": 2,
43
+ "eval_config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/flappy.yaml",
44
+ "execution_audit": {
45
+ "issued_action_records": 311075,
46
+ "applied_action_records": 310911,
47
+ "dropped_action_records": 64,
48
+ "nonnoop_issued_records": 30817,
49
+ "finite_action_values": true,
50
+ "latency_sample_count": 311075,
51
+ "latency_mean_ms": 75.89784633675906,
52
+ "latency_std_ms": 3.799946378622932,
53
+ "latency_p95_ms": 81.3960393048375,
54
+ "latency_p99_ms": 87.23844517488543
55
+ }
56
+ },
57
+ "deadly_corridor": {
58
+ "n_episodes": 100,
59
+ "mean_return": 1620.7987757873534,
60
+ "std_return": 913.6242782186637,
61
+ "min_return": -76.45918273925781,
62
+ "max_return": 2287.240921020508,
63
+ "mean_length": 148.53,
64
+ "std_length": 49.455930888013825,
65
+ "min_length": 17.0,
66
+ "max_length": 199.0,
67
+ "return_field": "episode_return_env",
68
+ "length_field": "survival_steps",
69
+ "mode": "simulated",
70
+ "policy_id": "starvla",
71
+ "env_id": "doom_deadly_corridor",
72
+ "model_id": "openvla",
73
+ "gpu_class": "1x-rtx3090",
74
+ "workload_id": "deadly_corridor",
75
+ "instance_id": "instance_a5037b165aa0cedc",
76
+ "source_run_id": "20260914T171446047509Z",
77
+ "profile_ref": null,
78
+ "env_fps": 35.0,
79
+ "obs_fps": 8.75,
80
+ "frame_ms": 28.571428571428573,
81
+ "latency_type": "profile_sample",
82
+ "task": "deadly_corridor",
83
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
84
+ "checkpoint_path": "latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42",
85
+ "profile_sha256": "bbfb93cef9f63750a9a159ec10a93a9fc6c25e4cb0cac3b39532663b4dc11eba",
86
+ "condition": "profile-latency",
87
+ "invalid_actions": 0,
88
+ "dropped_actions": 0,
89
+ "unique_seeds": 100,
90
+ "physical_gpu": 3,
91
+ "eval_config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/deadly_corridor.yaml",
92
+ "execution_audit": {
93
+ "issued_action_records": 3753,
94
+ "applied_action_records": 3673,
95
+ "dropped_action_records": 0,
96
+ "nonnoop_issued_records": 3753,
97
+ "finite_action_values": true,
98
+ "latency_sample_count": 3753,
99
+ "latency_mean_ms": 74.01999621872471,
100
+ "latency_std_ms": 5.5537519652567635,
101
+ "latency_p95_ms": 89.54825982614612,
102
+ "latency_p99_ms": 95.97310052501227
103
+ }
104
+ },
105
+ "ant": {
106
+ "n_episodes": 100,
107
+ "mean_return": 1453.844063807972,
108
+ "std_return": 693.7275200567642,
109
+ "min_return": 85.64836938561511,
110
+ "max_return": 2508.917122342891,
111
+ "mean_length": 803.85,
112
+ "std_length": 328.8088312378486,
113
+ "min_length": 60.0,
114
+ "max_length": 1000.0,
115
+ "return_field": "episode_return_env",
116
+ "length_field": "survival_steps",
117
+ "mode": "simulated",
118
+ "policy_id": "starvla",
119
+ "env_id": "LatencyBench/AntContinuous-v0",
120
+ "model_id": "qwenoft",
121
+ "gpu_class": "1x-rtx3090",
122
+ "workload_id": "ant",
123
+ "instance_id": "instance_859cf1e47bca6046",
124
+ "source_run_id": "20260911T033037730561Z",
125
+ "profile_ref": null,
126
+ "env_fps": 10.0,
127
+ "obs_fps": 10.0,
128
+ "frame_ms": 100.0,
129
+ "latency_type": "profile_sample",
130
+ "task": "ant",
131
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
132
+ "checkpoint_path": "latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42",
133
+ "profile_sha256": "0e49f72ec05ac600a54e07bbca5af3143708444d606167f33fa21788a9fefe50",
134
+ "condition": "profile-latency",
135
+ "invalid_actions": 0,
136
+ "dropped_actions": 0,
137
+ "unique_seeds": 100,
138
+ "physical_gpu": 2,
139
+ "eval_config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant.yaml",
140
+ "execution_audit": {
141
+ "issued_action_records": 79573,
142
+ "applied_action_records": 79465,
143
+ "dropped_action_records": 0,
144
+ "nonnoop_issued_records": 79573,
145
+ "finite_action_values": true,
146
+ "latency_sample_count": 79573,
147
+ "latency_mean_ms": 90.00919554158884,
148
+ "latency_std_ms": 2.514492574433973,
149
+ "latency_p95_ms": 91.11971585797141,
150
+ "latency_p99_ms": 102.67108120995428
151
+ }
152
+ },
153
+ "intercept": {
154
+ "n_episodes": 100,
155
+ "mean_return": 3.5443485127069287,
156
+ "std_return": 7.07192296411853,
157
+ "min_return": 0.6267238368745893,
158
+ "max_return": 29.923812823486514,
159
+ "mean_length": 60.0,
160
+ "std_length": 0.0,
161
+ "min_length": 60.0,
162
+ "max_length": 60.0,
163
+ "return_field": "episode_return_env",
164
+ "length_field": "survival_steps",
165
+ "mode": "simulated",
166
+ "policy_id": "starvla",
167
+ "env_id": "mikasa_intercept_grab_fast",
168
+ "model_id": "qwenoft",
169
+ "gpu_class": "1x-rtx3090",
170
+ "workload_id": "mikasa_intercept_grab_fast",
171
+ "instance_id": "instance_3a0d42681a03715c",
172
+ "source_run_id": "20260909T044501695676Z",
173
+ "profile_ref": null,
174
+ "env_fps": 20.0,
175
+ "obs_fps": 20.0,
176
+ "frame_ms": 50.0,
177
+ "latency_type": "profile_sample",
178
+ "task": "intercept",
179
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
180
+ "checkpoint_path": "latency-aware/mikasa-intercept-grab-fast/vla/starvla-qwenoft-h1/intercept-qwenoft-mean-3090-h1-s0",
181
+ "profile_sha256": "31a9b15d6b04182439934f0b377cb3d09be16ce21f3cf95c1049918f8a5d4984",
182
+ "condition": "profile-latency",
183
+ "invalid_actions": 0,
184
+ "dropped_actions": 10,
185
+ "unique_seeds": 100,
186
+ "physical_gpu": 3,
187
+ "eval_config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/intercept.yaml",
188
+ "success_count": 9,
189
+ "success_rate": 0.09,
190
+ "execution_audit": {
191
+ "issued_action_records": 2974,
192
+ "applied_action_records": 2864,
193
+ "dropped_action_records": 10,
194
+ "nonnoop_issued_records": 2974,
195
+ "finite_action_values": true,
196
+ "latency_sample_count": 2974,
197
+ "latency_mean_ms": 99.11060319379854,
198
+ "latency_std_ms": 4.301543980874005,
199
+ "latency_p95_ms": 100.2889407458356,
200
+ "latency_p99_ms": 100.64616770379737
201
+ }
202
+ }
203
+ },
204
+ "quality_acceptance": "not inferred; observed statistics only"
205
+ }
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/episodes.csv ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ episode_id,seed,return_env,length,mean_latency_ms,invalid_actions,dropped_actions
2
+ 0,1000000,337.47547912597656,72,71.90727374040254,0,0
3
+ 1,1000001,819.0284423828125,143,73.84762082340946,0,0
4
+ 2,1000002,2284.857650756836,182,72.79171012339609,0,0
5
+ 3,1000003,2276.2068634033203,189,76.345275285376,0,0
6
+ 4,1000004,805.2153015136719,150,73.86282581373551,0,0
7
+ 5,1000005,621.8231658935547,115,74.31105893586228,0,0
8
+ 6,1000006,2276.414749145508,176,74.2226331369995,0,0
9
+ 7,1000007,2284.310989379883,176,72.9072057957754,0,0
10
+ 8,1000008,81.07798767089844,49,73.20258272646697,0,0
11
+ 9,1000009,317.2351837158203,75,72.54774919154028,0,0
12
+ 10,1000010,2282.7608489990234,176,72.78293151689127,0,0
13
+ 11,1000011,88.11907958984375,45,72.60486105128022,0,0
14
+ 12,1000012,2281.468536376953,176,72.29193331603048,0,0
15
+ 13,1000013,2276.6868591308594,178,72.73330265771509,0,0
16
+ 14,1000014,2276.1705932617188,178,73.30067987408609,0,0
17
+ 15,1000015,2282.6631622314453,177,72.49405489224537,0,0
18
+ 16,1000016,2280.300033569336,172,72.80884970803692,0,0
19
+ 17,1000017,2280.4182891845703,182,73.03539182090206,0,0
20
+ 18,1000018,2281.2594451904297,177,72.50972089313564,0,0
21
+ 19,1000019,479.8523712158203,99,72.58046231642126,0,0
22
+ 20,1000020,2279.7379455566406,181,72.47468246266928,0,0
23
+ 21,1000021,2284.9097442626953,197,83.18983231769475,0,0
24
+ 22,1000022,2286.2730407714844,172,72.84281562147524,0,0
25
+ 23,1000023,244.51919555664062,74,76.23461799191558,0,0
26
+ 24,1000024,2279.957275390625,195,72.94927214021655,0,0
27
+ 25,1000025,2283.952178955078,179,73.18968843008061,0,0
28
+ 26,1000026,2276.701370239258,178,72.87702909462648,0,0
29
+ 27,1000027,2277.142562866211,190,72.45412386128042,0,0
30
+ 28,1000028,2279.025634765625,177,74.11102172804317,0,0
31
+ 29,1000029,2285.7152099609375,177,71.63189230597281,0,0
32
+ 30,1000030,53.374298095703125,44,72.51418721312025,0,0
33
+ 31,1000031,2279.8080444335938,183,72.72702656843174,0,0
34
+ 32,1000032,2282.307357788086,178,74.33584751930213,0,0
35
+ 33,1000033,2282.834014892578,192,73.95005063555192,0,0
36
+ 34,1000034,2284.200241088867,188,76.29368894499888,0,0
37
+ 35,1000035,2287.2159118652344,179,72.81890806090988,0,0
38
+ 36,1000036,2284.693832397461,183,76.28284599973325,0,0
39
+ 37,1000037,2283.2066650390625,178,72.1797344044525,0,0
40
+ 38,1000038,2281.032196044922,178,73.74343783824916,0,0
41
+ 39,1000039,2282.960678100586,190,73.24816830891406,0,0
42
+ 40,1000040,2287.094253540039,185,72.35711232966574,0,0
43
+ 41,1000041,2279.3030853271484,179,72.42125368367608,0,0
44
+ 42,1000042,440.0892791748047,104,73.92064892672727,0,0
45
+ 43,1000043,2280.8592529296875,177,72.36020918178356,0,0
46
+ 44,1000044,2283.4308471679688,189,75.93658060557208,0,0
47
+ 45,1000045,2282.324264526367,181,73.54224681770178,0,0
48
+ 46,1000046,326.0184631347656,74,73.1983876441008,0,0
49
+ 47,1000047,2279.086135864258,182,73.00958120503027,0,0
50
+ 48,1000048,2280.3804626464844,179,73.17268244992928,0,0
51
+ 49,1000049,2276.215301513672,189,75.47590644230628,0,0
52
+ 50,1000050,2278.132034301758,182,74.50495464842548,0,0
53
+ 51,1000051,2285.6056518554688,181,73.41699294418743,0,0
54
+ 52,1000052,2287.240921020508,173,73.22110809114655,0,0
55
+ 53,1000053,310.81517028808594,73,74.09003681120738,0,0
56
+ 54,1000054,2276.6219787597656,175,72.98605010243534,0,0
57
+ 55,1000055,2276.2769470214844,194,75.17704077845171,0,0
58
+ 56,1000056,2278.861602783203,178,72.97353037051572,0,0
59
+ 57,1000057,2279.728561401367,181,73.96913002154926,0,0
60
+ 58,1000058,2280.544464111328,176,73.02432805290651,0,0
61
+ 59,1000059,487.829833984375,108,78.89398217393664,0,0
62
+ 60,1000060,567.0655517578125,113,72.64874721482185,0,0
63
+ 61,1000061,2278.210220336914,177,72.96068484971086,0,0
64
+ 62,1000062,2281.436721801758,186,75.46710866924751,0,0
65
+ 63,1000063,382.2119903564453,89,81.21157315209366,0,0
66
+ 64,1000064,246.2946014404297,70,73.9736408486285,0,0
67
+ 65,1000065,285.21240234375,76,73.13661133681993,0,0
68
+ 66,1000066,310.6737365722656,75,73.40468658737086,0,0
69
+ 67,1000067,346.1162872314453,75,72.1929723632303,0,0
70
+ 68,1000068,804.7056121826172,150,73.76397959753224,0,0
71
+ 69,1000069,2285.6442108154297,184,75.13255757158333,0,0
72
+ 70,1000070,730.5995788574219,132,73.25446825350764,0,0
73
+ 71,1000071,86.91796875,47,76.28335745963689,0,0
74
+ 72,1000072,60.30122375488281,44,76.83513093208644,0,0
75
+ 73,1000073,768.6264343261719,141,77.27057350071598,0,0
76
+ 74,1000074,2280.1071166992188,172,74.16699734355548,0,0
77
+ 75,1000075,860.9334106445312,151,73.15118478347584,0,0
78
+ 76,1000076,722.9459228515625,143,75.5655785931314,0,0
79
+ 77,1000077,2276.8687438964844,182,72.95102474014934,0,0
80
+ 78,1000078,368.3357238769531,79,71.51096709276341,0,0
81
+ 79,1000079,-76.45918273925781,17,72.24888432102617,0,0
82
+ 80,1000080,2281.5543823242188,183,73.32589540463356,0,0
83
+ 81,1000081,2281.6688842773438,171,73.10600900440717,0,0
84
+ 82,1000082,2277.5223083496094,178,73.55648700566698,0,0
85
+ 83,1000083,42.30937194824219,41,73.52700344736942,0,0
86
+ 84,1000084,2285.8980407714844,176,71.98655161011203,0,0
87
+ 85,1000085,68.90191650390625,45,72.84773487604696,0,0
88
+ 86,1000086,2286.2190551757812,171,72.82303966497733,0,0
89
+ 87,1000087,281.1173553466797,76,72.26983276661764,0,0
90
+ 88,1000088,2283.1607971191406,175,73.49638264342678,0,0
91
+ 89,1000089,2277.888946533203,177,73.44736473371472,0,0
92
+ 90,1000090,429.36326599121094,93,71.86172378947977,0,0
93
+ 91,1000091,252.0751953125,70,72.26459581736903,0,0
94
+ 92,1000092,2278.306442260742,192,80.97328482778371,0,0
95
+ 93,1000093,2285.236801147461,175,74.02717585214627,0,0
96
+ 94,1000094,857.2727355957031,152,85.59110000526613,0,0
97
+ 95,1000095,2275.9288024902344,199,73.62958803645523,0,0
98
+ 96,1000096,2286.8704833984375,179,72.31519682456816,0,0
99
+ 97,1000097,2278.048355102539,181,73.50330330803081,0,0
100
+ 98,1000098,2277.4480743408203,178,76.78472725777,0,0
101
+ 99,1000099,2276.9671478271484,178,77.9678189026336,0,0
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/eval_config.yaml ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ experiment:
2
+ name: deadly_corridor-mean5000-profile-simulation-100ep
3
+ seed: 1000000
4
+ backend:
5
+ type: sample_factory
6
+ algo: APPO
7
+ device: cpu
8
+ train_dir: results/sample_factory
9
+ restart_behavior: resume
10
+ run_mode: eval
11
+ executor:
12
+ mode: simulated
13
+ simulated_worker_capacity: 1
14
+ simulated_inference_pool: true
15
+ inference_devices:
16
+ - cuda:0
17
+ inference_batch_size: 32
18
+ env:
19
+ name: deadly_corridor
20
+ env_id: doom_deadly_corridor
21
+ env_fps: 35
22
+ obs_fps: 8.75
23
+ noop_action:
24
+ - 0
25
+ - 0
26
+ - 0
27
+ - 0
28
+ frame_stack: 1
29
+ res_w: 128
30
+ res_h: 72
31
+ wide_aspect_ratio: false
32
+ simulator: cpu
33
+ obs_resize:
34
+ - 224
35
+ - 224
36
+ action_map:
37
+ noop:
38
+ - 0
39
+ - 0
40
+ - 0
41
+ - 0
42
+ move_forward:
43
+ - 0
44
+ - 1
45
+ - 0
46
+ - 0
47
+ move_backward:
48
+ - 0
49
+ - 2
50
+ - 0
51
+ - 0
52
+ move_left:
53
+ - 0
54
+ - 0
55
+ - 1
56
+ - 0
57
+ move_right:
58
+ - 0
59
+ - 0
60
+ - 2
61
+ - 0
62
+ turn_left:
63
+ - 1
64
+ - 0
65
+ - 0
66
+ - 0
67
+ turn_right:
68
+ - 2
69
+ - 0
70
+ - 0
71
+ - 0
72
+ attack:
73
+ - 0
74
+ - 0
75
+ - 0
76
+ - 1
77
+ action_history_decisions: 8
78
+ screen_resolution: RES_160X120
79
+ render_hud: true
80
+ render_crosshair: false
81
+ render_weapon: true
82
+ render_decals: false
83
+ render_particles: false
84
+ latency:
85
+ method: temporal
86
+ profile_path: /home/ubuntu/lzj/profiles/published/profiles/openvla/1x-rtx3090/deadly_corridor/instance_a5037b165aa0cedc/profile.json
87
+ profile_worker_slot: 0
88
+ seed: 271828
89
+ add_latency_info: false
90
+ scheduler:
91
+ hold_policy: hold
92
+ ordering_policy: latest_ready
93
+ policy:
94
+ type: starvla
95
+ actions:
96
+ - MOVE_FORWARD
97
+ - MOVE_BACKWARD
98
+ - MOVE_LEFT
99
+ - MOVE_RIGHT
100
+ - TURN_LEFT
101
+ - TURN_RIGHT
102
+ - ATTACK
103
+ checkpoint_path: /home/ubuntu/lzj/mean-profiling/deadly_corridor/vla-publication/checkpoints/model.pt
104
+ model_config_path: /home/ubuntu/lzj/mean-profiling/deadly_corridor/vla-publication/config.full.yaml
105
+ device: cuda:0
106
+ unnorm_key: new_embodiment
107
+ prompt_mode: latency_neutral
108
+ action_layout: multibinary_7
109
+ state_source: transport
110
+ backbone_path: /home/ubuntu/lzj/models/Qwen3-VL-4B-Instruct
111
+ worker_python_executable: /home/ubuntu/lzj/conda/envs/qwenoft/bin/python
112
+ training:
113
+ train_for_env_steps: 25000000
114
+ num_workers: 32
115
+ num_envs_per_worker: 4
116
+ worker_num_splits: 2
117
+ num_policies: 1
118
+ batch_size: 1024
119
+ rollout: 128
120
+ recurrence: 128
121
+ num_epochs: 2
122
+ num_batches_per_epoch: 2
123
+ learning_rate: 0.0001
124
+ gamma: 0.99
125
+ gae_lambda: 0.95
126
+ ppo_clip_ratio: 0.1
127
+ ppo_clip_value: 0.2
128
+ exploration_loss: symmetric_kl
129
+ exploration_loss_coeff: 0.001
130
+ value_loss_coeff: 0.5
131
+ max_grad_norm: 4.0
132
+ async_rl: true
133
+ use_rnn: true
134
+ rnn_type: gru
135
+ rnn_size: 512
136
+ normalize_input: true
137
+ normalize_returns: true
138
+ stats_avg: 100
139
+ experiment_summaries_interval: 1
140
+ save_every_sec: 600
141
+ keep_checkpoints: 5
142
+ evaluation:
143
+ eval_interval_steps: 1000000
144
+ eval_episodes: 100
145
+ eval_parallel_envs: 32
146
+ eval_max_steps: 3600
147
+ eval_deterministic: true
148
+ eval_raw_reward: true
149
+ eval_suites:
150
+ fixed: []
151
+ normal: []
152
+ uniform: []
153
+ eval_latency_values: null
154
+ logging:
155
+ output_dir: /home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/deadly_corridor
156
+ video:
157
+ enabled: false
158
+ save_step_records: true
159
+ save_action_records: true
160
+ save_latency_records: true
161
+ wandb_project: null
162
+ wandb_group: null
163
+ wandb_job_type: null
164
+ wandb_tags: ''
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/batched_simulated.py ADDED
@@ -0,0 +1,702 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import time
4
+ from collections.abc import Callable, Mapping, Sequence
5
+ from dataclasses import dataclass, field
6
+ from pathlib import Path
7
+
8
+ import numpy as np
9
+
10
+ from latency_bench.core.clock import EnvClock
11
+ from latency_bench.core.decision_action_history import DecisionActionHistory
12
+ from latency_bench.core.timing import StageProfiler, profiler_scope
13
+ from latency_bench.core.types import ActionEvent, EpisodeMetrics, LatencyRecord, Observation, StepRecord
14
+ from latency_bench.envs.atari import TRUE_EPISODE_END_INFO_KEY
15
+ from latency_bench.envs.base import EnvAdapter
16
+ from latency_bench.executors._simulated_timeline import (
17
+ SimulatedResultTimeline,
18
+ SimulatedWorkerCapacity,
19
+ build_simulated_action_event,
20
+ )
21
+ from latency_bench.executors.base import BatchedExecutor
22
+ from latency_bench.executors.env_step_backend import EnvStepBackend, env_action_space
23
+ from latency_bench.latency.sample import LatencySample
24
+ from latency_bench.latency.samplers import LatencySampler
25
+ from latency_bench.logging.metrics import (
26
+ compute_episode_metrics,
27
+ compute_episode_metrics_from_aggregates,
28
+ episode_raw_fact_metadata,
29
+ latency_type_from_source,
30
+ profile_metadata_from_source,
31
+ )
32
+ from latency_bench.logging.records import build_step_record
33
+ from latency_bench.logging.trajectory_logger import TrajectoryLogger
34
+ from latency_bench.policy.action_prefix import with_action_prefix
35
+ from latency_bench.policy.base import PolicyRunner
36
+ from latency_bench.scheduler.action_queue import ActionScheduler
37
+ from latency_bench.scheduler.decision import DecisionScheduler
38
+ from latency_bench.utils.io import write_json
39
+ from latency_bench.utils.stats import series_stats
40
+
41
+
42
+ @dataclass
43
+ class _EpisodeBuffers:
44
+ step_records: list[StepRecord] | None = None
45
+ action_events: list[ActionEvent] | None = None
46
+ latency_records: list[LatencyRecord] | None = None
47
+ latency_values_ms: list[float] = field(default_factory=list)
48
+ episode_return_env: float = 0.0
49
+ survival_steps: int = 0
50
+ game_score: float | None = None
51
+ return_raw: float | None = None
52
+ num_actions: int = 0
53
+ num_dropped_actions: int = 0
54
+ num_invalid_actions: int = 0
55
+ submitted_observation_frames: int = 0
56
+ dropped_observation_count: int = 0
57
+ soft_reset_count: int = 0
58
+ final_lives: int | None = None
59
+ final_is_true_episode_end: bool | None = None
60
+ task_metrics: dict | None = None
61
+ task_metric_moments: dict | None = None
62
+
63
+ def record_step(self, *, reward: float, info: dict) -> None:
64
+ self.episode_return_env += float(reward)
65
+ self.survival_steps += 1
66
+ if "invalid_action" in info and info["invalid_action"]:
67
+ self.num_invalid_actions += 1
68
+ if "soft_reset" in info and info["soft_reset"]:
69
+ self.soft_reset_count += 1
70
+ if "lives" in info:
71
+ self.final_lives = info["lives"]
72
+ if TRUE_EPISODE_END_INFO_KEY in info:
73
+ self.final_is_true_episode_end = info[TRUE_EPISODE_END_INFO_KEY]
74
+ if "game_score" in info:
75
+ self.game_score = float(info["game_score"])
76
+ if "score" in info:
77
+ self.game_score = float(info["score"])
78
+ if "task_metrics" in info:
79
+ self.task_metrics = info["task_metrics"]
80
+ if "task_metric_moments" in info:
81
+ self.task_metric_moments = info["task_metric_moments"]
82
+ self._update_return_raw(info)
83
+ extra_stats = info["episode_extra_stats"] if "episode_extra_stats" in info else None
84
+ if isinstance(extra_stats, dict):
85
+ self._update_return_raw(extra_stats)
86
+
87
+ def _update_return_raw(self, stats: dict) -> None:
88
+ for key in ("return_raw", "raw_return", "episodic_raw_return", "episode/raw_return"):
89
+ if key in stats and stats[key] is not None:
90
+ self.return_raw = float(stats[key])
91
+
92
+
93
+ @dataclass
94
+ class _SlotState:
95
+ slot_id: int
96
+ env: EnvAdapter
97
+ latency_source: LatencySampler
98
+ action_scheduler: ActionScheduler
99
+ result_timeline: SimulatedResultTimeline
100
+ active: bool = False
101
+ episode_id: int | None = None
102
+ episode_seed: int | None = None
103
+ env_step: int = 0
104
+ recent_drop_count: int = 0
105
+ decision_action_history: DecisionActionHistory | None = None
106
+ decision_admitted: bool = False
107
+ decision_issued_action: object = None
108
+ buffers: _EpisodeBuffers = field(default_factory=_EpisodeBuffers)
109
+ worker_capacity: SimulatedWorkerCapacity = field(
110
+ default_factory=lambda: SimulatedWorkerCapacity(capacity=None, busy_until_by_worker={})
111
+ )
112
+
113
+
114
+ @dataclass
115
+ class _PendingPolicyObservation:
116
+ slot: _SlotState
117
+ observation: Observation
118
+ obs_id: int
119
+ latency_sample: LatencySample
120
+ worker_slot: int
121
+
122
+
123
+ class BatchedSimulatedLatencyExecutor(BatchedExecutor):
124
+ """Run multiple simulated episodes concurrently with independent slot state.
125
+
126
+ The main process owns policy inference, latency scheduling, episode accounting,
127
+ and logging. Env stepping can be serial in-process or delegated to worker
128
+ subprocesses through env_backend.
129
+ """
130
+
131
+ def __init__(
132
+ self,
133
+ *,
134
+ env_backend: EnvStepBackend,
135
+ policy: PolicyRunner,
136
+ decision_scheduler: DecisionScheduler,
137
+ latency_sources: Sequence[LatencySampler],
138
+ action_schedulers: Sequence[ActionScheduler],
139
+ clock: EnvClock,
140
+ logger: TrajectoryLogger | None = None,
141
+ episode_latency_source_factory: Callable[[int], LatencySampler] | None = None,
142
+ simulated_worker_capacity: int | None = None,
143
+ profile_pipeline: bool = False,
144
+ inference_pool=None,
145
+ action_prefix=None,
146
+ action_history_decisions: int | None = None,
147
+ ):
148
+ slot_count = env_backend.num_slots
149
+ self.env_backend = env_backend
150
+ self.envs = list(env_backend.slot_handles)
151
+ self.policy = policy
152
+ self.decision_scheduler = decision_scheduler
153
+ self.clock = clock
154
+ self.logger = logger
155
+ self.profile_pipeline = bool(profile_pipeline)
156
+ self.inference_pool = inference_pool
157
+ self.action_prefix = action_prefix
158
+ self._pipeline_profile_rows: list[dict[str, float]] = []
159
+ self.simulated_worker_capacity = simulated_worker_capacity
160
+ self._collect_step_records = bool(logger is not None and logger.save_step_records)
161
+ self._collect_action_records = bool(logger is not None and logger.save_action_records)
162
+ self._collect_latency_records = bool(logger is not None and logger.save_latency_records)
163
+ self.episode_latency_source_factory = episode_latency_source_factory
164
+ self.slots = [
165
+ _SlotState(
166
+ slot_id=slot_id,
167
+ env=self.envs[slot_id],
168
+ latency_source=latency_sources[slot_id],
169
+ action_scheduler=action_schedulers[slot_id],
170
+ result_timeline=SimulatedResultTimeline(
171
+ ordering_policy=action_schedulers[slot_id].ordering_policy
172
+ ),
173
+ decision_action_history=(
174
+ DecisionActionHistory(
175
+ env_action_space(self.envs[slot_id]), num_envs=1, decisions=action_history_decisions
176
+ ) if action_history_decisions is not None else None
177
+ ),
178
+ buffers=self._new_episode_buffers(),
179
+ worker_capacity=SimulatedWorkerCapacity(
180
+ capacity=simulated_worker_capacity,
181
+ busy_until_by_worker={},
182
+ ),
183
+ )
184
+ for slot_id in range(slot_count)
185
+ ]
186
+ self._next_obs_id = 0
187
+ self._next_action_id = 0
188
+ self.started_episodes = 0
189
+ self.completed_episodes = 0
190
+ self._completed_metrics: dict[int, EpisodeMetrics] = {}
191
+ self._completed_buffers: dict[int, _EpisodeBuffers] = {}
192
+ self._episode_log_order: list[int] = []
193
+ self._next_episode_log_index = 0
194
+
195
+ @property
196
+ def num_slots(self) -> int:
197
+ return len(self.slots)
198
+
199
+ def close(self) -> None:
200
+ if self.inference_pool is not None:
201
+ self.inference_pool.close()
202
+ self.env_backend.close()
203
+
204
+ def run_episodes(
205
+ self,
206
+ *,
207
+ episode_ids: Sequence[int],
208
+ seeds: Sequence[int | None],
209
+ eval_max_steps: int = 10000,
210
+ on_episode_complete: Callable[[EpisodeMetrics], None] | None = None,
211
+ ) -> list[EpisodeMetrics]:
212
+ if eval_max_steps < 0:
213
+ raise ValueError("eval_max_steps must be non-negative")
214
+ episode_ids = [int(episode_id) for episode_id in episode_ids]
215
+ if len(seeds) != len(episode_ids):
216
+ raise ValueError("seeds length must match episode_ids length")
217
+
218
+ self._reset_run_state(episode_ids)
219
+ if not episode_ids:
220
+ return []
221
+
222
+ next_episode_index = 0
223
+ initial_slots = min(self.num_slots, len(episode_ids))
224
+ for slot in self.slots[:initial_slots]:
225
+ self._start_slot(
226
+ slot,
227
+ episode_id=episode_ids[next_episode_index],
228
+ seed=seeds[next_episode_index],
229
+ )
230
+ next_episode_index += 1
231
+
232
+ while self.completed_episodes < len(episode_ids):
233
+ active_slots = self._active_slots()
234
+ if eval_max_steps == 0:
235
+ for slot in active_slots:
236
+ self._complete_slot(slot, on_episode_complete=on_episode_complete)
237
+ if next_episode_index < len(episode_ids):
238
+ self._start_slot(
239
+ slot,
240
+ episode_id=episode_ids[next_episode_index],
241
+ seed=seeds[next_episode_index],
242
+ )
243
+ next_episode_index += 1
244
+ continue
245
+
246
+ observations = []
247
+ observation_slots: list[_SlotState] = []
248
+ step_capacity_info: dict[int, dict[str, int | bool | None]] = {}
249
+ for slot in active_slots:
250
+ current_time_ms = self.clock.step_to_time_ms(slot.env_step)
251
+ slot.worker_capacity.release_ready(slot.env_step)
252
+ self._deliver_arrived_results(slot, raw_frame=slot.env_step)
253
+ observation_submitted = False
254
+ observation_dropped = False
255
+ if self.decision_scheduler.should_observe(slot.env_step, current_time_ms):
256
+ prefix_request_pending = (
257
+ self.action_prefix is not None
258
+ and self.action_prefix["mode"] != "none"
259
+ and slot.result_timeline.pending_observation_count > 0
260
+ )
261
+ if slot.worker_capacity.can_submit() and not prefix_request_pending:
262
+ observation_slots.append(slot)
263
+ observation_submitted = True
264
+ else:
265
+ slot.buffers.dropped_observation_count += 1
266
+ observation_dropped = True
267
+ slot.recent_drop_count += 1
268
+ if self.simulated_worker_capacity is not None:
269
+ step_capacity_info[slot.slot_id] = {
270
+ "observation_submitted": observation_submitted,
271
+ "observation_dropped": observation_dropped,
272
+ }
273
+ if slot.decision_action_history is not None and slot.env_step % self.clock.obs_stride_raw_frames == 0:
274
+ slot.decision_admitted = observation_submitted
275
+ slot.decision_issued_action = slot.action_scheduler.noop_action.value
276
+
277
+ observe_ms = 0.0
278
+ if observation_slots:
279
+ observe_start = time.perf_counter()
280
+ observations_by_slot = self.env_backend.observe_slots([slot.slot_id for slot in observation_slots])
281
+ observe_ms = (time.perf_counter() - observe_start) * 1000.0
282
+ pending_observations = [
283
+ self._sample_policy_observation(
284
+ slot,
285
+ self._policy_observation(
286
+ slot,
287
+ observations_by_slot[slot.slot_id],
288
+ transport=(
289
+ slot.decision_action_history.observation()[0]
290
+ if slot.decision_action_history is not None else None
291
+ ),
292
+ ),
293
+ )
294
+ for slot in observation_slots
295
+ ]
296
+ observations = [pending.observation for pending in pending_observations]
297
+
298
+ profile_row = None
299
+ if observations:
300
+ profiler = StageProfiler(enabled=self.profile_pipeline)
301
+ with profiler_scope(profiler):
302
+ policy_outputs = (
303
+ self.inference_pool.predict_batch(observations)
304
+ if self.inference_pool is not None
305
+ else self.policy.predict_batch(observations)
306
+ )
307
+ if len(policy_outputs) != len(observations):
308
+ raise RuntimeError("policy.predict_batch returned the wrong number of outputs")
309
+ if self.profile_pipeline:
310
+ profile_row = {
311
+ "active_slots": float(len(active_slots)),
312
+ "batch_size": float(len(observations)),
313
+ "observe_slots_ms": observe_ms,
314
+ **{key: float(value) for key, value in profiler.timings.items()},
315
+ }
316
+ for pending, policy_output in zip(pending_observations, policy_outputs):
317
+ if pending.slot.decision_action_history is not None:
318
+ pending.slot.decision_issued_action = policy_output.action.value
319
+ self._enqueue_policy_output(
320
+ pending.slot,
321
+ pending.observation,
322
+ policy_output,
323
+ obs_id=pending.obs_id,
324
+ latency_sample=pending.latency_sample,
325
+ worker_slot=pending.worker_slot,
326
+ )
327
+
328
+ actions_by_slot = {}
329
+ for slot in active_slots:
330
+ current_time_ms = self.clock.step_to_time_ms(slot.env_step)
331
+ self._deliver_arrived_results(slot, raw_frame=slot.env_step)
332
+ active_action = slot.action_scheduler.update(slot.env_step, current_time_ms)
333
+ actions_by_slot[slot.slot_id] = active_action
334
+
335
+ env_step_start = time.perf_counter()
336
+ step_responses = self.env_backend.step_slots(actions_by_slot)
337
+ if profile_row is not None:
338
+ profile_row["env_step_ms"] = (time.perf_counter() - env_step_start) * 1000.0
339
+ self._pipeline_profile_rows.append(profile_row)
340
+ for slot in active_slots:
341
+ current_time_ms = self.clock.step_to_time_ms(slot.env_step)
342
+ active_action = actions_by_slot[slot.slot_id]
343
+ if (
344
+ slot.decision_action_history is not None
345
+ and (slot.env_step + 1) % self.clock.obs_stride_raw_frames == 0
346
+ ):
347
+ slot.decision_action_history.append(
348
+ [0], [slot.decision_admitted],
349
+ [slot.decision_issued_action], [active_action.value],
350
+ )
351
+ result = step_responses[slot.slot_id].result
352
+ soft_reset = bool(result.info.get("soft_reset")) if isinstance(result.info, dict) else False
353
+ episode_done = bool(result.done or result.truncated) and not soft_reset
354
+ if slot.buffers.step_records is not None:
355
+ record = build_step_record(
356
+ episode_id=int(slot.episode_id),
357
+ env_step=slot.env_step,
358
+ scheduled_time_ms=current_time_ms,
359
+ active_action=active_action,
360
+ reward=result.reward,
361
+ done=episode_done,
362
+ info=result.info,
363
+ active_event=slot.action_scheduler.latest_applied_event,
364
+ frame_ms=self.clock.frame_ms,
365
+ latency_type=latency_type_from_source(slot.latency_source),
366
+ )
367
+ slot.buffers.step_records.append(record)
368
+ slot.buffers.record_step(reward=float(result.reward), info=record.info)
369
+ else:
370
+ slot.buffers.record_step(reward=float(result.reward), info=result.info)
371
+ if self.simulated_worker_capacity is not None and slot.buffers.step_records is not None:
372
+ slot.buffers.step_records[-1].info.update(
373
+ {
374
+ **step_capacity_info[slot.slot_id],
375
+ "in_flight_count": slot.worker_capacity.in_flight_count,
376
+ "idle_worker_count": slot.worker_capacity.idle_worker_count,
377
+ }
378
+ )
379
+ if soft_reset:
380
+ slot.buffers.num_dropped_actions += slot.action_scheduler.dropped_events_count
381
+ slot.action_scheduler.reset()
382
+ slot.result_timeline.reset()
383
+ self._reset_policy_state(slot.slot_id)
384
+ slot.worker_capacity.reset()
385
+ if slot.decision_action_history is not None:
386
+ slot.decision_action_history.reset()
387
+ slot.recent_drop_count = 0
388
+
389
+ slot.env_step += 1
390
+ if episode_done or slot.env_step >= eval_max_steps:
391
+ self._complete_slot(slot, on_episode_complete=on_episode_complete)
392
+ if next_episode_index < len(episode_ids):
393
+ self._start_slot(
394
+ slot,
395
+ episode_id=episode_ids[next_episode_index],
396
+ seed=seeds[next_episode_index],
397
+ )
398
+ next_episode_index += 1
399
+
400
+ self._write_pipeline_profile_summary()
401
+ return self._ordered_metrics(episode_ids)
402
+
403
+ def _policy_observation(
404
+ self,
405
+ slot: _SlotState,
406
+ observation: Observation,
407
+ transport: np.ndarray | None = None,
408
+ ) -> Observation:
409
+ observation = with_action_prefix(observation, slot.action_scheduler, self.action_prefix)
410
+ metadata = dict(observation.metadata)
411
+ metadata["slot_id"] = slot.slot_id
412
+ metadata["episode_id"] = int(slot.episode_id)
413
+ metadata["action_noise_seed"] = slot.episode_seed
414
+ data = observation.data
415
+ if transport is not None:
416
+ data = {**data, "transport": transport} if isinstance(data, Mapping) else {"obs": data, "transport": transport}
417
+ return Observation(
418
+ data=data,
419
+ env_step=observation.env_step,
420
+ sim_time_ms=observation.sim_time_ms,
421
+ metadata=metadata,
422
+ )
423
+
424
+ def _sample_policy_observation(
425
+ self,
426
+ slot: _SlotState,
427
+ observation: Observation,
428
+ ) -> _PendingPolicyObservation:
429
+ obs_id = self._next_obs_id
430
+ self._next_obs_id += 1
431
+ raw_frame = int(slot.env_step)
432
+ current_time_ms = self.clock.step_to_time_ms(raw_frame)
433
+ worker_slot = slot.worker_capacity.assign_worker()
434
+ latency_context = {
435
+ "observation": observation,
436
+ "obs_id": obs_id,
437
+ "env_step": raw_frame,
438
+ "raw_frame": raw_frame,
439
+ "sim_time_ms": current_time_ms,
440
+ "episode_id": slot.episode_id,
441
+ "slot_id": slot.slot_id,
442
+ "worker_slot": worker_slot,
443
+ "recent_drop_count": slot.recent_drop_count,
444
+ "in_flight_count": slot.worker_capacity.in_flight_count,
445
+ "idle_worker_count": slot.worker_capacity.idle_worker_count,
446
+ }
447
+ latency_sample = slot.latency_source.sample(latency_context)
448
+ metadata = dict(observation.metadata)
449
+ metadata["obs_id"] = obs_id
450
+ policy_observation = Observation(
451
+ data=observation.data,
452
+ env_step=observation.env_step,
453
+ sim_time_ms=observation.sim_time_ms,
454
+ metadata=metadata,
455
+ )
456
+ slot.worker_capacity.submit(
457
+ worker_slot, raw_frame + latency_sample.worker_service_raw_frames
458
+ )
459
+ return _PendingPolicyObservation(
460
+ slot=slot,
461
+ obs_id=obs_id,
462
+ latency_sample=latency_sample,
463
+ worker_slot=worker_slot,
464
+ observation=policy_observation,
465
+ )
466
+
467
+ def _reset_run_state(self, episode_ids: Sequence[int]) -> None:
468
+ self.started_episodes = 0
469
+ self.completed_episodes = 0
470
+ self._pipeline_profile_rows.clear()
471
+ self._completed_metrics.clear()
472
+ self._completed_buffers.clear()
473
+ self._episode_log_order = [int(episode_id) for episode_id in episode_ids]
474
+ self._next_episode_log_index = 0
475
+ for slot in self.slots:
476
+ slot.active = False
477
+ slot.episode_id = None
478
+ slot.episode_seed = None
479
+ slot.env_step = 0
480
+ slot.recent_drop_count = 0
481
+ slot.buffers = self._new_episode_buffers()
482
+ slot.action_scheduler.reset()
483
+ slot.result_timeline.reset()
484
+ slot.worker_capacity.reset()
485
+ if slot.decision_action_history is not None:
486
+ slot.decision_action_history.reset()
487
+
488
+ def _active_slots(self) -> list[_SlotState]:
489
+ return [slot for slot in self.slots if slot.active]
490
+
491
+ def _deliver_arrived_results(self, slot: _SlotState, *, raw_frame: int | None) -> None:
492
+ released, dropped = slot.result_timeline.release_arrived(raw_frame)
493
+ slot.buffers.num_dropped_actions += len(dropped)
494
+ for event in released:
495
+ slot.action_scheduler.enqueue(event)
496
+
497
+ def _start_slot(self, slot: _SlotState, *, episode_id: int, seed: int | None) -> None:
498
+ if self.episode_latency_source_factory is not None:
499
+ slot.latency_source = self.episode_latency_source_factory(episode_id)
500
+ slot.active = True
501
+ slot.episode_id = int(episode_id)
502
+ slot.episode_seed = None if seed is None else int(seed)
503
+ slot.env_step = 0
504
+ slot.recent_drop_count = 0
505
+ slot.buffers = self._new_episode_buffers()
506
+ slot.action_scheduler.reset()
507
+ slot.result_timeline.reset()
508
+ slot.worker_capacity.reset()
509
+ if slot.decision_action_history is not None:
510
+ slot.decision_action_history.reset()
511
+ self._reset_policy_state(slot.slot_id)
512
+ self.env_backend.reset_slot(slot.slot_id, episode_id=episode_id, seed=seed)
513
+ self.started_episodes += 1
514
+
515
+ def _reset_policy_state(self, slot_id: int) -> None:
516
+ if self.inference_pool is not None:
517
+ self.inference_pool.reset_state(slot_id)
518
+ else:
519
+ self.policy.reset_state(slot_id=slot_id)
520
+
521
+ def _complete_slot(
522
+ self,
523
+ slot: _SlotState,
524
+ *,
525
+ on_episode_complete: Callable[[EpisodeMetrics], None] | None = None,
526
+ ) -> None:
527
+ if not slot.active or slot.episode_id is None:
528
+ return
529
+ episode_id = int(slot.episode_id)
530
+ self._deliver_arrived_results(slot, raw_frame=None)
531
+ slot.buffers.num_dropped_actions += slot.action_scheduler.dropped_events_count
532
+ metrics = self._compute_episode_metrics(
533
+ episode_id=episode_id,
534
+ buffers=slot.buffers,
535
+ metadata=episode_raw_fact_metadata(
536
+ mode="simulated",
537
+ episode_seed=slot.episode_seed,
538
+ env_fps=self.clock.env_fps,
539
+ obs_fps=self.clock.obs_fps,
540
+ frame_ms=self.clock.frame_ms,
541
+ latency_type=latency_type_from_source(slot.latency_source),
542
+ latency_source=slot.latency_source,
543
+ )
544
+ | slot.action_scheduler.chunk_metrics()
545
+ | (
546
+ {
547
+ "submitted_observation_frames": slot.buffers.submitted_observation_frames,
548
+ "dropped_observation_count": slot.buffers.dropped_observation_count,
549
+ "simulated_worker_capacity": self.simulated_worker_capacity,
550
+ "inference_worker_count": self.simulated_worker_capacity,
551
+ "in_flight_count": slot.worker_capacity.in_flight_count,
552
+ "idle_worker_count": slot.worker_capacity.idle_worker_count,
553
+ }
554
+ if self.simulated_worker_capacity is not None
555
+ else {}
556
+ ),
557
+ )
558
+ self._completed_metrics[episode_id] = metrics
559
+ self._completed_buffers[episode_id] = slot.buffers
560
+ self.completed_episodes += 1
561
+ slot.active = False
562
+ slot.episode_id = None
563
+ slot.episode_seed = None
564
+ slot.env_step = 0
565
+ slot.recent_drop_count = 0
566
+ slot.buffers = self._new_episode_buffers()
567
+ slot.action_scheduler.reset()
568
+ slot.result_timeline.reset()
569
+ slot.worker_capacity.reset()
570
+ if slot.decision_action_history is not None:
571
+ slot.decision_action_history.reset()
572
+ self._flush_completed_in_episode_order()
573
+ if on_episode_complete is not None:
574
+ on_episode_complete(metrics)
575
+
576
+ def _enqueue_policy_output(
577
+ self,
578
+ slot: _SlotState,
579
+ observation,
580
+ policy_output,
581
+ *,
582
+ obs_id: int,
583
+ latency_sample: LatencySample,
584
+ worker_slot: int,
585
+ ) -> None:
586
+ raw_frame = int(slot.env_step)
587
+ latency_ms = latency_sample.latency_ms
588
+ ready_raw_frame = raw_frame + latency_sample.action_ready_raw_frames
589
+ ready_time_ms = self.clock.step_to_time_ms(ready_raw_frame)
590
+ latency_type = latency_type_from_source(slot.latency_source)
591
+ profile_metadata = profile_metadata_from_source(slot.latency_source)
592
+ slot_metadata = {
593
+ "episode_id": int(slot.episode_id),
594
+ "slot_id": int(slot.slot_id),
595
+ "worker_id": int(worker_slot),
596
+ }
597
+ latency_record, event = build_simulated_action_event(
598
+ action_id=self._next_action_id,
599
+ obs_id=obs_id,
600
+ policy_output=policy_output,
601
+ raw_frame=raw_frame,
602
+ ready_raw_frame=ready_raw_frame,
603
+ ready_time_ms=ready_time_ms,
604
+ latency_sample=latency_sample,
605
+ frame_ms=self.clock.frame_ms,
606
+ latency_type=latency_type,
607
+ profile_metadata=profile_metadata,
608
+ latency_record_metadata=slot_metadata,
609
+ extra_event_metadata=slot_metadata,
610
+ )
611
+ self._next_action_id += 1
612
+ slot.result_timeline.submit(obs_id=obs_id, ready_raw_frame=ready_raw_frame, event=event)
613
+ slot.buffers.submitted_observation_frames += 1
614
+ slot.recent_drop_count = 0
615
+ slot.buffers.num_actions += 1
616
+ if slot.buffers.action_events is not None:
617
+ slot.buffers.action_events.append(event)
618
+ slot.buffers.latency_values_ms.append(latency_ms)
619
+ if slot.buffers.latency_records is not None:
620
+ slot.buffers.latency_records.append(latency_record)
621
+
622
+ def _flush_completed_in_episode_order(self) -> None:
623
+ if self.logger is None:
624
+ return
625
+ while self._next_episode_log_index < len(self._episode_log_order):
626
+ episode_id = self._episode_log_order[self._next_episode_log_index]
627
+ if episode_id not in self._completed_metrics:
628
+ break
629
+ buffers = self._completed_buffers[episode_id]
630
+ metrics = self._completed_metrics[episode_id]
631
+ if buffers.step_records is not None:
632
+ for record in buffers.step_records:
633
+ self.logger.log_step(record)
634
+ if buffers.action_events is not None:
635
+ for event in buffers.action_events:
636
+ self.logger.log_action_event(event)
637
+ if buffers.latency_records is not None:
638
+ for latency_record in buffers.latency_records:
639
+ self.logger.log_latency(latency_record)
640
+ self.logger.log_episode_metrics(metrics)
641
+ self._next_episode_log_index += 1
642
+
643
+ def _ordered_metrics(self, episode_ids: Sequence[int]) -> list[EpisodeMetrics]:
644
+ return [self._completed_metrics[int(episode_id)] for episode_id in episode_ids]
645
+
646
+ def _new_episode_buffers(self) -> _EpisodeBuffers:
647
+ return _EpisodeBuffers(
648
+ step_records=[] if self._collect_step_records else None,
649
+ action_events=[] if self._collect_action_records else None,
650
+ latency_records=[] if self._collect_latency_records else None,
651
+ )
652
+
653
+ def _write_pipeline_profile_summary(self) -> None:
654
+ if not self.profile_pipeline or self.logger is None or not self._pipeline_profile_rows:
655
+ return
656
+ keys = sorted({key for row in self._pipeline_profile_rows for key in row})
657
+ summary = {
658
+ "num_profiled_batches": len(self._pipeline_profile_rows),
659
+ **{
660
+ key: series_stats([float(row[key]) for row in self._pipeline_profile_rows if key in row])
661
+ for key in keys
662
+ },
663
+ }
664
+ write_json(Path(self.logger.output_dir) / "simulated_pipeline_summary.json", summary)
665
+
666
+ def _compute_episode_metrics(
667
+ self,
668
+ *,
669
+ episode_id: int,
670
+ buffers: _EpisodeBuffers,
671
+ metadata: dict,
672
+ ) -> EpisodeMetrics:
673
+ if buffers.task_metrics is not None:
674
+ metadata["task_metrics"] = buffers.task_metrics
675
+ if buffers.task_metric_moments is not None:
676
+ metadata["task_metric_moments"] = buffers.task_metric_moments
677
+ if buffers.final_lives is not None:
678
+ metadata["final_lives"] = buffers.final_lives
679
+ if buffers.final_is_true_episode_end is not None:
680
+ metadata["final_is_true_episode_end"] = buffers.final_is_true_episode_end
681
+ metadata["soft_reset_count"] = buffers.soft_reset_count
682
+ if buffers.step_records is not None and buffers.action_events is not None:
683
+ return compute_episode_metrics(
684
+ episode_id=episode_id,
685
+ step_records=buffers.step_records,
686
+ action_events=buffers.action_events,
687
+ latency_values_ms=buffers.latency_values_ms,
688
+ metadata=metadata,
689
+ frame_ms=self.clock.frame_ms,
690
+ )
691
+ return compute_episode_metrics_from_aggregates(
692
+ episode_id=episode_id,
693
+ episode_return_env=buffers.episode_return_env,
694
+ survival_steps=buffers.survival_steps,
695
+ return_raw=buffers.return_raw,
696
+ game_score=buffers.game_score,
697
+ latency_values_ms=buffers.latency_values_ms,
698
+ num_actions=buffers.num_actions,
699
+ num_dropped_actions=buffers.num_dropped_actions,
700
+ num_invalid_actions=buffers.num_invalid_actions,
701
+ metadata=metadata,
702
+ )
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/deadly-compatibility.patch ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ diff --git a/latency_bench/envs/deadly_corridor.py b/latency_bench/envs/deadly_corridor.py
2
+ index 4dcaa48c..dc4d1186 100644
3
+ --- a/latency_bench/envs/deadly_corridor.py
4
+ +++ b/latency_bench/envs/deadly_corridor.py
5
+ @@ -5,7 +5,7 @@ from collections import deque
6
+ from typing import Any
7
+
8
+ import numpy as np
9
+ -from gymnasium.spaces import Box, Tuple
10
+ +from gymnasium.spaces import Box, MultiBinary, Tuple
11
+
12
+ from latency_bench.core.types import Action, Observation, StepResult
13
+ from latency_bench.envs.base import EnvAdapter
14
+ @@ -346,6 +346,7 @@ class DeadlyCorridorVlaEnvAdapter(EnvAdapter):
15
+ export_env_raw_rgb_frames: bool = True,
16
+ ):
17
+ import gymnasium as gym
18
+ + import vizdoom
19
+ import vizdoom.gymnasium_wrapper # noqa: F401 (registers the env ids)
20
+
21
+ env_cfg = config["env"]
22
+ @@ -360,30 +361,27 @@ class DeadlyCorridorVlaEnvAdapter(EnvAdapter):
23
+ )
24
+ if key in env_cfg
25
+ }
26
+ - attempts = [
27
+ - ("VizdoomDeadlyCorridor-MultiBinary-v1", {}),
28
+ - ("VizdoomDeadlyCorridor-MultiBinary-v0", {}),
29
+ - ("VizdoomDeadlyCorridor-v1", {"max_buttons_pressed": 0}),
30
+ - ("VizdoomDeadlyCorridor-v0", {"max_buttons_pressed": 0}),
31
+ - ]
32
+ - last_exc: Exception | None = None
33
+ - self.gym_env = None
34
+ - for env_id, kwargs in attempts:
35
+ - try:
36
+ - # frame_skip=1: the latency_bench scheduler advances obs_stride raw
37
+ - # frames per decision and holds the action between observations.
38
+ - self.gym_env = gym.make(
39
+ - env_id, render_mode="rgb_array", frame_skip=1, **render_options, **kwargs
40
+ - )
41
+ - self.env_id = env_id
42
+ - break
43
+ - except (gym.error.NameNotFound, gym.error.VersionNotFound, gym.error.NamespaceNotFound) as exc:
44
+ - last_exc = exc
45
+ - if self.gym_env is None:
46
+ - raise RuntimeError(f"Failed to create Deadly Corridor MultiBinary env: {last_exc}")
47
+ + # ViZDoom registers deadly_corridor.cfg under this official Gym ID.
48
+ + self.env_id = "VizdoomCorridor-v0"
49
+ + self.gym_env = gym.make(
50
+ + self.env_id, render_mode="rgb_array", frame_skip=1, max_buttons_pressed=0,
51
+ + )
52
+ + game = self.gym_env.unwrapped.game
53
+ + game.close()
54
+ + for key, value in render_options.items():
55
+ + if key == "screen_resolution":
56
+ + value = getattr(vizdoom.ScreenResolution, value)
57
+ + getattr(game, f"set_{key}")(value)
58
+ + game.init()
59
+ + self.gym_env.unwrapped.observation_space.spaces["screen"] = Box(
60
+ + 0, 255,
61
+ + shape=(game.get_screen_height(), game.get_screen_width(), game.get_screen_channels()),
62
+ + dtype=np.uint8,
63
+ + )
64
+
65
+ self._runtime_button_order = _deadly_runtime_button_names(self.gym_env)
66
+ self._num_buttons = len(self._runtime_button_order)
67
+ + self.gym_env.unwrapped.action_space = MultiBinary(self._num_buttons)
68
+ self.noop_action = noop_action or Action(
69
+ value=[0] * self._num_buttons, name="NOOP", is_noop=True
70
+ )
71
+ diff --git a/tests/integration/test_deadly_render_contract.py b/tests/integration/test_deadly_render_contract.py
72
+ index 535db22a..09894b1b 100644
73
+ --- a/tests/integration/test_deadly_render_contract.py
74
+ +++ b/tests/integration/test_deadly_render_contract.py
75
+ @@ -5,11 +5,13 @@ import json
76
+ import numpy as np
77
+ import pytest
78
+
79
+ -pytest.importorskip("vizdoom", minversion="1.3.0")
80
+ +pytest.importorskip("vizdoom", minversion="1.2.4")
81
+ pytest.importorskip("sample_factory")
82
+
83
+ from latency_bench.envs.deadly_corridor import DeadlyCorridorEnvAdapter, DeadlyCorridorVlaEnvAdapter
84
+ from latency_bench.envs.raw_rgb import ENV_RAW_RGB_FRAME_STACK_INFO_KEY
85
+ +from latency_bench.core.types import Action
86
+ +from gymnasium.spaces import MultiBinary
87
+ from scripts.tasks.decision_history.eval_vla_hist8 import evaluation_config
88
+
89
+
90
+ @@ -33,6 +35,9 @@ def test_hist8_deadly_vla_uses_the_teacher_resolution_and_hud(tmp_path):
91
+ # The health/ammo panel is stable across the two engine reset paths;
92
+ # the animated face and enemies can differ with their RNG streams.
93
+ np.testing.assert_array_equal(teacher_frame[-20:, :64], student_frame[-20:, :64])
94
+ + assert isinstance(student.gym_env.action_space, MultiBinary)
95
+ + step = student.step(Action(value=[1, 0, 0, 0, 0, 0, 1], name="forward_attack"))
96
+ + assert np.isfinite(step.reward)
97
+ finally:
98
+ teacher.close()
99
+ student.close()
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/deadly_corridor.py ADDED
@@ -0,0 +1,455 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import copy
4
+ from collections import deque
5
+ from typing import Any
6
+
7
+ import numpy as np
8
+ from gymnasium.spaces import Box, MultiBinary, Tuple
9
+
10
+ from latency_bench.core.types import Action, Observation, StepResult
11
+ from latency_bench.envs.base import EnvAdapter
12
+ from latency_bench.utils.array import looks_chw
13
+ from latency_bench.envs.raw_rgb import RawRgbFrameStackBuffer
14
+
15
+
16
+ def _noop_action_from_space(space) -> Any:
17
+ n = getattr(space, "n", None)
18
+ if n is not None:
19
+ return 0
20
+ if isinstance(space, Tuple):
21
+ return tuple(_noop_action_from_space(subspace) for subspace in space.spaces)
22
+ if isinstance(space, Box):
23
+ import numpy as np
24
+
25
+ return np.zeros(space.shape, dtype=space.dtype)
26
+ raise TypeError(f"Unsupported action space for Deadly Corridor no-op action: {space}")
27
+
28
+
29
+ def _coerce_noop_action_for_space(value: Any, space) -> Any:
30
+ if isinstance(space, Tuple):
31
+ if isinstance(value, (list, tuple)):
32
+ if len(value) != len(space.spaces):
33
+ raise ValueError(
34
+ f"Deadly Corridor no-op action length {len(value)} does not match action space {space}"
35
+ )
36
+ return tuple(
37
+ _coerce_noop_action_for_space(item, subspace)
38
+ for item, subspace in zip(value, space.spaces)
39
+ )
40
+ if value == 0:
41
+ return _noop_action_from_space(space)
42
+ return value
43
+
44
+
45
+ def _spec_with_reward_scaling(spec: Any, disable_reward_scaling: bool) -> Any:
46
+ if not disable_reward_scaling:
47
+ return spec
48
+ spec_to_use = copy.copy(spec)
49
+ spec_to_use.reward_scaling = 1.0
50
+ return spec_to_use
51
+
52
+
53
+ def _synchronous_eval_fps_from_config(config: dict[str, Any], default: int = 35) -> int:
54
+ env_cfg = config.get("env", {})
55
+ try:
56
+ fps = int(float(env_cfg.get("env_fps", default)))
57
+ except (TypeError, ValueError) as exc:
58
+ raise ValueError("env_fps must be positive") from exc
59
+ if fps <= 0:
60
+ raise ValueError("env_fps must be positive")
61
+ return fps
62
+
63
+
64
+ def _build_sample_factory_eval_cfg(config: dict[str, Any]) -> Any:
65
+ from training.deadly_corridor_sf import integration
66
+ from training.common.utils import maybe_set_cli_override
67
+
68
+ integration.register_deadly_corridor_components()
69
+ base_cfg = integration.SAMPLE_FACTORY_CONFIG_PARSER.parse_eval(
70
+ integration.build_cli_args_from_config(config)
71
+ )
72
+ eval_fps = _synchronous_eval_fps_from_config(config)
73
+ cfg = copy.deepcopy(base_cfg)
74
+ if _requires_sample_factory_checkpoint_config(config):
75
+ from sample_factory.cfg.arguments import load_from_checkpoint
76
+
77
+ cfg = load_from_checkpoint(cfg)
78
+
79
+ for key in (
80
+ "seed",
81
+ "res_w",
82
+ "res_h",
83
+ "wide_aspect_ratio",
84
+ ):
85
+ if hasattr(base_cfg, key):
86
+ maybe_set_cli_override(cfg, key, getattr(base_cfg, key))
87
+ maybe_set_cli_override(cfg, "frame_stack", 1)
88
+ explicit_max_episode_steps = int(getattr(base_cfg, "max_episode_steps", 0) or 0)
89
+ if explicit_max_episode_steps > 0:
90
+ maybe_set_cli_override(cfg, "max_episode_steps", explicit_max_episode_steps)
91
+ else:
92
+ eval_max_steps = int(getattr(base_cfg, "eval_max_steps", 0) or 0)
93
+ if eval_max_steps > 0:
94
+ maybe_set_cli_override(cfg, "max_episode_steps", eval_max_steps)
95
+
96
+ maybe_set_cli_override(cfg, "mode", "eval")
97
+ maybe_set_cli_override(cfg, "latency_type", "zero")
98
+ maybe_set_cli_override(cfg, "fixed_latency_ms", 0.0)
99
+ maybe_set_cli_override(cfg, "env_frameskip", 1)
100
+ maybe_set_cli_override(cfg, "eval_env_frameskip", 1)
101
+ maybe_set_cli_override(cfg, "num_envs", 1)
102
+ maybe_set_cli_override(cfg, "no_render", True)
103
+ maybe_set_cli_override(cfg, "save_video", False)
104
+ maybe_set_cli_override(cfg, "fps", eval_fps)
105
+ maybe_set_cli_override(cfg, "eval_deterministic", bool(getattr(base_cfg, "eval_deterministic", True)))
106
+ maybe_set_cli_override(cfg, "disable_reward_scaling", bool(getattr(base_cfg, "eval_raw_reward", False)))
107
+ return cfg
108
+
109
+
110
+ def _requires_sample_factory_checkpoint_config(config: dict[str, Any]) -> bool:
111
+ policy_type = str(config.get("policy", {}).get("type", "")).strip().lower()
112
+ return policy_type == "deadly_corridor_sf"
113
+
114
+
115
+ def _seed_initialized_vizdoom_game(env: Any, seed: int) -> bool:
116
+ unwrapped = getattr(env, "unwrapped", env)
117
+ game = getattr(unwrapped, "game", None)
118
+ if game is None:
119
+ return False
120
+ unwrapped.seed(int(seed))
121
+ game.set_seed(int(unwrapped.curr_seed))
122
+ return True
123
+
124
+
125
+ class DeadlyCorridorEnvAdapter(EnvAdapter):
126
+ """Latency-bench adapter for ViZDoom Deadly Corridor using the SF Doom env stack."""
127
+ OBSERVATION_TYPE = "vizdoom_frame_v1"
128
+
129
+ def __init__(
130
+ self,
131
+ *,
132
+ config: dict[str, Any],
133
+ noop_action: Action | None = None,
134
+ export_env_raw_rgb_frames: bool = False,
135
+ ):
136
+ env_cfg = config["env"]
137
+ env_id = str(env_cfg.get("env_id", "doom_deadly_corridor"))
138
+ env_fps = float(env_cfg.get("env_fps", 35))
139
+ self.frame_stack = int(env_cfg.get("frame_stack", 1) or 1)
140
+
141
+ from sample_factory.utils.attr_dict import AttrDict
142
+ from sf_examples.vizdoom.doom.doom_utils import DOOM_ENVS, make_doom_env_from_spec
143
+
144
+ cfg = _build_sample_factory_eval_cfg(config)
145
+ spec = next((item for item in DOOM_ENVS if item.name == str(env_id)), None)
146
+ if spec is None:
147
+ raise ValueError(f"Unknown ViZDoom env spec: {env_id}")
148
+ spec_to_use = _spec_with_reward_scaling(
149
+ spec,
150
+ disable_reward_scaling=bool(getattr(cfg, "disable_reward_scaling", False)),
151
+ )
152
+ self.gym_env = make_doom_env_from_spec(
153
+ spec_to_use,
154
+ str(env_id),
155
+ cfg,
156
+ AttrDict(worker_index=0, vector_index=0, env_id=0),
157
+ render_mode=None,
158
+ )
159
+ self.cfg = cfg
160
+ self.env_id = env_id
161
+ self.env_fps = float(env_fps)
162
+ action_space = self.gym_env.action_space
163
+ noop_value = _noop_action_from_space(action_space)
164
+ if noop_action is None:
165
+ self.noop_action = Action(value=noop_value, name=str(noop_value), is_noop=True)
166
+ else:
167
+ coerced_noop_value = _coerce_noop_action_for_space(noop_action.value, action_space)
168
+ self.noop_action = Action(
169
+ value=coerced_noop_value,
170
+ name=str(coerced_noop_value),
171
+ is_noop=True,
172
+ is_oneshot=noop_action.is_oneshot,
173
+ )
174
+ self.env_step = 0
175
+ self.export_env_raw_rgb_frames = bool(export_env_raw_rgb_frames)
176
+ self._last_info: dict[str, Any] = {}
177
+ self._last_frame: Any = None
178
+ self._observed_frames: deque[np.ndarray] = deque(maxlen=self.frame_stack)
179
+ self._raw_rgb_frames = RawRgbFrameStackBuffer(num_frames=self.frame_stack)
180
+
181
+ def reset(self, seed: int | None = None) -> Observation:
182
+ self.env_step = 0
183
+ self._observed_frames.clear()
184
+ if seed is not None:
185
+ if _seed_initialized_vizdoom_game(self.gym_env, int(seed)):
186
+ obs, info = self.gym_env.reset()
187
+ else:
188
+ try:
189
+ obs, info = self.gym_env.reset(seed=seed)
190
+ except TypeError:
191
+ obs, info = self.gym_env.reset()
192
+ else:
193
+ obs, info = self.gym_env.reset()
194
+ self._last_frame = obs
195
+ self._last_info = dict(info or {})
196
+ self._reset_frame_stack(obs)
197
+ if self.export_env_raw_rgb_frames:
198
+ self._reset_raw_rgb_frame_stack()
199
+ return self._make_observation(info=self._last_info)
200
+
201
+ def step(self, action: Action) -> StepResult:
202
+ gym_action = action.value
203
+ obs, reward, terminated, truncated, info = self.gym_env.step(gym_action)
204
+ self.env_step += 1
205
+ self._last_frame = obs
206
+ self._last_info = dict(info or {})
207
+ self._append_frame(obs)
208
+ if self.export_env_raw_rgb_frames and not bool(terminated or truncated):
209
+ self._append_raw_rgb_frame()
210
+ observation = self._make_observation(info=self._last_info)
211
+ step_info = dict(self._last_info)
212
+ step_info.update(
213
+ {
214
+ "env_step": self.env_step,
215
+ "sim_time_ms": self.env_step * self.frame_ms,
216
+ "applied_action": gym_action,
217
+ "applied_action_name": action.name,
218
+ "observation": "vizdoom_frame_v1",
219
+ }
220
+ )
221
+ return StepResult(
222
+ observation=observation,
223
+ reward=float(reward),
224
+ done=bool(terminated),
225
+ truncated=bool(truncated),
226
+ info=step_info,
227
+ )
228
+
229
+ def observe(self) -> Observation:
230
+ if self._last_frame is None:
231
+ raise RuntimeError("DeadlyCorridorEnvAdapter has no current observation; call reset() first")
232
+ metadata = self._metadata(self._last_info)
233
+ return Observation(
234
+ data=self._policy_frame_stack(),
235
+ env_step=self.env_step,
236
+ sim_time_ms=self.env_step * self.frame_ms,
237
+ metadata=metadata,
238
+ )
239
+
240
+ def render_game_frame(self) -> np.ndarray:
241
+ return np.transpose(self.gym_env.unwrapped.game.get_state().screen_buffer, (1, 2, 0))
242
+
243
+ def close(self) -> None:
244
+ self.gym_env.close()
245
+
246
+ def _reset_frame_stack(self, frame: Any) -> None:
247
+ self._observed_frames.clear()
248
+ self._append_frame(frame)
249
+
250
+ def _append_frame(self, frame: Any) -> None:
251
+ self._observed_frames.append(_single_frame_data(frame))
252
+
253
+ def _policy_frame_stack(self) -> np.ndarray:
254
+ frames = list(self._observed_frames)
255
+ if not frames:
256
+ raise RuntimeError("Deadly Corridor observe() has no current frame; call reset() first")
257
+ if len(frames) < self.frame_stack:
258
+ frames = [frames[0]] * (self.frame_stack - len(frames)) + frames
259
+ frames = [np.asarray(frame, dtype=np.uint8) for frame in frames[-self.frame_stack :]]
260
+ if self.frame_stack == 1:
261
+ return frames[-1]
262
+ axis = 0 if looks_chw(frames[0]) else -1
263
+ return np.concatenate(frames, axis=axis)
264
+
265
+
266
+ def _single_frame_data(frame: Any) -> np.ndarray:
267
+ value = frame.get("obs") if isinstance(frame, dict) else frame
268
+ arr = np.asarray(value, dtype=np.uint8)
269
+ if arr.ndim == 2:
270
+ return arr[..., None]
271
+ if arr.ndim != 3:
272
+ raise ValueError(f"Expected Deadly Corridor image frame with 2 or 3 dims, got {arr.shape!r}")
273
+ return arr
274
+
275
+
276
+ # Fixed semantic button order the StarVLA multibinary head is trained against.
277
+ # Mirrors starVLA.training.rl_games.eval_core._semantic_to_runtime_multibinary.
278
+ DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER = (
279
+ "MOVE_FORWARD",
280
+ "MOVE_BACKWARD",
281
+ "MOVE_LEFT",
282
+ "MOVE_RIGHT",
283
+ "TURN_LEFT",
284
+ "TURN_RIGHT",
285
+ "ATTACK",
286
+ )
287
+
288
+
289
+ def _deadly_runtime_button_names(gym_env: Any) -> list[str]:
290
+ """Return the live ViZDoom action-button order (ports eval_core helper).
291
+
292
+ The MultiBinary action vector is indexed by the game's available-button
293
+ order, which is not guaranteed to equal the semantic order the head emits.
294
+ """
295
+
296
+ def _button_name(button: Any) -> str:
297
+ name = getattr(button, "name", None)
298
+ if name is not None:
299
+ return str(name)
300
+ text = str(button)
301
+ return text.split(".")[-1] if "." in text else text
302
+
303
+ for candidate in (gym_env, getattr(gym_env, "unwrapped", None)):
304
+ if candidate is None:
305
+ continue
306
+ for attr_name in ("game", "_game"):
307
+ game = getattr(candidate, attr_name, None)
308
+ if game is None:
309
+ continue
310
+ getter = getattr(game, "get_available_buttons", None)
311
+ if getter is None:
312
+ continue
313
+ names = [_button_name(button) for button in getter()]
314
+ if names:
315
+ return names
316
+ return list(DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER)
317
+
318
+
319
+ def _semantic_to_runtime_multibinary(semantic_values: list[int], runtime_order: list[str]) -> list[int]:
320
+ semantic_map = {
321
+ name: int(semantic_values[idx])
322
+ for idx, name in enumerate(DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER)
323
+ if idx < len(semantic_values)
324
+ }
325
+ return [semantic_map.get(name, 0) for name in runtime_order]
326
+
327
+
328
+ class DeadlyCorridorVlaEnvAdapter(EnvAdapter):
329
+ """Deadly Corridor adapter for StarVLA eval, matching eval_core's env.
330
+
331
+ Unlike :class:`DeadlyCorridorEnvAdapter` (sample_factory, factorised action
332
+ tuple), this uses the gymnasium ``VizdoomDeadlyCorridor-MultiBinary`` env so
333
+ the model's multibinary head can fire arbitrary button subsets, exactly like
334
+ ``starVLA.training.rl_games.eval_core``. Native ``frame_skip=1`` is used so
335
+ latency_bench's observation-cadence scheduler owns the obs_stride stepping
336
+ (see ObservationCadenceDecisionScheduler); setting a native skip would
337
+ double-count it.
338
+ """
339
+
340
+ OBSERVATION_TYPE = "vizdoom_frame_v1"
341
+
342
+ def __init__(
343
+ self,
344
+ *,
345
+ config: dict[str, Any],
346
+ noop_action: Action | None = None,
347
+ export_env_raw_rgb_frames: bool = True,
348
+ ):
349
+ import gymnasium as gym
350
+ import vizdoom
351
+ import vizdoom.gymnasium_wrapper # noqa: F401 (registers the env ids)
352
+
353
+ env_cfg = config["env"]
354
+ self.env_fps = float(env_cfg.get("env_fps", 35))
355
+ self.frame_stack = int(env_cfg.get("frame_stack", 1) or 1)
356
+ # The raw teacher view is part of the policy's observation contract.
357
+ render_options = {
358
+ key: env_cfg[key]
359
+ for key in (
360
+ "screen_resolution", "render_hud", "render_crosshair",
361
+ "render_weapon", "render_decals", "render_particles",
362
+ )
363
+ if key in env_cfg
364
+ }
365
+ # ViZDoom registers deadly_corridor.cfg under this official Gym ID.
366
+ self.env_id = "VizdoomCorridor-v0"
367
+ self.gym_env = gym.make(
368
+ self.env_id, render_mode="rgb_array", frame_skip=1, max_buttons_pressed=0,
369
+ )
370
+ game = self.gym_env.unwrapped.game
371
+ game.close()
372
+ for key, value in render_options.items():
373
+ if key == "screen_resolution":
374
+ value = getattr(vizdoom.ScreenResolution, value)
375
+ getattr(game, f"set_{key}")(value)
376
+ game.init()
377
+ self.gym_env.unwrapped.observation_space.spaces["screen"] = Box(
378
+ 0, 255,
379
+ shape=(game.get_screen_height(), game.get_screen_width(), game.get_screen_channels()),
380
+ dtype=np.uint8,
381
+ )
382
+
383
+ self._runtime_button_order = _deadly_runtime_button_names(self.gym_env)
384
+ self._num_buttons = len(self._runtime_button_order)
385
+ self.gym_env.unwrapped.action_space = MultiBinary(self._num_buttons)
386
+ self.noop_action = noop_action or Action(
387
+ value=[0] * self._num_buttons, name="NOOP", is_noop=True
388
+ )
389
+ self.export_env_raw_rgb_frames = bool(export_env_raw_rgb_frames)
390
+ self.env_step = 0
391
+ self._last_info: dict[str, Any] = {}
392
+ self._last_frame: Any = None
393
+ self._raw_rgb_frames = RawRgbFrameStackBuffer(num_frames=self.frame_stack)
394
+
395
+ def reset(self, seed: int | None = None) -> Observation:
396
+ self.env_step = 0
397
+ try:
398
+ obs, info = self.gym_env.reset(seed=seed)
399
+ except TypeError:
400
+ obs, info = self.gym_env.reset()
401
+ self._last_frame = obs
402
+ self._last_info = dict(info or {})
403
+ if self.export_env_raw_rgb_frames:
404
+ self._reset_raw_rgb_frame_stack()
405
+ return self._make_observation(info=self._last_info)
406
+
407
+ def step(self, action: Action) -> StepResult:
408
+ # action.value is a 7-dim multibinary vector in semantic order; re-order
409
+ # to the live game's button layout before stepping the MultiBinary env.
410
+ semantic = [int(v) for v in np.asarray(action.value).reshape(-1).tolist()]
411
+ expected = len(DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER)
412
+ if len(semantic) != expected:
413
+ raise ValueError(
414
+ "DeadlyCorridorVlaEnvAdapter expects a "
415
+ f"{expected}-dim multibinary action in semantic order, got "
416
+ f"{len(semantic)} values ({action.value!r}). This usually means the "
417
+ "policy decoded a non-multibinary layout; ensure the deadly head is "
418
+ "action_layout=multibinary_7 and reached the multibinary decode path."
419
+ )
420
+ runtime_buttons = _semantic_to_runtime_multibinary(semantic, self._runtime_button_order)
421
+ gym_action = np.asarray(runtime_buttons, dtype=np.int8)
422
+ obs, reward, terminated, truncated, info = self.gym_env.step(gym_action)
423
+ self.env_step += 1
424
+ self._last_frame = obs
425
+ self._last_info = dict(info or {})
426
+ if self.export_env_raw_rgb_frames and not bool(terminated or truncated):
427
+ self._append_raw_rgb_frame()
428
+ observation = self._make_observation(info=self._last_info)
429
+ step_info = dict(self._last_info)
430
+ step_info.update(
431
+ {
432
+ "env_step": self.env_step,
433
+ "sim_time_ms": self.env_step * self.frame_ms,
434
+ "applied_action": runtime_buttons,
435
+ "applied_action_name": action.name,
436
+ "observation": self.OBSERVATION_TYPE,
437
+ }
438
+ )
439
+ return StepResult(
440
+ observation=observation,
441
+ reward=float(reward),
442
+ done=bool(terminated),
443
+ truncated=bool(truncated),
444
+ info=step_info,
445
+ )
446
+
447
+ def observe(self) -> Observation:
448
+ return self._make_observation(info=self._last_info)
449
+
450
+ def render_game_frame(self) -> np.ndarray:
451
+ frame = self.gym_env.render()
452
+ return np.asarray(frame, dtype=np.uint8)
453
+
454
+ def close(self) -> None:
455
+ self.gym_env.close()
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/decision_action_history.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Causal action history sampled at completed decision boundaries."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import numpy as np
6
+ from gymnasium.spaces import Discrete, MultiBinary, Tuple
7
+
8
+
9
+ class DecisionActionHistory:
10
+ """Encode admission, admitted command, and last applied action for each decision."""
11
+
12
+ def __init__(self, action_space, *, num_envs: int, decisions: int):
13
+ self._multibinary = isinstance(action_space, MultiBinary)
14
+ if isinstance(action_space, Discrete):
15
+ self.action_sizes = (action_space.n,)
16
+ elif isinstance(action_space, Tuple) and all(isinstance(space, Discrete) for space in action_space.spaces):
17
+ self.action_sizes = tuple(space.n for space in action_space.spaces)
18
+ elif self._multibinary and action_space.shape == (7,):
19
+ self.action_sizes = (3, 3, 3, 2)
20
+ else:
21
+ raise NotImplementedError(f"Decision action history does not support {action_space!r}")
22
+ self.decisions = decisions
23
+ self.action_dim = sum(size - 1 for size in self.action_sizes)
24
+ self.step_dim = 1 + 2 * self.action_dim
25
+ self.data = np.zeros((num_envs, decisions, self.step_dim), dtype=np.float32)
26
+ self._basis = tuple(np.eye(size, dtype=np.float32)[:, 1:] for size in self.action_sizes)
27
+
28
+ @property
29
+ def observation_dim(self) -> int:
30
+ return self.decisions * self.step_dim
31
+
32
+ def reset(self, indices=None) -> None:
33
+ if indices is None:
34
+ self.data.fill(0)
35
+ else:
36
+ self.data[indices] = 0
37
+
38
+ def append(self, indices, admitted, issued_actions, applied_actions) -> None:
39
+ admitted = np.asarray(admitted, dtype=np.float32).reshape(-1)
40
+ issued = self._encode(issued_actions) * admitted[:, None]
41
+ applied = self._encode(applied_actions)
42
+ rows = self.data[indices].copy()
43
+ rows[:, :-1] = rows[:, 1:]
44
+ rows[:, -1, 0] = admitted
45
+ rows[:, -1, 1 : 1 + self.action_dim] = issued
46
+ rows[:, -1, 1 + self.action_dim :] = applied
47
+ self.data[indices] = rows
48
+
49
+ def observation(self) -> np.ndarray:
50
+ return self.data.reshape(self.data.shape[0], self.observation_dim).copy()
51
+
52
+ def _encode(self, actions) -> np.ndarray:
53
+ if self._multibinary:
54
+ # The VLA button order is move, strafe, turn, attack; teacher history
55
+ # encodes turn, move, strafe, attack. Keep both opposing bits if issued.
56
+ return np.asarray(actions, dtype=np.float32).reshape(-1, 7)[:, [4, 5, 0, 1, 2, 3, 6]]
57
+ values = np.asarray(actions, dtype=np.int64).reshape(-1, len(self.action_sizes))
58
+ return np.concatenate(
59
+ [basis[values[:, index]] for index, basis in enumerate(self._basis)], axis=1
60
+ )
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/eval_driver.py ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Single evaluation driver: run one config's episodes and attach metadata.
2
+
3
+ This is the core ``run_from_config`` and its episode-side helpers. Sweep/suite
4
+ orchestration lives in :mod:`latency_bench.eval.sweeps`; the CLI in
5
+ :mod:`latency_bench.run`.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from collections.abc import Callable, Sequence
10
+ from pathlib import Path
11
+ from typing import Any
12
+
13
+ import yaml
14
+
15
+ from training.common.utils import seed_everything
16
+ from latency_bench.core.types import EpisodeMetrics, ExecutorMode
17
+ from latency_bench.eval.config import (
18
+ _episode_seed,
19
+ _eval_episodes,
20
+ _eval_max_steps,
21
+ _evaluation_seed,
22
+ resolve_evaluation_config,
23
+ )
24
+ from latency_bench.eval.reporting import _write_non_sweep_summary
25
+ from latency_bench.envs.base import EnvAdapter
26
+ from latency_bench.executors.base import BatchedExecutor
27
+ from latency_bench.executors.factory import build_executor
28
+ from latency_bench.executors.realtime_warmup import plot_realtime_eval_latency
29
+ from latency_bench.latency.config import latency_type_from_config
30
+ from latency_bench.logging.action_trace_replay import record_videos_from_action_trace
31
+ from latency_bench.logging.video import select_episode_return_stratified
32
+
33
+
34
+ def run_from_config(
35
+ config: dict[str, Any],
36
+ extra_metadata: dict[str, Any] | None = None,
37
+ *,
38
+ write_summary: bool = True,
39
+ on_episode_complete: Callable[[EpisodeMetrics], None] | None = None,
40
+ episode_ids: Sequence[int] | None = None,
41
+ policy: Any | None = None,
42
+ env: EnvAdapter | None = None,
43
+ env_backend: Any | None = None,
44
+ inference_devices: list[str] | None = None,
45
+ ) -> list[EpisodeMetrics]:
46
+ eval_max_steps = _eval_max_steps(config)
47
+ resolve_evaluation_config(config)
48
+ if (
49
+ policy is None
50
+ and env is None
51
+ and env_backend is None
52
+ and config["policy"]["type"] == "starvla"
53
+ ):
54
+ from latency_bench.policy.starvla import prepare_starvla_checkpoint_input_config
55
+
56
+ prepare_starvla_checkpoint_input_config(config)
57
+
58
+ experiment_cfg = config["experiment"]
59
+ policy_cfg = config["policy"]
60
+ logging_cfg = config["logging"]
61
+ seed = _evaluation_seed(config)
62
+ configured_num_episodes = _eval_episodes(config)
63
+ selected_episode_ids = list(range(configured_num_episodes)) if episode_ids is None else list(episode_ids)
64
+ seed_everything(seed)
65
+
66
+ executor_kwargs = {}
67
+ if policy is not None:
68
+ executor_kwargs["policy"] = policy
69
+ if env is not None:
70
+ executor_kwargs["env"] = env
71
+ if env_backend is not None:
72
+ executor_kwargs["env_backend"] = env_backend
73
+ if inference_devices is not None:
74
+ executor_kwargs["inference_devices"] = inference_devices
75
+ executor = build_executor(config, **executor_kwargs)
76
+ metrics = []
77
+ warmup_metadata_by_episode: dict[int, dict[str, Any]] = {}
78
+ try:
79
+ output_dir = Path(logging_cfg["output_dir"])
80
+ output_dir.mkdir(parents=True, exist_ok=True)
81
+ (output_dir / "resolved_config.yaml").write_text(
82
+ yaml.safe_dump(config, sort_keys=False), encoding="utf-8"
83
+ )
84
+ if isinstance(executor, BatchedExecutor):
85
+ warmup_metadata = executor.run_warmup()
86
+ run_episodes_kwargs: dict[str, Any] = {
87
+ "episode_ids": selected_episode_ids,
88
+ "seeds": [_episode_seed(config, episode_id) for episode_id in selected_episode_ids],
89
+ "eval_max_steps": eval_max_steps,
90
+ }
91
+ if on_episode_complete is not None:
92
+ run_episodes_kwargs["on_episode_complete"] = on_episode_complete
93
+ metrics = list(executor.run_episodes(**run_episodes_kwargs))
94
+ warmup_metadata_by_episode.update(
95
+ (episode_id, warmup_metadata) for episode_id in selected_episode_ids
96
+ )
97
+ else:
98
+ warmup_metadata = executor.run_warmup()
99
+ for episode_id in selected_episode_ids:
100
+ warmup_metadata_by_episode[episode_id] = warmup_metadata
101
+ episode_metrics = executor.run_episode(
102
+ episode_id=episode_id,
103
+ seed=_episode_seed(config, episode_id),
104
+ eval_max_steps=eval_max_steps,
105
+ )
106
+ metrics.append(episode_metrics)
107
+ if on_episode_complete is not None:
108
+ on_episode_complete(episode_metrics)
109
+ metrics.sort(key=lambda item: int(item.episode_id))
110
+ for episode_metrics in metrics:
111
+ for key, value in _evaluation_raw_fact_metadata(config, int(episode_metrics.episode_id)).items():
112
+ if episode_metrics.metadata.get(key) is None:
113
+ episode_metrics.metadata[key] = value
114
+ episode_metrics.metadata.update(warmup_metadata_by_episode[int(episode_metrics.episode_id)])
115
+ if "measurement" in config:
116
+ episode_metrics.metadata["measurement"] = config["measurement"]
117
+ episode_metrics.metadata["config_name"] = experiment_cfg.get("name")
118
+ episode_metrics.metadata["run_name"] = experiment_cfg.get("name")
119
+ if "checkpoint_path" in policy_cfg:
120
+ episode_metrics.metadata["checkpoint_path"] = policy_cfg["checkpoint_path"]
121
+ if "profile_path" in config["latency"]:
122
+ episode_metrics.metadata["source_profile_path"] = config["latency"]["profile_path"]
123
+ if "checkpoint_kind" in policy_cfg:
124
+ episode_metrics.metadata["checkpoint_kind"] = str(policy_cfg["checkpoint_kind"])
125
+ episode_metrics.metadata["output_dir"] = str(logging_cfg["output_dir"])
126
+ if "action_prefix" in policy_cfg:
127
+ episode_metrics.metadata["action_prefix"] = policy_cfg["action_prefix"]
128
+ if extra_metadata:
129
+ episode_metrics.metadata.update(extra_metadata)
130
+ if executor.logger is not None:
131
+ executor.logger.flush()
132
+ _record_realtime_eval_latency_plot(config, executor)
133
+ if write_summary:
134
+ _write_non_sweep_summary(config, metrics)
135
+ _record_stratified_replay_videos(config, metrics, seed=seed)
136
+ finally:
137
+ executor.close()
138
+ return metrics
139
+
140
+
141
+ def _record_realtime_eval_latency_plot(config: dict[str, Any], executor: Any) -> None:
142
+ if ExecutorMode(config["executor"]["mode"]) != ExecutorMode.REALTIME:
143
+ return
144
+ if not config["logging"]["save_latency_records"]:
145
+ return
146
+
147
+ latency_values = list(executor.logger.latency_ms_values)
148
+ plot_realtime_eval_latency(
149
+ latency_values,
150
+ Path(config["logging"]["output_dir"]) / "eval_latency_trace.png",
151
+ )
152
+
153
+
154
+ def _record_stratified_replay_videos(
155
+ config: dict[str, Any],
156
+ metrics: list[EpisodeMetrics],
157
+ *,
158
+ seed: int,
159
+ ) -> None:
160
+ if "video" not in config["logging"]:
161
+ return
162
+ video_cfg = config["logging"]["video"]
163
+ if not video_cfg["enabled"]:
164
+ return
165
+ if not config["logging"]["save_step_records"]:
166
+ # Replay reads steps.jsonl, which is only written when save_step_records is on.
167
+ # Without it (e.g. factor-sweep evals) skip video instead of crashing on a missing file.
168
+ return
169
+ if ExecutorMode(config["executor"]["mode"]) == ExecutorMode.REALTIME:
170
+ return
171
+ selections = select_episode_return_stratified(
172
+ metrics,
173
+ num_bins=video_cfg["num_bins"],
174
+ seed=seed,
175
+ )
176
+ record_videos_from_action_trace(config, selections=selections, metrics=metrics)
177
+
178
+
179
+ def _evaluation_raw_fact_metadata(config: dict[str, Any], episode_id: int) -> dict[str, Any]:
180
+ env_cfg = config.get("env", {})
181
+ policy_cfg = config.get("policy", {})
182
+ latency_cfg = config.get("latency", {})
183
+ executor_cfg = config.get("executor", {})
184
+ env_fps = float(env_cfg["env_fps"]) if "env_fps" in env_cfg else None
185
+ obs_fps = float(env_cfg["obs_fps"]) if "obs_fps" in env_cfg else None
186
+ frame_ms = None if env_fps is None or env_fps <= 0 else 1000.0 / env_fps
187
+ executor_mode = str(executor_cfg.get("mode", "")).strip().lower()
188
+ latency_type = latency_type_from_config(latency_cfg)
189
+ if executor_mode == "paused":
190
+ latency_type = "zero"
191
+ elif executor_mode == "realtime":
192
+ latency_type = "measured"
193
+ return {
194
+ "mode": executor_cfg.get("mode"),
195
+ "episode_seed": _episode_seed(config, episode_id),
196
+ "policy_id": _metadata_id(policy_cfg, "policy_id", "id", "type"),
197
+ "env_id": _metadata_id(env_cfg, "env_id", "id", "name"),
198
+ "model_id": latency_cfg.get("model_id"),
199
+ "gpu_class": latency_cfg.get("gpu_class"),
200
+ "workload_id": latency_cfg.get("workload_id"),
201
+ "instance_id": latency_cfg.get("instance_id"),
202
+ "source_run_id": latency_cfg.get("source_run_id"),
203
+ "profile_ref": latency_cfg.get("profile_ref"),
204
+ "env_fps": env_fps,
205
+ "obs_fps": obs_fps,
206
+ "frame_ms": frame_ms,
207
+ "latency_type": latency_type,
208
+ }
209
+
210
+
211
+ def _metadata_id(config: dict[str, Any], *keys: str) -> str | None:
212
+ for key in keys:
213
+ value = config.get(key)
214
+ if value is not None:
215
+ return str(value)
216
+ return None
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/mikasa_evaluate.py ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import json
6
+ import sys
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ import gymnasium as gym
11
+ import numpy as np
12
+ import torch
13
+ import yaml
14
+
15
+
16
+ ROOT = Path(__file__).resolve().parents[2]
17
+ sys.path.insert(0, str(ROOT))
18
+ sys.path.insert(0, str(ROOT / "third_party" / "MIKASA-Robo"))
19
+
20
+ from latency_bench.core.types import Action, Observation # noqa: E402
21
+ from latency_bench.executors.gpu_batched_env_step_backend import ( # noqa: E402
22
+ GpuBatchedEnvStepBackendBase,
23
+ SlotStepOutcome,
24
+ )
25
+ from mikasa_robo_suite.seed_reset import ( # noqa: E402
26
+ reset_seeded_slot as _reset_seeded_slot,
27
+ reset_seeded_slots as _reset_seeded_slots,
28
+ )
29
+
30
+
31
+ ENV_ID = "InterceptGrabFast-VLA-v0"
32
+ INSTRUCTION = "Intercept the rolling ball and grasp it to stop it."
33
+ START_SEED = 4242424242
34
+ MIKASA_IMAGE_VIEWS_INFO_KEY = "mikasa_image_views"
35
+ MIKASA_STATE_INFO_KEY = "mikasa_proprio"
36
+
37
+
38
+ def _scalar(value: Any) -> Any:
39
+ if torch.is_tensor(value):
40
+ return value.detach().reshape(-1)[0].cpu().item()
41
+ return np.asarray(value).reshape(-1)[0].item()
42
+
43
+
44
+ def _make_raw_env(
45
+ obs_mode: str,
46
+ num_envs: int = 1,
47
+ simulator_device: str = "gpu",
48
+ ):
49
+ import mikasa_robo_suite.vla.memory_envs # noqa: F401
50
+
51
+ return gym.make(
52
+ ENV_ID,
53
+ num_envs=num_envs,
54
+ obs_mode=obs_mode,
55
+ control_mode="pd_ee_delta_pose",
56
+ render_mode="all",
57
+ sim_backend=simulator_device,
58
+ render_backend=simulator_device,
59
+ reward_mode="normalized_dense",
60
+ )
61
+
62
+
63
+ def _make_ppo_env(num_envs: int = 1, simulator_device: str = "gpu"):
64
+ from baselines.ppo.ppo_memtasks import FlattenRGBDObservationWrapper
65
+ from mani_skill.vector.wrappers.gymnasium import ManiSkillVectorEnv
66
+ from mikasa_robo_suite.vla.dataset_collectors.get_mikasa_robo_datasets import (
67
+ env_info,
68
+ )
69
+
70
+ env = _make_raw_env(
71
+ "state",
72
+ num_envs=num_envs,
73
+ simulator_device=simulator_device,
74
+ )
75
+ wrappers, _ = env_info(ENV_ID)
76
+ for wrapper, kwargs in wrappers:
77
+ env = wrapper(env, **kwargs)
78
+ env = FlattenRGBDObservationWrapper(env, rgb=False, depth=False, state=True)
79
+ return ManiSkillVectorEnv(
80
+ env,
81
+ num_envs,
82
+ ignore_terminations=True,
83
+ record_metrics=True,
84
+ )
85
+
86
+
87
+ def _make_vla_env(num_envs: int = 1, simulator_device: str = "gpu"):
88
+ from mikasa_robo_suite.vla.utils.apply_wrappers import apply_mikasa_vla_wrappers
89
+
90
+ return apply_mikasa_vla_wrappers(
91
+ _make_raw_env(
92
+ "rgb",
93
+ num_envs=num_envs,
94
+ simulator_device=simulator_device,
95
+ ),
96
+ include_overlays=False,
97
+ )
98
+
99
+
100
+ class _PpoPolicy:
101
+ def __init__(self, env, checkpoint: Path):
102
+ from baselines.ppo.ppo_memtasks import AgentStateOnly
103
+
104
+ self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
105
+ self.agent = AgentStateOnly(env).to(self.device)
106
+ self.agent.load_state_dict(torch.load(checkpoint, map_location=self.device))
107
+ self.agent.eval()
108
+
109
+ def forward(self, observation):
110
+ with torch.no_grad():
111
+ return self.agent.get_action(
112
+ {key: value.to(self.device) for key, value in observation.items()},
113
+ deterministic=True,
114
+ )
115
+
116
+
117
+ class MikasaEnvStepBackend(GpuBatchedEnvStepBackendBase):
118
+ """Own the native MIKASA simulator and its 7D action contract."""
119
+
120
+ backend_name = "mikasa_gpu_batched"
121
+
122
+ def __init__(self, *, config: dict[str, Any], num_slots: int, env=None):
123
+ noop_action = Action(
124
+ value=np.asarray(config["env"]["noop_action"], dtype=np.float32),
125
+ name="noop",
126
+ is_noop=True,
127
+ )
128
+ super().__init__(
129
+ config=config,
130
+ noop_action=noop_action,
131
+ num_slots=num_slots,
132
+ action_space=gym.spaces.Box(-1.0, 1.0, shape=(7,), dtype=np.float32),
133
+ )
134
+ self.env = (
135
+ _make_vla_env(
136
+ num_envs=num_slots,
137
+ simulator_device=config["env"]["simulator_device"],
138
+ )
139
+ if env is None
140
+ else env
141
+ )
142
+ self._episode_seeds = [0] * num_slots
143
+ self._success = np.zeros(num_slots, dtype=np.bool_)
144
+ self._observation, _ = self.env.reset(seed=self._episode_seeds)
145
+
146
+ def _reset_slot_observation(self, slot_id: int, *, seed: int | None) -> Observation:
147
+ if seed is not None:
148
+ self._episode_seeds[slot_id] = int(seed)
149
+ self._observation, _ = _reset_seeded_slot(
150
+ self.env,
151
+ slot_id=slot_id,
152
+ seed=self._episode_seeds[slot_id],
153
+ )
154
+ self._env_steps[slot_id] = 0
155
+ self._success[slot_id] = False
156
+ return self._observation_for_slot(slot_id)
157
+
158
+ def _observe_slot_observations(
159
+ self,
160
+ slot_ids: list[int],
161
+ ) -> dict[int, Observation]:
162
+ return {slot_id: self._observation_for_slot(slot_id) for slot_id in slot_ids}
163
+
164
+ def _step_cores(
165
+ self,
166
+ slot_ids: list[int],
167
+ *,
168
+ actions: np.ndarray,
169
+ active_mask: np.ndarray,
170
+ ) -> Any:
171
+ del slot_ids, active_mask
172
+ tensor_actions = torch.as_tensor(
173
+ actions,
174
+ dtype=torch.float32,
175
+ device=self.env.unwrapped.device,
176
+ )
177
+ self._observation, reward, terminated, truncated, info = self.env.step(
178
+ tensor_actions
179
+ )
180
+ return reward, terminated, truncated, info
181
+
182
+ def _slot_step_outcome(self, state: Any, slot_id: int) -> SlotStepOutcome:
183
+ reward, terminated, truncated, info = state
184
+ success = bool(_slot_value(info["success"], slot_id))
185
+ self._success[slot_id] |= success
186
+ return SlotStepOutcome(
187
+ reward=float(_slot_value(reward, slot_id)),
188
+ done=bool(_slot_value(terminated, slot_id)),
189
+ truncated=bool(_slot_value(truncated, slot_id)),
190
+ info={
191
+ "success": success,
192
+ "task_metrics": {"success": float(self._success[slot_id])},
193
+ },
194
+ )
195
+
196
+ def _observation_for_slot(self, slot_id: int) -> Observation:
197
+ rgb = self._observation["rgb"]
198
+ if torch.is_tensor(rgb):
199
+ rgb = rgb.detach().cpu().numpy()
200
+ rgb = np.asarray(rgb)
201
+ views = np.stack(
202
+ [
203
+ np.asarray(rgb[slot_id, :, :, :3], dtype=np.uint8),
204
+ np.asarray(rgb[slot_id, :, :, 3:6], dtype=np.uint8),
205
+ ]
206
+ )
207
+ metadata = {
208
+ MIKASA_IMAGE_VIEWS_INFO_KEY: views,
209
+ MIKASA_STATE_INFO_KEY: self._observation["proprio"][slot_id].detach().cpu().numpy(),
210
+ "slot_id": slot_id,
211
+ }
212
+ if "action_prefix_state_key" in self.config["env"]:
213
+ metadata["action_prefix_state_key"] = self.config["env"]["action_prefix_state_key"]
214
+ if "returned_action_context" in self.config["env"]:
215
+ context = self.config["env"]["returned_action_context"]
216
+ metadata["returned_action_context"] = {
217
+ **context,
218
+ "order": np.asarray(context["order"]),
219
+ "low": np.asarray(context["low"], dtype=np.float32),
220
+ "high": np.asarray(context["high"], dtype=np.float32),
221
+ }
222
+ return Observation(
223
+ data=None,
224
+ env_step=int(self._env_steps[slot_id]),
225
+ sim_time_ms=float(self._env_steps[slot_id]) * self._frame_ms,
226
+ metadata=metadata,
227
+ )
228
+
229
+ def close(self) -> None:
230
+ if not self.closed:
231
+ self.env.close()
232
+ super().close()
233
+
234
+
235
+ def _slot_value(value: Any, slot_id: int) -> Any:
236
+ if torch.is_tensor(value):
237
+ return value.detach().reshape(-1)[slot_id].cpu().item()
238
+ return np.asarray(value).reshape(-1)[slot_id].item()
239
+
240
+
241
+ def _evaluate(args: argparse.Namespace) -> dict[str, Any]:
242
+ env = _make_ppo_env()
243
+ policy = _PpoPolicy(env, args.checkpoint)
244
+ seeds = []
245
+ successes = []
246
+ returns = []
247
+ lengths = []
248
+ try:
249
+ for episode_index in range(args.episodes):
250
+ seed = START_SEED + episode_index
251
+ observation, _ = env.reset(seed=seed)
252
+ success_once = False
253
+ episode_return = 0.0
254
+ for step in range(60):
255
+ action = policy.forward(observation)
256
+ observation, reward, terminated, truncated, info = env.step(action)
257
+ success_once = success_once or bool(_scalar(info["success"]))
258
+ episode_return += float(_scalar(reward))
259
+ if bool(_scalar(terminated)) or bool(_scalar(truncated)):
260
+ break
261
+ seeds.append(seed)
262
+ successes.append(success_once)
263
+ returns.append(episode_return)
264
+ lengths.append(step + 1)
265
+ finally:
266
+ env.close()
267
+ summary = {
268
+ "seeds": seeds,
269
+ "successes": successes,
270
+ "success_rate": float(np.mean(successes)),
271
+ "returns": returns,
272
+ "lengths": lengths,
273
+ }
274
+ (args.output_dir / "summary.json").write_text(
275
+ json.dumps(summary, indent=2) + "\n", encoding="utf-8"
276
+ )
277
+ return summary
278
+
279
+
280
+ def _latency_eval(argv: list[str]) -> None:
281
+ from latency_bench.core.config import load_config
282
+ from latency_bench.eval.config import apply_runtime_overrides
283
+ from latency_bench.eval.driver import run_from_config
284
+
285
+ parser = argparse.ArgumentParser()
286
+ parser.add_argument("--eval-config", type=Path, required=True)
287
+ parser.add_argument("--checkpoint-path", type=Path)
288
+ parser.add_argument("--model-config-path", type=Path)
289
+ parser.add_argument("--task-contract-path", type=Path)
290
+ parser.add_argument("--run-name")
291
+ parser.add_argument("--output-dir", type=Path)
292
+ parser.add_argument("--latency-method", choices=("zero", "temporal"))
293
+ parser.add_argument("--profile-path", type=Path)
294
+ parser.add_argument("--latency-seed", type=int)
295
+ args = parser.parse_args(argv)
296
+ config = load_config(args.eval_config)
297
+ apply_runtime_overrides(
298
+ config,
299
+ checkpoint_path=args.checkpoint_path,
300
+ model_config_path=args.model_config_path,
301
+ task_contract_path=args.task_contract_path,
302
+ run_name=args.run_name,
303
+ output_dir=args.output_dir,
304
+ latency_method=args.latency_method,
305
+ latency_profile_path=args.profile_path,
306
+ latency_seed=args.latency_seed,
307
+ )
308
+ output_dir = Path(config["logging"]["output_dir"])
309
+ output_dir.mkdir(parents=True, exist_ok=True)
310
+ (output_dir / "eval_config.yaml").write_text(
311
+ yaml.safe_dump(config, sort_keys=False), encoding="utf-8"
312
+ )
313
+ backend = MikasaEnvStepBackend(
314
+ config=config,
315
+ num_slots=int(config["evaluation"]["eval_parallel_envs"]),
316
+ )
317
+ run_from_config(
318
+ config,
319
+ env_backend=backend,
320
+ inference_devices=config["executor"]["inference_devices"],
321
+ )
322
+
323
+
324
+ def main() -> None:
325
+ if sys.argv[1:2] == ["latency-eval"]:
326
+ _latency_eval(sys.argv[2:])
327
+ return
328
+
329
+ parser = argparse.ArgumentParser()
330
+ parser.add_argument("--policy", choices=("ppo",), required=True)
331
+ parser.add_argument("--checkpoint", type=Path)
332
+ parser.add_argument("--episodes", type=int, default=50)
333
+ parser.add_argument("--output-dir", type=Path, required=True)
334
+ args = parser.parse_args()
335
+ args.output_dir.mkdir(parents=True, exist_ok=True)
336
+
337
+ _evaluate(args)
338
+
339
+
340
+ if __name__ == "__main__":
341
+ main()
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/starvla.py ADDED
@@ -0,0 +1,1207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import sys
5
+ from collections.abc import Mapping, Sequence
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ import numpy as np
10
+ import numpy.typing as npt
11
+ from PIL import Image
12
+
13
+ from latency_bench.core.actions import ActionResolver
14
+ from latency_bench.core.clock import EnvClock
15
+ from latency_bench.core.timing import current_profiler
16
+ from latency_bench.core.types import Action, Observation, PolicyOutput
17
+ from latency_bench.data.ghost_trail import GhostTrailConfig, build_flappy_ghost_trail_window
18
+ from latency_bench.data.state_normalization import min_max_normalize_state
19
+ from latency_bench.envs.raw_rgb import ENV_RAW_RGB_FRAME_STACK_INFO_KEY
20
+ from latency_bench.envs.gymnasium_task import (
21
+ gymnasium_action_space_contract,
22
+ gymnasium_task_contract,
23
+ )
24
+ from latency_bench.policy.base import PolicyRunner
25
+ from latency_bench.policy.starvla_prompts import load_latency_prompt_map, resolve_starvla_prompt
26
+
27
+ from latency_bench.utils.paths import REPO_ROOT
28
+
29
+
30
+ STARVLA_ROOT = REPO_ROOT / "third_party" / "starVLA"
31
+ STATEFUL_STARVLA_MODEL_IDS: tuple[str, ...] = (
32
+ "pi0",
33
+ "pi-0",
34
+ "pi05",
35
+ "pi-0.5",
36
+ "gr00t",
37
+ "qwenpi",
38
+ "qwenpi_v3",
39
+ "qwengr00t",
40
+ )
41
+ STATELESS_STARVLA_MODEL_IDS: tuple[str, ...] = (
42
+ "openvla",
43
+ "qwenoft",
44
+ )
45
+
46
+ DEMON_ATTACK_ACTION_LABELS: tuple[str, ...] = (
47
+ "NOOP",
48
+ "FIRE",
49
+ "RIGHT",
50
+ "LEFT",
51
+ "RIGHTFIRE",
52
+ "LEFTFIRE",
53
+ )
54
+ DEADLY_CORRIDOR_TURN_LABELS: tuple[str, ...] = (
55
+ "TURN_NOOP",
56
+ "TURN_LEFT",
57
+ "TURN_RIGHT",
58
+ )
59
+ DEADLY_CORRIDOR_MOVE_LABELS: tuple[str, ...] = (
60
+ "MOVE_NOOP",
61
+ "MOVE_FORWARD",
62
+ "MOVE_BACKWARD",
63
+ )
64
+ DEADLY_CORRIDOR_STRAFE_LABELS: tuple[str, ...] = (
65
+ "STRAFE_NOOP",
66
+ "MOVE_LEFT",
67
+ "MOVE_RIGHT",
68
+ )
69
+ DEADLY_CORRIDOR_ATTACK_LABELS: tuple[str, ...] = (
70
+ "ATTACK_NOOP",
71
+ "ATTACK",
72
+ )
73
+
74
+
75
+ class StarVlaPolicyRunner(PolicyRunner):
76
+ """Translate observations and model outputs using the task action contract."""
77
+
78
+ def __init__(
79
+ self,
80
+ *,
81
+ wrapper: Any,
82
+ checkpoint_path: str,
83
+ device: str,
84
+ unnorm_key: str | None,
85
+ env_name: str,
86
+ action_resolver: ActionResolver,
87
+ action_refs: Sequence[Any],
88
+ latency_prompt_map: dict[str, Any] | None = None,
89
+ base_prompt: str | None = None,
90
+ latency_prompt_key: int | str | None = None,
91
+ prompt_mode: str | None = None,
92
+ obs_resize: tuple[int, int] | None = None,
93
+ image_transform_config: Mapping[str, Any] | None = None,
94
+ observation_stride_raw_frames: int,
95
+ model_cfg: Mapping[str, Any] | None = None,
96
+ state_normalization: Mapping[str, Any] | None = None,
97
+ state_source: str | None = None,
98
+ image_views_info_key: str | None = None,
99
+ action_output_type: str | None = None,
100
+ ) -> None:
101
+ self._wrapper = wrapper
102
+ self._obs_resize = tuple(obs_resize) if obs_resize else None
103
+ self._checkpoint_path = checkpoint_path
104
+ self._device = device
105
+ self._unnorm_key = unnorm_key
106
+ self._env_name = env_name
107
+ self._action_by_raw_id = {
108
+ raw_action_id: action_resolver.resolve(action_ref)
109
+ for raw_action_id, action_ref in enumerate(action_refs)
110
+ }
111
+ self._latency_prompt_map = latency_prompt_map
112
+ self._base_prompt = base_prompt
113
+ self._latency_prompt_key = latency_prompt_key
114
+ self._prompt_mode = str(prompt_mode or "default").strip().lower()
115
+ self._image_transform_config = dict(image_transform_config or {"image_transform": "raw_rgb"})
116
+ self._image_transform = str(
117
+ self._image_transform_config.get("image_transform", "raw_rgb") or "raw_rgb"
118
+ ).strip().lower()
119
+ model_cfg = (
120
+ _normalized_model_cfg_from_wrapper(wrapper)
121
+ if model_cfg is None
122
+ else _normalized_model_cfg(model_cfg)
123
+ )
124
+ self._include_state = _include_state_from_model_cfg(model_cfg)
125
+ self._state_dim = _state_dim_from_model_cfg(model_cfg) if self._include_state else None
126
+ self._state_normalization = dict(state_normalization or {})
127
+ self._state_source = state_source
128
+ self._image_views_info_key = image_views_info_key
129
+ self._action_output_type = action_output_type
130
+ vla_data = (model_cfg.get("datasets", {}) or {}).get("vla_data", {}) or {}
131
+ self._pack_image_sequence = (
132
+ bool(vla_data["pack_image_sequence"])
133
+ if "pack_image_sequence" in vla_data
134
+ else False
135
+ )
136
+ self._image_sequence_length = (
137
+ int(vla_data["image_sequence_length"])
138
+ if self._pack_image_sequence
139
+ else 1
140
+ )
141
+ self._observation_stride_raw_frames = int(observation_stride_raw_frames)
142
+ self._image_sequence_raw_span = (
143
+ 1
144
+ + (self._image_sequence_length - 1)
145
+ * self._observation_stride_raw_frames
146
+ )
147
+ self._num_obs_frames = int(vla_data.get("num_obs_frames", 1) or 1)
148
+ self._image_mode = str(vla_data.get("image_mode", "single"))
149
+ self._stitch_grid = tuple(vla_data.get("stitch_grid", [2, 2]))
150
+ framework_cfg = model_cfg["framework"]
151
+ kv_cfg = framework_cfg["kv_memory"] if "kv_memory" in framework_cfg else {}
152
+ self._kv_memory_enabled = bool(kv_cfg["enabled"]) if "enabled" in kv_cfg else False
153
+
154
+ def reset_state(self, slot_id: int | None = None) -> None:
155
+ # Clears the model's per-slot KV memory at episode boundaries (req3).
156
+ # No-op unless the framework maintains KV memory.
157
+ reset = getattr(self._wrapper, "reset_memory", None)
158
+ if callable(reset):
159
+ reset(slot_id)
160
+
161
+ def predict(self, observation: Observation) -> PolicyOutput:
162
+ return self.predict_batch([observation])[0]
163
+
164
+ def predict_batch(self, observations: Sequence[Observation]) -> list[PolicyOutput]:
165
+ profiler = current_profiler()
166
+ with profiler.time("policy_build_example_ms"):
167
+ examples = [self._build_example(observation) for observation in observations]
168
+ with profiler.time("policy_wrapper_predict_action_ms"):
169
+ prediction = self._wrapper.predict_action(
170
+ examples=examples, unnorm_key=self._unnorm_key, profiler=profiler
171
+ )
172
+ with profiler.time("policy_decode_ms"):
173
+ outputs = [
174
+ self._decode_prediction(
175
+ prediction=prediction,
176
+ index=index,
177
+ observation=observation,
178
+ example=example,
179
+ )
180
+ for index, (observation, example) in enumerate(zip(observations, examples))
181
+ ]
182
+ return outputs
183
+
184
+ def _decode_prediction(
185
+ self,
186
+ *,
187
+ prediction: dict[str, Any],
188
+ index: int,
189
+ observation: Observation,
190
+ example: dict[str, Any],
191
+ ) -> PolicyOutput:
192
+ actions = np.asarray(prediction["actions"])
193
+ raw_action_scores = (
194
+ np.asarray(prediction["raw_action_scores"])
195
+ if "raw_action_scores" in prediction
196
+ else None
197
+ )
198
+ return self._policy_output(
199
+ observation=observation,
200
+ example=example,
201
+ action_payload=actions[index, 0],
202
+ action_output_type=(
203
+ prediction["action_output_type"]
204
+ if self._action_output_type is None
205
+ else self._action_output_type
206
+ ),
207
+ raw_action_scores=None if raw_action_scores is None else raw_action_scores[index, 0],
208
+ )
209
+
210
+ def _build_example(self, observation: Observation) -> dict[str, Any]:
211
+ frame_source = observation.metadata[
212
+ ENV_RAW_RGB_FRAME_STACK_INFO_KEY
213
+ if self._image_views_info_key is None
214
+ else self._image_views_info_key
215
+ ]
216
+ frames = observation_data_to_hwc_uint8_frames(frame_source) # oldest .. newest
217
+ transformed = self._transformed_frame(frames=frames, observation=observation)
218
+
219
+ if self._image_views_info_key is not None:
220
+ pass
221
+ elif self._pack_image_sequence:
222
+ if transformed is not None:
223
+ raise ValueError(
224
+ "WanOFT packed image sequences require image_transform=raw_rgb"
225
+ )
226
+ if len(frames) < self._image_sequence_raw_span:
227
+ raise ValueError(
228
+ "WanOFT packed image sequence requires "
229
+ f"{self._image_sequence_raw_span} raw frames for "
230
+ f"{self._image_sequence_length} decision observations at stride "
231
+ f"{self._observation_stride_raw_frames}, got {len(frames)}"
232
+ )
233
+ frames = frames[
234
+ -self._image_sequence_raw_span
235
+ :: self._observation_stride_raw_frames
236
+ ]
237
+ elif transformed is not None:
238
+ frames = [transformed]
239
+ elif self._image_mode == "single" or self._kv_memory_enabled:
240
+ frames = frames[-1:]
241
+ else:
242
+ # Select the temporal observation window to match training (_pack_sample).
243
+ raw_span = 1 + (self._num_obs_frames - 1) * self._observation_stride_raw_frames
244
+ frames = frames[-raw_span :: self._observation_stride_raw_frames]
245
+
246
+ prompt = resolve_starvla_prompt(
247
+ env_name=self._env_name,
248
+ observation_metadata=observation.metadata,
249
+ latency_prompt_map=self._latency_prompt_map,
250
+ base_prompt=self._base_prompt,
251
+ latency_prompt_key=self._latency_prompt_key,
252
+ prompt_mode=self._prompt_mode,
253
+ )
254
+
255
+ if self._image_mode == "stitch":
256
+ if transformed is not None:
257
+ raise ValueError("image_transform is not compatible with image_mode=stitch")
258
+ # Tile the window into one image; matches _pack_sample's stitch branch
259
+ # (raw frames passed to stitch_frames, which resizes each cell to 224).
260
+ images = [_get_stitch_frames()(frames, grid=self._stitch_grid, size=(224, 224))]
261
+ else:
262
+ if self._obs_resize is not None:
263
+ height, width = self._obs_resize
264
+ # match training preprocessing exactly: gr00t LeRobotSingleDataset._pack_sample
265
+ # does `Image.fromarray(image).resize((224, 224))` (PIL default resample = BICUBIC).
266
+ frames = [
267
+ np.asarray(Image.fromarray(frame).resize((width, height)), dtype=np.uint8)
268
+ for frame in frames
269
+ ]
270
+ images = [Image.fromarray(frame) for frame in frames]
271
+
272
+ example = {
273
+ "image": images,
274
+ "lang": prompt,
275
+ }
276
+ if self._kv_memory_enabled:
277
+ example["slot_id"] = observation.metadata["slot_id"]
278
+ elif "slot_id" in observation.metadata:
279
+ example["slot_id"] = observation.metadata["slot_id"]
280
+ if self._include_state:
281
+ if self._state_source == "transport":
282
+ state = np.asarray(observation.data["transport"], dtype=np.float32)
283
+ example["state"] = state.reshape(1, self._state_dim)
284
+ elif self._state_normalization:
285
+ state = np.asarray(
286
+ observation.metadata["gymnasium_state"], dtype=np.float32
287
+ )
288
+ state_min = np.asarray(self._state_normalization["min"], dtype=np.float32)
289
+ state_max = np.asarray(self._state_normalization["max"], dtype=np.float32)
290
+ state = min_max_normalize_state(state, state_min, state_max)
291
+ example["state"] = state.reshape(1, self._state_dim)
292
+ else:
293
+ example["state"] = np.zeros((1, self._state_dim), dtype=np.float32)
294
+ return example
295
+
296
+ def _transformed_frame(
297
+ self,
298
+ *,
299
+ frames: Sequence[npt.NDArray[np.uint8]],
300
+ observation: Observation,
301
+ ) -> npt.NDArray[np.uint8] | None:
302
+ if self._image_transform in {"", "none", "raw", "raw_rgb"}:
303
+ return None
304
+ if self._image_transform not in {"flappy_ghost_trail", "demon_attack_ghost_trail"}:
305
+ raise ValueError(f"Unsupported StarVLA image_transform={self._image_transform!r}")
306
+ if self._image_transform == "flappy_ghost_trail" and self._env_name != "flappy":
307
+ raise ValueError("image_transform=flappy_ghost_trail is only supported for env_name=flappy")
308
+ if self._image_transform == "demon_attack_ghost_trail" and self._env_name != "demon_attack":
309
+ raise ValueError("image_transform=demon_attack_ghost_trail is only supported for env_name=demon_attack")
310
+
311
+ config = GhostTrailConfig(
312
+ image_transform=self._image_transform,
313
+ history_frames=int(self._image_transform_config.get("history_frames", 5)),
314
+ gamma=float(self._image_transform_config.get("gamma", 1.3)),
315
+ min_alpha=int(self._image_transform_config.get("min_alpha", 35)),
316
+ ground_fraction=float(self._image_transform_config.get("ground_fraction", 0.22)),
317
+ scroll_px_per_step=float(self._image_transform_config.get("scroll_px_per_step", 4.0)),
318
+ )
319
+ if self._image_transform == "demon_attack_ghost_trail":
320
+ # env_step counts raw ALE frames (buffer updated 4× per decision step).
321
+ # frames[-0:] == frames, so env_step=0 falls back to the full reset-fill buffer.
322
+ valid_count = min(len(frames), int(observation.env_step))
323
+ else:
324
+ max_frames = max(1, int(config.history_frames) + 1)
325
+ valid_count = min(len(frames), max(1, int(observation.env_step) + 1), max_frames)
326
+ window = [np.asarray(frame, dtype=np.uint8) for frame in frames[-valid_count:]]
327
+
328
+ if self._image_transform == "demon_attack_ghost_trail":
329
+ from latency_bench.data.ghost_trail_demon import build_demon_attack_ghost_trail_window
330
+ steps_arg = list(range(len(window)))
331
+ return build_demon_attack_ghost_trail_window(window, steps_arg, config=config)
332
+
333
+ current_step = int(observation.env_step)
334
+ start_step = current_step - valid_count + 1
335
+ steps = list(range(start_step, current_step + 1))
336
+ return build_flappy_ghost_trail_window(window, steps, config=config)
337
+
338
+ def _policy_output(
339
+ self,
340
+ *,
341
+ observation: Observation,
342
+ example: dict[str, Any],
343
+ action_payload: npt.NDArray[Any],
344
+ action_output_type: str,
345
+ raw_action_scores: npt.NDArray[Any] | None,
346
+ ) -> PolicyOutput:
347
+ payload = np.asarray(action_payload)
348
+ action, action_metadata = action_from_starvla_payload(
349
+ payload=payload,
350
+ env_name=self._env_name,
351
+ action_by_raw_id=self._action_by_raw_id,
352
+ action_output_type=action_output_type,
353
+ )
354
+ metadata = {
355
+ "policy_type": "starvla",
356
+ "prompt_source": "latency_prompt_map" if self._latency_prompt_map is not None else "base",
357
+ "checkpoint_path": self._checkpoint_path,
358
+ "unnorm_key": self._unnorm_key,
359
+ "device": self._device,
360
+ "input_frame_count": len(example["image"]),
361
+ "image_transform": self._image_transform,
362
+ "action_output_type": action_output_type,
363
+ "action_payload": to_jsonable_action_payload(payload),
364
+ "kv_memory_enabled": self._kv_memory_enabled,
365
+ **action_metadata,
366
+ }
367
+ if self._pack_image_sequence:
368
+ metadata["image_sequence_length"] = self._image_sequence_length
369
+ metadata["input_frame_raw_stride"] = self._observation_stride_raw_frames
370
+ metadata["input_frame_raw_span"] = self._image_sequence_raw_span
371
+ if "slot_id" in example:
372
+ metadata["slot_id"] = example["slot_id"]
373
+ if raw_action_scores is not None:
374
+ metadata["raw_action_scores"] = [
375
+ float(item) for item in np.asarray(raw_action_scores, dtype=np.float32).tolist()
376
+ ]
377
+ if "latency_raw_frames" in observation.metadata:
378
+ metadata["latency_raw_frames"] = observation.metadata["latency_raw_frames"]
379
+ if "latency_ms" in observation.metadata:
380
+ metadata["latency_ms"] = observation.metadata["latency_ms"]
381
+ if self._latency_prompt_key is not None:
382
+ metadata["latency_prompt_key"] = self._latency_prompt_key
383
+ return PolicyOutput(
384
+ action=action,
385
+ raw_output=metadata["action_payload"],
386
+ metadata=metadata,
387
+ )
388
+
389
+
390
+ def observation_data_to_hwc_uint8_frames(data: Any) -> list[npt.NDArray[np.uint8]]:
391
+ frame = _extract_observation_array(data)
392
+ if frame.ndim == 4 and frame.shape[-1] == 3:
393
+ return [_as_uint8_image(item) for item in frame]
394
+ if frame.ndim == 4 and frame.shape[1] == 3:
395
+ return [_as_uint8_image(np.transpose(item, (1, 2, 0))) for item in frame]
396
+ if frame.ndim == 3 and frame.shape[-1] == 3:
397
+ return [_as_uint8_image(frame)]
398
+ if frame.ndim == 3 and frame.shape[0] == 3:
399
+ return [_as_uint8_image(np.transpose(frame, (1, 2, 0)))]
400
+ if (
401
+ frame.ndim == 3
402
+ and frame.shape[0] % 3 == 0
403
+ and frame.shape[0] < frame.shape[1]
404
+ and frame.shape[0] < frame.shape[2]
405
+ ):
406
+ return [
407
+ _as_uint8_image(np.transpose(frame[start : start + 3, :, :], (1, 2, 0)))
408
+ for start in range(0, frame.shape[0], 3)
409
+ ]
410
+ if frame.ndim == 3 and frame.shape[-1] % 3 == 0:
411
+ return [
412
+ _as_uint8_image(frame[:, :, start : start + 3])
413
+ for start in range(0, frame.shape[-1], 3)
414
+ ]
415
+ if frame.ndim == 3 and frame.shape[0] % 3 == 0:
416
+ return [
417
+ _as_uint8_image(np.transpose(frame[start : start + 3, :, :], (1, 2, 0)))
418
+ for start in range(0, frame.shape[0], 3)
419
+ ]
420
+ return [_as_uint8_image(frame)]
421
+
422
+
423
+ def decode_starvla_action(
424
+ *,
425
+ vector: npt.NDArray[Any],
426
+ env_name: str,
427
+ action_by_raw_id: Mapping[int, Action],
428
+ action_layout: str | None = None,
429
+ ) -> tuple[Action, dict[str, Any]]:
430
+ deadly_layout = None
431
+ if str(env_name) == "deadly_corridor":
432
+ action_dim = int(np.asarray(vector).shape[-1])
433
+ deadly_layouts = {
434
+ 7: "deadly_corridor_semantic_7",
435
+ 11: "deadly_corridor_factorized_11",
436
+ 54: "deadly_corridor_joint_54",
437
+ }
438
+ if action_dim not in deadly_layouts:
439
+ raise ValueError(
440
+ "Deadly Corridor StarVLA action vector expected 7, 11, or 54 "
441
+ f"values, got {action_dim}"
442
+ )
443
+ deadly_layout = deadly_layouts[action_dim]
444
+ asterix_layout = None
445
+ if str(env_name) == "asterix":
446
+ action_dim = int(np.asarray(vector).shape[-1])
447
+ if action_layout is not None:
448
+ asterix_layout = str(action_layout).strip().lower()
449
+ else:
450
+ asterix_layout = "factorized_6" if action_dim < 9 else "discrete_9"
451
+
452
+ decode_rl_games_actions, _, _ = _load_rl_games_action_decode()
453
+ prediction = decode_rl_games_actions(
454
+ normalized_actions=np.asarray(vector),
455
+ env_name=str(env_name),
456
+ deadly_action_layout=(deadly_layout.removeprefix("deadly_corridor_") if deadly_layout is not None else None),
457
+ asterix_action_layout=asterix_layout,
458
+ )
459
+ action, metadata = action_from_starvla_payload(
460
+ payload=np.asarray(prediction["actions"]),
461
+ env_name=env_name,
462
+ action_by_raw_id=action_by_raw_id,
463
+ action_output_type=prediction["action_output_type"],
464
+ )
465
+ if deadly_layout is not None:
466
+ metadata["action_layout"] = deadly_layout
467
+ if deadly_layout == "deadly_corridor_joint_54":
468
+ turn, move, strafe, attack = action.value
469
+ metadata["raw_action_id"] = turn * 18 + move * 6 + strafe * 2 + attack
470
+ elif deadly_layout == "deadly_corridor_semantic_7":
471
+ semantic_actions = (
472
+ [0, 1, 0, 0],
473
+ [0, 2, 0, 0],
474
+ [0, 0, 1, 0],
475
+ [0, 0, 2, 0],
476
+ [1, 0, 0, 0],
477
+ [2, 0, 0, 0],
478
+ [0, 0, 0, 1],
479
+ )
480
+ metadata["raw_action_id"] = semantic_actions.index(action.value)
481
+ if asterix_layout is not None:
482
+ metadata["action_layout"] = asterix_layout
483
+ return action, metadata
484
+
485
+
486
+ # Fixed semantic button order the StarVLA multibinary head is trained against.
487
+ # Mirrors starVLA.training.rl_games.eval_core._semantic_to_runtime_multibinary;
488
+ # the env adapter re-orders this to the live ViZDoom button layout.
489
+ DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER = (
490
+ "MOVE_FORWARD",
491
+ "MOVE_BACKWARD",
492
+ "MOVE_LEFT",
493
+ "MOVE_RIGHT",
494
+ "TURN_LEFT",
495
+ "TURN_RIGHT",
496
+ "ATTACK",
497
+ )
498
+
499
+
500
+ def action_from_starvla_payload(
501
+ *,
502
+ payload: npt.NDArray[Any],
503
+ env_name: str,
504
+ action_by_raw_id: Mapping[int, Action],
505
+ action_output_type: str = "",
506
+ ) -> tuple[Action, dict[str, Any]]:
507
+ if str(action_output_type) == "rl_games_continuous":
508
+ values = [float(item) for item in np.asarray(payload).reshape(-1).tolist()]
509
+ return Action(
510
+ value=values,
511
+ name="continuous_torque",
512
+ is_noop=all(value == 0.0 for value in values),
513
+ is_oneshot=False,
514
+ ), {"continuous_action": values}
515
+ if str(env_name) == "demon_attack":
516
+ return demon_attack_action_from_id(int(np.asarray(payload).reshape(-1)[0]))
517
+ if str(env_name) == "deadly_corridor":
518
+ # Multibinary heads emit an already-thresholded 7-dim button vector in
519
+ # fixed semantic order; the env adapter re-orders it to the live ViZDoom
520
+ # button layout. Keep it as-is rather than reinterpreting it as a
521
+ # [turn, move, strafe, attack] categorical tuple.
522
+ if str(action_output_type) == "rl_games_deadly_corridor_multibinary":
523
+ buttons = [int(item) for item in np.asarray(payload).reshape(-1).tolist()]
524
+ active = [
525
+ DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER[idx]
526
+ for idx, pressed in enumerate(buttons)
527
+ if idx < len(DEADLY_CORRIDOR_SEMANTIC_BUTTON_ORDER) and pressed
528
+ ]
529
+ action_name = "+".join(active) if active else "NOOP"
530
+ return Action(
531
+ value=buttons,
532
+ name=action_name,
533
+ is_noop=not any(buttons),
534
+ is_oneshot=False,
535
+ ), {
536
+ "decoded_multibinary_buttons": buttons,
537
+ "action_label": action_name,
538
+ "action_layout": "deadly_corridor_multibinary_7",
539
+ }
540
+ return deadly_corridor_action_from_tuple(
541
+ action_value=[int(item) for item in np.asarray(payload).reshape(-1).tolist()],
542
+ metadata={"action_layout": "deadly_corridor_tuple"},
543
+ )
544
+ raw_action_id = int(np.asarray(payload).reshape(-1)[0])
545
+ return action_by_raw_id[raw_action_id], {"raw_action_id": raw_action_id}
546
+
547
+
548
+ def to_jsonable_action_payload(payload: npt.NDArray[Any]) -> Any:
549
+ value = np.asarray(payload).tolist()
550
+ if isinstance(value, list) and len(value) == 1:
551
+ return value[0]
552
+ return value
553
+
554
+
555
+ def demon_attack_action_from_id(action_id: int) -> tuple[Action, dict[str, Any]]:
556
+ action = Action(
557
+ value=action_id,
558
+ name=DEMON_ATTACK_ACTION_LABELS[action_id],
559
+ is_noop=action_id == 0,
560
+ is_oneshot=False,
561
+ )
562
+ return action, {"raw_action_id": action_id, "action_label": action.name}
563
+
564
+
565
+ def deadly_corridor_action_from_tuple(
566
+ *,
567
+ action_value: list[int],
568
+ metadata: dict[str, Any],
569
+ ) -> tuple[Action, dict[str, Any]]:
570
+ turn, move, strafe, attack = action_value
571
+ action_value = [turn, move, strafe, attack]
572
+ turn_label = DEADLY_CORRIDOR_TURN_LABELS[turn]
573
+ move_label = DEADLY_CORRIDOR_MOVE_LABELS[move]
574
+ strafe_label = DEADLY_CORRIDOR_STRAFE_LABELS[strafe]
575
+ attack_label = DEADLY_CORRIDOR_ATTACK_LABELS[attack]
576
+ active_labels = [
577
+ label
578
+ for label in (turn_label, move_label, strafe_label, attack_label)
579
+ if not label.endswith("_NOOP")
580
+ ]
581
+ action_name = "+".join(active_labels) if active_labels else "NOOP"
582
+ return Action(
583
+ value=action_value,
584
+ name=action_name,
585
+ is_noop=action_value == [0, 0, 0, 0],
586
+ is_oneshot=False,
587
+ ), {
588
+ "decoded_action_tuple": action_value,
589
+ "turn_label": turn_label,
590
+ "move_label": move_label,
591
+ "strafe_label": strafe_label,
592
+ "attack_label": attack_label,
593
+ "action_label": action_name,
594
+ **metadata,
595
+ }
596
+
597
+
598
+ def _extract_observation_array(data: Any) -> npt.NDArray[Any]:
599
+ if isinstance(data, Mapping):
600
+ return np.asarray(data["observation"])
601
+ return np.asarray(data)
602
+
603
+
604
+ def _as_uint8_image(frame: npt.NDArray[Any]) -> npt.NDArray[np.uint8]:
605
+ return np.ascontiguousarray(frame, dtype=np.uint8)
606
+
607
+
608
+ def _normalized_model_cfg(model_cfg: Mapping[str, Any]) -> dict[str, Any]:
609
+ _ensure_starvla_path()
610
+ from omegaconf import OmegaConf
611
+ from starVLA.model.framework.share_tools import apply_config_compat
612
+
613
+ cfg = OmegaConf.create(model_cfg)
614
+ apply_config_compat(cfg)
615
+ _apply_model_family_include_state_compat(cfg)
616
+ return OmegaConf.to_container(cfg, resolve=True)
617
+
618
+
619
+ def _normalized_model_cfg_from_wrapper(wrapper: Any) -> dict[str, Any]:
620
+ return _normalized_model_cfg(wrapper._model_cfg)
621
+
622
+
623
+ def _load_starvla_model_config(path: str | Path) -> dict[str, Any]:
624
+ from omegaconf import OmegaConf
625
+
626
+ return _normalized_model_cfg(OmegaConf.load(path))
627
+
628
+
629
+ def _apply_model_family_include_state_compat(cfg: Any) -> None:
630
+ from omegaconf import OmegaConf
631
+
632
+ if OmegaConf.select(cfg, "datasets.vla_data.include_state") is not None:
633
+ return
634
+
635
+ model_ids = (
636
+ _normalized_optional_config_string(cfg, ("model",)),
637
+ _normalized_optional_config_string(cfg, ("rl_games", "model_alias")),
638
+ _normalized_optional_config_string(cfg, ("framework", "name")),
639
+ )
640
+ if any(model_id in STATEFUL_STARVLA_MODEL_IDS for model_id in model_ids if model_id is not None):
641
+ OmegaConf.update(cfg, "datasets.vla_data.include_state", True, force_add=True)
642
+ return
643
+ if any(model_id in STATELESS_STARVLA_MODEL_IDS for model_id in model_ids if model_id is not None):
644
+ OmegaConf.update(cfg, "datasets.vla_data.include_state", False, force_add=True)
645
+
646
+
647
+ def _normalized_optional_config_string(cfg: Any, path: tuple[str, ...]) -> str | None:
648
+ from omegaconf import OmegaConf
649
+
650
+ value = OmegaConf.select(cfg, ".".join(path))
651
+ if value is None:
652
+ return None
653
+ return str(value).strip().lower()
654
+
655
+
656
+ def _state_dim_from_model_cfg(model_cfg: dict[str, Any]) -> int:
657
+ return model_cfg["framework"]["action_model"]["state_dim"]
658
+
659
+
660
+ def _include_state_from_model_cfg(model_cfg: dict[str, Any]) -> bool:
661
+ return model_cfg["datasets"]["vla_data"]["include_state"]
662
+
663
+
664
+ _STITCH_FRAMES = None
665
+
666
+
667
+ def _get_stitch_frames():
668
+ """Lazily import starVLA's stitch_frames (starVLA path is added at runtime)."""
669
+ global _STITCH_FRAMES
670
+ if _STITCH_FRAMES is None:
671
+ _ensure_starvla_path()
672
+ from starVLA.training.trainer_utils.trainer_tools import stitch_frames
673
+
674
+ _STITCH_FRAMES = stitch_frames
675
+ return _STITCH_FRAMES
676
+
677
+
678
+ def _ensure_starvla_path() -> None:
679
+ starvla_root = str(STARVLA_ROOT)
680
+ if starvla_root not in sys.path:
681
+ sys.path.insert(0, starvla_root)
682
+
683
+
684
+ def _observation_stride_raw_frames(config: Mapping[str, Any]) -> int:
685
+ env_cfg = config["env"]
686
+ return EnvClock(
687
+ env_fps=float(env_cfg["env_fps"]),
688
+ obs_fps=float(env_cfg["obs_fps"]),
689
+ ).obs_stride_raw_frames
690
+
691
+
692
+ def apply_starvla_model_input_config(
693
+ config: dict[str, Any],
694
+ *,
695
+ model_cfg: Mapping[str, Any],
696
+ image_transform: str = "raw_rgb",
697
+ ) -> None:
698
+ """Match latency_bench's raw frame stack to a saved StarVLA input contract."""
699
+ vla_data = model_cfg["datasets"]["vla_data"]
700
+ pack_image_sequence = (
701
+ bool(vla_data["pack_image_sequence"])
702
+ if "pack_image_sequence" in vla_data
703
+ else False
704
+ )
705
+ normalized_transform = str(image_transform).strip().lower()
706
+ raw_image_transform = normalized_transform in {"", "none", "raw", "raw_rgb"}
707
+ if pack_image_sequence:
708
+ if not raw_image_transform:
709
+ raise ValueError(
710
+ "WanOFT packed image sequences require image_transform=raw_rgb"
711
+ )
712
+ input_frame_count = int(vla_data["image_sequence_length"])
713
+ else:
714
+ if not raw_image_transform:
715
+ return
716
+ framework_cfg = model_cfg["framework"]
717
+ kv_cfg = framework_cfg["kv_memory"] if "kv_memory" in framework_cfg else {}
718
+ kv_memory_enabled = bool(kv_cfg["enabled"]) if "enabled" in kv_cfg else False
719
+ if kv_memory_enabled:
720
+ return
721
+ image_mode = str(vla_data["image_mode"]) if "image_mode" in vla_data else "single"
722
+ if image_mode == "single":
723
+ return
724
+ input_frame_count = int(vla_data["num_obs_frames"])
725
+
726
+ observation_stride = _observation_stride_raw_frames(config)
727
+ required_raw_frames = 1 + (input_frame_count - 1) * observation_stride
728
+ config["env"]["frame_stack"] = max(
729
+ int(config["env"]["frame_stack"]),
730
+ required_raw_frames,
731
+ )
732
+
733
+
734
+ def prepare_starvla_checkpoint_input_config(config: dict[str, Any]) -> None:
735
+ """Apply the saved checkpoint input contract before env construction."""
736
+ if config["policy"]["type"] != "starvla":
737
+ return
738
+
739
+ policy_cfg = config["policy"]
740
+ if "task_contract_path" in policy_cfg:
741
+ if config["env"]["name"] == "gymnasium":
742
+ contract = json.loads(
743
+ Path(policy_cfg["task_contract_path"]).read_text(encoding="utf-8")
744
+ )
745
+ config["env"]["state_space"] = {"labels": contract["state_labels"]}
746
+ if contract["robot_type"] in ("latency_balance_profile_h8", "latency_balance_profile_h16"):
747
+ config["env"]["name"] = "balance_profile"
748
+ config["env"]["action_context_horizon"] = contract["action_horizon"]
749
+ config["env"]["frame_stack"] = 1
750
+ return
751
+ if "model_config_path" in policy_cfg:
752
+ model_cfg = _load_starvla_model_config(policy_cfg["model_config_path"])
753
+ else:
754
+ _ensure_starvla_path()
755
+ from starVLA.model.framework.share_tools import read_mode_config
756
+
757
+ saved_model_cfg, _norm_stats = read_mode_config(policy_cfg["checkpoint_path"])
758
+ model_cfg = _normalized_model_cfg(saved_model_cfg)
759
+ if config["env"]["name"] == "gymnasium":
760
+ image_size = model_cfg["rl_games"]["env_eval"]["image_size"]
761
+ config["env"]["obs_resize"] = [image_size, image_size]
762
+ image_transform_cfg = (
763
+ policy_cfg["image_transform_config"]
764
+ if "image_transform_config" in policy_cfg
765
+ else {}
766
+ )
767
+ image_transform = (
768
+ image_transform_cfg["image_transform"]
769
+ if "image_transform" in image_transform_cfg
770
+ else "raw_rgb"
771
+ )
772
+ apply_starvla_model_input_config(
773
+ config,
774
+ model_cfg=model_cfg,
775
+ image_transform=image_transform,
776
+ )
777
+
778
+
779
+ def _load_policy_wrapper_class() -> Any:
780
+ _ensure_starvla_path()
781
+ from deployment.model_server.policy_wrapper import PolicyServerWrapper
782
+
783
+ return PolicyServerWrapper
784
+
785
+
786
+ def _profiler_stage(profiler: Any, name: str) -> Any:
787
+ from contextlib import nullcontext
788
+
789
+ return profiler.time(name) if profiler is not None else nullcontext()
790
+
791
+
792
+ def _load_rl_games_action_decode() -> tuple[Any, Any, Any]:
793
+ _ensure_starvla_path()
794
+ from deployment.model_server.rl_games_action_decode import (
795
+ decode_rl_games_actions,
796
+ resolve_asterix_action_decode_spec,
797
+ resolve_deadly_action_decode_spec,
798
+ )
799
+
800
+ return decode_rl_games_actions, resolve_deadly_action_decode_spec, resolve_asterix_action_decode_spec
801
+
802
+
803
+ class LiveStarVlaWrapper:
804
+ """In-process stand-in for ``PolicyServerWrapper`` over a *live* framework.
805
+
806
+ During training the trainer already holds the model in memory
807
+ (``accelerator.unwrap_model(self.model)`` — the same object eval_core calls).
808
+ This wrapper exposes only the rl_games-mode surface ``StarVlaPolicyRunner``
809
+ uses — ``predict_action`` (framework forward + rl_games decode),
810
+ ``reset_memory`` passthrough, and the ``_model_cfg`` attribute — so no
811
+ checkpoint reload is needed. The disk-backed ``PolicyNormProcessor`` is never
812
+ built because rl_games decoding ignores un-normalization stats.
813
+ """
814
+
815
+ def __init__(
816
+ self,
817
+ *,
818
+ framework: Any,
819
+ model_cfg: dict[str, Any],
820
+ env_name: str,
821
+ rl_games_action_env_dim: int | None = None,
822
+ gymnasium_action_space_type: str = "discrete",
823
+ action_layout: str | None = None,
824
+ multibinary_threshold: float | None = None,
825
+ ) -> None:
826
+ self._framework = framework
827
+ self._model_cfg = model_cfg
828
+ self._rl_games_env_name = str(env_name)
829
+ self._rl_games_action_env_dim = rl_games_action_env_dim
830
+ self._gymnasium_action_space_type = gymnasium_action_space_type
831
+ (
832
+ self._decode_rl_games_actions,
833
+ resolve_deadly_action_decode_spec,
834
+ resolve_asterix_action_decode_spec,
835
+ ) = _load_rl_games_action_decode()
836
+ self._action_layout = action_layout
837
+ self._multibinary_threshold = multibinary_threshold
838
+ if self._rl_games_env_name == "deadly_corridor":
839
+ self._action_layout, self._multibinary_threshold = resolve_deadly_action_decode_spec(
840
+ model_cfg,
841
+ action_layout=action_layout,
842
+ multibinary_threshold=multibinary_threshold,
843
+ )
844
+ elif self._rl_games_env_name == "asterix":
845
+ self._action_layout = resolve_asterix_action_decode_spec(
846
+ model_cfg,
847
+ action_layout=action_layout,
848
+ )
849
+
850
+ def reset_memory(self, slot_id: int | None = None) -> None:
851
+ reset = getattr(self._framework, "reset_memory", None)
852
+ if callable(reset):
853
+ reset(slot_id)
854
+
855
+ def predict_action(
856
+ self,
857
+ examples: list[dict[str, Any]],
858
+ unnorm_key: str | None = None,
859
+ **kwargs: Any,
860
+ ) -> dict[str, Any]:
861
+ # unnorm_key is unused in rl_games mode; kept for interface parity.
862
+ del unnorm_key
863
+ profiler = kwargs["profiler"] if "profiler" in kwargs else None
864
+ out = self._framework.predict_action(examples=examples, **kwargs)
865
+ normalized = np.asarray(out["normalized_actions"]) # (B, T, D)
866
+ decode_kwargs: dict[str, Any] = {}
867
+ if self._rl_games_env_name == "gymnasium":
868
+ decode_kwargs["action_env_dim"] = self._rl_games_action_env_dim
869
+ if self._gymnasium_action_space_type == "box":
870
+ decode_kwargs["gymnasium_action_space_type"] = "box"
871
+ with _profiler_stage(profiler, "starvla_wrapper_rl_games_decode_ms"):
872
+ return self._decode_rl_games_actions(
873
+ normalized_actions=normalized,
874
+ env_name=self._rl_games_env_name,
875
+ deadly_action_layout=(
876
+ self._action_layout
877
+ if self._rl_games_env_name == "deadly_corridor"
878
+ else None
879
+ ),
880
+ deadly_multibinary_threshold=(
881
+ self._multibinary_threshold
882
+ if self._rl_games_env_name == "deadly_corridor"
883
+ else None
884
+ ),
885
+ asterix_action_layout=(
886
+ self._action_layout
887
+ if self._rl_games_env_name == "asterix"
888
+ else None
889
+ ),
890
+ **decode_kwargs,
891
+ )
892
+
893
+
894
+ _LEGACY_GYMNASIUM_TASK_NAMES = {
895
+ "ant_rgb_state": "ant",
896
+ "half_cheetah_rgb_state": "half_cheetah",
897
+ "hopper_rgb_state": "hopper",
898
+ "humanoid_rgb_state": "humanoid",
899
+ "inverted_pendulum_rgb_state": "inverted_pendulum",
900
+ "swimmer_rgb_state": "swimmer",
901
+ "walker2d_rgb_state": "walker2d",
902
+ }
903
+
904
+
905
+ def _canonical_gymnasium_contract_namespace(
906
+ contract: Mapping[str, Any],
907
+ ) -> dict[str, Any]:
908
+ canonical = dict(contract)
909
+ task_name = canonical["task_name"]
910
+ if task_name in _LEGACY_GYMNASIUM_TASK_NAMES:
911
+ canonical["task_name"] = _LEGACY_GYMNASIUM_TASK_NAMES[task_name]
912
+ if canonical["env_id"] == "LatencyBench/HopperRgbState-v0":
913
+ canonical["env_id"] = "LatencyBench/Hopper-v0"
914
+ canonical["registration_imports"] = [
915
+ "latency_bench.envs.gymnasium_hopper"
916
+ if module == "latency_bench.envs.gymnasium_hopper_rgb_state"
917
+ else module
918
+ for module in canonical["registration_imports"]
919
+ ]
920
+ return canonical
921
+
922
+
923
+ def _validate_gymnasium_starvla_contract(
924
+ *,
925
+ env_cfg: Mapping[str, Any],
926
+ policy_cfg: Mapping[str, Any],
927
+ model_cfg: Mapping[str, Any],
928
+ manifest: Mapping[str, Any],
929
+ ) -> None:
930
+ eval_contract = gymnasium_task_contract(env_cfg)
931
+ manifest_task = manifest.get("gymnasium_task")
932
+ expected = policy_cfg.get(
933
+ "gymnasium_training_task_contract", manifest_task or eval_contract
934
+ )
935
+ comparable_eval_contract = {**eval_contract, "make_kwargs": expected["make_kwargs"]}
936
+ if _canonical_gymnasium_contract_namespace(
937
+ comparable_eval_contract
938
+ ) != _canonical_gymnasium_contract_namespace(expected):
939
+ raise ValueError(
940
+ "Evaluation Gymnasium task contract does not match the StarVLA training contract or dataset manifest"
941
+ )
942
+ if manifest.get("integration_name", "gymnasium") != "gymnasium":
943
+ raise ValueError("StarVLA task manifest is not a Gymnasium handoff")
944
+ if manifest_task is not None:
945
+ if _canonical_gymnasium_contract_namespace(
946
+ manifest_task
947
+ ) != _canonical_gymnasium_contract_namespace(expected):
948
+ raise ValueError(
949
+ "Evaluation Gymnasium task contract does not match the StarVLA dataset manifest"
950
+ )
951
+ model_contract = model_cfg["datasets"]["vla_data"].get("gymnasium_task_contract")
952
+ if model_contract is not None:
953
+ if _canonical_gymnasium_contract_namespace(
954
+ model_contract
955
+ ) != _canonical_gymnasium_contract_namespace(expected):
956
+ raise ValueError(
957
+ "Evaluation Gymnasium task contract does not match the StarVLA model config"
958
+ )
959
+ action_space = gymnasium_action_space_contract(env_cfg)
960
+ action_layout = str(policy_cfg.get("action_layout", "") or "").strip().lower()
961
+ is_asterix_factorized = (
962
+ str(env_cfg.get("task_name", "")) == "asterix"
963
+ and action_layout in {"factorized_6", "factorized6", "asterix_factorized_6", "asterix_factorized6"}
964
+ )
965
+ if not is_asterix_factorized and manifest["active_action_dim"] != len(action_space["labels"]):
966
+ raise ValueError(
967
+ "StarVLA dataset active_action_dim does not match its Gymnasium action catalog"
968
+ )
969
+ if (
970
+ model_cfg["framework"]["action_model"]["action_env_dim"]
971
+ != manifest["active_action_dim"]
972
+ ):
973
+ raise ValueError(
974
+ "StarVLA model action_env_dim does not match the dataset manifest"
975
+ )
976
+ model_uses_state = bool(model_cfg["datasets"]["vla_data"]["include_state"])
977
+ manifest_has_state_metadata = (
978
+ "uses_state" in manifest or "state_labels" in manifest
979
+ )
980
+ manifest_uses_state = bool(manifest.get("uses_state", model_uses_state))
981
+ if manifest_has_state_metadata:
982
+ if policy_cfg.get("state_source") != "transport" and manifest_uses_state != ("state_space" in expected):
983
+ raise ValueError(
984
+ "StarVLA dataset uses_state does not match the Gymnasium state space"
985
+ )
986
+ if manifest_uses_state != model_uses_state:
987
+ raise ValueError(
988
+ "StarVLA dataset uses_state does not match the model include_state"
989
+ )
990
+ if manifest_has_state_metadata and manifest_uses_state:
991
+ state_labels = manifest["state_labels"]
992
+ expected_state_labels = expected["state_space"]["labels"] if policy_cfg.get("state_source") != "transport" else state_labels
993
+ if state_labels != expected_state_labels:
994
+ raise ValueError(
995
+ "StarVLA dataset state_labels do not match the Gymnasium state space"
996
+ )
997
+ if manifest["state_dim"] != len(state_labels):
998
+ raise ValueError(
999
+ "StarVLA dataset state_dim does not match its state_labels"
1000
+ )
1001
+ if (
1002
+ model_cfg["framework"]["action_model"]["state_dim"]
1003
+ != manifest["state_dim"]
1004
+ ):
1005
+ raise ValueError(
1006
+ "StarVLA model state_dim does not match the dataset manifest"
1007
+ )
1008
+ if not manifest["state_normalization"]:
1009
+ raise ValueError(
1010
+ "StarVLA state-enabled dataset manifest is missing state_normalization"
1011
+ )
1012
+
1013
+
1014
+ def _starvla_runner_kwargs(
1015
+ config: dict[str, Any],
1016
+ action_resolver: ActionResolver,
1017
+ model_cfg: Mapping[str, Any] | None,
1018
+ *,
1019
+ base_prompt: str | None,
1020
+ ) -> dict[str, Any]:
1021
+ """Resolve task and input settings shared by checkpoint and resident models."""
1022
+ env_cfg = config["env"]
1023
+ policy_cfg = config["policy"]
1024
+ if env_cfg["name"] == "gymnasium":
1025
+ task_manifest = json.loads(
1026
+ Path(policy_cfg["task_manifest_path"]).read_text(encoding="utf-8")
1027
+ )
1028
+ _validate_gymnasium_starvla_contract(
1029
+ env_cfg=env_cfg,
1030
+ policy_cfg=policy_cfg,
1031
+ model_cfg=model_cfg,
1032
+ manifest=task_manifest,
1033
+ )
1034
+ semantic_env_name = env_cfg["task_name"]
1035
+ action_refs = env_cfg.get("action_order", [])
1036
+ base_prompt = env_cfg["base_prompt"]
1037
+ state_normalization = task_manifest.get("state_normalization")
1038
+ else:
1039
+ semantic_env_name = env_cfg["name"]
1040
+ action_refs = policy_cfg.get("actions", action_resolver.default_action_refs())
1041
+ state_normalization = policy_cfg["state_normalization"] if "state_normalization" in policy_cfg else None
1042
+ return dict(
1043
+ unnorm_key=policy_cfg.get("unnorm_key"),
1044
+ env_name=semantic_env_name,
1045
+ action_resolver=action_resolver,
1046
+ action_refs=action_refs,
1047
+ latency_prompt_map=(
1048
+ load_latency_prompt_map(policy_cfg["latency_prompt_map_path"])
1049
+ if "latency_prompt_map_path" in policy_cfg
1050
+ else None
1051
+ ),
1052
+ base_prompt=base_prompt,
1053
+ latency_prompt_key=policy_cfg.get("latency_prompt_key"),
1054
+ prompt_mode=policy_cfg.get("prompt_mode"),
1055
+ obs_resize=tuple(env_cfg["obs_resize"]) if env_cfg.get("obs_resize") else None,
1056
+ image_transform_config=policy_cfg.get("image_transform_config"),
1057
+ observation_stride_raw_frames=_observation_stride_raw_frames(config),
1058
+ model_cfg=model_cfg,
1059
+ state_normalization=state_normalization,
1060
+ state_source=policy_cfg["state_source"] if "state_source" in policy_cfg else None,
1061
+ )
1062
+
1063
+
1064
+ def build_starvla_policy(
1065
+ config: dict[str, Any],
1066
+ action_resolver: ActionResolver,
1067
+ ) -> PolicyRunner:
1068
+ policy_cfg = config["policy"]
1069
+ if "task_contract_path" in policy_cfg:
1070
+ _ensure_starvla_path()
1071
+ from latency_bench.policy.starvla_tasks import build_task_starvla_policy
1072
+
1073
+ return build_task_starvla_policy(config)
1074
+ env_cfg = config["env"]
1075
+ integration_env_name = env_cfg["name"]
1076
+ model_cfg = (
1077
+ _load_starvla_model_config(policy_cfg["model_config_path"])
1078
+ if integration_env_name == "gymnasium" or "model_config_path" in policy_cfg
1079
+ else None
1080
+ )
1081
+ runner_kwargs = _starvla_runner_kwargs(
1082
+ config, action_resolver, model_cfg, base_prompt=env_cfg.get("base_prompt")
1083
+ )
1084
+ wrapper_cls = _load_policy_wrapper_class()
1085
+ wrapper_kwargs: dict[str, Any] = dict(
1086
+ ckpt_path=policy_cfg["checkpoint_path"],
1087
+ device=policy_cfg["device"],
1088
+ use_bf16=True,
1089
+ unnorm_key=runner_kwargs["unnorm_key"],
1090
+ action_output_mode=(
1091
+ policy_cfg["action_output_mode"]
1092
+ if "action_output_mode" in policy_cfg
1093
+ else "rl_games"
1094
+ ),
1095
+ rl_games_env_name=integration_env_name,
1096
+ rl_games_action_layout=(
1097
+ policy_cfg["action_layout"] if "action_layout" in policy_cfg else None
1098
+ ),
1099
+ rl_games_multibinary_threshold=(
1100
+ policy_cfg["multibinary_threshold"]
1101
+ if "multibinary_threshold" in policy_cfg
1102
+ else None
1103
+ ),
1104
+ )
1105
+ if "backbone_path" in policy_cfg:
1106
+ wrapper_kwargs["backbone_path"] = policy_cfg["backbone_path"]
1107
+ if integration_env_name == "gymnasium":
1108
+ action_space = gymnasium_action_space_contract(env_cfg)
1109
+ wrapper_kwargs["rl_games_action_env_dim"] = len(action_space["labels"])
1110
+ if action_space["type"] == "box":
1111
+ wrapper_kwargs["rl_games_gymnasium_action_space_type"] = "box"
1112
+ wrapper_kwargs["rl_games_env_name"] = integration_env_name
1113
+ wrapper = wrapper_cls(**wrapper_kwargs)
1114
+ return StarVlaPolicyRunner(
1115
+ wrapper=wrapper,
1116
+ checkpoint_path=policy_cfg["checkpoint_path"],
1117
+ device=policy_cfg["device"],
1118
+ **runner_kwargs,
1119
+ image_views_info_key=(
1120
+ policy_cfg["image_views_info_key"]
1121
+ if "image_views_info_key" in policy_cfg
1122
+ else None
1123
+ ),
1124
+ action_output_type=(
1125
+ policy_cfg["action_output_type"]
1126
+ if "action_output_type" in policy_cfg
1127
+ else None
1128
+ ),
1129
+ )
1130
+
1131
+
1132
+ def build_live_starvla_policy(
1133
+ *,
1134
+ framework: Any,
1135
+ model_cfg: dict[str, Any],
1136
+ config: dict[str, Any],
1137
+ action_resolver: ActionResolver | None = None,
1138
+ ) -> PolicyRunner:
1139
+ """Build a StarVLA policy around a *live* in-memory framework (no reload).
1140
+
1141
+ Mirrors ``build_starvla_policy`` but swaps the ckpt-loading
1142
+ ``PolicyServerWrapper`` for :class:`LiveStarVlaWrapper`, so the trainer's
1143
+ resident model is evaluated directly. ``model_cfg`` is the in-memory model
1144
+ config (e.g. ``read_mode_config`` output) the wrapper would otherwise read
1145
+ from disk.
1146
+ """
1147
+ policy_cfg = config["policy"]
1148
+ if "task_contract_path" in policy_cfg:
1149
+ from latency_bench.policy.starvla_tasks import TaskStarVlaPolicyRunner
1150
+
1151
+ contract = json.loads(
1152
+ Path(policy_cfg["task_contract_path"]).read_text(encoding="utf-8")
1153
+ )
1154
+ return TaskStarVlaPolicyRunner(
1155
+ framework,
1156
+ policy_config=policy_cfg,
1157
+ model_config=model_cfg,
1158
+ contract=contract,
1159
+ )
1160
+
1161
+ env_cfg = config["env"]
1162
+ integration_env_name = env_cfg["name"]
1163
+ normalized_model_cfg = (
1164
+ _normalized_model_cfg(model_cfg)
1165
+ if integration_env_name == "gymnasium"
1166
+ else None
1167
+ )
1168
+ # Resident evaluation historically takes non-Gymnasium prompts from the map.
1169
+ runner_kwargs = _starvla_runner_kwargs(
1170
+ config, action_resolver, normalized_model_cfg, base_prompt=None
1171
+ )
1172
+ wrapper_kwargs: dict[str, Any] = dict(
1173
+ framework=framework,
1174
+ model_cfg=model_cfg,
1175
+ env_name=integration_env_name,
1176
+ action_layout=policy_cfg["action_layout"] if "action_layout" in policy_cfg else None,
1177
+ multibinary_threshold=(
1178
+ policy_cfg["multibinary_threshold"]
1179
+ if "multibinary_threshold" in policy_cfg
1180
+ else None
1181
+ ),
1182
+ )
1183
+ if integration_env_name == "gymnasium":
1184
+ action_space = gymnasium_action_space_contract(env_cfg)
1185
+ wrapper_kwargs["rl_games_action_env_dim"] = len(action_space["labels"])
1186
+ if action_space["type"] == "box":
1187
+ wrapper_kwargs["gymnasium_action_space_type"] = "box"
1188
+ wrapper_kwargs["env_name"] = integration_env_name
1189
+ wrapper = LiveStarVlaWrapper(**wrapper_kwargs)
1190
+ return StarVlaPolicyRunner(
1191
+ wrapper=wrapper,
1192
+ checkpoint_path=policy_cfg.get("checkpoint_path", ""),
1193
+ device=policy_cfg.get("device", "cuda"),
1194
+ **runner_kwargs,
1195
+ )
1196
+
1197
+
1198
+ __all__ = [
1199
+ "LiveStarVlaWrapper",
1200
+ "StarVlaPolicyRunner",
1201
+ "apply_starvla_model_input_config",
1202
+ "build_live_starvla_policy",
1203
+ "build_starvla_policy",
1204
+ "decode_starvla_action",
1205
+ "observation_data_to_hwc_uint8_frames",
1206
+ "prepare_starvla_checkpoint_input_config",
1207
+ ]
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-code/starvla_tasks.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """StarVLA inference using the task's training observation/action contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from pathlib import Path
7
+
8
+ import numpy as np
9
+ from PIL import Image
10
+
11
+ from latency_bench.core.types import Action, Observation, PolicyOutput
12
+ from latency_bench.data.starvla_tasks import denormalize, normalize
13
+ from latency_bench.policy.base import PolicyRunner
14
+
15
+
16
+ class TaskStarVlaPolicyRunner(PolicyRunner):
17
+ """Map task RGB/state into a StarVLA model and decode its action chunk."""
18
+
19
+ def __init__(self, framework, *, policy_config: dict, model_config: dict, contract: dict):
20
+ self.framework = framework
21
+ self.policy_config = policy_config
22
+ self.model_config = model_config
23
+ self.contract = contract
24
+
25
+ def _example(self, observation: Observation) -> dict:
26
+ cfg = self.policy_config
27
+ state = normalize(
28
+ observation.metadata[cfg["state_info_key"]],
29
+ self.contract["normalization"]["state"],
30
+ ).reshape(1, self.contract["state_dim"])
31
+ data_cfg = self.model_config["datasets"]["vla_data"]
32
+ height, width = data_cfg["obs_image_size"]
33
+ images = [
34
+ Image.fromarray(frame).resize((width, height))
35
+ for frame in observation.metadata[cfg["image_views_info_key"]]
36
+ ]
37
+ if data_cfg["image_mode"] == "stitch_views":
38
+ from starVLA.training.trainer_utils.trainer_tools import stitch_frames
39
+
40
+ # MIKASA's two simultaneous views form one Wan observation, not a video.
41
+ images = [stitch_frames(images, grid=data_cfg["stitch_grid"], size=(width, height))]
42
+ example = {"image": images, "state": state, "lang": self.contract["prompt"]}
43
+ if "action_prefix" in observation.metadata:
44
+ example["action_prefix"] = normalize(
45
+ observation.metadata["action_prefix"],
46
+ self.contract["normalization"]["action"],
47
+ )
48
+ example["action_prefix_mask"] = observation.metadata["action_prefix_mask"]
49
+ return example
50
+
51
+ def predict(self, observation: Observation) -> PolicyOutput:
52
+ return self.predict_batch([observation])[0]
53
+
54
+ def predict_batch(self, observations: list[Observation]) -> list[PolicyOutput]:
55
+ prediction = self.framework.predict_action(
56
+ examples=[self._example(observation) for observation in observations]
57
+ )
58
+ actions = denormalize(
59
+ prediction["normalized_actions"], self.contract["normalization"]["action"]
60
+ )
61
+ # Prefix heads were excluded from the loss; retain the frozen controller plan.
62
+ for chunk, observation in zip(actions, observations):
63
+ if "action_prefix" in observation.metadata:
64
+ mask = observation.metadata["action_prefix_mask"]
65
+ chunk[mask] = observation.metadata["action_prefix"][mask]
66
+ return [
67
+ PolicyOutput(
68
+ action=Action(value=chunk[0].tolist(), name="task_command"),
69
+ action_chunk=chunk,
70
+ raw_output=chunk.tolist(),
71
+ metadata={"policy_type": "starvla", "task": self.contract["task"]},
72
+ )
73
+ for chunk in actions
74
+ ]
75
+
76
+
77
+ def build_task_starvla_policy(config: dict) -> TaskStarVlaPolicyRunner:
78
+ # StarVLA and torch are optional in the simulator process; workers own them.
79
+ import torch
80
+ from starVLA.model.framework.base_framework import baseframework
81
+ from starVLA.model.framework.share_tools import read_mode_config
82
+
83
+ cfg = config["policy"]
84
+ model_config, _ = read_mode_config(cfg["checkpoint_path"])
85
+ framework = baseframework.from_pretrained(
86
+ cfg["checkpoint_path"], backbone_path=cfg["backbone_path"]
87
+ )
88
+ framework = framework.to(device=cfg["device"], dtype=torch.bfloat16).eval()
89
+ contract = json.loads(Path(cfg["task_contract_path"]).read_text(encoding="utf-8"))
90
+ return TaskStarVlaPolicyRunner(
91
+ framework, policy_config=cfg, model_config=model_config, contract=contract
92
+ )
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/evaluation-plan.json ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "condition": "profile-latency",
3
+ "executor_mode": "simulated",
4
+ "latency_method": "temporal",
5
+ "profile_source": "originalRTX3090immutableprofiles",
6
+ "episodes_per_checkpoint": 100,
7
+ "total_episodes": 400,
8
+ "rounds": [
9
+ [
10
+ "flappy",
11
+ "deadly_corridor"
12
+ ],
13
+ [
14
+ "ant",
15
+ "intercept"
16
+ ]
17
+ ],
18
+ "physical_gpu_assignments": {
19
+ "flappy": 2,
20
+ "deadly_corridor": 3,
21
+ "ant": 2,
22
+ "intercept": 3
23
+ },
24
+ "single_gpu_per_job": true,
25
+ "round2_requires_both_round1_complete": true,
26
+ "latency_seed": 271828,
27
+ "tasks": {
28
+ "flappy": {
29
+ "gpu": 2,
30
+ "seed_start": 1000000,
31
+ "seed_end": 1000099,
32
+ "env_fps": 10,
33
+ "obs_fps": 10,
34
+ "max_raw_steps": 3600,
35
+ "parallel_envs": 32,
36
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
37
+ "checkpoint_path": "latency-aware/flappy/vla/starvla-qwenoft-h1/flappy-qwenoft-mean-3090-s42",
38
+ "profile": {
39
+ "mean_ms": 75.87417450998383,
40
+ "profile": "/home/ubuntu/lzj/profiles/published/profiles/openvla/1x-rtx3090/flappy/instance_a5037b165aa0cedc/profile.json",
41
+ "sha256": "c266cba7ebac05c7e37bc83f1f16fe4b27dab97942ff43290e6c41514f6e39fc"
42
+ },
43
+ "config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/flappy.yaml",
44
+ "output": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/flappy",
45
+ "metrics": "return mean/std/min/max;length mean/std;success where nativeprovided;latency/drops/invalid/action audits;100 episode vectors"
46
+ },
47
+ "deadly_corridor": {
48
+ "gpu": 3,
49
+ "seed_start": 1000000,
50
+ "seed_end": 1000099,
51
+ "env_fps": 35,
52
+ "obs_fps": 8.75,
53
+ "max_raw_steps": 3600,
54
+ "parallel_envs": 32,
55
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
56
+ "checkpoint_path": "latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42",
57
+ "profile": {
58
+ "mean_ms": 73.69250777493353,
59
+ "profile": "/home/ubuntu/lzj/profiles/published/profiles/openvla/1x-rtx3090/deadly_corridor/instance_a5037b165aa0cedc/profile.json",
60
+ "sha256": "bbfb93cef9f63750a9a159ec10a93a9fc6c25e4cb0cac3b39532663b4dc11eba"
61
+ },
62
+ "config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/deadly_corridor.yaml",
63
+ "output": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/deadly_corridor",
64
+ "metrics": "return mean/std/min/max;length mean/std;success where nativeprovided;latency/drops/invalid/action audits;100 episode vectors"
65
+ },
66
+ "ant": {
67
+ "gpu": 2,
68
+ "seed_start": 42,
69
+ "seed_end": 141,
70
+ "env_fps": 10,
71
+ "obs_fps": 10,
72
+ "max_raw_steps": 1000,
73
+ "parallel_envs": 16,
74
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
75
+ "checkpoint_path": "latency-aware/ant/vla/starvla-qwenoft-h1/ant-qwenoft-mean-3090-s42",
76
+ "profile": {
77
+ "mean_ms": 90.56460638563993,
78
+ "profile": "/home/ubuntu/lzj/mean-profiling/reference/checkpoint-configs/latency-aware/ant/small-policy/sample-factory-qwenoft-rtx3090-v1/profile/profile.json",
79
+ "sha256": "0e49f72ec05ac600a54e07bbca5af3143708444d606167f33fa21788a9fefe50"
80
+ },
81
+ "config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant.yaml",
82
+ "output": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/ant",
83
+ "metrics": "return mean/std/min/max;length mean/std;success where nativeprovided;latency/drops/invalid/action audits;100 episode vectors"
84
+ },
85
+ "intercept": {
86
+ "gpu": 3,
87
+ "seed_start": 4242424242,
88
+ "seed_end": 4242424341,
89
+ "env_fps": 20,
90
+ "obs_fps": 20,
91
+ "max_raw_steps": 60,
92
+ "parallel_envs": 32,
93
+ "checkpoint_revision": "d4825bbad8d15bc50b6b8481eb2abc84846a54fb",
94
+ "checkpoint_path": "latency-aware/mikasa-intercept-grab-fast/vla/starvla-qwenoft-h1/intercept-qwenoft-mean-3090-h1-s0",
95
+ "profile": {
96
+ "mean_ms": 99.05021289731565,
97
+ "profile": "/home/ubuntu/lzj/profiles/intercept-published/profiles/qwenoft/1x-rtx3090/mikasa_intercept_grab_fast/instance_3a0d42681a03715c/profile.json",
98
+ "sha256": "31a9b15d6b04182439934f0b377cb3d09be16ce21f3cf95c1049918f8a5d4984"
99
+ },
100
+ "config": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/intercept.yaml",
101
+ "output": "/home/ubuntu/lzj/mean-profiling/evaluation/profile-latency-100ep-20261001/intercept",
102
+ "metrics": "return mean/std/min/max;length mean/std;success where nativeprovided;latency/drops/invalid/action audits;100 episode vectors"
103
+ }
104
+ }
105
+ }
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/execution_audit.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "issued_action_records": 3753,
3
+ "applied_action_records": 3673,
4
+ "dropped_action_records": 0,
5
+ "nonnoop_issued_records": 3753,
6
+ "finite_action_values": true,
7
+ "latency_sample_count": 3753,
8
+ "latency_mean_ms": 74.01999621872471,
9
+ "latency_std_ms": 5.5537519652567635,
10
+ "latency_p95_ms": 89.54825982614612,
11
+ "latency_p99_ms": 95.97310052501227
12
+ }
latency-aware/deadly-corridor/vla/starvla-qwenoft-h1/deadly_corridor-qwenoft-mean-3090-s42/evaluation/profile-simulation-100ep-20261001/files.sha256.json ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "REPORT.md": {
3
+ "bytes": 2163,
4
+ "sha256": "b2fd63b1cde2a415b2d77daf0184ce5ec3b6ada1aa199c21941fb04031f77db6"
5
+ },
6
+ "all_episodes.csv": {
7
+ "bytes": 25198,
8
+ "sha256": "bd41f35a464250ed6f9bc16e466aa9f1b55a48ac29072bb0ec3559a24129edac"
9
+ },
10
+ "comparison.csv": {
11
+ "bytes": 438,
12
+ "sha256": "a0c7cf191395dd851bd6222bdf61427f15782fea2db4416ddc072a5f5dc8a861"
13
+ },
14
+ "comparison.json": {
15
+ "bytes": 7826,
16
+ "sha256": "0d5dd042439466aee84cd0d96c31a27a951e57965a7e468cb73ec07883f1f751"
17
+ },
18
+ "episodes.csv": {
19
+ "bytes": 5665,
20
+ "sha256": "69e8140b74f407803e15adcf4412ccb7c5a51abd0a9c274ee55a6c51b4e9245d"
21
+ },
22
+ "eval_config.yaml": {
23
+ "bytes": 3299,
24
+ "sha256": "cdebec7e4e48415f530a665a08f2dd98808381ce1d871f75d25385e4a38b54ec"
25
+ },
26
+ "evaluation-code/batched_simulated.py": {
27
+ "bytes": 31282,
28
+ "sha256": "b901f966d911feab7962a32f21095cb90f7880121811f2b4eab2193afe1381db"
29
+ },
30
+ "evaluation-code/deadly-compatibility.patch": {
31
+ "bytes": 4570,
32
+ "sha256": "623676cc4542b1eab6c9395b163b369ddc605353c1de02d17d8f713167ee07fa"
33
+ },
34
+ "evaluation-code/deadly_corridor.py": {
35
+ "bytes": 17902,
36
+ "sha256": "47f7bc65cba9853e66d79ed2a28f844bd2a094f1285458be166045f2db1690dc"
37
+ },
38
+ "evaluation-code/decision_action_history.py": {
39
+ "bytes": 2746,
40
+ "sha256": "14a9d223e775745b6c402dbce9e2a50a1c3f7b5b9fe528150ef8689126fe97cf"
41
+ },
42
+ "evaluation-code/eval_driver.py": {
43
+ "bytes": 9133,
44
+ "sha256": "330030270fbb695bc5f14037ef7349650bd20c53c881c1159ee55ea066408d9e"
45
+ },
46
+ "evaluation-code/mikasa_evaluate.py": {
47
+ "bytes": 11466,
48
+ "sha256": "6cf9ffee25fcfd6f3255c520fc544c48ff2c8f8912e5369c2410a709820c4ffd"
49
+ },
50
+ "evaluation-code/starvla.py": {
51
+ "bytes": 48378,
52
+ "sha256": "6d9988f3a28d39e46c2f6e80da85edebc42cafa629a2b9f75000414324c1065a"
53
+ },
54
+ "evaluation-code/starvla_tasks.py": {
55
+ "bytes": 4029,
56
+ "sha256": "3fc74169d1554d9dc3358ed85e450cca75eb69bc1fff85284c1054a605633a52"
57
+ },
58
+ "evaluation-plan.json": {
59
+ "bytes": 4698,
60
+ "sha256": "b758a5fb72dcdef49d025e2fd168d024ebd8b18b2b00125145b3cde38b16a318"
61
+ },
62
+ "execution_audit.json": {
63
+ "bytes": 357,
64
+ "sha256": "cd445b9926cd0c8b4da3e48d2137bf80ae44e44a0cef30563d3c7a1f2a31b920"
65
+ },
66
+ "profile/latency_burst_model.json": {
67
+ "bytes": 26211,
68
+ "sha256": "2e52774207a61ccc9902ec6c576d75ae0f60925611f1f8a9fc55c3109f7ff34c"
69
+ },
70
+ "profile/latency_distribution.json": {
71
+ "bytes": 25069,
72
+ "sha256": "c6c7926af60218a9b5f8b0fbabb7f10466d224dd739171349650520ef1da9fc8"
73
+ },
74
+ "profile/profile.json": {
75
+ "bytes": 2115,
76
+ "sha256": "bbfb93cef9f63750a9a159ec10a93a9fc6c25e4cb0cac3b39532663b4dc11eba"
77
+ },
78
+ "provenance.json": {
79
+ "bytes": 3856,
80
+ "sha256": "a34689af61c380a5e7a64d3bf25d921a44967aee0c2220c7ede4a36a97b9cae5"
81
+ },
82
+ "queue_eval_latency_profile_sample.json": {
83
+ "bytes": 3848,
84
+ "sha256": "dd4c4be8669838a85c0d7e06c5ccf20f133bb2fb2cacdd9b905972343bbd03b6"
85
+ },
86
+ "raw-records/actions.jsonl.gz": {
87
+ "bytes": 522227,
88
+ "sha256": "53f0b7bb59fb99cdd2917642c9881cb1443f897c78e20f1567929b4b232680fd"
89
+ },
90
+ "raw-records/e2e_latencies.jsonl.gz": {
91
+ "bytes": 70931,
92
+ "sha256": "9c6b0b88fbfb5f6b37ea28ac5c6701c9abc2fa89b2d6b36b7fe747b6c1cf4398"
93
+ },
94
+ "raw-records/episode_metrics.jsonl.gz": {
95
+ "bytes": 7835,
96
+ "sha256": "c96daa6d0d6f5051f6a20701c54ba21ebf5e425740028916cd553e2c8bd7cbd2"
97
+ },
98
+ "raw-records/infer_latencies.jsonl.gz": {
99
+ "bytes": 60189,
100
+ "sha256": "42a899945c8383a4d86d62b77692c1a2f4022a3cec41d5aada23bdc8f45df931"
101
+ },
102
+ "raw-records/latencies.jsonl.gz": {
103
+ "bytes": 60183,
104
+ "sha256": "12d682b1436b118a5058ec2364e2e7ee9cf45035224d7e04e0723689f476b01b"
105
+ },
106
+ "raw-records/observation_attempts.jsonl.gz": {
107
+ "bytes": 47,
108
+ "sha256": "6ce7d0c6fa3086525b7ba82526a5db7d4a26d33a64b16875bdd644c436069469"
109
+ },
110
+ "raw-records/queue_eval_results.jsonl.gz": {
111
+ "bytes": 1468,
112
+ "sha256": "c717edfdd81c255faec3f3f765ecc4d378f353e459e1124a02b3fb070c71a10a"
113
+ },
114
+ "raw-records/steps.jsonl.gz": {
115
+ "bytes": 495220,
116
+ "sha256": "f6a4d4bf35f367394f0754bff9ada16daa229726d0ccbbfede23411cffbdbd74"
117
+ },
118
+ "resolved_config.yaml": {
119
+ "bytes": 3367,
120
+ "sha256": "0ac444e55dcf84745badbb2614d75fc38b23abd09c87aee5fbc2ecba991854f0"
121
+ },
122
+ "statistics.json": {
123
+ "bytes": 1288,
124
+ "sha256": "39d572fde494928e335d2999b2731fc2705e3d98bb260af101e2d1eef2089467"
125
+ },
126
+ "stdout.log": {
127
+ "bytes": 59183,
128
+ "sha256": "3a511f78f66916995fc35c64092732d1e1499a092cb4db441e003c70a6273c2f"
129
+ }
130
+ }