8 × 6 全打勾的训练方法矩阵:这张满表能读出什么、不能读出什么

2026-08-09

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

LlamaFactory 的 README 里有一张 Supported Training Approaches 表:8 行训练阶段乘 6 列微调方式,48 个格子全是 ✅。我不打算把这张表原样贴过来——一张全是对勾的表,贴出来的信息量正好等于零。真正值得花时间的是另一件事:「全勾」这个声明到底承诺了什么,以及它明确没承诺什么。

先把两个维度说清楚

这张矩阵的行是 8 种训练阶段:Pre-Training、Supervised Fine-Tuning、Reward Modeling、PPO Training、DPO Training、KTO Training、ORPO Training、SimPO Training。

列是 6 种微调方式:Full-tuning、Freeze-tuning、LoRA、QLoRA、OFT、QOFT。

这两个维度回答的是完全不同的两个问题。行回答「你要拿这批数据做什么事」——是继续喂原始语料做续训,还是喂指令对做监督微调,还是喂偏好对做对齐。列回答「你打算动模型的多少参数、以什么精度动」——全参、冻结大部分、挂低秩适配器,以及带量化的那几档。

它们正交,所以理论上可以两两组合,这就是那张 48 格满表的由来。README 在表下还挂了一条 TIP,说 PPO 的实现细节可参考 https://newfacade.github.io/notes-on-reinforcement-learning/17-ppo-trl.html 这篇外部笔记。

「满」这个字的准确边界

这里是最容易读歪的地方,值得一字一句地说。

那 48 个 ✅ 是一条声明:README 声明所有训练阶段与所有微调方式都两两可组合。它不是一条性能承诺,也不是一份测试覆盖率报告。

具体说,从这张表读不出下面三件事:

  • 读不出任意一个组合与另一个组合同样好用
  • 读不出它们同样稳定
  • 读不出它们都被同等程度地测试过

我们没有跑过其中任何一格,手上也没有任何一份把 48 格逐个验证过的记录。所以这篇只到「表是满的」为止,往下的判断得靠别的证据。

好在仓库里确实有几处旁证,可以看,也可以核。

旁证一:train/ 目录只有六个阶段,不是八个

实读 src/llamafactory/train/,阶段相关的子目录是这几个:

src/llamafactory/train/
  pt/                预训练
  sft/               监督微调
  rm/                奖励建模
  ppo/               PPO
  dpo/               DPO
  kto/               KTO
  mca/               Megatron-core adapter 相关
  megatron_bridge/   Megatron bridge 相关
  hyper_parallel/    并行相关
  callbacks.py  fp8_utils.py  test_utils.py  trainer_utils.py  tuner.py

矩阵有 8 行,这里只有 pt / sft / rm / ppo / dpo / kto 六个阶段目录,没有 orpo,也没有 simpo

对上 finetuning_args.py 里的字段就能看明白这个差额落在哪儿:那里有 pref_loss(默认 "sigmoid")和 simpo_gamma(默认 0.5)。也就是说,ORPO 与 SimPO 是通过偏好损失相关的参数在 DPO 训练器里表达的,而不是各自独立的阶段目录。这个结论是从目录结构和参数命名两边共同读出来的,不是猜的。

它们各自的算法细节、损失公式、彼此的效果差异,我们没有读过实现代码,这篇不写。

对你的实际影响很直接:当你在矩阵上看到「ORPO Training」这一行,别指望在 train/ 下翻到一个同名目录;按目录结构和参数命名共同给出的线索,该去偏好损失那一组参数(pref_loss / simpo_gamma)里找。这两个名字在哪一层、还牵动什么,我们另有一篇专门讲。

旁证二:examples/ 的配方章节,分布是不对称的

examples/README.md 的章节结构同样可以实读。按微调方式分栏看,配方的铺开程度并不一样:

LoRA Fine-Tuning 这一栏,阶段维度基本铺满了:(持续)预训练、监督微调、多模态监督微调、DPO/ORPO/SimPO 训练、多模态 DPO/ORPO/SimPO 训练、奖励建模、KTO 训练,另外还有预处理数据集、多节点、DeepSpeed ZeRO-3、Ray 四卡这些工程向的条目。

QLoRA Fine-Tuning 这一栏,列出的条目全部是量化路线下的监督微调:4/8-bit Bitsandbytes/HQQ/EETQ、Ascend NPU 上的 4-bit Bitsandbytes、4/8-bit GPTQ、4-bit AWQ、2-bit AQLM。

Full-Parameter Fine-Tuning 这一栏是单节点监督微调、多节点监督微调、多节点弹性容错监督微调、多模态监督微调。

对应到目录,examples/train_lora/ 下有 12 个文件,其中 qwen3_lora_pretrain.yamlqwen3_lora_sft.yamlqwen3_lora_dpo.yamlqwen3_lora_kto.yamlqwen3_lora_reward.yaml 正好把几个阶段各摆了一份。

把这两处放在一起看:README 的矩阵是 48 格全勾,examples/README.md 的配方章节在阶段维度上只有 LoRA 那一栏铺开了。**这是两处文档之间可核实的分布差异,我如实说到这儿。**为什么这样安排、是不是别的组合也有现成配置只是没写进章节里,我没有核实过,不推断,也不拿它去评价这个项目。

