想象你是一家新餐厅的主厨,怀揣五道拿手菜,却要接待来自天南海北的客人。客人点菜五花八门:有人要清淡素食,有人要重口川味,还有人想试试分子料理。你急需一本几百道菜的菜单,可手写菜谱太慢,请大厨太贵。怎么办?你让后厨团队参考已有菜品风格,批量试做新菜,再交给品控把关——留下好吃的、扔掉雷同的,如此反复,菜单就越滚越大。这是自指令(Self-Instruct)的横向扩菜法。接着你又想冲击米其林星级,把“番茄炒蛋”升级成“低温慢煮番茄水晶蛋”,增加工序、限定食材、要求更高技巧。这是 Evol-Instruct 的纵向升级法。本文就用这套“菜品进化论”,把大模型微调中的指令数据构建讲清楚。
掌握这两种自动化数据构建方法,你就能用少量种子指令造出高质高量的 SFT 训练集,这是算法工程师和数据工程师摆脱人工标注瓶颈的核心技能。
可视化演示
展示Self-Instruct从种子指令滚雪球扩展和Evol-Instruct进化增强两种数据构建方法的核心流程与对比。
本节配有交互动效(进入视口后自动加载,约 3KB)。
Self-Instruct数据管线 种子指令:175条人工编写,覆盖多任务类型 迭代生成:每轮采样6条做Few-Shot,滚雪球扩展 ROUGE-L去重阈值:0.7 从少量种子自动扩展至数万条指令数据。
指令数据概览
开餐厅首先要解决“菜谱从哪来”。同理,想让大模型学会听懂人话并漂亮地完成任务,监督微调(SFT)需要大量“指令—回答”对。指令是顾客的点单,回答是后厨端出的菜。没有足够菜单,后厨再厉害也应付不了千奇百怪的需求。
现实中人工标注指令数据非常昂贵:请一位专业标注员写 100 条高质量指令要好几小时,还难免带有个人风格、覆盖不全。这就像你主厨一个人把几百道菜都写出来,既慢又单调。于是业界开始寻求自动化:让模型自己生产训练材料,人工只做“质检”。
不过,自动构建不是瞎编。它需要一个清晰的数据结构来承载。指令数据集可以形式化定义为:
所以,SFT 的第一步就是造一个 D。Self-Instruct 和 Evol-Instruct 正是两条自动化造 D 的道路。方向清楚了,我们先进第一扇门:Self-Instruct。
- 指令数据集 D相当于最终菜单,所有训练样本的集合。
- 第 i 条指令 I_i由人写或模型生成的任务描述,比如“用一句话解释什么是机器学习”。
- 第 i 条回答 R_i模型应该输出的标准答案,是后厨端出的成品菜。
- 样本总数 N数据集中指令对的数量,N 越大通常数据越充沛。
Self-Instruct原理
Self-Instruct 的核心思路是“让模型当厨师,照着老菜谱做新菜”。你不需要手写几百条指令,只需要准备几十条高质量的种子指令,再把它们作为示例喂给大模型,让模型模仿新写一批指令、输入和输出。这就像让新厨师先尝五道招牌菜,然后说“照着这个风格,再创作十道”。
具体流程是:先建一个种子指令池,每条指令配上输入/输出;然后构造一个生成提示,让 LLM 批量产出候选新指令;接着对新指令做一轮过滤去重,剔除不合格项;最后把幸存者放回池子,作为下一轮生成的参考。如此反复多轮,池子就会像滚雪球一样膨胀。每一轮迭代可以被写成一个简洁的递推公式:
Self-Instruct 的关键在于生成提示中必须给出不同任务的示例,这能引导模型覆盖丰富领域。否则厨师只会围着烤鸭打转,菜单越翻越像同一道菜。所以,种子指令的多样性直接决定了扩展方向的广度。
- 第 t 轮数据集 D^{(t)}当前菜谱库,也就是已经通过质检的指令集合。
- 生成函数 Gen模型根据现有菜谱风格“创作新菜”的过程,对应一次 LLM 推理。
- 并集 ∪把模型新生成的指令并回池子,完成一次横向扩量。
- 迭代 t反复执行这个操作,每轮都会让菜单越来越厚。
数据质量控制
菜单厚了,但质量也得把关。你可以想象品控团队每天的工作:第一,新菜不能和菜单上已有菜太像;第二,卖相口味要达标;第三,菜品种类要覆盖不同顾客群体。对应到数据构建,就是去重、质量打分和多样性采样。
相似度去重非常关键。如果两条指令只是换了个说法,语义几乎一致,模型在训练时就会反复学习同一种模式,导致泛化能力差。工程上常用 ROUGE-L 或句向量余弦相似度衡量两条指令的接近程度。质量打分则依赖规则或小型评分模型:太短、无意义、包含敏感词、回答不完整都会被标记为坏菜。综合起来,一条候选指令是否保留可以写成如下判断:
多样性的另一个重要手段是采样:当一批新指令同时涌入时,优先选择与现有池相似度最低的那些,这样能够用更少的数据覆盖更广的任务类型。质量控制不是一次性的,而是每一轮 Self-Instruct 都要跑的例行检查。
- 质量打分 quality(x)相当于品控试吃评分,衡量指令是否清晰、完整、可执行。
- 相似度 sim(x,y)衡量新指令和池中某条指令长得有多像,相似度太高视为雷同菜。
- 阈值 θ质量下限,低于这条线的直接淘汰。
- 阈值 τ多样性上限,超过这条线的重复菜也淘汰。
- Keep(x)最终决定这道菜能不能进菜单,1 表示保留,0 表示丢弃。
Evol-Instruct原理
Self-Instruct 解决了“宽度”问题,但很多高难度任务不能靠简单指令覆盖。就像顾客想吃“分子料理”时,普通炒蛋就不够看了。Evol-Instruct 的思路是:让 LLM 把已有指令往深处演化——加约束、加步骤、具体化场景、要求逐步推理,从而制造出复杂度更高的训练样本。
演化方向通常分两类:深度演化(Deep Evolve)和广度演化(Breadth Evolve)。深度演化让指令更难,比如把“解释水循环”升级为“用初中生能听懂的语言,分四个步骤解释水循环,并各举一个城市洪涝的例子”。广度演化则把指令迁移到新场景,比如把“写邮件”升级为“写一封给客户的售后道歉邮件,语气要诚恳且不推卸责任”。演化之后,还需要一个复杂度评估步骤,防止模型把指令改得模棱两可甚至退化。它的核心约束可以写成:
Evol-Instruct 的产出和 Self-Instruct 可以合流。先让 Self 把数据量扩上来,再从中挑一批基础指令做深度演化,就能得到一个既有广度又有深度的 SFT 数据集。
- 原始指令 I演化前那道简单菜,比如“写一封邮件”。
- 演化后指令 I'模型加工后的新菜,比如“以营业厅经理身份写一封包含三点说明的投诉回复邮件”。
- 复杂度函数 complexity衡量指令要求的知识量和推理深度,可以基于指令长度、约束数量等近似。
- 提升量 δ强制要求复杂度至少增加 δ,保证演化不是换汤不换药。
方法对比取舍
开餐厅选择多条腿走路时,要清楚每条路擅长什么。Self-Instruct 是“开分店”:靠模板和迭代迅速增加菜品覆盖面,成本低、速度快,但容易出现大量相似指令,复杂推理能力偏弱。Evol-Instruct 是“做招牌”:专注把菜做精做深,产出高难度指令,对提升模型推理有帮助,但演化过程消耗更多算力,且指令过难可能让模型学不动。
实际选型要看业务目标。如果你的模型主要做文案写作、日常问答,Self-Instruct 的广覆盖更划算;如果模型要处理数学推理、代码生成、复杂决策,Evol-Instruct 的价值更大。两者不是竞争关系,而是前后脚关系:数据量不足时先用 Self-Instruct 补量,基础量够了再用 Evol-Instruct 精选提质。
从成本维度看,Self-Instruct 一轮生成可能只要一次普通推理,Evol-Instruct 则要多次尝试演化并筛选,成本更高。因此不少团队采用“双速”策略:80% 预算走 Self 扩量,20% 预算走 Evol 提质。这就像后厨既保留大锅菜满足翻台率,又设一个创意料理台打造口碑菜。
落地实践指南
把理论变成后厨标准流程,最直接的方式是复用开源工具。早期的 Stanford Alpaca 项目公开了 Self-Instruct 的数据生成脚本,你可以准备种子数据、调用大模型 API,一键生成数万条指令。WizardLM 则开源了 Evol-Instruct 的实现,可以配置深度/广度演化的轮数。这些工具像现成的锅铲,不需要从零造。
落地时先算总账。指令数据集通常由三部分组成:人工种子、Self 扩展、Evol 升级。总规模可以表达为:
实际操作中,建议先跑一个小规模试吃:用 100 条种子生成 2000 条数据,人工抽检 50 条,看质量和重复度。满意后再放大到十万级。同时别忘了把高质量种子和最终数据集一起喂给 SFT 训练,让模型既见多识广又精通难题。
- 种子指令量 N_seed人工精心编写的基础指令,是整本菜单的“骨血”。
- 自指令扩展量 N_self通过 Self-Instruct 自动生成的增量部分,负责铺量。
- 演化升级量 N_evol由 Evol-Instruct 加工出的高难度指令,负责拔高天花板。
AI 应用场景
场景一:垂直领域客服机器人指令扩充
阶段:数据准备与 SFT 微调
解决的问题:某电商公司要做一个客服大模型,但手头只有 50 条历史工单问答。人工标注几千条才能满足 SFT 需求,成本极高。用 Self-Instruct 快速把种子指令扩展到 5000 条,再配合相似度去重和质量过滤,最终得到干净的高覆盖训练集。
具体案例:数据工程师把 50 条真实问答作为种子,让 LLM 生成“退款怎么处理”“物流延迟如何解释”等新变体,经去重后得到 5000 条,抽检准确率 94%。模型微调后客服问题拦截率提升 27%。
场景二:代码助手复杂指令生成
阶段:指令演化与数据集构建
解决的问题:基础代码助手很容易被简单指令训练成“只会填空”,遇到多步骤调试需求就崩溃。用 Evol-Instruct 对已有代码问答做深度演化,增加“用单元测试验证”“解释边界条件”等要求,从而提升模型对复杂编码任务的推理能力。
具体案例:某团队从 2000 条基础代码问答出发,演化出 8000 条高复杂度指令,与原始数据混合微调。模型在 HumanEval 上的 pass@1 指标从 36% 提升到 52%。
Python 演示
# Simplified Self-Instruct-like data generation demoimport randomimport re SEEDS = [ "用一句话解释什么是机器学习", "把下列句子翻译成英文:今天天气很好", "写一首关于春天的五言绝句", "总结这篇文章的三个要点",] TEMPLATES = [ "请用通俗语言解释{concept}", "给{audience}写一封关于{event}的邮件", "列出{count}个关于{topic}的建议", "将文本改写成更正式的版本:{text}",] CONCEPTS = ["区块链", "量子计算", "递归神经网络", "数据增强"]AUDIENCES = ["客户", "老板", "小学生", "新人同事"]EVENTS = ["项目延期", "产品发布", "团队扩展", "预算调整"]TOPICS = ["时间管理", "代码规范", "团队协作", "自我提升"]TEXTS = ["这个功能下周上线", "预算需要再审批一次", "模型效果不错但有点慢"] def replace_placeholders(inst): for c in CONCEPTS: inst = inst.replace("概念", c) for a in AUDIENCES: inst = inst.replace("某人", a) return inst def generate_new(seed_num=10): dataset = [] seen = set() for seed in SEEDS: if seed not in seen: dataset.append(seed) seen.add(seed) for _ in range(seed_num): template = random.choice(TEMPLATES) inst = template.format( concept=random.choice(CONCEPTS), audience=random.choice(AUDIENCES), event=random.choice(EVENTS), count=random.randint(2, 5), topic=random.choice(TOPICS), text=random.choice(TEXTS), ) if inst not in seen: dataset.append(inst) seen.add(inst) return dataset def simple_filter(items): result = [] for item in items: if len(item) < 5: continue if re.search(r"失败|错误", item): continue result.append(item) return result def dedup_simple(items): return list(dict.fromkeys(items)) if __name__ == "__main__": random.seed(42) data = generate_new(seed_num=12) data = simple_filter(data) data = dedup_simple(data) print("Generated instruction dataset:") for i, inst in enumerate(data, 1): print(f"{i}. {inst}") print(f"Total: {len(data)}")
SEEDS = [...]人工编写的种子指令,对应餐厅的招牌菜底本。TEMPLATES可变指令模板,模仿“模型生成新指令”的提示模板。random.choice(TEMPLATES)随机选择一种指令模板,模拟模型从任务示例中创作。if inst not in seen完全一致的去重,防止相同指令重复进池。simple_filter规则过滤:太短或含敏感词的指令被淘汰。dedup_simple再跑一遍保序去重,确保最终数据干净。datasets.append(seed)先把种子加入数据池,保证扩展从可靠基础出发。
常见误区
误区只要用 Self-Instruct 源源不断生成数据,模型效果一定更好,数量最重要。
正解数据量爆炸但质量失控,等于往菜单里塞满雷同菜,顾客全吃腻。重复、低质量甚至错误指令会让模型学到噪声。过滤和多样性控制往往比单纯扩量更影响效果。
为何常见:直觉上模型见过更多样例就更强,却忽略了数据分布和质量才是决定 SFT 效果的关键。
误区既然叫“自指令”,那只要写好脚本,后面就全自动,人可以躺平。
正解种子指令需要人工精心挑选,每一轮生成结果需要人工抽检,过滤规则也需要人工迭代。自动化释放的是重复劳动,不是质量责任。
为何常见:“自”字容易让人误解为全自动,实际上工程中人工质检永远是最后一道保险。
误区Evol-Instruct 能造更难的指令,所以直接用 Evol 代替 Self 更高效。
正解两者解决不同问题,Self 负责横向扩量,Evol 负责纵向提质。没有足够的基础指令,Evol 就像没有食材的分子料理厨房,难为无米之炊。
为何常见:比较两种方法时,容易陷入“谁更好”的思维,忽略它们其实能前后衔接。
误区两条指令只要字面不完全一样,就算不同数据,可以保留。
正解语义重复同样会带来数据冗余。比如“翻译这句话”和“把这句中文变成英语”对模型来说是同一类任务。必须用 ROUGE-L 或向量相似度做语义去重。
为何常见:人的眼睛容易识别文字完全相同的重复,却难以在大规模数据中发现语义近义。
面试题
Q1. Self-Instruct 的核心思想是什么?
- A.让模型自己生成训练数据← 正确答案
- B.用人工标注全部数据
- C.用强化学习优化策略
- D.用蒸馏压缩模型
答案:A。Self-Instruct 的核心是让 LLM 基于少量种子指令自动生成新指令,再用过滤机制筛出高质量数据。人工标注全部数据是传统做法,强化学习和蒸馏关注的是训练策略而非数据构建。
Q2. Self-Instruct 的数据扩展通常从什么开始?
- A.随机噪声文本
- B.少量人工种子指令← 正确答案
- C.预训练语料库
- D.其他模型输出
答案:B。Self-Instruct 必须从少量人工精心设计的种子指令出发,它们决定生成方向。随机噪声文本和预训练语料库不携带任务语义,其他模型输出未经种子约束,难以生成合格指令。
Q3. 下列哪项不是指令数据质量控制的常用手段?
- A.语义相似度去重
- B.规则过滤敏感词
- C.提高模型参数量← 正确答案
- D.质量分数阈值筛选
答案:C。质量控制针对的是数据本身,包括去重、过滤和打分。提高模型参数量属于模型架构层面的选择,与指令数据构建无直接关系。
Q4. Evol-Instruct 的核心目标是?
- A.增加指令数量
- B.提升指令复杂度← 正确答案
- C.降低数据噪声
- D.加快训练速度
答案:B。Evol-Instruct 通过深度和广度演化,给指令增加约束、步骤和场景,目的是提升复杂度,从而训练出更强推理能力的模型。数量扩展是 Self-Instruct 的强项。
Q5. 已知新指令质量分 0.85,与已有数据最高相似度 0.92,若 θ=0.8、τ=0.9,该指令应如何处理?
- A.保留
- B.丢弃← 正确答案
- C.备份后保留
- D.降低阈值后保留
答案:B。保留条件是质量分 ≥ θ 且相似度 ≤ τ。虽然 0.85 ≥ 0.8,但 0.92 > 0.9,相似度超限,因此该指令应被丢弃。它相当于一道口味不错但与菜单上某菜太像的重复菜。
Q6. Self-Instruct 生成新指令时,通常需要哪些上下文?
- A.多个任务示例← 正确答案
- B.种子指令← 正确答案
- C.生成规则提示← 正确答案
- D.标签分布统计
答案:ABC。模型依赖任务示例、种子指令和规则提示来模仿指令写作风格。标签分布统计与指令生成无关,它通常用于分类任务的分析,不参与生成上下文。
Q7. 与 Self-Instruct 相比,Evol-Instruct 更擅长?
- A.提高指令多样性
- B.提高指令复杂度← 正确答案
- C.降低标注成本
- D.减少重复数据
答案:B。Evol-Instruct 的演化策略专门提升指令的约束、推理和知识要求,因此更擅长提高复杂度。多样性的扩展主要靠 Self-Instruct 的种子覆盖和采样策略。
Q8. 下列哪些属于 Evol-Instruct 的演化策略?
- A.增加约束条件← 正确答案
- B.具体化场景描述← 正确答案
- C.增加推理步骤要求← 正确答案
- D.删除背景信息
答案:ABC。演化策略包括加约束、加场景细节、加推理步骤,这些都是为了让指令更难、更具体。删除背景信息会降低指令信息量,属于退化而非演化。
Q9. 构建指令数据集时,最重要的目标是什么?
- A.数据量越大越好
- B.质量与多样性平衡← 正确答案
- C.完全自动化无人工
- D.使用尽量多种子指令
答案:B。高质量保证模型学得正确,多样性保证模型适应不同任务。只追数量或只求自动化都会牺牲数据可用性。种子指令适度即可,过多反而增加人工成本。
Q10. 关于 Self-Instruct 和 Evol-Instruct,下列说法正确的有?
- A.二者可以联合使用← 正确答案
- B.Self 偏横向扩展← 正确答案
- C.Evol 偏纵向深化← 正确答案
- D.两者方法完全相同
答案:ABC。Self 负责从种子向多领域扩展,Evol 负责把已有指令往复杂方向演化,二者互补。实践中常先用 Self 扩量再用 Evol 提质,但它们实现机制完全不同。