SFT 指令微调数据格式全解(Alpaca、ShareGPT、ChatML 三套范式)

SFT(Supervised Fine-Tuning)数据本质就是”问题+人工示范答案”配对——单轮走 Alpaca、多轮走 ShareGPT 或 ChatML、偏好对齐走 DPO/ORPO,差别只在字段抽象。在内部知识库项目上做模型风格迁移时,我先后用三套格式喂过同一个 7B 基座,最后训练质量与”答案字段是否完整覆盖了多轮上下文”强相关;选错格式,损失函数会把噪声 token 一并学进去,模型越训越飘。下文把三套主流范式放一起对照,给出字段定义、最小化样例和落地步骤。

一、SFT 数据格式的演进逻辑

SFT 数据格式从早期的 Alpaca 出发,已经走过三代演进:

  1. Alpaca 范式(单轮指令):instruction + input + output 三元组。instruction 是任务,input 是补充上下文(可为空),output 是人类示范答案。简单直接,但无法表达多轮。
  2. ShareGPT 范式(多轮对话):用 conversations 列表堆角色(human/gpt/observation/functioncall),天然模拟真实对话流。代价是角色映射繁琐,且需要保证 human/observation 出现在奇数位、gpt/functioncall 出现在偶数位。
  3. ChatML / Messages 范式(行业事实标准):用 messages 数组 + role/content 字段,完美兼容多轮、System Prompt 与 Tool Calling。现代微调框架(Transformers、TRL、LLaMA-Factory)都会把前两种格式先转成 Messages,再交给 Tokenizer 的 Chat Template 序列化为最终训练样本。

这一收敛过程在 LLaMA-Factory、TRL 的文档里都能看到痕迹:Alpaca、ShareGPT 仍作为”原始数据格式”存在,但内部管线统一以 ChatML 为中间表示。理解这一点,就理解了为什么”格式选错”在工程上不是 typo 那么简单——它会影响整个数据预处理与损失掩码链路。

二、三种主流格式的字段定义与样例

下面从最小化数据切入,给出三种格式的字段定义和可直接复用的样例。

2.1 Alpaca 格式(单轮)

字段约定:

  • instruction(必填):人类指令
  • input(选填):额外输入上下文
  • output(必填):模型应给出的回答
  • system(选填):系统提示词
  • history(选填):历史多轮消息,二元组列表

最小化样例:

{
  "instruction": "把下面这句话翻译成英文",
  "input": "今天天气不错",
  "output": "The weather is nice today."
}

2.2 ShareGPT 格式(多轮 + 工具调用)

字段约定:

  • conversations(必填):消息列表
  • from(必填):角色,human/gpt/observation/function_call
  • value(必填):消息文本
  • system(选填):系统提示词
  • tools(选填):工具描述(JSON 字符串)

最小化样例:

{
  "conversations": [
    {"from": "human", "value": "我出生于 1990-05-15,今天几岁?"},
    {"from": "function_call", "value": "{\"name\": \"calculate_age\", \"arguments\": {\"birthdate\": \"1990-05-15\"}}"},
    {"from": "observation", "value": "{\"age\": 31}"},
    {"from": "gpt", "value": "根据计算,你今天 31 岁。"}
  ],
  "tools": "[{\"name\": \"calculate_age\", \"description\": \"根据出生日期计算年龄\", \"parameters\": {\"type\": \"object\", \"properties\": {\"birthdate\": {\"type\": \"string\"}}, \"required\": [\"birthdate\"]}}]"
}

2.3 ChatML / Messages 格式(现代事实标准)

字段约定:

  • messages(必填):消息数组
  • role(必填):system/user/assistant/tool
  • content(必填):消息内容

最小化样例:

{
  "messages": [
    {"role": "system", "content": "你是客服助手"},
    {"role": "user", "content": "怎么修改收货地址?"},
    {"role": "assistant", "content": "请在订单详情页点击「修改地址」按钮..."}
  ]
}

三套格式对比表如下:

维度 Alpaca ShareGPT ChatML / Messages
适用场景 单轮、任务边界清晰 多轮对话、工具调用 多轮 + System + Tool Calling
核心字段 instruction/input/output conversations[] messages[]
角色表达 不支持 from/value 枚举 role/content
训练损失计算范围 仅 output 字段 仅 gpt/function_call 角色 仅 assistant 角色
现代框架支持 需转 ChatML 需转 ChatML 原生

三、损失掩码:SFT 数据最关键的细节

