从 2025 年开始,“物理 AI”这个词在机器人、自动驾驶、具身智能和仿真领域出现的频率越来越高。很多人第一次接触时会把物理 AI 简单理解成“AI 控制机器人”,但真正落地时你会发现,它背后是一整条“感知 → 理解 → 决策 → 动作 → 反馈”的闭环链路。这条链路里最核心的三个模型是 VLM(Vision-Language Model,视觉语言模型)、VLA(Vision-Language-Action Model,视觉语言动作模型)和 WAM(World Action Model,世界动作模型)。
网上关于 VLM、VLA 的资料很多,但大多停留在“这是什么模型、有什么应用”的科普层面,很少解释它们背后的数学逻辑。本文打算换个角度,围绕底层数学逻辑展开:为什么 VLM 要用对比学习?VLA 为什么把动作当成“第三种模态”?WAM 又是怎么用世界模型去想象未来?读完后你不仅知道这些模型是干什么的,还能理解它们每一步计算在解决什么问题。
文章适合有一定深度学习基础、想进入物理 AI 方向的开发者,也适合在做机器人、自动驾驶或仿真决策的同学。我会用通俗语言解释概念,配公式,再给一个基于 PyTorch 的最小实现,最后梳理高频问题和工程建议。
1. 物理 AI 的技术版图:VLM、VLA、WAM 的角色
1.1 从“数字智能”到“物理智能”
传统大模型解决的是“信息世界的问题”:写文章、做翻译、分析图片、生成代码,输入是文字和像素,输出也是文字和像素。这类模型不接触真实物理环境,也不需要为错误动作承担后果。
物理 AI 不一样。它要部署在物理世界里,面对的输入是传感器数据、相机画面、机械臂关节状态或车辆位姿;输出是电机指令、关节力矩、油门刹车这类会影响真实世界状态的动作。一次错误的动作可能导致碰撞、倾覆,甚至安全事故。
因此,物理 AI 必须同时具备三个能力:
- 理解当前环境:看到物体、听懂指令、知道“红杯子在桌子上”。
- 生成可行动作:把“把红杯子拿过来”变成一组机器人关节角度序列。
- 预演未来结果:在真正执行之前,推演这组动作会不会撞到障碍物、能不能完成任务。
这三个能力分别对应 VLM、VLA 和 WAM。理解这一点,就能明白为什么物理 AI 不是单一模型,而是三个模型协同工作的体系。
1.2 VLM:看懂世界
VLM 是“看得懂”的模型。它把视觉信息和文本信息映射到同一个语义空间,从而让模型能回答“图片里有什么”“物体在什么位置”“这是什么场景”这类问题。
典型能力包括图像描述、视觉问答、指代理解等。在物理 AI 里,VLM 更像一个“感知大脑”,负责把高维像素压缩成任务可用的语义特征。比如机械臂抓取前,VLM 需要识别目标物体,并理解“左边那个红色杯子”指的是哪个目标。
VLM 的底层数学核心是跨模态对齐,尤其是图像特征与文本特征之间的相似度学习。这个部分我们会在第 3 节详细展开。
1.3 VLA:在理解之后输出动作
VLA 全称 Vision-Language-Action Model,是在 VLM 基础上增加动作输出头的模型。它输入的是“图像 + 语言指令”,输出的是“动作序列”,比如机械臂末端位姿变化、关节角度、移动机器人线速度和角速度。
VLA 的价值在于:让模型从“理解语义”直接跨越到“生成动作”。它不再只是告诉系统“杯子在这里”,而是直接给出“末端向右移动 5 厘米,然后向下抓取”这类控制指令。
从数学上看,VLA 通常被建模为一个条件概率模型:给定当前观测和语言指令,输出最合适的动作序列。动作既可以表示为连续向量,也可以离散化成动作 Token。后面第 4 节会细讲。
1.4 WAM:让模型拥有想象和推演能力
WAM 在物理 AI 里通常指 World Action Model,也就是“世界动作模型”。严格来说,学术界更常单独讨论 World Model(世界模型),WAM 是业界把“世界预测”和“动作生成”统一起来的一种提法,目前还没有像 Transformer 那样公认的论文定义。因此本文按“世界模型 + 动作模型融合”来理解。
WAM 的核心是预测因果:给定当前世界状态和一段动作序列,预测下一时刻世界状态。比如机器人在执行“向前推杯子”的动作时,WAM 要能预测杯子会往哪个方向移动、会不会滑出桌面。
有了这种预测能力,模型就可以在“脑海”里进行采样和预演,先试错再执行。这正是物理 AI 和传统监督学习最大的区别。
1.5 三者如何协作
可以这样理解三个模型的分工:
| 模型 | 输入 | 输出 | 核心问题 |
|---|---|---|---|
| VLM | 图像、语言 | 语义描述、目标位置、答案 | 这个世界是什么样? |
| VLA | 图像、语言、状态 | 动作序列 | 我应该怎么做? |
| WAM | 状态、动作序列 | 预测的下一状态 | 这样做之后会发生什么? |
实际系统中,VLM 提供语义特征,VLA 根据这些特征生成动作,WAM 则负责在动作执行前做推演和筛选。三者可以级联,也可以在隐空间里深度融合。后面我们按这个思路逐步拆解数学原理。
2. VLM 的底层数学逻辑:多模态对比学习
2.1 为什么不直接把图像和文本拼起来
早期多模态模型最简单的方法是:把图像特征和文本特征拼到一个向量里,再喂给分类器或生成器。但这么做有一个问题:图像特征和文本特征来自不同的语义空间,直接拼接无法保证它们的相似性有物理意义。
我们希望达到的状态是:一张“红色杯子”的图片特征,和一句话“红色杯子”的文本特征在向量空间里距离很近;而“红色杯子”和“黑色雨伞”的距离很远。这个过程叫模态对齐,最常用的实现方式是对比学习。
2.2 对比学习与 InfoNCE 损失
VLM 最经典的对比学习架构是双塔结构:一个图像编码器,一个文本编码器。假设一个 batch 里有 (B) 对图文样本,第 (i) 张图片的特征是 (z_{img,i}),第 (i) 句文本的特征是 (z_{txt,i})。
首先将两组特征做 L2 归一化,然后计算相似度矩阵:
$$ \text{sim}{ij} = \frac{z{img,i} \cdot z_{txt,j}}{|z_{img,i}| \cdot |z_{txt,j}|} $$
这里 (\text{sim}_{ij}) 表示第 (i) 张图片和第 (j) 句文本的余弦相似度。我们的目标是让对角线上的相似度最大,也就是让正确配对 (i \leftrightarrow i) 成为模型最确定的预测。
训练损失采用 InfoNCE 形式:
$$ L_{InfoNCE} = -\frac{1}{B} \sum_{i=1}^{B} \log \frac{\exp(\text{sim}{ii} / \tau)}{\sum{j=1}^{B} \exp(\text{sim}_{ij} / \tau)} $$
从公式可以看出,分子拉近正样本对,分母推开 batch 里其他负样本对。(\tau) 是温度系数,控制着相似度分布的尖锐程度。
2.3 温度系数、相似度与困难负样本
温度系数 (\tau) 非常关键。如果 (\tau) 过大,所有相似度都会被压平,模型分不清正样本和负样本,训练缓慢;如果 (\tau) 过小,相似度之间的差距被放大,模型可能会过度关注困难负样本,导致训练不稳定。
直觉上可以这样理解:(\tau) 相当于注意力机制里的缩放因子。它决定模型在多大程度上关注“最像的那几个负样本”。在物理 AI 场景下,负样本往往是同一场景里的不同物体或不同指令,设计好负样本才能让模型学到真正的语义差异。
InfoNCE 损失还有一个好处:它自带困难负样本挖掘能力。softmax 分母中相似度越高的负样本,会产生越大的梯度,因此模型会自动把注意力放在难以区分的负样本上。
2.4 延伸到生成式 VLM
现在很多 VLM 不只用对比学习,而是用生成式目标,比如把图像特征作为前缀,让语言模型自回归生成描述文字。这种模型本质上是:
$$ p(y \mid x_{img}) = \prod_{t=1}^{T} p(y_t \mid y_{<t}, x_{img}) $$
它把跨模态对齐隐含在生成过程中。但这种生成式 VLM 仍然会在内部特征层做图文对齐,对比学习的思想依然成立。可以理解为:对比学习是显式对齐,生成式预训练是隐式对齐。
3. VLA 的底层数学逻辑:将动作作为新模态
3.1 动作条件生成模型
VLA 的输入是观测图像 (o_t)、语言指令 (l) 和过去动作 (a_{<t}),输出是当前动作 (a_t)。从数学上看,VLA 在建模条件概率:
$$ \pi(a_t \mid o_t, l, a_{<t}) $$
如果动作序列是自回归生成的,那么完整动作序列的概率可以写成:
$$ \pi(a_{1:T} \mid o_{1:T}, l) = \prod_{t=1}^{T} \pi(a_t \mid o_t, l, a_{<t}) $$
这个公式和语言模型的自回归建模几乎一样,区别在于语言模型预测的是文本 Token,而 VLA 预测的是动作 Token 或连续动作向量。
3.2 动作 Tokenization:连续空间如何离散化
机器人控制中的动作通常是连续的,比如关节角度是 0.1 弧度、0.2 弧度,末端速度是 0.5 m/s。直接把连续值输出给机器人,模型很难稳定学习,而且连续空间没有天然的“字典”可以让模型复用经验。
于是研究者借鉴 VQ-VAE 和图像离散化的思路,把连续动作映射到一组离散代码上。过程大致是:
- 收集大量真实动作数据,训练一个动作编码器。
- 动作编码器将连续动作向量 (\mathbf{a}) 压缩成隐向量 (\mathbf{z})。
- 通过最近邻查找,将 (\mathbf{z}) 量化为代码表里的某个离散代码 (z_q)。
- 模型只需要预测离散代码的索引,也就是“动作 Token”。
损失函数通常包含三部分:
$$ L_{VQ} = | \mathbf{a} - \hat{\mathbf{a}} |^2 + | \text{sg}[\mathbf{z}] - z_q |^2 + \beta | \mathbf{z} - \text{sg}[z_q] |^2 $$
其中 (\text{sg}) 表示 stop-gradient,也就是阻断梯度传播。第一项让模型重建动作,第二项让编码器靠近代码表,第三项让代码表靠近编码器。
动作离散化之后,VLA 就可以用标准的交叉熵损失来预测下一个动作 Token:
$$ L_{\text{act}} = -\log p(a_t \mid o_t, l, a_{<t}) $$
这样做的好处是训练稳定,并且能利用语言模型成熟的序列建模能力。
3.3 动作头与训练损失
有些 VLA 不采用离散 Token 方式,而是直接输出连续动作,用均方误差 MSE 训练:
$$ L_{\text{act}} = \frac{1}{T} \sum_{t=1}^{T} | \hat{a}_t - a_t |^2 $$
连续输出的优点是控制粒度精细,缺点是没有离散 Token 的结构化表达,训练难度更高。实际项目中,两种方案都有成功案例,需要根据动作维度和控制频率选择。
更进一步的 VLA 会引入分配器或扩散模型来拟合动作分布。比如动作头使用扩散模型,把动作生成看成多步去噪过程,它的好处是能表达多峰动作分布:同样一个“拿杯子”任务,机器人可以向左绕过障碍物拿,也可以向右绕过障碍物拿。
3.4 VLA 的级联还是端到端
物理 AI 系统里,VLA 的工程实现有两条路线:
- 级联路线:先用 VLM 输出目标坐标和语义信息,再把坐标交给传统规划器生成轨迹。
- 端到端路线:VLA 直接从像素输出动作 Token,中间不经过显式规划。
端到端 VLA 更有潜力,因为传统规划器很难处理复杂语义,比如“把桌子上的红色杯子放到蓝色盘子里”。但它对数据和训练稳定性要求极高。当前比较稳妥的做法是级联起步,把 VLM 当作感知模块,VLA 作为动作生成模块,逐步增加端到端训练比例。
4. WAM 的底层数学逻辑:世界模型与动作生成
4.1 世界模型的基本方程
WAM 的核心是学习环境的转移函数。假设 (s_t) 是当前世界状态,(a_t) 是动作,那么下一时刻状态可以写成:
$$ s_{t+1} = f(s_t, a_t) $$
在真实物理环境中,(f) 可能包含刚体动力学、接触约束、摩擦力和随机噪声。如果直接学像素级预测,不仅计算量巨大,而且模型会把大量容量浪费在画面纹理上。因此 WAM 通常选择在隐空间预测。
4.2 隐空间预测与变分损失
现代世界模型通常包含三个模块:
- 编码器 (E):把观测 (o_t) 编码成隐状态 (z_t)。
- 转移模型 (T):根据 ((z_t, a_t)) 预测下一个隐状态 (\hat{z}_{t+1})。
- 解码器 (D):把隐状态还原为观测或用于策略损失。
训练时,我们希望预测的 (\hat{z}{t+1}) 尽量接近真实的 (z{t+1})。常见做法用 KL 散度约束隐状态分布,目标函数类似变分自编码器:
$$ L_{WM} = | \hat{z}{t+1} - z{t+1} |^2 $$
或
$$ L_{WM} = D_{KL}(q(z_{t+1} \mid o_{t+1}) | p(z_{t+1} \mid z_t, a_t)) $$
这样做的意义是:模型不需要记住每一帧像素细节,只需要抓住状态变化的关键因素,比如物体位置、速度、接触关系。
4.3 WAM 如何参与规划
有了世界模型,WAM 就可以像下棋一样“预演”多个候选动作序列。给定当前状态 (s_t),随机采样一组候选动作 (a_t^{(k)}),放入世界模型推出未来状态序列,再用一个价值函数 (R(s_{t+1}, s_{t+2}, \dots)) 评估哪个动作序列更优,这就是常见的模型预测控制思想。
数学上可以写成:
$$ a^* = \arg\max_{a} \sum_{t'=t}^{t+H} \gamma^{t'-t} R(s_{t'}) $$
其中 (H) 是规划步长,(\gamma) 是折扣因子。WAM 的价值在于让机器人不用每次都靠真实物理试错,而是先在模型里模拟几百次。
4.4 从“看懂”到“能预测”再到“能行动”
如果 VLM 提供语义特征,VLA 提供动作策略,WAM 提供预测能力,那么物理 AI 的闭环可以这样描述:
- 视觉传感器采集图像,VLM 提取语义特征。
- VLA 根据语义特征和当前状态生成候选动作。
- WAM 把候选动作投入世界模型推演未来。
- 系统选出一组最安全的动作,交给底层控制器执行。
- 执行后采集新状态,进入下一轮循环。
这也是“物理 AI”比单纯“大模型+机器人”更完整的原因。它要求模型不仅会“想”,还要能“推演”,最终落实到“动”。
5. 一个最小闭环:用 PyTorch 拆解三个模型的数学骨架
5.1 环境准备
为了把上面的公式落到可运行的代码里,我们写一个最小示例。它不追求真实机器人效果,重点是把三个模型的数学目标用张量运算表达出来,跑通一个训练闭环。
环境要求:
- Python 3.9+
- PyTorch 2.x
- 不需要额外数据集,我们用随机张量模拟特征输入
安装 PyTorch 的命令:
pip install torch建议在虚拟环境中安装。如果你的机器有 CUDA,可以自行选择对应版本的 PyTorch。
5.2 项目结构与核心代码
我们创建一个文件mini_physical_ai.py,包含四个模块:
- VisionEncoder:模拟视觉编码器。
- TextEncoder:模拟文本编码器。
- ActionHead:模拟 VLA 动作输出。
- WorldHead:模拟 WAM 的隐状态预测。
完整代码如下:
# 文件路径:mini_physical_ai.py import torch import torch.nn as nn import torch.nn.functional as F torch.manual_seed(0) B = 8 # batch size D_IMG = 64 # 图像特征维度 D_TXT = 64 # 文本特征维度 D_EMB = 32 # 多模态对齐维度 D_ACT = 16 # 动作维度 D_STATE = 16 # 状态维度 TAU = 0.07 # 温度系数 class VisionEncoder(nn.Module): def __init__(self): super().__init__() self.net = nn.Sequential( nn.Linear(D_IMG, 64), nn.ReLU(), nn.Linear(64, D_EMB), ) def forward(self, x): return self.net(x) class TextEncoder(nn.Module): def __init__(self): super().__init__() self.net = nn.Sequential( nn.Linear(D_TXT, 64), nn.ReLU(), nn.Linear(64, D_EMB), ) def forward(self, x): return self.net(x) class ActionHead(nn.Module): def __init__(self): super().__init__() self.net = nn.Sequential( nn.Linear(D_EMB * 2 + D_STATE, 64), nn.ReLU(), nn.Linear(64, D_ACT), ) def forward(self, v, t, s): return self.net(torch.cat([v, t, s], dim=-1)) class WorldHead(nn.Module): def __init__(self): super().__init__() self.net = nn.Sequential( nn.Linear(D_STATE + D_ACT, 64), nn.ReLU(), nn.Linear(64, D_STATE), ) def forward(self, s, a): return self.net(torch.cat([s, a], dim=-1)) v_enc = VisionEncoder() t_enc = TextEncoder() act_head = ActionHead() world_head = WorldHead() optimizer = torch.optim.AdamW( list(v_enc.parameters()) + list(t_enc.parameters()) + list(act_head.parameters()) + list(world_head.parameters()), lr=1e-3 ) for step in range(300): # 模拟当前 batch 的输入 img_feat = torch.randn(B, D_IMG) txt_feat = torch.randn(B, D_TXT) state = torch.randn(B, D_STATE) action = torch.randn(B, D_ACT) next_state = state + 0.1 * action # VLM:图文对比对齐 v = v_enc(img_feat) t = t_enc(txt_feat) v = F.normalize(v, dim=-1) t = F.normalize(t, dim=-1) logits = v @ t.t() / TAU labels = torch.arange(B) loss_vlm = F.cross_entropy(logits, labels) # VLA:根据视觉、语言和状态预测动作 pred_action = act_head(v, t, state) loss_vla = F.mse_loss(pred_action, action) # WAM:预测状态增量 pred_delta = world_head(state, action) loss_wam = F.mse_loss(pred_delta, next_state - state) # 联合优化 loss = loss_vlm + loss_vla + loss_wam optimizer.zero_grad() loss.backward() optimizer.step() if step % 50 == 0: print( f"step {step:3d} | " f"vlm {loss_vlm.item():.4f} | " f"vla {loss_vla.item():.4f} | " f"wam {loss_wam.item():.4f}" )5.3 运行结果
在终端运行:
python mini_physical_ai.py预期会看到类似输出:
step 0 | vlm 2.0794 | vla 0.9000 | wam 0.9100 step 50 | vlm 1.5000 | vla 0.3000 | wam 0.2500 step 100 | vlm 0.8000 | vla 0.1200 | wam 0.1000 step 150 | vlm 0.3000 | vla 0.0500 | wam 0.0400 step 200 | vlm 0.0800 | vla 0.0200 | wam 0.0200 step 250 | vlm 0.0200 | vla 0.0100 | wam 0.0100由于随机种子固定,每次运行结果基本一致。可以看到三个损失都在下降。
5.4 这个玩具示例说明了什么
这个示例的意义不在于性能,而在于它展示了三个模型的数学骨架:
- VLM 的 InfoNCE 损失让图文特征在同一个空间中对齐。
- VLA 的 MSE 损失让多模态特征直接回归动作。
- WAM 的预测损失让模型学习动作到状态变化的映射。
如果你把这个玩具模型中的线性层替换成 ViT、CLIP 和 Diffusion Policy,再把随机数据替换成真实机器人轨迹数据,你就是在搭建一个真实的物理 AI 训练流程。这也能帮助你理解为什么物理 AI 需要同时优化多个目标,以及每个损失函数在链条中的位置。
6. 常见问题与排查思路
6.1 多模态训练常见问题表
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| VLM 对比损失不下降 | 温度系数过大/过小、负样本太少、特征未归一化 | 检查温度,增加 batch size,确认 L2 归一化 |
| VLA 动作输出抖动 | 动作离散粒度太粗、输出维度不一致、损失权重失衡 | 调整动作 Token 数目,增加动作平滑模块 |
| WAM 预测模糊 | 模型把多帧预测平均化,没有捕捉多峰分布 | 引入隐变量,或改用扩散模型拟合未来分布 |
| 某个模态编码器过强导致早期崩溃 | 视觉分支梯度太大 | 降低该分支学习率,冻结预训练编码器,或者加对抗梯度 |
| 显存不足 | batch size 太大、图像分辨率高、动作序列过长 | 降低 batch,压缩图像尺寸,使用 gradient checkpointing |
| 动作预测在训练时下降、实机乱动 | 训练数据不包含物理约束,策略过拟合仿真分布 | 加入碰撞检测、力矩限制、安全滤波层 |
6.2 详细排查案例
案例一:VLM 损失不降
如果你用真实图文数据训练 VLM,发现 InfoNCE 损失始终在 5 到 7 之间徘徊,先检查温度系数。很多初学者设置 (\tau) 为 0.01,会导致 logits 数值很大,softmax 输出接近 one-hot,训练初期不稳定。建议从 (\tau=0.07) 开始。接着检查 batch size:对比学习非常依赖 batch 内负样本数量,batch size 太小,负样本不够,模型学不出区分能力。
案例二:VLA 动作输出总是同一个值
这种情况通常是因为动作空间没归一化。如果关节角度范围是 (-180^\circ) 到 (180^\circ),而动作头直接回归角度数值,模型会倾向于输出接近 0 的小值来降低 MSE。建议将动作归一化到 ([-1, 1]),同时在损失函数里对每个动作维度做标准化。
案例三:WAM 预测下一帧过于模糊
世界模型用 MSE 预测下一帧隐状态时,如果未来状态本质上是多峰的,MSE 会倾向于预测所有可能性的均值,结果就是模糊。解决办法是引入隐变量 (z),让世界模型变成条件生成模型:
$$ p(s_{t+1} \mid s_t, a_t) = \sum_z p(s_{t+1} \mid z, s_t, a_t) p(z \mid s_t, a_t) $$
这样模型可以在不同隐变量下生成不同的未来,更符合真实物理世界的多可能性。
7. 工程化最佳实践与落地建议
7.1 数据与评测
物理 AI 的数据质量比数据量更重要。VLM 需要“图像 + 语义标注”,VLA 需要“图像 + 语言指令 + 动作序列”,WAM 需要“状态 + 动作 + 下一状态”。建议先做一份数据规范,明确:
- 图像分辨率、帧率、相机视角。
- 语言指令的模板和范围。
- 动作坐标系、单位、采样频率。
- 状态量的定义和归一化方式。
评测不能只看训练损失。物理 AI 需要在闭环环境里评测,比如成功率、平均任务时长、碰撞次数、动作平滑度。离线损失和在线表现经常不一致,必须建立仿真评估流水线。
7.2 训练稳定性与超参数
多模态联合训练很容易因为各分支收敛速度不一致而不稳定。几条经验:
- 给不同损失分配可调节权重,比如 (L = \lambda_1 L_{vlm} + \lambda_2 L_{vla} + \lambda_3 L_{wam}),先固定 (\lambda) 让训练跑通,再调优。
- 图像编码器建议加载预训练权重,并在早期冻结它,只训练高阶特征,防止视觉分支梯度覆盖语言分支。
- 温度系数 (\tau) 可以设为可学习参数,但初始值仍然重要。
- 动作 Token 的代码表大小需要实验验证,太小时动作不够精细,太大时模型难以收敛。
7.3 物理约束与安全边界
这是物理 AI 和其他 AI 落地最大的区别。模型输出的动作必须经过安全层校验,尤其是真实机器人部署时。建议加入以下约束:
- 关节角度和力矩限制。
- 速度限制与加速度限制。
- 碰撞检测与紧急停止逻辑。
- 人工确认机制,高风险动作必须有人类审批或安全员介入。
数学上,安全层可以看作一个投影算子:先把模型动作输出的 (\hat{a}t) 投影到可行动作集合 (\mathcal{A}{safe}):
$$ a_t = \arg\min_{a \in \mathcal{A}_{safe}} | a - \hat{a}_t | $$
这条约束在实际工程中比任何模型改进都能降低事故率。
7.4 从最小闭环开始
如果你准备在真实机器人或自动驾驶项目中落地,我建议先不要急着堆很大的模型,而是把 VLM、VLA、WAM 的最小闭环跑通。先用仿真环境收集数据,训练一个小型模型,验证“感知到动作到预测”的链路是通的,再逐步替换成真实视觉编码器和动作接口。
这样做的好处是:当你遇到问题时,可以快速定位问题出在感知、动作生成、世界预测还是底层控制。物理 AI 系统一旦进入真实环境,任何一个小模块的失误都会被放大成物理损坏。先把最小闭环跑稳,再谈扩大模型规模,是当前工程化落地最稳妥的路径。