Chapter 11
常见错误与调试
调试 LLaMA-Factory 的第一条原则:
第一步永远是
跑
llamafactory-cli env,把输出贴去 issue,绝大多数问题都和版本组合 / 平台有关,不看版本组合多说无益。
11.1 安装期错误
| 现象 | 原因 | 修复 |
|---|---|---|
ERROR: Could not find a version that satisfies the requirement torch==X.Y.Z | PyTorch 通道没加 | pip install torch --index-url https://download.pytorch.org/whl/cu126 |
RuntimeError: bitsandbytes was compiled without GPU support | 装的是 CPU-only 版 | Linux: pip install -U bitsandbytes;Windows: 用 jllllll 预编译 whl |
flash-attn 编译时 OOM 或耗尽内存 | 未限制并行编译 | MAX_JOBS=4 pip install flash-attn --no-build-isolation |
ImportError: cannot import name '...' from 'transformers' | transformers 版本与 LLaMA-Factory 不匹配 | pip install -e . 时让 pyproject.toml 把版本锁回来;或单独 pip install transformers==<pin> |
OSError: libcuda.so.1: cannot open shared object file | 容器没挂 NVIDIA driver | docker run --gpus=all 必须加;或装 nvidia-container-toolkit |
Windows 启动报 Can't pickle local object | Windows 多进程 spawn 模式 | YAML 加 dataloader_num_workers: 0 |
11.2 启动期 / 数据加载错误
| 现象 | 原因 | 修复 |
|---|---|---|
ValueError: Dataset xxx not found | 没注册到 data/dataset_info.json | 按第 4.5 节注册;或检查 dataset_dir 指向正确 |
KeyError: 'instruction' / 'output' | 数据 schema 不符 alpaca/sharegpt | 检查 formatting 与 columns 映射 |
| 训练启动几秒后 loss = 0.0 | 对 prompt 也算了 loss,被 mask 全 0 | train_on_prompt: false;检查 template 是否能区分 user / assistant |
RuntimeError: Index out of range in tokenization | 词表与基座不匹配(用了 LLaMA tokenizer 训 Qwen) | 核对 model_name_or_path 与 template 是否同一家 |
多模态:shape mismatch / found N images but K placeholders | data 里 <image> 数量 ≠ images 长度 | 数据集预处理时严格校验占位符数 |
Map: 0% 卡很久 | preprocess 单进程 / 数据巨大 | 升 preprocessing_num_workers 至 8-16 |
启动报 FileNotFoundError: tokenizer.model | SentencePiece 模型需要单独下载 | 用 AutoTokenizer.save_pretrained() 重新生成;或换 fast tokenizer |
11.3 训练期 GPU / 显存错误
| 现象 | 原因 | 修复 |
|---|---|---|
CUDA out of memory 在第 1 步 | basic 配置就装不下 | 开 gradient_checkpointing、bf16、flash_attn: fa2;降 cutoff_len;改 QLoRA |
| 训 100 步后 OOM | 样本长度不齐,恰好遇到一条超长 | 开 packing: true;或 group_by_length: true;卡 cutoff_len |
| 多卡:1 张爆其他没事 | 未平均切分 / DataParallel 旧用法 | 用 FORCE_TORCHRUN=1 走 DDP;查 per_device_train_batch_size 一致 |
| NCCL hang,几分钟 timeout | 跨机网络 / iptables 阻塞 | 核对 MASTER_ADDR 可达;NCCL_DEBUG=INFO 看日志;适当调大 ddp_timeout |
| NaN loss / 训到一半飞掉 | fp16 数值范围太小、LR 太大 | 从 fp16 切 bf16;降 LR;查数据是否含异常长样本 |
QLoRA + DS3 报 not implemented | bnb 版本太老 | 升 bitsandbytes >= 0.43;YAML 加 quantization_device_map: auto |
| 多机训练 step 速度极慢 | 没挂 InfiniBand / RDMA | 查 NCCL_IB_DISABLE;走 RDMA;或单机训 |
11.4 训练效果不达预期
| 症状 | 多半原因 | 修复路线 |
|---|---|---|
| Loss 一路平 / 不降 | LR 太小、template 错 | 把 LR ×2;核对 template;用最少样本(max_samples: 50)跑通验证 |
| Loss 降到 0 后效果差 | 训了 prompt 部分 / 数据格式错 | train_on_prompt: false;alpaca vs sharegpt 是否对得上 |
| 训完模型变蠢 | 数据集与基座风格差距大 | 加入 identity 数据;缩 epoch;提高 pref_beta 限制漂移 |
| 训完输出乱码 / 特殊 token 暴露 | template 不匹配 | 核对 template;推理时也得带同一 template |
| 训完模型只会一种回答模式 | 样本太少 / 太单一 | 扩充数据多样性;减少 epoch 防过拟合 |
| 多模态:训完不看图就答 | visual encoder 全程冻结 + 数据太少 | 放开 freeze_multi_modal_projector: false;或仅 prompt 含图时不要 train_on_prompt |
| DPO 后乱说 | 没有合适 reference / β 太小 | 调 pref_beta: 0.1 → 0.3;加 pref_ftx: 0.5 |
11.5 保存 / 加载错误
| 现象 | 原因 | 修复 |
|---|---|---|
OSError: Unable to load weights from pytorch_model.bin | 磁盘损坏 / 中途断电 | 用上一个 checkpoint resume_from_checkpoint |
DeepSpeed ZeRO-3 保存 model 文件名怪异(多个 mp_rank_*) | ZeRO-3 分布式 checkpoint | 看 save_strategy;stage3_gather_16bit_weights_on_model_save: true 已开则会自动 gather |
| merge LoRA 时 OOM | device 选了 GPU | YAML 改 export_device: cpu |
| merge 后模型加载报 dtype mismatch | QLoRA 不能 merge | QLoRA 训出的 adapter 只能挂载推理,不能 merge;用普通 LoRA |
| 合并量化模型时数据集缺失 | 没填 export_quantization_dataset | 指定 data/c4_demo.jsonl 或类似校准集 |
11.6 推理错误
| 现象 | 原因 | 修复 |
|---|---|---|
| chat 输出全是乱码 / 特殊 token | template 没指定或不匹配 | 推理必须显式 template=... |
vLLM 后端崩溃 RuntimeError: Failed to spawn worker | 多卡环境 / Ray 没启动 | 设 vllm_gpu_util: 0.7;先 ray start --head |
| API 模式响应慢且 GPU 占用低 | HF 后端而非 vLLM | YAML 改 infer_backend: vllm |
| 多模态推理时图片不生效 | chat 里用的 <image> 拼写错 | 必须是英文尖括号 + 字面 image |
11.7 patcher 自动修复点速查
很多"为什么我的训练莫名变稳了 / 莫名变乱了"答案在 src/llamafactory/model/patcher.py 的 patch_config()(308–374)和 patch_model()(376–428)里——它们在模型加载前后默默给一组已知坑打补丁。下表是会影响最多用户的几条:
| patch(位置) | 触发条件 | 做了什么 |
|---|---|---|
configure_attn_implementation(patcher.py:321) | YAML flash_attn: auto / fa2 / sdpa / disabled | 映射到 HF config._attn_implementation;Gemma-2 强制 fa2,Youtu-VL 强制 eager |
configure_rope(line 322) | YAML rope_scaling: linear / dynamic / yarn / llama3 | 按 ceil(model_max_length / original_max_length) 计算 factor,写进 config.rope_scaling |
configure_longlora(line 323) | rope_scaling 已设 | patch attention forward 在 training 时启用 group_size 移位(仅 50% head 移位) |
configure_kv_cache(line 327) | 训练 vs 推理 | 训练时强制 use_cache=False;推理时按 use_kv_cache 决定 |
configure_moe(line 325) | moe_aux_loss_coef > 0 | 按 mixtral / qwen_moe / glm4 / deepseek 等不同字段名设置 router 辅助 loss |
configure_visual_model(line 326) | 多模态 | 把 hidden_size 同步给顶层 config(DS-ZeRO3 兼容);Yi-VL projector 单独 patch |
| low_cpu_mem_usage 禁用(patcher.py:365) | ZeRO-3 / FSDP 启用时 | 自动关掉,避免加载冲突 |
| do_sample 修正(patcher.py:384–389) | generation_config 里 do_sample=False + temp/top_p ≠ 1.0 | 自动设 do_sample=True,避免矛盾 |
resize_embedding_layer(line 399–405) | resize_vocab: true + 新 token | resize embedding 到 tokenizer 实际大小 |
autocast_projector_dtype | VLM 训练 | 给 projector 注册 post-hook,把输出强转 compute_dtype(QLoRA VLM 稳定关键) |
add_z3_leaf_module(moe.py:36–40) | MoE + ZeRO-3 / FSDP | 标记 expert block 为 leaf module,否则 ZeRO-3 切碎了 expert |
| Gemma-3n grad ckpt 禁用(patcher.py:408–409) | 训练 Gemma-3n | 架构与 gradient_checkpointing 冲突,强制关 |
| Qwen3.5 + FA2 + cu_seqlens(patcher.py:418–419) | 训练 Qwen3.5 | patch forward 支持 FLA varlen kernel(packing 友好) |
"我换了模型 / 换了字段后行为变了"——先去 patcher.py grep 模型名或字段名,确认是不是触发了一条 patch。这能省下大量调试时间。
11.8 BNB QLoRA + FSDP 的关键陷阱
QLoRA 配合 FSDP 时经常碰到 dtype 异常,源头在 quantization.py:178 这一行:
bnb_4bit_quant_storage = compute_dtype # 给 FSDP 用
含义:BNB 4-bit 在内部把权重存成一个 compute_dtype(bf16 或 fp16)的张量来 mask 出 4-bit 真实数据。FSDP shard 参数时只认 storage dtype——如果 storage 不是 bf16/fp16 而是默认的 uint8,FSDP 会按 uint8 切,导致 forward 报 dtype mismatch。
诊断:
- 报错形如
RuntimeError: expected scalar type Float but got UInt8→ 检查 BNB 版本(>=0.43 才支持 quant_storage); - 报错形如
FSDP requires uniform dtype across params→ 同上; - 同时不开 FSDP 训练正常,开了 FSDP 立刻报错 → 几乎必是这里。
修复:升 BNB 到 0.43+;YAML 显式写 bf16: true 确保 compute_dtype 是 bf16;不要混用 fp16/bf16 标志。
11.9 通用调试技巧
- 用
max_samples: 50跑通整条链路再上大数据。loss 降不降一目了然。 - 开
logging_steps: 1看前 20 步,多数错误(NaN、template 错)这里就暴露。 - preview command:用 Web UI 拼好后点 "Preview command",对照 CLI 学。
- 对照
examples/里的官方 YAML:你的配置不对时,diff 一份相同任务的官方例子最快。 - 少用
flash_attn: auto:显式写fa2或sdpa,避免环境不一致带来的意外。 - 把
output_dir放到大盘:checkpoint 文件大;ZeRO-3 还会乘以 GPU 数。 - 升级前看 CHANGELOG:LLaMA-Factory 高频迭代,大版本可能改字段名。