LLM 面试备考
首页/后训练

数据工程与合成数据 Data Engineering & Synthetic Data

所属:01-fundamentals / 02-post-training
面试权重:★★★
来源:通用领域知识;未做一手考证
相关项目:Own — HKGAI LLM(数据工程 + 数据配比)、Race Bot / HKJC(多策略合成数据流水线)→ 见 02-interview/projects/race-bot-hkjc.md

一句话#

Post-training 的瓶颈几乎从不在算法,而在数据:数据工程就是把「原始语料 / 种子指令 / 线上日志」变成「可训练、可信、与评测集不污染的样本」的那条流水线 —— 过滤、去重、增强、合成、验证、切分。合成数据是它的放大器,也是最容易把评测一起做假的雷区。

为什么重要(面试角度)#

面试官问不出「你有没有做过数据」,但一定能问出你的数据是怎么来的。这一题暴露的是工程成熟度:

  • 你有没有一条可复现的流水线,还是手工挑了几百条例子。
  • 你知不知道过滤是有成本的,以及怎么用低成本手段挡住绝大多数脏数据。
  • 你懂不懂合成数据的自证问题 —— 用模型造的数据去训模型,怎么保证它不是把模型的错误固化下来。
  • 你是否有污染意识 —— 随机切分 train/test 在合成数据场景下几乎必然泄漏。

你在 HKJC 项目里搭过完整的多策略合成数据流水线,在 HKGAI 做过数据配比 —— 这两段正好覆盖「合成」和「配比」两个维度,必须能讲出流水线的每一级,而不是只说「我们用了 GPT 造数据」。

核心内容#

数据的来源与分层#

来源 优点 代价 / 风险
人工标注 质量上限最高,口径可控 贵、慢、难以规模化;标注者之间一致性需要专门校准
线上真实日志 分布最真实,天然覆盖长尾 隐私与合规(必须脱敏);噪声大;长尾里大量是无效提问
公开指令数据集 便宜、覆盖广 与预训练语料可能重叠,带来污染;风格与你的场景不匹配
模型合成 便宜、可控、能定向补短板 会继承生成模型的偏置与错误;同质化;污染评测集

实践中不是四选一,而是分层配比:真实数据定分布(骨架),合成数据补覆盖(长尾与困难样本),人工数据做最后的高精度校准(种子与验收)。

过滤流水线(Filtering Pipeline)#

一条典型流水线的顺序是从便宜到昂贵,每一级都要明确「它挡掉什么、误杀什么」:

  1. 格式与完整性:字段缺失、token 数异常、chat template 未正确闭合、编码乱码。
  2. 规则过滤:语言检测(目标语言占比)、长度区间、重复 n-gram 比例、停止词堆叠、占位符残留(<|endoftext|>、TODO、模板变量没被替换)。
  3. 精确去重与近重复:详见下文「去重」。
  4. 质量打分:模型打分或启发式打分,见下两节。
  5. 答案可验证性:对可验证任务(代码、SQL、数学),实际执行一遍。这一步不能省 —— 一条语法对但语义错的 ground truth 会教模型系统性犯错。

易被忽视的一点:过滤的目标不是「留下最好的」,而是「把分布修正确」。只留高质量样本会让数据分布偏离真实分布,模型在脏输入上崩掉。保留一部分合理噪声通常比全留精品更有泛化价值 —— 这个权衡要能说清。

级联分类器(Cascaded Classifiers)#

核心思想:绝大多数样本是「显然好」或「显然坏」的,只有少数处在模糊区间才需要昂贵判断。所以不要一上来就调最强模型逐条判断。

原始样本 → [规则 / 小模型:挡掉明显坏数据,高召回、别误杀] → [小 LLM 打分器:批量便宜,处理「显然好」] → [强模型 / 人工:只处理需要世界知识的模糊区间]

设计要点:

  • 便宜级要高召回:它只负责「绝对不要」的样本,宁可放过,不可错杀。误杀的样本是永久损失,而误放的一张脏数据只是噪声。
  • 昂贵级只处理模糊带:需要事实核查、需要判断业务正确性、需要跨句推理的样本 —— 这类判断小模型给不出可信结果。
  • 两级判定要能对账:定期抽样比对「小模型说好、大模型说坏」的样本,这就是你升级小模型的训练数据来源。
  • 这和 RAG 里的「先粗筛再精排」是同一个工程模式:用逐级递增的单位成本换逐级递减的样本量。

质量分类器(Quality Classifier)#

