LLM MoE RL 学习报告

第一部分 深入理解 LLM MoE 的路由器机制

1. 路由器的训练机制

  • 路由器通常是一个怎样的网络结构?

    在 MoE 架构中,一部分 Decoder Layer 把原来的 FFN Layer 被替换为了 MoE Layer。MoE Layer 通常由一个路由器和多个专家组成。
image-20250819175525569
路由器是一个前馈神经网络,通常有两种网络结构:
  1. 一层线性层 + softmax :词向量经过 attention 层和残差归一化后,进入路由器,假设每个输入 Token 的维度是 d_model,路由器下游有 N 个专家,那么路由器就做了一个 d_model -> N 的线性映射。之后再对维度为 N 的结果进行 softmax,每个维度分别对应该 Token 与每个专家的匹配度或权重。

    用公式表示为,路由器内部有一个 d_model * N 大小的权重矩阵 W。输入 x 先与 W 进行矩阵乘法,得到 logits。
    $$
    logits = x * W
    $$
    之后再进行 softmax 得到最后的概率。
    $$
    probabilities = softmax(logits)
    $$

  2. 两层线性层 + 一层激活函数 + softmax :该方式与第一种方式的区别就是用了两层线性层。输入先通过第一个线性层映射到 hidden_size 维度,之后经过激活函数(通常为ReLU),然后再经过第二个线性层映射到 N 维度,最后再进行 softmax 操作。

  3. 添加高斯噪声因参数初始化等原因,可能会导致某些专家被频繁选择和更新参数,而其他专家很少被选择和训练,最后出现“赢家通吃”的情况。为防止这种情况发生,可以在 logits 上加上高斯噪声。高斯噪声是一个形状跟 logits 相同的向量,其中每一个 value 都是对均值为 0,标准差为 σ 的高斯分布的随机采样。然后对加和的结果再进行 softmax 。这样做的好处是在训练时有概率提升概率低的专家,削弱概率高的专家,避免频繁训练某些专家。

