Ở bài 2, chúng ta thấy Robo3R dựng hình học 3D metric-scale từ camera RGB thường ở 43 Hz — đủ nhanh cho robot control loop. Câu hỏi tiếp theo đặt ra tự nhiên: có point cloud rồi, làm gì với nó?
Đây là lúc 3D Diffusion Policy (DP3) vào cuộc.
DP3 là visuomotor policy framework được công bố tại RSS 2024, kết hợp hai ý tưởng tưởng chừng đơn giản nhưng khi ghép lại tạo ra kết quả ấn tượng: dùng point cloud thay ảnh 2D làm visual input cho diffusion policy. Kết quả theo paper: 24.2% cải thiện tương đối trên 72 simulation tasks, 85% success rate trên robot thật chỉ với 40 demonstrations.
Paper: 3D Diffusion Policy: Generalizable Visuomotor Policy Learning via Simple 3D Representations — Yanjie Ze, Gu Zhang, Kangning Zhang, Chenyuan Hu, Muhan Wang, Huazhe Xu — RSS 2024.
Bài này là hands-on: chúng ta sẽ hiểu kiến trúc, cài đặt môi trường, generate demonstrations, train từ scratch, và eval policy — tất cả dựa trực tiếp vào repo YanjieZe/3D-Diffusion-Policy.
Tại sao point cloud, không phải ảnh?
Trước khi vào hands-on, cần hiểu động lực thiết kế của DP3.
Image-based Diffusion Policy có gì?
Diffusion Policy (Chi et al., CoRL 2023) là một trong những state-of-the-art cho behavior cloning: dùng diffusion model để học phân phối xác suất trên không gian hành động, conditioning trên quan sát visual. Với input là ảnh RGB, nó hoạt động tốt trong môi trường lab cố định.
Nhưng bài 1 của series đã chỉ ra vấn đề cốt lõi: ảnh 2D không mã hóa được geometry. Policy học từ ảnh RGB phải "đoán" depth, shape, và spatial relationship từ pixel values — một bài toán ill-posed. Thay đổi góc camera một chút, thay đổi ánh sáng, hay thêm vật lạ vào background là đủ để làm policy fail.
DP3 thay thế ảnh bằng point cloud
Thay vì cho policy nhìn thấy ảnh, DP3 cho nó nhìn thấy point cloud thưa (sparse point cloud) — một tập hợp điểm 3D trong không gian robot frame. Mỗi điểm có tọa độ (x, y, z) và màu sắc (r, g, b) — 6 chiều mỗi điểm.
Ưu điểm so với ảnh:
| Vấn đề với ảnh 2D | Point cloud giải quyết thế nào |
|---|---|
| Không biết depth tuyệt đối | Tọa độ z metric trong robot frame |
| Camera-sensitive (thay góc → fail) | Pose-invariant (3D coords không đổi theo camera) |
| Domain gap (lighting, background) | 3D geometry ít bị ảnh hưởng bởi appearance |
| Occlusion ambiguous | Depth order tường minh |
| Ảnh 224×224 = 150K values | Sparse point cloud ~1024 pts × 6 = 6K values |
Nhược điểm: cần thêm bước preprocessing để có point cloud — hoặc depth camera (RealSense, Azure Kinect), hoặc 3D reconstruction như Robo3R từ bài 2.
Kiến trúc DP3