把「逐条问大模型」替换成「训一个小打分器」,是让流水线能跑在百万量级的关键:

  • 训练信号从哪来:人工标注一个几千条的小验证集,用强模型蒸馏一批弱标签,两者结合。分类器的偏置会一比一变成数据的偏置 —— 它认为什么好,你的模型就学什么。
  • 形态:二分类(保留 / 丢弃)或连续打分(用于排序与阈值裁剪)。回归打分更适合做「分层采样」而不是硬切。
  • 阈值是业务决策:阈值定在哪取决于你要多少数据。永远保留一个人工抽检的黄金集来校准这个阈值,否则阈值会随模型漂移而静默失效。
  • 别用同一个模型既是生成方又是裁判:生成方和裁判同源时,它会给自己的风格打高分,这是一种自我强化的窄化。

Evol-Instruct 式数据增强#

思路:从一个(相对简单的)种子指令出发,用一系列定向变换把它变难、变深、变具体,从而在数据量不增的前提下抬高复杂度分布。

常见变换维度(每一步都有淘汰机制,这是关键):

维度 做法 失败的形态
加约束 增加输出格式、长度、语气、受众约束 约束冗余,与原指令等价 → 应淘汰
深化 增加推理步骤、要求解释理由 变成不可答或答案不唯一 → 淘汰
具体化 把泛泛的问题替换成带真实实体/数值的具体问题 编造出不存在的事实 → 淘汰
复杂化 合并多个子问题、增加条件分支 超出可验证范围 → 淘汰

淘汰机制通常检查三件事:① 与原指令是否实质等价;② 是否可答(能否构造出正确回复);③ 是否破坏了指令的合法性(如引入了不存在的约束)。 没有淘汰的增强只会造出大量同质样本,把数据量堆上去、把质量摊薄。

诚实提醒:各种增强策略的效果高度依赖领域与基座,公开结论不能直接搬到垂域。面试时把它讲成「一类思路 + 我们的淘汰准则」,比引用具体收益数字更稳。

合成数据生成的多策略框架#

单一合成策略必然导致同质化 —— 这是 HKJC 项目最直接的教训。可靠的合成数据是多策略并行、各有分工:

  • 主题引导生成(topic-guided):按业务主题/意图分类逐个覆盖,保证广度。适合防止某类问题在数据里完全缺席。
  • 字段聚合 / 结构驱动(field-based aggregation):按 schema 的字段组合生成查询,专门造统计、聚合、分组类样本。这类样本在真实数据里天然稀缺,但它们恰恰是最难的能力。
  • 困难样本构造(hard-case construction):从已知失败模式与线上 bad case 定向补数据。这是唯一能持续提高上限的策略 —— 前两个只保证覆盖,只有它能针对性修 bug。
  • 回灌闭环:线上失败 case 定期归档 → 人工确认 ground truth → 补进训练集。这个闭环的存在本身就是加分项,说明你理解「上线不是终点」。

合成数据的验收标准必须包含 ground truth 的可执行验证(见过滤流水线第 5 步)。以 Text2SQL 为例:(自然语言问题, ground-truth SQL) 成对,且 SQL 必须实跑通过、返回非空、结果与预期一致。否则你在教模型写一种语法正确但语义错误的 SQL —— 这种错误比不会写更糟,因为评测集上它看起来是对的。

偏好数据的构造(三元组形式)#

偏好数据的基本形态是三元组 (prompt, chosen, rejected),它是 DPO 与 reward model 的唯一输入。构造要点:

chosen 的来源

  • 人工撰写(质量最高、最贵)
  • 强模型生成 + 人工/规则筛选(主流)
  • 拒绝采样(Rejection Sampling):用当前模型采样多条,选通过验证的那条作为 chosen —— 采样自当前策略,因此分布与待优化模型天然贴近,这是它比「用强模型造」更有优势的地方。

    ⚠️ 术语要收紧:这不等于是「on-policy 训练」。 on-policy 的严格定义要求生成 rollout 的行为策略 μ\mu 与当前正在优化的策略 π\pi 相同或足够接近。拒绝采样只是采样时用的是当前策略;一旦你把这些筛出来的成功轨迹冻结成一个固定数据集去做 SFT(也就是 RFT),它就已经是离线(offline)训练了 —— 策略更新时数据不再随策略刷新。 差别不是抠字眼:离线训练会累积分布偏移(covariate shift),误差最坏可随轨迹长度 TT 近似按 T2T^2 累积,而在策略实际访问的状态上训练(在线数据聚合)能把它降到约 TT。所以「用拒绝采样 + SFT」和「用在线 RL」是两种东西,前者便宜但会漂,后者贵但不漂。面试里说「采样自当前策略」而不要说「天然 on-policy」 —— 后者正好踩在这个词被严格定义的坑上。

rejected 的来源与关键原则