我的思考:为什么要这样选择?
  1. 计算速度快:简单的 “线性层 + softmax” 结构计算速度极快,可以为后面专家计算节约时间。
  2. 信息足够丰富:输入到路由器的 Token 向量 x 已经经过了自注意力层处理,因此其已经包含了一定的信息量。路由器阶段只需要负责计算 x 与各个专家的匹配度即可,所以不需要复杂的网络结构。
  3. 防止过拟合:路由器网络结构如果很复杂,意味着函数更复杂,这有可能会导致过拟合。简单的网络可以减少过拟合风险。

  • 在 MoE 模型的整体训练过程中,路由器是如何与专家模型协同训练的?请描述其损失函数,特别是用于促进负载均衡的辅助损失的作用和原理。

    路由器和专家模型通过反向转播在端到端的框架下进行协同训练。

    在前向传播过程中
    1. 路由器拿到自注意力模块的输出作为输入 x,通过矩阵乘法来线性映射,并进行softmax 得到输出。

    2. 根据路由器的输出,采用 Top-k 机制,选择概率最大的 k 个专家,将 x 输入给这些专家并得到每个专家的输出 expert_i 。然后对这 k 个专家的概率进行归一化,并与其输出进行加权求和作为 MoE 层的输出。
      $$
      y = \sum w_i * expert_i
      $$

    3. 最后 MoE 的输出加上残差作为这个 Decoder Layer 的输出,继续向下传播,直到模型最后得到预测结果。

    image-20250821024626367

    MoE 模型损失函数:

    MoE 模型的损失函数由一个主要损失和辅助损失组成,用公式表达为:
    $$
    total_loss = main_loss + \alpha * auxiliary_loss
    $$
    其中 α 是超参数,用来平衡主损失和辅助损失。

    **main_loss **:

    主要是交叉熵损失,用来衡量模型输出的概率分布与真实标签分布的差异程度。对于单个样本,交叉熵损失公式如下:
    $$
    H(p, q) == -\sum_x{p(x)log(q(x))}
    $$
    其中 p(x) 是真实分布中类别 x 的概率,q(x) 是预测概率中类别 x 的概率。通过对所有类别进行计算并求和得到最后的交叉熵损失。交叉熵损失对于接近正确的预测会给出很小的损失,对于很不正确的预测会给出非常大的损失,这有助于模型参数的快速更新。

    我的思考:为什么主损失函数选择交叉熵损失?
    1. 因为交叉熵损失能体现模型预测概率和真实标签概率之间的差异程度,很适合多标签分类任务,可以把大模型视为一个以语料库为类别的大型多标签分类器,因此很适合衡量大模型的预测性能。
    2. 在大模型的最终解码阶段,会把输入先进行 Layer Normalization,然后通过一个线性层映射到一个 vocab_size 大小的向量,之后进行 softmax 操作。因此我们得到的 logits 就是一个针对每个 token 的概率分布,可以很好的适用于交叉熵损失。
    auxiliary_loss:

    辅助损失的计算公式是:
    $$
    auxiliary_loss = \sum_i^{expert}{P_i * N_i}
    $$
    其中 Pi 是一个 Batch 中的所有 Token 由路由器分配给第 i 个专家的权重和。用来反映一个专家 i 的重要性。

    Ni 是一个 Batch 中所有 Token 里,将专家 i 选入 Top-K 列表的 Token 比例。用来反映专家 i 的被选中比例或受欢迎程度。

    辅助损失的计算,就是对于所有专家计算其 Pi 和 Ni 的内积并求和。

    由于我们的目标是最小化损失函数,因此辅助损失也会向着变小的趋势更新。这就使得 P 向量和 N 向量在各个维度上的方向要尽可能不一致。也就是对于某一个专家 i,不会出现 Pi 和 Ni 都很大的情况。最终希望调整的结果为所有专家的 P 值都很高,N 值都近似相等。这样的话,所有专家都能够被给予足够多的权重,并且也都能以均衡的概率被选中,充分发挥了多专家的功能性。

    其主要作用就是平衡专家们的权重和被选中率,让每个专家都能有足够的机会得到训练和使用,减少赢家通吃的现象,发挥多专家的多功能性。

    我的思考:为什么这样辅助损失这样设计可以达到均衡的效果?

    总结:在向量 L1 范数相对固定和 P、N 的内在逻辑约束下,当辅助损失变小时会自然出现的趋势。

    向量 L1 范数相对固定:通过 P 和 N 的定义可知,P 向量的 L1 范数是一个固定值,大致等于 总 Token 数 ,N 向量的 L1 范数是一个相对固定值,大致等于 总 Token 数 * k 。因此 P 向量和 N 向量不会出现每个位置的值都趋近于 0 的情况,总有一些位置的值是较大的,或者有所位置的值都均匀分配。

    P、N 的内在逻辑约束:根据 P 和 N 的定义可知,当 P 变大时,该专家所被分配的权重和变大,那么该专家就更有可能被更多 Token 所选入 Top-K 列表,也就是 N 也会随之变大。当 P 变小时同理,N 也会随之变小。因此不会出现 P 很小但是 N 很大的情况,因为 P 很小意味着该专家在每个 Token 中被路由器分配的权重很少,其他专家被分配的权重更多,那么该专家不可能被很多 Token 选中,否则易证明不满足不等式。同理也不会出现 P 很大但是 N 很小的情况。因为 P 很大意味着该专家在每个 Token 中都被路由器分配了较多的权重,那么该专家有很大概率被多个 Token 选中,否则也易证明不满足不等式。

    根据上述两种约束,我发现 P、N 向量中相同位置的值总是在各自的 L1 范数中占据相似的比例。在各自 L1 范数相对固定的约束下,如果极少数位置的值占比很大,其他大部分位置的值占比很小,也就是少数专家出现了赢家通吃时,辅助损失会很大。因此想要降低损失,就必然要朝着大部分位置的值都适中,没有占比很小的,也没有占比很大的,这样的趋势移动,这样才能降低辅助损失,具体降低的过程就依靠优化器来实现。

    因此该辅助损失的设计可以实现均衡专家的效果。


  • 在训练开始阶段,如何避免“赢家通吃”的现象,即部分专家被过度使用,而另一些专家得不到充分训练?

    主要是通过计算辅助损失、添加路由噪声、限制专家容量三种方式来避免赢家通吃现象。

    计算辅助损失 (auxiliary_loss]) 和添加高斯噪声 (高斯噪声) 的方式在上文已经叙述过了,这里重点来讨论限制专家容量如何避免赢家通吃现象。

    限制专家容量

    其核心思想是规定了每个专家在一个 Batch 中最多只能处理一定数量的 Token ,若某个专家被选中次数超过了该数目,则多余的 Token 会被舍弃专家计算过程并直接进行残差连接。

    其中,每个专家的容量计算公式如下:
    $$
    expert_capacity = \frac{tokens_per_batch}{number_of_experts} * num_of_k * capacity_factor
    $$
    在《Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity》原文中,公式里并没有 num_of_k,是因为论文中提出了只选择一个专家,因此 k 的值为 1。

    在每个 batch 中,所有 token 经过 router 后选出 top-k 个专家,此时统计每个专家的被选择数量,若超过专家容量,则多余数目的 token 直接跳过专家计算,或者专家计算结果为 0,其结果等于残差连接的结果。

    我的思考:为什么这样做可以防止赢家通吃?

    当赢家通吃现象发生时,受偏重的专家会被很多 token 选入 top-k,因此会有一部分 token 被跳过专家计算。这部分被跳过专家计算的 token 相当于没有经过 FFN 层的处理,只经过了自注意力处理,包含的信息更少,因此预测结果也更差,损失更高。优化器就会据此来调整 router 的参数,使之向着降低损失的方向更新,也就是减少给赢家分权重,多给其他训练次数少的专家分权重,从而简介的抑制赢家通吃现象的膨胀,协助专家均衡。


