成都专业网站推广公司注册100万公司每年费用多少
成都专业网站推广公司,注册100万公司每年费用多少,许昌市城市建设局网站,零食网站模板下载前言
截止到25年7月份#xff0c;本博客内已经陆续解读了physical intelligence公司推出的一系列模型/算法#xff0c;成了一个大系列#xff0c;比如
π0 涉及对其原理的解读、lerobot pi0代码的解析、openpi官方代码的解析#xff0c;以及我司对其的微调FASTHi Robotπ…前言截止到25年7月份本博客内已经陆续解读了physical intelligence公司推出的一系列模型/算法成了一个大系列比如π0涉及对其原理的解读、lerobot pi0代码的解析、openpi官方代码的解析以及我司对其的微调FASTHi Robotπ0.5π0.5的KI改进版这家公司确实因为牛人很多加之很多又是斯坦福、UC伯克利等高校的副教授/研究员带了一堆聪明的博士生(要知道现在具身科研的主力一半都是TOP高校的博士生)所以使得他们产出很快、很多这不在25年6.9日他们又推出了本文要介绍的实时动作分块技术使得VLA也可以做点燃火柴、插入网线的高精度任务由此证明了VLA也是可以做高精度任务的不一定只有RL或RL参与的算法才能做高精度任务顺带小小感慨一下本博客π0系列的文章 已经十多篇了搞vla必读而我和我司『七月在线』组织的π0交流群成员来自各大top985以及各大科研院所、公司我们这帮人见证和推动了中国具身的飞跃且我司也会在中国具身科技发展史上留下浓墨一笔期待与更多同行、同仁、工厂多多合作25年12月中旬更新因为PI公司后续又推出了一个Training-Time RTC的工作其《在训练时模拟推理延迟(承认既定事实专心预测后续动作)消除推理阶段的计算开销让π0.6完成箱子装配与咖啡制作》故又再次注意到了本文介绍的RTC考虑到原RTC论文只提供了伪代码实现 无法运行故我于25年12.15上午在文末提供了一份RTC的Python实现并把Python代码和论文中的公式做了一一对应且详尽细致解读了下第一部分 动作分块流策略的实时执行1.1 引言、相关工作、预备知识与动机1.1.1 引言如原论文所说与聊天机器人和图像生成器不同信息物理系统始终在实时环境中运行。当机器人在“思考”时其周围的世界仍然根据物理定律不断演化。因此输入和输出之间的延迟会对性能产生切实的影响对于一个语言模型来说生成速度快或慢的区别通常只是让用户感到满意或恼火而对于一个机器人动作模型而言这种差异则可能意味着机器人要么把一杯热咖啡稳稳递到你手中要么把它洒在你的腿上不幸的是现代大规模机器学习的高效能不可避免地伴随着高延迟这一副作用。LLMs、VLMs以及VLAs都拥有数十亿个参数 [8,29,5,4,57]这些模型不仅运行缓慢而且还难以部署到诸如移动机器人等边缘设备上的重型硬件从而使远程推理带来更多额外开销虽然边缘硬件会随时间改进但随着机器人数据集规模扩大最优视觉语言动作模型(VLA)的复杂度也将同步提升[28]因此要在实时控制问题中有效应用大模型就必须引入某种形式的异步机制也就是说模型必须在执行前一个动作的同时思考其未来动作动作分块(action chunking)[68,33,11]即模型在每次推理调用中输出并执行一个由多个动作组成的序列提供了一个部分性的解决方案。尽管动作分块已经在灵巧操作领域取得了多项最新的最优结果[5,4,58]但它仍然饱受时延问题的困扰即分块会牺牲系统对外部刺激的反应能力并且还会在不同分块的衔接点引入不连续性因为相邻分块可能会在学习到的动作分布中跳转到不同的模式或“策略”此类异常对基于学习的系统尤为有害因为它们会在动力学上造成分布偏移而模型很可能并未具备应对这种偏移的能力朴素的平滑策略『例如将多个预测结果进行平均[68]』并不能保证产生有效动作反而可能使问题更加严重(例如见图2如果没看明白没事下文会再详细解释该图)一个良好的实时系统必须产生一致且连续的控制信号在融合最新观测的同时既不扰乱环境的自然动力学过程也不削弱模型产生正确动作的能力在本研究中作者提出了实时分块(RTC)方法其对应的paper为Real-Time Execution of Action Chunking Flow PoliciesSubmitted on9 Jun 2025其对应的github为Physical-Intelligence/real-time-chunking-kinetix其将异步动作分块建模为一个图像填补(inpainting)问题即算法在执行上一段动作块的同时生成下一段动作块冻结那些由于推理延迟而必然会被执行的动作并对剩余部分进行“图像填补”操作Our algorithmgenerates the next action chunk while executing the previous one,freezing the actionsthat areguaranteed to be executed(due to inference delay) and “inpainting” the rest.——————该方法适用于任意基于扩散 [22] 或基于流 [36] 的 VLA并且仅在推理阶段运行无需对现有训练方案做任何修改1.1.2 相关工作第一对于动作分块与VLA动作分块技术部分受到人类运动控制的启发[32]其近年来已成为视觉运动控制模仿学习领域的事实标准[67,11]从人类数据中学习生成动作分块需要具有表现力的统计模型如变分推断[67,18]、扩散模型[11,12,68,67,45,58]、流匹配[5,6]、向量量化方法 [33,3,43]或字节对编码 [46]最近这些方法中的一些已扩展到数十亿参数催生了VLA[7,13,29,5,70,10,9,69,23,46,36]即基于预训练视觉语言模型骨架构建的大型模型且由于随着适配不断增长的机器人数据集 [13,28,61,14,40,26]以及来自视觉-语言预训练的互联网知识VLA 在通用机器人操作任务中取得了令人瞩目的成果此外应用于真实机器人时动作分块策略通常与底层高频控制回路如PID控制器协同工作后者PID控制器将策略输出(如关节位置)转换为硬件特定的控制信号(如关节力矩)在此类场景中动作分块策略可视为级联控制的一种形式[14]其中学习策略作为最外层控制回路运作然而也存在例外例如作者的仿真实验直接采用输出力矩和力的学习策略。因此关于级联控制理论与学习型动作分块策略交叉领域的研究作者表示将留待未来工作探讨第二对于降低推理延迟提升模型实时性能的一个自然方法就是简单地加快其运行速度例如consistency policy [48] 通过蒸馏扩散策略来省略昂贵的迭代去噪过程Streaming diffusion policy [22] 提出了一种替代的训练方法使每个控制器时间步仅需极少的去噪步骤Kim 等人 [30] 通过并行解码增强了 OpenVLA [29]从而省略了昂贵的自回归解码更广泛而言针对扩散模型[51,37,55,16] 和大型 Transformer [31,24,34] 的推理速度优化已有大量研究文献然而这些方法都无法将推理成本降到一次前向传播以下。只要这一步前向传播所需时间超过控制器的采样周期要实现实时执行仍需其他方法第三对于图像修复与引导技术已有大量文献探讨了利用“预训练扩散模型和流模型”进行图像修复的方法 [47,54,39,41]在本文介绍的工作中作者将此类方法 [47] 融入了他们新颖的实时执行框架并进行了必要的修改(即软掩码和引导权重裁剪)以适应他们的应用场景在序列决策制定方面Diffuser [25] 首次提出了基于扩散的图像修复方法用于在长期规划中遵循状态和动作约束尽管其修复方法并非基于引导机制此外Diffuser 及其他相关工作 [63,1] 也通过价值函数对扩散模型进行引导以解决强化学习问题作者宣称他们的工作具有独特性因为这是首次将图像修复或引导方法应用于机器人的实时控制『Our work is distinct in that it is the first to apply either inpainting or guidance to real-time control.』第四对于实时执行早在VLA出现之前实时控制就已被广泛研究与动作分块类似模型预测控制『MPC[50]』在递进的时间范围内生成计划与作者的方法一样它将执行与计算并行化并利用前一个分块为下一个规划提供热启动————尽管近期将学习方法与MPC结合的研究已在狭窄领域中展现出实时控制能力[52,20]但这些方法仍依赖于显式手工构建的动力学模型及代价函数『Though recent works combining learning methods with MPC have demonstrated real-time control capabilities in narrow domains [ 53 , 21], they rely on explicit, hand-crafted dynamics models and cost function』使其在非结构化环境下的应用变得困难而VLA正是在这些领域获得了广泛应用另一方面在强化学习领域已有多项研究提出了时延决策方法[56,15,53,62,65,66]。然而这些方法并不总能适用于模仿学习且均未利用动作分块技术巧的是在25年7月10日前后RL用到动作分块了详见下一篇博客的解读最近出现的分层VLA设计[57,4-GR00T N1] 将模型拆分为System 2(高层规划)和System 1(低层动作生成)两个部分用于高层规划的System 2组件承载VLA的主要能力但运行频率较低而用于低层动作生成的System 1组件则轻量且快速这种方法与本文介绍的方法相互独立并具有自身的权衡(例如需要限制System 1组件的规模并需要其专门的训练方法)第五对于双向解码与本研究最为相关的前期工作是双向解码(BID[38]该方法通过拒绝采样使预训练的动作分块策略能够实现完全闭环控制————尽管Liu等人[38]未考虑推理延迟但BID算法依然可以用于实现与本文基于引导的图像修复(inpainting)相同的效果作者在模拟基准测试中将BID与RTC进行了对比发现BID的性能不如RTC同时计算资源消耗却显著更高1.1.3 预备知识与动机如原论文所述作者介绍了本工作所涉及的预备知识与动机比如从一个动作分块策略开始记作其中是一个未来动作分块是观测值表示控制器的时间步且称为预测时域当动作分块策略被执行时仅执行每个分块中的前个动作然后策略会生成一个新的分块作者称为执行视野它通常比预测视野短但仍远大于1例如此可参见[11,5,23]分块执行在牺牲反应性的前提下确保时间一致性较长的执行时域会降低策略对新信息的响应能力而较短的执行时域则会增加发生模式跳变的可能性即由于不同块之间的不连续性而产生的生硬、抖动式行为在本文中作者考虑使用条件流匹配[35] 训练的策略『当然该方法也可以通过在推理时将扩散策略转换为流策略从而以兼容扩散策略[48, 18]』为了从一个流策略中生成一个动作块首先从标准高斯中采样随机噪声然后利用更新规则将流的速度场一个已学习的神经网络从积分到1此过程定义为公式1其中表示流匹配的时间步表示去噪步骤的数量现在令为控制器采样周期即单步控制时长表示策略生成一个动作块所需的时间如果称一个系统是实时系统则意味着其能保证在固定时间约束内对一个事件(接收观测值)产生响应(在本场景中动作若那么满足实时约束是很容易的因为在两个控制器时间步之间可以生成完整的一个块然而对于现代VLAs这几乎是不可能实现的。例如在一块NVIDIA RTX 4090 GPU上具有30亿参数的π0 VLA 仅在KV 缓存预填充上就花费了46 ms这还不包括任何去噪步骤[5]而目标控制频率为50Hz ()在移动操作的远程推理场景中即使在使用有线连接且条件完美的情况下π0 的网络时延也达到13 ms。而在更为现实的环境下仅网络开销就很容易超过20msKim 等人[31] 专门针对推理速度对70 亿参数的OpenVLA 模型[30] 进行了优化但即便在服务器级A100 GPU 上其延迟也不过降至321 ms至于朴素的同步推理『许多先前工作的默认设置[5, 29, 8, 23, 30, 58]』 则更不用说了因为其仅在执行时限结束后才开始推理并等待策略生成下一个动作组块即当使得在分块之间引入了明显的停顿这不仅会减慢执行速度还会改变机器人的动态特性从而导致训练与评估之间出现分布偏移如上使得为实现实时策略必须首先引入异步推理机制提前启动推理过程使其与动作执行并发进行作者定义并将该量称为推理延迟对应于从接收到到获得动作块之间的时间间隔令表示从观察到后生成的chunk At 的第个动作如果当前正在执行并且希望在第步切换chunk那么异步算法必须在时刻开始推理然而由于策略在生成时无法知道在步骤到之间会发生什么因此与之间的切换点可能是任意不连续的并且超出了分布范围若动作正在执行中且期望执行时限为则异步算法必须在时刻启动推理即只要满足该策略就会满足实时约束并保证在需要时总有一个可用的动作即如果H8s6d2则始终有动作可以用但如果H8s6d4则在t 5和t6时则没动作可以用了(因为s6故需要执行6个动作)然而由于在生成时策略无法知道在步与之间会发生什么因此在与之间的切换点可能出现任意程度的不连续性并落在分布之外类似于执行时限过短的情形这一策略会导致动作抖动并且在延迟增大时这种现象会显著恶化具体参见下图图2这是连续两个块之间典型分叉的一个示例。推理在第 3 步和第 4 步之间开始。正在执行的原始块 {}黑色计划从障碍物上方通过而新生成的块 {}红色则计划从下方通过。然而{} 要到 7 步之后的时刻才可用一个简单的异步算法可能会从跳转到从而导致非常高的、超出分布的加速度——即机械臂突然剧烈抖动到某个位置————至于时间集成 [67]即在块之间进行插值可以减少加速度但会产生较差的动作1.2 基于图像修复的实时分块技术实时执行的关键挑战在于保持各分块之间的连续性当新分块可用时前一个分块往往已经执行完部分因此新分块必须与前一个分块“兼容”。与此同时新分块还应当融合新的观测信息以保证策略不会丧失反应和纠正的能力————作者的关键见解是将实时分块问题视为一次图像修复(inpainting)问题为了使新分块“兼容”必须利用与前一分块剩余动作重叠的时间步——例如下图的到。在新分块中最开始的动作不能被使用因为当新分块变为可用时这些时间步已经过去因此将这些动作“冻结”为已知会被执行的值是合理的作者的目标是在保证该冻结前缀一致性的前提下补全新分块的剩余部分(如上图的a11-a15如下图图3的a4-a10)这类似于修复一幅被移除部分的图像总之上图图3展示了在实时分块过程中动作生成如何关注前一个动作块更多下文会详解看到上面这我觉得可能还是会有些朋友懵为一目了然我再补充说明下简单一句话RTC 让机器人“边做边想”不耽误干活更具体地说它用了一种“异步流水线”的小技巧先“锁”住已经做过的动作机器人每走一步后台就开始算下一步。但算得没那么快比如慢了 4 拍。等新的动作算出来时机器人已经把前 4 拍的动作做完了RTC 就把这 4 拍“锁死”保证新算出来的动作必须从这里接着往下走不会前后脱节再“续”出还没做的动作锁完以后剩下没做的部分就由模型继续往后编。它会参考刚才那 4 拍的动作风格把后续动作补得又顺又自然就像画画时把缺的那一角按原画风补全举个日常例子一辆开着自动驾驶模式的汽车(本质就是机器人)在高速上快速行驶此时自驾算法看到前面有左转的指示牌于是自驾算法开始推理2s后 自驾算法给出“左转”的指令可这2s的时间内车子已经开过左转指示牌50米远了然后听到指令后不得不猛打方向盘此时会导致车子剧烈晃动甚至翻车RTC给出的策略是自驾算法看你正在直行心里清楚“我推理的这2秒内他肯定会继续直行这部分是改变不了的于是自驾算法不再规划现在的路而是直接规划2秒后的路。他想“等我把话说完车子应该已经到了‘大树’旁边。所以我的指令是——‘从大树那里开始’向左转。”因此车子边开自驾算法边想。等自驾算法把指令说完时车子刚好开到大树旁边指令和车子的当前位置完美无缝衔接过弯如丝般顺滑1.2.1推理阶段的流匹配补绘确保新动作跟冻结部分吻合图像修复是迭代去噪框架(如扩散和流匹配)已知的优势之一作者基于Pokle 等人[47] 提出的免训练图像修复算法进行改进该算法本身基于伪逆引导IIGDM[54]该算法通过在每一步去噪时向学习到的速度场中添加一个基于梯度的引导项见上文提到的这个公式1The algorithm operates by adding a gradient-based guidance term to the learned velocity fieldvat each denoising step (Equation 1)以促使最终生成结果匹配某个目标值其中是预期结果的受损版本that encourages the final generation to match some target value,Y, which is a corrupted version of the desired result.在图像修复的情况下损坏操作表现为掩码处理是被掩码的图像而预期结果是与在非掩码区域 保持一致的完整图像针对作者设定的IIGDM 梯度修正为——分别定义为为公式2 3 4其中是最终完全去噪动作片段的估计W 是掩码作者在这里滥用了记号将,和视为维度为的向量其中是每个动作的维度因此引导项是一个向量-雅可比积可以通过反向传播计算。引导权重裁剪是作者新增的内容作者发现如果没有它在控制问题中常用的较少去噪步数下算法会变得不稳定——比如避免因为去噪步数少比如n5导致动作乱飞1.2.2 软掩码以提升跨片段连续性在实际操作中仅仅利用前一个动作片段的前几个时间步进行原生图像修复通常不足以确保新的动作分块能够采用一致的策略尤其当较小时例如参见图4——说白了有时新旧分块的策略差别太大接起来还是不顺ΠGDM校正并不完美且较小的会导致指导信号较弱这可能会导致新的分块仍然可能切换策略并导致不连续性『比如当前分块计划让火柴划盒子顶部新分块却想划底部直接切换会让机器人动作猛地一跳』作者的解决方案如图3 所示是通过不仅仅考虑前个重叠动作而是考虑所有个重叠动作(上面说过了H是预测范围s是执行范围)来赋予作者的策略更多跨分块的连续性作者通过软掩码(Soft Masking)实现这一点将设置为实值权重而不是1 和0前d 个动作的权重为1相当于是必然会被执行的如果推理在执行完之后开始且推理延迟为则新生成的块要等到被消耗后才能使用。因此被“冻结”并以完全的引导权重1进行关注新分块的最后s 个动作则不与前一个区块重叠的部分因此权重为0最后的个动作超出了前一个块的末尾需要重新生成。执行视野是一个超参数满足的约束中间的动作则赋予从1到0指数衰减的权重以反映距离未来越远的动作应当被赋予更高的不确定性在中间区域前一个块中的动作可用但可能会被更新因为推理会在被需要之前完成。该区域以指数递减的引导权重进行关注由此得到的W的表达式为——定义为公式5直观来看W调节了对前一块中每个相应动作所给予的“关注度”简言之软掩码就像在两段动作间加了个“缓冲带”让动作接得更自然举个例子假设预测范围H16执行范围s5延迟d4RTC会给前4个动作(即图中的到已执行)的权重1完全冻结接下来的7个动作(即到可能执行)的权重从1逐渐降到0最后5个动作(即到全新生成)的权重是0这样新分块在点火柴时会更“尊重”前一段的划火柴动作慢慢过渡到点燃蜡烛而不是突然换个策略还可以再想象你正在看一部连续剧H16 表示总计有 16 集你已经看完了 4 集d4这 4 集的内容板上钉钉不能改接下来 7 集 是“预告片”可能拍也可能不拍所以它们的“戏份”从 100% 慢慢降到 0%最后 5 集还没写剧本完全自由发挥软掩码就像剪辑师在两段剧情之间加了“淡入淡出”老剧情音量先保持最大再慢慢调低新剧情音量从 0 逐渐拉高。于是观众不会觉得“咔”一下换台而是感觉剧情顺滑地接下去了1.2.3 实时分块的完整算法流程(含论文中的伪代码和我写的Python代码)如上可知RTC 的核心思想是异步推理 (Asynchronous Inference)通过将动作生成视为一个Inpainting (修补) 问题利用上一块(Chunk)未执行完的动作来“引导”新块的生成从而实现平滑过渡作者在算法1 中展示了完整的实时分块系统参见图3控制器通过GETACTION 与RTC的算法进行交互该函数每隔调用一次用于消耗一个动作并提供下一个观测INFERENCELOOP在后台线程中运行以确保始终有可用的动作它通过保留过去延迟的缓冲区来预测下一个延迟执行范围s 可以在不同分块之间变化用户提供一个期望的最小范围对于给定分块的实际范围为其中是在计算下一个分块时遇到的延迟最后算法在GUIDEDINFERENCE 中描述了带有软掩码的修复过程该过程明确地定义了去噪函数——即上文提到的公式3并计算向量-雅可比积这可以通过反向模式自动微分实现[2]可以看到Algorithm 1 (Lines 24-29)forto 1 ... do (循环开始)Compute vector-Jacobian product ... via autodiff (在循环内部计算导数/疯狂算数学)Integration step ... g (把修正加进去)即模型每进行一步思考(Denoising Step)算法都会计算一次复杂的导数向量-雅可比积强行把模型生成的动作“头”按在“既定事实”上为了方便大家更好的理解我还是把上述整套伪代码改写成Python代码并再给大家逐一分析下这个算法主要分为三个部分分别对应代码中的三个方法A. get_action: 与环境的实时交互这是前台线程必须满足实时性要求Real-time constraint功能接收最新的观测并从当前缓存的动作序列中“切”出下一步动作发送给机器人关键点它只负责读和取不会被繁重的推理过程阻塞def get_action(self, o_next): [Algorithm 1: GETACTION] 由控制器以固定频率调用 (如 50Hz) with self.mutex: # 1. 更新观测 self.o_cur o_next # 2. 通知后台线程观测已更新 (如果是新的一步) self.t 1 self.cond.notify() # 3. 返回当前时间步的动作 # 注意如果 t 超出了 H通常需要处理异常但 RTC 设计保证新块会及时替换 if self.t self.H: current_action self.A_cur[-1] # Fallback else: current_action self.A_cur[self.t - 1] return current_actionB. inference_loop: 后台异步推理这是后台线程负责在机器人执行动作的同时“预判”未来的动作。延迟估计 ()代码维护一个队列delay_queue记录过去几次推理实际花费的时间步数。在开始新推理时取最大值作为保守估计快照 ()在开始推理的一瞬间记录下当前正在执行的动作序列中剩余未执行的部分。新生成的动作序列必须在这个基础上“长”出来不能发生突变def inference_loop(self): [Algorithm 1: INFERENCELOOP] 后台循环线程负责生成新的动作块 while self.running: with self.cond: # 1. 等待直到满足最小执行时间 s_min # 同时也确保有新的观测数据进来 while self.t self.s_min: self.cond.wait() # 2. 获取用于推理的快照数据 s self.t # 已执行的步数 # 提取上一块中剩余未执行的部分 A_prev (用于Inpainting) # A_prev A_cur[s : H] if s self.H: A_prev self.A_cur[s:].clone() else: A_prev torch.empty(0) # 上一块已耗尽 obs self.o_cur # 3. 估计延迟 d d_est max(self.delay_queue) # --- 释放锁进行繁重的推理计算 (With M released) --- start_time time.time() # 4. 执行引导式推理 (核心算法)下文有单独实现 A_new self.guided_inference(obs, A_prev, d_est, s) inference_time time.time() - start_time # --- 重新获取锁更新状态 --- with self.mutex: # 5. 只要新块可用立即交换 (Swap) self.A_cur A_new # 6. 重置 t使其指向新块的正确位置 # 新块生成花费了实际延迟时间因此我们需要跳过已经过去的时间步 # 实际延迟计算逻辑可能需要根据具体的 system clock 调整这里简化为 s # 论文伪代码写的是 t t - s意味着新块从索引 t-s 开始用 (通常是0附近取决于对齐) self.t self.t - s # 7. 记录实际延迟 (转换为时间步) # 假设 control_dt 是控制周期例如 0.02s control_dt 0.02 actual_delay_steps int(inference_time / control_dt) self.delay_queue.append(actual_delay_steps)C. guided_inference: 引导式 Inpainting (数学核心)这是论文最核心的贡献位于代码的 guided_inference 函数中。它利用 Flow Matching (或者 Diffusion) 的迭代去噪过程进行动作生成Soft Masking (软掩码):为了解决拼接处的跳变Jerky movements算法基于公式5定义了一个权重矩阵(推理延迟期)这部分时间在推理结束时已经过去了动作必须完全等于中已规划的值因为它们将被实际执行(过渡期):指数衰减这允许新生成的动作平滑地偏离旧计划去响应新的观测(新未来):完全由新观测决定def guided_inference(self, obs, A_prev, d, s): [Algorithm 1: GUIDEDINFERENCE] 基于流匹配 (Flow Matching) 和 Inpainting 的生成过程 H self.H action_dim self.A_cur.shape[1] # 1. 计算 Soft Masking 权重 W [Eq. 5] [cite: 162] # W 决定了我们多大程度上通过 A_prev 来约束新动作 W torch.zeros(H, action_dim) # 重叠区域长度 overlap_len A_prev.shape[0] # 填充 A_prev 到长度 H (右侧补零虽然补零部分权重为0不影响) A_prev_padded torch.zeros(H, action_dim) if overlap_len 0: A_prev_padded[:overlap_len] A_prev for i in range(H): if i d: # 冻结区域必须完全匹配上一块因为这些时刻在推理完成前就会被执行 W[i] 1.0 elif d i H - s: # 中间过渡区域指数衰减权重允许平滑修正 # c_1 是衰减系数 c_1 (H - s - i) / (H - s - d 1 1e-6) W[i] c_1 else: # 自由生成区域新产生的未来动作权重为 0 W[i] 0.0Guidance Gradient (引导梯度)先后基于公式3、2、1在去噪的每一步计算当前(最新)生成的估计值——如上文提到过的是最终完全去噪动作片段的估计与上一块的差异背后本质是这两、的重叠区域 得是非常像的利用 PyTorch 的 autograd 计算这个差异相对于输入噪声的梯度。这告诉模型“请在这个方向上修改噪声使得生成的动作更像上一块的延续”————接下来我们具体逐一的实现首先实现公式3# 2. 初始化噪声 A^0 ~ N(0, I) A_tau torch.randn(H, action_dim) # 3. 迭代去噪循环 (Euler Integration) dt 1.0 / self.n for k in range(self.n): tau k / self.n # 当前时间步 [0, 1] t_tensor torch.tensor(tau).float() # 开启梯度计算因为我们需要对 input 求导来计算 Guidance A_tau.requires_grad_(True) # 预测速度场 v v_pred self.model(A_tau, obs, t_tensor) # --- 计算 Guidance (Inpainting) --- # 估计最终生成的动作 A_hat^1 [Eq. 3] # A_hat^1 A_tau (1 - tau) * v_pred A_hat_1 A_tau (1 - tau) * v_pred其次是围绕公式2的实现而从上可知公式2如下所示——其背后本质就是要平滑去噪咋做到呢把神经网络原始的“意图”和我们想强制的“平滑约束”加在一起————对此我们把其中的下面这部分定义为引导项——它将引导新块的生成 本质实则就是引导去噪了然后将其一拆为二第一步先算加权误差项这里的Y是目标——即上一块的动作『相当于计算当前(最新)生成的估计值——如上文提到过的是最终完全去噪动作片段的估计与上一块的差异』# 计算加权误差项 e # e (A_prev - A_hat_1) * W # 注意这里我们只关心重叠部分的误差 error (A_prev_padded - A_hat_1) * W第二步再算Vector-Jacobian Product# 计算 Guidance 梯度 g [Eq. 2 Algorithm 1 line 27] # g e * d(A_hat_1)/d(A_tau) # 这本质上是 error 对 A_tau 的梯度 # 我们可以通过反向传播计算这个向量-雅可比积 # 这里的 Loss 本质上是 || (A_prev - A_hat_1) * sqrt(W) ||^2 的导数相关项 # 简化的实现方式是直接对 error 求和后 backward # 但论文公式 explicit 写的是 Vector-Jacobian Product # 技巧由于我们需要 grad(A_hat_1, A_tau) * error # 这等价于 torch.autograd.grad(A_hat_1, A_tau, grad_outputserror) g torch.autograd.grad(outputsA_hat_1, inputsA_tau, grad_outputserror, retain_graphFalse)[0]————再补充解释下在数学上需要计算“最终估计值与旧动作的差距”相对于“当前输入噪声”的梯度。在 PyTorch 中torch.autograd.grad 的 grad_outputs 参数正是用来实现(向量-雅可比积) 的这里的 error 就是那个向量而 A_hat_1 对 A_tau 的导数就是雅可比矩阵Integration (更新)最后把公式2代入进公式1中将模型预测的速度场加上引导梯度受裁剪限制————接下来再看具体的实现首先在上面我们已经实现了公式2的后半部分——即引导项其次为了防止在附近梯度爆炸论文引入了裁剪而其中的是怎么计算的呢好办根据公式4可得# 计算 Guidance 权重限制 # term min(beta, (1-tau)/(tau * r_tau^2)) # r_tau^2 定义见 Eq. 4: (1-tau)^2 / (tau^2 (1-tau)^2) if tau 0: weight_clip self.beta # 避免除以0第一步直接用 beta else: r_tau_sq ((1-tau)**2) / (tau**2 (1-tau)**2) val (1 - tau) / (tau * r_tau_sq) weight_clip min(self.beta, val)动作更新步 (Integration Step) - Equation 1根据论文公式 (Eq. 1)做标准的欧拉积分更新但加入了引导项# 4. 更新步 (Integration Step) [Eq. 1 Algorithm 1 line 28] # A^{tau1/n} A^tau 1/n * (v weight * g) # dt 对应 1/n dt 1.0 / self.n with torch.no_grad(): updated_v v_pred weight_clip * g A_tau A_tau dt * updated_v A_tau A_tau.detach() #以此作为下一步的输入切断图 return A_tau注意如上述代码中的这一行updated_v v_pred weight_clip * g所述先通过公式2即先做了下面这个操作其中引导项是一个“修正力”用来把动作拉向上一块动作的轨迹以保证平滑连接更新后的速度 (updated_v)这就是公式2 的计算结果相当于在这一步去噪中不使用模型原始输出的速度场而是使用一个基于公式 2 修改后的合成速度场来推动的更新。这确保了生成的动作既符合模型的分布又符合平滑过渡的约束再之后执行公式1// 待更