Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9aef52d
Optimize JAX training data pipeline
Hubo1231 Aug 27, 2026
8ccf99c
Profile and optimize H200 training
Hubo1231 Aug 27, 2026
d0aec27
Update H100 RTC training configs
Hubo1231 Aug 28, 2026
476babe
Enable cuDNN fused attention training
Hubo1231 Aug 29, 2026
f42992e
Document cuDNN production validation
Hubo1231 Aug 29, 2026
c1b70b2
Optimize H200 training and fix cuDNN attention NaNs
Hubo1231 Aug 29, 2026
6305750
Remove per-step finite update guard
Hubo1231 Aug 29, 2026
51d9af3
Preserve the fast cuDNN mask for invalid queries
Hubo1231 Aug 29, 2026
ad08973
Stabilize cuDNN attention training diagnostics
Hubo1231 Aug 31, 2026
c9e77cc
cudnn issues
Hubo1231 Aug 31, 2026
895811c
docs: consolidate cuDNN attention incident reports
Hubo1231 Aug 31, 2026
3b2795e
feat: add Nova5 LeRobot data config
Hubo1231 Sep 2, 2026
3c5aac6
add loreal train config yaml
Vertax42 Sep 3, 2026
df9755f
Improve cuDNN attention precision diagnostics
Hubo1231 Sep 3, 2026
3ea2b1c
Optimize cuDNN FP16 attention VJP
Hubo1231 Sep 3, 2026
cf07bbe
Speed up H100 training: token length 128, XLA collective flags, remat…
Hubo1231 Sep 4, 2026
cf03854
docs: consolidate training optimization history
Hubo1231 Sep 4, 2026
4606754
configs: refresh optimized training examples
Hubo1231 Sep 4, 2026
72ace2a
docs: tidy training optimization report
Hubo1231 Sep 6, 2026
95785a7
policies: disable cuDNN attention for JAX inference
Hubo1231 Sep 7, 2026
e13ac0f
Clean up training diagnostics and refresh optimized configs
Hubo1231 Sep 10, 2026
0b8330d
Update Flexiv inference recipes for serial grippers
Hubo1231 Sep 10, 2026
bbccfae
fix(configs): restore three configs that callers still reference
Vertax42 Sep 11, 2026
1db0ec9
fix(training): keep a NaN loss visible in the logged metrics
Vertax42 Sep 11, 2026
bc477a6
fix(models): validate the private cuDNN symbols instead of importing …
Vertax42 Sep 11, 2026
9cbea2c
fix(scripts): gate the FP16 cuDNN path, and accept patch releases
Vertax42 Sep 11, 2026
fef66f2
docs(configs): fix the copy-paste in the cube-color-sorting config
Vertax42 Sep 11, 2026
7ac2a6a
docs(data-loader): tie the torch-internal shutdown to the version pin
Vertax42 Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 61 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ GIT_LFS_SKIP_SMUDGE=1 pip install -e .
# 2. Install the main openpi package
cd ../..
GIT_LFS_SKIP_SMUDGE=1 pip install -e .