来源 特点
模型自采样中的低分样本 分布真实,最能暴露模型自身的错法
人工扰动(改错实体、截断、加错误的推理步骤) 可控、成本低,但容易造出「明显垃圾」
不同模型的输出对撞 天然有区分度,适合做「风格偏好」类数据

⚠️ 核心原则:rejected 必须有信息量,不能用随机负例。 如果正负样本在很多维度上同时有差异(既更长、又更流畅、又更准确),模型学到的偏好方向是模糊的;你要的负例是只在目标维度上更差、其他维度接近的样本 —— 在 writing-copilot 项目里就是「合规但拒答」vs「合规且作答」这种仅差一个维度的对比。随机负例(比如一个语法都不通的回答)会让训练看起来收敛,但解决不了你真正想解决的问题。

两个必须警惕的结构性偏置:长度偏置 —— 标注者与模型裁判都偏好更长的回答,如果 chosen 系统性比 rejected 长,偏好数据里就同时编码了「长度」这个虚假特征,DPO 会把它放大;格式偏置 —— 带 markdown 标题/表格的回答更容易被选中,于是模型学会的是格式而非内容。构造时常用长度受控配对(chosen 与 rejected 长度接近)剥掉长度这个混淆变量。

去重#

去重有两个层次,缺一不可:

  • 精确去重:规范化(大小写、空白、全半角)后做哈希。挡掉整段复制粘贴的数据。
  • 近重复去重:MinHash + LSH 做 n-gram 级别的近似去重,或直接用 embedding 相似度做语义去重。同一道题的措辞变体是最常见、也最有害的近重复。

为什么必须做:① 重复样本会放大过拟合 —— 一条样本出现 50 次,等价于把它上了 50 遍,模型会把这个模式当成规律;② 它是 train/test 泄漏的最主要来源 —— 合成数据的自然变体与评测集撞车,指标虚高但不泛化;③ 不均衡的重复会静默改变训练的类别分布。

基准污染(Benchmark Contamination)#

症状:离线指标异常高且与线上表现严重不符;模型在评测集上的表现显著好于同分布的留出集;模型对某个 benchmark 的题目能「背出」解析。

检测手段:

  • n-gram 重叠:把评测样本切成 n-gram,检查有多少比例出现在训练语料中(n 越大越保守,如 13-gram 是常见的保守选择)。
  • embedding 检索:对训练集建索引,用评测样本去检索,看是否命中高相似近邻。
  • 补全/困惑度检测:给模型看评测题目的开头,看它是否能异常流畅地补全 —— 能补全意味着见过。
  • 模型自我报告:直接问模型「你见过这道题吗」,只作辅助信号,不可单独作为证据。

流程上的避免方式(比检测更重要):

  • 按主题/实体切分,而不是随机切分。随机切分在合成数据场景下几乎必然泄漏 —— 因为同一模板生成的变体会被分到训练和测试两侧。
  • 评测集冻结,且与训练数据的生成流水线物理隔离(不同的生成脚本、不同的种子、最好不同时期)。
  • 换用外部/第三方评测集做交叉验证,即使它不完全贴合业务。

面试策略:如果你确实存在污染风险而没处理,直说,并说明「如果重做我会按主题/实体切分」。面试官吃这一套,硬撑不吃。

常见面试问法#

Q:你们的合成数据是怎么造的? A:分层回答 —— ① 生成方式(多策略:主题引导保广度、字段/结构驱动造聚合类、失败模式驱动造困难样本);② 验证方式(ground truth 必须实跑验证,不能只看格式);③ 去重与切分(问题级 + 答案级双重去重,按主题切分);④ 闭环(线上 bad case 回灌)。把「验证」和「切分」主动讲出来,是区分「造过数据」和「用过数据」的分界线。

Q:为什么不用最强的模型来过滤所有的数据? A:成本不可接受,且没有必要。绝大多数样本的判定不需要世界知识(长度、语言、重复、格式这些用规则就能挡);级联分类器的设计原则是让便宜的那级只负责「高置信度的坏样本」,把昂贵算力集中在模糊区间。同时便宜级必须高召回 —— 误杀好数据的损失不可逆。

Q:质量分类器的偏置会不会成为数据的偏置? A:会,而且这是这条路线最大的系统性风险。缓解:分类器训练信号要混合人工标注与强模型蒸馏,人工抽检的黄金集要长期保留用于校准阈值,以及定期检查分类器是不是在奖励某种单一风格(长度、markdown 格式)。

Q:模型造的数据训模型,会不会把错误固化? A:会,这叫自我强化的窄化 / 错误固化。三道防线:① 输出必须有可验证信号(执行、单测、事实核查),不能只靠「看起来对」;② 生成方与裁判方尽量不同源;③ 保留真实数据作为分布锚点,不要让合成数据占据主导。

