LLM自进化这个话题,最近半年在圈子里被反复聊起,每次组会都有人问“能不能让模型自己生成数据再自己训自己”。说白了,这就是一个增强回路:大模型自己出题、自己作答、自己打分,再把筛选后的数据喂回去微调,让下一次迭代更强。它的价值不是替代人工标注,而是把那些人工成本过高、又必须反复积累的环节自动化,让模型在已经学会的能力基础上持续爬坡。这篇文章我会把自进化的几条主流技术路线拆开讲清楚,然后给出一条我能跑通的最小流水线实录,最后说说我在数据塌缩、自评偏差上踩过的坑,希望对正在做 LLM 微调或 Agent 落地的朋友有参考价值。
1. LLM自进化到底在解决什么问题
1.1 从数据瓶颈说起
做对话模型、垂直领域助手的人都有体会:模型效果的上限,很大程度上被训练数据卡着。公开的高质量指令数据就那么些,英文的多、中文的少,通用场景多、专业场景少。想自己标注一批数据,招人、写标注规范、做质检,一套下来成本极高,还未必能覆盖长尾场景。
自进化的核心动机就在这里:与其等人来写数据,不如让模型利用已有能力去“产出”训练素材。这背后的前提是,现阶段的 LLM 在生成、判断、反思上已经具备相当强的能力。它虽然不能保证每个回答都正确,但它能生成大量候选,也能大致判断哪些回答更好——这两件事组合起来,就构成了一条可以自动转起来的数据生产流水线。
要注意的是,“让 AI 自己训练自己”并不是指模型直接修改自己的权重,那是当前架构做不到的。实际的做法是:模型产出数据 → 用某种机制筛选 → 用筛选后的数据做监督微调(SFT)或偏好优化(DPO/RLHF)→ 得到新模型 → 继续迭代。自进化是一个训练流程层面的工程方案,不是一个神秘的算法。
1.2 自进化的基本框架
不管技术路线怎么变,自进化流水线大致都长这样:
- 种子集:一小撮高质量种子指令或问题,作为起点,可能只有几十到几千条。
- 生成:用当前模型(或辅助模型)对种子集进行扩写、改写、多轮生成,扩大数据规模。
- 筛选:通过规则、外部工具、模型自评分等方式过滤低质量样本。
- 训练:在筛选后的数据上做 SFT 或 DPO,得到新一轮模型。
- 评估:用固定评测集检查是否真的变强了,决定是否继续迭代。
这个框架本身不复杂,真正的难点在每个环节的质量控制。生成环节怎么保证多样性,筛选环节怎么防止模型“自卖自夸”,训练环节怎么避免灾难性遗忘,这些都是实操里绕不开的坎,后面我会一个个展开。
2. 三大主流技术路线拆解
2.1 自指令与合成数据:让模型当出题人
先说最经典的一条线,代表工作是斯坦福 2022 年的 Self-Instruct。它的思路很直接:先准备一小批种子指令(比如 175 条人工写的任务描述),让模型模仿这些指令的风格,生成新的指令;然后让模型为新指令生成回答;最后用规则过滤掉过于相似的样本,合并成新数据集去微调模型。
这个方案最容易被低估的点是“指令生成”的难度。你如果直接跟模型说“再给我生成 100 条问题”,它往往会退化成同义改写,表面上一堆变体,实际信息量很低。Self-Instruct 原文里做了不少细节设计,比如限制关键词重叠度、用 ROUGE 相似度去重,就是为了逼模型产出真正多样的任务。
后来的合成数据工作基本都在这个框架上加料。比如在指令里要求模型替换领域、变换复杂度、指定输出格式;或者用一个强模型(比如大参数的闭源模型)做教师,生成数据后再交给小模型去学。我自己的经验是,自指令生成的数据质量方差很大,必须配合严格筛选,否则模型很快会学到“话多但空洞”的毛病。
2.2 自评估与自反馈:让模型当裁判
第二条线是让模型参与质量评估,代表方向是 Constitutional AI 和 RLAIF(Reinforcement Learning from AI Feedback)。Constitutional AI 的做法是给模型一组行为准则,让它基于这些准则对自己的输出进行批评和修订,用修订后的回答构造偏好对,再训练一个奖励模型,最后做强化学习。
这条线在实操里非常依赖“评估提示词”的设计。你让模型打分,它很容易犯两个毛病:一是所有分数都往高处给,缺乏区分度;二是容易被长回答带跑,觉得字数多就是质量高。解决这些问题没有银弹,常用的手段包括:要求模型先输出评审理由再给出分数、强制使用 1~5 分或 1~10 分的离散标尺、对长度做回归修正、引入多个独立打分取平均。
自评估的另一个衍生方向是自我反思(Self-Refine/Reflexion)。模型回答一个问题后,先自己审视哪里错了,把反思结果写下来,再带着反思去重新回答。这不需要重新训练,只是在推理阶段加了一步迭代,但对数学题、代码调试这类任务提升明显。如果再把反思后的正样本收集起来做微调,就变成了 STaR(Self-Taught Reasoner)那套逻辑:模型自己尝试解答,只保留回答正确的推理过程,拿去微调,循环往复。
2.3 自我博弈与迭代偏好优化
第三条线更像是强化学习的思路:让模型和自己的不同版本竞争或合作,不断拉高上限。Self-Play Fine-Tuning 是让模型针对同一指令生成两个回答,然后自己判断哪个更好,把偏好对拿去做 DPO。Meta 的 Self-Rewarding Language Models 更进一步:模型同时具备生成和评估能力,每次迭代都用模型自己构造的偏好对训练,让模型的判断力也跟着提升。
迭代 DPO 是我在实际项目里用得最多的一种形态。流程大概是:用当前模型对一批指令生成两个回答 → 用奖励模型或规则打分 → 构建好/坏偏好对 → 做一轮 DPO → 得到新模型 → 重复。每一次迭代,模型生成数据的分布都在移动,所以每一轮都要重新生成数据,不能拿旧数据反复用。
这条线最大的坑是“自我欺骗”:模型打分偏好很容易被某个表面特征抓住(比如带很多 bullet point 就高分),于是训练完的模型学会了堆格式、堆术语,真实能力并没有提升。所以我通常会把自评分和规则评分混合使用,至少留一部分硬性检查(关键词是否出现、格式是否合法、长度是否达标、是否能被验证器确认),不要让模型一个人说了算。
3. 实操记录:搭建一条最小可用的自进化流水线
3.1 环境与模型选型
先说结论:如果你只是想跑通流程验证想法,不需要一张 A100。7B 级别的开源模型配合 LoRA,一张 24GB 显存的消费级卡就能做微调;数据生成阶段用 vLLM 加速推理,8GB 显存也能勉强跑小模型。我自己这次演示用的是一张 4090(24GB),微调用的 Qwen2.5-7B-Instruct,推理用 vLLM,训练用 LLaMA-Factory 的 DPO 组件。
选模型时有几个经验:第一,基座模型本身能力不能太弱,自进化的天花板由“生成质量+判断质量”共同决定,模型如果连基本的格式化输出都做不好,后面全是垃圾进垃圾出;第二,优先选指令微调过的模型,因为自评估、自我反思这些操作对遵循指令的能力要求很高;第三,如果预算允许,教师模型和学生模型分开,用一个更强的模型做评分器,能明显缓解自评偏差。
依赖环境其实就三块:推理服务(vLLM)、微调框架(LLaMA-Factory 或 TRL)、评测工具(lm-evaluation-harness 或自己写脚本)。我当时是直接用 conda 建了一个 Python 3.10 的环境,装好 torch 2.3 + CUDA 12.1,然后 pip 装 vllm 和 LLaMA-Factory,整体没遇到什么环境地狱,比早期折腾 TF 舒服太多。
3.2 第一轮:种子集生成
我做的任务是一个垂直领域的技术问答场景,目标是让模型在“数据库性能优化”这类问题上回答得更专业。种子集我用了两批:一批是从已有日志和知识库抽出的 500 条真实用户问题,一批是人工写的 50 条高质量问题模板。然后写提示词让 Qwen2.5-7B 基于种子问题扩写,要求“保持领域不变、难度覆盖从入门到资深、输出格式为问答对”。
这里有个关键参数:生成温度。我第一次跑的时候温度设成 0.3,结果 2000 条数据里有一大半是近义改写,多样性很差。后来调到 0.9,多样性上来了,但噪声也明显变多。最终我采用的是分桶策略:基础问题用低温度(0.4)生成保证可用性,复杂推理类问题用高温度(0.9)生成保证多样性,两边数据量按 7:3 混合。
生成完成后必须做一轮机器清洗,我用的规则有:长度过滤(回答少于 50 字或超过 2000 字的去掉)、去重(对问题做 SimHash 去重)、格式校验(必须包含“问题:”“回答:”两个字段)、安全词过滤。这一轮从 3000 条原始生成里筛出了约 1800 条,进入下一步。
3.3 迭代优化:反馈、筛选、微调闭环
数据准备好之后,就是标准的迭代循环。我拆成四个步骤来跑:
第一步,用当前模型为每条指令生成两个独立回答(温度 0.7,seed 不同)。注意一定要用两个不同随机种子多次采样,否则两次回答高度相似,后面构造偏好对时区分度太低。
第二步,评分。我混合了三种信号:规则分数(是否包含关键实体、是否存在重复表述、长度是否合理)+ Qwen2.5-72B 教师模型的 1~5 分打分 + 人工抽检的 100 条做校准基准。三种信号加权合成最终分数,权重的确定方式比较粗糙——我先跑了一轮,看哪个权重的排序结果和人工抽检一致性高,再固定下来。
第三步,构造训练数据。SFT 数据取分数前 30% 的回答;DPO 数据取同一指令下高分回答和低分回答配成对,要求两段回答长度差不能超过 1.5 倍,避免模型只学“长=对”这种捷径。
第四步,训练。SFT 用 LoRA(rank=32,alpha=64,学习率 2e-4),DPO 用同样的 LoRA 配置,beta 默认 0.1。每轮迭代训练 3 个 epoch,同时用保留的 500 条评测题做自动评估,如果 BLEU/相似度分数掉了就回滚上一轮权重。
这样一个循环跑下来大约花 6~8 个小时(数据生成 2 小时 + 评分 1 小时 + 训练 2 小时 + 评估 1 小时)。我跑了三轮,第二轮的收益最明显,第三轮提升就很小了,再往下开始出现退化迹象。这个“三轮之后收益递减”的现象不是偶然,模型在自身输出分布上反复拟合,边际收益必然下降,这时候应该停止而不是硬着头皮继续刷。
4. 常见问题与避坑实录
4.1 数据塌缩:模型越训越窄
数据塌缩(模型坍缩)是自进化最隐蔽的杀手。现象是:模型在评测集上分数挺好看,但实际对话时明显变“油滑”了,什么话题都能接,但回答都很空,知识面反而变窄了。
原因是反复用模型自己的输出训练,会把数据分布推向模型已经擅长的区域,长尾知识逐渐消失。这就好比一个学生反复做自己会做的题,成绩单好看,但遇到没见过的题型立刻露馅。
我的对策有三个:每轮迭代必须混入至少 30% 的原始人工数据或外部高质量数据,防止分布偏移;生成时故意引入高温度样本,保持分布宽度;设定一个多样性监控指标(比如回答的 embedding 聚类的平均距离),如果连续两轮多样性显著下降,立即停止迭代。
4.2 自评偏差与提示词敏感
模型给自己打分这件事,远没有论文里那么可靠。我试过让同一个模型用不同提示词打分,相关系数只有 0.6 左右;如果提示词里加了“请严格打分”,分数分布会整体下移,但排序几乎没有变化——也就是说模型学会了调整分数的尺度,但没有学会真正区分好坏。
几类典型的自评偏差:
- 宽松偏差:给分普遍偏高,集中在 4~5 分,失去区分度。
- 长度偏差:回答越长分数越高,跟内容质量无关。
- 位置偏差:两个回答做对比时,排在前面的更容易被选中。
- 术语偏好:看起来专业术语多的回答得分高,实际可能是胡编。
缓解手段:对长度做显式分箱校正;对比评估时交换两个回答的顺序、跑两次再汇总;在提示词里让模型先引用回答中的具体证据,再给分;引入第二模型交叉验证。记住,自评永远只是弱信号,真正的质检底线是靠规则和人工抽检兜住的。
4.3 过拟合与灾难性遗忘
微调阶段最常见的问题是灾难性遗忘——模型在新语料上增强了,但把原有的通用能力丢了。症状包括:模型不再会说“我不知道”,遇到不懂的问题硬编;格式遵循能力反而变差;对某些常识问题答非所问。
我做过的有效缓解措施是:LoRA 参数牢牢控制在低 rank(不超过 64);训练数据里保留 20% 的通用对话数据;每轮迭代训练完,都会跑一遍通用基准(比如 C-Eval 的子集或 MMLU 子集),如果通用能力明显下降,就减少训练步数或降低学习率。还有一个容易被忽略的细节:DPO 的 beta 参数不要调得太高,beta 过大模型会太激进地往偏好方向挤,遗忘会更严重。
另外一个评估层面的坑:别只盯着单一指标。我第一轮迭代的时候,数学类评测分数涨了 12%,当时很开心,后来发现是因为评测集被污染了——评测题目本身可能出现在模型的预训练数据里。后来我换成动态抽题的方式,每轮从题库里按不同 seed 抽题,才让指标可信起来。
5. 工具链与生态速览
5.1 主流框架与组件
自进化并不是某一家公司的专属技术,现在开源生态里能拼出一整套工具链。我做了一个简单的分工梳理:
| 环节 | 推荐工具 | 说明 |
|---|---|---|
| 推理与数据生成 | vLLM、SGLang | 支持高吞吐批量推理,适合批量生成训练数据;SGLang 在多轮生成上更灵活 |
| 数据合成与筛选 | Distilabel、Argilla、Data-Juicer | Distilabel 专门做 LLM 数据的生成-评分-过滤流程,自带很多预置任务 |
| 微调 | LLaMA-Factory、TRL、Axolotl | LLaMA-Factory 上手快,支持 SFT/DPO/PPO;TRL 更贴近底层,灵活度更高 |
| 评估 | lm-evaluation-harness、AlpacaEval、MT-Bench | 标准评测集一把梭;AlpacaEval 适合衡量指令跟随能力 |
| 实验追踪 | W&B、MLflow | 记录每次迭代的数据分布、训练参数和评测结果,回溯排查时非常关键 |
Distilabel 是我最近用得比较顺手的组件,它把“生成→评分→过滤→打包”这些步骤声明式地串起来,支持自定义评分器。如果你不想折腾 YAML,直接用 Python 脚本也能实现同样的逻辑,流程感反而更清晰。
5.2 按场景选型建议
不同场景下自进化的侧重点完全不一样,我总结了几类常见情况:
第一类,垂直领域问答助手。这是最容易见效的场景,因为有领域知识做天然筛选器。建议用“教师模型评分 + 规则校验”双通道,教师模型选闭源强模型或大参数开源模型,学生模型用 7B~14B 级别。迭代两到三轮足够了。
第二类,代码生成助手。这个场景最大的优势是有编译器/测试用例做硬信号,自进化可以非常激进。正确的回答会被测试用例验证,天然形成高质量偏好对。我身边做代码助手的团队,基本都在用类似 STaR 的路线,让模型自己写代码、跑测试、保留通过的样本,效果比人工标注好很多。
第三类,Agent 工具调用场景。这里的自进化更多是行为层面的:让 Agent 自己尝试完成任务,成功与失败的轨迹构成偏好数据。难点是轨迹评估很复杂,成功不代表动作最优,我建议结合过程奖励(每个工具调用是否合理)和结果奖励(任务是否完成)一起打分。
第四类,通用对话模型。坦白讲,纯靠自进化做通用模型效果提升很有限,因为通用领域的“好回答”标准太主观,自评信号太弱。这一块更适合用 Self-Instruct 做数据扩张,而不是做迭代式自进化。
6. 一点实际操作体会
最后说点不太好写进论文里的东西。自进化这个方向上,最大的难点从来不是技术实现,而是对“数据质量”的判断力。我刚跑通第一版流水线的时候,觉得自己发现了新大陆——迭代了两轮,模型在自测集上哗哗涨分。后来把同样的问题拿给几个朋友做盲测,他们给出的评价却是“回答变官方了,不好用了”。那一刻我才意识到,评测集的分数和真实用户体验之间,还隔着很长一段距离。
所以如果你也想在这个方向尝试,我建议从一个小切口开始:选一个信号非常明确的任务类型(比如代码题、数学题、有标准答案的知识问答),先把流水线跑通,再去碰主观评价类的任务。前期把精力花在评分器上,它的质量直接决定自进化的上限。另外,每一轮迭代的数据、模型权重、评测结果都要完整存档,因为自进化的失误往往是累积性的,没有记录,出了问题你根本不知道是哪一轮引入的。
这套方法还有很多可以继续探索的空间,比如把外部工具引入反馈回路、让多模型互相评测、结合检索增强补充新鲜知识。技术路线会变,但“用模型自己的输出去训练模型”这个基本思路,未来几年应该会越来越普及。希望对正在尝试的朋友有帮助。