# 3. Verify that JAX and PyTorch load one coherent pip cu128 stack
# (requires an accessible NVIDIA GPU)
python scripts/check_cuda_stack.py
```

## Model Checkpoints
Expand Down Expand Up @@ -184,6 +188,9 @@ model:
paligemma_variant: gemma_2b
action_expert_variant: gemma_300m
enable_training_time_rtc: true
# Explicit attention is the default. For validated FP16 cuDNN training,
# see the configuration and validation notes below.
use_cudnn_attention: false
max_delay: 10

data:
Expand All @@ -208,10 +215,58 @@ Then use it exactly like any other config:

```bash
python scripts/compute_norm_stats.py --config-name my_task
XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 python scripts/train.py my_task --exp-name=run_0520 --overwrite
python scripts/serve_policy.py policy:checkpoint --policy.config=my_task --policy.dir=checkpoints/my_task/run_0520/<step>
XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 \
python scripts/train.py my_task \
--exp-name=my_exp \
--overwrite
python scripts/serve_policy.py policy:checkpoint --policy.config=my_task --policy.dir=checkpoints/my_task/my_exp/<step>
```

For the optimized 8×H100 FSDP launch, set the measured XLA collective
combining and pipelining flags before Python starts:

```bash
env -u LD_LIBRARY_PATH \
XLA_FLAGS="--xla_gpu_enable_latency_hiding_scheduler=true \
--xla_gpu_all_gather_combine_threshold_bytes=1073741824 \
--xla_gpu_reduce_scatter_combine_threshold_bytes=1073741824 \
--xla_gpu_all_reduce_combine_threshold_bytes=1073741824 \
--xla_gpu_enable_pipelined_all_gather=true \
--xla_gpu_enable_pipelined_reduce_scatter=true \
--xla_gpu_enable_while_loop_double_buffering=true" \
XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 \
python scripts/train.py my_task \
--exp-name=my_exp \
--overwrite
```

Do **not** prepend `$CONDA_PREFIX/lib` to `LD_LIBRARY_PATH`. The supported
environment uses the pip CUDA 12.8 stack installed by `lerobot-xense`:
PyTorch 2.11 pins cuDNN 9.19 and JAX shares that same runtime. Before training,
run `python scripts/check_cuda_stack.py`; it rejects mixed library sources and checks a
real production-shape forward/backward for both the raw BF16 kernel and the FP16 custom
VJP, including the fully-masked query rows.

Full-layer cuDNN attention with the default `bfloat16` compute dtype is unsafe:
it diverged from the explicit-attention baseline after roughly 1,000 steps.
Either keep the explicit path (`use_cudnn_attention: false`) or use the
3,000-step strict-order validated FP16 path:

```yaml
model:
use_cudnn_attention: true
cudnn_attention_dtype: float16
```

At startup, `scripts/train.py` logs `JAX cuDNN runtime version: <version>`;
the unified PyTorch 2.11 cu128 environment reports `91900`. This number alone
does not detect mixed dispatcher/engine libraries, so the stack-check script is
the required gate. Use `--overwrite` only for a new run that may replace an
existing experiment directory; use `--resume` to preserve and continue an
existing run. See
[`docs/training-optimization.md`](docs/training-optimization.md)
for the numerical root cause, validation criteria, and fallback configuration.

⚠️ Before committing a YAML into `configs/_examples/`, scrub any machine-local
absolute paths from `weight_loader.params_path` (e.g. `/home/<you>/...`). Use
upstream URLs (`gs://openpi-assets/...`) or paths that every contributor can
Expand Down Expand Up @@ -246,7 +301,10 @@ python scripts/compute_norm_stats.py --config-name pi05_base_xtac_umi_pick_up_cu
Now we can kick off training with the following command (the `--overwrite` flag is used to overwrite existing checkpoints if you rerun fine-tuning with the same config):

```bash
XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 python scripts/train.py pi05_base_xtac_umi_pick_up_cube_0807_h200 --exp-name=my_experiment --overwrite
XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 \
python scripts/train.py pi05_base_xtac_umi_pick_up_cube_0807_h200 \
--exp-name=my_experiment \
--overwrite
```

The command will log training progress to the console and save checkpoints to the `checkpoints` directory. You can also monitor training progress on the Weights & Biases dashboard. For maximally using the GPU memory, set `XLA_PYTHON_CLIENT_MEM_FRACTION=0.9` before running training -- this enables JAX to use up to 90% of the GPU memory (vs. the default of 75%).
Expand Down
10 changes: 9 additions & 1 deletion configs/_examples/_FULL_REFERENCE.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ data:
# action_sequence_keys: [action]
# repack_transforms is built from use_head_camera and cannot be overridden here.

# ---- LeRobotDobotNova5DataConfig-specific (uncomment when used) ----
# Single right-arm Dobot Nova5 DH. 10D state/action order:
# [tcp.x, tcp.y, tcp.z, tcp.r1-r6, gripper.pos]. The dataset camera columns
# are observation.images.head and observation.images.wrist.
# use_delta_cartesian_actions: true # delta-encode TCP dims 0-8; keep gripper dim 9 absolute
# default_prompt: "..."
# action_sequence_keys: [action]

# ---- LeRobotAlohaDataConfig-specific (uncomment when used) ----
# use_delta_joint_actions: true # delta-encode joints, keep grippers absolute
# default_prompt: "..."
Expand Down Expand Up @@ -239,7 +247,7 @@ strict_batch_order: false # false ⇒ hand batches over as workers finish th
# and lets the loader iterate without epoch boundaries.
# true ⇒ strict sampler order, reproducible batch sequence,
# one slow worker blocks everything behind it.
# See docs/data-pipeline-stalls.md.
# See docs/training-optimization.md.
num_train_steps: 30000 # total gradient steps

