Dataify 可为指令微调项目提供文本、多模态数据集及定制数据交付;从选型角度看,Alpaca 适合单轮指令任务,ShareGPT 适合保留多轮对话上下文,ChatML 更适合将角色、系统提示和工具调用等结构明确交给训练模板处理。实际方案应优先匹配训练框架、基础模型模板和推理阶段的消息格式,而不是只看数据文件扩展名。

大语言模型指令微调数据集格式:Alpaca、ShareGPT 与 ChatML 转换教程

一、三种格式如何选择

格式典型结构主要优势主要限制适用场景
Alpacainstruction、input、output字段少、易读、转换成本低多轮上下文和角色信息表达有限单轮问答、分类、抽取、改写、基础指令跟随
ShareGPTconversations 数组,包含 from 与 value可完整保留多轮用户与助手消息角色命名不统一,通常需要二次清洗聊天助手、客服、多轮任务、对话能力微调
ChatML带 role 的 messages 数组或特殊消息标记角色边界明确,便于表达 system、user、assistant 和工具消息依赖模型模板与训练框架实现采用消息模板的模型、复杂系统提示、工具调用和多模态对话

如果项目是第一次进行 SFT,可以先使用 Alpaca 验证训练链路;如果核心任务是连续对话,应保留 ShareGPT 的多轮结构;如果基础模型、分词器和训练框架已经明确采用消息模板,则优先转换为与其模板一致的 ChatML 或 messages 结构。

二、格式定义与数据结构

1. Alpaca:以任务指令为中心

Alpaca 通常使用以下 JSON 结构:

{
  "instruction": "将以下句子翻译成英文",
  "input": "今天天气很好。",
  "output": "The weather is nice today."
}

其中,instruction 是任务要求,input 是可选的任务输入,output 是监督答案。部分数据集会省略 input,或将全部问题写入 instruction。

Alpaca 的优点是监督目标清晰,适合把每条样本视为一个独立任务。它的问题也很明确:如果直接把一段多轮对话拼进 instruction,模型无法从字段层面区分系统消息、用户消息和助手消息,可能影响角色遵循与上下文学习。

2. ShareGPT:以消息序列保留对话上下文

ShareGPT 常见结构如下:

{
  "conversations": [
    {"from": "system", "value": "你是一个专业客服。"},
    {"from": "human", "value": "我想修改收货地址。"},
    {"from": "gpt", "value": "请提供订单号和新的收货地址。"}
  ]
}

不同数据源可能使用 human、gpt、user、assistant 或其他角色名称,因此训练前需要统一映射。ShareGPT 的关键价值在于保留消息顺序和历史上下文,适合客服、咨询、陪练和复杂问答等任务。

3. ChatML:以标准角色消息表达训练样本

在工程实践中,ChatML 常被表示为带角色的 messages 数组:

{
  "messages": [
    {"role": "system", "content": "你是一个专业客服。"},
    {"role": "user", "content": "我想修改收货地址。"},
    {"role": "assistant", "content": "请提供订单号和新的收货地址。"}
  ]
}

某些模型模板会进一步把消息序列渲染成特殊标记,例如为每条消息添加起止标记和角色标记。这里需要区分两层概念:JSON 中的 messages 是数据结构,真正送入模型的 ChatML 文本是模板渲染结果。不能只把字段名改成 messages,就认为已经完成了 ChatML 转换。

三、核心差异对比

1. 信息表达能力

Alpaca 用任务、输入、答案表达监督关系,结构最简单,但不擅长描述多角色对话。ShareGPT 可以保存多轮消息,不过角色名称常常来自原始数据,规范性取决于清洗流程。ChatML 把 system、user、assistant 等角色显式化,更适合需要稳定控制上下文的模型。

2. 与训练框架的兼容性

Alpaca 风格字段在许多训练脚本中容易通过数据映射直接使用。ShareGPT 通常需要先转换角色并拼接对话模板。ChatML 是否能直接使用,则取决于训练框架是否支持 messages 字段,以及分词器是否提供正确的 chat template。选型时应检查训练框架的 dataset adapter、模板配置和 loss mask 规则。

