资讯动态

用NeMo Data Designer做数据增强:从300条问答扩展到5万条合成数据实战

发布时间:2026/10/23 7:14:00 来源:尧图企业网站定制
做自然语言处理项目的人大概都有同感真正卡住进度的往往不是模型结构而是数据。几个月前我接了个企业内部知识库问答系统的训练任务手里只有300多条人工整理的问答对模型怎么调都欠火候。后来我换了个思路用NeMo Data Designer把数据规模从几百条扩到了5万条训练出来的效果反而明显更好。这篇文章就围绕我这次的完整实操过程来写聊聊如何用这套工具从零构建高质量合成数据集希望能够帮到同样在数据问题上挣扎的朋友。1. 为什么需要合成数据从真实数据到数据增强的关键一步先说结论合成数据不是要替代真实数据而是把真实数据的能力放大。模型训练这事有个很朴素的规律数据量和分布决定了下限。但真实世界的数据从来都不是理想的标注成本高、隐私限制多、覆盖不均衡。拿我那个知识库项目来说300多条QA对连一个像样的验证集都分不出来更不要说训练了。人工标注的成本大家心里有数一条质量过得去的客服问答需要业务人员写初稿、审核人员改措辞人力和时间都投进去一天也出不了多少条。如果数据还涉及客户信息和内部业务数据想外包给第三方标注团队合规那一关就过不去。至于长尾问题真实数据里用户根本不问那些偶发情况等出了事故再去补数据黄花菜都凉了。1.1 合成数据的核心价值合成数据就是在这种情况下被推上台面的。我用个类比真实数据是实拍素材合成数据是摄影棚里搭景。实拍素材当然最真实但你没法控制天气、光线、演员的每一个动作搭景虽然要花功夫但一切要素都可控可以按需反复拍想拍多少拍多少。NeMo Data Designer干的就是搭景这件事给定一小批高质量种子数据由它基于模板和语言模型自动派生出一大批形态相近、但内容不同的新样本。合成数据三个最实在的价值第一条是规模化。几百条种子数据可以稳定扩展成几万条且扩展速度远远快于人工标注。第二条是可控性。数据的难度、长度、领域、说话风格都可以在设计模板时预先设定想要更多长文本样本就调长文本模板的占比想要更多反问句式就加反问式模板。第三条是隐私友好。因为生成过程不依赖真实用户对话原文很多时候可以做到数据脱敏的效果。当然合成数据也有自己的问题比如多样性不足、重复率高、错误信息被一本正经地生成出来。这也是为什么我不能只讲生成后面专门用一章讲质量控制和过滤这一步才是把大量数据变成高质量数据的关键。1.2 NeMo Data Designer 在这个环节里扮演什么角色NeMo Data Designer 是一套面向数据集设计与生成的工具核心思路是把数据生产拆成几个可编排的环节先定义数据长什么样Schema再定义内容从哪来模板与种子然后通过批量执行生成任务Generator最后对产物做校验和过滤Filter。这套设计最大的好处是流程可复用。我这次做知识库问答定义好的Schema和模板后面换到另一个业务线只需要替换种子文件和模板描述不用重写流程。另外它对并行生成的支持也比较省心多路并发跑起来之后基本就是等着看结果。需要说明的是工具本身不解决你想生成什么的问题——想生成客服对话、想生成摘要样本、想生成多选题这些都取决于你给它什么样的Schema和模板。工具的价值在于让生成-校验-筛选-导出这条流水线变得顺手、可靠把原来要在好几个脚本之间来回倒腾的活收敛到一个可控的项目里。2. 环境准备与项目初始化把NeMo Data Designer跑起来的完整流程工具再好跑不起来都是白搭。我这次是从零开始装的踩了一些环境上的坑把流程梳理出来供参考。2.1 安装与环境依赖先说一下我用的环境一台Linux机器内存32G有一块显存16G的GPU存储盘留了200G给数据文件。如果你没有GPU只做中小规模的数据生成CPU模式也能跑就是慢一些并发和batch要调小。安装依赖这一步建议用一个干净的Python环境来操作装一个虚拟环境把Python版本固定在一个较新的稳定版本上避免系统自带的旧版本Python带来一堆兼容性问题。工具依赖的库比较多包括数据处理、schema校验、文件IO相关的几个常见库都可以通过包管理器一次性拉下来。安装过程中我遇到一个比较典型的问题直接安装最新版之后和本机已有的一个老版本库产生了冲突表现为运行示例脚本时报类型错误。排查了一圈发现是依赖版本冲突不是代码问题。后来我在环境文件里把几个核心依赖的版本范围固定下来重新装一遍就正常了。2.2 创建项目与目录结构装好之后是创建项目。NeMo Data Designer的项目结构很清晰我建议按它默认的目录去建不要自己乱改因为后面批量生成时它会按约定去读文件和写结果。我的目录大致是这个样子data_project/ ├── configs/ # 项目配置文件 ├── schemas/ # 数据Schema定义 ├── templates/ # 生成模板与种子样本 ├── generated/ # 生成结果输出目录 ├── filtered/ # 过滤后结果输出目录 └── logs/ # 运行日志新手最容易忽略的是configs目录里的配置文件。生成并发数、batch大小、输出格式、随机种子等参数都在这里控制。随机种子这个东西容易被遗忘但如果你想复现同一批数据种子必须固定下来不然每次生成的结果都不一样。创建好项目之后第一步建议先用官方示例跑一遍全流程确认每一步都通。我自己的习惯是先配置一个小规模的任务比如只生成50条样本跑通后再放大到目标规模。别一上来就开5万条的任务万一中间配置有问题一次性任务跑几小时才发现错误时间成本太高。3. 核心实战从数据Schema到批量生成的高效流水线接下来是重头戏怎么把一批种子数据扩成大规模合成数据集。我以企业内部知识库问答为例完整走一遍流程。3.1 定义数据Schema先想好生成结果长什么样很多人在做合成数据时容易犯同一个毛病还没想清楚输出格式就急着写模板调模型。结果生成回来的数据结构五花八门清洗环节痛不欲生。Schema就是提前约定输出结构。我的问答数据Schema大概长这样schema: name: knowledge_base_qa fields: - name: question type: string required: true description: 用户问题应为一个完整的问句 - name: answer type: string required: true description: 基于知识库内容的回答需包含关键信息 - name: intent type: string required: false description: 问题意图分类属于枚举列表中的值 - name: topic type: string required: true description: 所属知识点主题定义字段时我建议把description写清楚。这句话看起来很不起眼但它是后续生成时的约束条件。模型或者规则引擎会参照这段描述来判断什么是合格输出描述写得模糊出来的数据质量就飘。还有一个容易被忽略的点字段的required标记一定要想清楚。我一开始把answer字段标成optional因为觉得某些场景可能没有标准答案。结果生成的样本里混进来一堆只有问题没有答案的残缺数据后面清洗时只能整批扔掉。设计上偷懒清洗时就加倍还回来。3.2 设计生成模板与种子数据Schema定好了下一步是准备模板和种子数据。模板的作用是告诉生成器问题应该怎么问、回答应该怎么答。比如我的模板里会写请根据以下知识库条目生成一个问答对。 知识库条目{knowledge_entry} 要求 1. 问题必须是用户在真实场景中可能会问出的自然问句 2. 回答必须基于知识库内容不得添加知识库中不存在的信息 3. 回答长度控制在50-200字之间 4. 如果知识库条目包含具体操作步骤请将操作步骤完整保留在回答中。这里有一个关键技巧模板里用占位符比如{knowledge_entry}来注入变化的内容。生成器每次运行时会从种子库里抽取不同的知识条目填入占位符这样每条生成结果都是不同的。种子的质量直接决定产出质量。我这次用的种子知识条目是从原始资料里精挑细选的大约200条覆盖了高频咨询、操作流程、政策说明、异常处理四个类别。每条都人工审过确保没有错误信息和过时内容。这一步别省种子烂了后面生成出来的东西只会更烂而且问题会被放大到几万条。3.3 配置生成策略并执行批量任务模板和种子就绪后开始配置生成策略。需要关注的几个参数batch size、并发数、输出路径。以我的项目为例我用的配置大致是generation: strategy: llm_based model: local_llm batch_size: 16 concurrency: 8 max_tokens: 512 temperature: 0.7 top_p: 0.95 seed: 42 output_format: jsonltemperature是最影响数据多样性的参数我个人习惯放在0.7附近太低会生成大量几乎一模一样的句子太高则容易跑偏输出一些逻辑不通的内容。如果某批生成结果看着太统一先检查一下temperature是不是设得太低。batch size和并发数要结合显存来定。16G显存跑16的batch还好如果改成64就会出现OOM。建议从小往大调稳定跑通之后再逐步增加。执行批量任务时强烈建议开启日志记录。生成过程中会有很多信息比如任务进度、失败样本数、每条样本的耗时。这些信息不只是用来监控更可以用来判断当前配置是否合理。跑起来之后不要干等。我习惯每隔一段时间去翻一下生成的中间结果随机看几十条。如果发现跑偏随时停下来调整参数重新跑总比5万条全生成完再返工省时间。4. 质量控制与数据多样性让合成数据真正可用生成只是一半另一半是筛。很多人在这一步没耐心结果模型训练出来效果差最后把锅甩给合成数据。实际上问题往往出在只生成、不质检。4.1 格式校验与字段一致性检查生成完成以后第一步就是格式校验。我这次用的输出格式是jsonl每一行都应该是一个结构完整的JSON对象。用脚本做一道基础校验把解析失败的行单独捞出来。格式校验的脚本逻辑很简单import json def validate_line(line): try: obj json.loads(line) except json.JSONDecodeError: return None for field in [question, answer, topic]: if not obj.get(field): return None return obj跑完这道校验能筛掉一批因为输出截断或JSON转义错误导致的坏数据。这类数据占比一般不高但如果不筛后面训模型时就是一颗颗雷。字段一致性检查则是看内容是否符合Schema里的约定。比如intent字段如果Schema里定义了枚举值就要检查生成结果里的值是否都落在枚举范围内。落到范围外的要么是模型自由发挥造出了新类别要么是模板里的描述不够严格。4.2 去重与相似度过滤合成数据最大的隐患是重复率。用模板LLM的方式生成即使固定了random seed同一批数据里依然会出现大量语义相同、措辞略有不同的样本。这些样本对模型训练来说信息量很低白白占用了训练预算。去重的思路分两层。第一层是精确去重直接去掉完全相同的字符串。第二层是近似去重用文本向量的余弦相似度来判断两条样本是否过于接近。我在项目里把阈值设为0.85高于这个值的样本直接视为重复。近似去重这一步要注意一个细节不要把同一topic下的样本误删。因为同一个知识条目生成的问答对语义上天然相近如果阈值设得太低会把本来应该保留的多样性样本也给滤掉。建议先用一批样本来测试阈值观察误删率再定最终的参数。4.3 人工抽检与迭代反馈自动化筛选做完最后还有一道人工抽检。我一直坚持这个环节不能省原因很简单规则和相似度阈值解决不了语义层面的错误。抽检的做法是按1%-2%的比例随机抽取生成结果逐条人工阅读记录错误类型和占比。我这次抽检了500条发现的问题主要集中在三类一类是知识幻觉个别回答添加了知识库中不存在的细节例如某个流程不该有的前置条件。一类是意图偏移生成的问题看起来自然但跟对应知识点的关系不够紧密。还有一类是模板痕迹太重读起来明显是机器生成的固定句式缺少真实场景里的口语感。这些反馈不能看完就算要拿回到生成环节去调。比如发现知识幻觉比较多就去强化模板里的约束描述明确不得添加知识库中不存在的信息发现模板痕迹重就调整temperature或者在模板里增加更多样化的句式和示例。我实际迭代了三轮第一轮跑出来2万条抽检发现幻觉率偏高调整模板后第二轮再跑2万条问题明显减少第三轮跑完剩下的1万条汇总抽检合格率已经能接受。整个调优过程看似繁琐但值得做。5. 常见问题与避坑实录我们实际踩过的那些坑最后分享几个我实际遇到的典型问题和处理过程有些是查了半天资料才弄明白的。5.1 生成结果里混入未替换的占位符这个坑非常隐蔽。一开始跑出来的数据里偶尔会出现一行包括{knowledge_entry}这类字样的文本。原因是模板解析时部分条目的占位符没有命中种子数据生成器直接原样输出了。排查方式是在格式校验之外再增加一道占位符检查扫描所有生成文本只要出现过{和}包围的占位符字符串就标记为异常。这个问题不大但影响很致命因为这种数据混入训练集后模型可能会学会在输出中保留占位符格式。5.2 输出文本被截断导致JSON解析失败LLM生成时设置了max_tokens回答较长时容易在JSON结束符之前被截断导致一整行解析失败。我遇到过一次比较严重的情况单批任务的失败率接近10%。解决思路有两个方向一是调大max_tokens二是把JSON输出改成逐字段输出最后再组装。我最后采用的是方案二让回答字段单独生成然后由后处理脚本统一封装成JSON行这样即使回答被截断也不会影响整行数据的结构。5.3 多样性不足生成的样本高度趋同有一批任务生成出来的结果风格极其统一句子结构几乎都长一个样。最初还以为是模板写得太死检查下来发现是temperature设得太低默认值0.1的情况下模型基本在走概率最高的路径。调整到0.7之后多样性有了明显改善。另外在模板中加入了多种句式提示词如以另一种方式表达同样的内容也起了一定的作用。多样性问题需要多管齐下单一参数往往解决不了。5.4 幻觉数据模型一本正经地编造事实这个是最难处理的一类。因为它的生成结果看起来完全合理词汇通顺、格式规范但内容本身是错的。对于知识库问答场景使用包含错误信息的样本训练模型风险比数据稀疏更大。我的应对手段是三层保障第一层在模板中明确约束只能使用知识库条目中的信息。第二层在生成后加一道基于知识库的自动比对抽取回答里的关键实体和数字与知识条目做匹配校验发现疑似新增信息就标记为存疑。第三层对存疑样本走人工复核能修则修不能修的直接删除。这套流程不一定能完全消除幻觉但可以把比例压到可接受范围。我把几个高频问题整理成了一个速查表大家可以对照参考问题现象可能原因处理建议占位符未替换种子数据未覆盖模板变量增加占位符后处理检查JSON解析失败max_tokens太小或输出被截断调大上限或改为逐字段生成样本高度趋同temperature过低调至0.6-0.8增加句式模板生成内容出错模板约束不足强化描述增加知识比对字段缺失Schema中required标记不准严格required并增加校验运行时报类型错误依赖版本冲突固定版本范围重装环境5.5 一个值得养成的习惯全流程版本化管理这个不能说是一个坑更多是吃过亏之后的习惯。数据生成项目和写代码类似模板文件、Schema、种子数据、配置参数每次改动都应该留下版本记录。否则调优三轮之后你会发现根本说不清哪些数据是哪一版配置生成的。我的做法是把每次运行的配置文件和模板目录做一个快照放在以时间戳命名的子目录下。这样既能复现也能随时对比不同版本的数据质量差异。数据链路越往后越复杂管理不过来的时候这个习惯能帮大忙。写到这里我这次用NeMo Data Designer构建合成数据集的完整过程就基本梳理完了。个人最大的体会是合成数据这项技术最考验人的不是工具操作而是对数据质量的敏感度。工具能帮你把生成、校验、过滤的流程自动化但在什么时候调模板、什么时候改阈值、怎么判断一批数据能不能用这些判断力只能从一次次抽检和复盘里积累出来。最后再分享一个小技巧不要一次性把全部资源压在最终版本上。先小批量、多轮次地跑通流程确认每一环的输出都符合预期之后再放开手脚做大规模生成。前期的试错成本很低但能帮你省下后期返工的大把时间。如果你正准备做合成数据集希望这篇实战记录能让你少走一点弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