Xiaomi-Robotics-0:面向实时执行的开放域视觉-语言-动作模型(含代码分析)
论文标题:Xiaomi-Robotics-0: An Open-Sourced Vision-Language-Action Model with Real-Time Execution
论文链接:项目主页
作者团队:Xiaomi Robotics
摘要
本文介绍 Xiaomi-Robotics-0,一个面向高性能与实时平滑执行的视觉-语言-动作(Vision-Language-Action,VLA)模型。该方法的核心贡献在于精心设计的训练配方与部署策略。Xiaomi-Robotics-0 首先在大规模跨本体(cross-embodiment)机器人轨迹数据和视觉语言数据上进行预训练,使其具备广泛且可泛化的动作生成能力,同时避免底层预训练视觉语言模型(VLM)的灾难性遗忘。在后训练阶段,本文提出多种技术来训练异步执行的 VLA 模型,以解决真实机器人部署中的推理延迟问题。在部署阶段,作者仔细对齐连续动作块(action chunk)的时间步长,确保连续且无缝的实时执行。实验结果表明,Xiaomi-Robotics-0 在模拟基准测试和两项需要精确灵巧双手操作的真实机器人任务上均达到最优性能。代码和模型权重已开源,便于复现和进一步研究。
1. 研究背景与动机
视觉-语言-动作(VLA)模型作为一种新兴的机器人策略学习范式,近年来引起了广泛关注。这类模型基于预训练的视觉语言模型(VLM),将观测图像和语言指令直接映射为动作,在广泛的任务范围内展现出强大的性能与泛化能力。然而,尽管 VLA 模型表现出色,其大规模参数(可达数十亿)导致推理延迟较高,这给平滑连接连续推理步骤带来了挑战,处理不当会导致运动不平滑甚至失控。
在真实机器人部署中,推理延迟是一个不可忽视的问题。同步执行策略要求机器人在推理完成前保持静止,这会造成动作执行的不连贯;异步执行虽然允许机器人在推理期间继续执行轨迹,但若缺乏适当的设计,连续推理生成的动作块之间可能存在不一致,导致运动卡顿甚至进入分布外状态。
本文提出的 Xiaomi-Robotics-0 旨在解决这一核心矛盾:在保持高性能的同时,实现快速平滑的实时机器人执行。
2. 方法论
2.1 模型架构
Xiaomi-Robotics-0 采用混合 Transformer(Mixture-of-Transformers,MoT)架构,由两部分组成:
- 视觉语言模型(VLM) :采用 Qwen3-VL-4B-Instruct,负责处理观测图像和语言指令输入
- 扩散 Transformer(DiT) :基于 Flow-Matching 生成动作块
模型总参数量为 4.7B。VLM 接收当前时刻的观测图像 ot 和用户提供的语言指令 l,DiT 则基于 VLM 产生的 Key-Value(KV)缓存和机器人本体状态(proprioceptive state)生成 T 步动作块 at:t+T。
2.2 训练数据
训练数据来自两个主要来源:
机器人轨迹数据:来源于多个开源数据集(DROID、MolmoAct)以及小米内部收集的数据。内部数据包含两项具有挑战性的任务:乐高拆解(Lego Disassembly)和毛巾折叠(Towel Folding),分别收集了 338 小时和 400 小时的遥操作轨迹。整个轨迹数据集包含约 2 亿个时间步。
视觉语言数据:构建了超过 8000 万样本的视觉语言语料库,来源包括通用视觉语言数据集和机器人数据集。数据聚焦于四类任务:视觉定位(Visual Grounding)、视觉问答(VQA)、图像描述和具身推理与规划。视觉定位采用 Grounded SAM、Grounding DINO 1.5 和 LLMDet 的交叉验证共识机制确保像素级标注精度;VQA 和图像描述通过最新预训练 VLM 重新标注以提升质量;具身推理与规划数据则利用预训练 VLM 从轨迹根生成。
2.3 预训练
预训练分为两个步骤:
第一步:赋予 VLM 动作生成能力。模型同时预测 N 个动作块候选及其对应分数,采用 Choice Policies 的训练范式。训练时计算每个候选动作块与真实动作的 L1 距离,将其作为分数预测的监督目标;动作预测采用胜者通吃(winner-takes-all)策略,仅更新 L1 距离最小的候选。为避免灾难性遗忘,模型同时在视觉语言数据和机器人轨迹数据上联合训练,采样比例为 1:6。
第二步:冻结 VLM,从头训练扩散 Transformer。DiT 通过 Flow-Matching 损失进行训练:
其中 τ ∈ [0, 0.999] 为 Flow-Matching 时间步, 为噪声动作。采用 Beta 分布采样时间步,在噪声较大的时间步上给予更多权重。
2.4 后训练:异步执行
在真实机器人部署中,推理延迟导致同步执行时机器人需要等待推理完成。为解决此问题,本文提出异步执行策略。
训练时动作前缀(Training RTC) :在生成动作时,将前一次推理已提交的动作作为前缀拼接到噪声动作之前。然而,这种方法存在副作用:后期时间步的动作预测可以简单地复制动作前缀而非关注视觉和语言输入,导致策略缺乏反应性。
Λ 形状注意力掩码:本文提出两种技术解决这一问题:
- 为噪声动作标记添加 RoPE 位置索引偏移,使其能够区分噪声动作与干净动作前缀
- 将 DiT 的因果注意力掩码替换为 Λ 形状注意力掩码,使噪声动作只能通过 VLM KV 缓存、sink 标记、状态标记和前 w 个时间步的动作标记进行注意力计算
这种设计确保早期时间步的动作可以平滑过渡,而后期时间步的动作必须关注视觉观测和语言输入,从而保证反应性。
2.5 部署策略
同步执行:执行预测动作块的前 Te 步,然后立即使用最新观测进行下一轮推理。
异步执行:每轮推理同样先执行 Te 步,但机器人在推理期间继续执行当前动作块的剩余步骤。下一轮推理使用当前动作块的第 Te 到 Te+Δtc-1 步作为前缀。通过设置 Δtc ≥ Δtinf(推理延迟),确保整个推理窗口内始终有可用动作,实现无缝过渡。
在 NVIDIA GeForce RTX 4090 GPU 上,模型推理延迟为 80ms。所有输入模态通过时间戳同步到统一的 30Hz 时间线。
3. 代码实现分析
3.1 项目结构
代码仓库的组织结构清晰,主要分为以下几个模块:
Xiaomi-Robotics-0/
├── deploy/ # 部署相关代码
│ ├── server.py # 模型推理服务器
│ └── client.py # 客户端连接封装
├── eval_libero/ # LIBERO基准评估
│ ├── main.py
│ └── merge_results.py
├── eval_calvin/ # CALVIN基准评估
│ └── main.py
├── eval_simplerenv/ # SimplerEnv基准评估
│ └── main.py
├── scripts/ # 启动脚本
│ ├── deploy.sh
│ ├── launch_libero.sh
│ ├── launch_calvin.sh
│ └── launch_simplerenv.sh
└── README.md
3.2 模型推理服务器(server.py)
模型推理服务器是整个系统的核心组件,采用多进程架构实现高性能推理:
class Server(mp.Process):
def __init__(self, model_path, host, port, seed=42):
super(Server, self).__init__()
self.host = host
self.port = port
# 加载模型,使用 Flash Attention 2 和 bfloat16 精度
self.model = AutoModel.from_pretrained(
model_path,
trust_remote_code=True,
attn_implementation="flash_attention_2",
dtype=torch.bfloat16
).cuda().to(torch.bfloat16)
self.processor = AutoProcessor.from_pretrained(
model_path,
trust_remote_code=True,
use_fast=False
)
关键技术点:
- 使用
flash_attention_2 加速注意力计算 - 采用
bfloat16 混合精度减少显存占用并加速推理 - 基于 socket 的 TCP 服务器架构,支持多客户端并发
服务器支持两种输入格式:
- 单目视觉输入(Bridge/Fractal 数据集):base 视角 + 语言指令
- 双目视觉输入(LIBERO/CALVIN 等):base 视角 + 左腕视角 + 语言指令
输入处理示例:
instruction = f"<|im_start|>user\nThe following observations are captured from multiple views.\n"
f"# Base View\n<|vision_start|><|image_pad|><|vision_end|>\n"
f"# Left-Wrist View\n<|vision_start|><|image_pad|><|vision_end|>\n"
f"Generate robot actions for the task:\n{language} /no_cot<|im_end|>\n"
f"<|im_start|>assistant\n<cot></cot><|im_end|>\n"
这里使用了 Qwen3-VL 的特殊 token 格式,其中:
-
<|vision_start|>...<|vision_end|>:视觉内容标记 -
/no_cot:禁用思维链(Chain of Thought) -
<cot></cot>:空的思维链占位符
3.3 客户端与通信(client.py)
客户端封装了与服务器的 socket 通信:
class Client:
def __init__(self, host="localhost", port=10086):
self.host = host
self.port = port
self._connect_with_retry(max_retries=None, retry_interval=1)
def _send_with_length_prefix(self, data):
# 使用 pickle 序列化 + 长度前缀协议
serialized = pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)
self.client_socket.sendall(struct.pack(">I", len(serialized)) + serialized)
def __call__(self, **data):
self._send_with_length_prefix(data)
response = self._recv_with_length_prefix()
return response
通信协议特点:
- 采用 pickle 序列化,支持任意 Python 对象传输
- 长度前缀协议确保数据完整性
- 自动重连机制提高鲁棒性
3.4 批量部署脚本(deploy.sh)
为了支持大规模并行评估,项目提供了 tmux 批量部署脚本:
# 为每个端口启动独立的模型服务器
for ((i=0; i<NUM_PORTS; i++)); do
PORT=$((BASE_PORT + i))
GPU_ID=$((i % NUM_GPUS)) # 在多个 GPU 间轮询
tmux new-window -d -t $SESSION_NAME -n $WINDOW_NAME
tmux send-keys -t $SESSION_NAME:$WINDOW_NAME \
"CUDA_VISIBLE_DEVICES=$GPU_ID python deploy/server.py --model '$MODEL_PATH' --port $PORT" Enter
done
这种设计使得:
- 单个模型服务器可服务多个评估 worker
- 通过多端口部署实现横向扩展
- 利用多 GPU 并行提升整体吞吐量
3.5 LIBERO 评估实现(eval_libero/main.py)
LIBERO 评估代码展示了动作块(action chunk)的执行逻辑:
action_plan = collections.deque()
while t < max_steps + args.num_steps_wait:
# 当动作队列耗尽时,请求新的动作块
if len(action_plan) <= 0:
model_inputs = {
"task_id": f"libero_all",
"state": state,
"base": base_obs,
"wrist_left": left_wrist_obs,
"language": instruction,
}
action_chunk = client(**model_inputs)[0, :, :-1]
# 取前 replan_steps 步加入执行队列
action_plan.extend(action_chunk[0 : args.replan_steps, 0:7])
# 从队列中取出下一步动作执行
action = action_plan.popleft().tolist()
obs, _, done, _ = env.step(action)
关键技术细节:
- 使用
collections.deque 作为高效的动作队列 -
replan_steps 控制每次推理的动作执行步数(论文中设为 10) - 状态预处理包括末端执行器位置、姿态(四元数转轴角)和夹爪状态
确定性哈希(Deterministic Hashing) :
def hash_data_to_seed(data, max_bytes=4):
"""为包含 Numpy 数组和 PIL 图像的字典计算稳定的 SHA256 哈希"""
def custom_encoder(obj):
if isinstance(obj, np.ndarray):
return {"__type__": "numpy", "data": obj.tobytes().hex()}
if isinstance(obj, Image.Image):
img_hash = hashlib.md5(img.tobytes()).hexdigest()
return {"__type__": "PIL.Image", "content_hash": img_hash}
json_str = json.dumps(data, default=custom_encoder, sort_keys=True)
hex_hash = hashlib.sha256(json_str.encode("utf-8")).hexdigest()
return int(hex_hash, 16) % (2 ** (8 * max_bytes))
这个函数确保即使在不同机器上运行,相同的输入也会产生相同的随机种子,保证结果可复现。
3.6 CALVIN 长程任务评估(eval_calvin/main.py)
CALVIN 评估针对长程多任务场景:
def evaluate_sequence(model, task_checker, initial_state,
eval_sequence, ...):
# 按顺序评估子任务,首次失败即停止
for subtask_i, subtask in enumerate(eval_sequence):
success = rollout(env, model, task_oracle, subtask, ...)
if success:
success_counter += 1
else:
break
图像预处理:
def random_crop(images, crop_ratio=0.98, center_crop=True):
h, w = image.size[1], image.size[0]
crop_h, crop_w = int(h * crop_ratio), int(w * crop_ratio)
if center_crop:
top = (h - crop_h) // 2
left = (w - crop_w) // 2
else:
top = np.random.randint(0, h - crop_h + 1)
left = np.random.randint(0, w - crop_w + 1)
cropped = IF.crop(image, top=top, left=left, height=crop_h, width=crop_w)
resized = IF.resize(cropped, size=(h, w))
return resized
使用中心裁剪(crop_ratio=0.95)去除图像边缘可能存在的干扰信息。
3.7 SimplerEnv 真实到模拟评估(eval_simplerenv/main.py)
SimplerEnv 评估需要处理不同数据集的坐标系差异:
Fractal 数据集预处理:
def preprocess_proprio_fractal(proprio: np.array) -> np.array:
# 将 Simpler 的 wxyz 四元数转换为 Fractal 的 xyzw 格式
gripper_quat_wxyz = proprio[3:7]
gripper_rotm = quat2mat(gripper_quat_wxyz)
gripper_xyzw = mat2quat(gripper_rotm)[[1, 2, 3, 0]]
# 夹爪状态:Simpler 用 [0, 1] 表示,0=关闭,1=打开
# 转换为闭合度表示
gripper_width = proprio[7]
gripper_closedness = 1 - gripper_width
return np.concatenate((proprio[:3], gripper_xyzw, [gripper_closedness]))
夹爪动作后处理:
def postprocess_gripper_fractal(action: float) -> float:
# 训练使用 [0, 1],0=关闭,1=打开
# 转换为 Simpler 的 [-1, 1],-1=关闭,1=打开
action = (action * 2) - 1 # [0, 1] -> [-1, 1]
relative_gripper_action = -action # 反转符号
return np.clip(relative_gripper_action, -1, 1)
4. 实验结果
4.1 模拟基准测试
LIBERO:该基准测试用于评估机械臂在模拟环境中的操作能力。Xiaomi-Robotics-0 在四个子集上取得平均 98.7% 的成功率,超越所有基线方法。其中在 Libero-Object 子集上达到 100% 成功率。
CALVIN:多任务学习和长程操作基准。在 ABCD→D 和 ABC→D 两种设置下,模型分别达到 4.80 和 4.75 的平均连续任务完成数,大幅领先此前最优方法 FLOWER(4.67 和 4.53)。
SimplerEnv:真实到模拟(real-to-sim)基准。在 Google Robot 评估的视觉匹配(Visual Matching)和视觉聚合(Variant Aggregation)设置下分别达到 85.5% 和 74.7% 的平均成功率;WidowX 评估达到 79.2%。
4.2 真实机器人实验
实验平台为配备两个 6-DoF 机械臂的双手机器人,使用三个摄像头进行观测。
乐高拆解任务:涉及将乐高结构拆解为单个积木并按颜色分类。在大装配(LA)和多装配(MA)两种设置下评估。虽然成功率与同步方法相当,但 Xiaomi-Robotics-0 在吞吐量(每小时正确分类的积木数)上显著领先,达到最高值。
毛巾折叠任务:需要从托盘拾取毛巾、展平、折叠两次并放置到暂存区。该任务具有挑战性,因为毛巾是柔性物体,其动态特性复杂且部分可观测。Xiaomi-Robotics-0 实现 1.2 件/分钟的吞吐量,优于 π0.5、Xiaomi-Robotics-0(同步)和训练 RTC 变体的 1.0 件/分钟。实验观察到,训练 RTC 变体在抓取多层毛巾时容易陷入重复循环,而 Xiaomi-Robotics-0 能够有效避免此类失败。
4.3 视觉语言能力保持
预训练后,模型在通用视觉语言基准和具身推理基准上的表现与底层 Qwen3-VL-4B-Instruct 相当。在 ERQA 基准上甚至小幅超越原始 VLM(40.8 vs 40.0),这归因于加入了来自机器人轨迹的视觉语言数据,增强了机器人中心图像的视觉感知。实验还表明,没有视觉语言数据监督的 VLA 模型会出现严重的灾难性遗忘,在大多数 VL 任务上接近零性能。
5. 核心贡献与创新点
5.1 技术创新
本文的核心贡献可归纳为以下几点:
大规模跨本体预训练:通过联合训练大规模机器人轨迹数据和视觉语言数据,赋予模型广泛的泛化能力,同时保持底层 VLM 的视觉语义知识。
异步执行的后训练技术:提出基于 Λ 形状注意力掩码的技术,有效解决动作前缀导致的策略反应性下降问题,实现平滑且反应灵敏的实时执行。
高效部署策略:通过精心设计的时间步对齐和推理窗口调度,在消费级 GPU 上实现 80ms 推理延迟的流畅实时执行。
5.2 工程实践
易于部署的架构设计:
- 基于 Hugging Face Transformers 生态,支持
AutoModel 和AutoProcessor 接口 - 开箱即用,只需一行代码即可加载模型:
AutoModel.from_pretrained("XiaomiRobotics/Xiaomi-Robotics-0") - 支持 Flash Attention 2 和混合精度,可在消费级 GPU(RTX 4090)上流畅运行
完善的评估基础设施:
- 覆盖 LIBERO、CALVIN、SimplerEnv 三大主流基准
- 提供标准化评估脚本和批量部署工具
- 支持分布式多 worker 并行评估
开源与可复现性:
- 完整开源模型权重(预训练 + 微调版本)
- 详细的部署文档和代码示例
- 透明的训练细节和超参数配置
6. 结论与展望
本文提出了 Xiaomi-Robotics-0,一个兼具高性能与平滑实时执行能力的视觉-语言-动作模型。该模型在大规模跨本体机器人轨迹和视觉语言数据上进行预训练,在后训练阶段开发了多项异步执行技术,实现了在消费级 GPU 上快速平滑的真实机器人运行。实验结果表明,所提方法在所有模拟基准上达到最优性能,并在两项需要精确灵巧双手操作的真实任务上实现了高成功率和强吞吐量。
从代码实现角度看,该项目展现了优秀的工程实践:清晰的模块划分、标准化的接口设计、完善的评估基础设施,以及易于部署的使用体验。这些工程细节对于学术研究的可复现性和实际应用的可落地性都至关重要。
未来工作将探索在更大规模、更多样化的机器人数据集上训练模型,并持续提升其在真实任务中的鲁棒性和泛化能力。
附录:快速上手
环境安装
# 克隆仓库
git clone https://github.com/XiaomiRobotics/Xiaomi-Robotics-0
cd Xiaomi-Robotics-0
# 创建环境
conda create -n mibot python=3.12 -y
conda activate mibot
# 安装依赖
pip install torch==2.8.0 torchvision==0.23.0 torchaudio==2.8.0
pip install transformers==4.57.1
pip install flash-attn==2.8.3 --no-build-isolation
模型推理示例
import torch
from transformers import AutoModel, AutoProcessor
# 加载模型
model_path = "XiaomiRobotics/Xiaomi-Robotics-0-LIBERO"
model = AutoModel.from_pretrained(
model_path,
trust_remote_code=True,
attn_implementation="flash_attention_2",
dtype=torch.bfloat16
).cuda().eval()
processor = AutoProcessor.from_pretrained(model_path, trust_remote_code=True, use_fast=False)
# 构建提示
language_instruction = "Pick up the red block."
instruction = (
f"<|im_start|>user\nThe following observations are captured from multiple views.\n"
f"# Base View\n<|vision_start|><|image_pad|><|vision_end|>\n"
f"# Left-Wrist View\n<|vision_start|><|image_pad|><|vision_end|>\n"
f"Generate robot actions for the task:\n{language_instruction} /no_cot<|im_end|>\n"
f"<|im_start|>assistant\n<cot></cot><|im_end|>\n"
)
# 准备输入
inputs = processor(
text=[instruction],
images=[image_base, image_wrist], # PIL.Image
videos=None,
padding=True,
return_tensors="pt",
).to(model.device)
inputs["state"] = torch.from_numpy(proprio_state).to(model.device, model.dtype).view(1, 1, -1)
inputs["action_mask"] = processor.get_action_mask("libero").to(model.device, model.dtype)
# 生成动作
with torch.no_grad():
outputs = model(**inputs)
action_chunk = processor.decode_action(outputs.actions, robot_type="libero")
启动评估服务器
# 单服务器
python deploy/server.py --model "XiaomiRobotics/Xiaomi-Robotics-0-LIBERO" --port 10086
# 批量部署(多 GPU)
./scripts/deploy.sh "XiaomiRobotics/Xiaomi-Robotics-0-LIBERO" 4 2
# 参数:模型路径、端口数量、GPU 数量
参考文献
本文涉及的主要相关工作包括:OpenVLA、π0、π0.5、GR00T-N1、UniVLA、FLOWER、EO-1 等 VLA 模型,以及 DROID、MolmoAct、RT-1 等机器人数据集。具体技术基础包括:Flow-Matching(扩散 Transformer)、Real-Time Chunking(RTC)、Mixture-of-Transformers(MoT)架构等。