SenseNova-Vision 跑在内网机器上——显卡和驱动该按什么顺序确认?

文章导读
内网机器跑 SenseNova-Vision,排查顺序建议自下而上:系统是否认卡、驱动版本是否满足运行时要求、运行时能否被加载、推理框架与依赖能否导入、最后才是权重加载和单图推理。越底层的环境越先固定,报错越容易归层;反过来先装框架再回头查驱动,通常会把“驱动不够”伪装成“框架装不上”,在内网里来回试错的成本很高。离线环境下还要额外把 wheel 包和系统库提前备到本地目录。
📋 目录
  1. A 先确认显卡被系统识别、驱动版本可用
  2. B 再确认运行时能被加载
  3. C 然后确认推理框架装得上、能导入
  4. D 最后才做权重加载与单图推理
  5. E 把整条链路写成一份可复用的自检脚本
A A

内网机器跑 SenseNova-Vision,排查顺序建议自下而上:系统是否认卡、驱动版本是否满足运行时要求、运行时能否被加载、推理框架与依赖能否导入、最后才是权重加载和单图推理。越底层的环境越先固定,报错越容易归层;反过来先装框架再回头查驱动,通常会把“驱动不够”伪装成“框架装不上”,在内网里来回试错的成本很高。离线环境下还要额外把 wheel 包和系统库提前备到本地目录。

内网机器排查 SenseNova-Vision 环境,建议按“系统认卡 → 驱动版本 → 运行时 → 推理框架依赖 → 权重与单图推理”自下而上确认。每一层先用一条命令或一段最小导入验证通过再往上走,这样驱动缺失、运行时未加载、依赖缺包、权重或显存问题才能分开定位。离线机器要把 wheel 包和系统库提前备好,否则报错会混在多层里,难以判断该改哪一处。

先确认显卡被系统识别、驱动版本可用

这一步只回答一个问题:设备到底有没有被系统认到。先看硬件是否出现在总线上,再看驱动是否正常加载。

lspci | grep -i -E "vga|3d|display"
nvidia-smi
nvidia-smi -L
cat /proc/driver/nvidia/version
nvidia-smi `--query-gpu`=name,driver_version,memory.total `--format`=csv

解读方式:lspci 里看不到 NVIDIA 设备,说明卡在硬件或虚拟化层,先查 PCIe 插槽、供电、BIOS 以及虚机/容器是否做了显卡直通,此时装任何框架都没有意义。nvidia-smi 输出 No devices were found 或 couldn't communicate with the NVIDIA driver,基本落在驱动层,需要重装或升级驱动。nvidia-smi 右上角显示的 CUDA Version 是当前驱动支持的上限,不代表机器上已经装了对应版本的运行时,请结合后面运行时自检一起判断。

再确认运行时能被加载

驱动通过后,下一步验证运行时(CUDA / cuDNN 等)是否能被 Python 侧真正调用。这一步的作用是把“驱动没装好”和“运行时没配好”分开。

SenseNova-Vision 跑在内网机器上——显卡和驱动该按什么顺序确认?
python -c "import torch; print(torch.__version__, torch.version.cuda, torch.cuda.is_available(), torch.cuda.device_count())"
python -c "import ctypes; ctypes.CDLL('libcudart.so')"

期望输出是 is_available() 为 True 且 device_count() 大于 0。常见报错特征可以这样区分:libcuda.so.1: cannot open shared object file 或 libnvidia-ml.so 找不到,多是驱动库或容器挂载缺失;CUDA driver version is insufficient for CUDA runtime version 表示驱动版本低于运行时要求,需要升级驱动或降到匹配的运行时;no CUDA-capable device is detected 多半是容器里没有透传设备或权限不足,检查容器启动参数和 /dev/nvidia* 是否可见。

然后确认推理框架装得上、能导入

内网机器不能临时联网,所以推理框架和它的依赖要在外网机器上先下好,再整体搬进内网。准备清单通常包括:框架自身的 wheel 或镜像、与运行时匹配的 torch、numpy、pillow、transformers、tokenizers、sentencepiece、accelerate、einops 等 requirements 里声明的包,以及 Python 版本一致的解释器。

