Alpaca 格式:`instruction\ninput` 是怎么拼出用户提示词的
本文所有事实以
hiyouga/LlamaFactory官方仓库 2026-08-09 的内容为准,主要出处是data/README.md。我们没有安装、训练或部署过任何模型,文中数字与规则均为仓库文档与源码里写着的值。
先把最容易被跳过的那句原文摆出来:监督微调时,instruction 列会与 input 列拼接作为用户提示词,即用户提示词是 instruction\ninput。
这句话短,但它决定了你手上那份 JSON 最后在模型眼里长什么样。很多人纠结”这句话该放 instruction 还是放 input”,纠结半天,其实框架把两列用一个换行符接起来就送进去了。真正需要搞清楚的是:这个拼接发生在哪一层、哪些列会参与损失、以及列名是不是可以换。
第一步不是写数据,是注册数据
data/README.md 开头就写死了几条前置规则,原文对其中第一条用的措辞是”必须”:
dataset_info.json里包含所有可用数据集;使用自定义数据集时,必须在dataset_info.json里加一段 dataset description,并在训练前指定dataset: dataset_namedataset_info.json必须放在dataset_dir目录下,dataset_dir可以改成别的目录,默认值是./data- 目前支持 alpaca 与 sharegpt 两种格式
- 允许的文件类型是 json、jsonl、csv、parquet、arrow
也就是说,alpaca 格式这件事并不是”把文件放对地方就行”,而是”文件 + 一段注册描述”两件东西。作为参照,我们实读 data/dataset_info.json,里面共有 104 个数据集条目,前几个键名是 identity、alpaca_en_demo、alpaca_zh_demo、glaive_toolcall_en_demo、glaive_toolcall_zh_demo 这些——本篇要对照的样例数据集就是其中的 alpaca_en_demo.json。
顺带一提:formatting 字段的默认值就是 alpaca(可选值只有 {alpaca, sharegpt})。所以写 alpaca 数据的注册段时,formatting 那一行不写也成立;反过来,如果你哪天把数据改成 sharegpt 结构却忘了加 formatting,按文档给出的默认值,这份数据仍会被当成 alpaca 来处理。至于这种情况下运行时会不会报错、报什么错,data/README.md 没有写,我们也没有跑过,这里只能停在”默认值是什么”这一层。
四个列,各自的角色
data/README.md 里监督微调数据集的 schema 是这样写的:
[
{
"instruction": "user instruction (required)",
"input": "user input (optional)",
"output": "model response (required)",
"system": "system prompt (optional)",
"history": [
["user instruction in the first round (optional)", "model response in the first round (optional)"],
["user instruction in the second round (optional)", "model response in the second round (optional)"]
]
}
]
对应的原文规则逐条是:instruction 列会与 input 列拼接作为用户提示词,即 instruction\ninput;output 列代表模型响应;system 列若指定,会用作 system prompt;history 列是一个由字符串二元组组成的列表,表示历史消息里的 prompt-response 对。
注意括号里的 required / optional 标注:必填的只有 instruction 和 output 两个,input、system、history 都是可选。也就是说,只写 instruction 与 output 两列的数据,在这份 schema 下就是合法的——input 从来不是必须项。(我们没有核实过任何公开数据集的内容,这里说的只是 schema 允许什么。)
至于 input 为空时拼接结果具体长什么样(会不会留下一个空行、会不会被去掉),data/README.md 只给了 instruction\ninput 这一句,没有再写细则。我们没有跑过任何一次训练,也不打算替它推断,这里就停在”原文只说到这一步”。
为什么要有 input 这一列
既然两列最后会被接起来,那把所有内容都塞进 instruction、input 一律留空,得到的用户提示词也是同一个方向的东西。这样看,input 更像是给数据组织留的一个位置:指令模板放一边、每条样本变化的部分放另一边,便于批量生成和后期替换。
这是从”两列会被拼接”这条规则本身能推出来的结构性理解,不是官方给的建议。官方没有说该怎么切分这两列,我们也不给”推荐把 X 放 instruction、把 Y 放 input”这类说法——怎么切取决于你的数据是怎么来的。
列名不是硬编码的:columns 映射这一层
这是 alpaca 格式里最值得单独强调的一层。上面 JSON 里的 instruction / input / output 看着像框架写死的字段名,其实它们是 dataset_info.json 中 columns 字典的默认值。
data/README.md 的字段规格里写得很清楚:columns.prompt 默认 instruction、columns.query 默认 input、columns.response 默认 output;history、system 这些默认都是 None。
于是一份完整的注册描述长这样(原文照抄):
"dataset_name": {
"file_name": "data.json",
"columns": {
"prompt": "instruction",
"query": "input",
"response": "output",
"system": "system",
"history": "history"
}
}
读这段的正确姿势是:冒号左边是框架内部的角色名,右边是你 JSON 文件里的实际列名。 左边固定为 prompt / query / response,右边随你的数据而变。如果你手上那份数据的列叫 question 和 answer,不用改文件,把右边填成 "prompt": "question"、"response": "answer" 就行。
这一层也解释了一个常见困惑:为什么文档里一会儿说 instruction、一会儿说 prompt?因为它们是同一件事的两个面——prompt 是角色名,instruction 是这个角色的默认列名。
推理模型的 CoT 放在哪
data/README.md 对含思维链的数据给了一条明确的位置规定:对推理模型,若数据集含思维链(CoT),CoT 需要放在模型响应里,形如 <think>cot</think>output。
也就是说 CoT 不另开一列,而是写进 output 的开头。与之配套的还有一个 enable_thinking 开关,它有三种取值、行为各不相同,并且训练与推理两侧必须保持一致——那一块单独展开够写一篇,我们另有一篇专门讲,这里不铺开。
history 这一列有个反直觉的地方
history 看名字像是”给上下文用的背景材料”,但原文明确写了:监督微调时,历史里的 response 也会被模型学习(原文 the responses in the history will also be learned by the model)。
这意味着你往 history 里塞的旧回复,性质上和 output 是一类,不是只读背景。这条规则的展开我们同样另有一篇专门讲,本篇只负责提醒:填 history 之前先知道它不是免费的上下文。
Alpaca 格式还覆盖哪些数据类型
data/README.md 的 Alpaca Format 一章下面共有 7 个小节:监督微调、预训练、偏好数据集、KTO 数据集,以及图像、视频、音频三类多模态数据集。
本篇只讲监督微调这一节。其余几节里,预训练只用 text 列、偏好数据集用 chosen / rejected 且注册时必须显式写 "ranking": true(ranking 默认是 False),这些各自都有专门篇目。KTO 与三类多模态小节的正文细则不在我们的核对范围内,本文不复述。
什么时候 alpaca 不够用
判断依据只有一条,很好用:看你的数据里有没有第三种角色。
alpaca 的结构里,一轮就是”用户提示词 + 模型响应”两个位置。而 sharegpt 格式允许更多角色,例如 human、gpt、observation、function,它们以对象列表的形式放在 conversations 列里。所以只要你的数据涉及工具调用、要记录工具返回结果,alpaca 这四列就装不下了,得换 sharegpt。
两种格式的小节结构几乎一一对应(各 7 个),差别有两处可以直接核对:sharegpt 那一章多出一节 OpenAI Format;而 sharegpt 的 Pre-training 一节原文只有一句 Not yet supported, please use the alpaca format.——预训练这条路目前只有 alpaca 能走。sharegpt 的位置约束、tags 机制、OpenAI 格式怎么被表达成 sharegpt 特例,我们都另有专篇。
还有一处顺带说明的仓库内不一致:data/README.md 讲 enable_thinking 那段 TIP 里,项目名写的是带连字符的旧写法 LLaMA-Factory,而仓库当前路径是 hiyouga/LlamaFactory。仓库内新旧写法并存,如实说到这儿为止,我们不推断原因。
拼完之后还有一道长度关卡
用户提示词拼好了,不代表整条样本会被完整用上。数据侧参数里有一个 cutoff_len,实读 src/llamafactory/hparams/data_args.py,它的默认值是 2048,是这一层最常被改动的值之一。
它该设成多少,取决于你的数据长度分布和硬件,官方没给通用值,我们也不给推荐数字。这里只提醒一件事:instruction 与 input 拼接之后的长度,和这个值是同一条链路上的,改数据结构时顺手看一眼它现在是多少。
同一个文件里还有两个与”哪部分参与损失”相关的开关,train_on_prompt 默认 False、mask_history 默认 False;以及 val_size 默认 0.0,即默认不切验证集。这三个默认值和 alpaca 数据的填法直接相关,值得在动手前扫一眼。
Windows 与 Linux / macOS 的一点差别
dataset_dir 默认是 ./data。如果你要把数据放到仓库之外的目录,两个平台写法不同:
# Linux / macOS
dataset_dir: /home/<你的用户名>/<你的项目目录>/data
# Windows
dataset_dir: D:/<你的项目目录>/data
Windows 下路径分隔符改成正斜杠是 YAML 与 JSON 里避免转义麻烦的通用写法,这是路径书写的通用做法,不是 LlamaFactory 官方文档里的规定;上面两段也是按官方参数语义写的示例,未逐项实测,以官方文档与 --help 的实际输出为准。不管哪个平台,硬要求只有一条来自原文:dataset_info.json 必须放在 dataset_dir 指向的那个目录下。
出问题时按这个顺序查
如果数据没被按你预期的方式读进去,按这几个可核查的点顺着看:
dataset_info.json在不在dataset_dir下——默认是./data,改过dataset_dir就去改后的目录看- 训练配置里的
dataset有没有写,写的名字和注册段的键名是否一致——原文要求”必须”在训练前指定dataset: dataset_name formatting是什么——不写就是 alpaca;数据结构是conversations列表却没写formatting: sharegpt,就是注册描述与文件结构对不上,这一处值得优先比对columns映射的右边是不是你文件里真实的列名——左边prompt/query/response固定不变- 文件类型在不在 json、jsonl、csv、parquet、arrow 这五种里
如果这五项都对上了,问题多半不在 alpaca 格式这一层,而在 template、模型侧或训练参数上——那就是另外几篇的范围了。
以上排查顺序是按官方文档写明的约束条件排的,我们没有逐项实跑验证,最终以 llamafactory-cli train -h 的实际输出与仓库当前的 data/README.md 为准。
本文依据 LlamaFactory 官方仓库(github.com/hiyouga/LlamaFactory)的 README、data/README.md、examples/ 下的配置与 src/llamafactory/hparams/ 的参数定义整理,核对日 2026-08-09。本文内容为仓库源码与文档口径,我们没有安装、训练或部署过任何模型,文中显存数字均为官方标注的估算值(README 原文标 * estimated)而非实测占用。参数与默认值随版本变动,请以 llamafactory-cli train -h 的实际输出为准。