LeRobot documentation

FLUX 3 操作

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

FLUX 3 操作

FLUX 3 Action 根据相机观测、状态和任务指令预测机器人动作。冻结的 Video VAE 和文本编码器为扩散 Transformer 提供输入,该 Transformer 预测视频潜变量和动作块;在推理时仅返回动作。LeRobot 支持推理和 PEFT:LoRA 用于适配主干网络,而机器人的动作和条件头则进行全量训练。

我们提供 flux-3-action-base 作为基础动作模型,并附带针对 SO-101 flux-3-action-so101 和 Franka Panda 机器人 flux-3-action-droid(在 DROID 数据集上微调)的微调版本。 此处的核心示例是基于 flux-3-action-so101 模型,通过 LoRA 进行任务适配。

若要基于基础模型训练新的机器人本体或进行全量微调,请使用我们独立的 flux-action 仓库。

安装

Video VAE 需要 NATTEN 0.21.6 或更高版本,且必须是从 https://whl.natten.org. 获取的、针对您的确切 torch 和 CUDA 版本构建的 wheel。NATTEN 提供了 torch 2.10 到 2.13 的 wheel,但尚未提供 LeRobot 默认安装的 torch 2.15 的 wheel,因此请先安装受支持的 torch。例如,在 LeRobot 检出目录中,安装 torch 2..13 与 CUDA 13.0,以及训练、策略、PEFT 和 EMA 依赖项。与安装指南中一样,TorchCodec 来自 CPU 索引:

pip install --index-url https://download.pytorch.org/whl/cu130 \
    'torch==2.13.0+cu130' 'torchvision==0.28.0+cu130' 'numpy>=2.0,<2.3'
pip install --index-url https://download.pytorch.org/whl/cpu 'torchcodec==0.13.0+cpu'
pip install -e ".[training,flux3,peft,diffusion]" \
    'torch==2.13.0+cu130' 'torchvision==0.28.0+cu130' 'torchcodec==0.13.0+cpu'
pip install 'natten==0.21.7+torch2130cu130' --find-links https://whl.natten.org

对于 580.65 之前的 NVIDIA 驱动程序,请改用 CUDA 12.6 构建版本:即 cu126 索引、+cu126 torch 和 torchvision 标签,以及 natten==0.21.7+torch2130cu126。对于其他 torch 版本,请使用标签与之匹配的 NATTEN wheel,例如针对 CUDA 13.0 的 torch 2.11,使用 natten==0.21.6+torch2110cu130。

SO-101 任务适配

使用 30 Hz 的 LeRobot v3 数据集,其中包含六个绝对指令动作通道和六个测量状态通道,且关节顺序和单位一致。夹爪位于最后。请提供原始值、一致的机器人校准以及 task 中的说明。

相机

相机名称、数量和布局均可配置。SO-101 软件包根据两个相机所显示的内容为其命名:

相机密钥
场景observation.images.scene
手腕observation.images.wrist

SO-101 scene camera (left) and wrist camera (right), showing the blue box and container

您可以使用 --rename_map 将相机名称映射到预期的键,例如:

--rename_map='{"observation.images.top":"observation.images.scene","observation.images.gripper_cam":"observation.images.wrist"}'

对 rollout 使用相同的映射;匹配的键无需映射。参见 重命名映射。

加载并训练

从 black-forest-labs/flux-3-action-so101 加载 SO-101 策略。 保存的配置会自动从 black-forest-labs/flux-3-action-base 的固定版本中加载共享的 VAE 和文本编码器。 如果访问受限,请使用具有访问权限的账户通过 hf auth login 进行身份验证。 在 LeRobot 检出目录中运行:

lerobot-train \
  --config_path=examples/flux3/lora.json \
  --policy.path=black-forest-labs/flux-3-action-so101 --policy.device=cuda \
  --dataset.repo_id=YOUR_ORG/YOUR_SO101_DATASET \
  --output_dir=outputs/so101_lora

Hub 缓存会保留已下载的模型和共享编码器,以便进行恢复和适配器推理。

固定的 SO-101-finetuned 检查点使用 scene / wrist 相机键,八个观测时间步,两个独立编码的视觉快照,以及过去动作/状态条件。它预测 42 个动作,以 30 Hz 执行前 32 个,然后重新规划。其保存的处理器携带与基础模型匹配的归一化统计信息。这些检查点设置在任务适应期间保持不变。 共享的 examples/flux3/lora.json 仅提供训练/运行时设置和训练预算;同一文件作为 lora.json 打包在每个 Hub 包中。相机布局、条件、动作表示和损失设置来自检查点。这些命令保留了保存的执行长度 32、guidance 3/3 和 eager 执行。对于 guidance 4/1 和编译,请添加 --policy.guidance_scale=4 --policy.guidance_scale_action=1 --policy.compile_model=true。