DP3 gồm ba thành phần chạy nối tiếp nhau:
1. Point Cloud Encoder (DP3 Encoder)
Đây là phần khác biệt cốt lõi so với image-based policy. Encoder nhận input là point cloud $P \in \mathbb{R}^{N_p \times 6}$ — mỗi điểm có 6 chiều (x, y, z, r, g, b).
Kiến trúc encoder theo phong cách PointNet++:
- Farthest Point Sampling (FPS): chọn $N_s$ điểm đại diện phân tán đều trong không gian 3D — tránh cluster quá nhiều điểm ở một vùng
- Ball Query: với mỗi điểm đại diện, gom các điểm lân cận trong bán kính $r$ thành một neighborhood
- MLP layers: encode local geometry của từng neighborhood thành feature vector
- Hierarchical grouping: lặp lại quá trình này nhiều lần ở resolution thô hơn — giống như pooling trong CNN nhưng trong 3D
- Global Pooling: aggregate tất cả local features thành một vector global $z_e \in \mathbb{R}^{d}$ compact
Điểm quan trọng: encoder này nhẹ — chỉ vài triệu parameters, chạy được trong real-time mà không cần GPU đắt tiền.
2. Conditional Denoising Diffusion (Action Head)
Sau khi có visual embedding $z_e$ từ point cloud encoder, DP3 dùng diffusion model để sinh action sequence — đây là phần được kế thừa từ Diffusion Policy gốc.
Cơ chế hoạt động:
Trong training:
- Lấy clean action $a^0$ từ dataset
- Thêm Gaussian noise theo schedule: $a^k = \sqrt{\bar{\alpha}_k} a^0 + \sqrt{1 - \bar{\alpha}_k} \epsilon$
- Network $\epsilon_\theta$ học predict noise $\epsilon$ với conditioning $(z_e, s_t)$
- Loss: $\mathcal{L} = \mathbb{E}{k,\epsilon}\left[||\epsilon - \epsilon\theta(a^k, k, z_e, s_t)||^2\right]$
Trong inference:
- Sample pure Gaussian noise $a^K$
- Chạy reverse denoising $K$ bước, mỗi bước guided bởi $(z_e, s_t)$
- Ra action sequence $a^0$ — thường là chuỗi 8–32 timesteps
Tổ hợp "point cloud encoder + diffusion head" này cực kỳ hiệu quả về sample efficiency: chỉ cần 10 demonstrations trong simulation để đạt performance tốt.
3. Simple DP3 — Variant nhanh hơn 2x
Paper cũng giới thiệu Simple DP3 — đơn giản hóa backbone diffusion:
- Thay U-Net đầy đủ bằng UNet nhỏ hơn với ít residual blocks
- 2x inference speedup trong khi giữ accuracy tương đương
- Dùng ~10GB GPU memory (so với ~16GB của full DP3)
- Training ~1–2 giờ trên Nvidia A40 (full DP3 mất ~3 giờ)