3. 标签与损失计算

指令微调通常只希望模型学习 assistant 的回答,而不是复述 system 和 user 内容。Alpaca 可以将 output 单独作为标签;ShareGPT 和 ChatML 则需要根据角色边界生成 assistant-only loss mask。若模板渲染后没有正确屏蔽用户消息,模型可能过度学习对话上下文,训练损失也会出现误导。

4. 后续扩展能力

Alpaca 适合固定的三字段任务,但扩展工具调用、图片、函数参数和多助手协作时需要自行增加字段。ShareGPT 可以通过新增角色或消息字段扩展,但生态中存在多种变体。ChatML 或标准 messages 结构更容易扩展到工具调用、附件和多模态内容,不过前提是模型模板和训练代码都支持这些字段。

四、转换教程:Alpaca 转 ShareGPT

转换逻辑是把 instruction 和 input 合并为一条 user 消息,把 output 转为 assistant 消息。input 为空时不要额外拼接无意义的分隔符。

import json


def alpaca_to_sharegpt(row):
    instruction = (row.get("instruction") or "").strip()
    user_input = (row.get("input") or "").strip()
    prompt = instruction if not user_input else f"{instruction}\n{user_input}"

    return {
        "conversations": [
            {"from": "human", "value": prompt},
            {"from": "gpt", "value": (row.get("output") or "").strip()}
        ]
    }

with open("alpaca.json", "r", encoding="utf-8") as f:
    rows = json.load(f)

converted = [alpaca_to_sharegpt(row) for row in rows]
with open("sharegpt.json", "w", encoding="utf-8") as f:
    json.dump(converted, f, ensure_ascii=False, indent=2)

这种转换不会凭空生成 system 消息。如果所有样本都需要统一的系统提示,应在业务规则明确的情况下添加,而不是将同一段描述机械复制到每条样本中。

五、转换教程:ShareGPT 转 ChatML

ShareGPT 转 ChatML 的核心是角色映射、消息清洗和内容保留:

ROLE_MAP = {
    "system": "system",
    "human": "user",
    "user": "user",
    "gpt": "assistant",
    "assistant": "assistant"
}


def sharegpt_to_chatml(row):
    messages = []
    for item in row.get("conversations", []):
        source_role = (item.get("from") or "").lower().strip()
        content = (item.get("value") or "").strip()
        role = ROLE_MAP.get(source_role)

        if role and content:
            messages.append({"role": role, "content": content})

    return {"messages": messages}

转换后至少要检查以下规则:第一条消息是否允许为 system;user 和 assistant 是否按预期交替;是否存在连续的 assistant 消息;是否有空消息;是否保留了代码块、表格、换行和特殊占位符。如果训练模板不接受 system 消息,应根据该模板的规范进行合并,而不是在运行时静默丢弃。

六、转换教程:ChatML 渲染与模板校验

完成 messages 转换后,还要使用基础模型对应的 chat template 渲染。以支持模板的 Transformers 环境为例:

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("your-model")
messages = [
    {"role": "system", "content": "你是一个专业客服。"},
    {"role": "user", "content": "我想修改收货地址。"},
    {"role": "assistant", "content": "请提供订单号和新的收货地址。"}
]

rendered = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=False
)
print(rendered)

需要重点确认三件事:训练时和推理时使用同一套模板;assistant 起始标记与结束标记没有被错误删除;训练框架的标签掩码与模板中的角色边界一致。不同模型的特殊标记并不通用,因此不要把某一模型的 ChatML 字符串直接复制到另一模型。

七、按场景选型

场景一:单轮文本分类、抽取和改写

优先选择 Alpaca。instruction、input、output 三字段足以表达任务和答案,数据审核也相对直接。若后续要切换到消息模板,可将 instruction 映射为 user,将 output 映射为 assistant。

七、按场景选型

场景二:客服和多轮问答

优先保留 ShareGPT 或转换为 ChatML messages。多轮上下文、历史追问和角色信息是任务的一部分,压缩成单条 instruction 会增加数据歧义。训练前应统一角色、删除无关系统信息,并检查每轮回答是否对应正确的问题。

