1. 从“聊天”到“办事”:为什么指令格式的选择如此重要?

如果你刚开始接触大模型微调,可能会被各种数据格式搞得晕头转向。Alpaca、ShareGPT、ChatML、OpenAI格式……名字一大堆,文档里列出的字段也各不相同。我刚开始的时候也犯过嘀咕:不都是“用户说一句,模型回一句”吗?搞这么复杂干嘛?直接用一种格式不就好了?

直到我在实际项目中踩了几个坑,才彻底明白:指令格式的选择,本质上是在为你的模型定义“思考模式”和“工作流程”。这绝不是简单的数据转换问题,而是决定了你的模型最终会成为什么样的“员工”。

想象一下,你要训练两个AI助手。第一个是陪你闲聊解闷的“聊天搭子”,你们可能从天气聊到电影,再聊到周末计划,话题天马行空,上下文环环相扣。第二个是帮你处理具体事务的“效率工具”,比如你命令它:“总结一下这篇文档的核心观点”,或者“把这段中文翻译成英文”。它需要精准理解你的单次指令,并给出高质量、无歧义的答复。

这两个助手需要的“训练教材”能一样吗?显然不能。前者需要学习如何在一来一往的对话中保持连贯、记住上下文、甚至理解言外之意。后者则需要学习如何精准拆解一个独立的任务指令,并给出最标准、最可靠的答案。

这就是 ShareGPT格式Alpaca格式 诞生的根本原因。它们分别对应了“多轮对话流”和“单轮任务链”这两种最核心的大模型应用范式。选对了格式,你的训练就像给模型指明了最清晰的学习路径,事半功倍。选错了,模型可能学得“四不像”,聊天时答非所问,做任务时又啰嗦冗余。

在接下来的内容里,我不会只给你干巴巴的格式定义。我会结合我大量使用 llama-factory 这个强大微调框架的实战经验,带你像老司机一样,深入理解这两种格式的“脾气秉性”。我们会看到,在llama-factory的配置里,一个简单的 formatting 参数切换,背后是整个训练目标和数据结构的根本性转变。我会告诉你,在什么业务场景下应该毫不犹豫地选择哪一种,以及如何根据你手头的数据特点,做出最明智的技术决策。

2. 深入拆解:ShareGPT格式如何塑造“对话大师”

让我们先来聊聊 ShareGPT格式。这个名字听起来就很有“群众基础”,没错,它最初正是源于用户们在网上分享的和ChatGPT等模型的真实对话记录。这些记录不是精心设计的单轮问答,而是充满跳跃、追问、澄清和话题转换的真实聊天。研究者们发现,用这种“原汁原味”的对话数据来训练模型,能极大地提升模型在多轮交互中的表现。

2.1 核心设计:模拟真实的对话回合

ShareGPT格式的核心是一个名为 conversations 的列表。列表里的每一个元素,都代表对话中的一个“回合”,并且明确标注了发言者的角色(from)和内容(value)。这是它最强大的地方:原生支持多角色、多轮次的对话结构

在llama-factory中,当你使用ShareGPT格式时,你通常会在 dataset_info.json 里这样定义:

"我的聊天数据集": {
  "file_name": "chat_data.json",
  "formatting": "sharegpt",
  "columns": {
    "messages": "conversations",
    "system": "system"
  }
}

注意那个 "formatting": "sharegpt",这就是告诉框架:“请用处理多轮对话的逻辑来解析我的数据”。

你的数据文件 chat_data.json 里,一条数据可能长这样:

{
  "conversations": [
    {"from": "human", "value": "推荐几部类似《星际穿越》的科幻电影吧。"},
    {"from": "gpt", "value": "当然!如果你喜欢《星际穿越》的硬核科幻和亲情内核,可以看看《降临》、《火星救援》和《2001太空漫游》。"},
    {"from": "human", "value": "《降临》我看过,有点烧脑。那个《火星救援》搞笑吗?"},
    {"from": "gpt", "value": "《火星救援》更偏向科学求生和乐观精神,有很多幽默桥段,不算特别搞笑但观影体验很轻松。主角用科学知识在火星上种土豆,非常有趣。"}
  ]
}