SenseNova-Vision 跑在内网机器上——显卡和驱动该按什么顺序确认?
# 外网机器上执行
pip download -r requirements.txt -d ./wheelhouse
# 内网机器上执行
pip install `--no-index` `--find-links`=/opt/wheelhouse -r requirements.txt
pip install `--no-index` `--find-links`=/opt/wheelhouse ./sensenova_vision-*.whl
# 导入自检(把包名换成实际的顶层模块名)
python -c "import sensenova_vision as m; print(getattr(m, '__version__', 'imported'))"

缺包的报错形态要分清:ModuleNotFoundError: No module named 'xxx' 是纯 Python 依赖没装上,补 wheel 即可;ImportError: libxxx.so: cannot open shared object file 是系统级库缺失,属于运行时或系统层,需要补 apt/yum 包,光拷 wheel 解决不了;ImportError: cannot import name ... 往往是包版本冲突,需要用 pip check 或逐个固定版本来排除。建议先确认 pip `--version` 和 Python 版本与打 wheel 时一致。

最后才做权重加载与单图推理

走到这一步,环境问题基本排除,剩下的问题范围收敛到权重文件和输入本身。分层对照可以按报错关键词判断:

  • 文件找不到:FileNotFoundError、unable to open file、分片索引缺失,属于权重层,检查路径、读取权限以及分片文件是否完整复制。
  • 精度或格式不匹配:size mismatch、unexpected key(s) in state_dict、dtype 不符(如权重是 bfloat16 而设备或运行时只接受 float16),属于权重层与框架层之间,检查 dtype 参数与模型版本是否对应。
  • 显存不足:CUDA out of memory,属于运行时加权重层,可尝试减小输入分辨率、降低 batch、切换半精度,先确认不是别的进程占着卡。
  • 输入形状或 dtype 不符:Expected ... but got ...,属于输入预处理层,检查图片通道数、归一化和尺寸是否符合该模型预期。
cd /opt/sensenova-vision && python infer_smoke.py \
  `--weights` /data/models/xxx \
  `--image` /data/test/one.jpg \
  `--device` cuda:0

单图跑通后,再考虑批量或并发;把单图作为最小验证基线,后续问题才有对照。

SenseNova-Vision 跑在内网机器上——显卡和驱动该按什么顺序确认?

把整条链路写成一份可复用的自检脚本

换机器时最省事的做法是把上面四层串成一个脚本,逐层打印通过与否,失败就停在该层并给出下一步动作。

#!/usr/bin/env bash
set -u
PKG=${PKG:-sensenova_vision}

step1() {
  echo "[1/4] 设备与驱动"
  lspci | grep -i -E "vga|3d|display" >/dev/null || { echo " FAIL: 系统未识别显卡,查 PCIe/直通"; return 1; }
  nvidia-smi -L >/dev/null 2>&1 || { echo " FAIL: 驱动层异常,重装或升级驱动"; return 1; }
  nvidia-smi `--query-gpu`=name,driver_version,memory.total `--format`=csv
}

step2() {
  echo "[2/4] 运行时"
  python - <<'PY' || { echo " FAIL: 运行时未加载,查 CUDA/driver 匹配与容器设备"; return 1; }
import torch
assert torch.cuda.is_available(), "cuda not available"
print(" runtime ok:", torch.version.cuda, torch.cuda.device_count())
PY
}

step3() {
  echo "[3/4] 推理框架"
  python -c "import $PKG" 2>/dev/null || { echo " FAIL: 导入失败,补 wheel 或系统库"; return 1; }
  echo " framework ok"
}

step4() {
  echo "[4/4] 权重与单图"
  python infer_smoke.py `--weights` "$W" `--image` "$IMG" `--device` cuda:0 \
    || { echo " FAIL: 看是路径、dtype 还是显存(见分层对照表)"; return 1; }
  echo " inference ok"
}

step1 && step2 && step3 && step4 && echo "ALL PASS" || echo "STOP at first failure"

脚本里每一层的失败提示都指向具体的下一步:第 1 层失败查硬件与驱动,第 2 层失败查运行时与容器设备,第 3 层失败补依赖,第 4 层失败按报错关键词归到权重、精度或显存。把这份脚本和 wheelhouse 目录一起留在内网,下次换机器或重建镜像时直接复用,比重新按经验猜哪一层出问题要稳。