条件化实验:LeRobot 暴露了 n_obs_steps、history_snapshots 和 condition_on_past_actions。更改这些参数需要兼容的模型/处理器设置以及微调;对于常规任务适配,请保留检查点中保存的值。

该预设启用了秩/alpha 为 32 的 LoRA 以及衰减系数为 0.999 的 EMA;不会自动上传任何内容。请通过顶层的 peft 设置来启用新适配器,而不是使用 --policy.use_peft=true,后者用于标识已保存的适配器。

在我们的实验中,EMA 在 DROID 上带来了显著收益,而 SO-101 的结果目前尚不一致。其收益取决于数据和训练配置。我们建议保持 EMA 启用,并在选择部署哪个模型之前,使用相同的 rollout 协议对原始权重和 EMA 检查点进行评估。周期性离线验证损失使用的是原始权重;它不会自动比较这两种变体。

从单 GPU 预算开始,以便快速迭代。对于更大的训练预算,请使用相同的配置并应用以下覆盖项:

accelerate launch --num_processes=4 --multi_gpu -m lerobot.scripts.lerobot_train \
  --config_path=examples/flux3/lora.json \
  --policy.path=black-forest-labs/flux-3-action-so101 --policy.device=cuda \
  --dataset.repo_id=YOUR_ORG/YOUR_SO101_DATASET \
  --batch_size=8 --steps=14000 \
  --output_dir=outputs/so101_lora_large
预算GPU每个 GPU 的批处理累积有效批次微步(steps)优化器更新
快速迭代(默认)124810,0002,500
更大的预算48412814,0003,500

有效批量为 GPU 数量 × 每 GPU 批量 × 梯度累积步数。LeRobot 以微步(microsteps)为单位计算 steps、save_freq 和 eval_steps;要得到优化器更新次数,需除以累积步数。预设配置每 500 个微步(即 125 次更新)保存并评估一次。修改累积步数时,请确保上述三项设置均能被其整除。 调度器的冻结、预热、衰减和冷却阶段长度同样以微步为单位。设置这些阶段长度时,请将期望的优化器更新次数乘以累积因子。 两种预算方案使用相同的 LoRA、优化器和 EMA 设置,并保留所加载基础模型的 conditioning、动作维度和归一化配置。检查点同时包含原始适配器和 EMA 适配器。请通过留出集评估和 rollout 来选择预算方案和检查点;更大的批量并不保证更好的结果。

该预设将每个任务最后 20% 的 episode 保留用于评估。请根据您的硬件调整 batch size 和 accumulation;请参阅 多 GPU 训练 和 PEFT 训练。

DROID 任务适配

实验性: examples/flux3/lora.json 复用了 SO-101 PEFT 优化器、LoRA、dropout、EMA 以及训练预算设置。配置加载已验证,但端到端的 DROID PEFT 训练和任务性能尚未验证。

通过仓库 ID 直接加载 DROID 策略;其共享编码器会自动解析:

lerobot-train \
  --config_path=examples/flux3/lora.json \
  --policy.path=black-forest-labs/flux-3-action-droid \
  --dataset.repo_id=YOUR_ORG/YOUR_DROID_TASK_DATASET \
  --output_dir=outputs/droid_lora

此配置使用有效批量大小 8 和 2,500 次优化器更新,启用 EMA,并每 125 次更新保存一次原始/EMA 检查点。已禁用自动上传至 Hub。对于更大的预算,请参照 SO-101 示例使用四块 GPU 启动,并添加 --batch_size=8 --steps=14000。

该预设会加载 DROID 检查点的相机布局、条件、动作表示、控制速率和处理器,仅覆盖列出的训练/运行时设置。您的数据集必须符合检查点的约定:当前软件包使用三个相机、八个状态/动作通道以及 15 Hz 的绝对关节位置指令。如有需要,请使用 --rename_map 映射相机名称。两个机器人使用相同的训练示例;加载或推理时无需针对特定机器人的配置。

默认值和归一化

新配置使用这些 PEFT 默认值。加载 --policy.path 时会使用检查点中保存的设置;显式的配置/CLI 覆盖项具有更高优先级。DROID 检查点保留其自身的配置。

设置默认
条件当前图像和测量状态;1 个快照,无历史操作
操作命令增量;以 30 Hz 的频率预测 32 个并执行 32 个
相机在 256 × 512 画布上并排显示两个视图
适配器 / 头学习率1e-4 / 5e-4
权重衰减 / 梯度裁剪0 / 1
冻结 / 预热无
梯度检查点 / 图像增强开 / 关

新配置使用 n_obs_steps=1、history_snapshots=1 和 condition_on_past_actions=false。 加载检查点时会保留其显式值:固定的 SO-101 包使用八个历史时间步、两个视觉快照以及过去动作/状态条件。 conditioning="history" 选择独立的快照编码;它本身并不决定时间步的数量。训练还会读取未来的帧和指令作为目标,以及前一个指令以计算动作增量。

