# π₀.₅ (Pi05) Policy

π₀.₅ là một **mô hình Vision-Language-Action với khả năng tổng quát hóa trong thế giới mở**, từ Physical Intelligence. Bản triển khai LeRobot được điều chỉnh từ kho mã nguồn mở [OpenPI](https://github.com/Physical-Intelligence/openpi) của họ.

## Tổng quan về Mô hình

π₀.₅ đại diện cho một bước tiến hóa đáng kể từ π₀, được phát triển bởi [Physical Intelligence](https://www.physicalintelligence.company/blog/pi05) để giải quyết một thách thức lớn trong robotics: **khả năng tổng quát hóa trong môi trường mở**. Trong khi robot có thể thực hiện các tác vụ ấn tượng trong các môi trường được kiểm soát, π₀.₅ được thiết kế để tổng quát hóa sang các môi trường và tình huống hoàn toàn mới mà chưa từng được nhìn thấy trong quá trình huấn luyện.

### Thử thách Tổng quát hóa

Như Physical Intelligence đã giải thích, thách thức cơ bản không nằm ở việc thực hiện các tác vụ đòi hỏi sự nhanh nhẹn hay khéo léo, mà là khả năng khái quát hóa, tức là khả năng thực hiện đúng các tác vụ trong những bối cảnh mới với những đối tượng mới. Hãy xem xét một robot dọn dẹp các ngôi nhà khác nhau: mỗi ngôi nhà có những đối tượng khác nhau ở những vị trí khác nhau. Khái quát hóa phải diễn ra ở nhiều cấp độ:

- **Mức vật lý**: Hiểu cách cầm thìa (bằng cán) hoặc đĩa (bằng mép), ngay cả với các vật chưa từng thấy trong môi trường lộn xộn
- **Mức ngữ nghĩa**: Hiểu ngữ nghĩa của tác vụ, ví dụ như quần áo và giày dép nên để ở đâu (thùng giặt, không phải trên giường), và dụng cụ nào phù hợp để làm sạch vết bẩn
- **Mức độ môi trường**: Thích ứng với các môi trường thực tế "bộn bề" như nhà ở, cửa hàng tạp hóa, văn phòng và bệnh viện

### Huấn luyện đồng thời trên dữ liệu dị thể

Đột phá đổi mới trong π₀.₅ là **đồng huấn luyện trên các nguồn dữ liệu dị thể**. Mô hình học từ:

1. **Dữ liệu Web đa phương thức**: Mô tả hình ảnh, trả lời câu hỏi trực quan, phát hiện đối tượng
2. **Chỉ dẫn bằng lời**: Con người hướng dẫn robot thực hiện các tác vụ phức tạp từng bước
3. **Lệnh con**: Nhãn hành vi ngữ nghĩa cấp cao (ví dụ: "nhặt gối lên" đối với một chiếc giường chưa được dọn)
4. **Dữ liệu robot đa nền tảng**: Dữ liệu từ các nền tảng robot khác nhau với các khả năng khác nhau
5. **Dữ liệu đa môi trường**: Các robot tĩnh được triển khai trên nhiều ngôi nhà khác nhau
6. **Dữ liệu Thao tác Di động**: ~400 giờ diễn示 robot di động

Hỗn hợp huấn luyện đa dạng này tạo ra một “chương trình học” cho phép khái quát hóa đồng thời trên các cấp độ vật lý, thị giác và ngữ nghĩa.

## Yêu cầu cài đặt

1. Cài đặt LeRobot bằng cách làm theo [Hướng dẫn cài đặt](./installation) của chúng tôi.
2. Cài đặt các phụ thuộc của Pi0.5 bằng cách chạy:

   ```bash
   pip install -e ".[pi]"
   ```

   Nếu bạn đã cài đặt LeRobot từ PyPI:

   ```bash
   pip install 'lerobot[pi]'
   ```

## Cách sử dụng

Để sử dụng π₀.₅ trong cấu hình LeRobot của bạn, hãy chỉ định loại policy là:

```python
policy.type=pi05
```

## Huấn luyện

### Bắt đầu nhanh với LIBERO

Finetune mô hình cơ sở LIBERO trên [lerobot/libero](https://huggingface.co/datasets/lerobot/libero), một bản sao mã hóa video ~1.9 GB của các bản demo đằng sau [kết quả bên dưới](#libero-benchmark-results).

Nó chứa các khóa mà π₀.₅ đọc, đây cũng là những khóa mà môi trường LIBERO tạo ra khi đánh giá:

| Tính năng                     | Hình dạng trong bộ dữ liệu | Cách π₀.₅ sử dụng nó                                    |
| --------------------------- | -------------------- | ------------------------------------------------------- |
| `observation.images.image`  | 256×256×3, agentview | được điều chỉnh kích thước thành 224×224                                      |
| `observation.images.image2` | 256×256×3, cổ tay     | được điều chỉnh kích thước thành 224×224                                      |
| `observation.state`         | 8                    | được chia thành 256 khoảng và được viết vào prompt   |
| `action`                    | 7                    | được đệm lên 32 bên trong; loss sử dụng 7 chiều đầu tiên |

**Không cần `--rename_map` ở đây** — các khóa đã khớp; xem [Rename Map and Empty Cameras](./rename_map) nếu của bạn khác.

  π₀.₅ sử dụng tokenizer [google/paligemma-3b-pt-224](https://huggingface.co/google/paligemma-3b-pt-224) có cổng — hãy chấp nhận giấy phép của nó trên Hub và đăng nhập bằng `hf auth login` trước khi huấn luyện.

Được thiết kế cho một GPU 80 GB:

```bash
lerobot-train \
    --dataset.repo_id=lerobot/libero \
    --policy.type=pi05 \
    --policy.pretrained_path=lerobot/pi05_libero_base \
    --policy.normalization_mapping='{"ACTION": "MEAN_STD", "STATE": "MEAN_STD", "VISUAL": "IDENTITY"}' \
    --policy.n_action_steps=10 \
    --policy.empty_cameras=1 \
    --policy.freeze_vision_encoder=false \
    --policy.train_expert_only=false \
    --policy.gradient_checkpointing=true \
    --policy.dtype=bfloat16 \
    --policy.device=cuda \
    --policy.push_to_hub=false \
    --output_dir=./outputs/pi05_libero \
    --job_name=pi05_libero \
    --batch_size=64 \
    --num_workers=8 \
    --steps=30000 \
    --save_freq=5000 \
    --seed=1000
```

**Chuẩn hóa theo trung bình/độ lệch chuẩn, không phải [mặc định theo phân vị](#quantile-statistics) của π₀.₅** — khớp với [pi05_libero_finetuned_v044](https://huggingface.co/lerobot/pi05_libero_finetuned_v044), checkpoint mà các kết quả bên dưới được đo trên đó.

**`--policy.n_action_steps=10` và `--policy.empty_cameras=1` được khai báo tường minh** vì `--policy.pretrained_path` chỉ nạp trọng số — `lerobot/pi05_libero_base` lưu cả hai, và nếu không chúng sẽ quay về mặc định là `50` và `0` (xem [Nạp checkpoint](#loading-a-checkpoint)).

Sau đó, đánh giá một checkpoint bằng `lerobot-eval` và so sánh với tỷ lệ thành công tham chiếu — xem [LIBERO](./libero).

### Thống kê phân vị

π₀.₅ chuẩn hóa `STATE` và `ACTION` bằng các phân vị, do đó `meta/stats.json` của bộ dữ liệu của bạn cần có `q01` và `q99`. Các bộ dữ liệu cũ chỉ chứa `min`/`max`/`mean`/`std` và sẽ gặp lỗi ở lô dữ liệu đầu tiên:

```
ValueError: QUANTILES normalization mode requires q01 and q99 stats
```

Tính lại chúng:

```bash
lerobot-edit-dataset \
    --repo_id your_dataset \
    --new_repo_id your_dataset \
    --operation.type recompute_stats \
    --operation.overwrite true
```

**The result lands in `$HF_LEROBOT_HOME/your_dataset`**, not the cache `--dataset.repo_id` reads — so train with `--dataset.root=$HF_LEROBOT_HOME/your_dataset`, or add `--push_to_hub true` above.

Hoặc giữ nguyên dataset và truyền `--policy.normalization_mapping='{"ACTION": "MEAN_STD", "STATE": "MEAN_STD", "VISUAL": "IDENTITY"}'`.

Ghi lại, tiếp tục và gộp các phân vị tổng hợp từ các bản tóm tắt theo từng episode, để `meta/stats.json` cuối cùng chứa một bao bảo thủ (`min` cho `q <= 50`, `max` cho `q > 50`) thay vì các phân vị của toàn bộ tập dữ liệu. Để ước lượng các phân vị của toàn bộ tập dữ liệu, quét mọi episode bằng một histogram chạy:

```bash
python src/lerobot/scripts/augment_dataset_quantile_stats.py \
    --repo-id=your_dataset \
    --overwrite \
    --skip-images
```

`--skip-images` giữ nguyên thống kê hình ảnh hiện có và tránh tải hoặc giải mã dữ liệu video khi chỉ cần tính lại `STATE`/`ACTION`, và `--root` đọc bộ dữ liệu cục bộ thay vì từ Hub. Các giá trị này là ước lượng histogram, chịu sai số do rời rạc hóa và gộp lại bin, nên chúng có thể khác so với các giá trị bảo thủ — điều này làm thay đổi mục tiêu đã chuẩn hóa của π₀.₅ và do đó thay đổi thang loss của nó. Thống kê đã được lưu bên trong checkpoint hiện có không bị ảnh hưởng.

### Ví dụ lệnh huấn luyện

Cùng một quy trình finetune nhưng giữ VLM ở trạng thái đóng băng: tốn ít bộ nhớ hơn, đổi lại tỷ lệ thành công có thể giảm. Thay `--dataset.repo_id` bằng dataset của bạn.

```bash
lerobot-train \
    --dataset.repo_id=lerobot/libero \
    --policy.type=pi05 \
    --policy.pretrained_path=lerobot/pi05_libero_base \
    --policy.normalization_mapping='{"ACTION": "MEAN_STD", "STATE": "MEAN_STD", "VISUAL": "IDENTITY"}' \
    --policy.n_action_steps=10 \
    --policy.empty_cameras=1 \
    --policy.freeze_vision_encoder=true \
    --policy.train_expert_only=true \
    --policy.gradient_checkpointing=true \
    --policy.dtype=bfloat16 \
    --policy.device=cuda \
    --policy.push_to_hub=false \
    --output_dir=./outputs/pi05_libero_expert \
    --job_name=pi05_libero_expert \
    --batch_size=64 \
    --num_workers=8 \
    --steps=30000 \
    --save_freq=5000 \
    --seed=1000
```

### Các tham số huấn luyện chính

- **`--policy.compile_model=true`**: Bật biên dịch mô hình để huấn luyện nhanh hơn
- **`--policy.gradient_checkpointing=true`**: Giảm đáng kể lượng bộ nhớ sử dụng trong quá trình huấn luyện
- **`--policy.dtype=bfloat16`**: Sử dụng huấn luyện độ chính xác hỗn hợp để tăng hiệu quả
- **`--batch_size=64`**: Kích thước batch cho huấn luyện, điều chỉnh giá trị này dựa trên bộ nhớ GPU của bạn
- **`--policy.pretrained_path=lerobot/pi05_base`**: Mô hình π₀.₅ cơ bản mà bạn muốn tinh chỉnh, các tùy chọn là:
  - [lerobot/pi05_base](https://huggingface.co/lerobot/pi05_base)
  - [lerobot/pi05_libero_base](https://huggingface.co/lerobot/pi05_libero_base) (được huấn luyện cụ thể trên bộ dữ liệu Libero)
- **`--policy.optimizer_fused=true`**: Sử dụng AdamW đã hợp nhất (fused) để thực hiện các bước tối ưu hóa nhanh hơn; cờ này sẽ bị bỏ qua khi tiếp tục một lần chạy

### RTC tùy chọn trong quá trình huấn luyện

Pi05 có thể tùy chọn học điều kiện tiền tố hành động cho [Real-Time Chunking](./rtc) hiệu quả, theo [Training-Time Action Conditioning for Efficient Real-Time Chunking](https://arxiv.org/abs/2512.05964). Đặt `policy.rtc_training_max_delay` bằng độ trễ suy luận lớn nhất dự kiến theo các bước điều khiển:

```bash
lerobot-train \
    --dataset.repo_id=${HF_USER}/my_dataset \
    --policy.type=pi05 \
    --policy.pretrained_path=lerobot/pi05_base \
    --policy.rtc_training_max_delay=10 \
    --policy.dtype=bfloat16 \
    --policy.device=cuda \
    --batch_size=8 \
    --steps=30000 \
    --output_dir=outputs/pi05_rtc \
    --job_name=pi05_rtc
```

Mặc định là `0`, điều này vô hiệu hóa RTC trong quá trình huấn luyện và giữ nguyên mục tiêu Pi05 tiêu chuẩn. Độ trễ được cấu hình phải nhỏ hơn `chunk_size`. Trong quá trình huấn luyện, Pi05 lấy mẫu độ dài tiền tố sạch độc lập cho mỗi ví dụ và chỉ tính toán tổn thất dòng chảy trên phần hậu tố còn lại.

Sử dụng checkpoint kết quả với RTC đã được huấn luyện một cách rõ ràng:

```bash
lerobot-rollout \
    --strategy.type=base \
    --policy.path=outputs/pi05_rtc/checkpoints/last/pretrained_model \
    --inference.type=rtc \
    --inference.rtc.mode=trained \
    --inference.rtc.execution_horizon=10 \
    --robot.type=so100_follower \
    --robot.port=/dev/ttyACM0 \
    --task="pick up the cube" \
    --fps=50 \
    --device=cuda
```

Đặt `inference.rtc.execution_horizon` nằm giữa `rtc_training_max_delay` và `chunk_size - rtc_training_max_delay` của checkpoint, và đặt `inference.queue_threshold` ít nhất bằng `rtc_training_max_delay`. Một lần tăng độ trễ vượt quá phạm vi đã huấn luyện sẽ loại bỏ chunk đó và thử lại; quá trình rollout chỉ dừng lại với một lỗi rõ ràng nếu độ trễ vẫn nằm ngoài phạm vi. Chế độ mặc định `--inference.rtc.mode=guided` vẫn khả dụng cho các checkpoint thông thường.

### Tải checkpoint

Hai dạng này không thể thay thế cho nhau:

|                                        | `--policy.path`                                | `--policy.pretrained_path`                |
| -------------------------------------- | ---------------------------------------------- | ----------------------------------------- |
| Tải                                  | weights **và** `config.json` của checkpoint | chỉ trọng số                              |
| Tên tính năng                          | từ checkpoint                            | từ bộ dữ liệu của bạn, sau `--rename_map`   |
| Cài đặt được lưu, ví dụ `n_action_steps` | kế thừa                                      | đặt lại về mặc định                     |
| `--policy.type`                        | phải được bỏ qua                                | bắt buộc                                  |
| `--rename_map`                         | cần thiết khi các phím camera của bạn khác nhau            | được hỗ trợ để chuẩn hóa các khóa của bộ dữ liệu |

Sử dụng `--rename_map` với bất kỳ dạng nạp nào khi tên đặc trưng của bộ dữ liệu thô khác với tên đặc trưng của chính sách. Ví dụ, lệnh tinh chỉnh RoboMME ánh xạ các cột thô `image`, `wrist_image`, `state` và `actions` trong khi khởi tạo trọng số bằng `--policy.pretrained_path`.

### Giải thích các tham số huấn luyện

| Tham số               | Mặc định | Mô tả                                 |
| ----------------------- | ------- | ------------------------------------------- |
| `freeze_vision_encoder` | `false` | Không đóng băng bộ mã hóa thị giác            |
| `train_expert_only`     | `false` | Không đóng băng VLM, huấn luyện tất cả các tham số |

**💡 Mẹo**: Đặt `train_expert_only=true` sẽ đóng băng VLM và chỉ huấn luyện action expert cùng các lớp projection, cho phép finetuning với mức sử dụng bộ nhớ thấp hơn.

## Bộ nhớ quan sát tầm ngắn (MEM)

Pi05 có thể tùy chọn sử dụng ngữ cảnh thị giác và cảm giác vị thế ngắn hạn dựa trên [MEM](https://arxiv.org/abs/2603.03596). Cả hai đường dẫn đều bị vô hiệu hóa theo mặc định, do đó các checkpoint và lệnh huấn luyện hiện có vẫn giữ nguyên hành vi khung hình đơn của Pi05.

Phần này chỉ triển khai bộ nhớ tầm ngắn của MEM — bộ mã hóa video của mục III-C và phép chiếu cảm giác chủ quan của mục III-D. Bộ nhớ _ngôn ngữ_ tầm dài của MEM (mục III-B), trong đó một chính sách cấp cao dự đoán nhiệm vụ con tiếp theo và một bản tóm tắt ngôn ngữ tự nhiên đã nén về những gì đã xảy ra cho đến nay, chưa được triển khai. Trong các thí nghiệm tách biệt (ablation) của bài báo, chỉ riêng bộ nhớ video chỉ khôi phục được một phần tiến độ nhiệm vụ của MEM đầy đủ trên các tác vụ tầm dài.

Việc đưa vào bộ nhớ khi tinh chỉnh từ một checkpoint được tiền huấn luyện mà không có bộ nhớ cũng tương ứng với phép loại trừ yếu hơn `MEM-Posttrain-Only` trong bài báo. Các kết quả nổi bật của MEM đến từ việc tiền huấn luyện bộ mã hóa video trên một hỗn hợp đa dạng các video robot và phi robot, điều mà không có checkpoint Pi05 công khai nào hiện tại cung cấp.

Bật tính năng này khi tinh chỉnh với:

```bash
lerobot-train \
    --dataset.repo_id=your_dataset \
    --policy.type=pi05 \
    --policy.pretrained_path=lerobot/pi05_base \
    --policy.use_visual_memory=true \
    --policy.memory_frames=6 \
    --policy.memory_stride=30 \
    --policy.memory_temporal_attention_every=4 \
    ...
```

`memory_frames` bao gồm quan sát hiện tại. `memory_stride` được đo bằng **khung dữ liệu**, không phải giây, vì vậy hãy điều chỉnh nó theo `fps` của bộ dữ liệu của bạn: MEM được tiền huấn luyện trên sáu quan sát cách nhau một giây, tương ứng với `memory_stride=30` cho bộ dữ liệu 30 fps (mặc định) nhưng là `memory_stride=10` cho bộ dữ liệu 10 fps như `lerobot/robomme`.

Mỗi bốn lớp SigLIP, lớp đó thay thế cơ chế attention của nó bằng attention không gian-thời gian tổng hợp của MEM: attention thời gian nhân quả giữa các patch token tương ứng, được tổng hợp với attention không gian chuẩn và tái sử dụng các phép chiếu đã được huấn luyện trước, do đó không có tham số học được nào được thêm vào tháp thị giác. Các token từ khung hình trước đó sẽ bị loại bỏ ngay khi lớp cuối cùng như vậy đã chạy xong, giữ cho độ dài tiền tố ngôn ngữ/hành động phía sau không thay đổi.

Lịch sử không khả dụng ở đầu một episode sẽ được đệm và che (mask). Khi suy luận, Pi05 duy trì lịch sử ảnh có bước nhảy (strided) bên trong và xóa nó mỗi khi chính sách được đặt lại.

Tri giác bản thể lịch sử là một tùy chọn độc lập:

```bash
--policy.use_proprioceptive_memory=true
```

Khi được bật, một token trạng thái liên tục đã được chiếu sẽ được thêm vào cho mỗi khung hình được giữ lại, và trạng thái rời rạc sẽ bị loại bỏ khỏi prompt văn bản để đảm bảo trạng thái được biểu diễn chính xác một lần (phần III-D của MEM). Điều này làm thay đổi định dạng prompt, vì vậy hãy bật tính năng này ngay từ đầu quá trình huấn luyện thay vì bật ở giữa chừng. Bộ nhớ thị giác và bộ nhớ cảm giác bản thể sử dụng cùng các cài đặt `memory_frames` và `memory_stride`, nhưng mỗi đường dẫn có thể được bật độc lập. Hãy huấn luyện hoặc tinh chỉnh với các tùy chọn bộ nhớ đã chọn; việc chỉ bật chúng ở giai đoạn suy luận sẽ không mang lại hành vi bộ nhớ đã học từ checkpoint một khung hình.

Dưới PEFT, `proprio_history_proj` được huấn luyện và lưu trữ đầy đủ thông qua `modules_to_save`, vì nó không có trọng số được huấn luyện trước để thích ứng.

Khi suy luận, MEM duy trì một hàng đợi lịch sử được nhóm theo batch và giả định rằng mọi hàng trong batch đều chia sẻ các ranh giới episode. `lerobot-eval` đáp ứng điều này bằng cách gọi `policy.reset()` trước mỗi rollout được nhóm theo batch và trước khi đặt lại môi trường vector. Việc tự động đặt lại các hàng độc lập trong một batch vector bất đồng bộ không được hỗ trợ; hãy bắt đầu một rollout mới để hàng đợi policy và hàng đợi action hoàn chỉnh được đặt lại cùng nhau.

## Hành động tương đối

Mặc định, π₀.₅ dự đoán các hành động tuyệt đối. Bạn có thể bật **hành động tương đối** để mô hình dự đoán các độ lệch so với trạng thái hiện tại của robot. Điều này có thể cải thiện độ ổn định của quá trình huấn luyện cho một số cấu hình nhất định.

Để sử dụng hành động tương đối, trước tiên hãy tính lại thống kê tập dữ liệu của bạn trong không gian tương đối thông qua CLI:

```bash
lerobot-edit-dataset \
    --repo_id your_dataset \
    --new_repo_id your_dataset \
    --operation.type recompute_stats \
    --operation.overwrite true \
    --operation.relative_action true \
    --operation.chunk_size 50 \
    --operation.relative_exclude_joints "['gripper']" \
    --push_to_hub true
```

Hoặc tương đương trong Python:

```python
from lerobot.datasets import LeRobotDataset, recompute_stats

dataset = LeRobotDataset("your_dataset")
recompute_stats(dataset, relative_action=True, chunk_size=50, relative_exclude_joints=["gripper"])
dataset.push_to_hub()
```

`chunk_size` phải khớp với `chunk_size` của policy của bạn (mặc định là 50 cho π₀.₅). `relative_exclude_joints` liệt kê tên các khớp cần giữ trong không gian tuyệt đối (ví dụ: lệnh gắp). Sử dụng `--push_to_hub true` để tải thống kê đã cập nhật lên Hub.

Sau đó, huấn luyện với hành động tương đối được bật:

```bash
lerobot-train \
    --dataset.repo_id=your_dataset \
    --policy.type=pi05 \
    --policy.use_relative_actions=true \
    --policy.relative_exclude_joints='["gripper"]' \
    ...
```

## Kết quả Hiệu năng

### Kết quả Benchmark Libero

π₀.₅ đã thể hiện hiệu suất mạnh mẽ trên bộ benchmark Libero. Để so sánh và kiểm tra việc triển khai LeRobot của nó, chúng tôi đã tinh chỉnh thêm 6k bước trên tập dữ liệu Libero cho mô hình libero base và so sánh kết quả với kết quả tham chiếu từ OpenPI.

| Đánh giá hiệu năng          | LeRobot Implementation | Tham khảo OpenPI |
| ------------------ | ---------------------- | ---------------- |
| **Libero Spatial** | 97.0%                  | 98.8%            |
| **Libero Object**  | 99.0%                  | 98.2%            |
| **Mục tiêu Libero**    | 98.0%                  | 98.0%            |
| **Libero 10**      | 96.0%                  | 92.4%            |
| **Trung bình**        | 97.5%                  | 96.85%           |

Những kết quả này cho thấy khả năng tổng quát hóa mạnh mẽ của π₀.₅ trên nhiều tác vụ thao tác robot đa dạng. Để tái tạo các kết quả này, bạn có thể làm theo các hướng dẫn trong phần [Libero](https://huggingface.co/docs/lerobot/libero).

## Giấy phép

Mô hình này tuân theo **Giấy phép Apache 2.0**, nhất quán với [kho OpenPI](https://github.com/Physical-Intelligence/openpi) gốc.

