配置系统:YAML 全字段拆解
第 4 章解释了 LLaMA-Factory 把所有参数切成 6 类 dataclass 的设计。本章按这 6 类的顺序,把 YAML 里能写的字段过一遍。你不需要现在就记住每一个,只需要知道"这个字段写错了应该去哪个文件里找说明"。
5.1 YAML / CLI 解析的总入口
所有训练 YAML 都会经过 src/llamafactory/hparams/parser.py 中的 get_train_args()。它做三件事:
- 把 YAML / CLI / 环境变量合并成一个扁平的 dict;
- 调用 HuggingFace
HfArgumentParser分别填充 6 个 dataclass; - 跑各类
__post_init__()做合法性校验(比如quantization_bit必须配quantization_method)。
看到 ValueError: ... must be set when ... 这类报错,几乎都是 __post_init__() 抛的,直接 grep 报错文案就能定位到代码位置。
5.2 ModelArguments:模型相关
| 字段 | 默认 | 含义 |
|---|---|---|
model_name_or_path | 必填 | HF / ModelScope 仓库 ID 或本地路径 |
adapter_name_or_path | null | 已有 LoRA adapter 的路径,可多个用逗号 |
cache_dir | null | HF 缓存目录覆盖 |
trust_remote_code | false | 是否信任模型仓库里的自定义代码 |
use_fast_tokenizer | true | 用 Rust 实现的 fast tokenizer |
resize_vocab | false | SFT 时若数据有新 special token,自动 resize embedding |
split_special_tokens | false | tokenize 时拆 special token |
flash_attn | "auto" | auto / disabled / fa2 / sdpa |
moe_aux_loss_coef | null | MoE 的辅助负载均衡 loss 权重 |
quantization_method | bnb | on-the-fly 量化方法:bnb / hqq / eetq |
quantization_bit | null | 4 / 8,决定是 QLoRA / int8-LoRA |
quantization_type | nf4 | fp4 / nf4,bnb int4 时 |
double_quantization | true | bnb int4 的二次量化 |
image_max_pixels | 768*768 | 多模态时单图最大像素 |
video_max_pixels | 128*128 | 多模态时单帧最大像素 |
量化字段之间的相互约束(来自 QuantizationArguments.__post_init__):
quantization_bit ∈ {4,8}且quantization_method = bnb→ 需要bitsandbytes >= 0.43;quantization_method = hqq需要装hqq;- 导出
export_quantization_bit必须配export_quantization_dataset(不然量化校准数据无来源)。
5.3 DataArguments:数据相关
| 字段 | 默认 | 含义 |
|---|---|---|
dataset | 必填 | 逗号分隔多个 dataset 注册名 |
eval_dataset | null | 验证集,留空则从 train 里切 |
dataset_dir | data | dataset_info.json 所在目录 |
template | 必填 | 对话模板,必须和基座匹配 |
cutoff_len | 1024 | 样本最大 token 数,超出截断 |
max_samples | null | 每个 dataset 取前 N 条,常用于 debug |
preprocessing_num_workers | null | tokenize 并行进程数 |
dataloader_num_workers | 0 | 训练时 DataLoader worker;Windows 必须设 0 |
packing | null | 开启样本拼接、效率明显提高 |
neat_packing | false | 带 attention mask 的 packing,需要 FlashAttention 2 |
train_on_prompt | false | 是否对 prompt 部分计 loss(默认只对 response 计) |
mask_history | false | 多轮对话只学最后一轮 |
val_size | 0 | 从训练集切多少做验证(0 表示不切) |
5.4 FinetuningArguments:选算法 + 算法参数
这是 LLaMA-Factory 最大的 dataclass,分成 FreezeArgs / LoraArgs / RLHFArgs / Galore... + 顶层 FinetuningArgs 五块。下面按用得最多的字段挑:
顶层选择
| 字段 | 取值 | 含义 |
|---|---|---|
stage | pt / sft / rm / ppo / dpo / kto | 训练阶段(第 4 章已讲) |
finetuning_type | full / lora / freeze | 动模型的范围 |
do_train | true / false | 训练开关 |
use_galore | false | 开启 GaLore 梯度低秩近似 |
use_apollo | false | 开启 APOLLO 低秩优化器 |
use_badam | false | BAdam 块坐标 |
use_swanlab | false | 开启 SwanLab 跟踪 |
LoRA / QLoRA 段(finetuning_type=lora 才生效)
| 字段 | 默认 | 含义 |
|---|---|---|
lora_rank | 8 | 低秩维度 $r$ |
lora_alpha | 2*lora_rank | 缩放系数 $\alpha$ |
lora_dropout | 0.0 | LoRA dropout |
lora_target | "all" | 目标 Linear 名字,多个用逗号;all = 全部 Linear |
additional_target | null | 额外要训的模块(如 lm_head、embed_tokens) |
loraplus_lr_ratio | null | 开 LoRA+ 时,$B$ 矩阵的 LR 倍数 |
use_rslora | false | Rank-Stabilized LoRA |
use_dora | false | DoRA(解耦方向 + 模长) |
pissa_init | false | PiSSA 初始化 |
pissa_iter | 16 | PiSSA SVD 迭代次数 |
create_new_adapter | false | 继续训时是否新建 adapter,避免覆盖 |
RLHF 段(stage ∈ {dpo,kto,orpo,ppo,rm} 才生效)
| 字段 | 默认 | 含义 |
|---|---|---|
pref_beta | 0.1 | DPO 系正则系数 $\beta$ |
pref_loss | sigmoid | sigmoid (DPO) / orpo / simpo / hinge / ipo / kto_pair |
pref_ftx | 0.0 | DPO 时再叠加一项 SFT loss 的权重 |
reward_model | null | PPO 时奖励模型路径 |
reward_model_type | lora | lora / full / api |
ppo_buffer_size | 1 | PPO mini-batch 缓冲 |
ppo_epochs | 4 | 每批 PPO 更新轮数 |
ppo_score_norm | false | 是否对 reward 做归一化 |
ppo_target | 6.0 | 自适应 KL 控制器的目标 |
5.5 TrainingArguments:训练循环
这一类直接继承自 transformers.TrainingArguments,能用的字段非常多,只列工程上几乎每次都要写的几个:
| 字段 | 用途 |
|---|---|
output_dir | checkpoint / 日志保存目录 |
per_device_train_batch_size | 单卡 micro batch |
gradient_accumulation_steps | 梯度累积,等价"虚拟扩大 batch" |
learning_rate | LoRA 推荐 1e-4~2e-4;全参 1e-5 |
num_train_epochs | 训练轮次;和 max_steps 二选一 |
lr_scheduler_type | cosine / linear / constant / ... |
warmup_ratio | warmup 占总步数比例 |
bf16 / fp16 | 混合精度选项 |
gradient_checkpointing | 用时间换显存 |
logging_steps | 多少步打印一次 |
save_steps | 多少步保存一次 |
save_total_limit | 最多保留几份 checkpoint |
ddp_timeout | DDP 通信超时,长样本时调大 |
resume_from_checkpoint | 断点续训路径 |
report_to | none / wandb / tensorboard / swanlab / mlflow |
5.6 GeneratingArguments:推理 / chat / api 共用
训练 YAML 通常不写这些;它们出现在 llamafactory-cli chat / api / predict 时。
| 字段 | 默认 | 含义 |
|---|---|---|
do_sample | true | 开 sampling |
temperature | 0.95 | 采样温度 |
top_p | 0.7 | nucleus 采样阈值 |
top_k | 50 | top-k 截断 |
num_beams | 1 | beam search 数 |
max_new_tokens | 512 | 生成最大新 token 数 |
repetition_penalty | 1.0 | 重复惩罚 |
length_penalty | 1.0 | 长度惩罚(仅 beam) |
default_system | null | 覆盖模板自带的 system prompt |
5.7 EvaluationArguments:评测
| 字段 | 默认 | 含义 |
|---|---|---|
task | 必填 | mmlu_test / ceval_validation / cmmlu_test ... |
task_dir | evaluation | 放评测数据的目录 |
lang | en | en / zh |
n_shot | 5 | few-shot 数 |
save_dir | null | 结果保存目录 |
5.8 把一份 YAML 翻译给"非工程"同事
第 3 章那份默认 SFT YAML,可以这样口语化解读:
| YAML 行 | 翻译 |
|---|---|
model_name_or_path: Qwen/Qwen3-4B-Instruct-2507 | "从 Qwen3-4B-Instruct 这个基座开始" |
stage: sft, finetuning_type: lora | "做监督微调,只动 LoRA 层" |
lora_rank: 8, lora_target: all | "LoRA 秩=8,给所有 Linear 都加旁路" |
dataset: identity,alpaca_en_demo | "喂这两个数据集,拼接后训" |
template: qwen3_nothink | "按 Qwen3 的对话格式包裹(关掉 think 模式)" |
cutoff_len: 2048 | "每条样本最长 2048 token" |
per_device_train_batch_size: 1, gradient_accumulation_steps: 8 | "单卡 micro=1,累 8 次才反传一次" |
learning_rate: 1.0e-4, lr_scheduler_type: cosine, warmup_ratio: 0.1 | "用 1e-4 学习率,cosine schedule,前 10% 步 warmup" |
num_train_epochs: 3.0, bf16: true | "训 3 轮,用 bfloat16 混精" |
掌握这一层"YAML → 自然语言"的翻译能力,你看任何别人公开的 LLaMA-Factory 配置都不会再迷糊。
5.10 派生字段:YAML 不写但运行时存在
ch04.10 已经讲过这个概念——这里给和具体 YAML 字段对应的"运行时实际值"对照表,写 config 时配对着看:
| YAML 你写 | 派生 / 自动调整 | 什么时候坑你 |
|---|---|---|
bf16: true | model_args.compute_dtype = torch.bfloat16;自动决定 BNB bnb_4bit_compute_dtype | 同时写 fp16: true 会冲突 |
cutoff_len: 4096 | model_args.model_max_length = 4096;触发 RoPE 检查 | 超过模型原生 max_position_embeddings 时要配 rope_scaling |
neat_packing: true | 自动 packing: true;cutoff_len -= 1;block_diag_attn: true;要求 FlashAttention-2 | 没装 fa2 时启动报错 |
lora_rank: 16 | lora_alpha = 32(如未显式给) | — |
stage: pt | 自动 packing: true(预训练默认拼) | — |
stage: dpo, pref_loss: simpo | use_ref_model = False(SimPO 不需要 ref) | 同时配 ref_model 时会被无视,浪费显存 |
stage: dpo, pref_loss: sigmoid | use_ref_model = True | 没配 ref_model 时框架会自动用 base 模型当 ref |
quantization_bit: 4 | BNB 时 bnb_4bit_quant_storage = compute_dtype(FSDP+QLoRA 必须这个值) | — |
deepspeed: examples/.../ds_z3_config.json | low_cpu_mem_usage = False;device_map = None | ZeRO-3 与 quantization_bit 冲突(除 MXFP4/FP8 外) |
5.11 OFT / OFTv2 字段(2025-08 新增)
OFT(Orthogonal Fine-Tuning)是 LoRA 之外的新 PEFT 路径,仓库通过 FinetuningArguments → OFTArguments mixin 提供。启用:finetuning_type: oft。
| 字段 | 含义 |
|---|---|
oft_rank | OFT 旋转矩阵秩 |
oft_block_size | 分块大小(OFTv2 关键参数) |
module_dropout | OFT 专用 dropout(不是 lora_dropout) |
oft_target | 目标模块,写法同 lora_target |
OFT 和 LoRA 互斥(同 finetuning_type 只能选一种);但都通过同一个 init_adapter() 入口走 PEFT 库。ch06.10 会展开实际差异。
5.12 新优化器字段:APOLLO / Muon
2025-01 (APOLLO) 与 2025-04 (Muon) 引入两个新优化器,都通过 FinetuningArguments 启用。
| 字段 | 含义 | 典型值 |
|---|---|---|
use_apollo | 启用 APOLLO(Hessian-aware 低秩优化器) | false |
apollo_target | 目标模块(all / 列表) | all |
apollo_rank | 低秩维度 | 256 |
apollo_proj | 投影方向(同 galore_proj_type) | — |
apollo_update_interval | 投影更新间隔 | 200 |
apollo_layerwise | 每层独立 optimizer 字典;要求 gradient_accumulation_steps=1 | false |
optim: muon | 启用 Muon(写在 TrainingArguments.optim 字段) | — |
Muon 是 newton-schulz 风格的二阶优化器,不通过 use_* flag,而是直接 optim: muon(同 adamw_torch / adamw_bnb_8bit / adafactor 一类)。配置最简洁。
5.13 DeepSpeed / FSDP 字段对接
LLaMA-Factory 自己不维护 ZeRO 实现,这些走 HF Trainer:
| 字段 | 对应行为 |
|---|---|
deepspeed | 指向 ds_config.json 路径;HF Trainer 自动接管 |
fsdp | HF Trainer 的 FSDP 字符串配置("full_shard auto_wrap" 等) |
fsdp_config | 更细的 FSDP 设置(min_num_params / state_dict_type 等) |
use_hyper_parallel | 启用 HyperParallel FSDP2 路径(新版) |
use_mca | 启用 Megatron-core 后端(2025-10 接入) |
本书 ch10 完整对比这几种加速后端的取舍。
5.14 字段查不到怎么办
grep -rn '"<字段名>"' src/llamafactory/hparams/—— 看它在哪个 dataclass;- 找不到 → 看是不是 HF
TrainingArguments自带的,去transformers仓库找; - 再找不到 → 可能是新版才加的,
git log -p src/llamafactory/hparams/看历史; - 都不是 → YAML 拼写错了,会被忽略,不会报错。这是新手最容易踩的坑。