系统学习 AI 学习路径:从 GPU 运行时到推理、微调与 RAG 评估

版本信息最后核对:2026-10-25

model-load-failed

模型加载失败的定位与修复:权重、权限、显存与量化不兼容。

现象

推理服务启动后很快退出,日志停在下载权重、读取配置、加载分片或初始化 KV Cache 的阶段。进程可能返回明确异常,也可能被 OOM Killer 以 SIGKILL 结束,只留下退出码 137 和没有堆栈的 Killed。在 Kubernetes 上,Pod 往往表现为 CrashLoopBackOff,或者进程仍在重试但 readiness 始终不通过。

常见报错包括 FileNotFoundError、Permission denied、401/403、does not appear to have a file named config.json、requires you to execute custom code、unsupported dtype、quantization method not found、no CUDA-capable device is detected、CUDA out of memory 以及多卡启动时某个 rank 失败后其他 rank 挂起。同一个模型宿主机能起、容器或 Kubernetes 失败时,先查路径挂载、运行用户和 GPU 可见性,而不是模型本身。

快速判断

先读完整日志,定位失败发生在“下载、读取配置、加载权重、初始化缓存、启动服务”中的哪一步。Kubernetes 中要同时看当前日志和上一次退出日志:

kubectl logs <pod> -n <ns> --tail=200
kubectl logs <pod> -n <ns> --previous --tail=200
docker logs --tail=200 <container>

确认路径、权限和磁盘:

ls -ld <model-dir>
namei -l <model-dir>/config.json
du -sh <model-dir>
df -h <model-dir>
id

路径要用实际启动用户验证。符号链接或网络挂载要在容器内再看一次目标是否存在。接着检查权重清单:

ls -lh <model-dir>
python - <<'PY'
import json, pathlib
root = pathlib.Path("<model-dir>")
index = root / "model.safetensors.index.json"
if index.exists():
    data = json.loads(index.read_text())
    missing = sorted({name for name in data["weight_map"].values()
                      if not (root / name).is_file()})
    print("missing:", missing)
PY

确认 GPU 对当前进程是否可见:

nvidia-smi
python -c 'import torch; print(torch.__version__, torch.cuda.is_available(), torch.cuda.device_count())'
env | grep -E 'CUDA_VISIBLE_DEVICES|NVIDIA_VISIBLE_DEVICES|HF_|HUGGING|TRANSFORMERS|HTTP_PROXY|HTTPS_PROXY|NO_PROXY'

可以用下面的对应关系快速缩小范围:

临时设置 HF_HUB_OFFLINE=1 可区分缓存与在线下载问题;成功后仍要修复网络根因,不能把它当长期配置。

常见原因

  1. 权重路径错误:使用了相对路径,而工作目录在容器中已经改变;挂载点拼错;软链接指向容器外;模型文件放在只读镜像层但启动脚本仍假设可写。
  2. 文件权限或运行用户不匹配:目录属主是宿主机的某个 UID,容器内进程使用另一个 UID;路径中间某一级目录缺少执行权限;安全模块限制了读取。只读挂载不是问题,读不到才是。
  3. 权重或配套文件不完整:只下载权重,漏掉 tokenizer、config.json、generation config;索引文件存在但分片缺失;下载中断留下零字节或截断文件;不同 revision 的文件混在同一个目录。
  4. 主机内存或磁盘不足:加载过程中需要暂存和映射文件,多个进程同时加载会放大主机内存占用;临时目录、缓存目录或共享内存空间不足也会导致失败。
  5. GPU 显存不足:模型权重本身放不下,或权重放得下但启动时按上下文长度预分配 KV Cache 失败;同卡还有训练进程、旧服务或其他副本;多卡张量并行没有真正生效。
  6. dtype 与量化方式不兼容:checkpoint 实际是预量化权重,却被当作普通浮点模型加载;或者为了省显存强行指定了 GPU 架构不支持的 dtype;量化后端、内核版本与模型格式不匹配。
  7. 需要远端自定义代码:模型通过 auto_map 引用仓库内的建模文件,而启动时没有允许执行;允许执行后又缺少自定义代码依赖的 Python 包。还有一种情况是加载了不受信任的仓库代码。
  8. 网络、鉴权和缓存问题:私有模型返回 401/403;代理或 HF_ENDPOINT 配置错误;离线节点仍尝试联网;容器没有挂载宿主机的模型缓存,导致重复下载;缓存目录被清理或磁盘已满。
  9. GPU 不可见:容器没有请求 GPU,运行时没有注入设备,CUDA_VISIBLE_DEVICES 设置为空,或者 Kubernetes 节点没有由 device plugin 暴露 nvidia.com/gpu。此时 nvidia-smi 在宿主机正常,不代表应用容器内也正常。
  10. 并行配置不成立:张量并行或流水并行数量超过可见 GPU 数;并行度与模型头数、层数或当前引擎实现不兼容;只给主进程传了配置,Ray 或启动器拉起的子进程没有获得相同环境。
  11. 引擎与模型架构不匹配:当前推理引擎版本不识别该模型结构或新的量化实现,报错位置看起来像权重损坏,实际是代码版本过旧。

排查步骤

  1. 固定复现命令。排除编排层探针、超时和副作用,使用与线上一致的用户、镜像和绝对路径启动。先不覆盖 dtype、量化方式和并行度,让引擎读取模型配置,确认基础路径可用。
vllm serve /models/<model-dir> --host 0.0.0.0 --port 8000
python -m sglang.launch_server --model-path /models/<model-dir> --host 0.0.0.0 --port 30000