2. 路由器的决策过程

  • 在模型进行推理时,路由器如何为每个输入选择最合适的专家?

    路由器采取 Top-k 策略来为每个 Token 选取最合适的专家。

    Top-k 策略:

    在路由器得到每个输入 x,将其与权重矩阵进行矩阵乘法,并对结果进行 softmax,得到输出 logits 。之后会选择概率最高的 k 个专家。对于未被选中的专家,其概率会被置为 0 ,然后对选中的 k 个专家的概率重新进行归一化得到权重。然后将输入 x 送入这 k 个专家中计算并得到输出,最后的输出与权重相乘并累加得到最后的输出。(top-k

    模型在推理阶段不会添加高斯噪声,这一点与在训练阶段有所不同。


  • 路由器的决策是基于哪些信息做出的?

    目前大部分主流的 MoE 架构中,路由器的决策都仅仅是根据单个 Token 来决定的,即对输入 x 进行线性映射。

    尽管这有点反常,毕竟我们采取 MoE 架构的初衷是让不同领域的专家来处理不同领域的输入,如果不结合上下文理解,只凭借单一的 Token ,那很难将这个 Token 来划分到某一类别。

    比如:”What is computer?” 和 “What is piano?” ,前者是针对计算机方面的知识,后者是针对音乐方面的知识。两者都含有共同的 What 和 is。如果只根据这两个 Token 来路由,是很难知道它到底是哪个领域的知识的。

    我的思考:为什么只根据单一 Token 就可以决策?
    1. 其实经过路由器的 Token 已经经过了自注意力机制,也就是其学习到了上下文的相关信息,在词向量空间中的方向已经靠近了其对应的领域。因此该 Token 可以反映出其不同的上下文,就可以仅仅根据 Token 来做领域划分。
    2. 这符合高内聚,低耦合的设计原理。自注意力机制主要负责让每个 Token 学习其丰富的上下文信息,而路由器机制主要负责为 Token 选择合适的专家。二者功能相对分离,互不冲突。如果路由器在划分领域时也需要参考上下文的信息,那跟自注意力模块的功能就有些重合,这部分功能或许可以抽离到自注意力模块中。

3. LLM MoE 不足与挑战

  • 当前 LLM MoE 路由器在训练和推理过程中存在哪些主要问题?

    1. 负载不均衡。当前 MoE 架构最核心的问题和挑战就是负载不均衡。由于训练过程的不可控和随机性,很容易发生赢家通吃的现象。如果有的专家被频繁训练,而其他专家训练机会很少,那么就会出现专家广而不精的现象,与我们设计的多专家多方向的初衷相违背。同时严重的负载不均衡也会导致梯度更新不均衡,进一步加剧训练不稳定。

      我的思考:如何才能缓解负载不均衡?

      上文提到的添加高斯噪声、设计辅助损失函数、限制专家容量等方法都是在尽可能规避、改变赢家通吃的现象,并没有从根本上预防这种现象的发生。

      对于专家,我认为可以采取预设参数的方式,从已经训练好的专业领域大模型的 FFN 层中随机选择一部分参数来作为专家的初始参数。这样可以加快训练过程,提前让专家有一部分前置知识。

      对于路由器,我认为可以参考验证集调整超参数的思想,提前随机初始化多个路由器权重,然后根据验证集的效果来选择最好的权重,而不用等到反向转播时更新权重。

    2. 通信成本高。由于 MoE 架构采取了多个专家,在显著提升了参数量的同时,也对训练提出了更高的要求。专家在训练的时候必须被分散存储在多个 GPU 上,当一个批次中的 Token 经过路由器后,这些输入需要发送到对应专家所在的 GPU 上,这个过程需要一次大规模的数据交换,也就是 All-to-All Communication 。这个步骤对网络带宽要求高,延迟大,导致有可能成为性能瓶颈。就像高速计算 CPU 和低速访存之间的关系一样。

    3. 内存开销成本大。尽管 MoE 架构的计算是稀疏的,每次只会激活 k 个专家。但是在推理或训练时,所有 N 个专家的参数都必须加载到 GPU 的显存里,因为不知道哪 k 个专家会最终进行计算。这就需要我们拥有大量的大显存 GPU 。


  • 微调 MoE 模型时,路由器会带来哪些新的挑战?

    很容易过拟合。由于微调阶段,通常会针对某一个特定领域来训练,这个领域对应的专家表现很好,其他专家由于领域不同表现较差。因此路由器往往会给这个领域的专家很高的权重,并取得较好的效果。这会让路由器学到一种“规律”,即可以把所有 Token 都给这个专家处理,失去了选择性,最后过拟合了。

    我的思考:这种方式的后果
    1. 路由器只会无脑选择训练领域的那个专家,根本不选其他专家。这种情况泛化能力很差,而且会浪费绝大部分专家的参数,失去了多专家的优势,牺牲了成本和性能。

    2. 导致只有少量专家真正被微调了,其余专家没有被微调,专家能力差距很大。如果在应用时遇到了其他领域的问题,路由器选择了其他专家,由于没有经过微调训练,这些专家的回答还是遵循预训练中下一个词预测的模式,没有真正解答问题的能力。


第二部分 **VLM MoE **的新挑战与借鉴经验

1. **VLM MoE **的挑战

  • 多模态输入的路由:

    VLM 的输入包含图像和文本两种状态,其路由器在决策时需要处理和融合来自不同模态的信息。这相比于只处理文本的 LLM MoE ,带来了哪些新的复杂性?

    我的思考:

    1. 特征空间的不同。LLM 的所有输入都是文本语言,其每个 Token 经过 embedding 后会被映射到词向量特征空间中的一个向量。而 VLM 是跨模态模型,包含文本和图像。其中图像在经过 ViT 等视觉编码器后,每个 patch 被映射为一个视觉隐藏层维度的向量,这个向量位于视觉特征空间中。为了实现图像和文本的维度一致,还需要一个视觉-语言连接器把每个 patch 对应的向量映射成维度与词向量一致的向量。但是在未经训练的情况下,二者包含的语义大概率不同,尽管维度一致,也不能很好的被 LLM 的 router 兼容。
    2. **路由器选择不同。**在 LLM 中,路由器接收到的所有输入都是文本,因此只需要为文本进行领域归类即可。但是在 VLM 中,路由器接收到的输入可以是图片或者文本,因此路由器需要先判断该输入的模态,再判断该模态的内容,最后判断该模态内容的目标是什么。这对于路由器有了更大的要求,同时也对专家类型有更高的要求,例如可能有纯视觉专家,纯文本专家等。
    3. 文本和图片的数量差异。在 VLM 中,文本所占 Token 通常要小于图片所占 Token ,因此路由器输入的更多 Token 是来源于图片而非文本。但是往往文本涵盖用户的关键信息,路由器如何在庞大的 Token 中找到真正重要的信息是很复杂的。

  • 专家专业化的多样性:

    VLM 中的专家可能需要专精于不同的任务,例如某些专家处理视觉特征提取,某些处理跨模态对齐,还有⼀些处理高级的推理。这对路由器的设计和训练提出了哪些新要求?

    LLM 中路由器的结构比较简单,难以精准的把 token 分派给功能细化的专家,因此需要设计复杂的路由器来满足需求。

    1. 分层路由器

      第一层是模态路由器。模态路由器根据 Token 的特征,判断它主要偏向视觉处理,还是文本分析,还是跨模态处理,并据此做出决策。

      第二层是任务路由器。根据模态路由器决策,将 Token 传递给一个专门的子任务路由器。比如视觉子路由器会进一步判断这个视觉 Token 是需要特征提取还是物体识别,语言子路由器可能会判断是需要语法分析还是语义推理。

    2. 层级依赖路由:路由器的决策不仅依赖于当前的 Token 向量,还可能依赖*当前所在的 Transformer 层的深度。在模型的底层,路由策略可能更倾向于选择特征提取专家;而在高层,则更倾向于选择推理专家。

    3. 历史感知路由:路由器的决策可能还需要考虑这个 Token 在前几步被哪些专家处理过的历史,并依次为参考来进行路由。

    复杂的路由器结构也对路由器的训练提出了更高的要求。

    原来的 LLM 的辅助损失只能促进负载均衡,即均衡的让每个专家都能被选择训练。但是这种方式无法引导专家学习的内容,比如让某个专家主要学习图片视觉,某个专家主要学习文本理解等等。这时候可能需要设计新的损失来促进学习。

    1. 专家专业化损失。可以为训练数据打上元标签来标记该数据的类别。对于一个视觉问答任务,可以预先定义哪些 Token 主要与视觉感知相关,哪些与逻辑推理相关。然后,设计一个损失函数来奖励路由器将视觉 Token 发送给我们预设的视觉专家,并惩罚它将推理 Token 发送给视觉专家。

    2. 专家多样性损失。我们可以设计一个损失函数,来鼓励不同专家处理的 Token 类型尽可能地不同。可以计算不同专家接收到的 Token 向量的平均余弦相似度,并将其作为惩罚项加入总损失中。如果所有专家处理的 Token 都很相似,说明它们没有形成分工,损失就大。

    除了设计新的损失,我们还可以改进训练模式。

    1. 模态分离训练。可能先使用模态纯净的数据进行训练。例如,只用图像数据训练视觉专家,只用文本数据训练语言专家。在这个阶段让路由器学会基本的模态区分。
    2. 跨模态对齐训练。然后使用图文对数据,专门训练跨模态对齐专家,让路由器也学会了何时需要进行信息融合。
    3. 指令与推理微调。最后在复杂的指令跟随和推理数据上进行端到端微调,激活并训练高级推理专家。

  • 维持跨模态理解

    在稀疏激活专家的同时,如何保证模型不会丢失图像和文本之间的整体关联性和深层语义理解?

    1. 稠密子层的交替使用。其核心思想是交替在 Transformer 中使用 MoE 架构和 FFN 架构。一般是 FFN Layer 多一些,MoE Layer 少一些。

      我的思考:为什么这样做可以加强图像和文本的整体关联?

      我认为这样做就是保证每个 Token 既可以在专业的专家那里学到特异的知识,同时也能在通用的 FFN 层进行通识理解。由于多个 Decoder Layer 相连接,在上一个 Layer 中学到的知识可以在下一个 Layer 的自注意力模块里交换知识,让图像和文本有相互的关联。再合理搭配上通用学习和特异学习,可以更全面均衡的理解深层语义信息。

    2. **视觉语言连接器。**设计一个稠密的连接器模块,在 Token 进入 Transformer 之前,先进入连接器中进行深度全局的信息融合学习,让每个 Token 都学到其他 Token 的信息。


  • 推理开销激增

    由于图像 tokens 数量相比于文本 token 数量急剧增大,对推理速度会带来怎样的挑战?

    1. 自注意力机制计算量增大。在计算 Q,K,V 的时候,时间复杂度是 O(n^2) 的时间复杂度。因此当图片的 token 大小激增后,自注意力层的计算量也会以二次方速度增长,使得计算压力非常大,拖慢了推理速度。
    2. **内存开销增大。**图像 Token 增多后,K,V 向量的缓存也会增多,这增加了 GPU 显存的压力,同时巨大缓存导致的读写带宽高延迟也会拖慢推理速度。

2. **VLM MoE **路由器的训练与借鉴:

  • 目前已有的 VLM MoE(如Kimi-VL、GLM-4.5V)是如何训练其路由器的?它们采用了哪些创新的策略?

    Kimi-VL:Kimi-VL 的 MoE Language Model 部分是基于其纯语言模型 Moonlight 构建的。其包含了 MoE 架构中的经典结构。包括负载均衡辅助损失 ,Top-k Gating。专家容量限制等。Kimi-VL 的 MoE 解码器激活了 2.8B 参数,总参数量为 16B。

    alt text

    **创新策略一:解耦与对齐的分阶段训练 **

    这是 Kimi-VL 训练路由器的核心创新策略。它没有一开始就让路由器面对复杂的图文混合数据,而是采用了一个由简到繁、逐步对齐的流程。

    1. 第一阶段:语言模型预训练

      首先,其 MoE 语言模型 Moonlight 在一个 5.2T Token 的纯文本数据集上进行了充分的预训练。在这个阶段,路由器已经学会了如何根据纯文本的语义来高效、均衡地分配专家。它已经为语言理解任务建立了一套成熟的、专业化的路由策略。

    2. 第二阶段:视觉编码器独立训练与对齐

      视觉编码器 MoonViT 首先在图文对上进行独立训练(类似 CLIP),然后通过一个 MLP Projector 对齐到已经训练好的 MoE 语言模型上。在对齐阶段(0.1T Token),只有 MoonViT 和 MLP Projector 的参数被更新。

      在这个关键的对齐阶段,路由器和整个 LLM 的参数是冻结的。这意味着,路由器不会被初始的、可能充满噪声的视觉特征所干扰。模型的目标是让 MLP Projector 学会如何将视觉特征“翻译”成 LLM 和路由器已经能够理解的、类似文本词向量的语言。

    3. **第三阶段:联合预训练 **

      在对齐完成后,才开始在一个 1.4T Token 的混合数据上,对整个模型(ViT, Projector, LLM+Router)进行端到端的联合训练。并且,多模态数据的比例是逐步增加 (Progressive)的。此时,路由器接收到的视觉 Token 已经经过了精心翻译,与文本 Token 在特征空间中更加接近。这极大地降低了路由器学习多模态路由策略的难度。渐进式的数据混合,也让路由器可以平滑地从处理纯文本,过渡到处理图文混合流。

    创新策略二:原生分辨率视觉编码器 (MoonViT)

    Kimi-VL 设计了 MoonViT,一个可以原生处理不同分辨率和宽高比图像的视觉编码器,避免了传统 VLM 中将图像强制缩放或切分成多个子图的复杂操作。这意味着送入连接器和路由器的视觉 Token 序列,能更真实、更完整地反映原始图像的信息,而没有因为切割或缩放引入的人工痕迹和信息损失。


  • LLM MoE在解决负载均衡、稀疏性控制和高效训练等方面的经验,有哪些可以直接或经过改造后应用于VLM MoE?请举例说明

    我的思考:

    1. 负载均衡辅助损失可以直接应用到 VLM MoE 中。由于最终图片和文本的 Token 都会在维度对齐后送入 Transformer 模块中,因此对于负载均衡损失而言依然可以继续使用。其目标还是平衡 N 个专家的机会和能力,这对于多模态而言也是同样重要的。
    2. 路由高斯噪声也可以直接应用于 VLM MoE 中。路由高斯噪声是在路由器已经生成权重后对权重随机的更改,这于路由的过程无关,是直接在结果层面的改变,因此可以直接套用。同时其训练目标也是防止赢家通吃,在这 VLM MoE 中同样需要。
    3. 限制专家容量可以改造后应用于 VLM MoE。首先在 VLM 中,每个专家的容量限制不应该相同。由于 VLM 中图片 token 更多,因此专门负责视觉处理的专家天然的会被更多 token 选择,因此其容量应该大于文本处理专家。可以结合专家专业化的引导来选定不同类别的专家,然后特定的设置专家容量,这样更合理一些。

第三部分 学习 DPO、**PPO **与 GRPO 算法

1. PPO

  • PPO 的基本原理是什么?它如何利用奖励模型和强化学习来优化语言模型?

    强化学习的本质是一种试错学习,模型的每一个行动都会有一个对应的奖励,模型通过奖励来判断行动的好坏,然后学习一个策略去最大化模型获得的累积奖励。

    PPO,近端策略优化,在允许模型自我探索的基础上,严格限制新策略与旧策略的差异程度,防止模型忘记之前学到的知识。其每次模型更新都是小步更新,确保了训练的稳定性,不会出现策略崩溃。

    首先需要训练一个奖励模型 Reward Model 。训练过程是通过对一个 Prompt 的回答进行人为排序标注,来规范回答的好坏程度。奖励模型的训练任务就是对一个 prompt 的回答进行打分,其打分的依据就是人类标注的训练数据。

    在 PPO 训练时,有两个 SFT 模型,其中一个是在线模型,是训练优化的目标模型,会更新参数。另一个是参考模型,是参数冻结模型,这个模型不更新参数,用来计算 KL 散度。还有一个奖励模型,用来评价 prompt 和回复的好坏。和一个价值模型,输入一个状态,预测从这个状态出发,未来能获得的期望总奖励。

    PPO 的工作循环

    1. 采样:从一个大的 Prompt 数据集中,随机抽取一个批次的 Prompt。

    2. 生成:对于抽取的每一个 Prompt ,将其输入给在线模型和参考模型,让它自回归地生成一个完整的回答,得到一批由当前策略生成的完整对话。

    3. 评估:对于每一个prompt,将 (Prompt, 生成的回答) 这个组合,送入奖励模型 (RM),得到一个奖励分数。这个分数告诉我们这个回答有多好,并且这个reward只在对话的最后一个 token 处被给予。

    4. KL 散度惩罚:对于每一个 token ,计算在线模型的输出与冻结的 SFT 参考模型的输出的概率分布之间的 KL 散度 。
      $$
      β * log(\frac{π_θ(a_t|s_t)} { π_ref(a_t|s_t)})
      $$

    这是一个惩罚项,它衡量了在线模型的回答与原始 SFT 模型的偏离程度。这个 KL 惩罚项会从每一步的源氏奖励从被减去。这个惩罚项是 PPO 稳定性的另一个关键,它防止模型为了追求高奖励而忘记之前学到的知识。

    1. 调整奖励: 将(奖励分数 - KL 惩罚)作为最终的每一步的调整后的奖励。
      $$
      Adjusted_Reward_t = (Reward_t) - (KL_Penalty_t)
      $$
      其中,只有最后一个 token 的 reward 是 RM 最后给出的原始奖励,其他中间的 token 的 reward 都是 0 。

    2. 计算优势:对于轨迹中的每一个状态,都将其输入到价值模型中。价值模型会输出一个预测值,代表它认为从这个状态出发,未来能获得的期望总奖励是多少。对于每一个时间步 t,优势的计算公式是:
      $$
      A_t = (实际获得的未来奖励) - (价值模型预测的未来总奖励)
      $$
      若 A_t > 0,则说明从当前状态出发,采取现在的行动,比预期的要好。

    3. 更新策略:首先计算策略比率,对于轨迹中的每一个(状态,行动),计算新旧策略的比率。
      $$
      r_t = \frac{π_θ_new(a_t|s_t)} {π_θ_old(a_t|s_t)}
      $$
      PPO 的目标是最大化目标函数:
      $$
      L_{CLIP} = min( r_t * A_t , clip(r_t, 1-ε, 1+ε) * A_t )
      $$
      r_t * A_t 是标准的策略梯度目标。

      clip(r_t, 1-ε, 1+ε) * A_t 是被超参数 ε 约束的目标。clip 函数会强制策略比率 r_t 不能超出 [1-ε, 1+ε] 这个区间。

      通过min挑选二者中较小的值,可以防止 r_t 变得太大而大幅度更新,放置了梯度过大。

      最后使用梯度更新策略模型的参数。

    4. 重复:不断重复 1-7 步,让在线模型在“奖励”的引导和“KL 惩罚 + PPO 裁剪”的约束下,逐步地、稳定地学会生成更符合人类偏好的回答。


  • 解释PPO中的“策略(Policy)”和“价值(Value)”函数的作用

    策略函数的作用是将当前的状态映射到一个行动上

    当前的状态是到目前为止所有的上下文,包含输入的 prompt 和模型的思考与回复。行动是模型接下来要生成的下一个 token。策略函数是负责做出决策的组件,就像是模型的大脑,负责根据所有的状态来决定下一步的行动是什么。这也是我们要优化的目标。

    价值函数的作用是评价当前行动的优劣程度。主要用来减少梯度方差,稳定训练过程。PPO 使用价值函数来计算一个优势度。用实际获得的奖励减去模型预测的奖励。根据这个优势程度来更新策略。


  • 相比于传统的强化学习算法,PPO的“近端”更新策略有什么优势

    优势在于可以限制更新的幅度。更新更稳定、高效、简单。

    PPO 会计算一个比率,这个比率可以衡量新策略选择该动作的概率是旧策略的多少倍。如果比率大于一,说明这个动作发生概率在增大,反之亦然。

    PPO 引入了一个超参数,相当于在比率的周围定义了一个安全边界。

    当我们发现优势很大,想要更新策略以增加动作发生概率时,这个安全便捷会限制更新的幅度,使我们不会一次性更新很大。


2. DPO

  • DPO为什么被称为“直接”偏好优化?它与PPO最大的不同在于哪里

    DPO 被称为直接,是因为它绕过了整个传统 RLHF 流程中最复杂、最间接的步骤,建立了一条从人类偏好到模型参数更新的直接通路。

    传统的 RLHF 不直接使用人类偏好数据,而是用这些数据去训练一个奖励模型,用 RM 的打分来间接反映人类偏好。并且 PPO 的过程中,模型的目标变成了最大化分数。

    而 DPO 没有以上的步骤,其通过数学推导证明了 RLHF 的优化目标可以转化为一个损失函数,这个损失函数可以直接作用于语言模型,利用人类偏好数据来进行优化。

    在 DPO 的训练过程中,只有策略模型和参考模型。

    DPO 的工作循环

    1. 采样:从预先准备好的人类偏好数据集中,取出一个偏好对。这个偏好对中包含了 prompt(x),较好的回答(y_w),较差的回答(y_1),三部分。

    2. 计算策略模型的概率:将(x, y_w)这个组合输入到策略模型中,模型会计算出在给定 x 的条件下,生成 y_w 这个完整序列的总对数概率,记为 log_prob_π_θ(y_w) 。同样的,将(x,y_1)输入到策略模型并计算出 log_prob_π_θ(y_1) 。

      计算总对数概率的过程实际上是基于概率链式法则来计算的:
      $$
      P(y | x) = P(t_1 | x) * P(t_2 | x, t_1) * P(t_3 | x, t_1, t_2) * … * P(t_L | x, t_1, …, t_{L-1})
      $$
      由于将大量的小概率值连乘,会导致结果非常小,容易出现数值下溢的问题,所以在实践中,因此使用对数概率。在对数空间中,连乘就变成了求和,这在计算上更稳定、更高效。
      $$
      log P(y | x) = Σ log P(t_i | x, t_1, …, t_{i-1})
      $$

    3. 计算参考模型的概率:跟 2 相似,将(x, y_w)和(x,y_1)输入到参考模型中,计算出总对数概率,记为 log_prob_π_ref(y_w) 和 log_prob_π_ref(y_1) 。

    4. 计算对数概率差:

      获胜回答的对数概率差为
      $$
      diff_w = log_prob_π_θ(y_w) - log_prob_π_ref(y_w)
      $$
      落败回答的对数概率差为
      $$
      diff_l = log_prob_π_θ(y_l) - log_prob_π_ref(y_l)
      $$
      diff_w 衡量了我们的策略模型相比于参考模型,在生成好答案方面的进步有多大。diff_l 衡量了在生成坏答案方面的退步有多大。

    5. 计算隐式奖励差:将上述两个差值再相减,并乘以超参数 β
      $$
      reward_diff = β * (diff_w - diff_l)
      $$
      reward_diff 可以被看作是当前模型 π_θ 隐式地赋予 y_w 相对于 y_l 的优势分数。

      DPO 的训练目标就是让这个分数尽可能地大。

    6. 计算最终损失:
      $$
      Loss_{DPO} = -log(sigmoid(reward_diff))
      $$

    7. 反向传播:通过标准反向传播算法来更新参数。

    8. 重复:不断重复 1-7 步。


  • 描述DPO是如何利用“偏好对”(Preference Pairs,即⼀个“更好”的回答和⼀个“更差”的回答)来直接优化语言模型的。

    偏好对会调整 π_θ 的参数,使得在下一次遇到类似的 Prompt 时:

    • 模型生成 y_w 这类回答的概率会上升
    • 模型生成 y_l 这类回答的概率会下降

    同时,由于 π_ref 的存在(它隐式地起到了 KL 散度正则化的作用),模型的更新不会过于“激进”,确保了 π_θ 不会与它微调前的 SFT 模型偏离得太远。


  • 相比 PPO,DPO 在训练稳定性和效率方面有哪些优势

    DPO 相比 PPO 而言,核心优势在于 PPO 是在线强化学习算法,而 DPO 则是一个离线监督学习算法,

    DPO 是离线的,它在一个预先收集好的人类偏好数据集上进行训练。整个训练过程中不需要模型进行任何的在线生成,训练数据也固定不变,于是 DPO 的训练过程变成了一个确定性的,可重复的损失最小化问题。这样稳定的流程也使得训练过程非常稳定,不会出现损失突然上升等情况。

    DPO 没有在线采样的步骤,其只需要计算当前模型和参考模型在一个固定的偏好对上的概率,这个计算要比 PPO 快很多。


3. GRPO

  • GRPO 是对 DPO 的改进么

    GRPO 是对 DPO 的改进,旨在解决 DPO 的一个核心局限问题,从而更充分的利用人类偏好信息。

    DPO 的训练数据是大量的偏好对,他的损失函数处理这一对回答。但是现实世界的偏好是多层次的,而DPO会造成这种信息的浪费,并且每次只能学习两个信息之间的偏好,无法建立上下文的关联。

    GRPO 对 DPO 进行了改进,从一对一变成了一组多。它不再孤立地看待每一个偏好对,而是将一个 Prompt 下的一组多个回复及其排序作为一个整体来进行优化。


  • 理解GRPO的核心思想,特别是它如何利用⼀组生成的回复来更有效地进行优化

    GRPO 的世界中,是由有序的列表构成的。其引入了 Plackett-Luce 模型,来计算一个特定排序出现的概率。GRPO 就是将 DPO 中那个隐式奖励的数学形式,代入到这个 Plackett-Luce 模型中,从而构建出了它的损失函数。

    GRPO 的最终损失函数 L_GRPO,可以被直观地理解为对一个组内所有优势对的 DPO 损失的加权总和。

    GRPO 拥有更丰富的梯度信号,因为可以从一组序列偏好对中获得综合梯度。同时可以整体的看待排行榜。


  • 在需要复杂推理或多样化生成的任务中,GRPO可能比DPO或PPO更有优势吗?为什么?

    GRPO 有更大的优势。

    在需要复杂推理的任务中,思维链一般都很复杂且很长。

    PPO 的奖励机制难以合理衡量两个思维链的好坏程度,比如一个过程全对但是结果错误的思维链和一个过程错误但结果正确的思维链,PPO 的奖励模型难以精确判断或容易错误判断其好与坏。

    DPO 每次只能比较两个思维链的优势,其失去了全局视角。

    GRPO 则可以利用一个完整的推理链排行榜,全局性的学习到他们共有的推理模式或思考方式,而不仅仅局限于谁比谁好的二元判断。且 GRPO 还可以包容优劣程度类似的情况。同时 GRPO 还从数据和优化目标层面,鼓励模型生成维护一个多模态的输出分布,这有注意完成多样化生成任务。