☰
P40 显卡跑 vllm 报 CUDA error: no kernel image is available,用 TaoToken 统一 Key 排查配置骨架
2026/9/27 22:44:45 网站建设 项目流程

1. P40 跑 vllm 报 no kernel image 到底卡在哪

你手里有一张 Tesla P40,24G 显存,二手价格便宜到让人心动,拿来跑 7B、13B 的量化模型本来挺香。结果 pip 装完 vllm,一启动就给你甩一句CUDA error: no kernel image is available for execution on the device,进程直接退出。这个报错的意思是:你编译出来的 CUDA kernel,里面没有任何一份机器码能在当前这张卡上执行。换句话说,程序带着一堆为别的显卡编译好的二进制,到了 P40 面前发现"没有一个能跑"。

P40 的计算能力是 6.1,属于 Pascal 架构。而 vllm 官方安装文档里写得很清楚,CUDA 后端要求计算能力不低于 7.0,也就是 Volta 起步。你升级 vllm 到 0.8.1 甚至更新版本都没用,因为这不是版本新旧的问题,是预编译 wheel 里压根没打包 sm_60/sm_61 的 kernel。很多人第一反应是"版本太旧",折腾半天升级降级,最后才发现方向从一开始就错了。

这篇内容面向三类人:手上还留着 P40/P100 这类老卡想榨干余热的、正在被这个报错卡住不知道往哪查的、以及想搞清楚"算力架构—wheel 编译目标—驱动版本"这三者关系的人。我会先讲清楚报错的三个根因,再给一套可复制的配置骨架,把 TaoToken 统一 Key 的接入方式一并放进去,最后给你 nvcc 架构校验和最小复现动作,让你五分钟内确认自己的卡到底能不能跑 vllm。

2. 先搞清楚三处根因,别急着升级 vllm

2.1 算力架构不匹配是主因

no kernel image is available这个报错,本质是 CUDA 运行时在 fatbin 里找不到匹配当前 device 的 SASS 或 PTX。P40 是 sm_61,vllm 官方 wheel 在构建时用的TORCH_CUDA_ARCH_LIST通常只覆盖 7.0、7.5、8.0、8.6、9.0 这些。你装上去,PyTorch 和 vllm 自带的算子库里没有 sm_61 的机器码,一调用自定义 kernel 就炸。

你可以用一条命令确认自己的卡算力:

nvidia-smi --query-gpu=name,compute_cap --format=csv

P40 会输出Tesla P40, 6.1。只要这个数字小于 7.0,官方 vllm wheel 基本没戏。

2.2 vllm 预编译 wheel 的 arch 列表

vllm 发布到 PyPI 的 wheel 是预编译的,不会为每张卡单独编译。它的构建脚本里TORCH_CUDA_ARCH_LIST决定了打包哪些架构。你可以装完之后自己验证一下当前环境支持的架构:

python -c "import torch; print(torch.cuda.get_arch_list())"

如果输出里没有sm_61,那 P40 就是跑不了。这不是 bug,是设计取舍——维护 sm_60/61 会显著增加构建体积和 CI 时间,而 Pascal 在数据中心已经属于淘汰梯队。

2.3 驱动与 CUDA 版本只是次要因素

驱动和 CUDA 版本不匹配会引发别的报错,比如CUDA driver version is insufficient,但不会直接导致no kernel image。你 excerpt 里提到用的是 CUDA 12.6,这个版本本身对 Pascal 还是支持的,问题不在 CUDA 版本,而在编译目标。所以别把时间浪费在反复重装 CUDA Toolkit 上。

注意:如果你坚持要在 P40 上用 vllm,唯一的路是从源码编译,并且显式设置TORCH_CUDA_ARCH_LIST="6.1"。但即便编译成功,vllm 的部分 attention 算子和量化 kernel 在 Pascal 上也可能有兼容问题,稳定性没保证。生产环境不建议这么干。

3. TaoToken 前置:统一 Key 把模型通道先理顺

在纠结显卡能不能跑之前,有个更实际的问题:你跑推理是为了调模型,而调模型不一定非得本地跑。P40 这种卡适合跑量化后的小模型做实验,但如果你要的是稳定的 API 通道,本地折腾显卡的性价比其实很低。

TaoToken 在这里的角色是统一 Key 和统一 API 通道。你可以在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 注册后拿到一个 Key,然后用它同时访问多个模型,不用为每个厂商单独维护一套鉴权和 base_url。对于本地跑 vllm 的场景,你可以把 TaoToken 当作对照通道——本地跑不通的时候,先用 API 通道验证你的业务代码逻辑是不是对的,把"模型问题"和"显卡问题"分开。

接入方式很简单,OpenAI 兼容格式,base_url 指向https://taotoken.net/api。下面给一份可复制的配置骨架。

3.1 config.toml 骨架

# ~/.config/taotoken/config.toml # TaoToken 统一 Key 配置骨架 [default] base_url = "https://taotoken.net/api" api_key = "sk-你的TaoToken密钥" timeout = 60 max_retries = 3 [models] # 本地 vllm 通道(P40 编译成功后可用) local_vllm = "http://127.0.0.1:8000/v1" # TaoToken 远程通道(对照验证用) remote_default = "gpt-4o-mini" remote_reasoning = "claude-3-5-sonnet" [logging] level = "info" file = "~/.config/taotoken/taotoken.log"

3.2 settings.json 骨架

