11# SimpleVLA-RL (arXiv:2509.09674) on LIBERO: OpenVLA-OFT token variant (7B),
2- # the paper's hyper-parameters. Parallel MuJoCo workers (one process each)
3- # feed a single training device ; see the README for the multi-GPU notes and
2+ # the paper's hyper-parameters. H100 fast mode uses shared policy-server
3+ # MultiCollector rollout workers ; see the README for the multi-GPU notes and
44# the LoRA fallback. Requires LIBERO (and its deps) plus transformers/timm.
55#
6- # Per-iteration accounting: groups_per_iter x group_size = 512 trajectories,
6+ # Per-target-wave accounting: groups_per_iter x group_size = 320 trajectories,
77# each up to max_outer_steps = 64 chunk decisions (512 env steps / chunk 8).
88
99env :
1010 backend : libero
1111 task_suite : libero_spatial # libero_spatial | libero_object | libero_goal | libero_10
1212 task_ids : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # one worker per task (num_envs must cover them)
13- # Parallel MuJoCo processes (training); >= len(task_ids). For GRPO, each
14- # worker owns serial group ids, so keep num_envs <= groups_per_iter (ideally
15- # a divisor, often equal) or no worker may finish a full group per iteration.
16- num_envs : 10
13+ num_envs : 80
1714 # false: each worker replays group_size rollouts serially for one group.
1815 # true: group_size workers share the same task/init state/group id and
1916 # collect a GRPO group in parallel. This improves group-completion throughput
2623 # batches can overcollect under one policy, but without a group barrier they
2724 # may also drift; the LIBERO wrapper groups parallel repeats by cycled
2825 # init-state id to reduce this waste.
29- parallel_group_repeats : false
26+ parallel_group_repeats : true
3027 eval_num_envs : 10 # parallel MuJoCo processes (evaluation); >= len(task_ids)
3128 camera_height : 256
3229 camera_width : 256
3330 render_backend : egl # egl (GPU/headless) | osmesa (CPU fallback)
34- render_gpu_ids : [0] # EGL-visible ids; override to [0,1,...] to spread workers
35- eval_render_gpu_ids : null # null = reuse render_gpu_ids for eval workers
31+ render_gpu_ids : [2, 3, 4, 5] # H100 fast mode render GPUs for rollout workers
32+ eval_render_gpu_ids : [7] # reserve GPU 7 for eval/video rendering
33+ render_gpu_device_zero_fallback : true
34+ env_kwargs : null
3635 chunk_size : 8 # NUM_ACTIONS_CHUNK of the checkpoint
3736 max_env_steps : 512 # base env steps per episode (the paper's cap)
3837 max_outer_steps : 64 # = max_env_steps / chunk_size, in chunk decisions
39- train_init_state_mode : random # random | cycle | fixed; eval always cycles
38+ train_init_state_mode : cycle # random | cycle | fixed; eval always cycles
39+ train_init_state_id : 0 # selected LIBERO init state when train_init_state_mode=fixed
4040 seed : 0
4141
4242tokenizer :
4343 vocab_size : 256 # unused for the openvla backend (codec comes from the checkpoint)
4444
4545policy :
4646 backend : openvla
47+ mode : tokens # tokens: SimpleVLA-RL GRPO path; l1: official continuous OFT reference/eval path
4748 # the checkpoint MUST match task_suite (it fixes the SFT policy AND the
4849 # action statistics unnorm_key resolves into)
4950 checkpoint : Haozhan72/Openvla-oft-SFT-libero-spatial-traj1
@@ -56,58 +57,54 @@ policy:
5657 temperature : 1.6 # rollout sampling temperature (greedy eval)
5758 top_k : null # null = full categorical; small values keep token exploration local
5859 use_wrist_image : false
60+ # L1 reference path: set mode=l1, checkpoint=moojink/openvla-7b-oft-finetuned-libero-spatial,
61+ # use_wrist_image=true, use_proprio=true, num_images_in_input=2.
62+ action_head_file : action_head--150000_checkpoint.pt
63+ proprio_projector_file : proprio_projector--150000_checkpoint.pt
64+ use_proprio : false
65+ num_images_in_input : 1
5966 center_crop : true # the SimpleVLA-RL checkpoints are trained with augmentations
60- image_backend : torchvision # OpenVLA image preprocessing backend : torchvision | pil
67+ image_backend : torchvision # OpenVLA preprocessing: torchvision | pil | tensorflow (reference)
6168 # the model emits a continuous gripper; LIBERO/robosuite needs a firm +/-1
6269 # open/close (demo gripper is binary, -1 open / +1 close). SimpleVLA-RL
63- # applies sign(2* g - 1) then inverts, i.e. a 0.5 binarization threshold
64- # before the open/close sign flip .
70+ # applies sign(2 * g - 1) then inverts, so threshold 0.0 here is equivalent
71+ # to threshold 0.5 on the raw decoded gripper scalar .
6572 gripper_binarize : true
66- gripper_binarize_threshold : 0.5
73+ gripper_binarize_threshold : 0.0
6774 gripper_invert : true
6875 lora_rank : 32 # de-risk fallback; set to 0/null for full fine-tuning (needs FSDP)
6976 lora_target_modules : [q_proj, k_proj, v_proj, o_proj]
70- device : null # null = auto (cuda if available)
77+ device : cuda:0 # training device
7178
7279collector :
7380 group_size : 8 # n: rollouts per initial state (GRPO group)
7481 candidate_group_size : null # null = group_size; e.g. 16 samples 16 and selects 8
75- # Initial states per iteration (512 trajectories). Must be >= env.num_envs;
76- # for best throughput, use a multiple of env.num_envs so no partial groups
77- # are discarded at the synchronous update boundary. If
78- # env.parallel_group_repeats=true, use env.num_envs / group_size instead.
79- groups_per_iter : 64
80- # Safety cap in target group waves. The collector writes complete
81- # trajectories directly to the replay buffer every one-outer-step internal
82- # poll; one wave is approximately max_outer_steps *
83- # ceil(groups_per_iter * group_size / num_envs) polls. Keeping MCAdvantage
84- # queues across these same-policy polls lets partial GRPO groups finish
85- # without crossing a policy update.
86- max_collect_batches_per_iter : 1
87- # If a capped wave produces too few useful replay decisions, keep the same
88- # rollout policy and queued partial groups for another capped wave instead
89- # of updating on a tiny replay batch and clearing those queues immediately.
90- max_same_policy_collect_attempts : 2
91- min_replay_decisions : null # null/0 = collect one target group wave
82+ # Initial states per iteration (320 trajectories). With shared fast mode and
83+ # env.parallel_group_repeats=true, use
84+ # num_collectors * envs_per_collector / group_size.
85+ groups_per_iter : 40
86+ # null/0 = one full selected rollout set:
87+ # groups_per_iter * group_size * max_outer_steps decisions.
88+ min_replay_decisions : null
9289 total_iters : 100 # the paper's total_epochs
93- policy_device : null # null = policy.device; set e.g. cuda:1 for rollout inference
94- # Execution-mode switches for throughput ablations:
95- # - false/false: regular synchronous TorchRL Collector.
96- # - true/false: async env slots with one request per policy forward.
97- # - true/true: async env slots plus auto-batched policy inference.
98- # - false/true: sync env stepping through the policy server path.
99- async_env : false
100- async_policy : false
101- env_backend : threading # AsyncBatchedCollector env backend: threading | multiprocessing
102- policy_backend : threading # inference transport: threading | multiprocessing | ray | monarch
103- server_backend : thread # process server needs a policy_factory and is not used here
104- server_max_batch_size : null # null = env.num_envs when async_policy=true
90+ policy_device : cuda:1 # H100 default: rollout/eval inference server device
91+ # null = one model forward for the complete request batch. Set to 1 for
92+ # single-environment numerical parity while keeping batched env collection.
93+ policy_micro_batch_size : null
94+ replay_wait_s : 0.5
95+ replay_log_s : 30.0
96+ num_collectors : 4
97+ envs_per_collector : 80
98+ num_threads : 1
99+ server_max_batch_size : 1 # one batched ParallelEnv request; avoids mixed eval/rollout modes
105100 server_min_batch_size : 1
106- server_timeout : 0.01
101+ server_timeout : 0.001
107102 server_collect_stats : true
108103 server_stats_window_size : 1024
109104 max_inflight_per_env : 1
110- storing_device : null
105+ env_sub_threads : 1
106+ storing_device : cpu
107+ use_buffers : null
111108
112109advantage :
113110 trajectory_return : sum # binary success return per trajectory
@@ -120,6 +117,9 @@ advantage:
120117
121118buffer :
122119 device : cpu # decisions hold raw uint8 images; keep the buffer off-GPU
120+ shared_init : true
121+ capacity_group_waves : 7 # replay capacity as multiples of one target group wave
122+ consume_after_n_samples : 1 # sampled decisions leave the buffer after one update pass
123123
124124loss :
125125 clip_epsilon : [0.2, 0.28] # asymmetric DAPO Clip-Higher (per-token, see ratio_level)
@@ -142,12 +142,11 @@ logger:
142142 mode : online
143143 eval_iter : 4 # evaluate every N iterations (the paper's cadence)
144144 eval_episodes : 50 # greedy episodes per evaluation (cycled init states)
145- eval_process : false # true = run eval in a dedicated process
146- eval_async : false # with eval_process, submit eval and log result later
147- eval_device : null # null = policy.device/auto; set e.g. cuda:7 with eval_process
148- eval_state_dir : null # null = tempfile dir for trainable-weight snapshots
149- record_video : true # render eval rollouts via VideoRecorder (needs a logger)
150- video_episodes : 2 # greedy episodes per recorded video (one camera stream)
145+ eval_backend : process # TorchRL Evaluator backend: thread | process | ray
146+ eval_async : false # submit eval and log result later
147+ eval_busy_policy : skip # skip | error | queue
148+ eval_timeout_s : 1800.0
149+ eval_device : null # null = rollout device; set e.g. cuda:7 for eval
151150 video_fps : 8 # frames per second of the logged video (one frame per decision)
152151
153152checkpoint :
0 commit comments