多任务扩散 Transformer(DiT)policy 是原始 Diffusion Policy 架构的演进,它利用一个带文本和视觉条件的大型 DiT 进行多任务机器人学习。该实现同时支持用于 action 生成的扩散和流匹配目标,使机器人能够根据语言指令执行多种操作任务。
该模型使用:
这个模型令人兴奋之处在于,你只需约 450M 参数且训练量显著更少,就能实现极高的灵巧性,与数十亿参数的 VLA 模型相媲美。
多任务 DiT policy 有额外的依赖。使用以下命令安装:
pip install lerobot[multi_task_dit]
这将安装所有必要的依赖,包括用于 CLIP 模型的 HuggingFace Transformers 库。
要在你的 LeRobot 配置中使用多任务 DiT,请将 policy 类型指定为:
policy.type=multi_task_dit下面是在你的 dataset 上训练多任务 DiT 的完整训练命令:
lerobot-train \
--dataset.repo_id=YOUR_DATASET \
--output_dir=./outputs/multitask_dit_training \
--batch_size=32 \
--steps=5000 \
--save_freq=500 \
--log_freq=100 \
--policy.type=multi_task_dit \
--policy.device=cuda \
--policy.repo_id="HF_USER/multitask-dit-your-robot" \
--wandb.enable=true为了获得可靠的性能,请从这些建议的默认超参数开始:
lerobot-train \
--dataset.repo_id=YOUR_DATASET \
--output_dir=./outputs/mutitask_dit_training \
--batch_size=320 \
--steps=30000 \
--policy.type=multi_task_dit \
--policy.device=cuda \
--policy.horizon=32 \
--policy.n_action_steps=24 \
--policy.objective=diffusion \
--policy.noise_scheduler_type=DDPM \
--policy.num_train_timesteps=100 \
--policy.repo_id="HF_USER/multitask-dit-your-robot" \
--wandb.enable=true关键参数:
diffusion——从扩散开始,如果生成质量不佳,再尝试流匹配在扩散和流匹配之间选择:
# Diffusion objective (default)
--policy.objective=diffusion \
--policy.noise_scheduler_type=DDPM \ # or "DDIM"
--policy.num_train_timesteps=100 \
--policy.num_inference_steps=10 \ # For faster inference
--policy.beta_schedule=squaredcos_cap_v2 \ # Noise schedule type
--policy.prediction_type=epsilon \ # "epsilon" (predict noise) or "sample" (predict clean)
--policy.clip_sample=true \ # Clip samples during denoising
--policy.clip_sample_range=1.0 # Clipping range [-x, x]
# Flow matching objective
--policy.objective=flow_matching \
--policy.timestep_sampling_strategy=beta \ # or "uniform" | the beta sampling strategy performance appears much better in practice
--policy.num_integration_steps=100 \
--policy.integration_method=euler \ # or "rk4"
--policy.sigma_min=0.0 # Minimum noise in flow interpolation path根据 dataset 大小调整模型容量:
# Small datasets (< 100 examples)
--policy.num_layers=4 \
--policy.hidden_dim=512 \
--policy.num_heads=8 # should ideally be hidden_dim // 64
# Medium datasets (100-5k examples) - default
--policy.num_layers=6 \
--policy.hidden_dim=512 \
--policy.num_heads=8 # should ideally be hidden_dim // 64
# Large datasets (> 5k examples)
--policy.num_layers=8 \
--policy.hidden_dim=512 \
--policy.num_heads=8 # should ideally be hidden_dim // 64位置编码选项:
该模型支持两种用于 action sequence 的位置编码方法:
# Rotary Position Embedding (RoPE) - default, recommended
--policy.use_rope=true \
--policy.rope_base=10000.0 # Base frequency for RoPE
# Absolute positional encoding
--policy.use_positional_encoding=true # Disables RoPE when true其他 Transformer 参数:
--policy.dropout=0.1 # Dropout rate for DiT blocks (0.0-1.0)
--policy.timestep_embed_dim=256 # Timestep embedding dimension# Use different CLIP model for more expressivity at the cost of inference time
# experiment with larger or smaller models depending on the complexity of your tasks and size of dataset
--policy.vision_encoder_name=openai/clip-vit-large-patch14
# Use separate vision encoder per camera
# This may be useful when cameras have significantly different characteristics, but
# be wary of increased VRAM footprint.
--policy.use_separate_rgb_encoder_per_camera=true
# Image preprocessing
--policy.image_resize_shape=[XXX,YYY] \ # you may need to resize your images for inference speed ups
--policy.image_crop_shape=[224,224] \
--policy.image_crop_is_random=true # Random during training, center at inference# Use different CLIP text encoder model
# same as vision: experiment with larger or smaller models depending on the
# complexity of your tasks and size of dataset
--policy.text_encoder_name=openai/clip-vit-large-patch14视觉编码器使用独立的学习率倍率,建议以 1/10 作为理想的起始点:
--policy.optimizer_lr=2e-5 \
--policy.vision_encoder_lr_multiplier=0.1 # Vision encoder LR = 0.1 * optimizer_lr这里的原始扩散实现基于 TRI 的 LBM 论文 中描述的工作
此外,我们实现了流匹配目标,这在 Boston Dynamics 博客文章 中有高层次介绍。
可以考虑测试流匹配目标,并评估你的任务上的性能差异:
--policy.objective=flow_matching \ --policy.timestep_sampling_strategy=beta \ --policy.timestep_sampling_alpha=1.5 \ --policy.timestep_sampling_beta=1.0 \ --policy.timestep_sampling_s=0.999
这并未被证明在每种使用场景下都是银弹,但它偶尔能产生更平滑、更一致的 action。
使模型容量匹配你的 dataset 大小:
模型可能对你选择的预测长度(horizon)很敏感。根据你的控制频率,从约 1 秒的预测长度开始:
horizon=30horizon=10然后在此基础上尝试增加。预测长度决定了模型向未来预测 action 多远。
该模型对 n_action_steps 也可能非常敏感。根据你的控制频率,先将其设为约 0.8 秒,然后在此基础上调优:
为了更快的 inference,使用更少采样步数的 DDIM:
--policy.noise_scheduler_type=DDIM \ --policy.num_inference_steps=10
要从 checkpoint 恢复训练:
lerobot-train \
--config_path=./outputs/mutitask_dit_training/checkpoints/last/pretrained_model/train_config.json \
--resume=truecheckpoint 目录应包含 model.safetensors 和 config.json 文件(训练期间自动保存)。恢复时,配置会从 checkpoint 加载,因此你无需指定其他参数。
训练这些模型可能会比较棘手。以下是常见的失败模式和调试方法:
模型可能在 inference 期间“坍缩”,导致静止或没有 action。这可能发生在以下情况:
训练数据不足:如果你只有 20-50 个样本,试着将 dataset 规模大约翻倍。一旦你有 300 个以上的样本,如果仍然出现这种情况,任务可能太复杂了。
多个相似任务:当你的 dataset 包含多个相似任务(例如拾取 2 个不同的物体)时,模型可能过度依赖语言条件,而语言条件可能不够丰富。
调试提示:
有时机器人会完全忽略你的指令,转而执行其他任务。这通常只在你训练了多个任务时才会发生。
可能的原因:
调试提示:
如果训练损失不稳定或发散:
1e-5 和 3e-4 之间调整学习率下面是在自定义 dataset 上训练的完整示例:
lerobot-train \
--dataset.repo_id=YOUR_DATASET \
--output_dir=./outputs/mutitask_dit_training \
--batch_size=320 \
--steps=30000 \
--save_freq=1000 \
--log_freq=100 \
--env_eval_freq=1000 \
--policy.type=multi_task_dit \
--policy.device=cuda \
--policy.horizon=32 \
--policy.n_action_steps=24 \
--policy.objective=diffusion \
--policy.noise_scheduler_type=DDPM \
--policy.num_layers=6 \
--policy.hidden_dim=512 \
--policy.vision_encoder_name=openai/clip-vit-base-patch16 \
--policy.image_resize_shape=[320,240] \
--policy.image_crop_shape=[224,224] \
--policy.repo_id="HF_USER/multitask-dit-your-robot" \
--wandb.enable=true \
--wandb.project=multitask_ditpython -m lerobot.scripts.lerobot_train \
--dataset.repo_id=HuggingFaceVLA/libero \
--policy.type=multi_task_dit \
--policy.push_to_hub=false \
--output_dir="./outputs/multitask_dit_libero" \
--job_name="multitask-dit-libero" \
--wandb.enable=true \
--wandb.project=multitask_dit_libero \
--dataset.image_transforms.enable=true \
--dataset.image_transforms.max_num_transforms=4 \
--dataset.image_transforms.tfs='{"brightness":{"type":"ColorJitter","kwargs":{"brightness":[0.75,1.25]}},"contrast":{"type":"ColorJitter","kwargs":{"contrast":[0.6,1.4]}},"saturation":{"type":"ColorJitter","kwargs":{"saturation":[0.8,1.2]}},"hue":{"type":"ColorJitter","kwargs":{"hue":[-0.05,0.05]}},"sharpness":{"type":"SharpnessJitter","kwargs":{"sharpness":[0.6,1.4]}},"rotation":{"type":"RandomRotation","kwargs":{"degrees":[-5,5]}},"translation":{"type":"RandomAffine","kwargs":{"degrees":0,"translate":[0.1,0.1]}}}' \
--dataset.video_backend=torchcodec \
--policy.use_amp=true \
--policy.horizon=48 \
--policy.n_obs_steps=2 \
--policy.use_rope=true \
--policy.use_positional_encoding=false \
--policy.hidden_dim=768 \
--policy.num_layers=8 \
--policy.num_heads=12 \
--policy.dropout=0.1 \
--policy.timestep_embed_dim=256 \
--policy.objective=diffusion \
--policy.optimizer_lr=3e-4 \
--policy.optimizer_weight_decay=0 \
--policy.scheduler_warmup_steps=0 \
--policy.vision_encoder_name=openai/clip-vit-base-patch16 \
--policy.image_resize_shape=[256,256] \
--policy.image_crop_is_random=true \
--policy.text_encoder_name=openai/clip-vit-base-patch16 \
--policy.vision_encoder_lr_multiplier=0.1 \
--policy.device=cuda \
--num_workers=8 \
--save_freq=4000 \
--log_freq=100 \
--steps=100000 \
--batch_size=320结果:
| LIBERO Spatial | LIBERO Object | LIBERO Goal | LIBERO 10 | 平均 |
|---|---|---|---|---|
| 87.0 | 98.2 | 93.8 | 83.2 | 90.6 |
有关技术实现和架构的更多细节,请参阅: