【论文阅读+代码梳理】Multimodal Diffusion Transformer: Learning Versatile Behavior from Multimodal Goals
一、论文阅读
借助deepseek和豆包,对此表示感谢。
1.1 摘要
问题:现有的绝大多数模仿学习的方法只从个别的目标模态中学习,例如语言和图像。但是现有的大规模模仿学习数据集仅部分标注了语言标注,是的现有方法无法充分利用这些数据集中学习语言条件化行为。
解决方案:MDT引入在多模态目标指令上同时训练的潜在目标条件状态表示来解决。CLIP将图像和语言的目标嵌入对齐,通过两个自监督辅助任务进行训练,让目标嵌入能够编码足够的信息预测未来状态。
效果:在包含不到2%的语言注释的数据集任务中表现出右移的性能,展示了从稀疏标注中解决长时操纵的能力。
创新点:
- 提出了一种新的基于Transformer的扩散方法,Multimodal Diffusion Transformer,从多模态目标中学习。具体来说,CLIP对多模态目标信息(语言指令/未来20-50帧的图像)编码,Voltron&Perceiver/ResNet18对当前的图像(第三视角静态图像、机械臂腕部图像)进行编码,将编码得到的token concat然后输入到Multimodal TransformerEncoder中进行编码得到条件上下文token能包含当前状态和未来信息,用MGF和CLA两个自监督任务提升token的信息的完整性。一个是GPT-Dffusion Policy,输入是noisy actions tokens和上下文编码,noisy action token进行自注意力学习序列中动作连贯性,与条件上下文编码进行cross attention结合现有状态和目标状态信息得到符合目标要求的动作序列,且在 scale & shift 及 scale 环节融入噪声编码以优化去噪精度。
- 设计了MGF和CLA两个自监督损失,提升了从稀疏标注数据集中进行多任务学习行为的性能。具体来说MGF是通过mask未来图像部分区域,训练模型基于多模态目标编码的潜在表示重建被遮挡区域,学习目标导向的未来状态预测能力。CLA通过对比学习对齐图像目标与语言目标对应的latent表示,让不同模态目标映射到统一的特征空间,确保跨模态信息的一致性。
- 一个全面的实证研究覆盖了多个基准测试的184个不同的任务,验证了MGF和MDT的性能和有效性。
1.2 方法
1.2.1 任务定义
在理解公式前,必须先对应选中内容里的核心变量——这些变量是公式的“语言”:
| 符号 | 选中内容中的定义 |
|---|---|
| πθ\pi_{\theta}πθ | 目标条件策略(模型核心),输入“当前状态+多模态目标”,输出“动作序列的概率分布”。 |
| a‾i\overline{a}_iai | 真值动作序列(长度为kkk),比如“推滑块→握取→放水槽”的连续kkk步真实动作。 |
| sis_isi | 当前状态嵌入(来自机器人摄像头的图像特征,比如“滑块在左侧、手在中间”的视觉信息)。 |
| ggg | 多模态目标(仅两种:g=og=og=o是“目标图像”,如“滑块在右侧”的图;g=lg=lg=l是“语言指令”,如“把滑块推到右边”)。 |
| DDD | play数据集(机器人自由交互产生的无结构化数据),每个样本是(si,a‾i)(s_i, \overline{a}_i)(si,ai)(当前状态+真值动作序列)。 |
| Gsi,a‾iG_{s_i,\overline{a}_i}Gsi,ai | 每个样本的“可用目标集合”:包含oio_ioi(未来状态图像,从当前状态往后20-50步采样)和lil_ili(稀疏语言标注,存在则有,不存在则仅用oio_ioi)。 |
公式本质是 “让模型在所有样本、所有可用目标下,预测出‘真值动作序列’的概率尽可能高” ,写法上通过“期望+双重求和+对数似然”实现这个目标,具体拆解如下:
Lplay=E[∑(si,a‾i)∈D∑g∈Gsi,a‾ilogπθ(a‾i∣si,g)⏟核心:模型对真值动作的置信度⏟遍历所有样本⏟遍历每个样本的所有目标]⏟保证泛化性:对所有数据取期望\underbrace{\mathcal{L}_{play }=\mathbb{E}\left[ \underbrace{\sum_{\left(s_{i}, \overline{a}_{i}\right) \in \mathcal{D}} \underbrace{\sum_{g \in \mathcal{G}_{s_{i}, \overline{a}_{i}}} \underbrace{log \pi_{\theta}\left(\overline{a}_{i} | s_{i}, g\right)}_{核心:模型对真值动作的置信度}}_{遍历所有样本} }_{遍历每个样本的所有目标} \right]}_{保证泛化性:对所有数据取期望}保证泛化性:对所有数据取期望Lplay=E遍历每个样本的所有目标(si,ai)∈D∑遍历所有样本g∈Gsi,ai∑核心:模型对真值动作的置信度logπθ(ai∣si,g)
1. 最内层:logπθ(a‾i∣si,g)log \pi_{\theta}\left(\overline{a}_{i} | s_{i}, g\right)logπθ(ai∣si,g) —— 模型对“真值动作序列”的置信度
这是公式的核心项,需要先理解 πθ(a‾i∣si,g)\pi_{\theta}\left(\overline{a}_{i} | s_{i}, g\right)πθ(ai∣si,g) 的含义:
- πθ(A∣B)\pi_{\theta}(A|B)πθ(A∣B) 是“条件概率”:表示“在给定BBB(当前状态sis_isi+目标ggg)的情况下,模型预测出动作序列AAA(这里是真值动作序列overlineaioverline{a}_ioverlineai)的概率”。
- 例子:给定“当前滑块在左(sis_isi)”和“目标是滑块在右(g=og=og=o)”,模型预测出“推滑块→握取→放右侧”(a‾i\overline{a}_iai)的概率。
- 加logloglog的原因:
- 数学上:logloglog是单调递增函数,“最大化logPlog PlogP”等价于“最大化PPP”(避免直接最大化概率时的数值下溢);
- 直观上:logπθ(...)log \pi_{\theta}(...)logπθ(...) 的值越大,说明模型在“当前状态+目标”下,对“真值动作序列”的置信度越高(越确定“这就是该做的动作”)。
2. 中层求和1:∑g∈Gsi,a‾i\sum_{g \in \mathcal{G}_{s_{i},\overline{a}_{i}}}∑g∈Gsi,ai —— 遍历每个样本的“所有可用目标”
选中内容明确:每个样本的目标集合(G)(G)(G)包含“图像目标(oi)(o_i)(oi)”和“语言目标(li)(l_i)(li)”((li(l_i(li)仅稀疏存在)。
这个求和的目的是让模型同时适配两种目标模态:
- 如果样本有语言标注((li)(l_i)(li)存在):模型需要用“(si+li)(s_i + l_i)(si+li)”和“(si+oi)(s_i + o_i)(si+oi)”两种条件,分别预测(a‾i)(\overline{a}_i)(ai),并都让置信度高;
- 如果样本无语言标注((li)(l_i)(li)不存在):仅用“(si+oi)(s_i + o_i)(si+oi)”预测(a‾i)(\overline{a}_i)(ai),保证稀疏标注数据也能利用。
例子:某样本有“滑块推到右”的语言指令((li)(l_i)(li))和“滑块在右”的图像((oi)(o_i)(oi)),求和会让模型同时计算“用语言指令预测真值动作的置信度”和“用图像目标预测真值动作的置信度”,并都纳入优化。
3. 中层求和2:∑(si,a‾i)∈D\sum_{\left(s_{i}, \overline{a}_{i}\right) \in \mathcal{D}}∑(si,ai)∈D —— 遍历play数据集中的“所有样本”
选中内容提到(D)(D)(D)是“任务无关的play轨迹”(机器人自由交互产生的海量无结构化数据),这个求和的目的是让模型在所有数据上都泛化良好,避免只在少数样本上表现好。
比如:数据集里有“推滑块”“开微波炉”“放香蕉”等不同任务的样本,求和会让模型在所有这些任务的样本上,都满足“目标→真值动作”的高置信度。
4. 最外层:E[...]\mathbb{E}\left[ ... \right]E[...] —— 对所有数据取“期望”
(E)(\mathbb{E})(E)(数学期望)是对“双重求和结果”的进一步优化:
- 直观理解:避免模型“偏向某类样本/某类目标”(比如只在“推滑块”样本上表现好,在“开微波炉”样本上差);
- 实现方式:训练时随机采样数据集(D)(D)(D)的批次,用批次的“双重求和结果”近似整个数据集的期望,保证模型对所有数据的平均表现最优。
1.2.2 模型框架

编码器部分首先处理当前图像观测和期望的多模态目标的令牌,将这些输入转换为一系列的潜在表示令牌。具体来说,在图像编码方面有两种,一种MDT-V (冻结Voltron嵌入的变体)和MDT (默认为深度残差网络的模型),MDT-V每幅图像通过Voltron编码到196个token中,然后通过Perceiver module通过交叉注意力压缩为3个token。MDT使用ResNet18为每个图像返回一个token。两种类型的编码器都是通过冻结的CLIP模型将图像和文本的goal编码成一个token合起来作为Multimodel Transformer-Encoder的输入,经过自注意力transformer层产生一组信息丰富的潜在表示Token。
解码器的功能是作为一个扩散器,对未来的动作序列进行去噪。具体来说是输入加噪的动作序列,经过自注意力和与编码的条件信息token进行交叉注意力进行去噪,为了让模型能够感知噪声强弱使用不同的归一化参数也就是layernormer中的γ\gammaγ和β\betaβ,实现对不同噪声强度的适配,使用AdaLN调节。
1.2.3 基于分数的扩散策略
“基于分数的扩散策略”是MDT实现“从噪声中生成稳定动作序列”的核心方法,本质是**“先给真实动作加噪,再让模型学习‘去噪指南’,最终用这个指南从纯噪声中生成符合目标的动作”**。
其中的关键是“分数”——指“分数函数(score function)”,它是模型的“去噪指南”,告诉模型“往哪个方向调整,才能把带噪声的动作恢复成真实动作”。
1.2.3.1 理论
1. 核心1:分数函数——模型要学的“去噪指南”
选中内容第一句明确:扩散模型的目标是近似分数函数
∇a‾ilogpt(a‾i∣si,g)\nabla_{\overline{a}_{i}} log p_{t}(\overline{a}_{i} | s_{i}, g)∇ailogpt(ai∣si,g)
- 逐符号通俗解释:
- ∇a‾i\nabla_{\overline{a}_i}∇ai:对“动作序列a‾i\overline{a}_iai”求梯度(可以理解为“方向”,比如“动作应该往左调还是往右调”);
- logpt(a‾i∣si,g)log p_t(\overline{a}_i | s_i, g)logpt(ai∣si,g):在“当前状态sis_isi+多模态目标ggg”下,带噪声动作序列a‾i\overline{a}_iai在ttt时刻的“对数概率”(值越大,说明这个带噪声动作越接近真实动作);
- 整体含义:分数函数是“带噪声动作序列a‾i\overline{a}_iai的对数概率对动作本身的梯度”——本质是“去噪方向”:沿着这个梯度方向调整带噪声动作,就能逐步接近真实动作。
举个例子:假设真实动作是“推滑块向右10cm”,加噪后变成“推滑块向右3cm”,分数函数会给出“再向右调7cm”的方向指南。
2. 核心2:分数匹配损失(LSM\mathcal{L}_{SM}LSM)——教模型学“去噪指南”
选中内容中的公式(4)是训练模型学习分数函数的“标尺”,它通过“让模型预测的去噪动作尽可能接近真实动作”,间接学会分数函数:
LSM=Eσ,a‾i,ϵ[α(σt)∥Dθ(a‾i+ϵ,si,g,σt)−a‾i∥22]\mathcal{L}_{SM}=\mathbb{E}_{\sigma, \overline{a}_{i}, \epsilon}\left[\alpha\left(\sigma_{t}\right)\left\| D_{\theta}\left(\overline{a}_{i}+\epsilon, s_{i}, g, \sigma_{t}\right)-\overline{a}_{i}\right\| _{2}^{2}\right]LSM=Eσ,ai,ϵ[α(σt)∥Dθ(ai+ϵ,si,g,σt)−ai∥22]
- 逐部分拆解(结合选中内容):
① 输入:Dθ(a‾i+ϵ,si,g,σt)D_{\theta}(\overline{a}_i+\epsilon, s_i, g, \sigma_t)Dθ(ai+ϵ,si,g,σt)② 损失计算:∥Dθ(...)−a‾i∥22\left\| D_\theta(...) - \overline{a}_i \right\|_2^2∥Dθ(...)−ai∥22③ 权重与期望:Eσ,a‾i,ϵ[α(σt)⋅...]\mathbb{E}_{\sigma, \overline{a}_i, \epsilon}[\alpha(\sigma_t) \cdot ...]Eσ,ai,ϵ[α(σt)⋅...]- a‾i+ϵ\overline{a}_i+\epsilonai+ϵ:给真实动作序列a‾i\overline{a}_iai加噪声ϵ\epsilonϵ(选中内容:“noise levels from PnoiseP_{noise}Pnoise are sampled randomly and added to the action sequence”);
- si,gs_i, gsi,g:当前状态和多模态目标(保证去噪是“目标导向”的,比如“为了‘推滑块到右’的目标去噪”);
- σt\sigma_tσt:当前噪声强度(告诉模型“这次加了多少噪声”,以便调整去噪力度);
- DθD_\thetaDθ:可训练的去噪网络(模型的核心,负责根据“带噪声动作+状态+目标+噪声强度”输出“去噪后的动作”)。
- L2损失(欧氏距离平方):衡量“模型输出的去噪动作”与“真实动作序列a‾i\overline{a}_iai”的差距——差距越小,说明模型的去噪效果越好,间接说明它学到的“分数函数(去噪指南)”越准。
- α(σt)\alpha(\sigma_t)α(σt):噪声强度权重(避免强噪声样本主导训练,比如强噪声下允许稍大的去噪误差,弱噪声下要求更精准);
- E\mathbb{E}E:对“所有噪声强度σ\sigmaσ、所有样本a‾i\overline{a}_iai、所有噪声ϵ\epsilonϵ”取期望(保证模型在各种噪声场景下都能学好去噪指南)。
1.2.3.2 实践
结合选中内容的后半段,从“训练阶段”和“推理阶段(生成动作)”两部分看具体操作:
1. 训练阶段:教模型学“去噪指南”
选中内容描述:“During training, noise levels from PnoiseP_{noise}Pnoise are sampled randomly and added to the action sequence and the model predicts the denoised action sequence.”
- 具体步骤:
① 采样:从play数据集中取一个样本(真实动作序列a‾i\overline{a}_iai、当前状态sis_isi、目标ggg);
② 加噪:从噪声分布PnoiseP_{noise}Pnoise中随机采样噪声强度σt\sigma_tσt和噪声ϵ\epsilonϵ,给a‾i\overline{a}_iai加噪得到a‾i+ϵ\overline{a}_i+\epsilonai+ϵ;
③ 预测:将a‾i+ϵ\overline{a}_i+\epsilonai+ϵ、sis_isi、ggg、σt\sigma_tσt输入去噪网络DθD_\thetaDθ,得到模型预测的“去噪动作”;
④ 优化:通过LSM\mathcal{L}_{SM}LSM计算“预测去噪动作”与“真实动作a‾i\overline{a}_iai”的差距,反向更新DθD_\thetaDθ——本质是让DθD_\thetaDθ逐步学会“根据分数函数去噪”。
2. 推理阶段:用“去噪指南”生成动作
选中内容描述:“To generate actions during a rollout, the learned score model is inserted into the reverse SDE and the model iteratively denoises the next sequence of actions. By setting βt=0\beta_t=0βt=0, the model recovers the deterministic inverse process… uses the DDIM sampler to diffuse an action sequence in 10 steps.”
- 具体步骤(从“纯噪声”到“可用动作”):
① 初始化:从纯高斯噪声中采样一个“随机动作序列”(完全无意义的乱动作);
② 反向去噪:将学到的“分数模型”(即DθD_\thetaDθ)代入“反向SDE”(去噪过程的数学描述),让模型逐步调整随机动作——每一步都根据“当前状态sis_isi+目标ggg+当前噪声强度”,沿着分数函数指示的方向去噪;
③ 加速去噪:设置βt=0\beta_t=0βt=0(选中内容重点),把“随机反向SDE”变成“确定性ODE”——避免去噪过程中注入新噪声,让去噪更快更稳定;
④ 快速采样:用DDIM采样器(选中内容),仅需10步迭代去噪,就能从纯噪声中生成“符合目标的稳定动作序列”(比如“推滑块→握取→放水槽”的连续动作)。
1.2.3.3 效果
- 动作序列稳定:通过“分数函数指导去噪”,生成的长时程动作连续平滑(比如CALVIN中连续完成5个任务);
- 鲁棒性强:能处理play数据中的噪声(环境干扰、传感器误差),因为模型在训练时学过各种噪声场景的去噪;
- 效率高:βt=0\beta_t=0βt=0+DDIM采样,仅需10步就能生成动作,满足机器人实时操作需求;
- 目标导向:去噪过程始终结合“当前状态sis_isi+多模态目标ggg”,确保生成的动作符合任务要求(比如“为了‘开微波炉’的目标生成动作”)。
简单说,“基于分数的扩散策略”就是:先教会模型“怎么根据目标把乱动作调成正确动作”(学分数函数),再让模型从纯噪声中一步步调出符合目标的动作——这也是MDT能在稀疏标注数据上实现长时程操作的关键。

1.2.4 基于掩码的预测生成策略
通过重建未来帧的掩码补丁,增强文本 / 图像目标引导下的未来状态预测能力,让 latent 表示编码‘目标→未来行为’的关键信息”。
ViT输入时未来帧(当前状态后第3帧)分割为16*16的图像patch后,直接通过编码模块生成局部embedding,随机将75%的patch embedding替换为掩码embedding,仅计算mask后的embedding的重建MSE Loss。

1.2.5 目标条件的潜在对齐策略
对齐‘当前状态 + 文本目标’与‘当前状态 + 图像目标’的 latent 表示,让两种模态的目标信息映射到统一的行为空间,确保模型对多模态目标的理解一致。
CLIP表现出静态图像的倾向,难以解释空间关系和动态。机器人方面没有大量的数据进行微调。所以引入辅助目标。
仅当当前样本同时具备语言目标和图像目标时,才计算 CLA 的对比学习损失;
InfoNCE 损失的计算范围是 “单个 batchsize 内”,通过批次内的正负样本对比实现多模态表示对齐。
损失计算流程(对应公式6):
- 对批次内每个双模态目标样本,计算(zi0)(z_i^0)(zi0)与(zi1)(z_i^1)(zi1)的余弦相似度(C(zi0,zi1))(C(z_i^0, z_i^1))(C(zi0,zi1));
- 对每个样本(i)(i)(i),计算其正样本相似度的指数值((exp(C(zi0,zi1)/υ))(exp(C(z_i^0, z_i^1)/\upsilon))(exp(C(zi0,zi1)/υ)));
- 计算批次内所有负样本相似度的指数和((∑j=1Bexp(C(zi0,zj1)/υ))(\sum_{j=1}^B exp(C(z_i^0, z_j^1)/\upsilon))(∑j=1Bexp(C(zi0,zj1)/υ)) 与 (∑j=1Bexp(C(zj0,zi1)/υ))(\sum_{j=1}^B exp(C(z_j^0, z_i^1)/\upsilon))(∑j=1Bexp(C(zj0,zi1)/υ)));
- 取对数后求和并平均(除以(2B)(2B)(2B),因每个样本有两组对比方向),得到最终CLA损失。
总结:
- CLA损失的计算前提:样本必须同时具备语言目标和图像目标(双模态目标样本);
- CLA损失的计算范围:严格限制在单个训练批次(batchsize)内,通过批次内正负样本对比实现对齐;
- 核心逻辑:用批次内的“同一任务双模态表示”做正样本,“不同任务跨模态表示”做负样本,确保对齐的是“任务级别的行为分布”,而非单纯的模态语义匹配。
1.3 实验部分
本文实验核心围绕**“验证MDT在稀疏语言标注下的长时程多模态目标策略学习能力”** 展开,覆盖2个主流仿真基准(CALVIN、LIBERO)和1个真实机器人场景,通过对比实验、消融实验验证方法有效性。以下从评价指标定义、实验设计(仿真+真实)、关键结果与结论三部分详细拆解,结合你选中的LIBERO表格展开说明。
1.3.1 核心评价指标:定义、计算与意义
实验针对“长时程操作”“多模态目标”“稀疏标注”三大核心场景设计指标,不同基准/场景的指标侧重不同,但均量化“策略完成任务的准确性”和“长时程稳定性”。
| 评价指标 | 适用场景 | 定义(论文原文+计算方式) | 反映的核心能力 |
|---|---|---|---|
| 平均任务链长度(Avg. Len.) | CALVIN、真实机器人长时程任务 | 1000个“连续指令链”的平均完成任务数(每个链含5-6个任务,完成1个得1分,满分5/6),结果带标准差(±)。 | 长时程任务稳定性:值越高,说明策略能连续完成更多任务,不易中途失败(如CALVIN中Avg. Len. 4.52代表平均完成4.52个连续任务) |
| 任务成功率(Success Rate) | LIBERO、真实机器人单任务 | 每个任务重复20次rollout(测试回合),成功完成的rollout占比(%),结果带标准差(±);多任务时取平均。 | 单任务泛化能力:值越高,说明策略对特定任务(如空间定位、物体操作)的理解越准确,受模态/标注量影响小 |
| 连续指令成功率 | CALVIN | 1000个指令链中,成功完成第1、2、3、4、5个任务的比例(如“Task 1: 98.6%”代表98.6%的链完成第1个任务)。 | 长时程任务的“递进稳定性”:前序任务成功率高但后序低,说明策略缺乏长期规划能力;反之则规划能力强 |
1.3.2 实验设计:整体逻辑与分场景细节
实验围绕论文提出的3个核心研究问题展开,设计“对比实验(验证MDT vs SOTA)”“消融实验(验证MGF/CLA/架构的作用)”“数据效率实验(验证稀疏标注/小数据性能)”,覆盖仿真与真实场景。
1.3.2.1 实验整体逻辑
目标回答3个关键问题:
- 问题I:MDT能否从稀疏标注的play数据中学习长时程操作?
- 问题II:MGF(掩码生成预见损失)和CLA(对比 latent 对齐损失)是否提升性能?(IIa:MDT自身;IIb:迁移到其他策略)
- 问题III:MDT能否在真实机器人场景中从稀疏标注数据学习?
1.3.2.2 仿真实验:CALVIN基准(长时程语言-视觉任务)
(1)数据集设置
- 任务类型:20个厨房长时程操作任务(如“推滑块→开抽屉→按LED”),需连续完成5个任务组成的“指令链”;
- 数据规模:
- 全量数据集(ABCD→D):24小时无结构化play数据(4个环境A/B/C/D),仅1%语言标注;
- 小数据集(D→D):6小时play数据(仅环境D),同样1%语言标注(验证数据效率);
- 输入模态:静态相机+手腕相机图像、语言指令/目标图像;
- 动作空间:机器人末端执行器速度控制+夹爪开合。
(2)对比实验:MDT vs 主流SOTA
选择5个代表性基线方法,均采用相同输入模态和训练超参(保证公平性):
| 基线方法 | 核心特点 | 参数量 | 预训练需求 |
|---|---|---|---|
| HULC [36] | 分层策略,用VAE编码技能空间 | 约100M | 无 |
| LAD [69] | 分层扩散策略,U-Net扩散模型做高层规划 | 约150M | 需HULC预训练 |
| Distill-D [16] | CNN-based扩散策略,需全量语言标注 | 318M | 无 |
| MT-ACT [3] | Transformer+VAE,预测动作块(chunk) | 122M | 无 |
| RoboFlamingo [27] | 视觉-语言基础模型(30亿参),需大规模互联网数据预训练 | 3B | 需互联网预训练 |
(3)关键结果(对应论文Table I)
- 长时程性能SOTA:MDT-V(Voltron编码器版本)在ABCD→D任务中Avg. Len.达4.52,比RoboFlamingo(4.09)提升10%,且参数量仅40M(为RoboFlamingo的1/75)、无需预训练;
- 数据效率突出:在D→D小数据集上,MDT-V的Avg. Len. 3.72,比第二名MT-ACT(2.98)提升25%,证明稀疏小数据下的有效性;
- 多模态兼容:同时支持语言和图像目标,且性能无显著差异(论文补充实验验证)。
1.3.2.3 仿真实验:LIBERO基准(多类型多任务泛化)
(1)数据集设置
- 稀疏标注设置:仅2%演示含语言标注(每个任务50个演示中,仅1个有语言,其余49个无标注),模拟真实场景的标注稀缺性;
- 输入模态:静态相机+手腕相机图像、语言指令/目标图像。
任务类型:5个任务套件共130个操作任务,覆盖不同泛化挑战(你选中的表格即此实验结果):
| 任务套件 | 核心挑战 | 任务数量 | 每个任务演示数 |
|---|---|---|---|
| LIBERO-Spatial | 空间关系泛化(如“将左侧碗放在盘子上”) | 10 | 50 |
| LIBERO-Object | 物体识别泛化(如“拿起香蕉/拿起锅”) | 10 | 50 |
| LIBERO-Goal | 目标意图泛化(相同物体不同目标,如“开微波炉/关微波炉”) | 10 | 50 |
| LIBERO-Long | 长时程泛化(单任务含多个子步骤,如“拉托盘→放香蕉→推托盘”) | 10 | 50 |
| LIBERO-90 | 多场景泛化(90个短任务,覆盖5个不同环境) | 90 | 50 |
(2)对比实验:MDT vs 基线(对应你选中的表格)
选中表格的核心是**“2%语言标注下,MDT与基线及消融版本的性能对比”**,关键基线解读:
- Transformer-BC [29]:全量语言标注(100%)的Transformer基线,代表“理想标注下的上限”;
- Distill-D [16]:2%标注的CNN-based扩散基线,代表“无MGF/CLA的扩散策略性能”;
- MDT系列:4个版本(无MGF/CLA、仅CLA、仅MGF、两者都有),验证辅助损失的作用。
(3)关键结果(从你选中的表格解读)
- 稀疏标注下超越全标注基线:MDT(2%标注,无MGF/CLA)的Spatial任务成功率66.0%,超过Transformer-BC(100%标注)的71.8%仅差5.8%;Object任务85.2%,远超Transformer-BC的71.0%,证明MDT的标注效率;
- MGF与CLA的增益:
- 仅加CLA:平均成功率从68.5%→73.1%(提升4.6%),LIBERO-90任务从58.7%→66.9%(提升8.2%,因任务多、对比样本丰富,CLA作用更显著);
- 仅加MGF:平均成功率从68.5%→70.0%(提升1.5%),Spatial任务从66.0%→67.5%(提升1.5%,因空间任务需预见未来位置,MGF作用更显著);
- 两者都加:平均成功率达74.3%,比无辅助损失版本提升5.8%,证明协同效应;
- 跨套件泛化稳定:MDT在5个套件中均优于Distill-D,尤其在Long任务(65.0% vs 47.3%)和90任务(58.7% vs 49.9%),证明长时程和多场景泛化能力。
1.3.2.4 真实机器人实验:玩具厨房场景(验证落地性)
(1)实验 setup
- 硬件:7自由度Franka Emika Panda机器人、玩具厨房(含微波炉/烤箱/水槽)、2个静态RGB相机(俯视+侧视);
- 任务类型:20个单任务(如“香蕉从右灶台→水槽”“开微波炉”)+4个长时程指令链(如“推烤面包机→拿吐司→放水槽→开烤箱”);
- 数据集:4.5小时无结构化play数据(志愿者遥操作收集,无任务分段/场景布置),仅20%片段含语言标注(360个短片段);
- 输入模态:相机图像、语言指令/目标图像;
- 动作空间:机器人关节角度归一化([-1,1])+夹爪二进制控制(开/合)。
(2)实验设计:单任务+长时程任务
- 单任务评价:每个任务5次rollout(从随机初始位置出发),人工判断是否成功,计算平均成功率;
- 长时程评价:4个指令链(每个含5-6个任务),仅完成前序任务才给后序目标,计算平均任务链长度(Avg. Len.)。
(3)关键结果(论文Table III、IV)
- 单任务性能:MDT(无MGF/CLA)成功率0.51,比MT-ACT(0.25)提升104%;加MGF/CLA后达0.58,进一步提升14%,证明真实场景下辅助损失的作用;
- 长时程性能:语言目标下,MDT的Avg. Len. 1.38,是MT-ACT(0.81)的1.7倍;图像目标下,MDT的Avg. Len. 0.56,是MT-ACT(0.13)的4.3倍,证明多模态目标的落地能力;
- 失败分析:主要失败在“精细操作”(如关烤箱门差几毫米)和“相似状态区分”(如“推锅到左灶台”vs“推锅到右灶台”),因标注少、相机存在自遮挡。
1.3.2.5 消融实验:验证核心设计的必要性
消融实验围绕“MGF、CLA、架构组件”展开,核心验证“哪些设计对性能至关重要”,结果均基于CALVIN/LIBERO基准。
(1)消融1:MGF与CLA的独立作用(对应LIBERO表格+CALVIN补充实验)
- 实验设计:对比“无MGF无CLA”“仅MGF”“仅CLA”“两者都有”4个版本;
- 核心结论:
- CALVIN上:MGF作用更显著(Avg. Len. 提升25%),因长时程任务需“预见未来状态”;
- LIBERO上:CLA作用更显著(平均成功率提升4.6%),因多任务需“多模态目标对齐”;
- 两者协同:在所有基准上均实现“1+1>2”的增益(如LIBERO平均成功率提升5.8%)。
(2)消融2:架构组件的必要性(CALVIN ABCD→D任务)
实验设计:对比3个架构版本(论文Table IX):
| 架构版本 | 核心修改 | Avg. Len. | 结论 |
|---|---|---|---|
| MDT-V(原版本) | 含Transformer编码器+AdaLN噪声条件 | 4.18 | 基线性能 |
| 无AdaLN条件 | 去掉噪声强度的AdaLN调节 | 3.58 | AdaLN对噪声适应至关重要,提升16%; |
| 无Transformer编码器 | 用CNN替代编码器(如Distill-D) | 1.41 | 编码器是多模态融合核心,去掉后性能暴跌66%,证明分离式编码器-解码器设计的必要性。 |
(3)消融3:MGF的迁移性(验证问题IIb)
- 实验设计:将MGF加到MT-ACT(另一Transformer策略)中,在CALVIN ABCD→D任务测试;
- 结果:MT-ACT的Avg. Len. 从2.80→4.03(提升44%,论文Table XI),证明MGF是“通用辅助损失”,可迁移到其他Transformer策略。
(4)消融4:预训练与图像编码器(LIBERO-Long任务)
- 实验设计:
- 预训练:用MGF/CLA在“无动作的视频数据”上预训练MDT,再微调LIBERO-Long;
- 图像编码器:对比“冻结CLIP”vs“从头训ResNet”;
- 结果:
- 预训练增益:5个演示时成功率提升100%(0.29→0.58),证明MGF/CLA可用于无动作数据预训练;
- 编码器无关:从头训ResNet的MDT性能(Avg. Len. 4.31)仅比冻结CLIP(4.41)差2.3%,证明MDT不依赖预训练视觉模型。
1.3.3 实验核心结论
- 稀疏标注效率:MDT仅需2%语言标注,即可在LIBERO超越100%标注的Transformer-BC,在CALVIN超越需全量标注的Distill-D;
- 辅助损失通用:MGF提升“未来预见能力”(长时程任务),CLA提升“多模态对齐能力”(多任务泛化),且可迁移到其他策略;
- 架构高效:分离式Transformer编码器-解码器+AdaLN设计,参数量仅为SOTA(如RoboFlamingo)的1/10,无需预训练;
- 真实落地性:在4.5小时无结构化真实数据上,MDT的长时程性能是MT-ACT的1.7-4.3倍,证明实际场景适用性。
2. 代码梳理

training.py是整体运行的流程,datasets是数据集读取函数存放位置,evaluation是评测代码,models是模型代码所在位置。
2.1 数据读取
主要在BaseDataset中self._get_sequences
这段代码的核心作用是加载并处理一个连续帧序列,将原始数据转换为模型训练/推理所需的结构化序列字典。具体来说,它从起始索引idx开始,获取长度为window_size的连续帧数据,并对不同模态(状态、RGB图像、深度、动作、语言等)进行处理,最终返回一个包含完整序列信息的字典。
| 处理函数 | 作用 | 输出示例 |
|---|---|---|
process_state | 处理状态信息(如机器人关节状态、场景观测) | {'robot_obs': tensor([[...]]), 'scene_obs': tensor([[...]])} |
process_rgb | 处理RGB图像(调整大小、归一化等),包括静态相机和机械臂相机图像 | {'rgb_obs': {'rgb_static': tensor([3, 224, 224]), ...}} |
process_depth | 处理深度图像(如果数据集包含) | {'depth_obs': {}}(示例中无深度数据,返回空字典) |
process_actions | 处理动作数据(如相对动作) | {'actions': tensor([10, 7])}(动作序列,长度为action_seq_len) |
get_state_info_dict | 获取状态相关的辅助信息 | {'state_info': {'robot_obs': [...], 'use_for_aux_lang_loss': False}} |
process_language | 处理语言指令(如果有),如转换为embedding | {'lang': tensor([384]), 'lang_text': 'lift the red block from the table'} |
- 将所有处理后的字典合并为一个完整的
seq_dict,包含:- 状态、RGB、深度、动作等模态数据。
- 语言信息(如果有)。
- 辅助信息(如状态信息、语言损失标志)。
- 原始索引
idx和未来帧差异future_frame_diff。

2.2 模型结构
mdt_agent.py中MDTAgent类是模型整体框架,在config配置文件中会对每个模块类别和参数进行配置。
MDTAgent的父类是pl.LightningModule,这个Agent简单流程如下:
classMDTAgent(pl.LightningModule):def__init__(self, model_config, optimizer_config):super().__init__()# 1. 定义模型组件(架构) self.static_resnet = BesoResNetEncoder(512)# 视觉编码器 self.model = hydra.utils.instantiate(model_config)# 核心网络 self.gen_img = hydra.utils.instantiate(img_gen_config)# MGF 组件# 2. 保存超参数 self.save_hyperparameters() self.optimizer_config = optimizer_config # 3. 训练单步逻辑deftraining_step(self, batch, batch_idx):# 数据处理→损失计算 perceptual_emb, latent_goal = self.compute_input_embeddings(batch) action_loss = self.diffusion_loss(perceptual_emb, latent_goal, batch["actions"]) self.log("train/action_loss", action_loss)# PL 自动记录日志return action_loss # 返回损失,Trainer 自动反向传播# 4. 验证单步逻辑defvalidation_step(self, batch, batch_idx): perceptual_emb, latent_goal = self.compute_input_embeddings(batch) action_pred = self.denoise_actions(perceptual_emb, latent_goal) val_loss = F.mse_loss(action_pred, batch["actions"]) self.log("val/loss", val_loss, sync_dist=True)# 分布式训练时同步日志# 5. 配置优化器defconfigure_optimizers(self): optimizer = torch.optim.AdamW(self.parameters(), lr=self.optimizer_config.lr) scheduler = TriStageLRScheduler(optimizer, self.lr_scheduler_config)return{"optimizer": optimizer,"lr_scheduler": scheduler}# 6. 推理逻辑defforward(self, obs, goal): perceptual_emb = self.embed_visual_obs(obs["rgb_static"], obs["rgb_gripper"]) action_seq = self.denoise_actions(perceptual_emb, self.visual_goal(goal))return action_seq 训练代码如下,主要流程有三个输入批量数据–> 多模态嵌入(compute_input_embeddings)–>分别计算SM损失(diffusion_loss预测动作与真实动作差距)、MGF损失(compute_img_gen_loss图像重建损失)、CLA损失(compute_contrastive_loss多模态对齐损失)–>输出总体损失。
deftraining_step(self, batch: Dict[str, Dict], batch_idx:int, dataloader_idx:int=0)-> torch.Tensor:# type: ignore""" 计算并返回MDT的训练损失,包含: 1. 扩散模型的分数匹配损失(SM损失) 2. 多模态编码器的对比损失(CLA损失) 3. 掩码生成预测损失(MGF损失) compute and return the training loss for the MDT agent. The training loss consists of the score matching loss of diffusion model and the contrastive loss of the CLIP modle for the multimodal encoder. Args: batch: Dictionary containing the batch data for each modality. batch_idx: Index of the batch. used for compatibility with pytorch lighting. dataloader_idx: Index of the dataloader. used fir compatibility with pytorch lightning. Returns: loss tensor 1. 数据输入:多模态批次(视觉目标+语言目标数据) 2. 嵌入处理:双相机图像->ResNet编码,目标->CLIP编码 3. 三重损失计算: SM损失:动作序列加噪->去噪,优化扩散模型分数函数 MGF损失:用编码器latent重建未来图像掩码块,增强"远见"能力 CLA损失:对齐语言、视觉目标的latent,解决多模态对齐问题 4. 损失融合:加权累加后平均,确保多模态批次平衡 5. 梯度更新:PL自动用总损失反向传播,更新所有模型参数 """# 1. 初始化损失变量(均初始化位0,移到当前设备) total_loss, action_loss, cont_loss, id_loss, img_gen_loss =( torch.tensor(0.0).to(self.device), torch.tensor(0.0).to(self.device), torch.tensor(0.0).to(self.device), torch.tensor(0.0).to(self.device), torch.tensor(0.0).to(self.device),) encoders_dict ={}# 预留:编码器相关缓存(未使用) batch_size: Dict[str,int]={}# 记录每个模态的批次大小 total_bs =0# 总批次大小# 2. 遍历多模态批次(batch包含视觉目标批次,语言目标批次等)for self.modality_scope, dataset_batch in batch.items():# 3. 计算多模态输入嵌入# perceptual_emb:双相机图像的Token序列(static + gripper)# latent_goal:目标嵌入(视觉/语言)# image_latent_goal: 仅语言模态时,保存对应的视觉目标嵌入(用于CLA对比) perceptual_emb, latent_goal, image_latent_goal = self.compute_input_embeddings(dataset_batch)# 4. 计算SM损失(分数匹配损失,论文3.2节核心损失)# act loss:当前批次的SM损失# sigmas:采样的噪声强度序列# noise:生成的高斯噪声 act_loss, sigmas, noise = self.diffusion_loss( perceptual_emb, latent_goal, dataset_batch["actions"],)#感觉这个是去噪的# 获取编码器的latent特征(用于MGF和CLA损失) latent_encoder_emb = self.model.inner_model.latent_encoder_emb # 5. 计算MGF损失(掩码生成预测损失)# Compute the masked generative foresight lossifnotisinstance(self.gen_img, NoEncoder):# 如果启用MGF模块# 提取未来帧图像(static和gripper相机的未来状态) rgb_static_goal = dataset_batch["rgb_obs"]["gen_static"] rgb_gripper_goal = dataset_batch["rgb_obs"]["gen_gripper"]# 预测的未来帧到当前帧的距离,如果没有定义就是3,就测未来第三帧 img_gen_frame_diff = dataset_batch["future_frame_diff"]if"future_frame_diff"in dataset_batch else3#conbine both goal images# 拼接两个相机的未来图像(统一输入格式) rgb_pred_goal = torch.cat([rgb_static_goal, rgb_gripper_goal], dim=1)# MGF的输入:编码器latent特征 img_gen_embed = latent_encoder_emb # 计算单批次MGF损失() img_gen_loss_part = self.compute_img_gen_loss(img_gen_embed, rgb_pred_goal, img_gen_frame_diff = img_gen_frame_diff)# 累加加权后的MGF损失(masked_beta是权重) img_gen_loss += img_gen_loss_part * self.masked_beta # 将加权后的MGF损失加入总损失 total_loss += img_gen_loss_part * self.masked_beta # 6. 计算CLA损失(对比latent对齐损失,)# 用infoNCE损失计算两种latent的余弦相似度,让同一个任务的双模态latent互为正样本,不同任务的位负样本# 强制模态间对齐# 生成目标条件下的双模态latent# 经过投影层投影到统一维度# 特征归一化# 计算余弦相似度# infoNCE计算 cont_loss_part = self.compute_contrastive_loss( perceptual_emb,# 视觉观测嵌入 latent_goal,# 目标嵌入(语言模态是语言嵌入) image_latent_goal,# 语言模态对应的视觉目标嵌入 dataset_batch,# 当前批次数据 sigmas,# 噪声强度 noise,#高斯噪声)# 累加加权后的CLA损失(cont_alpha是权重,对应论文中的β) cont_loss += self.cont_alpha * cont_loss_part # 将加权后的CLA说你是加入总损失 total_loss += self.cont_alpha * cont_loss_part # 7. 累加SM损失 action_loss += act_loss # 将SM损失加入总损失 total_loss += act_loss # 8. 记录当前模态的批次大小 batch_size[self.modality_scope]= dataset_batch["actions"].shape[0] total_bs += dataset_batch["actions"].shape[0]#多少动作序列# 9. 平均损失 batch_len =len(batch)# 多模态批次的数量() total_loss = total_loss / batch_len # 总损失平均 cont_loss = cont_loss / batch_len # CLA损失平均 action_loss = action_loss / batch_len # SM损失平均(用于日志) img_gen_loss = img_gen_loss / batch_len # MGF损失平均(用于日志)# 10. 日志记录训练指标(同步分布式训练的指标) self._log_training_metrics(action_loss, total_loss, cont_loss, img_gen_loss, total_bs)# 11. 返回总损失(PyTorch Lightning自动反向传播更新参数)return total_loss 验证流程如下:
@torch.no_grad()# 禁用梯度计算(验证阶段不更新参数)defvalidation_step(self, batch: Dict[str, Dict], batch_idx:int, dataloader_idx:int=0)-> Dict[str, torch.Tensor]:#type:ignore""" 计算并记录验证损失,核心是验证动作预测精度和MGF损失稳定性 """ output ={}# 输出字典(记录批次索引和验证损失) val_total_act_loss_pp = torch.tensor(0.0).to(self.device)# 动作预测损失累加器# 1. 遍历多模态批次(同训练流程, 处理视觉、语言目标数据)for self.modality_scope, dataset_batch in batch.items():# 2. 计算多模态输入嵌入(与训练流程完全一致,保证输入格式统一) perceptual_emb, latent_goal, image_latent_goal = self.compute_input_embeddings(dataset_batch)# 3. 生成动作序列(推理模式,对应论文) action_pred = self.denoise_actions( torch.zeros_like(latent_goal).to(latent_goal.device), perceptual_emb,# 视觉观测嵌入 latent_goal,#目标嵌入 inference=True,#开启推理模式(使用配置的采样步数和采样器))# 4. 计算动作预测MSE损失(验证动作生成精度) pred_loss = torch.nn.functional.mse_loss(action_pred, dataset_batch["actions"])# 获取编码器latent特征(用于MGF损失验证) latent_encoder_emb = self.model.inner_model.latent_encoder_emb # 累加动作预测损失 val_total_act_loss_pp += pred_loss # 5. 验证MGF损失(与训练流程逻辑一致, 仅不记录单独累加值)ifnotisinstance(self.gen_img, NoEncoder):# 提取未来帧图像 rgb_static_goal = dataset_batch["rgb_obs"]["gen_static"] rgb_gripper_goal = dataset_batch["rgb_obs"]["gen_gripper"]# 远见距离v(默认3) img_gen_frame_diff = dataset_batch["future_frame_diff"]if"future_frame_diff"in dataset_batch else3# 拼接未来图像 rgb_pred_goal = torch.cat([rgb_static_goal, rgb_gripper_goal], dim=1)# MGF输入:编码器latent特征 img_gen_embed = latent_encode # 计算MGF损失(不存储生成图像,仅验证损失) img_gen_loss = self.compute_img_gen_loss( img_gen_embed, rgb_pred_goal, store_img=False, batch_idx=batch_idx, img_gen_frame_diff=img_gen_frame_diff )else: img_gen_loss = torch.tensor(0.0).to(self.device)# 未启用MGF则损失为0# 6. 日志记录验证指标(动作损失+MGF损失) self._log_validation_metrics(pred_loss, img_gen_loss, val_total_act_loss_pp)# 7. 记录当前模态的批次索引和总验证损失 output[f"idx_{self.modality_scope}"]= dataset_batch["idx"] output["validation_loss"]= val_total_act_loss_pp # 8. 返回输出字典(PL自动汇总验证结果)return output 我们继续看看一些mdt_transformer中的实现,encoder是生成上下文embedding,decoder去噪生成动作。
SinusoidalPosEmb是转化为正弦位置嵌入用于adaLN 。
classSinusoidalPosEmb(nn.Module):def__init__(self, dim):super().__init__() self.dim = dim defforward(self, x): device = x.device half_dim = self.dim //2 emb = math.log(10000)/(half_dim -1) emb = torch.exp(torch.arange(half_dim, device=device)*-emb) emb = x[:,None]* emb[None,:] emb = torch.cat((emb.sin(), emb.cos()), dim=-1)return emb 主要理解decoder怎么去噪。具体流程上面论文内容。
MGF就是随机mask未来帧图像,然后把图像打成token进行编码,以mdt transformer的encoder输出的latent embedding为条件,进行重建,只计算mask区域的MSE损失。
CLA就是计算两个模态goal embedding+当前状态embedding也就是上下文latent embedding进行proj后计算infoNCE Loss。