跳转至

故障排查指南

本文档提供了在使用本项目时可能遇到的常见问题及其解决方案。 如果您在这里找不到解决方案,请查阅相关文档或在 GitHub Issues 提交问题。

目录


安装与环境

  • 问题: make initmake sync 失败,或遇到依赖冲突.

    • 解决方案:
    • 确保您的 Python 版本符合 pyproject.tomlrequires-python 的要求(当前为 3.14+)。
    • 尝试清理 uv 缓存: uv clean
    • 检查 pyproject.tomluv.lock 文件,手动解决潜在的依赖冲突。
    • 确保您的网络连接正常,可以访问 PyPI。
  • 问题: make 命令无法执行,提示 "command not found"

    • 解决方案: 确保您的系统安装了 make 工具。
      • Linux/macOS: 通常预装。
      • Windows: 可以通过 Chocolatey (choco install make) 或 Scoop (scoop install make) 安装,或者安装 Git for Windows (它通常包含 make)。
  • 问题: 训练时遇到 torch.cuda.is_available() 返回 False,即使有 GPU

    • 解决方案:
    • 确保您安装了正确版本的 PyTorch,并且它与您的 CUDA 驱动版本兼容。
    • 检查您的 CUDA 驱动是否已正确安装并更新到最新版本。
    • 确认您的 GPU 设备已正确识别并启用。
    • 如果使用 Docker,确保容器以 --gpus all 或类似方式运行。

训练问题

  • 问题: 训练过程中出现内存不足 (OOM) 错误

    • 解决方案:
    • 减小 batch_size: 这是最直接有效的方法。
    • 减小模型大小: 尝试减小 hidden_sizenum_layers
    • 启用自动混合精度 (AMP): 默认已开启;调试时可用 --no-amp 关闭。AMP 可以显著减少显存占用。
    • 启用 torch.compile: 默认已开启;调试时可用 --no-compile 关闭。也可在 YAML 中设置 optimization.use_amp: false / optimization.use_compile: false
    • 梯度累积: 增大 YAML 中 optimization.gradient_accumulation_steps,用更小的实际 batch_size 模拟更大的批次。
  • 问题: 分词器抛出 KeyError,提示字符不在词汇表中

    • 解决方案: 当前的 SimpleCharacterTokenizer 是字符级别的,并且词汇表是根据初始化时提供的语料库构建的。确保您尝试编码的文本只包含在初始化分词器时语料库中存在的字符。如果需要处理更广泛的字符集,您可能需要更新分词器或其初始化语料。

分布式训练 (DDP)

  • 问题: DDP Misconfiguration: world_size is X, but ... insufficient GPUs

    • 解决方案:
    • 检查您的 DistributedConfig 或环境变量 GPUS_PER_NODE 是否设置正确。
    • 运行 nvidia-smi 确认您的机器上有多少可用的 GPU。
    • world_size 应该等于 num_nodes * gpus_per_node
  • 问题: 训练进程卡死 (Hang)

    • 解决方案:
    • 检查日志: 查看每个 rank 的日志文件,找出是否有某个进程在其他进程卡住之前就抛出了错误。
    • 网络问题: 在多节点环境中,确保节点之间的网络连接是畅通的,特别是 MASTER_ADDRMASTER_PORT 指定的端口没有被防火墙阻塞。
    • 代码分支: 确保在所有 DDP 进程中,参与分布式操作的代码路径是一致的。

性能优化

  • 问题: GPU 利用率低 / 性能不理想
    • 解决方案:
    • 增加数据加载 workers: 提高 optimization.num_workers 值,使用更多进程并行加载数据。
    • 启用内存钉选: 确保 optimization.pin_memory 设置为 true,加速 CPU 到 GPU 数据传输。
    • 启用 torch.compile: 确保 optimization.use_compile 设置为 true
    • 减少 CPU-GPU 同步: 减少不必要的同步操作,如频繁调用 .item()

检查点问题

  • 问题: Error(s) in loading state_dict for ...: Missing key(s) in state_dict: ...

    • 解决方案:
    • 确保您在恢复训练时使用的模型配置 (ModelConfig) 与保存该检查点时的配置完全相同。
    • 如果想加载结构不同的模型,可以手动编写代码加载匹配的权重部分。
  • 问题: 恢复训练后,效果与之前不符

    • 解决方案: 确保 CheckpointManager 正确保存和加载了所有相关状态,包括优化器、学习率调度器和随机数生成器状态。

