manipulationmanipulationdiffusion-policypoint-clouddp33d-reconstructionvisuomotorimitation-learningdexterousunitree-g1tutorialai-perception

DP3: 3D Diffusion Policy với point cloud (hands-on)

DP3 biến point cloud thành input trực tiếp cho diffusion policy — 24.2% cải thiện trên 72 tasks, 85% success rate trên robot thật. Hands-on: cài đặt, train, eval từ repo YanjieZe/3D-Diffusion-Policy.

Nguyễn Anh TuấnJune 13, 202615 min read
DP3: 3D Diffusion Policy với point cloud (hands-on)

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

Kiến trúc tổng thể của DP3 — nguồn: repo YanjieZe/3D-Diffusion-Policy
Kiến trúc tổng thể của DP3 — nguồn: repo YanjieZe/3D-Diffusion-Policy

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:

  1. Lấy clean action $a^0$ từ dataset
  2. Thêm Gaussian noise theo schedule: $a^k = \sqrt{\bar{\alpha}_k} a^0 + \sqrt{1 - \bar{\alpha}_k} \epsilon$
  3. Network $\epsilon_\theta$ học predict noise $\epsilon$ với conditioning $(z_e, s_t)$
  4. Loss: $\mathcal{L} = \mathbb{E}{k,\epsilon}\left[||\epsilon - \epsilon\theta(a^k, k, z_e, s_t)||^2\right]$

Trong inference:

  1. Sample pure Gaussian noise $a^K$
  2. Chạy reverse denoising $K$ bước, mỗi bước guided bởi $(z_e, s_t)$
  3. 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ờ)

Hiệu quả Simple DP3 vs DP3 đầy đủ — nguồn: 3d-diffusion-policy.github.io
Hiệu quả Simple DP3 vs DP3 đầy đủ — nguồn: 3d-diffusion-policy.github.io

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.0diffusers==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:

  1. Load pre-trained RL expert policy từ third_party/rrl-dependencies/
  2. Chạy expert trong MuJoCo simulation
  3. Thu thập ~400 episodes dưới dạng observations + actions
  4. 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ùng simple_dp3 cho Simple DP3)
  • adroit_hammer — tên environment
  • 0112 — 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:

  1. Load checkpoint mới nhất từ outputs/
  2. Chạy policy trong simulation 100 episodes
  3. Report success rate

Target performance theo paper:

  • adroit_hammer: >80% success rate
  • metaworld_* (most tasks): >85% success rate
  • dexart_*: 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

Spatial generalization của DP3 trên real robot — nguồn: 3d-diffusion-policy.github.io
Spatial generalization của DP3 trên real robot — nguồn: 3d-diffusion-policy.github.io

Điểm mạnh nhất của DP3 là generalization. Paper test 4 dạng generalization:

  1. Spatial generalization: vật ở vị trí khác nhau trong workspace — DP3 đạt 85% success nhờ point cloud encode được absolute 3D position
  2. Appearance generalization: thay đổi màu sắc, texture của vật — DP3 ổn định vì geometry không đổi
  3. 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
  4. 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

NT

Nguyễn Anh Tuấn

Robotics & AI Engineer. Building VnRobo — sharing knowledge about robot learning, VLA models, and automation.

Khám phá VnRobo

Related Posts

Vì sao VLA 2D chưa đủ cho manipulation
research

Vì sao VLA 2D chưa đủ cho manipulation

6/13/202614 min read
NT
Robo3R: tái dựng 3D feed-forward cho robot arm
research

Robo3R: tái dựng 3D feed-forward cho robot arm

6/13/202613 min read
NT
Train Diffusion Policy đầu tiên với UMI và test trên robot arm
manipulation

Train Diffusion Policy đầu tiên với UMI và test trên robot arm

6/3/20266 min read
NT