微调与量化
为什么需要参数高效微调
全量微调 7B 模型(fp16 + Adam)的显存构成:
参数 2B + 梯度 2B + Adam 动量 4+4B + fp32 参数副本 4B = 每参数约 16 字节
7B × 16 = 112 GB
单张 A100(80GB)装不下。而参数高效微调(PEFT) 的思路是冻结原权重、只训练极少量新增参数,把显存降一到两个数量级。
LoRA
核心假设:微调时权重的变化量 ΔW 是低秩的 —— 适配一个下游任务并不需要在全参数空间里移动,真正有效的更新集中在一个低维子空间。
做法:冻结原权重 W₀,把更新量分解成两个小矩阵的乘积:
h = W₀x + ΔWx = W₀x + (B·A)x
W₀ ∈ ℝ^(d×k) A ∈ ℝ^(r×k) B ∈ ℝ^(d×r) r ≪ min(d,k)
参数量从 d×k 降到 r×(d+k)。举例 d=k=4096, r=8:从 1678 万降到 6.5 万,降到 0.4%。
两个实现细节(常被追问):
- A 用高斯随机初始化,B 初始化为零 —— 保证训练开始时
BA = 0,即h = W₀x,模型行为与微调前完全一致,不会一上来就破坏预训练能力 - 缩放系数
α/r—— 实际计算是h = W₀x + (α/r)·BAx。这样调整 r 时不需要重调学习率。常见配置是α = 2r或α = r
推理零开销 —— 训练完可以把 BA 合并回 W₀(W = W₀ + BA),得到一个与原模型结构完全相同的权重,推理延迟不增加。这是 LoRA 相对 Adapter(串行插入新层,必然增加延迟)的关键优势。
加在哪些层 —— 原论文只加在注意力的 W_Q 和 W_V。实践中加到所有线性层(q, k, v, o, gate, up, down)效果更好,代价是参数变多。秩的选择:简单任务 r = 8,复杂任务或风格迁移 r = 32~64,再大收益递减。
多 LoRA 服务 —— 同一个基座 + 多个 LoRA 权重(每个几十 MB),可以在一次部署里服务多个任务,运行时动态切换(S-LoRA、vLLM 的 multi-LoRA)。这是 LoRA 的巨大工程价值。
QLoRA
在 LoRA 基础上把基座模型量化到 4bit,使 65B 模型能在单张 48GB 卡上微调。三个关键技术:
- NF4(4-bit NormalFloat) —— 不是均匀量化。基于「预训练权重近似服从正态分布」的观察,设计了信息论上最优的分位量化数据类型,让每个量化桶承载相同的概率质量
- 双重量化(Double Quantization) —— 量化过程本身会产生缩放常数(每 64 个权重一个 fp32 常数,平均每参数 0.5 bit)。把这些常数再量化一次,平均降到 0.127 bit/参数
- 分页优化器(Paged Optimizers) —— 利用 NVIDIA 统一内存,显存峰值时把优化器状态换出到 CPU 内存,避免 OOM
注意梯度仍以 bf16 计算,只有存储是 4bit —— 前向时把权重反量化回 bf16 再算。所以 QLoRA 省显存但不省时间,训练速度比 LoRA 慢约 30%。
量化(推理侧)
| 方式 | 时机 | 说明 |
|---|---|---|
| PTQ(训练后量化) | 训完再量化 | 不需要重训,主流方案 |
| QAT(量化感知训练) | 训练时模拟量化 | 精度更好但要重训,成本高 |
三种主流 PTQ 方法:
- GPTQ —— 逐层量化,用少量校准数据和二阶信息(Hessian)逐列调整未量化权重以补偿误差。4bit 下精度损失很小
- AWQ(Activation-aware Weight Quantization)—— 关键洞察是只有约 1% 的权重通道是「显著」的(对应激活值大的通道),保护这部分就能保住精度。通过逐通道缩放实现,无需反向传播,速度快且泛化好
- SmoothQuant —— 针对 W8A8(权重和激活都量化),把激活的量化难度「迁移」一部分到权重上,让两边都好量化
W4A16 vs W8A8 —— 前者只量化权重(激活保持 fp16),适合 decode 阶段的 memory-bound 场景,显存和带宽都省;后者权重激活都量化,能用上 INT8 Tensor Core,适合 prefill 的 compute-bound 场景。
KV Cache 量化 —— 长上下文下 KV Cache 可能比权重还大,量化到 INT8 甚至 FP8 能直接翻倍可用上下文长度。
该微调还是该用 RAG
高频架构题。判断标准是要解决的是「知识」问题还是「行为」问题:
| 需求 | 方案 |
|---|---|
| 补充私域知识、事实需要更新 | RAG。微调无法可靠注入事实,且知识一变就要重训 |
| 固定输出格式、特定语气风格 | 微调。prompt 也能做但不稳定,微调更可靠且省 token |
| 领域术语和表达习惯 | 微调 |
| 教会新任务 / 复杂推理模式 | 微调(SFT),或先试 few-shot |
| 降低推理成本(用小模型替代大模型) | 微调(蒸馏大模型的输出) |
| 需要引用来源、可审计 | RAG(必须) |
顺序建议:先 prompt 工程 → 再 RAG → 最后才微调。前两者迭代快、成本低、可逆;微调需要数据准备、训练、评测、部署一整套,且模型一旦微调就要承担长期维护成本。
两者不互斥 —— 生产系统常见组合是「微调模型学会怎么用检索到的材料回答 + RAG 提供事实」。
被问「我们公司有一批文档,想让模型回答相关问题,该怎么做」时,答微调是陷阱。正解是 RAG,理由要讲清:文档会更新(微调要重训)、需要引用溯源(微调给不出)、成本低几个数量级。