本页章节
TRAINING ENGINEERING / FINETUNING RECIPE
微调配方:从一万条数据到参数更新
数据条数、训练 token、epoch、batch 和 LoRA rank 分别描述不同的训练选择。沿着一份配方,把样本、监督位置、预算、可训练参数和评估结果对应起来。
先确定要让模型学会什么
| 需求 | 可选择的路径 | 需要什么数据 | 怎样评估 |
|---|---|---|---|
| 稳定输出格式、任务流程 | 提示基线 → SFT → 全参数或 LoRA。 | 输入与合格输出;覆盖缺失字段、模糊输入、异常情况。 | 内容正确性、协议符合率、未见模板和失败恢复。 |
| 获取经常更新、需要引用的事实 | 检索/工具提供当前证据,可再微调证据使用行为。 | 可信资料与访问接口;有依据的回答、无证据时的处理。 | 证据命中、引用支持、时效、权限和答案正确性。 |
| 适应领域分布 | 领域继续预训练,配合 SFT 和原能力回归。 | 领域原文与任务示范,区分新增知识和行为样例。 | 领域 held-out loss、任务质量、原有通用能力。 |
| 比较多个有效回答的取舍 | 偏好优化;有环境或规则奖励时可研究 RL。 | 偏好对、评分标准、可执行任务和验证器。 | 独立偏好、任务完成度、成本与奖励漏洞。 |
Base 与 Instruct 是不同起点。已经后训练的模型带有对话格式、拒答和工具行为,继续训练时需要保留这些能力的测试。选择底座还要核对许可、tokenizer、上下文、模板与部署支持;模型大小只是配方中的一项。
少量高质量示范有时能让已有能力更稳定地用于目标任务。LIMA(2023)研究了在已有 65B 模型上用 1,000 条精选示例训练的效果;这个结果依赖底座和测试范围。对新领域知识、长程工具任务或少数语言,应重新测量数据需求。具体依据见页尾 TRL、LIMA 与 LoRA 资料。
一条记录怎样变成训练序列?
原始记录 · 对话格式示例
{
"messages": [
{"role": "user", "content": "从‘周三十点与王老师讨论项目’提取日程。"},
{"role": "assistant", "content": "{\"time\":\"周三10:00\",\"person\":\"王老师\",\"topic\":\"项目\"}"}
]
}进入模型前
- 套用底座的 chat template。角色、轮次边界、BOS/EOS 与回答起点进入序列。
- 用对应 tokenizer 转成 ID。检查特殊 token 是否被重复添加,以及回答是否被截断。
- 构造标签和监督 mask。模型在位置 t 预测位置 t+1;由数据侧或模型内部完成一次 shift。
- 形成 batch。padding 或 packing 决定实际布局,attention 边界与 loss 边界分别设置。
多轮对话可能监督每个 assistant 轮次,也可能只监督末轮;工具观测通常作为上下文,工具调用动作可以成为监督目标。带 CoT 的记录还要说明哪些推理 token 被保留、是否计 loss、部署时允许多长输出。数据集有一行,并不代表只有一个监督片段。
生产流水线需要检查模板渲染结果和实际 mask。某个字段名写着 response,不能代替对 token 标签的核验。完整的梯度和边界推导见SFT 的 token mask 与对话模板。
一万条、三轮训练,对应多少 token 和更新?
本账本假设记录等长、每轮遍历一次、固定长度序列、右侧截断;不丢尾批,每个 epoch 结束时提交剩余累积梯度。所有长度已包含模板和特殊 token。
微调预算账本
教学调度模型 · 非框架默认值单条记录截断后,在一个长度槽中的占比
| 统计项 | 数量 |
|---|
packing 保持每条记录完整并隔离 attention,不跨记录预测。槽位填充率按固定长度与尾批空位计算,并非实测 GPU 利用率。变长 kernel、分布式 sampler 补样、drop_last、流式采样和 max_steps 会改变账本。
默认设置中,10,000 条记录读三遍,共处理 3,000 万非 padding token,其中 1,200 万是回答监督;每轮 157 个更新窗口,共 471 个。开启整条 packing 后,每完整序列放两条记录,更新窗口变成 237 个,监督总量保持不变。
这个差异说明:固定“每 batch 序列数”时,packing 会改变一次更新包含的原始样本量。比较训练效果时需要同时记录 token batch、学习率日程和更新次数。填充减少也不保证相同比例提速,实际执行还受 kernel、padding 消除和 attention 形状影响。
LoRA 的 rank 和 target modules 决定什么?
可训练矩阵账本
假设 32 层、7B 底座 · 非具名模型配置d=4096,KV 投影宽度=1024,FFN 中间宽度=11008。每层配置相同;不含 bias、embedding、LM head 或额外 modules_to_save。
| 矩阵 | 输入 → 输出 | 每层增量 | 32 层合计 |
|---|
Rank 决定增量容量
提高 r 增加可训练参数,选更多模块扩展可调整路径。数据量、学习率、目标模块和缩放共同影响结果;小 rank 也可能明显改变原行为。
QLoRA 改变底座存储精度
冻结底座以低位量化形式保存,计算时按实现恢复或转换;梯度经过底座计算图到达 adapter。参数梯度和优化器状态减少,激活、临时空间和底座存储仍需计算。
微调后的交付物
Adapter 需要精确匹配的底座 revision、tokenizer、模板和配置。合并得到完整权重后,还要在目标精度与推理引擎上回归;量化底座的合并与再量化需另行验证。
全参也有适用场景
全参提供更广的调整范围,同时增加优化器、梯度和保存成本。应在相同任务、训练预算与发布要求下比较实际收益。
条数之外,数据设计怎样影响训练?
列出任务切片
常见输入、长尾、无答案、歧义、错误工具结果、多轮约束分别采样。
定义可接受输出
标注依据、格式、错误处理、风格与边界。教师生成数据经过独立复核。
按关联来源切分
同用户、文档、仓库、题族或近重复簇尽量放在同一划分,隔离最终测试。
补充真实缺口
按失败类型扩充样本,记录规则和版本;复测目标能力与保留能力。
一千条同模板改写可能覆盖很窄的输入范围。十条不同表述也可能都源于同一事实或文档;独立性需要按任务判断。数据重复相当于提高样本权重,训练三轮应记作三次暴露,而独立信息量仍由原数据决定。
困难样本需有可靠答案;高 loss 也可能来自错误标注或不可判断问题。先抽查再决定提高采样权重。已有 Instruct 底座继续学习时,可混入需要保留的行为样本或研究教师约束,随后测量目标收益与遗忘程度。
怎样判断该补数据、加训练,还是换方案?
| 实验 | 固定与变化 | 能判断什么 | 需要防止的混淆 |
|---|---|---|---|
| 数据规模曲线 | 取嵌套子集,例如 500 / 2,000 / 10,000;固定独立评估与底座。 | 新增样本在各任务切片上的边际收益。 | 同 epoch 时训练 token 同时增长,要再做同预算对照。 |
| 固定数据的重复曲线 | 同一训练集,比较不同 epoch/checkpoint。 | 是否仍欠拟合,何时出现任务停滞或回归。 | 学习率日程、评估波动及验证集选参影响。 |
| 固定预算的质量对照 | 监督 token 或 FLOPs 对齐,比较清洗、来源或难例配方。 | 预算不变时配方是否改善目标任务。 | 不同长度、模型和目标下,相同 token 不一定同算力。 |
| 参数范围对照 | 同数据下比较 target modules、rank、全参,各自调合适学习率。 | 适配容量与原能力保持之间的实际取舍。 | 把“同学习率”误当成对各方案公平的优化设置。 |
曲线应来自实际独立评测,并报告样本数、区间和关键切片。格式满分而事实错误多,优先看答案依据;训练 loss 很低但新模板失败,优先看覆盖与泄漏;验证集和训练集都差,再检查标签、模板、优化和底座能力。这里提供实验设计,真实模型的曲线留给观测。
一份可复查的微调报告应包含哪些字段?
底座 revision;数据来源、独立记录数和切分规则;模板与 tokenizer;截断前后长度、有效监督 token 与 mask;packing 与采样;DP/microbatch/accumulation;epoch/max_steps;学习率、日程与精度;全参或 LoRA 的目标模块、rank、alpha;随机种子;所选 checkpoint;独立任务和保留能力;部署工件与运行成本。
十条样本分给三张卡,是否刚好读一遍?
Map-style 数据通常先由 sampler 给出索引顺序,再按 rank 分片,DataLoader 最后组成 batch。为了让各 rank 步数一致,sampler 可以补索引或丢尾索引;loader 的 drop_last 又决定各 rank 的尾 batch 是否保留。两处设置的作用不同。
样本 ID 分发账本
等量 rank 分片 · 教学随机置换置换后:
补齐或截断后:
| Rank | 分配索引 | 实际 batch | Loader 丢弃 |
|---|
补齐时循环取置换序列的开头,rank r 取 r,r+R,…;空数据不补样。随机算法是本页固定的教学实现,顺序不与 PyTorch 相同。这里不含 gradient accumulation、packing 或变长 token 计数。
默认 10 条、3 rank、每卡 batch=2:补齐到 12 个读取位置,所以至少两次读取是重复样本。Sampler 丢尾先保留 9 条,再由 Loader 丢尾可能只剩 6 条。评估时补齐样本也可能重复计分,需按原始 ID 去重或采用合适的汇总协议。
Rank 内还有多个 worker,谁负责避免重复?
Iterable 数据的四个读取者
2 rank × 2 worker · 样本数沿用上方| Rank | Worker | 全局编号 | 读取 ID |
|---|
IterableDataset 在不同 worker 中有各自副本。如果每个副本都遍历完整数据,就会重复读取。一个可行规则是 global_worker=rank×workers+worker_id,按编号对总 worker 数取模分片;块读取、远程 shard 和变长流可用其他规则,但需要证明覆盖与互斥。
Map-style DataLoader 的索引通常由主进程 sampler 分配,不应再无意套一层相同分片。每轮 shuffle 的 epoch/seed、worker 随机数、预取队列和已消费数据位置需要区分。精确恢复应保存“已用于更新”的游标,读取到了但仍在预取队列里的样本未必已参与训练。
适用范围与一手资料
预算使用等长记录和固定长度槽;样本分发另行展示 sampler 补齐/丢尾与 loader 丢尾。教学 shuffle 不复现 PyTorch RNG。LoRA 使用假设配置,槽位填充率不代表 GPU 利用率。
公式与机制的原始依据 · 7 项
- Hugging Face TRL · SFT Trainer数据格式、模板、assistant/completion loss、截断与 packing;文档于 2026-10-27 核对
- LoRA (2021)冻结原权重与低秩增量;可训练范围需看配置
- Hugging Face PEFT · LoRArank、目标模块、QLoRA 与 adapter 合并;具体默认值依版本
- QLoRA: Efficient Finetuning of Quantized LLMs (2023)冻结低位底座与可训练低秩增量、内存和质量评估
- LIMA: Less Is More for Alignment (2023)已有 65B 底座与 1,000 条精选示例的特定实验;不是通用数据需求阈值
- PyTorch · CrossEntropyLoss完整类别分母、ignore_index 与 reduction
- PyTorch · DataLoader and DistributedSampler采样索引、尾批、epoch 随机性和 IterableDataset worker 分片