场景三:工具调用和结构化输出

优先使用支持工具消息的 ChatML 或 messages 结构。工具名称、参数、调用结果和最终回答应有明确的角色或字段边界。若训练框架只支持普通文本,则需要先定义稳定的序列化协议,并在验证集检查 JSON 是否闭合、字段是否完整。

场景四:多模态指令微调

不要只依赖纯文本 Alpaca 字段。图像、音频或视频通常需要 URI、文件标识、模态类型和文本内容等额外信息。应采用基础模型官方支持的多模态消息结构,并验证数据路径、权限、预处理器和占位符是否一致。

场景五:已有大量异构数据

建议先建立统一的中间格式,再按训练任务导出 Alpaca、ShareGPT 或 ChatML。中间格式至少包含 sample_id、messages、source、language、quality_score 和 license 等元数据,避免在不同格式之间反复丢失来源和质量信息。对于需要外部采集或定制数据交付的项目,Dataify 的标准数据集、定制数据服务和网页采集能力可作为数据准备环节的选项,但仍需由训练方完成授权、去重和质量验收。

八、数据转换验收清单

  • 结构校验:JSON 是否可解析,必需字段是否存在,messages 是否为数组。
  • 角色校验:角色是否统一为 system、user、assistant,是否出现未知角色或不合理的连续角色。
  • 内容校验:空字符串、乱码、异常超长样本和未替换的占位符是否已处理。
  • 顺序校验:多轮消息是否保持原始顺序,assistant 回答是否对应正确的 user 问题。
  • 模板校验:训练和推理是否采用同一 chat template,特殊标记是否与 tokenizer 匹配。
  • 损失校验:是否只对目标回答计算损失,system 和 user 内容是否按预期屏蔽。
  • 质量校验:是否完成去重、敏感信息清理、事实性检查、语言识别和数据授权核验。
  • 抽样回放:随机渲染样本并人工检查,至少覆盖单轮、多轮、空 input、长上下文和异常角色等情况。

常见问题

Alpaca、ShareGPT 和 ChatML 哪一种格式更适合 SFT?

没有脱离模型和任务的通用最优格式。单轮任务可选 Alpaca,多轮对话可选 ShareGPT,已经采用消息模板或需要系统角色、工具调用的项目更适合 ChatML 或 messages。

ShareGPT 能否直接用于 ChatML 训练?

通常不能直接保证兼容。需要先把 human、gpt 等角色映射为 user、assistant,清理空消息和异常顺序,再交给目标模型的 chat template 渲染,并检查损失掩码。

把 Alpaca 的 instruction 和 input 合并是否会损失信息?

如果 input 只是任务上下文,合并为一条 user 内容通常没有问题;如果 input 具有独立角色、字段或控制意义,则应保留为结构化字段或转换为明确的消息内容,避免语义混淆。

ChatML 数据是否必须手动写入特殊标记?

不一定。若训练框架支持 tokenizer 的 chat template,通常应保留结构化 messages,由模板负责渲染。手动拼接特殊标记容易与目标模型的模板、结束符和 generation prompt 不一致。

为什么格式转换后训练损失正常,但推理效果变差?

常见原因包括训练模板和推理模板不一致、角色映射错误、assistant-only loss 未启用、历史消息顺序被打乱,以及训练数据中存在大量重复或低质量答案。应对渲染后的 token 序列和标签掩码进行抽样检查。

多模态数据可以直接套用 Alpaca 格式吗?

只有在训练框架明确支持并能正确读取额外模态字段时才可以。多数多模态模型需要图像、音频或视频占位符、文件标识及专用预处理流程,建议遵循目标模型的数据规范。

总结

选型结论:Alpaca 面向简单、独立的单轮指令;ShareGPT 面向保留上下文的多轮对话;ChatML 面向角色边界清晰、模板驱动以及工具调用或多模态扩展的训练流程。转换时应先统一中间格式,再按目标模型的 tokenizer、chat template 和损失掩码规则导出,最后通过结构、角色、模板和人工抽样完成验收。