Với deployment thực tế trên robot, Simple DP3 thường là lựa chọn tốt hơn do latency thấp hơn mà performance tương đương.
So sánh chi tiết: DP3 vs Image-based Diffusion Policy
| Tiêu chí | Image Diffusion Policy | DP3 |
|---|---|---|
| Visual input | RGB image (224×224 = 150K values) | Sparse point cloud (~1024 pts × 6 = 6K values) |
| Geometry encoding | Implicit (phải học từ pixel) | Explicit 3D coordinates |
| Camera sensitivity | Cao — thay đổi góc → fail | Thấp — pose-invariant |
| Lighting sensitivity | Cao | Thấp (geometry ổn định) |
| Data efficiency | Cần nhiều demos | Works với 10 demos (sim) |
| Inference speed | Nhanh | Nhanh (Simple DP3 ≈ tương đương) |
| Hardware | Camera RGB thôi | Depth sensor hoặc 3D reconstruction |
| Real-world generalization | Khó (domain gap ảnh) | Tốt hơn |
Kết quả quantitative trên 72 simulation tasks: DP3 cải thiện 24.2% so với image-based baseline. Trên robot thật: 85% success rate vs ~60% của image-based counterpart.
Hands-on: Cài đặt môi trường
Phần này follow đúng INSTALL.md của repo.
Requirements:
- Ubuntu 20.04 (khuyến nghị)
- CUDA ≥ 12.1
- Nvidia GPU (≥ 10GB VRAM cho Simple DP3, ≥ 16GB cho full DP3)
- Python 3.8
Bước 1: Clone repo
git clone https://github.com/YanjieZe/3D-Diffusion-Policy.git
cd 3D-Diffusion-Policy
Bước 2: Tạo conda environment
conda create -n dp3 python=3.8
conda activate dp3
Bước 3: Cài PyTorch (CUDA 12.1)
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
Nếu dùng CUDA version khác, điều chỉnh URL theo PyTorch install guide.
Bước 4: Cài DP3 package
cd 3D-Diffusion-Policy && pip install -e . && cd ..
Bước 5: Cài MuJoCo (cho simulation environments)
mkdir -p ~/.mujoco
cd ~/.mujoco
wget https://github.com/deepmind/mujoco/releases/download/2.1.0/mujoco210-linux-x86_64.tar.gz \
-O mujoco210.tar.gz --no-check-certificate
tar -xvzf mujoco210.tar.gz
Thêm vào ~/.bashrc:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/.mujoco/mujoco210/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/nvidia
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64
export MUJOCO_GL=egl
Sau đó source ~/.bashrc.
Bước 6: Cài mujoco-py
cd third_party/mujoco-py-2.1.2.14
pip install -e .
cd ../..
Bước 7: Cài simulation environments
pip install setuptools==59.5.0 Cython==0.29.35 patchelf==0.17.2.0
cd third_party
cd dexart-release && pip install -e . && cd ..
cd gym-0.21.0 && pip install -e . && cd ..
cd Metaworld && pip install -e . && cd ..
cd rrl-dependencies && pip install -e mj_envs/. && pip install -e mjrl/. && cd ..
cd ..
Bước 8: Cài PyTorch3D (simplified)
cd third_party/pytorch3d_simplified && pip install -e . && cd ../..
Bước 9: Cài các packages còn lại
pip install zarr==2.12.0 wandb ipdb gpustat dm_control omegaconf \
hydra-core==1.2.0 dill==0.3.5.1 einops==0.4.1 diffusers==0.11.1 \
numba==0.56.4 moviepy imageio av matplotlib termcolor
Lưu ý quan trọng: Version pinning là bắt buộc. hydra-core==1.2.0 và diffusers==0.11.1 phải dùng đúng version được chỉ định — dùng version mới hơn thường gây API incompatibility. Tương tự numba==0.56.4 cần match với Python 3.8.
Hands-on: Generate Demonstrations
DP3 dùng behavior cloning — cần demonstrations từ expert policy. Repo cung cấp sẵn script để generate từ pre-trained RL experts.
Environments hỗ trợ
| Benchmark | Số tasks | Ví dụ | Độ khó |
|---|---|---|---|
| Adroit | 4 | hammer, door, pen, relocate | Medium–Hard |
| DexArt | 4 | bucket, laptop, toilet, faucet | Hard |
| MetaWorld | 50 | reach, push, pick-place, button-press... | Easy–Medium |
| Bi-DexHands | nhiều | bimanual dexterous tasks | Very Hard |
Để bắt đầu, Adroit hammer là task tốt nhất: có sẵn RL expert, task có ý nghĩa thực tế (robot tay dexterous đóng đinh), và cho thấy rõ ưu điểm của 3D.
Generate demonstrations cho Adroit hammer
bash scripts/gen_demonstration_adroit.sh hammer
Script này:
- Load pre-trained RL expert policy từ
third_party/rrl-dependencies/ - Chạy expert trong MuJoCo simulation
- Thu thập ~400 episodes dưới dạng observations + actions
- Lưu vào
data/adroit_hammer.zarr
Dataset format mà DP3 dùng:
data/adroit_hammer.zarr/
├── data/
│ ├── point_cloud # (N, T, Np, 6) — T timesteps, Np points, xyz+rgb
│ ├── robot_state # (N, T, D_s) — robot joint positions
│ └── action # (N, T, D_a) — target actions
Hands-on: Training
Train DP3
bash scripts/train_policy.sh dp3 adroit_hammer 0112 0 0
Giải thích từng argument:
dp3— tên policy (có thể dùngsimple_dp3cho Simple DP3)adroit_hammer— tên environment0112— experiment ID (dùng để tổ chức checkpoint)0— GPU ID (0 = GPU đầu tiên)0— seed offset
Để dùng Simple DP3 (nhanh hơn, khuyến nghị):
bash scripts/train_policy.sh simple_dp3 adroit_hammer 0112 0 0
Monitoring training
Training mặc định log vào Weights & Biases. Nếu chưa có WandB account hoặc muốn chạy offline:
WANDB_MODE=disabled bash scripts/train_policy.sh dp3 adroit_hammer 0112 0 0
Thời gian training ước tính:
- Simple DP3 trên A40 (48GB): ~1–2 giờ
- Full DP3 trên A40: ~3 giờ
- Trên RTX 3090 (24GB): ~4–6 giờ (full DP3)
Checkpoints được lưu vào outputs/ theo format Hydra.
Hands-on: Evaluation
bash scripts/eval_policy.sh dp3 adroit_hammer 0112 0 0
Script này:
- Load checkpoint mới nhất từ
outputs/ - Chạy policy trong simulation 100 episodes
- Report success rate
Target performance theo paper:
adroit_hammer: >80% success ratemetaworld_*(most tasks): >85% success ratedexart_*: 60–80% success rate
Train và eval trên real-robot data
Nếu muốn test với data real robot (Franka + Allegro Hand với task khoan đinh realdex_drill):
Download dataset từ Google Drive:
# Dataset link: https://drive.google.com/file/d/1G5MP6Nzykku9sDDdzy7tlRqMBnKb253O/view
# Download và đặt vào thư mục data/
Sau đó train:
bash scripts/train_policy.sh dp3 realdex_drill 0112 0 0
Kết quả Generalization