看到这个结构了吗?它完整记录了一次包含两个回合的对话。模型在学习时,会看到整个对话流。它知道在用户第一次提问后,自己给出了一个包含三部电影的列表。接着,用户针对这个回答进行了追问(提到了《降临》,并询问《火星救援》是否搞笑),模型则需要基于整个上文来生成第二次回复。这种训练方式让模型学会了跟踪对话状态、指代消解(比如“那个”指代《火星救援》)、以及话题的自然延续。

2.2 高级能力:支持函数调用与工具交互

ShareGPT格式的强大不止于基础对话。为了构建更复杂的AI助手(比如能查天气、订机票的智能体),它设计了更丰富的角色类型。除了 humangpt,还有 function_callobservation

这有什么用呢?我举个例子。你想训练一个能使用计算器的AI。对话流程可能是:用户问“123乘以456等于多少?”,AI不应该直接心算(容易错),而应该“思考”:“我需要调用计算器函数”。于是它生成一个函数调用请求。系统(或一个外部工具)执行计算后,将结果“56088”作为观察结果返回给AI。AI最后再把这个结果组织成自然语言回复给用户。

在ShareGPT格式中,这条训练数据会被这样构造:

{
  "conversations": [
    {"from": "human", "value": "123乘以456等于多少?"},
    {"from": "function_call", "value": "{\"name\": \"calculator\", \"arguments\": {\"expression\": \"123*456\"}}"},
    {"from": "observation", "value": "56088"},
    {"from": "gpt", "value": "123乘以456的结果是56088。"}
  ],
  "tools": "[{\"name\": \"calculator\", \"description\": \"执行数学计算\", \"parameters\": {...}}]"
}

关键点来了:在llama-factory的ShareGPT格式定义中,有一条重要的规则:humanobservation 必须出现在奇数位置(第1、3、5…位),gptfunction_call 必须出现在偶数位置(第2、4、6…位)。这强制定义了一个严格的“刺激-反应”交替顺序,确保了对话逻辑的严谨性,让模型清晰地学会“在什么时机该思考”、“在什么时机该说话或调用工具”。

2.3 实战场景与配置要点

那么,什么时候你应该选择ShareGPT格式呢?我的经验是,只要你的业务目标涉及连续的、上下文相关的交互,ShareGPT就是首选。

  • 智能客服机器人:用户的问题往往需要多轮澄清。例如用户说“我的订单没收到”,客服AI需要追问订单号、查询物流,再给出解决方案。这个完整的Q&A流程就是完美的ShareGPT训练数据。
  • 陪伴式聊天助手:像Character.AI或各种社交聊天机器人,对话可能长达几十轮,话题随意切换。用ShareGPT格式能最好地训练模型维持人设、记忆关键个人信息(比如用户之前提过的宠物名字)。
  • 复杂任务导向型对话:比如旅行规划助手,用户说“我想去海边度假”,助手需要连续询问预算、时间、偏好,然后推荐目的地、酒店,甚至生成行程表。这整个多轮规划对话,用ShareGPT格式封装再合适不过。

在llama-factory中配置时,一个常见的“坑”是历史对话的处理。虽然ShareGPT的 conversations 列表已经包含了历史,但llama-factory的Alpaca格式里还有一个独立的 history 字段。切记不要混淆。在ShareGPT格式下,你只需要关心 conversations 和可选的 systemtools。框架会自动从 conversations 列表中为你构建出训练时所需的上下文。你的任务就是确保数据里那些生动的、多轮的真实对话被准确、完整地记录了进来。

3. 精准打击:Alpaca格式如何练就“任务专家”

现在我们转向 Alpaca格式。如果说ShareGPT是培养社交高手的“情景剧剧本”,那Alpaca就是训练特种兵的“标准化操作手册”。它由斯坦福团队在2023年提出,初衷非常明确:用一种极其简单、低成本的方式,让大模型学会遵循各式各样的单条指令。

3.1 核心设计:指令-输入-输出的黄金三角

