LLM reasoning & CoT

本文系统介绍了当前大语言模型推理(Reasoning)能力的核心技术路线,包括推理范式、推理蒸馏以及基于强化学习的推理训练方法,并实现了一套完整的 Reasoning Pipeline。在推理蒸馏阶段,利用 open-thoughts 数据集(由 DeepSeek-R1 生成的高质量推理轨迹)对 Qwen3.5 模型进行监督微调,使模型能够学习显式的 Chain-of-Thought 推理过程,从而获得基础推理能力。在此基础上,通过设计多种奖励函数对模型进行强化学习训练,进一步提升模型的推理能力与输出质量。本文通过完整的工程实践展示了从推理数据构建、蒸馏训练到强化学习优化的全过程,为构建具备推理能力的中小规模语言模型提供了一套可复现的实现方案。

大模型知识蒸馏

模型蒸馏即知识蒸馏,是一种模型压缩和加速技术。在深度学习中,大型深度神经网络虽性能优异,但因计算复杂度高、存储需求大,难以部署在资源受限设备上。模型蒸馏通过构建师生架构,让小的学生模型学习大的教师模型的知识,使学生模型在保持较小规模的同时,尽可能接近教师模型的性能。

Autograd from scratch

用了这么久的 PyTorch 框架,发现居然不知道它是怎么实现自动计算梯度的,今天来学习一下

我们回忆一下深度学习中,模型训练的流程。以简单的深度神经网络为例,我们不断把 mini-batch 送入网络进行前向传播,然后把输出的预测值同真实值对比,用 criterion 计算出此次迭代的 loss。之后把 loss 进行反向传播,送入神经网络模型中之前的每一层,以更新 weight 矩阵和 bias。其中前向传播就是一系列的矩阵+激活函数的组合运算,比较简单直观;反向传播就稍显复杂了,如果我们不用深度学习框架,单纯的使用 numpy 也是可以完成大多数的模型训练,因为反向传播本质上也就是一系列的矩阵运算,不过我们需要自己写方法以进行复杂的梯度计算和更新,而深度学习框架帮助我们解决的核心问题就是反向传播时的梯度计算和更新

LLM 中的强化学习:GRPO

GRPO 可以看做 PPO 的变体,我们回顾一下 PPO 这个算法:

LPPO=E[min(r(θ)A^, clip(r(θ),1ϵ,1+ϵ)A^)] \mathcal{L}_{PPO} = -\mathbb{E} \left[ \min\left( r(\theta) \hat{A}, \ \text{clip}(r(\theta), 1-\epsilon, 1+\epsilon) \hat{A} \right) \right]

PPO 需要同时加载 actor、ref、reward 和 critic 模型,reward 和 critic 模型得到 rewards 和 values 通过 GAE 计算得到 advantage,然后 actor 和 ref 模型得到新旧两个 log_probs 计算 KL 散度来约束模型变化。PPO 存在的问题就是,它需要 额外训练一个 critic model 显存翻倍了,其次 PPO 用的是 绝对优势,对 reward model 的噪声很敏感。所以 GRPO 的解决思路就是 去掉 critic model 同时用 相对优势 来代替。

LLM 中的强化学习:DPO

PPO 算法我们之前聊过,它需要同时加载四个模型(Actor、Critic、Reward Model、Ref Model),显存需求极大,还需要单独训练 Reward Model 和 Critic Model。 而 DPO 只需 2 个模型:待优化的 Actor Model (πθπ_θ) 和冻结的 Reference Model (πrefπ_{ref})。DPO 不对 prompt+response 打分,而是直接让模型学习区分 good answer (ywy_w) 和 bad answer (yly_l)。DPO 的本质就是把 reward model 隐式地参数化进了 policy 本身,从而一步到位完成对齐。

LLM 中的强化学习:PPO

PPO 算法可以看成 A2C 的优化版。A2C的训练策略是 “采样一次,更新一次,然后扔掉数据”,这就导致效率很低,每批数据只能用一次。PPO 采用 近端策略优化,它会对一批数据先进行采样得到 logprobref_logprobrewardsadvantages 等数据,然后进行 ppo_epochs 次循环。每次循环内,变化的只有概率分布 logprobref_logprobvalues,优势奖励这些都固定采用第一次得到的数据。

LLM 中的强化学习:基础知识

在 CS224N 中已经学习了一部分的 RLHF 但是感觉都忘掉了而且学习的一知半解,这次 minimind 正好也需要用到 RL 的知识,涉及到 PPO、DPO 啥的,所以来完整学习一遍。这次学习的目标就是搞懂 LLM 中强化学习的基本概念,学会目前常用的 PPO、DPO、GRPO 这几个算法,然后能调库进行 RLHF。

大模型量化

image.png

计算机中浮点数按 IEEE 754 标准存储,用 “指数+尾数” 的方式来表示一个实数的“科学计数法”形式。任何浮点数都可以写成:

(1)S×M×2E (-1)^S \times M \times 2^E

如上图:

LoRA&QLoRA

LoRA 现在的方案是 y=Wx+ΔWxy=Wx+\Delta{W}x 这样在旁路加一个矩阵进行微调,那为什么不选择 y=W2(W1x)y=W_2(W_1x) 这样的堆叠方案呢?

首先这种旁路设计可以保持原权重函数不变。LoRA 只提供一个低秩修正项。初始化时 A、B 接近零,模型行为≈原模型。训练是“微调偏移量”,不是“重建映射”。如果改成堆叠新层,前向函数直接改变,初始输出就漂移,大模型容易不稳定。

MiniMind 学习指北

在 CS336 的笔记中我已经完整介绍了一个 Tokenizer 是如何训练并且读取的,详情可见 cs336_assignment1

简单来说,训练一个 tokenizer 经过以下步骤:

  1. 通过正则分词,获得文本中全部 token,将其和 special_tokens 一起记录。
  2. 不断把文本中出现频率最高的 token_pair 合并得到新 token,然后用新 token 替换文本中原先的 pair。
  3. 重复上一步直到 vocab 达到指定规模。

上面的代码我们已经在 CS336 里实现过了,这一次我们通过 Huggingface 的 tokenizers 库直接生成。为了方便阅读,我先从如何得到一个 tokenizer 讲起。