Chapter 05

SFTTrainer 全字段拆解

📌 commit 8221a9fSFTConfig 50+ 字段按"该不该调"分组

SFTConfig 继承自 TrainingArguments,又加了 ~20 个自家字段。本章按"数据相关 / 训练相关 / PEFT 相关 / 性能相关"分组,告诉你哪些是必调、哪些可忽略。

5.1数据字段

字段默认含义建议
dataset_text_fieldNoneplain text 数据用哪列通常 "text"
max_length1024截断长度2048-4096
packingFalse是否打包短样本★ True(数据短时收益大)
padding_freeFalseflash-attn 支持的"去 pad"模式开 packing 后建议开
assistant_only_lossFalse只对 assistant 算 loss★ True
chat_template_pathNone自定义 chat 模板tokenizer 自带就够
eos_tokenNone显式指定 EOS多数 tokenizer 已设
completion_only_lossTrueprompt-completion 数据默认即可

5.2训练字段(来自 TrainingArguments)

字段SFT 推荐说明
num_train_epochs1-3SFT 多了易过拟合
per_device_train_batch_size看显存定大 model 可降到 1
gradient_accumulation_steps4-32调节有效 batch size
learning_rate2e-4(LoRA)/ 2e-5(全参)LoRA 用大 lr
lr_scheduler_typecosineSFT 标配
warmup_ratio0.03太小训不稳
weight_decay0.01LoRA 不一定要
bf16 / fp16bf16A100/H100 默认 bf16
gradient_checkpointingTrue(显存紧时)慢 25%
optimadamw_torchQLoRA 用 paged_adamw_8bit

5.3性能字段

字段含义建议
attn_implementation"eager" / "sdpa" / "flash_attention_2"flash_attention_2
torch_compile开 torch.compile训稳了再开
group_by_length按长度分桶不开 packing 时建议开
dataloader_num_workersdata 加载并发4-8

5.4评估和保存

字段含义
eval_strategy"no" / "steps" / "epoch"
eval_stepssteps 模式下间隔
save_strategy同上
save_steps / save_total_limit避免占盘
load_best_model_at_end训完加载最佳
metric_for_best_model"eval_loss"

5.5logging

字段含义
logging_steps10-50
report_to"wandb" / "tensorboard" / "none"
run_namewandb 项目里的实验名

5.6三套典型配置

① 单卡跑通 7B LoRA

SFTConfig(
    output_dir="./out",
    per_device_train_batch_size=2, gradient_accumulation_steps=8,
    num_train_epochs=2, learning_rate=2e-4,
    max_length=2048, packing=True, assistant_only_loss=True,
    bf16=True, attn_implementation="flash_attention_2",
    gradient_checkpointing=True,
    logging_steps=10, save_strategy="epoch",
)

② 多卡 70B QLoRA

SFTConfig(
    output_dir="./out",
    per_device_train_batch_size=1, gradient_accumulation_steps=16,
    num_train_epochs=1, learning_rate=1e-4,
    max_length=4096, packing=True, assistant_only_loss=True,
    bf16=True, attn_implementation="flash_attention_2",
    gradient_checkpointing=True,
    optim="paged_adamw_8bit",
    save_steps=500, save_total_limit=2,
    report_to="wandb", run_name="qwen-70b-qlora",
)

③ 全参 7B(多卡 DeepSpeed)

SFTConfig(
    output_dir="./out",
    per_device_train_batch_size=4, gradient_accumulation_steps=4,
    num_train_epochs=3, learning_rate=2e-5,
    max_length=4096, packing=True, assistant_only_loss=True,
    bf16=True, attn_implementation="flash_attention_2",
    gradient_checkpointing=True,
    deepspeed="ds_z3_config.json",
    save_steps=500,
)

5.7SFTConfig 的 3 种 loss_type

SFT 不只是 "next token prediction"。SFTConfigtrl/trainer/sft_config.py:264–274)的 loss_type 字段提供三种选项:

loss_type含义什么时候用
"nll"(默认) 标准负对数似然 常规 SFT
"dft" Dynamic Fine-Tuning(arXiv:2508.05629) 论文复现,对动态权重感兴趣
"chunked_nll" 分块计算 lm_head 减少 logits 显存 词表巨大(200K+) + 长序列时

chunked_nll 关键实现在 _chunked_cross_entropy_loss()sft_trainer.py:104–212):

5.8packing 两种实现 + v0→v1 重命名

v1 把 packing 的字符串值统一了:

packing 取值v0 名v1 名实现
True(默认 BFD) "bfd-requeue" "bfd_split" Best-Fit Decreasing,O(log N) 段树查空闲位
wrapped "wrapped" 不变 简单按序拼,遇 max_length 切下一条

BFD 比 wrapped 节省 padding 更多(实测 20-40% 训练时间),但要求所有样本 token 后再排序+装箱,启动期多花几秒。v0 旧名 "bfd-requeue" 在 v1 还能识别(向后兼容),但日志会有 deprecation warning。

5.9开箱 accelerate 配置(7 份 yaml)

仓库自带 trl/accelerate_configs/ 已经写好 7 份 yaml,accelerate launch --config_file ... 直接用:

yamldistributed_type典型场景
single_gpu.yaml NO 开发 / 调试
multi_gpu.yaml MULTI_GPU 单节点多卡 SFT,最常用
fsdp1.yaml FSDP(v1) 大模型分片(TRANSFORMER_BASED_WRAP)
fsdp2.yaml FSDP(v2,DTensor)新版 mesh-aware 分片
zero1.yaml DEEPSPEED ZeRO-1,optimizer 切分
zero2.yaml DEEPSPEED ZeRO-2,最常用 ZeRO 档位
zero3.yaml DEEPSPEED ZeRO-3,参数全切,含 zero3_save_16bit_model

不需要自己跑 accelerate config 交互式问答。trl sft --config sft.yaml --config_file zero3.yaml 直接跑通 ZeRO-3 SFT。

5.10chat template 38 个内置模板

trl/chat_templates/ 内置 38 个 jinja 模板,覆盖主流模型族:

模型族文件特别处理
Llama 3.x llama3.jinja / llama3_1.jinja / llama3_2.jinjatool call 单 JSON
Qwen 3.x qwen3.jinja / qwen3_5_think.jinja / qwen3_5_nothink.jinja / qwen3_6.jinjathink 模式独立模板
Gemma 1/2/3 gemma.jinja / gemma3.jinjaGemma 3 支持多模态 content blocks
Cohere cohere.jinja / cohere2.jinjaCommand R / R+
DeepSeek-V3 deepseekv3.jinja tool calling 完整支持
GLM-4 MoE glm4moe.jinja MoE 路由 token
GPT-OSS gptoss.jinja

每个模板都有 _training.jinja 双胞胎(如 llama3_training.jinja)。差异:

5.11这章你需要带走的