Alpaca格式的结构清晰得令人感动,主要就是三个字段:

  • instruction: 用户发出的核心指令。例如“将以下句子翻译成法语”。
  • input: 指令所作用的具体内容(可选)。接上例,这里就是“Hello, world!”。
  • output: 模型应该给出的正确回答。即“Bonjour le monde!”。

在llama-factory中,对应的 dataset_info.json 配置会是这样:

"我的任务数据集": {
  "file_name": "task_data.json",
  "columns": {
    "prompt": "instruction",
    "query": "input",
    "response": "output",
    "system": "system",
    "history": "history"
  }
}

注意,这里没有 "formatting": "sharegpt"。默认就是Alpaca格式(或称为标准指令格式)。prompt 映射到 instructionquery 映射到 inputresponse 映射到 output,一目了然。

一条典型的数据如下:

{
  "instruction": "总结以下文章的核心观点。",
  "input": "人工智能近年来发展迅速,在图像识别、自然语言处理等领域取得突破。但其发展也引发了对就业、伦理和安全问题的广泛讨论。文章认为,需要在推动技术创新的同时,建立相应的治理框架。",
  "output": "文章核心观点是:人工智能技术发展迅猛且成就显著,但同时也带来了就业、伦理和安全等挑战,因此有必要在鼓励创新的同时,构建与之配套的治理体系。"
}

这种格式的魅力在于它的专注性。模型在训练时,看到的就是一个明确的“任务包”:指令是什么,输入是什么,期望的输出是什么。它不需要分心去理解复杂的对话历史,它的全部目标就是学会从 instruction(和 input)到 output 的映射关系。这非常适合培养模型在特定任务上的精确度和可靠性。

3.2 灵活扩展:系统提示与历史上下文

虽然Alpaca格式主打单轮任务,但llama-factory对其做了非常实用的扩展,使其能适应更复杂的场景,而无需切换到ShareGPT格式。

  • system字段: 你可以在这里设定AI的角色。比如 system: “你是一位严谨的学术翻译助手,只提供精准的翻译,不添加任何额外解释。” 这个系统提示会作用于后续所有的 instruction,让模型的行为更具可控性。
  • history字段: 这是一个非常关键的设计。它允许你为当前任务提供“对话历史”,但其目的与ShareGPT有本质不同。在Alpaca格式下,history 的主要作用是为当前的单轮任务提供必要的背景信息,而不是训练多轮对话能力。

举个例子,一个客服场景:

{
  "system": "你是某电商平台的客服助手。",
  "history": [
    ["用户:我的订单#12345还没发货。", "客服:抱歉给您带来不便,我立刻为您查询。"],
    ["用户:已经超过48小时了。", "客服:理解您的焦急,查询需要一点时间,请稍等。"]
  ],
  "instruction": "根据以上对话,告知用户最新的物流状态。",
  "input": "经查询,订单#12345已于今天上午10点发出,物流公司是XX速运,运单号是SF123456789。",
  "output": "您好!让您久等了。您关心的订单#12345的最新状态是:已于今天上午10点正式发货,由XX速运承运,运单号为SF123456789。您可以凭此单号在官网跟踪物流信息。"
}

在这里,history 提供了本次查询的上下文(用户催单),instruction 给出了当前轮的具体任务(告知物流状态),input 甚至提供了后台查询到的原始信息。模型需要学习的,是如何基于这些信息,组织成一段友好、专业的客服回复。重点在于完成“告知状态”这个当前任务,而不是学习如何与用户进行多轮闲聊。这就是Alpaca格式下 history 的典型用法。

3.3 实战场景与配置要点

Alpaca格式是你的“瑞士军刀”,适用于几乎所有明确的、独立的、以结果为导向的任务

  • 文本转换类任务:翻译、总结、润色、扩写、风格转换。每条数据都是独立的指令-输出对。
  • 信息提取与问答:从给定文本中提取实体、回答基于文档的事实性问题。input 里放文档,instruction 里放问题。
  • 代码生成与解释:“用Python写一个快速排序函数”或“解释下面这段代码的功能”。
  • 结构化输出:“将以下产品描述转换为JSON格式,包含字段:名称、价格、颜色。”