Điểm mạnh nhất của DP3 là generalization. Paper test 4 dạng generalization:
- Spatial generalization: vật ở vị trí khác nhau trong workspace — DP3 đạt 85% success nhờ point cloud encode được absolute 3D position
- Appearance generalization: thay đổi màu sắc, texture của vật — DP3 ổn định vì geometry không đổi
- Instance generalization: dùng object khác cùng loại (ví dụ khoan điện khác kiểu) — ít bị ảnh hưởng
- Viewpoint generalization: camera ở góc khác — point cloud là 3D coordinates nên invariant với camera pose
Contrast với image-based policy: thay đổi lighting hay đặt vật lệch 5cm là đủ để fail. DP3 với point cloud ít nhạy cảm hơn đáng kể vì lý do này.
Kết nối với Robo3R: pipeline đầy đủ
Đây là phần quan trọng nhất để hiểu bức tranh lớn của series này.
DP3 cần point cloud làm input. Nhưng point cloud đến từ đâu trong thực tế?
Nguồn 1: Depth camera (cách repo gốc dùng)
Repo dùng RealSense L515 để lấy depth image rồi project thành point cloud:
RealSense L515 → depth image → backproject → point cloud (xyz) + color (rgb)
Đây là cách đơn giản nhất nhưng có hạn chế: depth camera không hoạt động tốt với vật trong suốt, phản chiếu, hay vật rất mỏng.
Nguồn 2: Robo3R feed-forward reconstruction (khuyến nghị)
Bài 2 đã giới thiệu Robo3R — cho ra metric-scale point cloud từ camera RGB thường ở 43 Hz. Ghép Robo3R với DP3 tạo ra pipeline mạnh hơn:
Camera RGB (bất kỳ loại nào)
↓
Robo3R (43 Hz) — feed-forward 3D reconstruction
↓
Metric-scale point cloud trong robot frame
↓
DP3 Point Cloud Encoder
↓
Diffusion denoising (K steps)
↓
Action sequence → gửi đến robot controller
Ưu điểm của pipeline này: chỉ cần camera RGB thông thường, không cần depth sensor đắt tiền. Mọi hạn chế của depth camera (vật trong suốt, phản chiếu, ánh sáng mạnh) đều được giải quyết vì Robo3R chỉ dùng ảnh RGB.
Triển khai thực tế trên Unitree G1
Unitree G1 có 43 DoF và hai tay dexterous — platform lý tưởng để test DP3. Dưới đây là những điểm thực tế khi deploy.
Hardware setup đề xuất
- Camera: RGB camera gắn trên đầu (head camera) hoặc cổ tay (wrist camera)
- Point cloud: dùng RealSense D435i (có depth) giai đoạn đầu, sau upgrade sang Robo3R pipeline
- Inference: Jetson Orin NX 16GB onboard (Simple DP3 ~10GB fit), hoặc workstation external qua WiFi
Những điều cần chỉnh khi adapt sang G1
1. Crop point cloud nghiêm ngặt
G1 có workspace rộng và nhiều visual clutter (tay robot, thân robot, sàn). Cần crop chỉ giữ lại vùng task-relevant:
def crop_workspace_pointcloud(pcd, x_range=(-0.5, 0.5),
y_range=(-0.3, 0.3),
z_range=(0.0, 0.6)):
mask = (
(pcd[:, 0] > x_range[0]) & (pcd[:, 0] < x_range[1]) &
(pcd[:, 1] > y_range[0]) & (pcd[:, 1] < y_range[1]) &
(pcd[:, 2] > z_range[0]) & (pcd[:, 2] < z_range[1])
)
return pcd[mask]
2. Dùng global position cho action space
Paper chỉ rõ: DP3 perform tốt hơn với global end-effector position thay vì delta/relative position. Với G1, action space nên là absolute position của wrist trong robot base frame.
3. Điều chỉnh prediction horizon
- Horizon 8: tốt cho tasks nhanh (pick-and-place)
- Horizon 16: balance giữa tốc độ và smoothness (khuyến nghị)
- Horizon 32: tốt cho tasks cần smooth trajectory dài (pouring, insertion)
4. Inference frequency
DP3 (full) chạy ~10 Hz, Simple DP3 ~25 Hz. Với G1 controller chạy 500 Hz, cần interpolation giữa các action prediction.
Pitfalls thường gặp khi setup DP3
1. Version incompatibility là thủ phạm số 1
hydra-core, diffusers, và numba đều cần version pinning chính xác. Dùng version mới hơn thường gây lỗi import hoặc API mismatch. Luôn dùng đúng version trong INSTALL.md.
2. Headless rendering trên server
Chạy trên server không có display: bắt buộc set MUJOCO_GL=egl. Thiếu setting này gây lỗi No display found ngay khi import MuJoCo.
export MUJOCO_GL=egl
# Thêm vào ~/.bashrc để tự động
3. Point cloud density không phù hợp
DP3 dùng FPS để sample ~1024 điểm từ input. Nếu input quá ít điểm (<500), encoder không đủ thông tin. Nếu quá nhiều (>10000), FPS chạy chậm đáng kể. Target input: 2000–5000 điểm trước FPS.
4. GPU memory OOM
Simple DP3 cần ~10GB, full DP3 cần ~16GB. Nếu gặp OOM error, giảm batch_size trong config:
# Trong config file:
training:
batch_size: 64 # Giảm xuống 32 hoặc 16 nếu OOM
5. WandB login blocking
Nếu server không có internet, WandB login sẽ block indefinitely. Luôn set WANDB_MODE=disabled khi train offline.
Simple DP3 vs Full DP3: chọn cái nào?
| Simple DP3 | Full DP3 | |
|---|---|---|
| GPU memory | ~10GB | ~16GB |
| Training time (A40) | 1–2 giờ | ~3 giờ |
| Inference speed | ~25 Hz | ~10 Hz |
| Accuracy | Tương đương | Baseline |
| Khi nào dùng | Deploy thực tế, Jetson | Research, benchmark |
Kết luận rõ ràng: với deploy thực tế trên robot (bao gồm Unitree G1), Simple DP3 là lựa chọn tốt hơn.
Tóm tắt và bước tiếp theo
DP3 là baseline mạnh cho visuomotor policy 3D-aware:
- Kiến trúc đơn giản: point cloud encoder (PointNet++-style) + diffusion backbone — dễ hiểu, dễ extend
- Repo well-maintained: 1,300+ stars, 16+ follow-up papers dùng làm baseline
- Data efficient: chỉ cần 10 demos trong sim, 40 demos trên robot thật
- Strong generalization: 4 dạng generalization đều tốt nhờ 3D representation
Tuy nhiên, DP3 vẫn có giới hạn rõ ràng: đây là single-arm policy không handle large-workspace của humanoid full-body, và chưa tích hợp language conditioning để ra instruction. Với Unitree G1 cần cả hai tay và di chuyển toàn thân, cần thứ gì đó rộng hơn.
Đây là lý do bài 4 sẽ đi vào Omni-Manip — framework mở rộng spatial 3D perception cho omnidirectional workspace, phù hợp hơn với humanoid.
Bài viết liên quan
- Bài 1: Vì sao VLA 2D chưa đủ cho manipulation — Nền tảng: 5 hạn chế cốt lõi của 2D representation
- Bài 2: Robo3R — tái dựng 3D feed-forward từ RGB — Cách lấy point cloud từ camera RGB thường
- Bài 4: Omni-Manip — Spatial 3D cho humanoid — Mở rộng DP3 cho omnidirectional large-workspace


