LlamaFactory 预训练数据:只用 `text` 列,以及 sharegpt 为什么不支持预训练

2026-08-09

本文所有事实以 hiyouga/LlamaFactory 官方仓库 2026-08-09 的内容为准,主要来源是 data/README.md。我们没有安装、训练或部署过任何模型,文中数字均为仓库文档与源码里写着的值。

data/README.md 全文 475 行,其中预训练数据那一节短得有点反差:数据本体是 [{"text": "document"}],dataset description 是一行 "columns": { "prompt": "text" },规则原文只有一句——预训练时只用 text 列参与学习。

而在 sharegpt 那一侧,同名的 ### Pre-training Dataset 小节内容更短,只有一句 Not yet supported, please use the alpaca format.

这两处放在一起看,就是这篇要讲的全部:一个格式简单到几乎不用学,另一个格式明确写着这条路走不通。麻烦的是,很多人手上现成的语料恰好是对话形态的,第一反应就是往 sharegpt 上套,然后卡在这句英文上。

预训练数据到底长什么样

data/README.md 的 Alpaca 格式里,Pre-training Dataset 一节给的示例数据集是 c4_demo.jsonl,数据结构原文照抄:

[
  {"text": "document"},
  {"text": "document"}
]

一条样本一个对象,对象里只有一个 text 键,值是一整篇文档。没有 instruction、没有 input、没有 output,也没有角色。

对应的 dataset description 是这样写的:

"columns": { "prompt": "text" }

这里有一个第一次写会愣一下的地方:预训练根本没有”提示词”这个概念,但 dataset description 里用的键仍然叫 prompt。原因是 columns 是所有格式共用的一套映射键,prompt 这个键的默认值是 instruction(见 data/README.md 的字段规格),预训练场景就是把它重新指向你自己文件里的那个文本列。所以如果你的文件里列名不叫 text 而叫别的,改的是 "prompt" 后面那个值,不是键名本身。

columns 的完整字段有十几个,我们另有一篇专门讲 dataset_info.json 的全字段规格,这篇只用到 prompt 这一行。

注册这一步没有捷径

数据文件本身写对了,训练还是可能读不到,因为 data/README.md 开头的总规则是硬性的:

  • dataset_info.json 包含所有可用数据集,使用自定义数据集时必须在里面加一段 dataset description,并在训练前指定 dataset: dataset_name
  • dataset_info.json 必须放在 dataset_dir 目录下;dataset_dir 可以改,默认值是 ./data
  • 目前支持 alpacasharegpt 两种格式
  • 允许的文件类型是 json、jsonl、csv、parquet、arrow 这五种

我们实读了 data/dataset_info.json,里面共有 104 个数据集条目。也就是说这个文件不是给你留白的空壳,你是往一份已经有内容的清单里追加一段。

预训练语料另有一个和 SFT 数据不太一样的现实:体量通常大得多,未必愿意先落到本地。这时候要注意四个数据来源字段之间存在明确的优先级覆盖链,规格原文的括号说明是这么写的:

  • 指定了 hf_hub_urlms_hub_url,就忽略 script_urlfile_namecloud_file_name
  • 指定了 script_url,就忽略 file_namecloud_file_name
  • 指定了 cloud_file_name,就忽略 file_name
  • 以上都没指定时,file_name必填

这条链和本篇直接相关的原因是:预训练语料放 hub 或者放 s3/gcs 都很常见,一旦你在同一段描述里既写了 hub 地址又留着早先调试用的 file_name,按规格生效的是前者,file_name 会被”忽略”。规格原文用的就是 ignore 这个词,至于会不会有任何提示,文档里没写,我们也没跑过,不替它下结论。你能做的判定动作是:发现自己改了本地文件却毫无变化时,回头把这一段描述从上往下过一遍,看有没有更高优先级的字段还留着。

下载源切换:Windows 侧的写法不一样

顺着上面这条链再往下走一步。README 另有一节讲模型与数据集的下载来源切换,用的是环境变量,不是 dataset description 里的字段——也就是说它和你这段 JSON 是两回事,别指望在 dataset_info.json 里配。

Hugging Face 下载有问题时,README 给的是 ModelScope Hub:

# Linux / macOS
export USE_MODELSCOPE_HUB=1
:: Windows
set USE_MODELSCOPE_HUB=1

另一个是 Modelers Hub,同一套写法,变量换成 USE_OPENMIND_HUB=1(Windows 侧同样是 set USE_OPENMIND_HUB=1)。以上为按官方参数语义组合的示例,未逐项实测,以官方文档与 --help 的实际输出为准。

sharegpt 那句 “Not yet supported” 该怎么理解

data/README.md 的章节结构我们逐节读过一遍,两种格式的小节几乎一一对应,各有 7 个:Supervised Fine-Tuning Dataset、Pre-training Dataset、Preference Dataset、KTO Dataset,以及图像 / 视频 / 音频三个多模态小节。差别只有两处:sharegpt 多了一节 OpenAI Format,以及 sharegpt 的 Pre-training Dataset 那一节写的是尚不支持、请改用 alpaca 格式。