在llama-factory中使用Alpaca格式,最需要注意的就是 prompt 模板的构建。框架在训练时,会将 instructioninput 用换行符拼接起来,作为最终的用户输入。这意味着你在设计 instruction 时,要考虑到它和 input 拼接后的可读性。例如,instruction 写成“翻译:”,input 放待翻译文本,这样拼接起来就是“翻译:\nHello”,非常自然。

另一个优势是数据构造简单。你不需要费力去爬取或构造多轮对话,很多时候,利用GPT-4等高级模型,按照“指令-输出”的格式批量生成训练数据(Self-Instruct),成本低、效率高。这正是Alpaca项目当初成功的秘诀。

4. 决策指南:在llama-factory中根据业务目标做选择

理论讲完了,现在我们来点实在的。面对一个具体的项目,我到底该怎么选?下面这个基于llama-factory实战经验的决策流程图,或许能帮你快速理清思路。

首先,问自己两个最核心的问题:

  1. 我的模型需要处理连续的、上下文依赖的多轮对话吗?
  2. 我的主要目标是让模型完成一个个独立、明确的指令任务吗?

根据答案,你可以遵循以下路径:

场景A:我要构建聊天机器人、客服系统或任何需要多轮交互的AI。

  • 数据特征:你的数据天然就是多轮的,每一条记录都是一次完整的、有来有往的对话。
  • 格式选择毫不犹豫地选择ShareGPT格式
  • llama-factory配置关键
    • dataset_info.json 中,为你数据集设置 "formatting": "sharegpt"
    • 确保你的数据文件里,conversations 列表中的角色顺序严格遵守 human/observation(奇)和 gpt/function_call(偶)的规则。
    • 如果你的对话需要系统角色设定或工具调用,别忘了填写 systemtools 字段。
    • 在训练脚本或Web UI中,选择对应的数据集名称即可。llama-factory会自动识别ShareGPT格式,并采用适合对话的训练数据加载器。

场景B:我要开发翻译助手、总结工具、代码生成器等任务型AI。

  • 数据特征:你的数据由大量独立的“任务指令”和“标准答案”组成。即使有上下文,也是作为当前任务的背景信息提供。
  • 格式选择Alpaca格式是你的最佳拍档
  • llama-factory配置关键
    • dataset_info.json 中,无需设置 formatting 参数,或设置为默认。正确映射 prompt, query, response 等字段。
    • 善用 system 字段来固定模型的行为风格(如“你是一位专业的翻译家”)。
    • 如果需要上下文,使用 history 字段,但明确其作用是提供背景,而非训练对话流。
    • 检查你的 instruction 是否清晰、无歧义,能够与 input 良好拼接。

场景C:我的数据有点混合,既有简单任务,也有多轮对话。 这是实践中常遇到的情况。我的建议是:不要强行混合。尽量将你的数据拆分。

  • 将清晰的多轮对话数据整理成ShareGPT格式,放入一个数据集(如 my_chat_data)。
  • 将独立的指令任务数据整理成Alpaca格式,放入另一个数据集(如 my_task_data)。
  • 在llama-factory中,你可以在单次训练中混合多个数据集。这是llama-factory一个非常强大的功能。你可以在配置文件中指定:
    "dataset": "my_chat_data,my_task_data"
    
    或者设置不同的采样比例:
    "dataset": "my_chat_data+my_task_data"
    
    框架会按照比例从两个数据集中抽取样本进行训练。这样,你就能训练出一个既会聊天又能干活的“全能型”助手,同时保证了每种数据都能以最合适的格式被模型学习。

5. 超越基础:格式选择对高级训练策略的影响

指令格式的选择,不仅影响基础的监督微调,还直接关系到你是否能顺利实施更高级的训练策略,比如直接偏好优化(DPO)、KTO等。在llama-factory中,不同格式下,这些数据集的构造方式也有差异。

5.1 偏好学习(DPO/ORPO)的数据准备

