vla学习
vla学习基础知识模型结构分类数据集相关LeRobot宇树数据格式字段介绍reward和done字段1. Reward(奖励)的计算方式(1)稀疏奖励(Sparse Reward)(2)稠密奖励(Dense Reward)(3)组合奖励2. Done(终止信号)的判定条件(1)任务成功(2)任务失败(3)超时3. 如何查看具体任务的 reward/done 逻辑?带底盘的机器人openvla动作离散化转tokenaction标签如何与token结合关键问题解答Q1: 7维动作是一次性生成的吗?Q3: 如何保证动作的物理合理性?基于diffusionπ0架构训练流程:预训练 + 后训练vlm模型PaliGemma结合代码学习PaliGemmaWithExpertModel类PaliGemmaWithExpertModel.compute_layer_completePaliGemmaWithExpertModel.compute\_layer\_complete条件归一化PI0Pytorch类embed_suffix后缀嵌入函数token编码,把字符串分词变成向量dataset部分pi0-fasttoken表示离散化的action基于分箱的动作token化DCT(离散余弦变换,π0-FAST 的 token 化器核心)FASTTokenizer代码pi0.5代码学习一处配置错误问题pi0.7是什么让 π0.7 拥有如此强大的泛化能力?通过多样化条件指令利用更多数据实际泛化效果,组合任务泛化跨机器人泛化基于速度与最优性的条件控制 recap强化学习算法gr00t模型结构gr00t的flow matching代码代码学习速度场和噪声轨迹代码RoboBrainRLinfVLA为什么需要RLFlow-Noise 与 Flow-SDE其他通用性代码co-train仿真环境Gymnasiumpi模型仿真环境基础知识action chunk是动作范围,比如模型推理一次,输出50步的动作,每一步都包含多个关节的动作,输出是二维矩阵?这里的50是chunk范围,是时间维度上的。模型结构分类基于经典 Transformer 结构的 VLA 模型: ALOHA (ACT) 系列、RT-1、HPT 等。其核心思想是利用强化学习轨迹与序列建模问题结构的自然对齐性,用Transformer模型过对状态 - 动作 - 奖励序列的建模。比如ACT,输入action query,得到action chunk基于预训练 LLM/VLM 的 VLA 模型: RT-2、OpenVLA 等。将 VLA 任务视为一个序列到序列的生成问题,借助预训练的视觉语言模型(VLM)来处理视觉和语言信息,并生成相应的动作,增强了模型的泛化性和指令理解能力。基于扩散模型的 VLA 模型: Diffusion Policy、RDT-1B、gr00T等。一般也是用vlm提取特征通过self attention与action state特征融合,通过扩散模型或流匹配算法生成连续动作序列。数据集相关libero数据集DROID数据集LeRobotLeRobot 是一个框架,也包含特定格式的数据集。遵循结构化组织,将元数据、原始数据和视觉模态分开。剧集被分组为多个块,默认每个块 1000 个 episode,以便于下载和处理。元数据以 JSON 和 JSONL 文件形式存储,不同数据类型分别存储,如 Parquet 格式用于状态数据,MP4 格式用于视频。下面介绍的宇树数据格式就是LeRobot 格式。宇树数据格式parquet存储的字段,有index、action、state等index和视频帧一一对应,一个task目录下所有视频轨迹的全局index,此外还有一个trajectory_id,就是视频轨迹的id。action和state的shape是相等的,也就是一个时刻,存储的时候,只存当前时刻的action就行了,如果模型chunk后续多个时刻的action,可以依次向后取就行。注意当前时刻的action,并不是下一个时刻的state! 两者的来源不同,和采集方式有关。如果有主臂从臂,那分别来自主从臂。如果遥操式,state来自机器人,action则来自遥操装置。字段介绍reward字段是一个奖励信号,评估动作好坏的。看gr00t代码,rewards字段,仅在仿真的时候用了,模型训练的时候没用到。next.done也是这样。一、训练阶段:聚焦模仿学习,弱化奖励依赖数据特性与任务目标的匹配, “直接模仿” 的方式能快速学习到稳定的动作模式。避免奖励函数的局限性,奖励函数的设计需要精确反映任务目标,训练阶段绕过奖励函数,提升模型的泛化能力。二、仿真阶段:利用奖励信号实现策略优化策略评估与迭代的核心依据,仿真阶段的目标是验证和优化模型在特定任务中的表现。例如,通过设计 “完成任务的步数”“动作平滑度”“碰撞次数” 等奖励项,模型可以在仿真中自主探索动作空间,逐步优化策略以最大化奖励。这种闭环反馈机制能弥补训练阶段的不足,例如提升模型对未知环境的适应性。与强化学习的深度结合,部分 VLA 模型(如 π0、DexVLA)在仿真阶段采用强化学习进行二次优化。next.done字段与奖励信号共同构成 马尔可夫决策过程(MDP) 的关键要素,用于计算折扣回报和策略梯度。例如,若机器人在动作执行中发生碰撞,next.done置为True,并给予负奖励,促使模型避免类似行为reward和done字段这两个字段一般是无需标注的,在强化学习汇中,模型和环境不断的进行交互,在vla任务中,一般有一套或较为通用的评判规则,用于在强化学习任务中,对模型表现进行惩罚或奖励。在 RoboCasa 仿真环境中,reward(奖励)和done(终止信号)的计算逻辑由具体任务定义决定,不同任务(如“整理桌面”“分拣物体”)有不同的判定规则。以下是其核心设计逻辑和实现方式:1. Reward(奖励)的计算方式奖励的作用是引导机器人学习“正确”的行为,其设计与任务目标强相关。RoboCasa 中奖励通常包含以下几类:(1)稀疏奖励(Sparse Reward)特点:仅在任务完成或失败时给予奖励(非 0 即 ±X),中间步骤无奖励。示例:在“Cansort(分拣罐子)”任务中:若机器人成功将所有罐子放入目标区域,奖励+100;若任务超时或罐子掉落,奖励-50;中间步骤奖励为0。(2)稠密奖励(Dense Reward)特点:根据任务进度实时给予奖励,引导机器人逐步逼近目标。常见计算维度:距离奖励:物体与目标位置的距离(如罐子到目标区域的距离越小,奖励越高)。公式示例:reward += 1.0 / (1.0 + distance)(距离越小,奖励越接近 1)。姿态奖励:机器人末端执行器与目标物体的姿态匹配度(如抓取时的对齐程度)。动作惩罚:对过大的动作或能耗进行惩罚(如reward -= 0.01 * ||action||²),避免机器人“乱动”。碰撞惩罚:若机器人与环境发生不必要碰撞(如撞翻桌子),奖励-10。(3)组合奖励大多数任务会结合稀疏奖励和稠密奖励,例如:总奖励 = 稠密进度奖励 + 稀疏完成奖励 - 动作惩罚2. Done(终止信号)的判定条件done为True表示当前回合(episode)结束,触发条件由任务的终止规则定义,常见情况包括:(1)任务成功机器人完成核心目标,例如:所有物体被正确分类到目标区域;成功抓取并移动物体到指定位置;完成语言指令对应的动作(如“打开抽屉”)。(2)任务失败出现不可逆错误,例如:物体掉落出场景(如罐子掉落到地面);机器人与关键物体发生严重碰撞(如撞碎杯子);机器人关节角度超出安全范围。(3)超时若机器人在规定步数/时间内未完成任务,强制终止。例如:max_episode_steps = 1000,当步数达到 1000 时,done = True。3. 如何查看具体任务的 reward/done 逻辑?RoboCasa 的任务逻辑通常在其代码库的tasks目录下,以 Python 类的形式实现。如果需要自定义奖励或终止规则,可以继承原有任务类,重写上述方法。带底盘的机器人控制底盘的数据维度分两种:差速驱动,两自由度,(v, ω),只有两个独立驱动轮(左右各一),通过左右轮速差实现转向,如DROID全向移动,三自由度,(vx, vy, ω),可在任意方向平移 + 旋转,无需先转向,如Mobile ALOHAopenvla模型结构比较简单,两个并行度的视觉编码器,MLP后与token文本特征拼接,送入Llama。动作离散化转token为了使 VLM 的语言模型主干网络能够预测机器人动作,通过语言模型token化器将连续的机器人动作映射为离散tokens,将机器人动作的每个维度分别离散化到 256 bins的一个。OpenVLA 语言主干使用的 Llama token化器 [10],仅为微调期间新引入的tokens保留了 100 个“特殊tokens”,这对于动作离散化的 256 个tokens来说太少了。再次选择简单性并遵循 Brohan [7] 的方法,只需用动作 tokens 去覆盖 Llama token化器词汇表中 256 个最少使用 tokens(对应于最后 256 个 tokens),生成token后就可以用vlm进行训练了。为什么占用最少使用的token,因为要使用vlm微调,尽可能不破坏vlm结构。action标签如何与token结合在模型训练时,作者将不同数据集进行打平,怎么打平呢,例如针对roll来说,A数据集的范围是从-0.2~0.2, B数据集的范围是-0.30.3,将每个数据集的minmax中间的值均分为255等分(就是代码中的bin的概念),如果某一帧的值是roll=0,那么就落在了第128个bin中。llama默认的tokenizer中的token是32000个,作者使用了最后的255个代表action(不包含最后一个32000),上面所说的第128个bin的id=31872,[31872-127, 31872+127]即[31745, 31999]共255个id,代表action的取值。如果某一帧七个维度都是0,那么就是[31872,31872,31872,31872,31872,31872,31872],也就是label是[31872,31872,31872,31872,31872,31872,31872]。关键问题解答vla的输入不包含机器人当前state,与后序的先进模型的差异。vla没有chunck概念?7维数据,需要自回归解码递归生成。最后的维度是[batch, 7] ?以下来自deepseek回答,不确定准确性Q1: 7维动作是一次性生成的吗?否!OpenVLA通过自回归逐Token生成动作序列(每个时间步输出一个动作Token),最终通过解码器将Token序列还原为连续的7D动作轨迹。Q3: 如何保证动作的物理合理性?后处理:对生成的7D动作进行运动学/动力学验证。训练数据偏差:数据集中仅包含可行动作,模型隐式学习约束。基于diffusionπ0架构其核心思想是在预训练好的视觉语言模型(VLM)基础上添加一个“动作专家”(action expert),通过流匹配(flow matching)的方式生成连续的高频控制指令。整个架构可以概括为:预训练VLM Backbone利用 PaliGemma 等大规模预训练的 VLM,将图像和文本信息嵌入统一的表示空间,继承了互联网规模的语义知识和视觉信息提取能力。跨机器人平台数据论文中使用了来自 7 种不同机器人配置、68 个任务的大规模数据(总计约 10,000 小时),实现跨平台、跨任务的联合训练,从而提升模型的泛化能力。动作生成 via Flow Matching针对连续动作生成的挑战,论文采用了一种基于扩散思想的流匹配方法(flow matching),使得模型能够生成高频(例如 50Hz)且精细的动作序列。与传统 autoregressive 离散生成方法相比,流匹配可以更好地处理连续控制信号和复杂动作分布。混合专家(Mixture of Experts)设计模型内部将输入分为两大部分:一部分(图像和文本)走 VLM backbone;另一部分(机器人状态和动作)通过专门设计的“动作专家”处理,这种设计有助于更好地融合预训练知识和机器人特定的控制需求。训练流程:预训练 + 后训练类似大语言模型的训练流程,π0 模型的训练分为两个阶段:预训练阶段:利用海量、但可能质量参差不齐的多任务、多平台数据,使模型具备广泛的基础能力和恢复错误的能力。后训练(微调)阶段:使用高质量、任务特定的数据对模型进行微调,从而获得更高效、流畅和鲁棒的动作执行策略。后训练阶段能够显著提升模型在复杂、多阶段任务(如叠衣服、组装盒子等)上的表现。添加链接描述这篇博客讲的更详细一些,输入输出,论文翻译:论文翻译vlm模型PaliGemma一个PaLI-Gemma模型,结合了Gemma语言模型和SigLIP视觉模型结合代码学习PaliGemmaWithExpertModel类模型基本结构,gamma_pytorch.py,封装为PaliGemmaWithExpertModel类,主要包含一个VLM以及一个专家结构的vlm。self.paligemma=PaliGemmaForConditionalGeneration(config=vlm_config_hf)self.gemma_expert=GemmaForCausalLM(config=action_expert_config_hf)models=[self.paligemma.language_model,self.gemma_expert.model]以上代码中的self.paligemma.language_model即预训练的vlm,self.gemma_expert.model(结构:GemmaForCausalLM)即动作专家模型。两个模型并非简单的前后堆叠,有一个复杂的结构(待学习)GemmaForCausalLM是一个带MoE结构的LLM模型,这里为何被用作了动作生成模型?flow matching是生成模型的一种算法,和扩散模型相同,还是要依赖模型生成特征,前者生成速度向量,后者生成噪声。模型可以用unet,也可以用Dit模块,这里只是用了LLM的结构而已。模型输出都是时序的三维结构!PaliGemmaWithExpertModel.compute_layer_complete两个模型的推理及特征融合的函数,主要是两个for循环,然后分别提取特征,特征拼接进行attention。流程大概清楚,内种细节仍不甚清楚。PaliGemmaWithExpertModel.compute_layer_complete条件归一化条件归一化一般用于不同特征尤其跨模态特征融合的时候,进行特征的归一化,条件归一化可借助模态专属条件向量,对各模态特征做针对性缩放与平移,让不同模态特征处于相近分布区间。与普通的BN不同,不是固定的可训练的参数β γ,引入另一模态的特征充当归一化的条件变量,进行归一化维度普通BN(批量归一化)条件归一化(代码中实现)输入依赖仅依赖当前批次的特征数据(hidden_states),无外部条件输入。依赖特征数据(hidden_states)+ 外部条件(adarms_cond),条件信号参与归一化参数调整。核心计算步骤1. 计算批次内特征的均值/方差;2. 用固定的可学习参数(gamma/beta)缩放和平移;3. 全程无外部信号干预。1. 计算批次内特征的均值/方差(基础步骤同BN);2. 外部条件(adarms_cond)通过映射生成动态参数(如动态gamma/beta);3. 用动态参数对特征缩放和平移,而非固定参数。参数特性缩放(gamma)、平移(beta)是全局固定的可学习参数,所有样本共享同一套参数。缩放、平移参数是动态生成的,由外部条件决定,不同条件对应不同参数,样本间参数可变化。# Define final norm computation function for gradient checkpointingdefcompute_final_norms(inputs_embeds,adarms_cond):outputs_embeds=[]fori,hidden_statesinenumerate(inputs_embeds):out_emb,_=models[i].norm(hidden_states,cond=adarms_cond[i])outputs_embeds.append(out_emb)returnoutputs_embedsPI0Pytorch类这是pi模型完整的模型定义,定义在pi0_pytorch.py,vlm和动作专家vlm的结合体PaliGemmaWithExpertModel类,作为pi模型类的一个成员变量。defforward(self,observation,actions,noise=None,time=None)-Tensor:"""Do a full training forward pass and compute the loss (batch_size x num_steps x num_motors)"""images,img_masks,lang_tokens,lang_masks,state=self._preprocess_observation(observation,train=True)ifnoiseisNone:noise=self.sample_noise(actions.shape,actions.device)iftimeisNone:time=self.sample_time(actions.shape[0],actions.device)time_expanded=time[:,None,None]x_t=time_expanded*noise+(1-time_expanded)*actions#当前时刻的采样状态,或当前时刻拥有的图像u_t=noise-actions#场向量,模型需要预测的真值,也可以简单理解为速度v#前缀嵌入,嵌入内容为图像和文本,输入到vlm#这里的文本,是已经经过PaligemmaTokenizer编码后的token了#PaligemmaTokenizer中,pi0就是文本token化,0.5是文本加state组合起来的tokenprefix_embs,prefix_pad_masks,prefix_att_masks=self.embed_prefix(images,img_masks,lang_tokens,lang_masks)#后缀嵌入,嵌入内容为state、当前时刻拥有的图像和时间,输入到动作专家模型#与前缀对应,因为pi0.5已将state输入到前缀向量,后缀仅在pi0模式下经MLP后拼接到后缀向量#adarms_cond是vlm的输入参数,门控信号,用来控制特征融合的权重,仅0.5模式有效suffix_embs,suffix_pad_masks,suffix_att_masks,adarms_cond=self.embed_suffix(state,x_t,time)if(self.paligemma_with_expert.paligemma.language_model.layers[0].self_attn.q_proj.weight.dtype==torch.bfloat16):suffix_embs=suffix_embs.to(dtype=torch.bfloat16)prefix_embs=prefix_embs.to(dtype=torch.bfloat16)pad_masks=torch.cat([prefix_pad_masks,suffix_pad_masks],dim=1)att_masks=torch.cat([prefix_att_masks,suffix_att_masks],dim=1)att_2d_masks=make_att_2d_masks(pad_masks,att_masks)position_ids=torch.cumsum(pad_masks,dim=1)-1# Prepare attention masksatt_2d_masks_4d=self._prepare_attention_masks_4d(att_2d_masks)# Apply gradient checkpointing if enableddefforward_func(prefix_embs,suffix_embs,att_2d_masks_4d,position_ids,adarms_cond):(_,suffix_out),_=self.paligemma_with_expert.forward(attention_mask=att_2d_masks_4d,position_ids=position_ids,past_key_values=None,inputs_embeds=[prefix_embs,suffix_embs],use_cache=False,adarms_cond=[None,adarms_cond],)returnsuffix_out#vlm和动作专家vlm的推理,PaliGemmaWithExpertModel,(bs, 10, 1024)suffix_out=self._apply_checkpoint(forward_func,prefix_embs,suffix_embs,att_2d_masks_4d,position_ids,adarms_cond)#截取chuncksize维度,对齐action维度,可能vlm输出的维度大?suffix_out=suffix_out[:,-self.config.action_horizon:]#(bs, 10, 1024)suffix_out=suffix_out.to(dtype=torch.float32)# Apply gradient checkpointing to final action projection if enableddefaction_out_proj_func(suffix_out):returnself.action_out_proj(suffix_out)#使用一个全连接head转换为action维度,1024-32v_t=self._apply_checkpoint(action_out_proj_func,suffix_out