结构上对齐、内容上留白,这是仓库当前的状态,如实说到这儿就够了。为什么没实现、后续会不会实现、是不是有技术上的取舍,我们没有依据,不做推断。

不过从两种格式各自的规则原文里,可以看出它们要求的东西确实不是一回事:

sharegpt 格式的核心是 conversations 列里的一个对象列表,它比 alpaca 允许更多角色——human、gpt、observation、function。而且原文给了两条硬约束:human 与 observation 必须出现在奇数位置,gpt 与 function 必须出现在偶数位置;学习范围上,gpt 和 function 会被模型学习。也就是说这个格式从定义上就是围绕”谁在说话、哪一部分算模型该学的”组织的。

预训练那一侧的规则则是”只用 text 列”。一整块连续文本,没有轮次,也没有”这段算用户、那段算模型”的划分。

把这两段规则并排看,你至少能得到一个可操作的判断:当你手上的数据本来就是带角色的对话,而你想做的又是继续预训练,那它落在 sharegpt 支持范围之外这件事不是配置写错,改 formatting 也绕不过去——formatting 的取值只能从 {alpaca, sharegpt} 里选,默认是 alpaca

OpenAI 格式的语料算不算例外

不算,而且这一点值得单独点一下,因为很容易被绕进去。

data/README.md 对 OpenAI 格式的定位原文是:openai 格式只是 sharegpt 格式的一个特例,其中第一条消息可以是 system prompt。它对应的 dataset description 里,formatting 填的仍然是 sharegpt,只是通过 tagsrole_tag 从默认的 from 改成 rolecontent_tagvalue 改成 contentuser_taghuman 改成 userassistant_taggpt 改成 assistant

顺带一提,tags 这一组字段在规格里明确标注是只用于 sharegpt 格式的。

所以如果你的语料是 OpenAI 那种 messages 数组,它在这套体系里的身份就是 sharegpt,前面那句”尚不支持预训练”同样适用。

那能不能自己把对话拼成一段连续文本、落成 text 列,走 alpaca 的预训练路径?格式上当然是能落成 [{"text": "..."}] 的,但怎么拼——要不要保留角色前缀、system prompt 放不放进去、多轮之间用什么分隔——data/README.md 里没有给做法,我们也不替它发明一套。这一步属于你自己的数据工程,做完之后它在 LlamaFactory 眼里就是一份普通的 alpaca 预训练数据。

和预训练相关的几个默认值

src/llamafactory/hparams/data_args.py 里有二十多个数据侧参数,各有专篇在讲,这里只挑与”喂一批预训练语料”直接相关的几个,全部为实读默认值:

参数默认值与本篇的关系
dataset_dir"data"dataset_info.json 必须待在这个目录下
cutoff_len2048数据侧最常被改的一个值
packingNone与序列打包相关的开关
neat_packingFalse同上
streamingFalse大语料不想全量落盘时会碰到
buffer_size16384与流式读取配套
mix_strategy"concat"多数据集混合方式
interleave_probsNone同上
max_samplesNone取多少条
val_size0.0默认不切验证集
tokenized_pathNone预处理产物的落点

这张表只回答”叫什么、默认是多少”。cutoff_len 该设多大、要不要开 packingval_size 切多少合适,取决于你的语料和硬件,官方没有给通用值,我们也不给。

其中 val_size 默认 0.0 这一格值得多看一眼:默认状态下是不切验证集的。这不是问题,只是一个你需要知道自己处在什么状态的默认值。

什么情况下说明你要的其实不是预训练

最后补一个反向判据,省得白改一遍数据。

如果你真正想要的是”让模型按某种格式回答""学会调用工具""在多轮里保持某种口吻”,那对应的是监督微调,不是预训练。data/README.md 的 SFT 一节给的规则完全是另一套:alpaca 侧 instruction 列会与 input 列拼接作为用户提示词(即 instruction\ninput),output 列是模型响应,history 列里那些历史轮次的 response 也会被模型学习;对推理模型,思维链要放进模型响应里,形如 <think>cot</think>output。这些规则连同 enable_thinking 的三态行为,data/README.md 都是放在监督微调的语境里写的,我们另有一篇专门讲。

判断方法很直白:你的目标能不能表述成”给定输入应该输出什么”。能,那是 SFT,走 alpaca 或 sharegpt 都行;不能,只是想让模型多见一些某个领域的文本,那才是预训练,那就老老实实把语料整理成一列 text


本文依据 LlamaFactory 官方仓库(github.com/hiyouga/LlamaFactory)的 README、data/README.mdexamples/ 下的配置与 src/llamafactory/hparams/ 的参数定义整理,核对日 2026-08-09。本文内容为仓库源码与文档口径,我们没有安装、训练或部署过任何模型,文中显存数字均为官方标注的估算值(README 原文标 * estimated)而非实测占用。参数与默认值随版本变动,请以 llamafactory-cli train -h 的实际输出为准。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。