MoE (Mixture of Experts)

  • 问题: MoE 训练收敛困难或性能不佳

    • 解决方案:
    • 调整 top_k: 尝试不同的 top_k 值。
    • 负载均衡损失: 在损失函数中添加负载均衡损失项,鼓励所有专家被均匀利用。
    • 门控网络初始化: 确保门控网络的初始化有助于有效的专家路由。
  • 问题: MoE 训练时出现 NaNInf

    • 解决方案:
    • 检查门控网络输出: 确保门控网络的 logits 不会过大或过小。
    • 调整学习率: 尝试减小学习率。
    • 梯度裁剪: 确保梯度裁剪 (training.gradient_clip_val) 已启用并设置合理。
    • 检查专家 MLP: 确保专家 MLP 内部的计算没有导致数值溢出。

LoRA 与 QLoRA 相关问题

  • 问题: 应用 LoRA 后模型输出与原始模型完全相同.

    • 解决方案: LoRA 的 B 矩阵初始化为零,因此初始输出应该相同。确保:
    • 您已正确调用 apply_lora(model, ...)
    • 训练时只优化 LoRA 参数: optimizer = AdamW(get_lora_parameters(model), lr=1e-4)
    • 确认 LoRA 参数的 requires_grad=True
  • 问题: QLoRA 推理速度比预期慢.

    • 解决方案: QLoRA 在每次 forward 时需要反量化权重,这会增加开销:
    • 对于推理,考虑使用标准 LoRA 并在训练后 merge_lora(model)
    • QLoRA 主要优势是训练时的内存节省,而非推理速度。

KVCache 相关问题

  • 问题: 使用 KVCache 时生成的文本与不使用时不同.

    • 解决方案: 确保:
    • 在新序列开始前调用 cache.reset() 重置缓存。
    • max_seq_len 足够大以容纳完整生成。
    • 首次 forward 传入完整 prompt,后续 forward 只传入新生成的 token。
  • 问题: KVCache 超出预分配长度导致错误.

    • 解决方案: 增大 max_seq_len 或在生成循环中检查 cache.seq_len < cache.max_seq_len

命令行参数

  • 问题: 运行 llm-train 时提示 unrecognized arguments / No such option
    • 解决方案: llm-train 只暴露少量扁平覆盖参数:--task(必填)、 --config-path--epochs--batch-size--lr--num-samples--steps-per-epoch--compile / --no-compile--amp / --no-amp模型结构、数据、分布式、checkpoint 等配置一律走 YAML,没有 --model-* / --training-* 之类的嵌套参数。
    • 布尔参数格式: 布尔参数不带值。默认 True 的用 --no-<name> 关闭 (如 --no-compile);默认 False 的用 --<name> 打开。
    • 查看帮助: 运行 uv run llm-train --help 查看全部参数;完整说明见 CLI 命令参考

Serving 推理服务

问题: llm-serve 启动失败,报 "Refusing to start: ... api_key is not set"

  • 解决方案: 这是公开主机守卫机制。当绑定 0.0.0.0 时必须设置 API key。本地开发使用 LLM_SERVING_HOST=127.0.0.1 或设置 LLM_SERVING_API_KEY

问题: curl 调用 /v1/chat/completions 返回 403

  • 解决方案: 服务需要 API key。确保请求头包含 X-API-KeyAuthorization: Bearer。本地开发不需要 key(使用 127.0.0.1)。

问题: 服务返回空输出或乱码

  • 解决方案: 如果 model_path=None(dummy 模型),输出是随机 token 解码。需要训练 checkpoint 后配置 model_pathtokenizer_path

PEFT 相关问题

问题: peft_kwargs 配置错误导致训练失败

  • 解决方案: 不同 peft_method 需要不同的 kwargs。检查 peft_kwargs 是否与方法的预期参数匹配。常见错误:Adapter 需要 bottleneck_dim,Prefix Tuning 需要 prefix_length,LoRA 需要 rankalpha

问题: PEFT adapter 加载到 serving 时提示 method_name mismatch

  • 解决方案: 训练时的 peft_method 必须与 serving 时的 LLM_SERVING_PEFT_METHOD 一致。adapter sidecar 文件中的 format_versionmethod_name 元数据会在 load 时校验。

评估相关问题

问题: import lm_eval 失败

  • 解决方案: 需要安装可选依赖:uv sync --extra evalpip install 'llm[eval]'

问题: MMLU 评估结果异常低

  • 解决方案: 检查 few-shot 设置(默认 5-shot)和模型是否已训练。dummy 模型在 MMLU 上 ≈ 随机水平是正常的。

导出相关问题

问题: ONNX 导出失败

  • 解决方案: 确保安装了 onnx 和 onnxruntime:uv sync --group test。ONNX 导出要求模型处于 eval 模式且输入 shape 固定。