相机名称/顺序、状态/动作维度以及绝对动作通道仍因机器人而异。 SO-101 检查点保留最后一个通道为绝对值(delta_absolute_dims=[-1]),并使用通道权重 [1, 1, 1, 1, 1, 2]。类的默认设置不使用绝对通道例外,且权重相等。

基础模型保存的处理器拥有归一化统计量。请输入原始状态/动作,并在训练、恢复和推理过程中保持相同的统计量。SO-101 软件包的分位数基于其特定的关节顺序、单位和校准;它们并非通用的 SO-101 校准值。若要使用不同的统计量,请在训练前准备一个具有匹配处理器的独立基础模型。绝对动作数据集的统计量不能替代命令增量统计量。

训练会保存适配器(adapters)和训练好的头部(heads),并引用完整的基座模型。在重新加载时,请确保该基座模型及其冻结的编码器文件可访问;适配器不会自动合并到基座模型中。

继续

lerobot-train \
  --config_path=outputs/so101_lora/checkpoints/last/pretrained_model/train_config.json \
  --resume=true

从原始的 pretrained_model 检查点恢复,这会还原优化器和 EMA 状态。对于推理, 当启用 EMA 时,您可以选择其 pretrained_model_ema 同级文件。请保留每个适配器的原始基础模型和处理器;新下载的基础模型不能替代旧适配器所使用的模型。

推理

将 LeRobot runner 的 --policy.path 指向训练好的适配器检查点;它会加载所引用的基础模型和已保存的处理器。对于使用 完整基础模型 的直接调用,请同时加载处理器:

from lerobot.policies.factory import make_pre_post_processors
from lerobot.policies.flux3 import Flux3Policy

checkpoint = "black-forest-labs/flux-3-action-so101"
policy = Flux3Policy.from_pretrained(checkpoint).eval()
preprocessor, postprocessor = make_pre_post_processors(policy.config, pretrained_path=checkpoint)

# Run on every control tick, including while actions are queued:
prepared = preprocessor(observation)
normalized_action = policy.select_action(prepared)
absolute_command = postprocessor(normalized_action)

预处理器会缓冲观测/命令历史。后处理器会撤销归一化,在每个 tick 上积分增量并更新共享的命令历史。第一条命令锚定到测量状态;后续命令则从上一条命令开始积分。直接策略输出经过归一化,必须经过后处理。在回合边界或干预之后,请重置策略以及两个处理器;LeRobot 的同步运行器会执行此操作。不支持 RTC/异步推理。

对于默认的单个时间步策略,当前图像和测量状态即可满足需求。对于带有显式增量锚点的离线预测,请在 observation.command_history 中提供一个先前的命令;这可以在不向模型的条件输入中添加命令的情况下,为输出积分提供锚点。明确配置为多个观测时间步的检查点需要 policy.config.n_obs_steps 个图像/状态以及命令历史。将输入通过预处理器,调用 predict_action_chunk,然后进行后处理。--policy.compile_model=true 会启用冻结编码器和推理 DiT 的延迟编译;它不会编译训练 DiT。

为了降低推理时的显存占用,请在加载 Qwen 以及最终的 policy.to(...) 调用之后,将其移至 CPU:

policy.frozen.text_encoder.cpu()

这会将约 8.3 GiB 的权重移至主机内存;未缓存的指令编码速度较慢,而嵌入仍会被传输到策略设备并缓存。这不会降低加载期间的峰值内存,且后续的 policy.to(...) 会将 Qwen 与策略一起移回。

训练其他实现

对于我们尚未提供微调检查点的实现,请从 flux-action 中的基础模型开始。该工作流需要定义机器人的动作和条件头、相机布局、动作表示以及归一化。仅维度相同并不意味着可以复用其他机器人的头。

对于后续的 LeRobot 推理或任务适配,请将训练好的模型打包为一个完整的 LeRobot 策略,包含其配置和相应的处理器。仅有一个原始权重文件并不构成可加载的 --policy.path 包。本指南专注于将现有的 SO-101 和 DROID 策略适配到新任务。

所有策略仅构建 video 和 video_cond 内容流,以及机器人的动作流。 未使用的图像/音频权重会在加载前被过滤,在不改变动作预测的情况下节省约 28% 的 DiT 参数。保存的流列表不会启用图像/音频分支;加载并保存完整基础模型会记录缩减后的布局。针对已移除流的适配器需要其原始基础模型和较旧版本的代码。

完整的策略默认采用严格加载。在过滤掉已知的未使用流之后,缺失、意外或形状不正确的权重会引发错误。显式指定 strict=False 仅允许初始化缺失的或调整不匹配的具身化头;主干权重仍然是必需的,并且会进行形状检查。

验证

CPU 测试涵盖了打包、处理器、PEFT 更新以及检查点/恢复。此前的真实权重 H200 检查早于当前的处理器重构。此确切修订版本仍需进行 GPU 和机器人验证;现有检查并未确立四 GPU 容量或在新形态下的 PEFT 质量。

Update on GitHub