这篇文章是以2025年2月的一篇综述论文为蓝本,对「LLM后训练技术」的全景讲解:[2502.21321] LLM Post-Training: A Deep Dive into Reasoning Large Language Models
2023 年,当 ChatGPT 惊艳世界时,很多人第一次意识到:原来 AI 不仅能背课文,还能写代码、编故事、解数学题。这些聪明表现的背后,得益于大语言模型(LLM)的两个关键训练阶段:预训练(Pretraining)和后训练(Post-training)。
预训练阶段通过海量文本数据(通常达到 TB 级别)的自我监督学习,使模型掌握基本的语言规律和世界知识。但仅有预训练的LLM,就好像刚学会六脉神剑的段誉,一身内功,但不会施展。这时,我们就需要通过「后训练」来给模型能力进行「塑型」—— 通过特定方法让模型在医疗诊断、法律咨询、编程开发等专业领域大显身手,同时学会遵守伦理规范、避免信口开河。正是这些「精装修」步骤,把原始的语言模型变成了我们日常使用的智能助手。
后训练技术的核心价值体现在三个维度:
在后面的讲述中,我们沿用上述原论文给出的分类视角(taxonomy),从「微调」、「强化学习」、「测试时拓展」三个类别去认识各种后训练技术。
全参数微调(Full Fine-tuning)是指在预训练模型的基础上,使用下游任务的数据集,更新模型中的所有参数,以使模型适应特定任务。这种方法在早期的深度学习中非常常见,但随着模型规模的增大,其弊端也逐渐显现。
挑战维度 | 具体表现 | 解决方案 |
---|---|---|
计算资源 | GPU 内存占用高,训练时间长 | 参数高效微调 (PEFT) |
灾难性遗忘 | 新任务覆盖旧知识 | 知识蒸馏 + 持续学习 |
数据依赖 | 需要大量标注数据 | 提示学习 + 数据增强 |
参数高效微调(Parameter-Efficient Fine-Tuning,PEFT)是一系列旨在以较少的计算资源和数据量,实现与全参数微调相近性能的技术。这类方法通常冻结预训练模型的大部分参数,只训练少量额外的参数。
低秩适配(LoRA) 的核心思想是冻结原始参数,通过低秩分解引入可训练参数。
数学原理:
LoRA 假设预训练模型的参数矩阵的更新可以表示为一个低秩矩阵。具体来说,对于一个预训练好的权重矩阵$$W_0 \in \mathbb{R}^{d \times k}$$,LoRA 引入两个低秩矩阵$$A \in \mathbb{R}^{d \times r}$$和$$B \in \mathbb{R}^{r \times k}$$,其中$$r \ll \min(d, k)$$是秩。在微调过程中,只优化$$A$$和$$B$$,而$$W_0$$保持不变。更新后的权重矩阵为:
$$W = W_0 + BA$$
由于$$r$$远小于$$d$$和$$k$$,因此 LoRA 只需要训练很少的参数,就可以达到与全参数微调相近的性能。
伪代码示例:
import torch
import torch.nn as nn
class LoRALayer(nn.Module):
def __init__(self, in_dim, out_dim, rank):
super().__init__()
self.A = nn.Parameter(torch.randn(in_dim, rank))
self.B = nn.Parameter(torch.zeros(rank, out_dim))
self.rank = rank # 秩的大小
def forward(self, x):
return x @ (self.A @ self.B) # 低秩矩阵乘积
关键技术演进:
AdaLoRA:
QLoRA:
Delta-LoRA:
提示微调(Prompt Tuning) 是一种通过设计合适的提示(Prompt) 来引导预训练模型完成下游任务的技术。与全参数微调和 LoRA 不同,提示微调通常不直接修改预训练模型的参数(注意不是完全不修改参数),而是通过优化提示相关的向量来调整模型的行为。
核心思想:
数学原理:
公式
$$h_{prompt} = [P_1;P_2;…;P_k] \quad P_i \in \mathbb{R}^{d}$$
描述了可学习的提示向量。其中,$$h_{prompt}$$表示提示向量,$$P_i$$表示第$$i$$个可训练的提示向量,$$k$$表示提示的长度,$$d$$表示提示向量的维度。
位置选择策略:
Prefix-Tuning(粉色):
P-Tuning v2(绿色):
Prompt-Tuning(蓝色):
关键差异对比表:
维度 | Prefix-Tuning | P-Tuning v2 | Prompt-Tuning |
---|---|---|---|
插入位置 | 每层输入序列头部 | 每层可学习位置 | 仅输入层头部 |
可训练参数占比 | 0.5%-2% | 0.3%-1.5% | 0.01%-0.1% |
典型应用场景 | 复杂逻辑推理 | 多任务适配 | 轻量化快速部署 |
显存占用 | 高(需存储各层前缀) | 中 | 极低 |
训练速度 | 慢(需反向传播至各层) | 中等 | 快(仅输入层梯度) |
技术演进趋势:
动态混合提示作为最新发展方向,允许模型自主决定:
领域自适应微调(Domain Adaptive Fine-Tuning) 是指在特定领域的数据上对预训练模型进行微调,以使其更好地适应该领域的任务。这种方法在医疗、法律等专业领域尤其重要,因为这些领域的数据具有独特的特点和术语。
案例:医疗问答系统的微调策略
以一个医疗问答系统的微调策略为例:
数据构造:
混合通用指令数据 (20%) + 专业文献问答 (80%):
分层微调:
评估指标:
FActScore(事实一致性评分)> 0.85:
奖励建模(Reward Modeling) 是很多 RL 方法的关键步骤之一。它的目标是根据人类的偏好数据,训练一个能够预测人类对模型输出的偏好程度的模型。
Bradley-Terry 模型是一种常用的奖励建模方法:假设对于给定的输入$$x$$,人类更喜欢输出$$y_i$$而不是$$y_j$$的概率可以表示为:
$$P(y_i \succ y_j|x) = \frac{\exp(R(x,y_i))}{\exp(R(x,y_i)) + \exp(R(x,y_j))}$$
其中,$$R(x, y)$$是奖励模型给出的奖励值,表示模型认为输出$$y$$对于输入$$x$$的好坏程度。$$\succ$$表示偏好关系,即$$y_i \succ y_j$$表示人类更喜欢$$y_i$$而不是$$y_j$$。
训练目标
训练奖励模型的目标是最小化负对数似然:
$$\mathcal{L}_{BT} = -\sum \log P(y_i \succ y_j|x)$$
这个公式表示,我们希望奖励模型给出的奖励值能够尽可能地符合人类的偏好。也就是说,如果人类更喜欢$$y_i$$而不是$$y_j$$,那么我们希望$$R(x, y_i)$$尽可能地大于$$R(x, y_j)$$。
方法 | 更新机制 | 优势 | 局限 |
---|---|---|---|
PPO | 带约束的策略梯度 | 训练稳定 | 需要价值函数估计 |
DPO | 直接偏好优化 | 无需奖励模型 | 依赖高质量偏好数据 |
GRPO | 组相对策略优化 | 降低方差 | 需要并行采样多个响应 |
在强化学习中,奖励函数的设计至关重要。奖励函数定义了模型在不同状态下应该获得的奖励,从而引导模型学习到期望的行为。
根据奖励的来源,可以将奖励分为过程奖励和结果奖励。
过程奖励(Process Reward)
过程奖励是指在每个步骤中,根据模型的行为给出的奖励。过程奖励可以提供更密集的反馈信号,帮助模型更快地学习。但缺点是设计比较困难,需要对任务有深入的理解。
举个例子:
def calculate_step_reward(response):
# 1. 语法正确性检查
syntax = check_syntax(response)
# 2. 逻辑连贯性评估
coherence = model.predict_coherence(response)
# 3. 事实一致性验证
fact_check = retrieve_evidence(response)
return 0.3*syntax + 0.5*coherence + 0.2*fact_check
在这个例子中,奖励函数考虑了三个方面:
对这三个方面进行加权求和,得到最终的奖励值。权重的选择需要根据实际情况进行调整。一般来说,更重要的方面应该分配更高的权重。
结果奖励(Outcome Reward)
结果奖励是指在任务完成后,根据模型的最终结果给出的奖励。结果奖励的设计比较简单,只需要关注最终结果即可。但可能提供较稀疏的反馈信号,导致模型学习困难。典型应用场景包括:
举一个 思维树(ToT)算法框架 的例子:
方法 | 核心思想 | 适用场景 |
---|---|---|
链式思考(CoT) | 显式生成推理步骤 | 数学解题、逻辑推理 |
自洽性解码(SC) | 多路径投票机制 | 开放域问答 |
思维树(ToT) | 树形结构空间搜索 | 复杂规划问题 |
蒙特卡洛树搜索(MCTS) | 模拟 - 评估 - 回溯机制 | 游戏类、策略性问题 |
不同的推理增强技术适用于不同的场景。如何根据具体的问题选择最优的推理增强技术呢?这就是 计算最优扩展策略 要解决的问题。
动态计算分配算法 的核心思想是根据问题的难度动态地分配计算资源。对于简单的问题,可以使用简单的推理方法;对于复杂的问题,可以使用更复杂的推理方法。
伪代码示例:
def dynamic_compute_allocation(query):
difficulty = estimate_difficulty(query)
if difficulty < 0.3:
return greedy_decode()
elif 0.3 <= difficulty < 0.7:
return beam_search(width=3)
else:
return monte_carlo_tree_search(depth=5)
在这个例子中,estimate_difficulty
函数用于评估问题的难度。根据问题的难度,选择不同的推理方法。
如何评估问题的难度呢?一个思路是根据问题的特征来预测。比如:
验证器增强推理 是一种通过使用验证器(Verifier)来检查模型生成的答案的正确性,从而提高推理准确率的技术。
可以构建一个多层验证体系,对模型生成的答案进行多方面的验证。
下面这个公式描述了如何将多个验证器的结果组合起来:
$$V_{total} = \prod_{i=1}^n V_i(s) \quad V_i \in [0,1]$$
其中,$$V_{total}$$表示总的验证分数,$$V_i(s)$$表示第$$i$$个验证器对答案$$s$$的评分,$$n$$表示验证器的数量。这个公式表示,总的验证分数是所有验证器评分的乘积。每个验证器的评分都在 0 到 1 之间,评分越高,表示答案越可靠。
奖励误导(Reward Hacking)
示例:
当前最佳方案:多目标对抗训练。多目标对抗训练是一种通过同时优化多个目标,并引入对抗性损失来防止模型过度优化表面指标的技术。
长程推理(Long-Range Reasoning)
示例:
当前最佳方案:层次化记忆机制。层次化记忆机制是一种通过将长文本分解为多个段落或章节,并使用层次化的记忆结构来存储和检索信息的技术。
个性化安全(Personalized Safety)
示例:
当前最佳方案:差分隐私强化学习。差分隐私强化学习是一种通过在训练过程中添加噪声来保护用户隐私,并在推理时根据用户的偏好进行调整的技术。
为了解决上述技术瓶颈,研究人员正在探索一些新的研究方向。比如 元认知机制、物理推理融合 、 群体智能系统等。下面我将对这些方向进行更详细的讲解:
元认知机制(Meta-Cognition)
核心思想是让模型学会何时需要深入思考。元认知是指对认知的认知,即对自己的思考过程的思考。通过赋予模型元认知能力,可以使其能够判断自身是否能够解决当前的问题,并根据需要分配更多的计算资源。
伪代码示例:
def meta_cognition(query):
uncertainty = calculate_uncertainty(query)
if uncertainty > threshold:
return allocate_more_compute(query)
else:
return fast_response(query)
在这个例子中,calculate_uncertainty
函数用于评估模型对当前问题的不确定性。如果模型对当前问题的不确定性超过某个阈值,则说明该问题比较复杂,需要分配更多的计算资源(allocate_more_compute
);否则,说明该问题比较简单,可以使用快速响应(fast_response
)。
物理推理融合(Physical Reasoning)
核心思想是将符号推理与神经网络结合。物理推理是指模型根据物理定律进行推理的能力。通过将符号推理与神经网络结合,可以使模型既能够利用神经网络的强大表示能力,又能够利用符号推理的精确性和可解释性。
通过将这些物理规则嵌入到模型中,可以使模型能够进行物理推理,例如,预测物体在自由落体运动中的位置和速度。
群体智能系统(Swarm Intelligence)
群体智能是指由多个个体组成的系统,通过个体之间的协作来实现复杂问题的解决。通过构建多模型协作推理框架,可以使不同的模型发挥各自的优势,共同完成复杂的推理任务。
在这个流程图中,「任务分解」Agent 负责将问题分解为多个子问题,并将这些子问题分配给各个子任务Agent。「结果整合」Agent 负责将这些结果整合起来,得到最终的答案。
工具类型 | 推荐选项 | 核心功能 |
---|---|---|
微调框架 | HuggingFace PEFT | LoRA/QLoRA实现 |
RLHF平台 | TRL (Transformer RL) | PPO/DPO实现 |
推理加速 | vLLM | 分页注意力机制 |
监控评估 | Weights & Biases | 训练过程可视化 |