log_interval: 100 # how often to push metrics to wandb
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Production launch (8xH100, hb-openpi env). XLA_FLAGS must be set before Python/JAX
# starts and therefore cannot be injected by a TrainConfig YAML. The flags below measured
# -3.5% step time on 2026-09-04 (FSDP collective combining + pipelined collectives); see
# docs/training-optimization.md for the performance results and numerical validation.
# env -u LD_LIBRARY_PATH python scripts/check_cuda_stack.py
# env -u LD_LIBRARY_PATH \
# XLA_FLAGS="--xla_gpu_enable_latency_hiding_scheduler=true \
# --xla_gpu_all_gather_combine_threshold_bytes=1073741824 \
# --xla_gpu_reduce_scatter_combine_threshold_bytes=1073741824 \
# --xla_gpu_all_reduce_combine_threshold_bytes=1073741824 \
# --xla_gpu_enable_pipelined_all_gather=true \
# --xla_gpu_enable_pipelined_reduce_scatter=true \
# --xla_gpu_enable_while_loop_double_buffering=true" \
# XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 \
# python scripts/train.py pi05_base_bi_flexiv_cube_color_sorting_rtc_0829_h100 \
# --exp-name=<experiment-name>
model:
type: Pi0Config
# ⚠️ Carried over from the earbuds config, where 128 was measured against that dataset's
# prompts (longest tokenized prompt 116 tokens). It has NOT been re-scanned against
# cube-color-sorting-0821, whose prompt and state layout differ. Scan the full transform
# chain before trusting it here -- the tokenizer only warns and truncates on overflow --
# or put 200 back. See docs/training-optimization.md.
max_token_len: 128
pi05: true
discrete_state_input: true
enable_training_time_rtc: true
# Encode all three visual views in one SigLIP call.
batch_image_views: true
# Run all 18 Gemma layers through the validated FP16 cuDNN custom VJP.
use_cudnn_attention: true
cudnn_attention_dtype: float16
weight_loader:
type: CheckpointWeightLoader
params_path: gs://openpi-assets/checkpoints/pi05_base/params
ema_decay: null
data:
type: LeRobotBiFlexivDataConfig
repo_id: Xense/cube-color-sorting-0821
base_config:
prompt_from_task: true
tactile: false
default_prompt: Put the green cubes in the right bin and the yellow cubes in the left bin.
batch_size: 256
num_workers: 64
num_train_steps: 60000
# Whole-model grad/parameter norms are computed only on these logging steps.
log_interval: 100
save_interval: 10000
keep_period: 10000
fsdp_devices: 8
strict_batch_order: false
project_name: xense-openpi-hubo

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Production launch (8xH100, hb-openpi env). XLA_FLAGS must be set before Python/JAX
# starts and therefore cannot be injected by a TrainConfig YAML. The flags below measured
# -3.5% step time on 2026-09-04 (FSDP collective combining + pipelined collectives); see
# docs/training-optimization.md for the performance results and numerical validation.
# env -u LD_LIBRARY_PATH python scripts/check_cuda_stack.py
# env -u LD_LIBRARY_PATH \
# XLA_FLAGS="--xla_gpu_enable_latency_hiding_scheduler=true \
# --xla_gpu_all_gather_combine_threshold_bytes=1073741824 \
# --xla_gpu_reduce_scatter_combine_threshold_bytes=1073741824 \
# --xla_gpu_all_reduce_combine_threshold_bytes=1073741824 \
# --xla_gpu_enable_pipelined_all_gather=true \
# --xla_gpu_enable_pipelined_reduce_scatter=true \
# --xla_gpu_enable_while_loop_double_buffering=true" \
# XLA_PYTHON_CLIENT_MEM_FRACTION=0.9 \
# python scripts/train.py pi05_base_bi_flexiv_earbuds_case_insertion_teleop_rtc_0904_h100 \
# --exp-name=<experiment-name>
model:
type: Pi0Config
# Scanned 2026-09-04 over this dataset (4037 states incl. per-dim extremes): the longest
# tokenized "Task: ..., State: ...;\nAction: " prompt
# is 116 tokens, so 128 leaves 12 spare. Down from 200: -6.2% step time, identical loss
# (padding tokens were masked anyway). Re-scan when the dataset or prompt changes.
max_token_len: 128
pi05: true
discrete_state_input: true
enable_training_time_rtc: true
# Encode all three visual views in one SigLIP call.
batch_image_views: true
# Run all 18 Gemma layers through the validated FP16 cuDNN custom VJP.
use_cudnn_attention: true
cudnn_attention_dtype: float16
weight_loader:
type: CheckpointWeightLoader
params_path: gs://openpi-assets/checkpoints/pi05_base/params
ema_decay: null
data:
type: LeRobotBiFlexivDataConfig
repo_id: Xense/earbud_case_insertion_teleop_0515_left_right
base_config:
prompt_from_task: true
tactile: false
default_prompt: Pick up each earbud case from the left stands, insert the matching earbuds, close the lid, and place the case in the box.
batch_size: 256
num_workers: 64
num_train_steps: 80000
# Whole-model grad/parameter norms are computed only on these logging steps.
log_interval: 100
save_interval: 10000
keep_period: 10000
fsdp_devices: 8
strict_batch_order: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
model:
type: Pi0Config
max_token_len: 200
pi05: true
discrete_state_input: true
enable_training_time_rtc: true
batch_image_views: true
use_cudnn_attention: true
weight_loader:
type: CheckpointWeightLoader
params_path: gs://openpi-assets/checkpoints/pi05_base/params
ema_decay: null
data:
type: LeRobotBiFlexivDataConfig
repo_id: Xense/earbud_case_insertion_teleop_0515_left_right
base_config:
prompt_from_task: true
# 这个数据集有 7 路视频流,其中 4 路触觉流被 repack 直接丢弃。
# false(默认)= 不解码它们,单样本 __getitem__ 快约 1.7 倍。
# 用触觉的模型(Pi0Tactile 等)必须设 true。
tactile: false
default_prompt: Pick up each earbud case from the left stands, insert the matching earbuds, close the lid, and place the case in the box.
batch_size: 512
num_workers: 96
num_train_steps: 60000
fsdp_devices: 8
# 是否严格按 sampler 顺序交付 batch。false(默认)= 谁先算完谁先交付,
# 消除每 num_workers 步一次的队头阻塞停顿;同时启用 InfiniteSampler,
# 去掉 epoch 边界重建迭代器的停顿。详见 docs/training-optimization.md。
# 代价:batch 的交付顺序不再逐次可复现(每个 index 每轮仍恰好出现一次)。
strict_batch_order: false
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ weight_loader:
ema_decay: null
data:
type: LeRobotBiFlexivDataConfig
repo_id: Xense/assemble_box_with_phone_stand0410_merged_fixed
repo_id: Xense/optical-module-insertion-0731
base_config:
prompt_from_task: true
default_prompt: Assemble the packaging by folding the flat box into shape, placing
the metal phone stand inside, and closing the box properly.
default_prompt: Pick up the bag, open it, inspect its contents, close it, and place
it on the opposite side.
batch_size: 256
num_workers: 64
num_train_steps: 80000
num_train_steps: 60000
fsdp_devices: 8
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fsdp_devices: 8
# Whether batches are delivered in strict sampler order. false (the default) hands each
# batch over as soon as a worker finishes it, which removes the head-of-line stall every
# num_workers steps, and enables the InfiniteSampler so the epoch boundary never tears the
# prefetch pipeline down. See docs/data-pipeline-stalls.md.
# prefetch pipeline down. See docs/training-optimization.md.
# Cost: batch delivery order is no longer reproducible run to run (every index is still
# visited exactly once per pass).
strict_batch_order: false
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ batch_size: 256
num_workers: 64
num_train_steps: 80000
fsdp_devices: 8
save_interval: 10000
keep_period: 10000
# Whether batches are delivered in strict sampler order. false (the default) hands each
# batch over as soon as a worker finishes it, which removes the head-of-line stall every
# num_workers steps, and enables the InfiniteSampler so the epoch boundary never tears the
# prefetch pipeline down. See docs/data-pipeline-stalls.md.
# prefetch pipeline down. See docs/training-optimization.md.
# Cost: batch delivery order is no longer reproducible run to run (every index is still
# visited exactly once per pass).
strict_batch_order: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# JAX-only pi0.5 training config for the single-arm Dobot Nova5 dataset.
model:
type: Pi0Config
max_token_len: 200
pi05: true
discrete_state_input: true
enable_training_time_rtc: true
use_cudnn_attention: false
weight_loader:
type: CheckpointWeightLoader
params_path: gs://openpi-assets/checkpoints/pi05_base/params
ema_decay: null
data:
type: LeRobotDobotNova5DataConfig
repo_id: Xense/loreal_returns_sorting_0831
use_delta_cartesian_actions: true
base_config:
prompt_from_task: true
tactile: false
default_prompt: Pick up returned cosmetic from conveyor, place neatly on left platform.
batch_size: 256
num_workers: 64
num_train_steps: 60000
save_interval: 10000
keep_period: 10000
fsdp_devices: 8
strict_batch_order: false
Loading
Loading