Agentic合成数据管线:SFT、mid-training与RL训练数据生产实战

📅 发布时间:2026/10/13 23:25:47
Agentic合成数据管线:SFT、mid-training与RL训练数据生产实战
1. 为什么“合成数据”正在成为训练流程里的独立工种过去两年我参与过好几个从零起步的模型训练项目最深的感受是数据准备早就不是“标标注、洗洗文本”这么简单了。尤其是当训练阶段从单纯的 SFT监督微调扩展到 mid-training中期训练和 RL强化学习之后数据的需求形态发生了根本变化——SFT 要的是“标准答案”mid-training 要的是“知识密度”RL 要的是“可验证的反馈信号”。这三者对数据的要求互相冲突靠一套静态数据集根本喂不饱。于是“agentic 方式合成 / 清洗训练数据”这个思路就浮出水面了。所谓 agentic不是指某个具体框架而是指把数据生产当成一个有目标、有工具、有反馈回路的智能体任务让模型自己规划怎么造数据、调用工具去验证、根据反馈迭代清洗而不是人工写死一套规则跑批处理。这套方法最早在 SFT 数据增广里被零星使用现在已经贯穿到 mid-training 的知识注入和 RL 的偏好对构造中。这篇文章适合谁看如果你正在负责训练数据的生产管线或者你是一个需要自己造数据做微调的开发者又或者你只是好奇“合成数据到底怎么保证质量”那接下来的内容应该能帮你少走至少三个月的弯路。我会从整体设计思路讲到具体实操包括参数选择、工具链搭配、以及我踩过的那些坑。2. 整体设计思路把数据管线拆成三个独立又串联的智能体2.1 为什么不能用一个“万能 agent”包打天下刚开始我也想过能不能写一个超级 prompt让模型一次性完成“生成清洗验证”。实测下来这种做法在数据量超过几千条之后就会崩溃。原因很简单生成和清洗的目标函数是矛盾的。生成阶段希望多样性最大化清洗阶段希望噪声最小化如果放在同一个上下文里模型会倾向于保守生成多样性直接掉一半。所以我的方案是拆成三个独立智能体各自有明确的职责边界和工具集合成智能体负责根据种子数据生成候选样本核心指标是覆盖度和多样性。清洗智能体负责对候选样本做质量过滤、去重、格式修正核心指标是准确率和一致性。验证智能体负责用外部工具或规则对清洗后的数据做最终校验核心指标是假阳性率和假阴性率。这三个智能体通过一个共享的数据池串联每个智能体只读写自己关心的字段。这样做的好处是每个环节都可以独立调参和替换不会牵一发动全身。2.2 不同训练阶段的数据需求差异这里必须把 SFT、mid-training、RL 三个阶段的差异讲清楚否则后面的参数选择你没法理解。SFT 阶段需要的是“输入-输出”配对重点是输出要符合人类偏好格式要统一。合成数据的难点在于模型自己生成的标准答案往往过于模板化缺乏真实场景中的多样性。我的做法是让合成智能体先从一个小的种子集里学习“风格”然后在这个风格约束下做变体生成。mid-training 阶段介于预训练和 SFT 之间核心目标是注入领域知识。这个阶段的数据不需要严格的输入输出配对更像是一种“知识密度更高的语料”。合成时重点在于事实准确性和知识覆盖的广度。我通常会在这个阶段引入检索工具让智能体先检索再合成避免模型胡编。RL 阶段需要的是偏好对或者可验证的奖励信号。合成数据的难点在于如何构造出“有区分度”的正负样本。如果正负样本差异太大模型学不到细粒度偏好差异太小又容易引入噪声。我的经验是让验证智能体用规则或小模型打分只保留分数差距在特定区间内的样本对。2.3 工具链选型与成本权衡工具链方面我试过三种方案方案优点缺点适用场景纯 API 调用部署简单模型能力强成本高延迟大小规模高价值数据本地小模型 规则成本低可控性强能力有限需要大量规则大规模粗筛混合方案兼顾成本和质量管线复杂生产级数据管线实测下来混合方案最稳。具体来说合成阶段用 API 调用大模型保证多样性清洗阶段用本地小模型做初筛验证阶段再用 API 做最终校验。这样成本能控制在纯 API 方案的 30% 左右而质量下降不到 5%。3. 核心细节解析合成、清洗、验证各自的关键参数3.1 合成智能体的温度与多样性控制合成阶段最重要的参数是温度temperature和 top-p。这两个参数直接决定了生成数据的多样性。我的经验值是这样的SFT 数据合成温度 0.8-1.0top-p 0.9-0.95。温度太低会导致输出雷同太高会引入语法错误。mid-training 语料合成温度 0.6-0.8top-p 0.85-0.9。这个阶段更看重事实准确性温度需要适当降低。RL 偏好对合成温度 1.0-1.2top-p 0.95-0.98。需要更大的多样性来构造有区分度的样本对。这里有个细节温度不是固定值而是应该随着生成轮次动态调整。我的做法是前 20% 的样本用高温度探索中间 60% 用中等温度稳定生成最后 20% 用低温度补充长尾。这样能在多样性和质量之间取得平衡。另外合成智能体的 prompt 里一定要包含“禁止重复”的指令并且要在上下文里动态插入已生成样本的摘要。否则模型会在几十轮之后开始自我重复这是实测中最常见的退化模式。3.2 清洗智能体的规则与模型结合策略清洗阶段我采用的是“规则先行、模型兜底”的策略。具体分四层格式层用正则表达式检查 JSON 结构、字段完整性、编码格式。这一层能过滤掉大约 15% 的明显坏样本。长度层根据训练阶段设定长度阈值。SFT 数据通常要求 50-2000 tokenmid-training 语料可以放宽到 100-8000 token。超出范围的直接丢弃。去重层用 MinHash 做近似去重阈值设在 0.85 左右。这个阈值是我试了多个值之后确定的太低会误删合法变体太高会漏掉重复样本。模型层用一个本地小模型对剩余样本做质量打分只保留分数在前 70% 的样本。小模型的选择很关键我试过几个开源模型最后选了一个 1.5B 参数量的在质量和速度之间平衡得最好。注意去重层一定要在模型层之前做否则小模型会对重复样本给出相似分数导致去重失效。3.3 验证智能体的假阳性与假阴性控制验证阶段的目标是尽可能降低假阳性把坏数据判为好和假阴性把好数据判为坏。这两个指标是矛盾的需要根据训练阶段做权衡。对于 SFT 数据我倾向于降低假阳性因为坏数据对 SFT 的伤害很大。具体做法是设置较高的验证阈值宁可错杀一千不放过一个。对于 mid-training 语料可以适当放宽因为语料量本身很大少量噪声可以被稀释。对于 RL 偏好对假阴性的代价更高因为构造一个高质量偏好对成本很高所以验证阈值要调低。验证智能体的工具集包括规则校验器、小模型打分器、以及可选的检索验证器。检索验证器主要用于事实性检查把合成样本中的关键断言提取出来去知识库检索确认。这个环节能过滤掉大约 8% 的事实错误但会增加 30% 的延迟所以只对高价值数据开启。4. 实操过程从种子集到最终数据集的完整管线4.1 种子集准备与风格锚定整个管线的起点是一个高质量的种子集。我的经验是种子集不需要很大但一定要“干净且有代表性”。对于 SFT 数据我通常准备 200-500 条人工标注的样本对于 mid-training 语料准备 50-100 篇领域文档对于 RL 偏好对准备 100-200 对人工标注的偏好数据。种子集的作用是“风格锚定”。具体操作是在合成智能体的 prompt 里先插入 3-5 条种子样本作为 few-shot 示例然后要求模型“在保持相同风格的前提下生成新样本”。这样能保证合成数据的风格和种子集一致避免风格漂移。这里有个坑种子样本的选择要避免过于相似。如果 5 条种子样本都是同一类型的合成数据也会局限在这个类型里。我的做法是用聚类算法对种子集做多样性采样确保选出的样本覆盖不同的子类型。4.2 合成阶段的批量生成与动态去重合成阶段我采用的是“批量生成动态去重”的策略。具体流程是把种子集分成 N 个批次每个批次包含 3-5 条种子样本。对每个批次让合成智能体生成 M 条候选样本M 通常设为 20-50。每生成一批就把新样本加入一个全局去重池用 MinHash 做实时去重。如果某个批次的去重率超过 50%就调整该批次的温度参数重新生成。这个流程的关键在于“动态去重”。如果等所有批次生成完再去重会浪费大量计算资源。实时去重能在生成过程中就过滤掉重复样本效率提升很明显。参数方面我通常设置 N50-100M30。这样一轮能生成 1500-3000 条候选样本去重后保留 1000-2000 条。对于 SFT 数据这个量级足够做一轮微调实验对于 mid-training 语料需要跑多轮。4.3 清洗阶段的流水线配置清洗阶段我搭了一个四层流水线每层的配置如下# 清洗流水线配置示例 pipeline_config { format_check: { required_fields: [input, output, metadata], encoding: utf-8, max_field_length: 10000 }, length_filter: { min_tokens: 50, max_tokens: 2000, tokenizer: cl100k_base }, dedup: { method: minhash, threshold: 0.85, num_perm: 128 }, quality_score: { model: local-1.5b, threshold: 0.7, batch_size: 32 } }这个配置是我经过多次调参后确定的。其中num_perm128是 MinHash 的排列数这个值越大去重越准确但速度越慢128 是一个比较平衡的值。threshold0.85是相似度阈值超过这个值就认为是重复样本。质量打分的阈值 0.7 也是试出来的。我试过 0.6、0.65、0.7、0.75、0.8 五个值最后发现 0.7 在保留率和质量之间平衡最好。低于 0.7 会保留太多低质量样本高于 0.7 会丢掉一些边缘但有用的样本。4.4 验证阶段的抽样与全量校验验证阶段我采用“抽样校验全量规则校验”的组合策略。抽样校验是用 API 调用大模型对随机抽取的 5% 样本做人工级别的质量评估全量规则校验是用规则引擎对所有样本做格式和事实性检查。抽样校验的目的是校准规则校验的阈值。具体做法是先跑一轮规则校验统计通过率然后对通过和未通过的样本各抽 100 条用大模型做二次评估根据二次评估的结果调整规则阈值。这个过程通常需要迭代 2-3 轮直到规则校验和大模型评估的一致率达到 90% 以上。全量规则校验包括JSON 结构校验、字段类型校验、事实性断言提取与检索验证。事实性验证只对包含明确断言的样本开启对于纯风格类样本可以跳过。5. 常见问题与排查技巧实录5.1 合成数据多样性不足的排查路径多样性不足是最常见的问题表现是合成数据看起来都“差不多”。排查路径如下检查温度参数如果温度低于 0.7先调到 0.8-1.0 试试。检查种子集多样性用聚类算法分析种子集的分布如果集中在少数几个簇需要补充种子样本。检查 prompt 中的禁止重复指令如果 prompt 里没有明确的多样性要求模型会倾向于生成相似样本。检查去重阈值如果去重阈值设得太低比如 0.7会误删合法变体导致看起来多样性不足。我的经验是90% 的多样性问题都能通过调整温度和补充种子样本解决。剩下 10% 需要修改 prompt 结构比如引入“角色扮演”或“场景变换”的指令。5.2 清洗阶段误删好数据的补救措施误删好数据通常是因为规则太严格。补救措施分三步统计误删率从被删除的样本里随机抽 200 条人工评估其中有多少是真正的好数据。定位误删原因如果是格式问题放宽正则表达式如果是长度问题调整阈值如果是去重问题提高相似度阈值。重新跑清洗管线用调整后的配置重新处理原始候选集对比新旧结果。这里有个技巧清洗管线的每一层都应该保留“被删除样本”的日志包括删除原因和原始内容。这样排查问题时不用重新跑管线直接分析日志就行。5.3 验证阶段假阳性过高的调优方法假阳性过高意味着坏数据被放行了。调优方法如下提高验证阈值这是最直接的方法但会同时提高假阴性。增加验证维度比如从单一的模型打分增加到“模型打分规则校验检索验证”三重验证。引入对抗验证用一个专门训练的小模型来识别合成数据的“机器味”这个模型可以用人工标注的合成数据做训练。我通常先用第一种方法快速调整如果效果不够再上第二种。第三种方法成本较高只在数据质量要求极高的场景下使用。5.4 常见问题速查表问题现象可能原因排查方法解决方案合成数据雷同温度过低/种子集单一检查温度和种子集分布调高温度补充种子样本清洗后数据量骤降规则过严/去重阈值过低分析删除日志放宽规则提高去重阈值验证通过率异常高验证阈值过低/验证维度单一抽样人工评估提高阈值增加验证维度合成数据事实错误多缺少检索验证抽查事实性断言引入检索验证器管线运行速度慢模型推理瓶颈/去重计算量大profiling 各层耗时用本地小模型替代 API优化去重算法6. 不同训练阶段的参数模板与经验值6.1 SFT 数据合成的推荐配置对于 SFT 数据我的推荐配置是合成温度0.9top-p0.92每批种子数5每批生成数30去重阈值0.85质量打分阈值0.7验证抽样率5%这套配置在我最近三个 SFT 项目里都跑通了合成数据的可用率大约在 65%-75% 之间。可用率的定义是经过完整管线后人工评估认为“可以直接用于训练”的样本比例。6.2 mid-training 语料合成的推荐配置mid-training 语料对事实准确性要求更高推荐配置是合成温度0.7top-p0.88每批种子数3每批生成数20去重阈值0.8质量打分阈值0.75验证抽样率10%检索验证开启这套配置的合成速度比 SFT 慢大约 40%但事实错误率能控制在 3% 以下。对于知识密集型领域这个代价是值得的。6.3 RL 偏好对合成的推荐配置RL 偏好对的核心是“有区分度”推荐配置是合成温度1.1top-p0.96每批种子数4每批生成数40去重阈值0.9质量打分阈值0.65验证抽样率15%偏好对筛选分数差距 0.1-0.3偏好对的分数差距控制在 0.1-0.3 之间是我试出来的经验值。差距小于 0.1 的样本对区分度太低模型学不到东西差距大于 0.3 的样本对太容易区分对模型提升有限。7. 工具链搭建与成本控制的实际经验7.1 本地小模型的选择与部署清洗阶段用的本地小模型我试过三个一个 1.5B 的、一个 3B 的、一个 7B 的。最后选了 1.5B 的原因是1.5B 在单张消费级显卡上就能跑吞吐量大约是 7B 的 4 倍。质量打分任务本身不需要太强的模型能力1.5B 足够。7B 模型虽然打分更准但速度太慢会成为管线瓶颈。部署方面我用的是 vLLM 做推理加速batch size 设为 32这样能在单卡上跑到每秒 200 条左右的吞吐量。对于大规模数据管线这个速度是够用的。7.2 API 调用的成本优化策略合成阶段和验证阶段需要调用 API成本是大头。我的优化策略是批量调用把多个生成任务合并成一个请求减少网络开销。缓存复用对相同的 prompt 做缓存避免重复调用。分级调用先用便宜的小模型做初筛只对通过初筛的样本调用大模型。错峰调用如果 API 有价格波动把大批量任务安排在低价时段。实测下来这些策略能把 API 成本降低 50%-60%。其中缓存复用的效果最明显因为合成阶段有很多相似的 prompt。7.3 管线监控与异常告警数据管线跑起来之后监控很重要。我通常会监控这几个指标每层通过率如果某一层通过率突然下降说明上游出了问题。合成多样性用去重率作为代理指标去重率突然升高说明多样性下降。API 调用成功率如果失败率超过 5%需要检查网络或配额。管线总耗时如果耗时突然增加说明某个环节出现了瓶颈。告警方面我设了三个阈值通过率下降超过 20%、去重率超过 60%、API 失败率超过 10%。触发任何一个就发通知人工介入排查。8. 一些踩坑之后的个人体会这套 agentic 数据管线我前前后后迭代了大概半年最大的体会是不要试图一次性设计一个完美的管线。我一开始想做一个“全自动、端到端”的系统结果发现每个环节都有大量需要人工干预的边界情况。后来改成“半自动人工抽检”的模式反而效率更高。另一个体会是种子集的质量比数量重要得多。我试过用 1000 条种子样本效果还不如 200 条精选的。种子集里的每一条样本都应该有明确的“代表性”能覆盖一个特定的子场景或风格。最后分享一个小技巧在合成智能体的 prompt 里加入“自我批评”环节。具体做法是让模型生成样本后先自己评估一遍“这条样本有没有问题”如果有问题就重新生成。这个简单的改动能把合成数据的可用率提升 10%-15%成本增加不到 20%。