{ "provider": "taotoken", "base_url": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY", "default_model": "gpt-4o-mini", "fallback": { "enabled": true, "local_endpoint": "http://127.0.0.1:8000/v1", "local_model": "your-local-model" }, "request": { "temperature": 0.7, "max_tokens": 2048, "stream": true } }

把 Key 放到环境变量里,别硬编码进文件:

export TAOTOKEN_API_KEY="sk-你的TaoToken密钥"

这样你的业务代码只认一个 base_url 和一个 Key,本地 vllm 跑通就切本地,跑不通就切 TaoToken 远程通道,排查问题时不会两头乱。

4. 可复制配置:从校验到最小复现

4.1 nvcc 架构校验

先确认你的 CUDA 工具链认识 sm_61:

nvcc --list-gpu-arch

输出里应该能看到compute_61和sm_61。如果没有,说明你的 CUDA Toolkit 版本太新,已经移除了 Pascal 支持。CUDA 12.x 还保留,13.x 开始逐步移除。

再确认 PyTorch 编译时带了哪些架构:

python - <<'PY' import torch print("torch:", torch.__version__) print("cuda:", torch.version.cuda) print("arch list:", torch.cuda.get_arch_list()) print("device cap:", torch.cuda.get_device_capability(0)) PY

如果arch list里没有sm_61,而device cap是(6, 1),那no kernel image就是必然的。

4.2 最小复现验证动作

写一个最小脚本,直接触发报错,确认问题边界:

# repro_p40.py import torch assert torch.cuda.is_available(), "CUDA 不可用" cap = torch.cuda.get_device_capability(0) print(f"设备算力: sm_{cap[0]}{cap[1]}") # 一个简单的矩阵乘,会调用 cuBLAS kernel a = torch.randn(1024, 1024, device="cuda") b = torch.randn(1024, 1024, device="cuda") c = a @ b print("矩阵乘成功,kernel 可执行") # 如果上面通过但 vllm 报错,说明是 vllm 自定义 kernel 的问题

跑这个脚本:

python repro_p40.py

如果矩阵乘能过,但 vllm 启动时报no kernel image,那就锁定是 vllm 自定义算子没有 sm_61 的编译产物。这时候你有两个选择:源码编译 vllm 并指定TORCH_CUDA_ARCH_LIST="6.1",或者换 llama.cpp 路线。

4.3 源码编译 vllm 的尝试(不保证稳定)

如果你非要试,可以这样:

export TORCH_CUDA_ARCH_LIST="6.1" export VLLM_TARGET_DEVICE=cuda pip install -e . --no-build-isolation

编译过程可能几十分钟,而且大概率会在某些算子处报错。实测下来,P40 上编译 vllm 的成功率不高,即使编译过了,推理速度也远不如预期。所以这条路我只建议做技术验证,不建议上生产。

4.4 用 TaoToken 通道做对照验证

在本地折腾的同时,用 TaoToken 跑一遍同样的请求,确认你的业务代码没问题:

# check_taotoken.py import os from openai import OpenAI client = OpenAI( base_url="https://taotoken.net/api", api_key=os.environ["TAOTOKEN_API_KEY"], ) resp = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "用一句话解释什么是 CUDA 计算能力"}], ) print(resp.choices[0].message.content)

如果这段能正常返回,说明你的网络、Key、SDK 都没问题,问题纯粹在本地显卡和 vllm 的兼容性上。这样排查范围一下就缩小了。

5. 本篇常见错排查

5.1 升级 vllm 后报错依旧

这是最常见的误区。no kernel image不是版本问题,是编译目标问题。升级到 0.8.1、0.9.x 都一样,因为官方 wheel 的 arch 列表没变。别在这上面浪费时间。

5.2 装了 CUDA 12.6 还是报错

CUDA 版本和 kernel 编译目标是两回事。你装 CUDA 12.6 只是让运行时可用,但 wheel 里没有 sm_61 的机器码,运行时照样找不到。检查torch.cuda.get_arch_list()才是关键。

5.3 报错信息里出现 sm_70 相关字样

有些报错会提示PTX was compiled for sm_70,这说明 wheel 里带了 PTX 但没有 SASS。PTX 理论上可以 JIT 编译到 sm_61,但 vllm 的构建通常禁用了 JIT fallback,所以还是跑不了。你可以在启动时加CUDA_FORCE_PTX_JIT=1试试,但成功率很低。

5.4 换 llama.cpp 后模型加载失败

llama.cpp 走的是 GGUF 格式,你需要先把 safetensors 转成 GGUF。转换脚本在 llama.cpp 仓库的convert_hf_to_gguf.py。转换时注意量化等级,P40 上 Q4_K_M 比较稳。转完之后用 ollama 加载,P40 是能正常跑的,这条路比硬刚 vllm 靠谱得多。

5.5 TaoToken 请求返回 401

先确认环境变量TAOTOKEN_API_KEY有没有正确 export,再确认 base_url 是不是https://taotoken.net/api(注意结尾没有多余斜杠)。如果用的是 settings.json 里的api_key_env,确认程序真的读到了这个环境变量。401 基本都是 Key 没传对,不是通道问题。

6. 把通道和显卡解耦,才是长期解法

P40 这张卡的价值在于显存大、价格低,适合跑量化模型做实验。但 vllm 的官方支持已经明确把门槛设在 7.0,你硬刚只会不断撞墙。我的建议是把两件事分开:本地用 llama.cpp + ollama 跑 P40 能支持的模型,做离线实验;需要稳定推理或者跑更大模型时,走 TaoToken 的统一 API 通道,用同一个 Key 切换模型,不用为每张显卡的兼容性买单。

如果你正在做 coding agent 或者长期跑的编码任务,可以看看 Coding Plan 那条线,把模型调用和本地环境彻底解耦,显卡换不换都不影响业务。接入文档在 https://taotoken.net/api 对应的 doc 页面,API Keys 在 console 里管理。先把通道理顺,再决定要不要为 P40 折腾编译,顺序别搞反了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询