2.3 自造数据:用强模型蒸馏指令对


2.3 自造数据:用强模型蒸馏指令对

本节摘要:当开源集覆盖不了你的场景(中文、垂直领域、特定文风),标准做法是蒸馏:让一个强模型替你生产指令数据。本节拆解三步回环——①写种子指令(可手写几十条、可模板扩增、可用强模型自举扩写);②强模型按种子生成回答(或多轮对话);③质量过滤把住回流关口(规则 + 抽检 + 可选的模型打分),过滤不过的种子直接淘汰而不是修复。附可跑的蒸馏管线示意代码与成本结构分析。本节同时预告中文语料方案:中文 SFT 的主力产线正是这条回环(中文种子 → 强模型中文回答 → 中文质量过滤),详细展开在第 8 章。

学习目标

阅读完本节,你应当能够:

  1. 说出蒸馏回环三步(种子→生成→过滤)各自的质量责任。
  2. 跑通一条最小蒸馏管线,估算"一万条数据要花多少钱"。
  3. 为中英混合或纯中文场景设计数据配比。

一、为什么蒸馏是主旋律

开源指令集有两个天然盲区:你的领域(开源集里没有你业务的问答)与你的语言/文风(英文为主的语料养不出中文手感)。蒸馏用"强模型当作者、你当主编"解决两个盲区:

开源路线: 现成数据集 ──清洗──► messages JSONL (快、便宜、不贴身) 蒸馏路线: 种子指令 ──强模型生成──过滤──► messages JSONL (慢、花钱、贴身)

工业界的普遍认知(属共识级结论):主流开源对话模型的 SFT 数据大量来自更强模型的生成与蒸馏,纯人工标注只占小比例。nanochat 的发布帖思路亦同源——实验规模下取一批高质量问答对即可,数据从哪来(开源、自写、蒸馏)方法上等价。

⚠️ 合规提醒:用商业 API 的输出训练竞品模型通常违反其服务条款;用允许蒸馏的模型(各类开放权重模型,条款以其 license 为准)或自建模型为佳。教学实验之外的商业用途,先读条款。

二、回环三步

第一步:种子指令。 三种产法按成本递增:手写(几十条定基调,值得亲手写);模板扩增("解释 X 概念/比较 X 与 Y/给 X 写大纲"套主题词,几百条即时可得);模型自举(把 20 条手写种子给强模型:"仿照这些例子再写 200 条,保持分布多样",数千条起)。种子决定分布——它的题材配比就是未来模型的题材配比。

第二步:强模型生成。 每条种子作为 user 消息,请求强模型产出 assistant 回答;多轮数据则让强模型同时扮演用户追问与助手回答。生成参数用偏保守的低温(temperature 0.6 左右),数据要稳不要野。

第三步:质量过滤。 过滤不过就淘汰,不要试图修复(修复一条脏数据的成本高于再生成一条)。三道闸:

  1. 规则闸:2.2 的 rule_filter 直接复用;
  2. 模型闸(可选):再调一次强模型当裁判("这个回答是否正确、是否完整?输出 yes/no"),裁判比作者便宜且有效;
  3. 人工闸:随机抽 5%~10% 人眼过一遍,校准前两道闸的误杀率。

三、最小蒸馏管线

# distill_sft.py —— 最小蒸馏管线(写法示意,API 以所用服务文档为准) import json import random from openai import OpenAI # 任何 OpenAI 兼容接口均可(本地 vLLM、云端网关等) client = OpenAI() # 从环境变量读取 API Key SEEDS = [ # 第一步:手写种子(示例为中文科普向,第 8 章主力产线的雏形) "用三句话解释什么是熵。", "比较 TCP 和 UDP 的核心差异。", "给初学者列一个学习线性代数的三步计划。", # ... 实际使用时 50~2000 条,题材配比即模型未来的能力分布 ] GEN_PROMPT = "你是中文科普助手,回答准确、简洁,不超过 150 字。" JUDGE_PROMPT = "判断以下回答是否正确且完整。只输出 yes 或 no。\n\n问题:{q}\n回答:{a}" def generate(seed: str) -> dict: """第二步:强模型生成回答,产出 2.1 契约格式。""" r = client.chat.completions.create( model="填入允许蒸馏的模型名", messages=[ {"role": "system", "content": GEN_PROMPT}, {"role": "user", "content": seed}, ], temperature=0.6, # 数据要稳:低温生成 ) return {"messages": [ {"role": "user", "content": seed}, {"role": "assistant", "content": r.choices[0].message.content}, ]} def judge(obj: dict) -> bool: # 第三步·模型闸 q, a = obj["messages"][0]["content"], obj["messages"][1]["content"] r = client.chat.completions.create( model="填入裁判模型名", messages=[{"role": "user", "content": JUDGE_PROMPT.format(q=q, a=a)}], temperature=0.0, ) return r.choices[0].message.content.strip().lower().startswith("yes") if __name__ == "__main__": random.shuffle(SEEDS) kept = 0 with open("data_sft/distilled.jsonl", "w", encoding="utf-8") as out: for seed in SEEDS: obj = generate(seed) if not judge(obj): # 过滤不过直接淘汰,不修复 continue out.write(json.dumps(obj, ensure_ascii=False) + "\n") kept += 1 print(f"蒸馏完成:{kept}/{len(SEEDS)}")

工程上再加三件套才叫产线:断点续跑(按种子哈希记录已完成项)、并发(异步或线程池打满配额)、去重(回流进 2.2 的清洗管线,蒸馏数据同样要过精确去重)。

四、成本结构与配比

成本速算(示意估算,单价随服务波动):设生成 0.5 美元/百万输入 token、1.5 美元/百万输出 token,每条"一问一答 + 裁判一轮"约 600 输入 + 400 输出 token——一万条约 710 美元,十万条约 70100 美元。结论:蒸馏便宜到可以放心试错,贵的不是钱是种子质量。

配比建议(衔接第 8 章的伏笔):

目标 数据配比
中文对话模型 蒸馏中文主力(约 70%)+ 开源英文集(约 30%,保持通用能力不塌)
垂直领域 领域蒸馏(约 50%)+ 通用开源集(约 50%,防止只会聊领域)
快速原型 纯开源集起步,跑通第 3 章后再回头蒸馏

英文掺入的直觉:预训练语料(FineWeb-Edu)以英文为主,基座的"母语"是英文;中文 SFT 数据教它用中文表达,但底层能力仍大量寄存在英文参数里——完全切掉英文 SFT 数据,通用能力会明显滑坡(灾难性遗忘的温和形态,3.3 节展开)。

本节要点回顾

  1. 蒸馏 = 强模型当作者、你当主编:种子定分布、低温生成、过滤不过就淘汰。
  2. 三道过滤闸(规则/模型/人工抽检)与 2.2 的清洗管线首尾相接;产线三件套:续跑、并发、去重。
  3. 成本量级:十万条约几十到一百美元;中文场景 70/30 中英配比是稳妥起点,详细方案第 8 章落地。

燃料备齐(2.2 的开源集 + 2.3 的蒸馏产线汇成 data_sft/train.jsonl),第 3 章点火:把它喂给基座。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U