Repository navigation
feat(rlt): sync with main and align online RL with the RLT paper - #26
Merged
Merged
Conversation
…orm stats Include Elite CS66 runtime, bench recipes, policy adapters, training config registration and tests, plus Elite egg-carton and Flexiv strap-tape training configs. Revert UMI-specific normalization changes and import training loaders only for Torch/RLDS paths so parquet statistics work with the local lerobot-xense implementation.
Handle lerobot-xense builds without dataset_reader and filter video timestamps on the dataset for their legacy getitem path. Preserve reader filtering for implementations that delegate reads to DatasetReader. Exercise both installed API variants, including actual frame reads with default, selected, and empty video whitelists.
Retire unsafe XLA collective launch flags and document the findings. Include the whiteboard inspection config, remove the obsolete box assembly config, and preserve current prompt formatting updates.
…ot resolution - compute_norm_stats parquet path now applies XtacUmiStateActions and XtacUmiRelativeActions, so drop_head_pose / use_relative_pose_actions configs get 2D gripper-state and relative-action stats instead of 29D absolute-pose stats that Normalize silently truncated. - Add config.resolve_dataset_root (DataConfig.dataset_root first, OPENPI_LEROBOT_DATASET_ROOT fallback), used by both training and compute_norm_stats so they read the same dataset. --dataset-root stays a one-off override and warns when it differs from the training root. - Add scripts/compute_norm_stats_test.py covering both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ttention feat: add Elite/Rebot robot support, extend XTac-UMI training, and clean up JAX attention
The lockfile was removed from the repo in 6061181, but `uv run` keeps regenerating it in the working tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bring in PR #24 (cuDNN attention removal, retired XLA flags, explicit LR schedules, Elite/Rebot/XTac-UMI work) and the follow-ups since. Conflicts: cylinder_stack_1009 and strap_tape_1010 VLA configs take main's version (strap_tape trains on Xense/strap-tape-taccap-1015). Fix the cylinder_stack launch comment that named the earbuds config. Fallout from the cuDNN removal: - rlt/vla.py: drop the use_cudnn_attention override; the field is gone and FrozenVLA.load_model would raise AttributeError. - insert_ethernet_0928 VLA config: drop use_cudnn_attention / cudnn_attention_dtype (config load would fail) and the retired XLA collective flags from the launch comment (they corrupted FSDP gradients). - strap_tape RLT config: dataset comment now says 1015. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The learner spent each round's earned updates between rounds while the robot idled, and the actor never improved within a round. Add a BackgroundTrainer thread that spends the earned budget while the robot collects, so every chunk acts with the latest weights (RLT paper, "Update", pp. 5-6). - Learner: one RLock guards weights, optimizer states, replay, the RNG and the update counters. train_step() does one earned update with the gradient steps outside the lock, so act/commit never wait behind them; train() is now a loop over it. Snapshots and checkpoints take the lock and never see half an update. - BackgroundTrainer: idles until commit() earns budget; a failure is re-raised by the next act()/mean() and by drain(), so collection does not continue on stale weights. - Rows still reach replay once per round, so a discard never has to be undone; UTD accounting is unchanged. - train_rl.py: rl.async_training (default true; operational, may change on resume). A finished run spends the remaining backlog before the final save; an interrupted one stops at once and resume picks the backlog up from the counters. Tests: background training reproduces synchronous training exactly, acting and committing while training, interrupt + resume keeps the backlog, trainer failures re-raise, and a multi-round collector loop with the trainer running. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The RLT paper uses C=10 (App. B, a 0.2 s chunk at 50 Hz); TacXense's C=20 is 0.67 s at our 30 Hz and is not covered by the paper's ablation (C=1 vs 10). C=10 makes the actor react twice as often and halves the TD bootstrap horizon; replay_stride 2 still divides it. Applies to the default and to the cylinder_stack, insert_ethernet and strap_tape RLT configs. The actor and critic head widths depend on C, so RL checkpoints trained at C=20 cannot be resumed under these configs (the contract check refuses them); phase-one token checkpoints are unaffected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The RLT paper's replay pools the warm-up rollouts, RL data and teleoperated interventions of the whole run (15 min to 5 h of robot data, p. 3 and App. B). Our 6000-row FIFO held ~7 min of labeled data at 30 Hz with replay_stride 2 (15 transitions per second), so the warm-up and the early interventions were overwritten within a few rounds. - Default rl.buffer_size 100k (~1.85 h of labeled data); also in the cylinder_stack, insert_ethernet and strap_tape configs. A row is 25.6 KB (measured, z_rl 2048, reference 50x20), so a full buffer costs ~2.6 GB of RAM and of each RL checkpoint. The arrays are allocated lazily. - ReplayBuffer counts rows ever added; eviction is logged once when it starts, reported in the round summary, and logged as round/replay_evicted. Older checkpoints without the counter still load. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The equivalence tests (remat, batch independence, trailing-padding trim, cache vs online features) assert ~1e-4, but on GPUs whose default float32 matmul uses TF32/bf16 passes the kernel choice varies with batch shape and results differ by a few 1e-4. They failed intermittently, and test_remat_matches failed every run on an RTX PRO 6000. Set jax_default_matmul_precision=highest for the rlt tests. It is set globally rather than with the jax.default_matmul_precision context, which is thread-local and would miss the BackgroundTrainer thread. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The RLT paper drops the language embeddings before training the RL token,
since each task has a fixed instruction (Sec. IV-A, footnote 1). pi05 with
discrete_state_input renders "Task: {instruction}, State: {state};\nAction: ",
so the prompt slots also carry the discretized robot state: masking only the
instruction keeps that state information.
- rlt/prompt_tokens.py: mask the prompt slots before the last "▁State" token.
The state section (digits, spaces, ";", "Action:") never tokenizes to
"▁State", so the last occurrence is the template's even if the instruction
says "State". Without a state in the prompt (pi0) or if it was truncated
away, the whole prompt is dropped.
- RLTModelConfig.drop_task_tokens (default true). Applied when the prefix
cache is built and when online features are extracted, so phase one and
phase two see the same prefix.
- The cache identity and the token checkpoint metadata record the setting.
Existing caches and token checkpoints (without the key) count as kept, so
a cache built before this change is refused under the new default instead
of silently mixing the two, and old token checkpoints keep working online
with the full prompt.
Migration: rebuild prefix caches (precompute_prefix.py --overwrite) and
retrain the token, or set model.drop_task_tokens: false to keep using them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AtticusZeller
pushed a commit
to AtticusZeller/xense-openpi
that referenced
this pull request
Nov 13, 2026
The pull_request filter "*" does not match "/", so PRs into branches like feature/rlt-jax (e.g. XenseRobotics-AI#26) got no checks at all. "**" matches every branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
把
feature/rlt-jax同步到最新main,并按 RLT 原论文(rlt.pdf)对齐在线 RL 的几处实现。建议按 commit 逐个 review:第一个是合并
main,diff 里大部分来自main(PR #24 等),真正的 RLT 改动集中在后面 5 个 commit。Commits
0e1121f合并mainmain的版本,strap_tape 用Xense/strap-tape-taccap-1015。rlt/vla.py删掉对use_cudnn_attention的引用(否则加载 VLA 时报AttributeError);insert_ethernet_0928 配置删掉 cuDNN 字段,以及启动说明里会把 FSDP 梯度算错的 XLA 参数。5468a47采集和训练同时进行(论文 pp. 5-6)BackgroundTrainer线程,机器人一边采集一边训练,每个动作块都用最新权重。以前每轮结束后机器人要停下来等训练。rl.async_training,默认true,resume 时可以改。3eba8fe动作块 C 改为 10(论文附录 B):默认值和 3 个任务配置都改了,30Hz 下一个动作块从 0.67s 缩短到 0.33s。2739370经验回放容量从 6000 改为 10 万条(约 1.85 小时的标注数据)round/replay_evicted。44f637eRLT 测试统一用完整 float32 精度做矩阵乘法test_remat_matches之前每次都失败。jax.default_matmul_precision上下文只对当前线程生效,管不到后台训练线程。5d6eca9RL token 的输入去掉任务指令 token(论文 §IV-A 脚注 1)Task: ...,部分,保留 pi05 prompt 里离散化的State: ...。model.drop_task_tokens,默认true。drop_task_tokens默认开启:check_identity拒绝。需要用precompute_prefix.py --overwrite重新生成,再重训 token;或者设model.drop_task_tokens: false继续用旧缓存。没做的
测试
src/openpi/rlt、rlt_policy_test、rlt_mode_test)连续两次跑出 82 passed, 9 skipped,test_remat_matches也包含在内。新增测试:learner_test.py:后台训练与同步训练结果完全一致;训练进行时仍能取 actor 输出、提交数据;中途打断再 resume 不丢待训练的更新;后台出错能报出来;经验回放的覆盖统计。collector_test.py:后台训练运行时的多轮采集集成测试。prompt_tokens_test.py:用真实 PaliGemma tokenizer 验证,只丢掉指令、保留 State,包括指令本身含 "State" 的情况。features_test.py:在线特征和缓存路径在开/关两种设置下一致。chunk/feature_ms(VLA 推理和后台训练抢同一块 GPU)和经验回放占用的内存。🤖 Generated with Claude Code