SFT 数据准备基础:质量检查流程、对话 JSONL 格式规范、推理和工具调用 schema 设计、代表性训练/评估集划分。
数据准备决定了任何监督微调(SFT)项目的天花板。你已经评估过你的基础模型(FM),开箱即用的性能无法满足你的生产需求。也许模型不能可靠地遵循你的输出模式,难以适应你的领域分类体系,或者无法保持你的应用所要求的语气。问题不在于是否要定制,而在于如何定制。本文假设你已经决定对基础模型进行微调,并正在评估如何为这项工作准备数据。
训练后定制提供了三个不同的杠杆。每个杠杆针对的是模型当前能力与你需要它具备的能力之间的不同差距。继续预训练(CPT)摄入大量非结构化领域文本,以扩展模型的知识库。当模型缺乏对你的领域术语、概念或数据模式的熟悉度时,使用 CPT。监督微调(SFT)通过精选的输入-输出对进行训练,以重塑模型的行为。SFT 教模型如何响应:遵循指令、遵守模式、采用特定语气或产生结构化输出。它不注入新知识。它教模型以你需要的方式应用它已经知道的东西,这个想法有时被称为表面对齐假设。强化微调(RFT)通过奖励信号而非明确演示来优化行为。当你能够以编程方式评估输出质量但无法轻松大规模展示推理路径时,RFT 有效。
这些技术并非相互排斥。生产模式是 CPT,然后 SFT,然后 RFT:首先扩展知识,然后塑造行为,然后通过反馈优化。实际上,CPT 使用得较少,只有在基础模型缺乏任务所需的关键领域词汇或知识时才需要。像 Amazon Nova 这样的基础模型已经在广泛语料库上进行了预训练,所以 SFT 然后 RFT 通常就足够了。
本文是两篇系列的第一篇,涵盖 SFT 数据准备的基础知识:质量检查、格式要求以及训练/评估划分。我们使用 Amazon Bedrock 文档中的代码片段来说明关键概念,同时使指导适用于你选择的任何模型。系列的第二篇涵盖高级策略:就绪度评估、数据子集选择和过滤、数据增强以及数据混合。
在你投入格式或训练基础设施之前,先审查你的原始数据。尽早发现问题可以为下游节省大量时间和计算成本。
数据集中每个响应都应该是你愿意部署到生产环境的黄金标准答案。错误的示例可能教会模型一个难以纠正的持久坏习惯。这种风险在 SFT 中尤其严重,因为模型学习的不是新事实,而是学习要模仿哪些模式。错误的演示会被模仿。
实际结果是质量以很大优势胜过数量。LIMA 表明,1000 个精心策划的示例可以匹配在数量级更大的数据上训练的模型。AlpaGasus 表明,将指令集过滤到其最干净的 20% 可以比完整数据集训练得更快、得分更高。如果你在处理人工标注的数据,在示例进入训练集之前实施多审流程。
数据集多样性是 SFT 成功的最强预测因素之一。监督微调可扩展性研究确定了两个决定微调泛化程度的属性。第一个是语义覆盖,即所代表的任务域和提示措辞的广度。第二个是信息深度,即单个示例的丰富程度。只覆盖生产流量一个窄片段的数据集将产生在该片段上表现良好但在其他所有地方表现不佳的模型。
首先审查数据集的提示变化。你的示例应包括用户表达相同意图的不同方式,因为只接受过"Summarize this document"训练的模型不会可靠地处理"Give me the key takeaways"。接下来检查领域和主题广度。如果你的任务跨越多个领域,验证每个领域都按与其生产频率成比例的方式表示。然后查看难度范围:包括直接案例和复杂的多步骤问题,并按实际流量的复杂性概况加权。最后,明确包含边缘情况,如模糊输入、信息不完整和超出范围请求,并配上你在这些情况下希望模型产生的响应。
一个实用的方法是按嵌入相似性聚类你的示例,并检查生成的聚类中的空白。稀疏或缺失的聚类表明模型将缺乏训练信号的领域。例如,客户支持数据集可能聚类为密码重置、账单查询和运输更新。如果退款是生产中的常见请求,但没有聚类覆盖它们,那个空白区域就是你的差距。模型将几乎没有退款对话的信号,所以在训练前收集或编写退款示例。系列中的第二篇文章展示了如何使用数据子集选择方法自动化这个想法。
虽然数据集的多样性至关重要,但处理相同类型情况的示例应该在内部保持一致。同一任务类型中的不一致会发送关于正确行为的矛盾信号。例如,如果相似的提示既产生要点列表答案又产生段落格式答案,模型将不会学习到可靠的响应结构默认样式。如果你需要简洁的两句话答案,不要在你的训练数据中包含段落长度的回复。
这条读起来相当负面。
登录失败后重置
当然!以下是快速总结:客户报告说……
客户在 iOS 17 上重置密码后无法登录。工单升级到二级支持。
客户的卡在结账时被拒绝了三次。账单确认发卡行阻止了该交易。
我无法帮助解决这个问题。
非常抱歉,但这超出了我今天能够协助的范围。不过,我很乐意……
该请求超出了此助手的服务范围。
该请求超出了此助手的服务范围。
重复或近似重复的示例会导致模型过度拟合这些模式,使它们相对于数据集其余部分的重要性被放大。重复在 SFT 中不如在预训练中那么关键,但当你合并来自多个标注者的数据、跨项目组合数据集或使用合成数据生成时,它可能会悄悄出现。在这些情况下,在训练前应用精确匹配和语义去重。
扫描数据集中的有害、有偏见或不适当内容。即使你的用例很窄,模型也可能从有问题的示例中内化模式,并在意想不到的上下文中呈现它们。使用自动化分类器(如开源的 Llama Guard)标记内容供人工审核,并为你的领域建立可接受训练数据的明确指南。
完成质量检查后,你可以为训练构建数据结构。格式不仅仅是关于语法。你如何构建示例会塑造模型的习得行为,因为 SFT 教模型响应特定形式的输入,而不仅仅是其内容。
当你在推理时计划使用系统提示时,在训练示例中包含系统提示。系统提示建立了塑造模型行为的上下文、角色和约束。如果训练数据缺少系统提示但推理包含它们,你就会产生一种分布不匹配,可能会降低行为。
大多数现代 SFT 管道,包括 Amazon Nova 配方,使用对话式 JSONL 格式,其中每行是一个自包含的 JSON 对象,表示一段对话。Amazon Nova 2.0 模型使用 Converse API 格式:
{
"schemaVersion": "bedrock-conversation-2024",
"system": [{"text": "You are a helpful coding assistant."}],
"messages": [
{
"role": "user",
"content": [{"text": "Write a Python function to check if a string is a palindrome."}]
},
{
"role": "assistant",
"content": [
{"text": "def is_palindrome(s):\n cleaned = s.lower().replace(' ', '')\n return cleaned == cleaned[::-1]"}
]
}
]
}
需要遵循的关键格式规则:
每行一个 JSON 对象,不跨多行美化打印。
上传前验证每行解析为有效 JSON。
在用户和助手轮次之间保持严格的角色交替。
当你的生产设置使用系统消息时包含它们。
对于具有推理能力的模型(如 Amazon Nova 2.0,reasoning_enabled: true),在 assistant 回合中使用 reasoningContent 字段包含中间思考步骤。在推理痕迹上训练,才是真正将 CoT(Chain-of-Thought,思维链)从一种提示技巧转化为模型自身的能力。
{
"schemaVersion": "bedrock-conversation-2024",
"system": [{"text": "You are a financial analyst. Provide data-driven answers with supporting calculations."}],
"messages": [
{
"role": "user",
"content": [{"text": "Calculate YoY revenue growth. 2024: $4.2M, 2025: $5.1M"}]
},
{
"role": "assistant",
"content": [
{
"reasoningContent": {
"reasoningText": {
"text": "The user asks for year-over-year revenue growth. I need to calculate the percentage change: (new - old) / old x 100. That gives (5.1 - 4.2) / 4.2 x 100 = 21.43%."
}
}
},
{"text": "YoY revenue growth is approximately 21.4 percent: ($5.1M - $4.2M) / $4.2M x 100."}
]
}
]
}
使用推理痕迹最难的部分不是格式,而是获取那些真正能教给模型新知识的痕迹。有效的推理痕迹具备以下几个特点。首先是忠实性(faithful):推理过程必须真正导向最终答案。其次是比例性(proportional):简单问题对应短推理链,复杂问题对应长推理链——难度感知的推理痕迹压缩技术将这一权衡显式化。第三是完整性(complete):不允许思维跳跃,因为专家撰写的推理过程往往会跳过模型尚未学会的中间步骤。第四是质量优先于数量:s1 和 LIMO 的研究均表明,少于 1,000 条经过精心筛选的推理示例,就足以在具备能力的基座模型上激发出强大的推理能力。本系列的第二篇文章将介绍如何通过蒸馏和自我生成大规模获取这些推理痕迹。
推理内容应使用纯文本,并保持与问题解决过程直接相关。当训练时启用了推理功能,推理时也应保持启用,以确保行为一致。需要注意的是,在非推理数据集上启用 reasoning_enabled: true 进行训练,可能导致模型丧失推理能力,因为它会学会在生成响应时不应用推理。
SFT 支持训练模型执行工具调用(Function Calling)和多模态理解(文档、图片、视频)。对于工具调用,toolUse 块出现在 assistant 回合,toolResult 块出现在 user 回合,每个块都通过唯一的 toolUseId 相互引用:
{
"schemaVersion": "bedrock-conversation-2024",
"system": [{"text": "You are an expert in composing function calls."}],
"toolConfig": {
"tools": [
{
"toolSpec": {
"name": "getItemCost",
"description": "Retrieve the cost of an item from the catalog",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"item_id": {
"type": "string",
"description": "The ASIN of item to retrieve cost for"
}
},
"required": ["item_id"]
}
}
}
}
]
},
"messages": [
{
"role": "user",
"content": [{"text": "How much does item id-456 cost?"}]
},
{
"role": "assistant",
"content": [
{
"toolUse": {
"toolUseId": "getItemCost_0",
"name": "getItemCost",
"input": {"item_id": "id-456"}
}
}
]
},
{
"role": "user",
"content": [
{
"toolResult": {
"toolUseId": "getItemCost_0",
"content": [
{"text": "{"name": "getItemCost", "results": {"cost": "$29.99"}}"}
]
}
}
]
},
{
"role": "assistant",
"content": [
{"text": "Item id-456 costs $29.99."}
]
}
]
}
工具调用数据的关键约束:
toolUse 必须只出现在 assistant 回合,toolResult 只出现在 user 回合。toolResult 必须引用一个前置 assistant 回合中有效的 toolUseId,且每个 ID 在一次对话中只能使用一次。toolResult 的内容只能是文本或 JSON。toolSpec 中的 inputSchema 必须是有效的 JSON Schema 对象。对于多模态训练,文档和图片内容块与文本一起出现在 user 回合,source 字段引用 Amazon Simple Storage Service(Amazon S3)位置:
{
"schemaVersion": "bedrock-conversation-2024",
"system": [{"text": "You are a document analysis assistant."}],
"messages": [
{
"role": "user",
"content": [
{
"document": {
"format": "pdf",
"name": "quarterly_report",
"source": {"s3Location": {"uri": "s3://<your-bucket-name>/report.pdf"}}
}
},
{"text": "Summarize the key findings from this quarterly report."}
]
},
{
"role": "assistant",
"content": [
{"text": "The quarterly report highlights three key findings..."}
]
}
]
}
每个基座模型在 post-training 阶段都使用特定的 chat template 进行训练:即用于界定系统提示、用户回合和 assistant 回合的确切 token 序列。你的训练数据应该与这个 template 完全一致。即使是细微的偏差,也会迫使模型在学习新行为的同时还要学习新的输入格式,从而将学习预算分散到两个目标上。在最坏的情况下,template 不匹配会导致模型忽略系统提示,或在推理时产生格式错误的输出。
Template 对齐的实践指南:
使用模型提供商官方提供的格式化工具。对于 Amazon Nova,使用 Converse API schema。对于开源模型,使用 Hugging Face Transformers 中 tokenizer 的 apply_chat_template() 方法。
永远不要手动编写分隔符。如果你正在将数据从其他格式(如 ShareGPT 或 Alpaca)转换过来,应该通过目标模型的 chat template 函数运行,而不是手动插入角色标记字符串。
验证 tokenization 往返过程。格式化后,对数据样本进行 tokenize,再解码回文本。确认角色边界、特殊 token 和内容都被完整保留。
在训练期间匹配推理时的结构。如果你的生产流程在特定位置注入了系统提示、工具定义或检索上下文,你的训练数据应该以相同的位置包含这些元素。
将 10–20% 的数据留出作为评估集。这不是可选项。没有评估集,你就无法区分真正的学习和过拟合。评估集应该代表你的生产分布,而不是随机切分——后者可能会低估重要但稀有的类别。
对于小数据集(少于 1,000 条样本),使用分层划分,确保每个任务类别同时出现在训练集和评估集中。对于更大的数据集,随机划分通常足够,但之后要验证分布情况。训练前,先在评估集上用未修改的模型建立基线性能。这能给你一个具体的超越目标,也能帮助你量化 SFT 的价值。
数据准备是任何 SFT 工作流中影响最大的环节。本文涵盖的模式——包括系统性的质量检查、符合 schema 的格式化,以及有代表性的训练/评估集划分——无论你是为狭义的分类任务还是复杂的多轮对话系统进行微调,都同样适用。前期投入时间,训练任务会收敛更快、泛化更好,并避免因数据问题导致的模型行为调试这一高成本循环。
本系列的第二篇文章将介绍 SFT 数据准备的高级内容:使用学习曲线评估数据就绪度、选择高价值子集、增强数据,以及混合数据源以防止灾难性遗忘。
要开始使用,请访问 Amazon Bedrock 控制台探索模型定制选项。在服务详情页了解更多关于 Amazon Nova 的信息,查阅 Amazon Nova 文档中的定制指南,并探索 Amazon SageMaker HyperPod recipes 仓库中可直接运行的训练配置。相关阅读请参阅 AWS Machine Learning Blog 上的《Customize Amazon Nova models with Amazon Bedrock fine-tuning》。