无论是Alpaca还是ShareGPT格式,偏好学习都需要你提供“好答案”(chosen)和“坏答案”(rejected)。但它们的组织方式不同。

  • Alpaca格式下的偏好数据: 结构非常直观。你有一条标准的Alpaca数据(instruction, input),然后为它配上一个优质回答和一个劣质回答。

    {
      "instruction": "如何泡一杯好茶?",
      "input": "",
      "chosen": "泡一杯好茶需要注意水温、茶具和冲泡时间。例如泡绿茶,建议用80-85℃的水,玻璃杯冲泡,浸泡1-2分钟即可,避免闷泡导致苦涩。",
      "rejected": "把茶叶扔进杯子里,倒上开水就行了,很简单。"
    }
    

    dataset_info.json 中,你需要设置 "ranking": true,并映射 chosenrejected 字段。

  • ShareGPT格式下的偏好数据: 这里就体现出其对话结构的特性了。conversations 字段里存放的是对话上下文(可能有多轮),而 chosenrejected 则是针对最后一轮用户输入,模型给出的两种不同回答。

    {
      "conversations": [
        {"from": "human", "value": "我喜欢喝绿茶,但总觉得有点苦。"},
        {"from": "gpt", "value": "绿茶苦涩可能是水温太高或浸泡时间太长导致的。试试降低水温到80℃左右,并缩短冲泡时间。"},
        {"from": "human", "value": "具体应该泡多久呢?"}
      ],
      "chosen": {
        "from": "gpt",
        "value": "对于大多数绿茶,第一泡建议在30秒到1分钟之间。您可以先尝试45秒,然后根据茶汤颜色和口味调整下一泡的时间。记住,快出汤是泡好绿茶的关键。"
      },
      "rejected": {
        "from": "gpt",
        "value": "泡多久都行,看你自己喜欢。一般几分钟吧。"
      }
    }
    

    注意,chosenrejected 本身也是一个包含 fromvalue 的对象,这保持了ShareGPT格式的角色一致性。在配置时,同样需要 "formatting": "sharegpt""ranking": true

选择影响:如果你的偏好数据是基于多轮对话上下文产生的(例如,在复杂的客服对话中,某个回复比另一个更得体),那么使用ShareGPT格式能更好地保留上下文信息,让奖励模型或DPO算法更准确地判断优劣。如果是针对独立指令的偏好(比如两个不同的翻译结果),Alpaca格式更简洁高效。

5.2 KTO(知识迁移优化)的数据准备

KTO要求对单个回答给出“好”(true)或“坏”(false)的标签。其格式差异与偏好学习类似。

  • Alpaca格式:在标准结构上增加一个 kto_tag 字段,值为布尔值。
  • ShareGPT格式:同样,在对话数据的基础上,增加 kto_tag 来标注最后一轮模型回答的质量。

关键点:KTO数据集的构造,强烈依赖于你希望模型强化的行为模式。例如,在Alpaca格式下,你可以给所有符合“简洁、准确”要求的 output 打上 true,给那些冗长、包含无关信息的 output 打上 false。在ShareGPT格式下,你可以给那些有效推进对话、解决用户问题的回复打 true,给那些敷衍、偏离主题的回复打 false。格式的选择,让你能针对“任务完成度”或“对话质量”进行精准优化。

5.3 多模态数据集的准备

当你的任务涉及图像理解时,llama-factory也支持多模态数据。无论是Alpaca还是ShareGPT格式,核心都是增加一个 images 字段,指向图像文件路径。

  • Alpaca格式示例
    {
      "instruction": "描述这张图片中的主要内容。",
      "images": ["path/to/image.jpg"],
      "output": "图片中有一只金色的拉布拉多犬在绿色的草坪上追逐一个飞盘。"
    }
    
  • ShareGPT格式示例
    {
      "conversations": [
        {"from": "human", "value": "图片里是什么?", "images": ["path/to/image.jpg"]},
        {"from": "gpt", "value": "这是一只可爱的拉布拉多犬在玩飞盘。"}
      ]
    }
    
    在ShareGPT格式中,images 可以放在 human 消息里,表示用户随消息上传了图片。

格式选择的影响:如果你的多模态交互是“用户上传图片并提问,模型回答”这种单轮模式,Alpaca格式足够。但如果是一个围绕图片展开的多轮对话(例如:用户问“图片里有什么?”,模型答“一只狗”,用户再问“什么品种?”),那么ShareGPT格式才能完整地保留这个对话流程,训练出能理解基于图像的连续对话的模型。

