OFT 与 QOFT:三个参数与它们在训练矩阵里的位置
本文所有事实以
hiyouga/LlamaFactory官方仓库 2026-08-09 的内容为准。我们没有安装、训练或部署过任何模型,文中数字均为仓库源码与文档里写着的值。
大多数人读 LlamaFactory 的 README,会在训练方法矩阵那张表上停一下:列头有六个,Full-tuning、Freeze-tuning、LoRA、QLoRA、OFT、QOFT。前四个大家都眼熟,后两个是什么?这篇不解释 OFT 这个方法本身——我们没有读过它的实现,也没有跑过任何一次训练,凭印象讲算法就是编。这篇只回答三个可以核实的问题:参数叫什么、默认值是多少、它们在配置的哪一层。
先把三个参数钉住
src/llamafactory/hparams/finetuning_args.py 里,OFT 这一组只有三个字段:
| 参数 | 默认值 |
|---|---|
oft_rank | 0 |
oft_block_size | 32 |
oft_target | "all" |
看完这张表,最该被记住的是 oft_rank 的默认值是 0。
放在同一个文件里对照就更明显:LoRA 那一组的 lora_rank 默认是 8,lora_target 默认是 "all"。也就是说,同样叫 rank 的字段,LoRA 侧给了一个非零的具体值,OFT 侧给的是 0。
这里必须停住。0 在这段代码里意味着”不启用”、“由别处推导”、还是别的什么,我们没有读过那段处理逻辑,不做推断。能写的只有一句:源码的 field(default=...) 里它就是 0,你如果照抄默认值跑,拿到的就是 0,而不是某个”框架会自动帮你选好的合理值”。这一点和 lora_alpha 的处境类似——lora_alpha 的默认值是 None 而不是数字,同样是”不显式设置时由代码另行决定”,同样是我们没有核实过的那一段。
第三个字段 oft_target 默认 "all",这个取值口径在这份参数表里是一以贯之的:lora_target 是 "all",galore_target 是 "all",apollo_target 是 "all",Freeze-tuning 的 freeze_trainable_modules 也是 "all"。同一套”作用范围”语义在多个算法开关上复用同一个默认字符串,这是从参数表直接读出来的规律,不用记特例。
oft_block_size 默认 32。它该不该改、改成多少合适,官方没给通用值,取决于你的模型、数据和硬件,我们更没有任何实测依据可以给建议。
这三个字段落在哪一层
LlamaFactory 把超参按用途拆进了 src/llamafactory/hparams/ 下的多个文件:数据、模型、微调、生成、评测、训练、Megatron 桥接各一份。判断一个参数该写在哪、和谁互相影响,第一步就是先认这个分层。
oft_rank / oft_block_size / oft_target 三个都在 finetuning_args.py,也就是和 lora_rank、use_galore、use_badam、pref_beta 这些同一层。同一个文件里还有两个字段值得顺带记住:stage 默认 "sft",finetuning_type 默认 "lora"。
于是就有一个很实际的问题:README 矩阵里那个叫 OFT 的列,在命令行里是靠哪个字段的哪个取值选中的?
我们抽取的参数定义里没有给出 finetuning_type 的取值枚举,只知道它的默认值是 "lora"。所以这里不猜,请以 llamafactory-cli train -h 的实际输出为准。这类”README 有这个概念、我手上的参数表没写全”的缺口,在这个仓库里不止一处,遇到就去 --help 里对,比在文章里读二手描述可靠。
顺带一提,同层还有多模态的三个冻结开关:freeze_vision_tower 默认 True、freeze_multi_modal_projector 默认 True、freeze_language_model 默认 False。它们和 OFT 这三个字段共处一个配置层,各自按各自的默认值生效——至于”在多模态模型上用 OFT 时这几个开关该怎么配”,参数表回答不了这个问题,我们也不替它回答。
QOFT 这个列头,在参数表里对应到哪
这是本篇唯一一个稍微绕一点的地方。
README 的训练方法矩阵里,QLoRA 和 QOFT 是两个独立列头,正如 LoRA 和 OFT 是两个独立列头。但在参数这一侧,OFT 只有上面那三个字段,没有另外一组以 qoft_ 开头的参数。
量化相关的字段不在 finetuning_args.py,而在 model_args.py 的量化组里:
| 参数 | 默认值 |
|---|---|
quantization_method | QuantizationMethod.BNB |
quantization_bit | None |
quantization_type | "nf4" |
double_quantization | True |
quantization_device_map | None |
也就是说,“带 Q 的那一列”和”不带 Q 的那一列”,在配置文件里落在两个不同的参数文件上:微调方式那几个字段在 finetuning_args.py,量化那几个字段在 model_args.py。README 把它们并成同一张表的六个列头,是文档层面的表达方式。这两层怎么组合、组合后各自的语义是什么,我们没有读过对应实现,只陈述这个结构差异,不推断。
量化这一层有一个已经能核实到的连带影响,值得单独记住:double_quantization 的源码默认值是 True,而 README 在 Ascend NPU 那一节里让用户在配置里显式写 double_quantization: false。默认开着、README 的那一节要求显式关掉——这个前后对照本身就是可核实的。至于这条提示覆盖到哪些场景、为什么这样写,README 那一节怎么写的就以它为准,我们不做延伸。
回到那张矩阵:8 行 × 6 列,48 格全是 ✅
README 的训练方法矩阵,行是 8 种训练阶段:Pre-Training、Supervised Fine-Tuning、Reward Modeling、PPO Training、DPO Training、KTO Training、ORPO Training、SimPO Training;列是 6 种微调方式。8 × 6 = 48 格,全部标了 ✅。
这张表是满的,这个事实本身可以写。但它的含义要按字面读:README 声明这些阶段与这些微调方式都两两可组合,不等于任意组合都同样好用、同样稳定、同样被测试过。我们不做这类推断,你在选组合时也别把一张满勾的表当成兼容性承诺。
读这张表时,还有一处结构信息值得知道。实读 src/llamafactory/train/ 目录,下面有 pt(预训练)、sft、rm、ppo、dpo、kto 六个阶段目录,没有 orpo 和 simpo 的独立目录;而 finetuning_args.py 里有 pref_loss(默认 "sigmoid")和 simpo_gamma(默认 0.5)这类字段。把目录结构和参数命名放在一起看,可以如实说:ORPO / SimPO 是通过偏好损失参数表达的,不是独立的训练阶段目录。再往下的算法细节——它们和 DPO 的差别、各自适合什么数据——我们没有读过实现,不写。
所以矩阵那 8 行落到代码上并不是 8 个平行的目录,这不是缺陷,只是读表时值得知道的一层映射关系。关于 ORPO / SimPO 这条线,我们另有一篇专门讲。
一条明确写在示例里的操作禁令
最后补一个容易踩的边界。examples/merge_lora/qwen3_lora_sft.yaml 这个示例文件顶部有一行原文注释:
### Note: DO NOT use quantized model or quantization_bit when merging lora adapters
全大写的 DO NOT,意思是合并 LoRA 适配器时不要使用量化模型或 quantization_bit。这条禁令的原文限定语是 lora adapters——它明说的是 LoRA 这条路径。OFT 侧有没有对应的约束,我们手上没有依据,因此不外推、不套用。要确认的话,去看你实际要用的那个导出/合并示例文件里写了什么,示例文件顶部的注释是这个仓库交代硬约束的常用位置。
同一组导出参数的默认值顺带记一下:export_size 默认 5、export_device 默认 "cpu"、export_legacy_format 默认 False,与 examples/merge_lora/qwen3_lora_sft.yaml 里写的一致。
这篇的结论其实很短
- OFT 在源码参数里就三个字段:
oft_rank(0)、oft_block_size(32)、oft_target("all"); - 它们和
lora_rank同层,都在finetuning_args.py,finetuning_type的默认值是"lora"; - QOFT 在参数表里没有独立的一组字段,量化那几个参数在
model_args.py,是另一层; - README 矩阵 48 格全勾,只表示声明支持,不构成稳定性或效果承诺;
oft_rank默认 0、lora_alpha默认None,这类”默认值不是一个可以照抄的数”的字段,抄默认值之前先去--help里确认一遍。
至于 OFT 到底适不适合你的任务、oft_block_size 该设多少,这些问题需要的是你自己的数据和硬件上的对照实验,官方没给通用值,我们也没有跑过任何一次训练——任何拍脑袋给出的数字都不比默认值更可信。
本文依据 LlamaFactory 官方仓库(github.com/hiyouga/LlamaFactory)的 README、data/README.md、examples/ 下的配置与 src/llamafactory/hparams/ 的参数定义整理,核对日 2026-08-09。本文内容为仓库源码与文档口径,我们没有安装、训练或部署过任何模型,文中显存数字均为官方标注的估算值(README 原文标 * estimated)而非实测占用。参数与默认值随版本变动,请以 llamafactory-cli train -h 的实际输出为准。