RTX 5090 到手那一刻,我本以为是愉快的开箱即用,结果装完驱动、配好 PyTorch,一跑测试直接甩给我一句CUDA error: no kernel image is available for execution on the device。新卡在 PyTorch 眼里就是个“不认识的设备”,这就是 Blackwell 架构里sm_120带来的第一个下马威。
后面又折腾 FlashAttention 的编译,前前后后踩了一堆坑才把 Qwen 系列大模型在本地顺畅跑起来。这篇文章就把完整的配置过程、版本匹配逻辑和排障记录整理出来,给同样入手了 RTX 5090、想在本地部署大模型的朋友一个可以直接照着做的参考。
1. 为什么 RTX 5090 让老环境一夜之间“全废”
1.1 sm_120 是什么,Blackwell 架构到底改了什么
先说结论:RTX 5090 的计算能力(compute capability)是 12.0,也就是 CUDA 术语里的sm_120。上一代 RTX 4090 是sm_89,专业卡 H100 是sm_90,这三者之间完全是不同的架构代际。
Blackwell 架构相比 Ada Lovelace 和 Hopper,有几个关键变化直接影响软件生态:
- 张量核心全面升级,支持 FP4/FP8 等低精度计算,这也是 Blackwell 主打 AI 推理的核心卖点
- 引入新一代线程块集群(thread block clusters)和 TMA(Tensor Memory Accelerator),对 kernel 的编写方式有影响
- 内存子系统、SM 内部调度单元都做了重新设计
这些改动带来的直接后果是:用旧的 CUDA 版本编译出来的二进制 kernel,在黑维尔 GPU 上根本没法执行。sm_120和sm_89的指令集不兼容,GPU 驱动不会做指令翻译,没有兜底机制,没有 kernel image 就是没有。
所以你会看到很多人在论坛上问“为什么我装好驱动、PyTorch 也能识别显卡,一跑模型就报错”——本质上就是某个组件还是老版本,编译产物里没有 Blackwell 对应的 SASS 代码。
1.2 驱动、CUDA、PyTorch、FlashAttention 的版本链条
这里要理清一个概念:大模型跑起来的依赖链条远比想象中长。最底层是 GPU 驱动,上面是 CUDA Toolkit,再往上是 PyTorch 这类深度学习框架,最后才是 FlashAttention 这种第三方加速库。每一层都得能识别和生成sm_120的代码,这条链才算通。
我整理了一份当时可用的版本对应关系,供参考:
| 组件 | 最低可用版本 | 推荐版本 | 说明 |
|---|---|---|---|
| GPU 驱动 | 570.x | 575.x 或更新 | Blackwell 需要 R570+ 驱动 |
| CUDA Toolkit | 12.8 | 12.8 / 12.9 | 12.8 起正式支持 sm_120 |
| PyTorch | 2.7 | 2.8+ | 需要 cu128 或更新的 wheel 包 |
| FlashAttention | 2.7.x | 2.7.3+ | 需要从源码编译或用新预编译包 |
| vLLM | 0.8.x | 0.8.5+ | 0.8 系列才完整支持 Blackwell |
这几个版本号不是随便选的,是有因果关系的。PyTorch 要支持sm_120,底层得链接到新版的 CUDA runtime;FlashAttention 要支持sm_120,得自己用新版 nvcc 重新编译 kernel;vLLM 同理,它内部集成了大量自定义 CUDA kernel,老版本编译产物根本跑不起来。
所以如果你还在用 PyTorch 2.5 + CUDA 12.4 的组合在 RTX 5090 上跑大模型,报错是必然的,跟你代码写没写对没关系,纯粹是环境版本落后了。
2. 环境准备:把依赖链条一次装对
2.1 硬件确认与驱动安装
装驱动这一步看似简单,其实很容易踩坑。我拿到卡之后,第一件事是在系统里装上了从官网下载的最新驱动,然后确认驱动版本。注意不要只看nvidia-smi显示的驱动日期,要重点看右上角的 CUDA Version,那个数字表示这个驱动最高支持到什么 CUDA 版本。
我当时装的是 575.x 驱动,nvidia-smi输出的最高 CUDA 版本是 13.0,这就意味着向下兼容 CUDA 12.8 完全没问题。如果你看到驱动版本还在 550 或者更老,那必须先升级驱动,否则后面都会被“no kernel image”卡住。
驱动确认之后,还要检查一下 GPU 是否真的被系统识别到:
nvidia-smi重点关注:
- GPU 型号显示为 NVIDIA GeForce RTX 5090
- 显存显示为 32GB(注意 5090 是 32GB GDDR7,比 4090 的 24GB 大了不少,这对跑大模型很关键)
- 驱动版本不低于 570
如果是刚装好驱动,建议重启一次系统,确保驱动模块完全加载。有时候不重启,nvidia-smi能显示但 CUDA 程序会诡异报错,这种问题排查起来很浪费时间。
2.2 创建 Python 环境与安装 PyTorch
驱动准备好之后,接下来是 Python 环境。我推荐用 conda 或 venv 创建独立环境,避免把系统 Python 搞乱。我的操作是:
conda create -n llm python=3.11 -y conda activate llmPython 版本我用的是 3.11,这是因为 PyTorch 对 3.11 的支持最成熟,而且 FlashAttention 编译时的兼容性也最好。3.12 和 3.13 不是不行,只是可能遇到一些第三方依赖还没适配的情况。
接下来安装 PyTorch。这一步非常关键,一定要安装带 CUDA 12.8 支持的版本。我当时用的命令是:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128如果你直接pip install torch,默认安装的很可能是 CPU 版本,或者是不带 Blackwell 支持的 CUDA 版本,那样后面就白折腾了。
装完之后必须立刻验证:
import torch print(torch.__version__) print(torch.version.cuda) print(torch.cuda.is_available()) print(torch.cuda.get_device_capability(0))我当时看到(12, 0)这个输出时,心里才踏实了一半。get_device_capability返回(12, 0)意味着 PyTorch 确实把这块卡识别成了sm_120设备。如果你这里返回的不是(12, 0)或者直接False,那说明 PyTorch 版本不对,停下来重新装,不要继续往下走。
注意:
get_device_capability返回(12, 0)不代表所有组件都能用。这只是 PyTorch 层面识别到了 GPU,真正跑模型时用的 FlashAttention、vLLM 里的 kernel 是另外编译的,它们同样需要支持sm_120。
2.3 从源码编译 FlashAttention 的完整流程
FlashAttention 是这次配置里最折腾的一步,也是收获最大的一步。很多大模型的前向推理和训练都会用到它,尤其是长上下文场景,有没有 FlashAttention,速度和显存占用完全是两个量级。
先说为什么需要从源码编译。FlashAttention 的 PyPI 预编译包长期以来只覆盖主流的 CUDA 版本和 GPU 架构,对于刚发布的新卡,预编译包往往还没有跟上。我当时在 RTX 5090 上直接pip install flash-attn,装是装上了,但一调用就报错,错误信息大概是“no kernel image available”或者直接段错误。所以只能老老实实从源码编译。
编译前先安装 CUDA Toolkit。如果你只是想编译 FlashAttention,不一定要装完整的 NVIDIA 官方 CUDA Toolkit,但 nvcc 编译器必须有。我建议直接用 conda 安装:
conda install -c nvidia cuda-toolkit=12.8这里有个坑:conda 安装的 cuda-toolkit 和系统级的 CUDA 可能会冲突,所以最好在激活的 conda 环境里先确认 nvcc 的版本:
nvcc --version输出应该是 12.8 或更高。如果显示的还是老版本,或者提示找不到 nvcc,需要检查环境变量CUDA_HOME和PATH。
编译 FlashAttention 前还需要设置一个关键环境变量,告诉它目标 GPU 架构:
export TORCH_CUDA_ARCH_LIST="12.0+PTX"这个变量的含义是:为sm_120生成 SASS 代码,同时生成 PTX 代码做向前兼容。加+PTX的好处是,未来如果驱动更新支持了更多特性,PTX 可以即时编译成更优的 SASS,不用重新编译。
然后开始拉代码编译:
git clone https://github.com/Dao-AILab/flash-attention.git cd flash-attention git checkout v2.7.3 # 选择支持 Blackwell 的版本 pip install -e .这里要注意几点:
- GCC 版本不能太老,建议 GCC 11 或 12。太老的 GCC 在处理新版 CUDA 的某些特性时会报错
- 编译时间比较长,大概要 20-40 分钟,取决于机器性能
- 如果编译中途报显存不足(OOM),可以降低编译并行度
编译成功的标志是最后没有红色错误信息,并且能正常import flash_attn:
import flash_attn print(flash_attn.__version__) print(flash_attn.__file__)如果能正常输出,说明 FlashAttention 已经编译成了支持sm_120的版本。我还建议跑一下自带测试来进一步确认:
python -m py_compile $(python -c "import flash_attn; print(flash_attn.__file__)")其实更直接的办法是跑一个真实的 attention 计算来验证结果是否正确。我当时用两个随机的张量做 scale-dot-product attention,对比 FlashAttention 和普通 attention 的输出,确认数值在误差范围内一致,才算真正放心。
3. 跑通大模型:从 transformers 到 vLLM
3.1 用 transformers 验证 FlashAttention 生效
环境配好之后,就该让大模型真正跑起来了。我选的第一个模型是 Qwen2.5-7B-Instruct,因为 7B 模型在 32GB 显存下跑起来非常宽裕,而且 Qwen 系列的中文能力很好,适合本地部署验证。
用 transformers 加载模型时可以显式指定 FlashAttention:
from transformers import AutoModelForCausalLM, AutoTokenizer model_name = "Qwen/Qwen2.5-7B-Instruct" model = AutoModelForCausalLM.from_pretrained( model_name, torch_dtype=torch.bfloat16, attn_implementation="flash_attention_2", device_map="cuda" ) tokenizer = AutoTokenizer.from_pretrained(model_name)这里的关键参数是attn_implementation="flash_attention_2",它会让模型内部的 attention 层使用 FlashAttention 的 kernel。如果 FlashAttention 装得有问题,这一步就会直接报错;如果一切正常,加载完成后就能看到显存被占用了大概 15-16GB,这是 7B 模型在 bf16 精度下的正常水平。
然后测试推理:
messages = [{"role": "user", "content": "RTX 5090 的 sm_120 计算能力有什么特点?"}] text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) inputs = tokenizer(text, return_tensors="pt").to("cuda") outputs = model.generate(**inputs, max_new_tokens=256) print(tokenizer.decode(outputs[0]))跑通之后,我对比了开不开 FlashAttention 的差异。在 7B 模型、2048 token 上下文、生成长度 256 的设置下,开启 FlashAttention 后生成长度 256 大约需要 6-8 秒,不开则要慢 30%-50%,而且长上下文下的显存占用差距更大。FlashAttention 的核心优势是内存效率和计算效率双重优化,在大模型推理和训练场景下收益非常明显。
指定torch_dtype=torch.bfloat16也很重要。Blackwell 架构对 bf16 的支持非常完善,相比 fp16 在数值稳定性上更好,而且速度也不慢。如果你在 5090 上用 fp32 加载 7B 模型,显存直接翻倍,完全没有必要。
3.2 用 vLLM 做更高吞吐的部署
如果只是单次推理验证,transformers 就够用了。但如果你想把这个模型当服务用,或者想同时处理多个并发请求,就需要上 vLLM。vLLM 有非常成熟的 PagedAttention 和 continuous batching 机制,吞吐量比 transformers 高一个数量级。
vLLM 的版本选择很重要。老版本的 vLLM 不认识sm_120,装了也是白装。我当时用的是 0.8.5,这个版本已经能比较好地支持 Blackwell 架构。
安装:
pip install vllm启动服务:
python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct \ --tensor-parallel-size 1 \ --gpu-memory-utilization 0.9 \ --max-model-len 32768 \ --dtype bfloat16这里解释一下参数:
--tensor-parallel-size 1:单卡部署,不用张量并行--gpu-memory-utilization 0.9:允许 vLLM 占用 90% 的显存--max-model-len 32768:最大上下文长度设为 32K--dtype bfloat16:用 bf16 加载模型
启动成功的标志是日志里能看到 GPU 显存信息,并且没有报错。之后就能用标准的 OpenAI API 格式来请求:
curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen/Qwen2.5-7B-Instruct", "messages": [{"role": "user", "content": "你好,介绍一下你自己"}], "max_tokens": 256 }'5120 个 token 的并发压力测试下,vLLM 的吞吐量大概能达到每秒 1000+ token,这个表现已经能和不少云服务比肩了,32GB 显存跑 7B 模型非常富余。实测下来,单张 5090 跑 7B 模型、32K 上下文,显存大概吃 18-20GB,剩下的空间足够给 KV cache 分配,多路并发毫无压力。
如果你想挑战更大的模型,比如 32B 甚至 70B,在 32GB 显存下就需要上量化了。常见方案是 AWQ 或 GPTQ 量化,4bit 精度下 32B 模型大约占 16-18GB 显存,也能流畅跑起来。不过量化之后模型质量会有小幅下降,需要根据实际场景权衡。
4. 常见问题与排查技巧实录
4.1 报错信息速查表
我把这次配置过程中遇到的所有报错和排查方法整理成了表格,方便大家直接搜索对照:
| 报错信息 | 可能原因 | 解决办法 |
|---|---|---|
| CUDA error: no kernel image is available | PyTorch 或 CUDA 版本太老,不认识 sm_120 | 升级到 PyTorch 2.7+(cu128)、CUDA 12.8+ |
| flash_attn 导入成功但调用时报段错误 | FlashAttention 不支持 sm_120 | 用TORCH_CUDA_ARCH_LIST="12.0+PTX"从源码重新编译 |
| 编译 FlashAttention 时报 GCC 版本错误 | GCC 太老 | 安装 GCC 11 或 12 |
| RuntimeError: CUDA out of memory | 模型太大或上下文太长 | 降低max-model-len,开启量化,或换更小的模型 |
| vLLM 启动时报 “Unsupported GPU” | vLLM 版本太老 | 升级到 vLLM 0.8.x 或更高 |
torch.cuda.get_device_capability返回(0, 0) | 驱动没装好或 PyTorch 版本不对 | 重新安装匹配的驱动和 PyTorch |
4.2 最容易踩的 5 个坑
第一个坑是忽略 GCC 版本。我当时编译 FlashAttention 时用系统自带的 GCC 9,编译到一半直接报错,信息是关于 CUDA 特性和编译器不兼容。后来装了 GCC 12,才顺利编过。建议编译前先检查一下 GCC 版本,不够就直接升级,别浪费时间试旧版本。
第二个坑是TORCH_CUDA_ARCH_LIST设置方式不对。有些人图省事,写的是"12.0"没有加+PTX。这样也能编过,但只生成 SASS 代码,兼容性差一些。加上+PTX之后,如果未来驱动更新,PTX 还能重新 JIT 编译成更优的 SASS,不会浪费新卡的潜力。
第三个坑是用 pip 直接装预编译版 FlashAttention 后以为成功了。pip install flash-attn装的是最新 release 的预编译包,理论上预编译包会包含主流架构,但新卡的架构往往不在其中。当时我验证发现 import 不报错,但一调用就段错误,白白排查了很久。所以对于新卡,不要相信 pip 能直接装,从源码编译最稳妥。
第四个坑是下载模型权重时网络不稳定。Hugging Face 直接下载经常断流,大文件重下很痛苦。我当时用环境变量切到了国内镜像站,或者直接用 ModelScope 下载,速度快很多。具体的做法是:
# 方法一:设置 HF 镜像 export HF_ENDPOINT=https://hf-mirror.com # 方法二:用 ModelScope from modelscope import snapshot_download snapshot_download('Qwen/Qwen2.5-7B-Instruct')第五个坑是跑大模型时没设好模型路径,导致一次性把权重全部加载到内存再拷到显存,速度很慢。用 transformers 时指定device_map="cuda"或者device_map="auto"可以避免这个问题,模型会按层分配到显存和内存中,加载速度会有明显提升。
4.3 显存优化的小技巧
RTX 5090 有 32GB 显存,这个容量对大多数开源模型来说已经相当宽裕了,但也不是无限大。跑 32B 模型、长上下文时还是需要精打细算。
有几个实用技巧:
- 尽量用
bfloat16而不是float16,两者占用一样但 bf16 数值更稳定,Blackwell 对 bf16 的支持更好 - 用
gradient_checkpointing可以在训练/微调时大幅降低显存,代价是变慢 - 推理场景下用 KV cache 量化(比如 KV cache 用 8bit),可以节省不少显存,对长上下文效果显著
- 考虑用
FlashAttention的window_size参数做滑窗注意力,可以控制 KV cache 大小,特别适合超长上下文的场景
如果想在 32GB 显存上跑更大的模型,可以用 AWQ 或 GPTQ 量化。就我实测来看,4bit 量化的 32B 模型在多轮对话的流畅度上,和原模型差距并不明显,但显存占用只有原来的不到一半。这个方案非常适合本地部署场景。
5. 跑通之后还能做什么
环境配好、模型跑通之后,能做的事情就很多了。
如果你对微调感兴趣,可以试试用 LLaMA-Factory 这类工具在 5090 上做 LoRA 微调。32GB 显存做 7B 模型的 LoRA 微调完全够用,甚至 32B 模型的 QLoRA 也能跑。Blackwell 架构的 FP8 能力在训练场景下也有收益,只是相关支持还在持续完善中。
如果你有编程需求,可以部署 CodeQwen 或者 DeepSeek-Coder 这类代码模型,配合 Continue 或 Cline 这类 IDE 插件用本地 API,写代码时的补全和问答响应速度非常快,还不用担心代码上传到第三方服务。
多模态方向也可以尝试,比如 Qwen2-VL 系列,或者用更轻量的多模态模型接入家庭服务器。5090 的 32GB 显存对这些任务来说都是很好的起步配置。
我个人比较推荐的做法是:先用 transformers 跑通一个 7B 模型做功能验证,然后用 vLLM 部署成服务,最后按需求再加 LoRA 微调或换更大的模型。这个路径最平滑,每个阶段的成果都能快速用起来,不会在配置环境上反复折腾。
如果你也刚拿到 RTX 5090 正准备部署大模型,建议按照这篇文章的顺序来配置环境。核心就一句话:驱动上 570+、CUDA 上 12.8+、PyTorch 上 2.7+、FlashAttention 源码编译加TORCH_CUDA_ARCH_LIST="12.0+PTX",vLLM 最低 0.8。这几件事做对了,后面就顺了。