1. 引言:模型的人格,是数据的投影
你看到的模型语气、口味、边界感,说到底都是它吃的数据的形状。一个回答简洁的模型,背后是短回答训练样本堆出来的;一个动不动就「我不能回答」的模型,对齐数据里拒绝样例塞得太多。模型没有性格,数据集有。
本系列讲训练三阶段的那篇《训练三阶段——从会接龙,到会听话,到会思考》把三道工序教什么讲清楚了。这篇换一个问题:每道工序,具体吃什么原料?原料长什么样?
你将会了解到:三类训练数据的真实 JSON 样例(可直接复制用)、数据怎么被送进模型的技术路径(packing 和 loss mask 到底在干什么),以及微调不是灌知识,是教格式。
2. 鸟瞰:三道工序,三种食材
先把全景铺开,后面每节给一种食材装细节。
三道工序吃三种食材,形状完全不同:
- 预训练吃生文本——互联网原样抓下来的网页、书、代码、论文,没有结构,只有文字。
- SFT吃规整问答——每条样本是「指令 + 理想回答」的配对,教模型怎么按格式作答。
- 对齐吃偏好对——同一个问题给两个回答,标注哪个更好,教模型区分好坏。
后面三节,每节给真实样例。
3. 预训练语料:互联网原生长什么样
原始文本:脏、杂、什么都有
预训练数据的源头是 Common Crawl——一个非营利组织持续爬取的互联网快照。原始抓下来的东西长这样(一段典型的 Common Crawl 提取文本):
Home > Blog > 10 Tips for Better Sleep 10 Tips for Better Sleep Posted by admin on March 15, 2024 Getting good sleep is essential for health. Here are our top tips: 1. Stick to a schedule... [广告代码] [导航链接] [评论区片段]这里面混着导航面包屑、发布日期、广告残片、正文。直接喂给模型,模型会学到一堆垃圾。所以需要清洗。
清洗管线:去重、过滤、打分
从原始网页到可用的预训练语料,要走一条完整的清洗管线。我把它压成四个关键步骤:
- 去重:互联网上同一篇文章被复制了几十次,MinHash / SimHash 近似去重把这些副本砍掉。
- 质量过滤:用规则(文本长度、标点比例、特殊字符密度)和分类器(训练一个小模型区分「高质量文本」和「垃圾文本」)把低质量内容过滤掉。
- 毒性过滤:用毒性检测模型标记并移除仇恨言论、色情内容等。
- 质量打分:给每段文本打一个教育价值分,让模型优先学「有信息密度」的内容。
HuggingFace 的 FineWeb 数据集就是走这条管线出来的。据 FineWeb 论文(Penedo et al., 2024)披露,它从 96 个 Common Crawl 快照中清洗出了15 万亿(15T)token的英文语料,后续扩展到 18.5T+ token(来源:HuggingFace FineWeb 数据集页面,截至 2026-08)。它的教育子集 FineWeb-Edu 约 1.3T token,是过质量打分后留下的「高教育价值」部分。
另一个标杆是 DCLM(DataComp-LM),据 Li et al. 2024 的论文(arXiv:2406.11794,NeurIPS 2024),它提供了 240T token 的 Common Crawl 原始池,作为数据集策略的标准化测试平台。
成品语料的形状
经过清洗后,预训练数据就是纯文本块。一条样本大致长这样:
{"text":"Quantum computing leverages quantum mechanical phenomena such as superposition and entanglement to perform computations. Unlike classical bits that exist in a state of 0 or 1, qubits can exist in multiple states simultaneously..."}没有标签,没有问答,没有结构。就是一段一段的文字。模型在这些文本上做 next-token prediction——给定前面所有字,预测下一个字。这就是本系列第一篇《LLM 是什么?——它不是查资料,是在接龙》里讲的那个接龙游戏,只不过语料规模是万亿级。
4. SFT 数据格式大观
SFT 是训练数据的第二道食材。它的核心结构是「指令 + 理想回答」的配对。2026 年主流的格式有三种:Alpaca、ShareGPT、ChatML(messages 数组)。三者不是互相替代的关系,是适用场景不同。
Alpaca 格式:三字段,单轮指令
Alpaca 格式源自斯坦福 2023 年的 Alpaca 项目,是最朴素的指令微调格式。每条样本三个字段:
{"instruction":"将以下英文翻译成法语。","input":"Hello, how are you?","output":"Bonjour, comment allez-vous ?"}instruction(必填):人的指令——告诉模型该干什么。input(可选):指令的补充上下文。训练时instruction和input会拼接在一起。如果没有额外输入,这个字段留空字符串""。output(必填):理想回答——模型应该学会生成的内容。
LlamaFactory 还支持两个扩展字段:system(系统提示词,可选)和history(历史对话轮次,可选,格式为[["上条指令", "上条回答"], ...]),给单轮格式加上多轮的扩展能力(来源:LlamaFactory 官方文档 Data Preparation)。
适用场景:单轮指令跟随——翻译、摘要、分类、信息提取这类「给一条指令出一个回答」的任务。
ShareGPT 格式:多轮对话,角色丰富
ShareGPT 格式因同名网站 ShareGPT(用户分享自己与 ChatGPT 对话记录的平台)得名。它的结构是一个conversations数组,每条消息有from(角色)和value(内容)两个字段:
{"conversations":[{"from":"system","value":"你是一个专业的翻译助手。"},{"from":"human","value":"把这段话翻译成日语:今天天气真好。"},{"from":"gpt","value":"今日はとても良い天気ですね。"},{"from":"human","value":"再用敬语说一遍?"},{"from":"gpt","value":"本日は誠に良いお天気でございます。"}]}角色标签据 LlamaFactory 文档支持以下取值:
human:用户消息。gpt:模型回答——训练时只对这部分算损失(原因后面 loss mask 那节讲)。system:系统提示词。observation:工具返回的结果(function calling 场景)。function_call:模型发起的工具调用。
适用场景:多轮对话 + 工具调用——聊天机器人、Agent 训练、需要来回追问的复杂交互。
ChatML / messages 数组:行业通用标准
ChatML(Chat Markup Language)最初由 OpenAI 在 API 中推广,后来成为事实上的行业标准。它的结构是一个messages数组,每条消息有role和content两个字段:
{"messages":[{"role":"system","content":"你是一个友好的 AI 助手。"},{"role":"user","content":"什么是机器学习?"},{"role":"assistant","content":"机器学习是人工智能的一个分支,它让计算机能够从数据中学习规律,而不需要为每个任务显式编写规则。"},{"role":"user","content":"能举个具体例子吗?"},{"role":"assistant","content":"比如垃圾邮件过滤:模型从大量已标记的「垃圾邮件」和「正常邮件」样本中学习特征,然后自动判断新邮件是否为垃圾邮件。"}]}role:角色标识——system(系统)、user(用户)、assistant(模型回答)。部分框架还支持tool(工具返回)。content:消息内容。
适用场景:与 API 调用格式一致——如果你平时调 OpenAI / Claude API 时就用 messages 数组,训练数据可以直接复用同一格式,训练和推理零转换成本。
三种格式的关系
三种格式不是互相替代,是不同场景下的最优选择:
| 维度 | Alpaca | ShareGPT | ChatML / messages |
|---|---|---|---|
| 结构 | 扁平三字段 | conversations 数组 | messages 数组 |
| 多轮对话 | 需 history 扩展 | 原生支持 | 原生支持 |
| 工具调用 | 不支持 | observation/function_call | tool role |
| 与推理 API 对齐 | 需转换 | 需转换 | 直接复用 |
| 最适场景 | 简单指令微调 | Agent / 多轮对话 | 通用 / API 一致 |
LlamaFactory 在dataset_info.json里通过formatting字段区分格式(默认"alpaca",设为"sharegpt"时走 ShareGPT 解析),通过columns字段映射数据列名(来源:LlamaFactory GitHub data/README.md)。
我的建议:如果你刚开始做微调,ChatML / messages 格式是最省事的选择——训练和推理用同一套格式,不用在数据侧做转换。ShareGPT 格式在需要训练工具调用能力时不可替代。Alpaca 格式适合从零构建简单的指令数据集,字段最少、心智负担最低。
5. 偏好对齐数据:教它「怎么答更好」
SFT 教会模型按格式回答,但回答有好有坏。对齐阶段需要模型学会区分:同一个问题,哪个回答更好。
DPO 偏好对
DPO(Direct Preference Optimization)是 2026 年偏好对齐的主流方法——本系列训练三阶段那篇讲过,它省掉了奖励模型,直接优化偏好。DPO 的训练数据是「偏好对」:同一个问题,给一个更好的回答(chosen)和一个更差的回答(rejected)。
Alpaca 格式下的 DPO 数据:
{"instruction":"解释什么是量子计算。","input":"","chosen":"量子计算利用量子比特的叠加和纠缠特性,在某些特定问题上(如大数分解、分子模拟)实现远超经典计算机的计算速度。它不是通用的更快计算,而是针对特定问题类型的加速。","rejected":"量子计算就是一种比普通电脑快很多倍的超级计算机,什么都能算得更快。"}LlamaFactory 在dataset_info.json中需要设置"ranking": true来标记这是偏好数据(来源:LlamaFactory 官方文档)。
ShareGPT 格式下的 DPO 数据:
{"conversations":[{"from":"human","value":"解释什么是量子计算。"}],"chosen":{"from":"gpt","value":"量子计算利用量子比特的叠加和纠缠特性,在某些特定问题上实现远超经典计算机的计算速度。它不是通用的更快计算,而是针对特定问题类型的加速。"},"rejected":{"from":"gpt","value":"量子计算就是一种比普通电脑快很多倍的超级计算机,什么都能算得更快。"}}这里conversations提供对话上下文(到这里为止的所有对话),chosen和rejected是两个候选回答,标注人已经判断了哪个更好。
奖励模型数据
如果用 RLHF(而非 DPO),数据格式类似,但标注方式不同:不是 chosen/rejected 对,而是给回答打分(通常是 Likert 量表 1-5 分,或二元的 thumbs up/down)。训练奖励模型本质上也是学偏好——从标注者的打分中学习「什么算好回答」。
6. 数据怎么进训练:token 化、packing、loss mask
格式对了只是入场券。模型真正学哪几个字,由一个更隐蔽的开关决定。
Token 化:文字变成数字
训练前,所有文本都要经过 tokenizer(分词器)转成 token 序列。本系列《LLM 是什么?——它不是查资料,是在接龙》那篇讲过,token 是模型的最小单位——不是字,不是词,是介于两者之间的子词。
一段 SFT 样本 token 化后变成:
[指令 tokens] + [输入 tokens] + [回答 tokens]模型拿这整条序列做 next-token prediction:看到前面所有 token,预测下一个。问题来了——指令部分本来就是人给的已知条件,模型不需要「学会预测」指令,它需要学会预测的是回答部分。
Loss mask:只对回答算损失
这就是 loss mask 的作用。它的原理一句话:把指令部分的 label 设成 -100,让损失函数跳过它们,只对回答部分的 token 算交叉熵损失。
在 PyTorch 里,CrossEntropyLoss默认忽略 label 为 -100 的位置(ignore_index=-100是默认值)。所以 SFT 训练时,数据加载器会把每个训练样本的 label 数组这样构造:
labels = [-100, -100, ..., -100, ans_tok_1, ans_tok_2, ..., ans_tok_n] ^--- 指令 + 输入部分 ---^ ^--- 回答部分,参与损失计算 ---^Sebastian Raschka 在技术博客里解释得很清楚:loss mask 不排除 prompt 的输入,也不阻止回答 token 关注 prompt token——它只决定哪些位置的预测误差参与梯度更新(来源:sebastianraschka.com - When to mask prompt tokens during SFT)。
为什么必须这样做?回到接龙的本质。预训练时,模型对每个 token 都算损失——因为整篇文本都是它要学的「知识」。但 SFT 时,指令是已知条件,模型要做的是「给定这个指令,输出正确回答」。如果对指令也算损失,模型会花力气去学「预测人的指令」,这不是我们要教的东西。
打个比方:考试时老师给你题目,你写答案。评分应该只看你写的答案对不对,不应该把你抄题目的准确度也算进分数。Loss mask 就是这个「只给答案打分」的评分规则。
HuggingFace TRL 的SFTTrainer默认行为就是对 completion token 计算损失、忽略 prompt token(来源:HuggingFace TRL SFTTrainer 文档)。
Packing:把多条样本拼满一个窗口
SFT 数据里很多样本很短——一条指令加一条回答可能就几百个 token,但模型的上下文窗口有 4096 甚至 8192 个 token。如果每条样本单独占一个窗口,剩下的空间全填 padding token,计算全浪费在无用功上。
Packing 的做法:把多条短样本首尾相接,拼满一个上下文窗口。比如一个 4096 的窗口里塞三条样本:
[指令1][回答1][EOS][指令2][回答2][EOS][指令3][回答3][EOS][padding...]但 packing 带来一个新问题:注意力机制会让窗口里每个 token 都能看到所有其他 token。这意味着样本 2 的回答能「偷看」样本 1 的答案——训练数据泄露。
解决方案是attention masking(注意力掩码):在同一个窗口里,每条样本只能看到自己和前面的 token,不能看到后面的样本。具体实现是给注意力矩阵加一个块对角掩码——每个样本形成一个独立的注意力块,块间互不可见(来源:HuggingFace Blog - Efficient LLM Pretraining with Packed Sequences)。
Packing + loss mask 组合起来的效果:一个窗口里塞了多条样本,每条样本只对回答部分算损失,每条样本互相独立。训练效率比逐条处理高 2-3 倍(来源:Unsloth Blog - 3x Faster Training with Packing),因为 padding 被压到最低、GPU 算力被充分利用。
7. 数据质量工程:去重、配比、合成
数据格式只是骨架,数据质量才决定模型好不好用。这节讲三个关键的工程环节。
去重与毒性过滤
预训练语料的去重前面已经提过(MinHash 近似去重),SFT 和偏好数据同样需要去重。重复样本会让模型过度学习某些模式,产生「复读机」倾向。毒性过滤用分类器标记有害内容,HuggingFace 的 FineWeb 管线里这一步是标准配置。
数据配比(Mix)
预训练语料不是均匀混合的。典型的配比大约是:网页 60%、书籍 15%、代码 10%、论文 5%、维基百科 5%、论坛 5%(这是行业公开的大致比例,各家具体配比不公开)。配比直接影响模型的能力分布——代码比例高的模型编程能力强,但可能牺牲一些通用对话的流畅度。
合成数据:2026 年的大趋势
2025-2026 年最明确的数据工程趋势是用大模型生成训练数据。几条主流路径:
- Self-Instruct:从少量种子指令出发,让大模型生成更多指令和回答,过滤后扩展成大规模指令数据集。原始的 Self-Instruct 论文把 175 条种子扩展到了 52,000 条过滤后的样本。
- Evol-Instruct:WizardLM 提出的方法——不是简单复制指令,而是让大模型把简单指令「进化」成更复杂、更难的版本,生成难度梯度更丰富的训练数据。
- 蒸馏:用强模型(如 GPT-4)生成高质量回答,喂给弱模型训练,本质是知识蒸馏。
PiKa 是这条路上的一个标志性工作。据其论文(Yin et al., arXiv:2510.06670)披露,PiKa 用合成方法生成的专家级对齐数据,只用十分之一的数据量就超过了官方指令微调版本,在 Qwen2.5 系列(0.5B-7B)上均验证有效。这呼应了本系列训练三阶段那篇讲的 LIMA 论文的结论——1000 条精选 SFT 数据就能做出可用的对话模型,数据质量比数量重要得多。
8. 技术深挖:规模与质量的账
本节是给想深挖的读者准备的,可跳过。
预训练的规模量级
截至 2026-08,主流预训练语料的规模量级:
| 数据集 | Token 数 | 来源 | 备注 |
|---|---|---|---|
| FineWeb | 15T(扩展至 18.5T+) | Common Crawl 96 快照 | HuggingFace 2024(数据集页面) |
| FineWeb-Edu | 1.3T | FineWeb 教育价值子集 | 高教育密度文本 |
| FineWeb2 | 8TB 原始文本 | 多语言扩展 | HuggingFace 2025 |
| DCLM | 240T token 池 | Common Crawl | Li et al. 2024(arXiv:2406.11794) |
| LLaMA 3 训练数据 | ~15T token(据公开报道) | 未公开具体来源 | Meta 2024 |
这些数字的意义不在于「谁更大」,而在于说明预训练的数据量级已经到了十万亿 token 级别。这个量级下,数据清洗的每一个百分点都意味着万亿 token 的取舍。
小而精 vs 大而杂
LIMA 论文(Zhou et al., 2023)的标题就是论点:LIMA: Less Is More for Alignment。它只用 1000 条精选的 SFT 样本,就做出了能与 GPT-4 在人类评测中打平手的对话模型。这不是说数据量不重要,而是说SFT 阶段的数据质量远比数量重要。
PiKa 把这个结论推得更远:3 万条合成的专家级数据,效果超过数万甚至数十万的普通质量数据。背后的逻辑是——模型在 SFT 阶段学的不是知识(知识在预训练时已经装进去了),学的是「怎么用已有知识组织出符合格式要求的回答」。教格式,不需要千万条样本,需要每条样本都是好样本。
这和预训练形成鲜明反差。预训练需要海量数据来「装知识」,因为知识的覆盖面取决于数据的覆盖面。SFT 和对齐只需要「教格式」和「教偏好」,精选少量高质量样本足够。
我把这笔账压成一句话:预训练拼规模,SFT 拼质量,对齐拼判断标准。三道工序的数据策略完全不同。
9. 结论:想改变模型,先看它吃什么
回到开头那句话:模型的人格,是数据的投影。
你觉得模型回答太啰嗦?SFT 数据里的回答样本就是那么长。你觉得模型动不动就拒绝?对齐数据里拒绝样例的比例太高。你觉得模型在某个领域不够专业?预训练语料在那个领域的覆盖不够。
想改变模型的行为,第一步不是调参数、不是换模型、不是改 prompt——是去看它吃了什么数据,然后换一批。
如果只让我留一句:数据决定了模型能变成什么样,架构和算法只是把那个「什么样」挖出来。
这篇是「LLM 那些事」系列的拓展篇。下一篇回到主线,聊一个更工程化的话题:模型怎么变小——量化与部署。
参考来源
- LlamaFactory 官方文档 - Data Preparation:https://llamafactory.readthedocs.io/en/latest/getting_started/data_preparation.html
- LlamaFactory GitHub - data/README.md:https://github.com/hiyouga/LlamaFactory/blob/main/data/README.md
- Anyscale - Dataset preparation for LLM post-training:https://docs.anyscale.com/llm/fine-tuning/data-preparation
- Unsloth - Datasets Guide:https://unsloth.ai/docs/get-started/fine-tuning-llms-guide/datasets-guide
- HuggingFace FineWeb 数据集:https://huggingface.co/datasets/HuggingFaceFW/fineweb
- Penedo et al. (2024) - The FineWeb Datasets: Decanting the Web for the Finest Text Data at Scale:https://arxiv.org/abs/2406.17557
- Li et al. (2024) - DataComp-LM: In search of the next generation of training sets:https://arxiv.org/abs/2406.11794
- Yin et al. (2025) - PiKa: Expert-Level Synthetic Datasets for Post-Training Alignment:https://arxiv.org/abs/2510.06670
- Sebastian Raschka - When to mask prompt tokens during SFT:https://sebastianraschka.com/faq/docs/when-mask-prompt-tokens.html
- HuggingFace TRL - SFTTrainer 文档:https://huggingface.co/docs/trl/en/sft_trainer
- HuggingFace Blog - Efficient LLM Pretraining with Packed Sequences:https://huggingface.co/blog/sirluk/llm-sequence-packing
- Unsloth Blog - 3x Faster Training with Packing:https://unsloth.ai/docs/blog/3x-faster-training-packing
- MachineLearningPlus - How to Build a Custom Instruction Dataset:https://machinelearningplus.com/machine-learning/custom-instruction-dataset-fine-tuning/
- Zhou et al. (2023) - LIMA: Less Is More for Alignment:https://arxiv.org/abs/2305.11206