格式只是”皮”,损失掩码才是”骨”。SFT 训练时只会对模型应该学习的 token 计算交叉熵损失,其余 token(包括 system、user、observation、padding)都需要被掩掉。

具体来说:

  • Alpaca 格式:训练时只对 output 字段对应的 token 计算损失。instruction 和 input 部分的 token 会被 mask 掉。
  • ShareGPT 格式:只对 gpt 和 function_call 角色的 token 计算损失,human 和 observation 角色的 token 被 mask 掉。
  • ChatML 格式:只对 assistant 角色的 token 计算损失,system、user、tool 角色的 token 被 mask 掉。

这条规则在数据预处理阶段就要贯彻。我曾在内部项目里见过一个反例:早期数据 pipeline 没正确掩掉 observation token,模型把工具返回值当成自己应该模仿的回答学进去了,结果推理时它开始”伪造”工具输出——这种行为修起来极费劲。

四、DPO/ORPO 偏好对齐数据格式

当你完成 SFT 想再往上做偏好对齐(让模型更偏好某类回答),就需要第三种数据格式。

4.1 DPO 数据格式

{
  "instruction": "用一句话解释相对论",
  "input": "",
  "chosen": "相对论是爱因斯坦提出的关于时空与引力的理论。",
  "rejected": "相对论是物理学家搞出来的东西。"
}

DPO 直接优化”chosen 优于 rejected”的偏好,不需要先训奖励模型,因此训练链路比 PPO 短很多。

4.2 ORPO 数据格式

ORPO 把 SFT 和 DPO 合并成一步,训练时同时计算普通语言模型损失和”odds ratio”偏好损失,字段同 DPO。好处是少一个训练阶段,代价是对超参敏感,learning rate 通常要比纯 SFT 低一个量级。

五、落地的五个步骤

从原始数据到可训练样本,要走完五步:

  1. 确定目标场景:单轮信息抽取/格式化输出 → Alpaca;多轮客服/聊天 → ShareGPT 或 ChatML;工具调用 Agent → ChatML + tools 字段。
  2. 构造最小化数据集:从 50~100 条样本开始,确认数据 pipeline 能跑通。
  3. 写 dataset_info.json:在 LLaMA-Factory 等框架里把字段映射到内部表示(prompt → instruction、query → input、response → output)。
  4. 做质量过滤:去重(按 instruction 哈希)、去脏(用规则或小模型打分)、去偏(剔除可能引入偏见的样本)。
  5. 验证损失掩码:用 framework 提供的 debug 工具打印前 3 条样本的 token 化结果,确认 user/system/token 不在损失范围里。

每一步都建议用一个小模型(1B~3B)跑 1~2 个 epoch,看 loss 曲线是否正常下降,再上 7B+ 模型全量训练。

下面给出一段在 LLaMA-Factory 中注册 SFT 数据集的最小化配置示例:

{
  "alpaca_demo": {
    "file_name": "data.json",
    "columns": {
      "prompt": "instruction",
      "query": "input",
      "response": "output",
      "system": "system",
      "history": "history"
    }
  },
  "sharegpt_demo": {
    "file_name": "data.json",
    "formatting": "sharegpt",
    "columns": {
      "messages": "conversations",
      "system": "system",
      "tools": "tools"
    }
  }
}

效果上,注册完毕后用 llamafactory-cli train 或 llamafactory-cli webui 启动训练;ShareGPT 格式会自动展开 conversations 列表、合并 system 字段、注入 tools 描述,最后统一渲染为 ChatML。LLaMA-Factory 文档里强调了一句话:”Alpaca 和 ShareGPT 在送入模型前都会被统一转换为 Messages 格式,再通过 Tokenizer 的 Chat Template 完成最终序列化。”把这条规则记牢,能避开大多数格式相关的事故。

到这里,SFT 数据从格式选型、字段定义到落地配置的链路就完整了。

常见问题(FAQ)

Q1:Alpaca 和 ShareGPT 选哪个?

单轮任务用 Alpaca,多轮对话或工具调用用 ShareGPT;最终都会转 ChatML。

Q2:损失函数应该覆盖哪些 token?

只覆盖 assistant(gpt)角色,system/user/observation 全部 mask 掉。

Q3:数据量多少够?

高质量 1k~10k 条可追平低质量 50k+;先小批量验证 pipeline 再扩量。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
赵其鑫的头像赵其鑫管理团队

相关推荐

返回顶部