问题与目标
第一轮 SFT 的目标不是训练大模型,而是证明数据、模板、训练、保存和推理可以闭环。本篇使用小型模型建立可复现基线,并明确哪些结果需要在 GPU 环境记录。
核心概念
一次最小 SFT 实验应固定:模型修订版本、依赖版本、随机种子、数据快照、Chat Template、最大长度、有效 Batch、学习率、训练步数和生成参数。
per_device_train_batch_size × gradient_accumulation_steps × GPU 数量 才是每次参数更新的有效 Batch。训练前后的推理必须使用同一测试集和生成参数。
可运行实现
python -m pip install "transformers>=4.56,<6" "datasets>=3,<5" "trl>=0.26,<1" "accelerate>=1,<2"
from datasets import Dataset
from trl import SFTConfig, SFTTrainer
rows = [
{"messages": [
{"role": "user", "content": "设备在线,温度 42℃,输出风险等级"},
{"role": "assistant", "content": "low"},
]},
{"messages": [
{"role": "user", "content": "设备离线 12 分钟,输出风险等级"},
{"role": "assistant", "content": "high"},
]},
]
dataset = Dataset.from_list(rows)
args = SFTConfig(
output_dir="outputs/sft-baseline",
max_steps=10,
per_device_train_batch_size=1,
gradient_accumulation_steps=2,
learning_rate=2e-5,
logging_steps=1,
save_steps=10,
seed=42,
report_to="none",
assistant_only_loss=True,
)
trainer = SFTTrainer(
model="Qwen/Qwen3-0.6B",
args=args,
train_dataset=dataset,
)
trainer.train()
trainer.save_model("outputs/sft-baseline/final")
十步训练只用于验证链路,不能证明泛化。正式实验要准备独立验证集和测试集,并保存训练前输出、训练后输出、Loss 曲线、运行时长与峰值显存。
若模型 Chat Template 不支持助手区域掩码,assistant_only_loss=True 会失败。此时选择支持的模板,或改用明确的 Prompt—Completion 数据契约,不要静默改成全序列 Loss。
常见问题与排查
Loss 很快接近零
少量重复样本很容易被记住。扩大独立测试集,检查近似重复和数据泄漏,不把记忆训练样本当泛化。
训练后生成和训练答案不一致
检查推理是否加载正确 Checkpoint、Chat Template 是否一致、是否错误保留 Prompt Token,以及采样温度是否改变。
第一步就 CUDA OOM
先缩短序列和 Batch,启用梯度累积与梯度检查点,再考虑 LoRA/QLoRA。记录每一步调整,避免同时改变过多变量。
只保存最后一个模型
最后一步不一定最好。按验证指标保存候选 Checkpoint,并记录选择理由与数据版本。
小结
SFT 基线的价值是建立可复现闭环。先用小模型和少量步骤验证数据、Loss、保存与加载,再扩大数据和资源,能够显著降低训练失败的定位成本。
License: CC BY-NC 4.0
Updated 2 hours ago
Was this article helpful? Give it a like.
0 comments