本地路径能起、远端仓库名不能起,问题在下载、鉴权或缓存,不在 GPU 参数。

  1. 检查文件清单与内容。查看 config.json 中的 model_type、architectures、torch_dtype、quantization_config 和 auto_map,再核对索引中的分片是否齐全。文件异常小通常意味着截断;若发布方提供校验和,用 sha256sum 对照,不要只凭目录名与总大小判断。

  2. 区分主机 OOM 与显存 OOM。主机侧看 free -h、df -h 和系统日志;GPU 侧用 nvidia-smi 看占用,并判断失败在权重加载还是 KV Cache 预分配。前者处理主机内存或并发加载,后者缩短上下文、调整显存预算或增加并行度。

  3. 检查 GPU 申请链路。裸机或 Compose 环境确认容器启动时确实透传了设备;Kubernetes 环境检查 Pod 的资源声明、RuntimeClass 以及节点上的 device plugin。nvidia.com/gpu 是扩展资源,通常要写进 limits,只在启动脚本里设置环境变量不会让调度器分配整卡。

kubectl get pod <pod> -n <ns> \
  -o jsonpath='{range .spec.containers[*]}{.name}{" "}{.resources}{"\n"}{end}'
kubectl get node <node> -o jsonpath='{.status.allocatable}'
  1. 验证量化与 dtype 路径。quantization_config 存在时,启动参数要匹配对应的量化后端,不能把它当全精度权重再量化。报 unsupported dtype 时核对 GPU 架构、引擎版本和内核支持,不要强行转换 dtype;用真实请求验证输出。

  2. 只对可信模型开启远端代码。只有确认仓库和 revision 可信、审阅过其中的 Python 代码,才使用 --trust-remote-code。开启后若报缺少模块,按仓库锁定的依赖安装,不要在生产镜像里随意升级全部包。安全要求高的环境应优先选择不需要远端代码的模型格式。

  3. 隔离网络与缓存问题。私有仓库先确认登录状态和 token 权限;检查 HF_HOME、缓存目录和下载目录是否挂载到持久卷;确认代理没有把发往镜像站的请求又转给另一个端点。网络不稳定时先下载到本地目录,再用绝对路径启动,避免每次重启都重新下载。

  4. 核对并行配置。列出所有可见 GPU,并确认每个 worker 看到的是同一组设备。张量并行数不能超过可见 GPU 数,还要满足模型结构和引擎的约束;多机场景下要检查每个节点的版本、NCCL 环境和互连配置。把并行度临时降为单卡只用于确认问题,不要因此误判生产容量。

  5. 查看所有 rank 和所有层次日志。多卡启动时第一个失败往往不是打印最响的那个;Kubernetes 中要同时看 head、worker、sidecar 和上一次容器日志。Ray Serve 场景还要确认副本是否真的被调度执行,而不是一直处于初始化。

修复与验证

修复后至少确认:进程稳定、健康端点成功、/v1/models 有预期模型、一次真实生成完整返回。多卡还要确认所有 rank 都完成初始化,日志中没有被淹没的通信错误。Kubernetes 的启动探针和就绪探针要区分“加载中”与“永久失败”,不要用无限重试掩盖配置错误。

curl -fsS http://localhost:8000/health
curl -fsS http://localhost:8000/v1/models
curl -sS http://localhost:8000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model":"<served-name>","messages":[{"role":"user","content":"你好"}],"max_tokens":32}'

不要只看 HTTP 200:确认返回内容无乱码、日志无量化内核警告、显存占用稳定,重启后能在同一路径成功加载。

预防

把模型发布做成可复现的制品:固定 revision,保存文件清单与校验值,记录是否需要远端代码、tokenizer、config 和量化信息。部署前在离线环境加载一次,确认缓存和持久卷真的可用,而不是只在有网络的开发机上成功。

容量上分别评估主机内存和 GPU 显存,按实际上下文与并发做启动测试;共卡副本设定明确限制。GPU 节点统一运行时和 device plugin 检查,并纳入启动自检。升级引擎、驱动或 CUDA 后重新做加载和生成验证,不要只检查容器能启动。探针和告警应能区分“还在加载”与“已经永久失败”。

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. 宿主机上路径存在,容器里却报模型文件找不到或没有权限,应该先检查什么?
  2. 怎样区分“加载权重时 OOM”和“初始化 KV Cache 时 OOM”?
  3. 模型要求 trust_remote_code,在生产环境应怎样处理?
答案
  1. 在容器内用实际运行 UID 检查绝对路径和挂载命名空间,确认软链接目标可见;再用 namei -l 检查路径各级目录的进入权限和文件的读取权限,并核对宿主与容器 UID 映射。不要只在自己的 shell 里 ls 成功就认为应用进程能读。
  2. 看日志停在哪个阶段:权重分片还没加载完就失败,通常先查主机内存、磁盘和分片完整性;权重加载完成、开始按上下文预分配缓存时失败,则重点看 GPU 显存、上下文长度、并发上限和并行度。再看 nvidia-smi 与其他进程,以及系统日志是否出现 OOM Killer,避免把主机内存问题当成显卡问题。
  3. 只对确认可信的仓库和固定 revision 开启,先审阅仓库中的自定义 Python 代码,再在隔离镜像中锁定依赖版本;不要因为启动报错就盲目允许任意远端代码。若无法完成安全审查,应改用不需要执行远端代码的模型或格式。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令