Q:怎么保证评测可信? A:去重(问题级 + 答案级)、按主题/实体而非随机切分、评测集冻结且生成流水线隔离、用外部评测集交叉验证、以及做污染检测(n-gram 重叠 / embedding 检索)。

易错点#

  • ❌ 说「数据用 GPT 造了一些」就结束 —— 没有验证、没有去重、没有切分,等于没有数据工程。
  • ❌ 只讲过滤,不讲误杀:过滤是有成本的,高精度阈值会静默砍掉长尾。
  • ❌ 认为合成数据越多越好 —— 单一策略堆量只会造出同质数据,把有限的能力预算摊薄。
  • ❌ 偏好数据里用随机负例,或让 chosen 系统性比 rejected 长。
  • ❌ 合成数据随机切分 train/test —— 在合成场景下这就是污染;也不要把「SQL 执行成功」当成数据正确的证据。
  • ❌ 只报告过滤后的数据量,从不报告过滤前的分布 —— 说不清流水线到底改变了什么。

自测#

1. 用一句话解释级联分类器为什么能省成本,并说明「便宜的那一级」在设计上最重要的约束是什么。

答案

省成本的原理:绝大多数样本的判定并不需要昂贵的能力(世界知识、跨句推理),用规则/小模型就能以极低单位成本挡掉大部分坏数据,把强模型只留给处在模糊区间的少数样本 —— 即「逐级递增的单位成本 × 逐级递减的样本量」。

最重要的约束是 高召回(宁可放过、不可错杀):被误杀的好样本是永久损失,而误放的一条脏数据只是噪声;且每增加一级,后续所有级都只能看到上一级筛过的数据。因此便宜级的阈值必须偏宽松,并且要定期用人工抽检校准。

2. 你造了一批合成偏好数据,训练很顺利,但线上模型变得啰嗦、爱加小标题。最可能的两个原因是什么?

答案

① 长度偏置 / 格式偏置被编码进了偏好数据:chosen 系统性比 rejected 更长、或更常带 markdown 结构,于是 DPO 学到的是「长 + 带格式 = 好」这个虚假特征而非内容质量。② 合成数据的多样化不足:多策略生成里如果某一类模板(如「结构化长回答」)占比过高,模型会把它当成普适的作答风格。

对策:长度受控配对(chosen/rejected 长度接近)、对结构类特征做显式消融、检查偏好数据在不同维度上的分布是否平衡,而不是只检查样本总量。

3. 合成数据流水线里,哪一步是最容易被跳过、但后果最严重的?

答案

切分与去重(含污染检测)。因为它不会让训练报错、也不会让 loss 曲线难看 —— 它的后果是在评测指标上显现为「虚高」,而虚高的指标恰恰是你用来做所有决策的依据(表现为离线指标异常好、与线上表现严重背离)。

正确的做法是按主题/实体而非随机切分(合成数据的模板变体天然会在随机切分下跨越 train/test),评测集冻结且与训练生成流水线隔离,并做 n-gram 重叠 / embedding 检索的污染检测。

4. 为什么「SQL 能执行」不能作为数据正确性的验收标准?正确的验收标准是什么?

答案

因为大量语义错误的 SQL 完全可以执行成功:恒真条件、错误的 JOIN 方向、聚合口径错(AVG 该在外层还是内层)、WHERE 与 HAVING 混用 —— 它们都能跑通并返回结果,甚至返回非空结果。用「能执行」做验收,等于把「语法正确但语义错误」的样本批量喂进训练集,模型学到的是错误的业务逻辑。

正确的验收标准是结果级等价:把合成 SQL 与参考 SQL 在同一数据快照上执行,比对结果集(排序无关的比较、浮点容差、空结果单独判定),并额外检查是否返回空集。

5. 如果你必须在一周内为一个小众垂域造 5 万条 SFT 数据,你会怎么分配预算?

答案

按「真实性 / 覆盖率 / 精度」三个目标分配,而不是平均用力:

① 真实数据(骨架,占比最高):从线上日志或已有文档中抽取真实问题(脱敏后),即使没有答案也要保留问题分布 —— 它定义了数据应该长什么样。② 多策略合成(覆盖):主题引导保广度、结构驱动造稀有但难的类型、失败模式驱动造困难样本,全部走 ground truth 实跑验证。③ 人工(精度):钱只花在两处 —— 造高质量种子(决定合成数据的上限)和人工审核抽样(决定你能否信任流水线)。

同时预留时间去重与按主题切分 —— 这一周里最不该省的就是最后这一步,因为前面所有投入的可信度都建立在它之上。