6. 避坑实践:llama-factory中的常见配置陷阱与解决方案

纸上得来终觉浅,绝知此事要躬行。在llama-factory里实际配置数据集时,我踩过不少坑,这里分享几个最常见的,希望能帮你省下大量调试时间。

陷阱一:角色顺序错乱导致训练失败

  • 问题:在使用ShareGPT格式时,报错提示“角色位置无效”或训练时损失异常。
  • 原因:没有遵守 human/observation(奇数位)和 gpt/function_call(偶数位)的强制顺序。比如以 gpt 开头,或者两个 human 连续出现。
  • 解决:写一个简单的数据校验脚本,在训练前遍历你的 conversations 列表,检查每个索引位置的角色是否符合规定。llama-factory在数据加载时也会检查,但提前自查更稳妥。

陷阱二:Alpaca格式中history字段使用不当

  • 问题:模型在推理时,似乎“忘记”了历史信息,或者把历史信息当成了当前指令的一部分。
  • 原因:误解了Alpaca格式下 history 的用途。它并非用于训练多轮对话能力,而是为当前单轮任务提供静态背景。在训练时,history 中的内容(包括AI的历史回复)会被拼接到输入中,但模型只会学习生成当前轮的 output。它不会去学习如何生成 history 里那些过去的回复。
  • 解决:明确你的目标。如果你需要真正的多轮对话生成能力,请将数据转换为ShareGPT格式。如果只是需要背景信息,那么确保 history 里的内容是完成当前任务所必需的上下文,并且 instruction 清晰地指明了基于历史要做什么(例如:“基于之前的对话,回答用户的最新问题”)。

陷阱三:dataset_info.json 配置映射错误

  • 问题:训练时提示“找不到某列”或数据加载为空。
  • 原因dataset_info.json 中的 columns 映射关系写错了。比如你的数据文件里叫 "question",但配置里映射成了 "prompt": "instruction"
  • 解决:仔细核对。file_name 指向的文件里的字段名是什么,columns 里的值就应该是什么。一个实用的技巧是,先用Python加载你的数据文件,打印出一条样本的键名,再对照着写配置。

陷阱四:混合训练时数据比例失衡

  • 问题:混合了ShareGPT(对话)和Alpaca(任务)数据训练后,模型表现“精神分裂”,有时话痨,有时又过于简短。
  • 原因:两种数据集的采样比例不合适。如果对话数据太多,模型会偏向于生成开放式的、多轮的回应;如果任务数据太多,模型在聊天时可能显得生硬、机械。
  • 解决:利用llama-factory的数据集混合语法进行精细控制。例如 "dataset": "chat_data:2+task_data:1" 表示每采样3条数据,其中2条来自 chat_data,1条来自 task_data。你需要根据你的业务侧重(是更偏聊天还是更偏任务)来调整这个比例,并通过验证集上的表现来确定最佳配比。

陷阱五:忽略系统提示词(system prompt)的威力

  • 问题:模型行为不稳定,时而正式时而随意。
  • 原因:没有有效利用 system 字段。系统提示词是塑造模型“人设”和行为的强大工具。
  • 解决:无论在哪种格式下,都认真设计 system 提示词。对于Alpaca格式,一个清晰的 system 可以让模型在所有任务上保持风格一致。对于ShareGPT格式,你甚至可以为不同类型的对话设置不同的 system(例如,客服对话用一套,闲聊用另一套),并在数据中体现出来。在llama-factory中,确保 system 字段被正确映射和加载。

说到底,选择ShareGPT还是Alpaca,不是一个非此即彼的技术判断题,而是一个面向业务目标的战略决策。理解它们背后的设计哲学——一个服务于流畅的对话流,一个专注于精准的任务链——你就能在llama-factory这个强大的工坊里,为你心中的AI助手挑选最合适的“成长蓝图”。当你看着模型按照你预期的格式,一步步学会聊天或执行任务时,那种感觉,就像一位工匠终于找到了最称手的工具。

更多推荐