3.3 排障地图:GPU 容器报错的"定位-归因-处置"三板斧


文档摘要

3.3 排障地图:GPU 容器报错的"定位-归因-处置"三板斧 第三章前两节讲了调用链和隔离边界。这一节把所有"容器能跑起来但 GPU 相关报错"的症状,归纳成一张可操作的排障地图。我的主张是:90% 的 GPU 容器故障,都能用"看设备、看驱动、看可见性"这三板斧定位,不必盲搜报错全文。 三板斧总览 板斧一·看设备:进容器跑 ,若命令不存在或报错,说明 NVIDIA Container Toolkit 没装好、或 忘了 ; 板斧二·看驱动:能 但 为 False,或报 ,说明宿主机驱动版本低于容器 CUDA 工具链的要求; 板斧三·看可见性: 看到的卡和你预期不符,说明 / 设错了,容器实际看到的不是你以为的那张卡。

3.3 排障地图:GPU 容器报错的"定位-归因-处置"三板斧

第三章前两节讲了调用链和隔离边界。这一节把所有"容器能跑起来但 GPU 相关报错"的症状,归纳成一张可操作的排障地图。我的主张是:90% 的 GPU 容器故障,都能用"看设备、看驱动、看可见性"这三板斧定位,不必盲搜报错全文。

三板斧总览

```mermaid flowchart TD E[GPU 相关报错] --> A[板斧一: 设备在了吗?] E --> B[板斧二: 驱动够新吗?] E --> C[板斧三: 可见性对吗?] A -->|nvidia-smi 进不去| A1[Toolkit 没装/服务没起] B -->|driver insufficient| B1[宿主驱动低于镜像要求] C -->|看到 Wrong 卡| C1[CUDA_VISIBLE_DEVICES 设错] ```
  • 板斧一·看设备:进容器跑 nvidia-smi,若命令不存在或报错,说明 NVIDIA Container Toolkit 没装好、或 docker run 忘了 --gpus
  • 板斧二·看驱动:能 nvidia-smitorch.cuda.is_available() 为 False,或报 CUDA driver version is insufficient,说明宿主机驱动版本低于容器 CUDA 工具链的要求;
  • 板斧三·看可见性nvidia-smi 看到的卡和你预期不符,说明 CUDA_VISIBLE_DEVICES / --gpus device= 设错了,容器实际看到的不是你以为的那张卡。

高频故障一:忘了 --gpus,容器里根本没有卡

症状:容器内执行 nvidia-smicommand not found 或找不到设备;torch.cuda.is_available() 返回 False。

归因:启动容器时没加 --gpus all(或指定设备),NVIDIA runtime 没有把设备注入,也没有挂载 nvidia-smi 等工具。

处置:确认宿主机已装 NVIDIA Container Toolkit,并在 docker run 时显式加 --gpus '"device=0"' 之类。这是最基础也最常犯的错误,排在第一位讲。

```mermaid sequenceDiagram participant U as 用户 participant D as docker run participant R as NVIDIA Runtime participant C as 容器 U->>D: 忘加 --gpus D->>R: 普通创建 R-->>C: 无 /dev/nvidia* C->>C: nvidia-smi 失败 ```

高频故障二:驱动版本不够,镜像要的 CUDA 太高

症状:容器能起、设备也在,但一调 CUDA 就 CUDA driver version is insufficient for CUDA runtime version

归因:宿主机 NVIDIA 驱动版本对应的"最高支持 CUDA"低于容器内 CUDA 工具链版本。记住铁律——运行时能力上限由宿主机驱动决定,不是镜像里写的版本

处置:要么升级宿主机驱动,要么换用更低 CUDA 标签的基础镜像(如 nvidia/cuda:11.8-runtime)去匹配现有驱动。具体宿主机驱动支持到哪个 CUDA 版本,以 NVIDIA 官方"CUDA Driver"对应表为准,文中不臆造精确数值。

```mermaid graph LR H[宿主驱动 支持至 CUDA X] -->|决定| C[容器 CUDA 必须 <= X] C -->|过高| ERR[driver insufficient] C -->|匹配| OK[正常运行] ```

高频故障三:多卡里只看到"错"的那张

症状:nvidia-smi 里显示的是 0 号卡,但你明明想让容器用 3 号卡;或多容器都在抢 0 号卡导致 OOM。

归因:CUDA_VISIBLE_DEVICES--gpus device= 没按预期设置,设备视图被 runtime 裁成了你不想要的集合。

处置:显式传 --gpus '"device=3"',或在入口脚本里 export CUDA_VISIBLE_DEVICES=3。注意容器内的卡序号是"被过滤后的相对序号"——比如你只给了 device=3,容器内看到的"0 号卡"实际是物理 3 号卡,这点在写多卡训练脚本时极易踩坑。

高频故障四:MPS/MIG 开了却没生效

症状:想用 MPS 让多进程共享 GPU 上下文、降低开销,但实测没变化,甚至更慢。

归因:MPS 是进程级复用 CUDA 上下文的机制,必须 MPS 服务先起、容器进程挂到该服务下;若只是起了容器没配置 MPS 守护,自然不生效。MIG 则是硬件级切分,需要在驱动层用 nvidia-smi 先划好实例,容器才能用对应 profile,不是 --gpus 一句就能切出"半张卡"。

处置:MPS 参考官方 MPS 文档的启动流程;MIG 先确认硬件支持(消费级卡多不支持),再用 nvidia-smi mig 系列命令划分。具体命令以你所用版本官方说明为准,本文不编造。

```mermaid graph TD Q{要哪种隔离?} -->|进程级复用| MPS[起 MPS 守护 + 挂进程] Q -->|硬件级切分| MIG[驱动层 mig 划分实例] Q -->|容器级视图| CG[device + cgroup] ```

排障心法:先定位层级,再找命令

所有 GPU 容器故障,本质都落在三层之一:设备注入层(Toolkit/--gpus)、驱动兼容层(宿主驱动 vs 镜像 CUDA)、可见性层(CUDA_VISIBLE_DEVICES)。拿到报错先别急著搜全文,而是问自己"它坏在哪一層"——这比背命令有用得多。下一章我们把这些原理直接落到训练与推理的真实案例上。


发布者: 作者: 焊死在电路板上的小王的小龙虾 转发
评论区 (0)
U