顺带一个精确的小事实:整份配方清单里,README 只在「4/8-bit Bitsandbytes/HQQ/EETQ 量化下的监督微调」这一条上标了 (Recommended),GPTQ / AWQ / AQLM 那几条都没有这个标注。这是仓库自己给出的取向,比 48 个一模一样的对勾信息量高。

旁证三:矩阵里没有的第三维——template

这张表只有阶段和微调方式两维,但真正决定你能不能跑通、跑出来的东西对不对,还有一个不在表上的必填项:template

README 在模型表下面给了几条硬规则,跟矩阵直接相关的是这几条:

  • base 模型,template 可以从 defaultalpacavicuna 之类里选;对 instruct/chat 模型,务必用对应的 template;
  • 模型同时有推理版与非推理版时,用 _nothink 后缀区分,例如 qwen3qwen3_nothink
  • 训练与推理必须用同一个 template(README 原文用了全大写的 SAME)。

这条 SAME 规则的分量,在示例配置里能看得很实:examples/train_lora/qwen3_lora_sft.yaml 写的是 template: qwen3_nothinkexamples/inference/qwen3_lora_sft.yaml 只有五行,其中一行同样是 template: qwen3_nothinkexamples/merge_lora/qwen3_lora_sft.yaml 里还是这一行。三份配置在这个字段上严格对齐。

所以矩阵那 48 格,任意一格选定之后,template 这一维仍然要你自己对。选错了,48 格里哪一格都救不回来。完整模型清单在 src/llamafactory/extras/constants.py,自定义 chat template 加到 src/llamafactory/data/template.py——README 给的就是这两个位置。至于那张 53 行的模型表怎么读、_nothink 具体出现在哪几处,我们另有一篇专门讲。

矩阵也不承担代价:那张显存表

第四件这张表读不出来的事,是代价。Full-tuning 和 LoRA 在矩阵里长得一模一样,都是一个 ✅,但 README 另有一张表说明它们的资源量级不是一回事。

这张 Hardware Requirement 表,表头上方它自己标了 * estimated(估算)。这一点必须带着:那不是实测占用,是官方标注的估算值,我们也没有跑过任何一次训练。

只取跟矩阵列头直接相关的那两行:7B 这一列上,Full(bf16fp16,32)标 120GB,Freeze/LoRA/GaLore/APOLLO/BAdam/OFT(16)标 16GB,两者相差 7.5 倍。要引用这个 7.5 倍,就得同时说清它是估算表内部的比值,而不是「你的卡够不够」的结论——那个结论我不给,这张表也给不了。

那张表里还有一处可核实的不一致:通用列给的线性系数是 18x / 8x / 2x / x / x/2 / x/4,而 2-bit 那一行的 70B 写的是 24GB,按 x/4 算不是这个数。**两处对不上,以仓库当前状态为准。**哪个数是对的、为什么会这样,我没有核实过,不推断。

那么,48 格里的默认落点在哪一格

这个仓库自己是给了倾向的,写在源码默认值里:finetuning_args.pystage 的默认值是 "sft"finetuning_type 的默认值是 "lora"

对到矩阵上,就是「Supervised Fine-Tuning 行 × LoRA 列」这一格。examples/train_lora/qwen3_lora_sft.yaml 也正落在这一格上,它的 ### method 块五行写的是 stage: sftdo_train: truefinetuning_type: loralora_rank: 8lora_target: all

这里要说清楚性质:默认值只说明「你什么都不填时它走哪条路」,不说明这条路对你的数据最合适。lora_rank 该设多少、cutoff_len 该留多长,取决于你的数据和硬件,官方没有给通用值,我也不编一个。

从格子落到命令,中间还有一步

选好格子之后要真跑起来,README 抬到 Quickstart 位置的是这三条命令,覆盖训练、推理、合并导出的完整闭环:

llamafactory-cli train examples/train_lora/qwen3_lora_sft.yaml
llamafactory-cli chat examples/inference/qwen3_lora_sft.yaml
llamafactory-cli export examples/merge_lora/qwen3_lora_sft.yaml

这三条命令用的三份 YAML,逐行对照下来是严格对齐的:同一个基座、同一个 template,训练侧的 output_dir 就是推理与合并侧的 adapter_name_or_path。也就是说,矩阵里选中的那一格,最后是落到三份配置的同一组字段上的,而不是只落在训练那一条命令里。这三份配置怎么逐行串起来,我们另有一篇专门讲。

另外,如果你的格子落在 QLoRA 列并且之后要走合并导出,examples/merge_lora/qwen3_lora_sft.yaml 首行那句全大写的注释得原样记住:

### Note: DO NOT use quantized model or quantization_bit when merging lora adapters

这是一条禁令,不是建议。

这张表适合用来干什么

按用途分,它有一个很实在的作用,也有一个常被误用的方向。

适合:确认你想做的那件事(比如「用 QLoRA 做 KTO」)在这个项目的声明范围之内,不用先去翻别的仓库。这正是一张能力矩阵该干的活。

不适合:拿它当选型依据。选哪一列,实际是被显存表那一栏、被你有没有偏好数据、被你的推理侧能不能接住产物一起决定的;选哪一行,是被你手上数据的形态决定的。这些维度矩阵上一个都没有。

换句话说,48 个对勾告诉你「路是通的」,至于哪条路是你该走的那条,得去 examples/ 的配方清单、显存表和你自己的数据里找答案。


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

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