# π₀.₅ with language supervision (Pi052) Pi052 extends [Pi05](./pi05) with a trainable PaliGemma language head and a runtime that alternates language generation with action generation. A single checkpoint can predict a low-level subtask, optionally update memory or answer visual questions, and condition its flow-matching action expert on that text. Use Pi05 when you only need task-conditioned actions. Use Pi052 when the policy must generate or consume intermediate language during a rollout. ## How Pi052 differs from Pi05 | Capability | Pi05 | Pi052 | | ------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------- | | Action model | PaliGemma vision-language prefix + Gemma action expert | Same base architecture | | Language head | Not trained for runtime generation | Re-enabled and trained with text cross-entropy | | Action conditioning | Episode task | Active low-level subtask plus normalized robot state | | Training targets | Flow-matching actions | Flow actions, recipe-selected text, and optional FAST action tokens | | Dataset requirement | Standard images, state, actions, and task | The same fields plus language annotations for every language capability you train | | Rollout | Direct task-to-action policy | Hierarchical task → subtask → action loop, with optional memory and VQA | Pi052 can initialize from a Pi05 checkpoint. The policy architecture remains compatible, while Pi052 builds its own processors so recipe labels and FAST labels are not silently replaced by the Pi05 processor stack. ## Install Install LeRobot with the PI dependencies: ```bash git clone https://github.com/huggingface/lerobot.git cd lerobot python -m venv .venv source .venv/bin/activate pip install -e ".[pi]" ``` The `pi` extra includes the PaliGemma/FAST dependencies. Install `liger-kernel` for the supported fused training kernels; optional FlashRT backends also require the Hugging Face `kernels` package and a supported CUDA GPU. ## Prepare language-annotated data Pi052 does not infer supervised subtasks from a normal LeRobot dataset during training. The dataset must contain the language targets used by the selected recipe in the optional `language_persistent` and `language_events` columns. At minimum, annotate a continuous `subtask` timeline so each training frame has an active low-level instruction. Add `memory`, VQA, interjections, and speech annotations only if the recipe trains those capabilities. The provided recipes are: | Recipe | Required annotations | Trains | | ------------------------------------- | ----------------------------------------------------------------------- | -------------------------------------------------- | | `recipes/subtask.yaml` | `subtask` | Subtask prediction and subtask-conditioned actions | | `recipes/subtask_mem.yaml` | `subtask`, `memory` | Subtasks, actions, and memory updates | | `recipes/subtask_mem_vqa_speech.yaml` | `subtask`, `memory`, `vqa`; interjection/speech rows for those branches | Subtasks, actions, memory, VQA, and spoken replies | Use `lerobot-annotate` to generate these columns. The repository includes a Hugging Face Jobs launcher that you can edit for your source and destination datasets. For a local annotation run, first install `pip install -e ".[annotations]"`: ```bash HF_TOKEN=hf_... uv run python examples/annotations/run_hf_job.py ``` Before a long training run, inspect several episodes and verify that subtasks are temporally correct and cover the full demonstration. See [Annotation Pipeline](./annotation_pipeline) for generation and validation, and [Language Columns and Recipes](./language_and_recipes) for the schema and recipe resolver. If a dataset has no language columns, recipe rendering becomes a no-op and Pi052 falls back to the plain Pi05 prompt path. This is useful for compatibility but does not train the language planner. ## Train Pi052 This example initializes Pi052 from the public Pi05 base checkpoint and trains the default subtask-and-memory recipe: ```bash lerobot-train \ --dataset.repo_id=${HF_USER}/my_language_annotated_dataset \ --policy.type=pi052 \ --policy.pretrained_path=lerobot/pi05_base \ --policy.recipe_path=recipes/subtask_mem.yaml \ --policy.dtype=bfloat16 \ --policy.device=cuda \ --policy.freeze_vision_encoder=false \ --policy.gradient_checkpointing=true \ --batch_size=8 \ --steps=30000 \ --output_dir=outputs/pi052 \ --job_name=pi052 \ --wandb.enable=true ``` For subtask-only data, change the recipe to `recipes/subtask.yaml` and disable memory during rollout. Start with a small run and confirm that W&B examples show the expected prompt, text target, and action endpoints before scaling up. ### Main training controls | Option | Default | Purpose | | -------------------------------- | -------------------------: | -------------------------------------------------------------- | | `policy.recipe_path` | `recipes/subtask_mem.yaml` | Selects the language/action objective mixture | | `policy.text_loss_weight` | `1.0` | Language-head cross-entropy weight; `0` disables text training | | `policy.flow_loss_weight` | `10.0` | Continuous action flow-loss weight | | `policy.enable_fast_action_loss` | `true` | Adds discrete FAST action-token supervision | | `policy.fast_action_loss_weight` | `1.0` | FAST cross-entropy weight | | `policy.knowledge_insulation` | `true` | Blocks action-loss gradients through the VLM K/V path | | `policy.flow_num_repeats` | `5` | Reuses one VLM prefix for independent denoising targets | | `policy.lm_head_lr_scale` | `1.0` | Scales language-head learning rate; `1.0` uses the base rate | The loss weights are starting points, not dataset-independent constants. Track flow loss and text/FAST losses separately, and inspect generated subtasks rather than selecting a checkpoint from total loss alone. ### Dataset-specific FAST tokenizer The universal FAST tokenizer works out of the box. For a large or embodiment-specific dataset, Pi052 can fit and cache a tokenizer on normalized actions before training: ```bash lerobot-train \ ... \ --policy.auto_fit_fast_tokenizer=true \ --policy.fast_tokenizer_fit_samples=4096 ``` The fit runs once per dataset/tokenizer configuration. Keep `auto_fit_fast_tokenizer=false` when you do not want the extra preprocessing pass. ## Training performance Pi052 uses optimized training paths by default: - batches repeated flow targets and suffix projections instead of replaying small operations in Python; - caches constant action masks and computes RoPE positions once per forward; - selects the text/FAST cross-entropy implementation from target shape and sparsity; - skips the mathematically dead VLM/vision backward on knowledge-insulated, flow-only batches; - uses native non-reentrant SigLIP layer checkpointing when gradient checkpointing is enabled; and - retains the Liger RoPE/GeGLU kernels while avoiding the slower LayerNorm patch at SigLIP shapes. Optional training backends are disabled by default: | Option | When to try it | | -------------------------------------- | ------------------------------------------------------------------------------------------------- | | `policy.use_flashrt_adarms=true` | Fused adaptive RMSNorm and gated residuals on supported CUDA GPUs | | `policy.use_compiled_text_ce=true` | Compiled materialized-logit CE buckets | | `policy.use_compiled_vision=true` | Compiled vision only when the vision pass has no gradients | | `policy.use_flex_attention=true` | Profiled CUDA setups with knowledge insulation and `flow_num_repeats > 1`; otherwise SDPA is used | | `policy.use_manual_attention=true` | Explicitly profiled shapes where materialized attention is faster | | `policy.manual_attention_scope=action` | Restricts manual attention to action queries | Do not enable every backend blindly. Flex and manual attention are mutually exclusive, and attention/AdaRMS alternatives require knowledge insulation. The benchmark-best configuration used compiled text CE and FlashRT AdaRMS, with Flex/manual attention and compiled vision disabled. ### Reported training benchmarks These benchmarks measure complete optimizer steps with three real camera inputs, BF16 transformer/action execution, FP32 vision, fused AdamW, and no video decoding or network I/O. Results vary with GPU, batch shape, annotation mixture, and checkpointing: | Workload | RTX PRO 6000 Blackwell | A100 80 GB | | -------------------------- | -------------------------: | -------------------------: | | Full flow + text, batch 1 | 4.75× vs checkpointing off | 3.33× vs checkpointing off | | Full flow + text, batch 8 | 2.16× vs checkpointing off | 1.66× vs checkpointing off | | Full flow + text, batch 64 | 1.24× vs checkpointing on | 1.15× vs checkpointing on | | Flow-only, batch 1 | 3.70× vs checkpointing off | 3.58× vs checkpointing off | | Flow-only, batch 64 | 3.76× vs checkpointing on | 3.61× vs checkpointing on | On those 80 GB GPUs, full training was fastest without gradient checkpointing through batch 8, then required checkpointing at batch 16 and above. Treat that as a tuning rule to test on your hardware, not a universal threshold. Flow-only means both text and FAST supervision are disabled; it is useful for action-only ablation or post-training but does not learn the language runtime. ## Inference performance Pi052 has two inference loops, and both avoid repeatedly encoding the expensive multimodal prefix: 1. **Action denoising** encodes the image/language prefix once, reuses its KV cache across flow steps, precomputes the timestep schedule on-device, and crops temporary suffix K/V instead of cloning the prefix cache. 2. **Language decoding** uses autoregressive KV caching, so each new token only processes the sampled token against cached image/language keys instead of rerunning the full prefix. The runtime also runs language and actions at different rates. Increase `--subtask_chunks_per_gen` when a subtask remains valid across several action chunks, lower `--high_level_hz`, or use `--direct_subtask` to bypass language generation entirely. These settings reduce compute but also slow replanning. `--fp8` enables the optional FlashRT inference MLP swap on supported CUDA GPUs. It calibrates on the first observation and falls back to BF16 when unavailable; because FP8 can change outputs slightly, validate task success before using it for production rollouts. ## Run a checkpoint RoboCasa: ```bash MUJOCO_GL=egl lerobot-rollout \ --policy.path=lerobot/pi052_robocasa \ --sim --sim.task=CloseFridge --sim.split=pretrain \ --task="close the fridge" \ --disable_memory \ --sim.render_size=384 \ --sim.views=robot0_agentview_left,robot0_eye_in_hand,robot0_agentview_right \ --mode=action --ctrl_hz=20 ``` Open `http://localhost:8010` for the live view. Without `--sim.direct_subtask`, Pi052 generates the low-level subtask; with it, each prompt becomes the action policy's subtask directly. The same runtime supports real robots. See [Interactive language control](./inference#interactive-language-control) for the real-arm command, safety behavior, and runtime controls. ## Troubleshooting - **No text loss or generated subtasks:** confirm the selected recipe can bind the annotations on sampled frames and that `policy.text_loss_weight > 0`. - **Subtasks look plausible but actions fail:** verify subtask boundaries, normalized state/action statistics, and that low-level recipe samples are present. - **Text collapses to repeated or location tokens:** inspect text-target coverage, language-head learning rate, and the balance between flow, FAST, and text losses. - **Out of memory:** reduce batch size first, then enable gradient checkpointing. Do not enable compiled or alternative attention backends without profiling their memory on your camera count. - **Slow rollout:** separate action latency from language latency, then tune `--subtask_chunks_per_gen`, `--high_level_hz`, and the number of flow inference steps.