前一段时间写过关于openvla的文章,openvla是基于VLM的多模态模型,本质上基于成熟的大语言模型来预测action。本文的RDT-1B是另一种路线,是基于diffusion扩散模型,可以经过多步forward,不断的去噪,生成更加精细的action。

关于模型技术路线分类,可以参考以下2篇文章 ,总结的不错:

具身智能Vision-Language-Action的思考
近几年VLA方案调研(截止25.03.14)

关于RDT-1B的详细技术原理,已经有很多篇不错的文章了,本文也不再赘述,可以自行检索。RDT-1B代码其实并不复杂,但涉及的背景知识比较多,需要大家先了解扩散模型,扩散模型中的条件机制,还有一些概率论知识。一般的文章中公式会有很多,能研究明白固然很好,但看不明白,初期也不影响读代码。我在学习的过程中,也看到了不少还不错的文章,也贴在这里供大家参考。本文不会探讨理论细节,更多的是从输入,输出,或者是从代码 ,工程的角度,来展现一下RDT-1B是个什么东西,比纯文字讲解原理的文章稍微深入那么一点点。

综述 - 扩散模型 - Diffusion Models
十分钟读懂Stable Diffusion运行原理
LDM(Latent Diffusion Model)详解
DiT(Diffusion Transformer)详解

在这里插入图片描述

在这里插入图片描述

上图第一张图是RDT-1B的总体架构图,下面讲解过程中的一些变量名会跟图中一致。

第二张图是类图,是前向推理过程中参与的类的结构图,一些核心的模块在下面讲解中会引用到,可以通过类图知道它在整体架构中的哪个位置。

模型输入:

1, Zt

Zt在论文中英文名是proprioception ,中文翻译过来是“本体感知”,就是一个128维的向量。每个维度的是什么含义如下表。作者的目标是将不同型号的具身智能机器人动作(例如有双臂的,单臂的,A品牌的,B品牌的…)统一到一个128维的动作空间中。这样可以将历史上公开的数据集都统一的使用起来,因为在具身智能领域,数据稀缺且不统一是一个比较大的问题。

举例来说,作者实验用的双臂机械手,作者使用了每个手臂的6个joint的位置数据(位置不是坐标,而是joint的开合程度, 是一个标量),还有一个gripper的开合程度数据。所以共(6+1)*2=14维数据,对应下面表格中的下标是[50, 51, 52, 53, 54, 55, 60, 0, 1, 2, 3, 4, 5, 10]。将这14维数据统一到128维空间中,就是Zt,同时会有一个mask,表示哪个下标的数据被赋值了(就是有意义的)。最终形成2个变量states, state_elem_mask两个变量。

states经过RDTRunner:state_adapter(见类图)转换后变成(1,1,2048),也就是将输入统一转换成2048维度。第一个1代表batch size

在这里插入图片描述
在这里插入图片描述

2,Image Inputs

在本文中输入了6张图片, 在这里插入图片描述

,就是正前,右手,左手三个视角的三张图片,再加上t-1历史时刻3张,共6张图片。每张图片经过image_processor(类图中RoboticDiffusionTransformerModel:image_processor)处理后变成了(3, 384, 384),6张就是(6, 3, 384, 384),再经过RoboticDiffusionTransformerModel:vision_model处理后变成了image_embeds(1, 4374, 1152)。至于为什么是4374, 1152这些数字,有兴趣的可以研究一下这个转换器,这个不重要,后续会通过RDTRunner:img_adapter模块统一转换为(1,4374, 2048)维度。

在这里插入图片描述

3,Language Inputs

在就是指令文本,经过大语言模型编码后生成向量,例如“Pick up the black marker on the right and put it into the packaging box on the left.”经过"google/t5-v1_1-xxl"处理后生成text_embeds(1, 20, 4096)。"google/t5-v1_1-xxl"比较大,在推理过程还要加载rdt模型本身,所以显存有限的情况下,可以将指令离线编码后存储下来再使用,在README中有详细介绍,可以参考。

数据再经过RDTRunner:lang_adapter转换后统一到(1,20, 2048)
在这里插入图片描述

4, a ~ t \tilde{a}_{t} a~t

它是一个action chunk(动作块),动作块就是倾向于一次性预测一系列动作(64个),而不是openvla中的一个动作,这样一致性会更好,误差也会更小。它跟第一部分的Zt是一样的,物理空间是一致的,原始数据是128维。在时间序上是64维,代表未来64个按序下发的动作(若每秒下发8个的话,就是未来8秒的执行动作)。

这64维动作在第一次的时候是随机生成的,也就是全部是噪声,然后通过diffusion的去噪的过程逐渐把噪声去掉,经过数次迭代后就变成无噪声的action。本文所说的扩散模型的核心点就体现在这里。diffusion传统上来讲,是把图片去噪,但在本文中,去噪的对象不是一张张图片了,而一个动作块。一般的图片去噪会在隐空间中进行(因为图片像素很多,维度很高,直接在图片上进行,计算代价太高,所以一般会将图片降维,例如降到1024维度,这个降维后的空间就叫隐空间),对于动作块来讲,因为维度本身就很低了(128),所以就省去了转到隐空间的操作。

把上面的64个带噪声的动作,就是图中的Noisy Act,通过RDTRunner:state_adapter转换到(1,64,2048)维度。图中把Zt和 a ~ t \tilde{a}_{t} a~t放在一起,因为它们共享了一个转换矩阵。

5,控制频率c和Time Step k

控制频率在本文中是c=25

Time Step k就是去噪过程中经过多次迭代的过程,经典的去噪过程可能得很多次的迭代才能得到一个比较好的结果(例如1000次)。但DPM-Solver算法可以将这个次数大大的减少(例如5次)。DPM-Solver算法大家可以自行检索,还是挺复杂的,但使用起来却比较简单,就是几行代码调用现成的库就可以。本文中,通过5次迭代,具体来说,就是DPM-Solver选择了1000次中的第999, 799, 599, 400, 200次,这里的k在每次迭代时分别等于999, 799, 599, 400, 200

c和k经过RDT:freq_embedder和RDT:t_embedder统一转换为(1,1,2048)和(1,1,2048),即统一到2048维度。

模型推理:

模型的前向推理过程也没啥可讲的,具体来说,就是将上面输入的k, c, Zt和 a ~ t \tilde{a}_{t} a~t
,按次序拼在一起,共1+1+1+64=67维,即(1, 67, 2048),送到RDT模型(本质上就是一个DiT),共28个block,每个block先在(1, 67, 2048)之间进行self attn,然后(1, 67, 2048)与image(Image Inputs)或 text(Language Inputs)之间进行cross attn

在每个block的cross attn的过程中,并不会同时与image和text进行cross attn,是由于图像 token 数量通常远多于文本 token,同时注入两种模态容易导致文本相关信息被掩盖,从而削弱模型的指令遵循能力。为缓解这一问题,我们在连续层的交叉注意力中交替注入图像和文本 token,而非在每一层同时注入两种模态。

最终的取67维中的后64维就是最终的action chunk

原始论文翻译:
论文阅读:RDT

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