Month: March 2025

  • 具身智能论文和开源系统之-GraspNet实现思路介绍

    这篇文章将向大家介绍机器人抓取物体方面的一篇论文GraspNet-1Billion[1]和其开源代码[2]的实现思路,GraspNet仅面向单臂机器人抓取物体任务,和RT-1,RT-2较为通用的任务相比有一些不同,他们的对比具体可以参考[3]: 数据集构建:数据收集和标注的方法可以参考[4],其中从DexNet2.0中收集的13种对抗性物体(adversarial objects),对抗性的含义是指表面较为复杂难以标注。由于抓取姿势和传统的视觉标注任务(如目标检测语义分割)等不同,抓取姿势分布在大的连续搜索空间(如图1所示),因此采用了力学(force-closure metric)等物理模型通过在离散化的搜索空间(其中平面一般基于抓取点的附近点云拟合抓取点的切平面的思路去确定,将搜索空间通过两个维度上的离散化即in-plane rotation sampling和depth sampling对抓取pose的搜索空间进行离散化采样),对每种抓取姿势进行评分。为了使得采样姿势多样,在采集数据时,只需要标注第一帧,后续的视频轨迹可以根据记录下来的位姿变换对抓举姿势进行传播计算。 关于夹爪坐标系有两点需要说明:(1)、平行夹爪的原点一般定义为其两个平面内面最下端的中间点,(2)、z轴指向夹爪当前的朝向(夹持物体的方向)。因为在模型生成时,一般在对应物体的表面的采样选择候选抓取点,在机器人RGB-D点云输入网络模型生成抓取位姿后,机械臂需要通过路径规划和轨迹生成实现从当前位置到目标位置的平滑运动。这里的抓取姿势采用7自由度(7-DoF)表示法。如图2所示,网络会预测如下几个部分的量(夹爪pose):(1)approaching vector v,亦即为物体目标点到夹爪原点形成的方向向量;(2) d为目标点和夹爪原点的距离;(3),R为夹爪转轴的旋转状态。 模型结构:采用了多阶段的多任务混合训练,第一阶段为特征提取层,输入为N个点云点,通过PointNet++骨干网络通过FPS(最远点采样策略[5])等过程采样M个特征[6]并通过下采样和上采样实现编码器解码器架构提取M个候选点的环境语义特征;第二阶段接ApproachNet,即为视点(viewpoint,approaching vector。如图2中的v向量)候选生成;第三,在OperationNet和ToleranceNet之前有一个分组和对齐的功能(CloudCrop里进行的实现),这个功能和之前的二阶段目标检测的ROIPooling或ROIAlign的作用类似,对对照说明,第四:OperationNet的功能时对角度进行分类(通过离散化化细粒度的角度范围通过分类实现角度预测,每个角度下对应着一个夹爪宽度预测,因此为3通道,其中k为离散化的depth数目,如一个bin为0.01m,具体的实现参考OperationNet),ToleranceNet的作用为预测每一个抓取姿势的抗干扰能力,其真值的大体思路为在抓取姿势的邻域空间进行评估,如果其邻近抓取空间的抓取分数都大于一定的阈值,则其抗干扰能力相对就高。 References

  • SLAM系列之FAST-LIVO2代码分析-基于直接法和ESKF相结合的VIO算法介绍

    这篇文章将向大家简要介绍FAST-LIVO2开源系统中的VIO部分实现的思路,具体的较为细节的内容在参考引文的链接里,这里对相关思路做一下汇总说明。VIO的实现采用直接法视觉里程计(Direct Visual Odometry)的核心概念,用光度残差衡量同一3D点在当前帧与参考帧的像素亮度差异。 在该系统的VIO算法中,基于ESKF(error state kalman filter)的误差测量方程的相关公式定义和基于光度残差和状态参数(误差状态,如基于旋转的李代数扰动量,平移噪声等)的雅可比矩阵的计算及推导参见[1],其中链式计算中的图像梯度的具体计算方法参考[2]。ESKF的状态更新公式及相关代码说明参考[3]。其中需要说明的是每一个可视点的测量光度误差的计算时,其参考图像帧可能不属于同一个参考帧(每个点云点根据光度一致性,几何约束或其他等条件选择最优的参考帧),而ESKF的每一次迭代都是基于当前的所有的用来优化位姿的地图点集合的光度误差总和进行的。具体的可以参考代码[4]中的详细实现。 函数retrieveFromVisualSparseMap基于当前处理逻辑点云帧(经时间对齐在原始点云帧基础上处理过的点云集合)中的点云集合信息动态提取当前帧可见的特征点,并构建高质量的局部子地图(visual_submap),其中稀疏地图中的可视点会基于点的多个观测,选择最优的patch参考(不同点可能会选择不同的参考图像帧),并根据姿态变换对图像做出对应的放射变换以便后续的光度残差的计算,ESKF基于子地图的可视点的观测状态(光度残差)和IMU的位姿误差运动方程紧耦合优化位姿; 问题:vio中关于地图的构建思路,和lidar的体素地图的关系? 回答:局部地图visual_submap主要用于优化位姿,在函数retrieveFromVisualSparseMap中构建局部稀疏地图的开始时进行重置,而全局地图feat_map为基于体素索引值和视觉点(VisualPoint)集合的hash表结构(unordered_map)。 References

  • SLAM系列之FAST-LIVO2代码分析-基于ESKF的LIO算法介绍

    这篇文章将向大家介绍LIO部分的基于ESKF(error state kalman filter)的误差状态卡尔曼滤波算法来进行位姿优化的一些细节内容。 LIO的ESKF实现的运动方程参考文献[4],其采用基于误差状态卡尔曼滤波器的原理,将系统的运行状态分解为非线性传播的名义状态和线性传播的误差状态;其中名义状态保持非线性状态的传播特性(IMU预积分的过程的imu pose的积分计算),而误差状态通过一阶泰勒展开将非线性问题局部线性化。通过线性模型将误差状态进行传播(参见预积分过程中state.cov协方差矩阵的传播计算,详细说明见文献[4]中)。 VoxelMapManager类的StateEstimation函数则实现了基于lidar和imu紧耦合的ESKF位姿优化算法,其中误差状态传播方程基于IMU的预积分结果,残差测量方程基于Lidar点云的多种误差因素(如基于李代数的旋转扰动量等),这里比较特殊的地方表现在:1、基于误差状态的传播计算,具体的关于误差状态的传播计算方式参考[1],主要在于基于IMU的误差状态传播协方差F_x的定义及误差传播协方差的计算实现[2];2、基于测量误差方法的特殊性(根据名义状态和误差状态的定义,以及基于李代数的扰动模型等便于求导的方法进行的状态定义),点云的测量残差方程的定义基于点云点到匹配平面的距离残差,其雅可比以及ESKF的计算公式推导请参考[5]。 References

  • LLM技术系列之-DeepSeek V1/V2/V3模型结构简介

    这篇文章将向大家简要介绍DeepSeek-V1/V2/V3的模型结构及其发展演化过程。 在介绍DeepSeek的模型结构之前,这里简要复习一下LLM关键的基于Transformer架构图的模型结构的主要知识和技术点。 Transformer的基本架构,包括多头自注意力机制,FFN等关键组件。其中自注意力机制也分为双向的(Multi-Head Self Attention)以及causal的(Masked Multi-head Self Attention),一般双向自注意力模块的用于编码器结构(如BERT,基于WordPiece分词器),主要用于上下文丰富语义信息提取,为下游任务如文本分类等提供很好的文本特征提取功能;causal自注意模块用于解码器架构(如GPT,基于BPE分词器),主要用于文本生成(自回归语言生成,基于之前生成的内容来生成后续的内容,为基于单向时序因果的计算逻辑,通过掩码机制进行计算),如问答系统等的应用,两种模块都会用到的为编码器解码器组合结构(Auto Encoder,双向自注意力结构和caual+交叉自注意力模块),主要用于机器翻译,序列转换等应用任务。 DeepSeek的文本生成,数学推理,代码补全等任务上基于传统的Transformer的解码器架构框架,但在两个核心组件上进行了调整:1为MSA到MLA(Multi-head Latent Attention)的调整;2为FFN到MoE组件的调整。下面将一一进行简要介绍。 MLA组件和原始Transformer版本的MSA的结构类似,差异仅仅在于对于token embedding的输入维度进行了降维,将其映射到隐空间上进行表示。可以理解为将token的embedding维度进行了压缩后进行的自注意力机制的计算,在计算之后再通过提升维度达到和原始的token embedding的维度一致。而原始版本的MSA中K,Q,V矩阵的第二个维度会保持和token embedding的维度一致(可以理解为一种在token上进行了基于类似扩展的VAE的算法实现了计算性能上的优化)。 MoE(Mixture of Experts)的基本原理是使用混合专家来替代原transformer架构中的前向反馈层(FFN),MOE层由多个FFN组成,每个FFN理论上更关注不同领域知识,即领域专家,每个token会选择其中的top-K(top-K为模型超参)个FFN向前传递。在具体实现时由路由选择组件和前向FFN专家集合组成。 问题1:MoE可以理解为首先用类似于早期的注意力机制选择token embedding的重要信息从而实现降维,然后将所得结果输送给多个领域专家进行计算聚合,可以这么理解对吗? 回答: 这种理解不是很正确,TopKRouter实现动态路,其核心功能为选择部分的token给对应的专家网络模块实现领域专家的计算。具体点的实现思路为: 基于门控网络(简单线性层+Softmax)实现TopK进行稀疏选择,将token输入给前topk个专家进行领域计算(剩下的专家不参与token的计算),这样可以较大效率提升计算效率,同时实现了不同专家的隐式领域划分,采用了负载均衡损失保证专家之间的计算平衡。同时聚合是基于token的,如token的结果由两个专家来进行领域计算,则结果为两个专家计算结果的加权和(topk权重之和归一化到1)。 其中负载均衡损失函数的定义可以参考参考[2]中的说明,其中fi为理想的专家分配概率分布(均匀分布),pi为实际的第i个token对于每个专家的概率分布,loss的计算可以基于KL散度进行计算。负载均衡损失只是一个约束项,在均匀性和有效性之间找到平衡。负载均衡损失的目的是防止专家塌陷,而不是让选择完全随机。 DeepSeek-V1模型在MoE的设计上做了两处的改进,具体如下图所示:(1)、细粒度的专家模型分割,采用了更多的专家模型子模块;(2)、采用了共享专家模型,学习通用知识。 问题2:请分析一下switch transformer和deepseek v1/v2/v3中的moe的实现上的模型结构,负载均衡损失等上的设计差别? 回答:DeepSeek的MoE架构的介绍见参考引文[2]。其中由于MoE的数量较多(v2版本路由专家达到160个),通常也会采用专家并行的策略,将专家分配到多个GPU设备上进行并行计算,但由于如果同一个token分配到的GPU设备如果过多,就会存在着GPU之间的通信开销问题,因此也会在路由中加入了设备数量限制。以达到通信的负载较为均衡的目的。v2中有160个路由专家,6个激活专家,v3的路由专家有256个,8个激活专家。v3在负载均衡的损失设计上也做了较大调整, References

  • SLAM系列之FAST-LIVO2代码分析-总体处理流程简介

    基于ROS1平台,整个流程是while循环,循环体内的流程以VIO和LIO迭代交替循环执行(如图1所示),这也是error state iterated kalman filter (ESIKF)的实现所需要的逻辑。 1、数据同步(sync_packages函数),如图所示,mode将在VIO和LIO间轮流变换,sync_pages会根据当前的mode进行对应的逻辑处理。 在VIO模式下,将以图片帧作为处理的截至时间,对齐imu和点云数据进行处理;如果图片的帧率过快,从buffer里获取的图片比last_lio_update_time时间还要早,则对图片进行丢帧处理,由于lidar传感器的扫描特性,原始帧每一个点云的采样时间不同,需要对原始帧的点云集合按对齐时间进行逻辑划分,比当前图片帧还要晚的点云点数据将会分配到下一个点云数据集合里。获取对齐的imu数据和lidar数据将更新到测量组里(MeasureGroup)。数据对齐完成后切换到LIO mode进行下一步的处理。 LIO模式下的数据同步主要来获取图像数据,图像数据获取后将切换到VIO mode进行下一步的处理。 图1:FAST-LIVO2处理流程图 2、数据预处理(processImu函数)在LIO模式下,主要处理包括:(1)、以预积分的方式计算imu在每一个时间戳下的初始位姿以及计算状态误差状态雅可比矩阵和误差传播协方差矩阵_state.cov,代码实现可以参考引文[1];(2)、通过imu预积分的结果(imu预积分计算在imu采样的时间戳序列下的对应的初始位姿)对lidar点云数据进行运动补偿去除畸变。运动补偿基于点云点时间戳和其对应的最近imu的时间戳的时间差和imu位姿及加速度角速度等数据按照运动方程进行时间对齐后的点云位姿估计,具体代码实现可以参考引文[2]。在VIO模式下,在基于LIO的点云和IMU紧耦合的ESKF优化的基础上,在对点云数据基于图像可视视角范围的过滤后在于图像的光度误差作为误差观测状态(又称为直接法)和前期IMU的姿态优化的基础上采用ESKF算法再次对位姿进行优化。 3、状态优化和建图,函数名为stateEstimationAndMapping,在步骤2中也有说明,其中LIO和VIO的迭代ESKF优化框架ESIKF(error state iterated kalman filter)在LIO和VIO依次都用到了ESKF滤波方法,其误差状态方程都是基于IMU的误差量(如基于李代数的旋转扰动量等19个维度),但误差观测方程不同,基于LIO的ESKF的误差观测基于点云点到匹配平面的距离残差,而VIO的ESKF的误差观测基于光度误差(直接法),具体后续将会在相关文章中详细介绍。 References

  • SLAM系列之FAST-LIVO2代码分析-基于点云的体素地图构建和更新方法介绍

    在参考文献[2]中,已经向大家介绍了点云相关的数据结构, 比如基于激光点集合的点云帧数据,体素地图的构建以及自适应体素分割方法。这篇短文将继续以问答的形式介绍FAST-LIVO2中的体素地图构建的更多内容。 问题1:该系统中有没有维护全局地图,还是只维护车机当前局部地图,以及如何实现的? 回答:该系统中只维护了局部地图,通过mapSliding()函数处理激光传感器所处位置的变化所带来的体素地图中点云数据的“可见性”,将当前“不可见”的点云数据从地图中进行清理删除,从而维护了当前系统运行所需的局部地图。当每次调用LIO处理激光点云和IMU进行ESKF算法联合优化位姿后,会判断地图当前的激光传感器所处的世界坐标位置和上一次进行滑动操作时激光传感器所处位置的距离,如果大于设定的阈值,则会将超过当前位置为中心点的地图大小范围外(定义了half_map_size变量可以作为参数在系统初始化时进行设定,体素坐标在x,y,z三个轴方向上在[-half_map_size:half_map_size]范围内的点云数据从地图内存中进行删除,从而维护了精简的局部地图。 问题2:地图创建及更新,自适应体素分割,体素平面的拟合等操作实现的关键的思想和作用分别是什么? 回答:1、地图的创建在系统初始化的时候进行,实现的函数为BuildVoxelMap,其主要思想是根据点云数据构建点云索引到八叉树地图节点的字典(unordered_map),并对每一个节点进行自适应体素划分;2、地图的更新函数为UpdateVoxelMap,当新的lidar帧到达的时候,会基于lidar帧的每一个点云点来更新体素地图,相邻lidar帧的点云可能会更新到同一个体素八叉树的节点上,需要根据具体的体素节点的状态,是否更新平面拟合,或进一步进行体素分割等;3、自适应体素分割主要针对的是体素内的点云的几何特征属性,如果能成功拟合一个平面,则保存拟合平面信息,否则如果体素内点云可能构成丰富的曲面,需要进一步去细分体素用更小的平面去拟合曲面信息;4、体素平面拟合的思路为:计算体素内三维点云的协方差矩阵的特征向量和对应的特征值,如果最小的特征值小于一定的阈值,说明只有两个主要向量,这两个主要的向量近似构成一个平面。 References

  • SLAM系列之FAST-LIVO2代码分析-LIV(LiDAR-Inertial-Visual)多传感器数据预处理过程介绍

    这篇文章将向大家介绍FAST-LIVO2开源系统中的数据预处理部分。包括多传感器数据同步、IMU预积分与激光点云去畸变(运动补偿)等。关于激光点云和IMU传感器的数据特性的详细说明请参考附录(基于像素表示的摄像头RGB图像数据比较普及不做介绍)。 其中多传感器数据同步的实现在sync_packages函数里,这里主要分析slam模式在LIVO下的数据同步方法。其主要的思想是以图片帧作为处理的时间基准(从lidar_header_time_buffer找出小于当前图片基准时间戳的所有点云原始帧数据),将原始的pcl数据帧按照时间关系重新组织到两个逻辑点云帧结构体(pcl_proc_cur和pcl_proc_next)中。 激光点云数据的时间戳是以point为粒度,扫描时间不同,激光雷达传感器的帧率相比图像和IMU是最低的(大概10-20Hz),在一帧图像数据中,点云之间被扫描到的时间点各异(因为扫描有先后,位置在时间上没有对齐),可以根据IMU的预积分的结果进行运动补偿。一般将这个过程分为两步:1、IMU预积分,也称前向传播(propogation of IMU); 2、基于IMU的预积分的结果对PointCloudXYZI类型的待处理的点云数据用反向传播的方式进行运动补偿。 附录: 附录A:关于激光点云的基本数据结构的介绍 1、激光点云原始数据帧PointCloudXYZI类,包含XYZ坐标和强度值(Intensity),为激光点的容器集合。在本开源系统中,点云数据等传感器数据通过ROS的message发出来,并进行预处理,激光点云信息中,将curvature属性作为当前点云点扫描时的时间信息加以存储(相对于原始点云帧的起始点时间差)。激光点云数据的一帧数据一般定义为一个完整的扫描周期内所获取的所有点云的集合,而且以最先扫描到的点的时间戳作为帧起始时间。激光雷达传感器也分为传统的激光的旋转式机械激光扫描和livox非重复式较高密度点云点采样扫描。有时如果点云分辨率过高,会需要更多的计算资源,点云处理库pcl中也有针对点云进行降采样的相关类pcl::VoxelGrid,直接调用相关函数即可实现点云降采样。 2、Voxel,体素,相对于二维平面的像素而言,为三维空间的细分表示单元,通常表示为一个小的立方体,存储的信息可能包括:1、该空间是否被占据;2、颜色或强度值;3、法向量;4、置信度。在体素地图(Voxel map)中,三维空间被划分成类似于魔方结构的多个体素单元,体素地图用于点云建图,三维重建等任务; 3、Octree(八叉树),满足一般的树结构的递归定义,为一种八叉空间划分树,如一开始的L*L*L尺寸的空间,第一级划分将空间的“长宽高”各对半切分,上下各四个子体素(八个子节点),以此类推进行递归再划分。八叉树的表示空间的好处在于对于稀疏的区域表示,可以用大体素(对应的叶子节点的层次比较低,可以提高存储效率),对于密集表面比较丰富的区域,可以用小体素(可以有更高的精细度),这种表示方法又称为自适应体素分割。 4、Octree Voxel Map(八叉树体素地图),体素的位置按照整数坐标存储,在空间上对应三个坐标轴上的整数索引x,y,z。某个点云的索引为点云的三个维度世界坐标除以根体素的大小(max_voxel_size)。八叉树体素地图可以基于字典结构(unordered_map,哈希表)实现体素的快速索引(map的key为三维整数坐标缩影,value为八叉树的根节点,可以存储多个点云数据)。一般如果max_voxel_size=0.5,则表示根体素的分辨率为0.5m*0.5m*0.5m。在该体素内部一般也会有几个到几十上百个点云点,具体要看采样的设备和是否进行了降采样处理。体素地图基于世界坐标构建,在系统运行过程中其体量可能较大。通过八叉树体素地图可以动态构建和更新全局地图。同时该体素地图支持点云的自适应体素分割,在代码实现中max_layer和voxel_size密切相关,如max_layer>1,则当原始体素内的点云点如果不满足拟合出平面的条件(说明表面为较为丰富的曲面),则会递归的进行八叉树子节点创建以支持构建更加丰富的表面信息。 5、Voxel Plane,代表了体素对应的局部平面信息,常用于基于八叉树的三维环境建模,对于体素内的多个点云,通过拟合平面模型,提取点云在该体素单元内的主要几何结构信息(如物体所表现的在该位置处的主体表面信息)。如果拟合平面成功,说明该体素对应的区域为平面如地面,否则可能对应着丰富的曲面表面,需要再进行细粒度的分割,用更小的平面去拟合曲面。 附录B:IMU数据基本结构介绍 IMU(Inertial Measurement Unit),即惯性测量单元,一般提供智能体运动的线性加速度(linear_acceleration,通过加速度计获取),角速度(angular_velocity,通过陀螺仪获取)等信息,通过线速度和角速度以及时间戳信息就可以通过预积分获取智能体的在时间戳上累积运动的位姿。 References

  • LLM技术系列之-GRPO算法介绍

    本篇文章将向大家介绍GRPO算法的基本原理,其也是DeepSeek模型训练所采用的关键算法。 GRPO(Group Relative Policy Optimization)算法和PPO(近端策略优化算法)类似,其中相似的地方有基于优势函数和重要性采样机制以及梯度裁剪相结合的loss定义。但GRPO算法的创新的地方在于其优势函数的定义和计算方式不同,也是其优势所在。 PPO算法在rollout时基于一个prompt生成一个response(completion),而GRPO中会基于一个prompt生成多个completions,图1为两个算法的优势函数定义对比图。PPO算法的优势函数的公式中[1]有依赖于即时奖励和价值函数的计算,而GRPO算法中没有Value Model,从而省去了训练时Value Model的推理和梯度更新的计算资源。GRPO的优势函数的计算方式可以参考[2],其基于生成的多个completions分别用奖励模型去计算奖励,然后基于多个奖励值进行归一化(减去均值除以标准差)后得出优势函数的计算结果,这也是群体相对策略优化(Group Relative Policy Optimization)名称的由来。 completions 之间的差异(diversity)正是由随机采样机制(如 top-k, top-p, temperature)来保证的,具体的这些超参在generation_config字典变量里进行设置。关于为什么用unwrapped model进行多个completions的生成以及采用model模型根据completion_ids进行logprobs的计算的原因可以参考相关issue[4]中的说明。 GPRO算法中的目标函数定义方法见图2。具体的计算时采用per_token_logps和ref_per_token_logps来计算训练模型的KL散度loss,同时用old_per_token_logps来计算模型当前rollout周期时生成completions样本时对应的per_token_logps(old_per_token_logps为当前数据采样周期时策略模型的生成的结果,可以达到一定程度的复用,用于策略模型的一个周期内的多次迭代;而ref_per_token_logps是参考模型的输出,用于计算KL loss,着PPO算法的机制相同)。详细的具体的实现参考代码[5]。 问题:ppo中critic和policy网络可以共享backbone,计算量也大不了多少? 回答:critic实现的价值网络虽然可以和policy网络共享backbone,但valuehead也需要在推理和梯度回传更新时需要不少资源。详细答案可以参考[3]中的描述。 问题:问答模型的数据集的格式是什么样的,如何实现不同推理场景的数据的统一描述? 回答:关于模型的训练数据方面的内容,如数据如何收集,数据的内容主题特性,以及如何通过角色实现对话上下文的管理并支持基于对话上下文的长token处理支持等内容,可以参考issue[6]中的描述。 References

  • LLM技术系列之-基于RLHF的生成式大模型实现思路及其中的关键算法PPO介绍

    这篇文章将向大家介绍基于RLHF的生成式大模型总体思路流程,以及介绍TRL库中的PPO训练算法实现中的几个关键细节点。 1、rollout数据回合采样的方法,rollout为对数据进行采集,类似于强化学习的gym模拟仿真环境中的step等环境仿真模拟方法(传统的RL任务,游戏,机器人仿真环境等,提供了统一的接口,如step,render等)。在LLM场景下,rollout 过程用于收集序列(states, actions, rewards)以供训练策略优化,states对应于queries tokens,actions对应于生成的response的tokens,以及通过奖励模型(Reward Model, RM) 计算生成的tokens序列奖励得分(一个query的得分为一个scalar的标量值来度量生成的tokens序列的质量)。这里对计算过程中的相关变量做一下说明:(1)logits为未经过softmax的原始值,如GTP-2的输出output有两个属性,一个为scores即为logits,另一个sequences为输出的tokens的序列。logprob为对logits进行log_softmax计算后选择生成的token对应索引位置的值,这里的参考模型和策略模型输出的KL散度的定义为基于对应的token id的概率之间的差异,而不是基于整个logits的所有词汇表(vocabulary)空间的概率分布去计算KL散度信息,详细的代码注释说明请见[1]。 2、从训练框架代码上需要说明的是,accelerator库提供不同GPU型号的memory伸缩训练支持(通过超参如local_batch_size,local_mini_batch_size,per_device_train_batch_size进行设置)。accelerator库可以通过多个小批次的梯度累积计算来模拟大批量的训练,具体的实现方法为:在 with accelerator.accumulate(model) 作用域内:减少显存占用,允许在小显存的 GPU 上模拟大批量训练。仅在梯度累积步数达到设定值时执行 optimizer.step()和 optimizer.zero_grad(),否则只进行梯度计算,不更新权重。避免手动使用 if step % accumulation_steps == 0: 逻辑,提高代码可读性及实现便捷性。 问题1:rewards代表即时回报,计算过程中为什么中间token的rewards值只与KL散度相关,而最后的token为KL散度相关的奖励加上reward_model给出的评分(score)之和?这么设计为什么有效? 回答:rewards在优势函数中参与了相关的计算,引文[2]公式中的r即为reward,根据回报函数或优势函数的计算方式,回报函数或优势函数为当前即时奖励到最后的每一个step对应奖励的序列的折扣和(具体公式见[2]),这样最后的回报通过传递都会对前面的token的优势函数有影响。在具体的设计过程中,KL loss前还有一个权重超参kl_coef。 问题2:在RLHRF算法中,参考策略模型,策略网络,价值网络,评分模型(网络)之间的关系是怎样的?以及ppo(近端策略优化)算法中的数据采样和迭代训练的大体流程是怎样的? 回答:在RLHF的训练过程中,一般包含三个步骤:(1)、在超大规模文本数据上基于自监督预训练的LLM模型上进行有监督微调(Supervised Fine-Tunning,基于人类标注的监督式数据),SFT模型在基于RLHF的PPO算法中用作参考策略模型提供训练数据样本生成;(2)、奖励建模,通过对比损失函数和基于人类反馈的偏好评分rank标记数据集(RLHF数据集)训练reward model;(3)采用PPO算法训练问答大模型,在实现时,参考模型既可以是独立传入的SFT训练的模型,也可以和策略网络共享部分或所有参数参与更新(具体可以查看参数num_shared_layers以及函数create_reference_model,但基于现有的调研来看,参考模型通常是冻结的,不参与训练,参数也不共享。策略模型从参考模型初始化,但在训练过程中独立更新),而价值网络一般可以和策略模型共享backbone(如类AutoModelForCausalLMWithValueHead),其在输出时多一个输出token对应的标量的value值(value值和reward值一起用于参与优势函数的计算)。而上述的rollout过程即为训练数据在线生成的过程,通过queries分别调用策略模型,参考策略模型,价值网络模型(可能和策略模型共享backbone),以及reward model(打分模型)推理以生成训练数据,然后基于一次rollout生成的数据进行num_ppo_epochs次参数更新迭代训练(policy网络和value网络的联合loss实现参数更新)。 References

  • SLAM技术系列之李群李代数简介

    这篇短文将向大家介绍李群李代数的相关知识点,以及其在slam中具体的应用。 群(group)是一种定义在特殊集合以及在该集合上定义的一种运算的特殊代数结构,比如整数集合及加法运算满足群的定义,旋转矩阵和矩阵的乘法构成了特殊正交群,欧式变换矩阵(又称特殊欧氏群,n维空间的欧式变换矩阵为(n+1)*(n+1)的欧式变换矩阵,基于欧式变换的计算采用齐次坐标系)和矩阵的乘法构成了n维欧式变换群等,群的定义需要满足三个约束条件:1、结合律,2、存在幺元和可逆,3、封闭性。而李群是指具有连续光滑性质的群,如上述的SO(3),SE(3)。 每个李群都有其对应的李代数,拿特殊正交群来举例,根据旋转矩阵的正交性以及微分方程的求解,可以得出旋转矩阵随时间变化的函数可以表示为其正切空间(为反对称矩阵,代表角速度的李代数元)上的指数映射(通常用于描述从李代数到李群的映射,描述几何变换的动态过程),具体的解释如下图所示: 通过将指数映射进行泰勒展开,由于旋转向量的大小和方向分别描述了旋转的角度和旋转轴。反对称矩阵是旋转向量的矩阵表示,通常通过叉乘矩阵来构造(待补充)。在SO(3)中,旋转向量和反对称矩阵等价,具体理解如图2所示。 具体的李群和李代数的指数映射的计算基于指数函数的泰勒展开,并且利用到了标准方向向量对应的反对称矩阵的一些计算性质,最后可以得出罗德里格斯公式。 两个李代数的指数映射的乘积和一般的标量的指数函数的乘积不同,根据泰勒展开以及多项式相乘的展开式,以及矩阵乘法的非交互性,计算过程如图3所示,由于BCH公式中在二次和更高阶的余项中只保留了非交换性的部分,因此BCH公式是对指数映射的乘积的一种近似。BCH公式为李代数的求导和扰动模型的计算提供了基础,而李代数的求导或扰动模型为优化非线性的变换矩阵(没有定义加法运算,不便求导)提供了基于李代数计算的导数优化。 李代数的扰动模型比李代数求导更加简洁,基于李代数的扰动模型由于比李代数的求导更加方便,在实际中用的会更多。 李代数在slam中的使用主要作用体现在优化相机位姿和地图点的过程中,具体可以参考g2o优化库的相关优化方法,如g2o::VertexSE3Expmap,就是基于SE(3)的指数映射进行的。 修订:关于BCH的公式的理解有出入:后面的解释请参考最新的手册[2] References