要让一个模型稳定输出客服需要的 JSON,可以修改全部参数,也可以只训练 LoRA;训练信号则可以来自示范,也可以来自偏好比较。“改哪些参数”和“按什么目标训练”是两件事,LoRA 与 SFT 完全可以同时使用。把这两个问题分开,后面的选择就容易多了。
这页负责比较方法。想看具体计算,可以接着读:
- Prompt / Prefix / Adapter:同一小模型里,更新位置、参数量和部署成本怎样不同。
- LoRA / QLoRA:低秩更新的梯度、初始化、显存与量化。
- 蒸馏:软标签、top-k 尾部概率与 on-policy 前缀。
四种参数适配方式
Full Fine-Tuning:整个模型都能动
Full-parameter fine-tuning 对所有参数求梯度:
$$ \theta\leftarrow\theta-\eta\nabla_\theta\mathcal L. $$
它给优化器最大的自由度,通常也需要最多的训练显存、optimizer state 和 checkpoint 存储。数据少或学习率控制不好时,还更容易过拟合(overfitting)或破坏原有能力。它适合数据充分、任务变化大,而且确实需要改变模型内部表示的场景。
LoRA:学习权重更新,而不是重训整块权重
对冻结的线性层 $W_0\in\mathbb R^{d_{out}\times d_{in}}$,LoRA 学习低秩增量:
$$ W=W_0+\Delta W,\qquad \Delta W=\frac{\alpha}{r}BA, $$
其中 $A\in\mathbb R^{r\times d_{in}}$、$B\in\mathbb R^{d_{out}\times r}$,且 $r\ll\min(d_{in},d_{out})$;$\alpha/r$ 控制增量尺度。基础权重冻结,只更新 $A,B$。它改的是模型内部线性变换,比只改输入的 Prompt Tuning 表达自由度更高;部署时也可以动态挂载或合并 adapter。
Prompt Tuning:只学习输入前的 virtual tokens
Prompt Tuning 冻结整个模型,只在正常 token embedding 前拼接 $m$ 个可学习向量 $P$,直接参数量是 $m\,d_{model}$。 $P$ 叫 soft prompt。它不是一句隐藏的自然语言,也不对应词表(vocabulary)里的 lexical token ID (框架可以给它分配占位索引),通常不能翻译成人能读懂的词。公式、参数账,以及“模型冻结了,梯度为什么还要穿过它”,见 Prompt / Prefix / Adapter。
每个任务可以保存一份很小的 $P_k$,共享同一个大模型:
P_refund + 用户消息 → 冻结模型 → 退款任务输出
P_routing + 用户消息 → 冻结模型 → 路由任务输出
P_summary + 对话记录 → 冻结模型 → 摘要
推理时 soft prompt 也必须放在输入前;它不是训练完就被吸收到基础模型里。代价是多占 $m$ 个上下文位置,并让每层多处理这些位置。
完整例子:用 Prompt Tuning 做电商客服分类
假设固定类别为 退款 / 物流 / 商品咨询。为这个任务训练五个 virtual-token embeddings:
$$P_{route}=[p_1,p_2,p_3,p_4,p_5].$$
一条训练数据是:
输入:我的包裹什么时候到?
标签:物流
模型实际接收:
[p1][p2][p3][p4][p5] 我的包裹什么时候到?
如果第一次给“物流”的概率很低,classification loss 或 label-token CE 产生梯度。模型权重不动,五个 $p_i$ 被更新。许多样本之后,这组向量学会把冻结模型带入“客服路由”的内部工作状态。上线后,任何新消息都先拼同一组 $P_{route}$。
这组向量主要是在调用与重组模型已有能力。如果基础模型根本不懂新的企业政策或商品事实,soft prompt 很难凭少量参数把知识装进去;此时更应考虑 retrieval、continued pretraining、LoRA 或 full fine-tuning。
Prefix Tuning:不只在输入层加向量
Prompt Tuning 通常只在 embedding 层加 virtual tokens;Prefix Tuning 为每一层 attention 直接提供可学习的 prefix key/value,普通 token 的 Query 可以在每一层关注它们。直接存储的规模约为 $2Lmd_{KV}$,其中 $d_{KV}$ 是每层实际的 KV 宽度,GQA / MQA 下小于 $d_{model}$;若用小 MLP 生成各层 prefix,可训练参数还要把 MLP 算进去。逐项的参数账见 Prompt / Prefix / Adapter。它比 Prompt Tuning 更直接影响各层注意力,参数更多、表达力也通常更强:
Prompt Tuning:input embedding 前加 P
Prefix Tuning:每一层 attention 都加入 learned K/V prefix
两者都属于 parameter-efficient fine-tuning(PEFT),但不是同一个机制。
一句话分清:为什么 Prompt Tuning 也会产生每层 K/V,却仍不等于 Prefix Tuning?
Prompt tokens 像普通 token 一样从输入层逐层传播,因此当然会在每层产生 K/V;但这些状态都由同一组输入 embeddings 间接演化而来。Prefix Tuning 则为各层直接提供 layer-specific prefix K/V,每层拥有独立控制信号。
分类输出怎么保证只落在合法标签里
Soft prompt 只能让正确标签更可能,不能单独保证输出 schema。可靠系统要把“模型学得准不准”和“输出是否合法”分开处理。
方法一:直接给固定标签打分
不让模型自由生成,而是比较候选(candidate)标签的 sequence log-probability(条件里的 $P$ 是前面学到的 soft prompt,$c_j$ 是标签 $c$ 的第 $j$ 个 token):
$$ \hat c=\arg\max_{c\in\mathcal C}\log P(c\mid P,x), \qquad \log P(c\mid P,x)=\sum_j\log P(c_j\mid P,x,c_{<j}). $$
工程上常用单 token、等长的 A/B/C 再映射到业务标签,避免不同 tokenization 与标签长度带来的偏差。
方法二:Constrained Decoding
约束的是完整标签序列,不是把标签里出现过的 token 合成一张固定白名单。例如合法标签是两个 token 组成的 a b 和 a c,仅允许 a/b/c 仍会生成非法的
b a。即使标签都是单 token 的 A/B/C,连续生成两步也可能得到非法的 AA。
多 token 标签可以组织成前缀树:每一步根据已经生成的标签前缀,只保留仍能到达某个合法标签的下一 token;只有当前前缀已经是完整标签,才允许结束。若一个标签也是另一个标签的前缀,可以结束,也可以沿合法分支继续。对其余 logits 置 $-\infty$。
下面用字母代指已经确定的 token ID,用保留符号 <EOS> 表示结束;它不属于任何标签。
prefix 只包含新生成的标签部分,不包含输入问题。这只是下一步允许集合的示例,不是完整解码器:
def legal_next_tokens(prefix, labels):
allowed = set()
for label in labels:
if label[:len(prefix)] != prefix:
continue
allowed.add("<EOS>" if len(prefix) == len(label) else label[len(prefix)])
return allowed
labels = (("a", "b"), ("a", "c"))
print(sorted(legal_next_tokens((), labels)))
print(sorted(legal_next_tokens(("a",), labels)))
print(sorted(legal_next_tokens(("a", "b"), labels)))
print(sorted(legal_next_tokens(("b",), labels)))
四行输出依次是 ['a']、['b', 'c']、['<EOS>']、[]。最后一个空集合表示路径已非法,应报告失败,不能退回“不加约束”。实际服务还要处理 tokenization、logits mask 和停止条件;被长度或时间上限截断的未完成标签不能作为合法结果返回。
若已验证业务标签在当前 tokenizer 和生成上下文中分别对应一个 token,则可以只允许这些 token,恰好生成一步就停止,再映射回业务枚举。前缀约束或这个单步特例保证的是成功完成时的格式,不是分类准确率;它们也不保证每次请求都能成功完成。
实现接口可参考 Transformers v5.20.0 的前缀约束文档
(2026-10 核对);这里没有调用该库,也没有假设其他版本的行为。用推理服务部署时,引擎通常自带这类约束:例如
vLLM 的 structured outputs 可以用 choice 让输出恰好是几个候选之一,也支持正则、JSON schema 和语法约束(2026-10 核对 stable 文档)。
方法三:Classification Head
取一个 hidden state $h$,训练固定输出维度的分类头:
$$ p(c\mid x)=\operatorname{softmax}(W_ch+b). $$
类别固定、只需要分类时,这通常比让 decoder 自由生成更直接。可以冻结 backbone,同时训练 soft prompt 与小分类头。
模型或 soft prompt 提高 accuracy;serving constraint 保证 schema。 不要把格式保证寄托在一句“请只输出标签”的自然语言指令上。
Distillation:监督来自 Teacher
Knowledge Distillation(知识蒸馏)通常有一个能力更强或成本更高的 Teacher,以及要部署的 Student。它不是一种固定的参数更新方式,而是一类监督来源。
常见的有三种。Response distillation:Teacher 先生成答案,Student 把它当示范做 SFT;实现简单,但只保留一条采样结果,看不到 Teacher 对其他 token 的相对偏好。Logit / distribution distillation:Student 拟合 Teacher 的 token 分布,经典做法是用温度 $T$ 软化两边分布后算 KL,再乘 $T^2$;只存 Teacher top-$k$ logits 时,要明确处理剩余概率质量、tokenizer 映射以及 mask 和归一化。On-policy distillation:Student 先从当前策略采样,Teacher 再给这些前缀上的 token 分布打分;监督更贴近 Student 真正会访问的状态,代价是持续 rollout、Teacher 推理和权重版本管理。三种做法的算例、温度和 top-k 的细节见蒸馏。
Distillation 可以和任何 parameterization 组合:Student 可以 full fine-tune,也可以只训 LoRA。Teacher 通常冻结;Student 才是被优化和最终部署的模型。
怎么选
| 目标 | 更自然的起点 | 原因 |
|---|---|---|
| 多个简单任务共享同一超大模型 | Prompt / Prefix Tuning | 每个任务只保存少量参数 |
| 需要明显改变内部行为,但资源有限 | LoRA-SFT | 比 soft prompt 自由度高;可训练参数、optimizer state 和 checkpoint 远小于 full FT |
| 数据充分、任务差异大、追求最高适配上限 | Full Fine-Tuning | 参数约束最少,但成本和回归风险最高 |
| 把大模型能力迁到小模型 | Distillation | Teacher 可以大量生成示范;logit 蒸馏还能提供比 hard label 更密的监督 |
| 固定枚举分类 | Label scoring 或 classification head | 不需要承担自由生成的不确定性 |
| 缺少会变化的外部事实 | Retrieval / tool use | 不应指望微调(fine-tuning)参数充当实时数据库 |
面试时最值得说清楚的三句话
- Prompt Tuning 学的是连续 virtual-token embeddings,不是自然语言 prompt;模型冻结,推理时仍要把它们拼到输入前。
- LoRA、Prompt Tuning 和 full fine-tuning 描述参数怎样更新;SFT、DPO 和 distillation 描述监督与 objective,两组概念可以交叉组合。
- 对分类任务,训练方法负责 accuracy,固定标签打分、constrained decoding 或 classification head 负责输出合法性。
自检
- 为什么 soft prompt 不对应词表里的 lexical token,也不一定能翻译成人话?
- Prompt Tuning 与 Prefix Tuning 分别在哪一层加入参数?
- 为什么“LoRA 和 SFT 哪个更好”不是一个完整的问题?
- 如何让生成式分类器保证只返回合法枚举值?
- Response distillation 与 token-distribution distillation 丢失的信息有什么不同?
继续阅读
快速学习:先把两条轴分开
两分钟讲清这些方法到底差在哪里
第一条轴是 learning objective(学什么):可以用 demonstration 做 SFT,用 teacher distribution 做 distillation,用 chosen/rejected pair 做 DPO,也可以用 reward 做 RL。
第二条轴是 parameterization(改哪里):可以更新全部权重,训练 LoRA / Adapter,或者只训练输入侧的 soft prompt。两条轴可以组合,例如 LoRA-SFT、LoRA-DPO,或者用 LoRA 参数化的 student 做 distillation。
Distillation 决定监督从 teacher 来;LoRA 与 Prompt Tuning 决定梯度允许改哪些参数。
深挖:为什么这个区分很重要?
如果实验说“LoRA 比 SFT 好”,比较本身就不完整:LoRA 是更新参数的方式,SFT 是数据与损失。正确对照应当是 full-parameter SFT 与 LoRA-SFT,或者在相同 parameterization 下比较 SFT 与 distillation。否则改变了两件事,却不知道提升来自哪里。
flowchart LR
B["Pretrained / SFT model"] --> O{"训练信号<br/>Learning objective"}
O --> S["Demonstrations · SFT"]
O --> D["Teacher outputs · Distillation"]
O --> P["Preferences · DPO"]
O --> R["Reward · RL"]
S --> U{"更新哪些参数<br/>Parameterization"}
D --> U
P --> U
R --> U
U --> F["Full fine-tuning"]
U --> L["LoRA / Adapter"]
U --> T["Prompt / Prefix tuning"]
参考论文
- The Power of Scale for Parameter-Efficient Prompt Tuning
- Prefix-Tuning
- LoRA
- Distilling the Knowledge in a Neural Network
本页术语 5
- 过拟合 overfitting
- 训练集越来越好,没见过的数据反而变差
- 词表 vocabulary
- 模型能输出的所有 token 的集合
- 候选 candidate
- 召回阶段捞出来、等待精排挑选的内容
- 蒸馏 distillation
- 用一个模型的输出训练另一个通常更小的模型
- 微调 fine-tuning
- 在预训练权重上继续训练以适配具体任务