Repository navigation
Optimize JAX training throughput and add FP16 cuDNN attention - #18
Conversation
… knobs A/B on 8xH100 (docs/2026-09-04-h100-speed-ab.md): trimming max_token_len 200->128 (-6.2%) and enabling XLA collective combining / pipelining (-3.5%) together cut the earbuds 0904 step time 1.328 -> 1.193 s (-10.2%) with identical loss. - Add configs/_examples/..._0904_h100.yaml with max_token_len 128 and the XLA_FLAGS launch line in its header. - Add scripts/token_len_scan.py: runs the real transform chain over real dataset states to measure tokenized prompt length before setting max_token_len. - Add Pi0Config.gemma_remat_policy / siglip_remat_policy (defaults unchanged). Neither "none" nor dots_with_no_batch_dims_saveable fits at batch 256 on 80 GB, but they are usable on larger GPUs or smaller per-device batches. - Pin q/k/v/mask shardings before the cuDNN attention call; the custom partitioner otherwise fails under non-default remat policies. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Pi0/Pi05 checkpoints trained with use_cudnn_attention now load with the flag cleared. The cuDNN path also runs during lazy initialization and prefix prefill, where no KV cache exists yet, and JAX 0.5.3 only permits head_dim=256 cuDNN attention on Hopper -- so serving such a checkpoint on a non-Hopper GPU failed at trace time. The attention backend does not change the checkpoint parameter structure, and the denoising steps already ran on the explicit path because they carry a KV cache, so only the single prefill call changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4606754 and e13ac0f deleted pi05_droid, pi05_base_xtac_umi_pick_up_cube_0807_h200 and pi05_base_bi_flexiv_pack_6_cosmetic_bottles_lora without updating anything that names them, and get_config() raises on a missing name rather than falling back: - xtac_umi_policy_test.py:112,126 call get_config() on the XTac-UMI config, so two tests fail outright. - serve_policy.py:70 maps EnvMode.DROID to pi05_droid; that was the one entry in DEFAULT_CHECKPOINT that still resolved. - README.md, examples/bi_flexiv_rizon4_rt/README.md, examples/xtac_umi_bi_flexiv_rizon4_rt/README.md and _FULL_REFERENCE.yaml link to all three. Restore them verbatim from 7c51dc5. The earbuds 0520_a100 config stays deleted: the 0904 h100/h200 configs supersede it and only the changelog mentions it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Computing the whole-model norms only on logging steps means the other steps carry NaN placeholders, and the logging reduction switched wholesale to jnp.nanmean to skip them. That also applies to `loss`, so a diverged step is now dropped from the average instead of showing up as loss=nan -- exactly the signal the FP16 cuDNN path needs, given that the per-step finite-update guard is gone and grad_norm is only sampled every log_interval steps. Reduce only grad_norm and param_norm with nanmean; everything else keeps a plain mean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…them eagerly gemma.py imported jax._src.cudnn.fused_attention_stablehlo at module scope. The module is not the fragile part -- jax.nn imports it too, so it is loaded before anything here runs -- but the *names* are: _dot_product_attention_bwd_rule and friends are private and only validated against the pinned jax 0.5.3. A rename would have surfaced as an AttributeError from inside a traced VJP, mid-training. Resolve the module through a cached helper on first use and check the seven symbols the FP16 path calls, so a JAX upgrade fails once with an actionable message naming the missing symbols and the use_cudnn_attention=false fallback. Explicit attention, CPU-only use and inference never reach the helper. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The README calls check_cuda_stack.py the required gate before production training, but section 3 only exercised jax.nn.dot_product_attention in bf16 -- the path this PR itself documents as unsafe. The configuration it tells you to run, `use_cudnn_attention: true` + `cudnn_attention_dtype: float16`, went through gemma._cudnn_attention_in_dtype and was never checked. Add a section 4 that differentiates the FP16 custom VJP at the same production shape against the same fp32 reference, and assert the zero (not NaN, not garbage) q-gradient it promises on the fully-masked rows padding produces. Also compare versions on major.minor: pyproject pins ranges (torch >=2.11,<2.12 and friends), so pinning 2.11.0+cu128 exactly here failed the gate on any upstream patch release. The +cu128 suffix is still checked explicitly, since a CPU-only wheel installs cleanly and silently removes everything this script exists to verify. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The header block was copied from the earbuds config and kept its launch command, so it told you to train pi05_base_bi_flexiv_earbuds_case_insertion_teleop_rtc_0904_h100. Its max_token_len comment was copied too, and claims 128 was scanned "over this dataset" -- but the 4037-state scan was the earbuds dataset, and docs/training-optimization.md is explicit that 128 was validated there and nowhere else. Say that 128 is carried over and not re-scanned against cube-color-sorting-0821, whose prompt and state layout differ. @Hubo1231: if you did scan it, replace this with the numbers; the tokenizer only warns and truncates on overflow, so it would not have shown up in training. Also repair the broken sentence in the earbuds comment the copy came from. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
close() drives _shutdown_workers, _workers and _iterator, none of which are public. Record that this is what the torch>=2.11,<2.12 pin in pyproject.toml protects, and that the getattr guards degrade to the old __del__ reaping rather than raising. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
我在这个分支上直接补了 6 个 commit( 1.
|
Vertax42
left a comment
There was a problem hiding this comment.
见 review 评论;FP16 路径待 GPU 机验证
Summary
Improve JAX training throughput and stability for large-scale Pi0.5 training, with a validated FP16 cuDNN fused-attention path and an
explicit-attention fallback.
This PR also adds Dobot Nova5 dataset/policy support, refreshes production training configs, and updates the Flexiv inference recipes
to use serial grippers.
Changes
NumPy views.
scripts/check_cuda_stack.py.diagonal-02andforward-04inference recipes to use serial grippers.Validation
70 passed:src/openpi/models/pi0_test.pysrc/openpi/training/data_loader_test.pysrc/openpi/policies/dobot_nova5_policy_test.pysrc/openpi/training/config_yaml_test.pygit diff --checkpasses.gradient norm remained below 1.3× the baseline.
Notes
Explicit attention remains the default. Production cuDNN training should use:
BF16 cuDNN attention is not production-safe; it diverged from the explicit baseline after approximately 1,000 steps.
The FP16 implementation calls private JAX 0.5.3 cuDNN APIs and must be revalidated when upgrading JAX, CUDA, or cuDNN.
max_token_len: 128 was validated only for the referenced earbuds dataset and must be checked again for other datasets and prompts.