先说句实在话vLLM 在 Windows 上不能直接装、不能直接跑想在一台 Windows 机器上把 Qwen3-8B-FP8 推理服务拉起来绕不开 WSL2。我这次从完全空白的 Ubuntu 子系统开始一步步装驱动、配 CUDA、拉模型、起服务最后成功用 OpenAI 兼容接口跑通了对话和压测。整个过程踩了不少坑这篇就当作一份可以照着抄的实战记录。适合手里有 NVIDIA 显卡显存建议 12GB 以上、想在本地体验大模型部署、或者后续准备迁移到 Linux 服务器的同学参考WSL2 里的操作和原生 Ubuntu 几乎一模一样学会这套后面换服务器也通用。1. 方案选型为什么 Windows 上跑 vLLM 首选 WSL21.1 vLLM 在 Windows 原生环境的天花板vLLM 从设计之初就没打算兼容 Windows。它的核心依赖 PagedAttention、CUDA Graph、以及大量针对 Linux 编译的 CUDA 扩展算子这些组件和 Linux 内核、glibc、CUDA runtime 的耦合非常深。Windows 上虽然有 CUDA 支持但 vLLM 官方根本不提供 Windows 分支社区也没有维护完整的移植版本。真有人尝试在 Windows 下硬编译最终基本都会卡在算子注册、链接库缺失、甚至是文件路径分隔符这类莫名其妙的问题上。所以大部分“Windows 跑 vLLM”的教程都会让你装 WSL2这其实不是绕路而是最省力的正路。WSL2 本质是个轻量虚拟机里面跑完整 Linux 内核微软通过 GPU-Paravirtualization 技术把 NVIDIA 显卡直接透传给 Linux 子系统。vLLM 在 WSL2 里跑跟在原生 Ubuntu 服务器上跑底层环境几乎一致性能损耗也很小我实测推理吞吐大概比裸 Linux 低 3% 到 5%日常使用根本感知不到差别。1.2 WSL2、Docker、原生安装三条路线怎么选我把市面上的方案分成三类分别说下适用场景。第一种是 WSL2 内 pip 安装 vLLM。这条路环境干净、链路透明vLLM 版本、PyTorch 版本、Python 版本都能自己控制出问题也方便排查适合想深入理解部署原理、后续要改代码或者调试源码的人。缺点是步骤多要手动装 Miniconda、配环境、处理依赖冲突。第二种是 Docker Desktop vLLM 官方镜像。官方在 Docker Hub 上维护了vllm/vllm-openai镜像拉下来docker run --gpus all就能跑CUDA 和 PyTorch 都不用自己装最适合快速验证“这模型到底能不能跑”。缺点是镜像体积大动辄几个 GBDocker Desktop 本身还吃内存如果要改 vLLM 内部参数或二次开发容器里的环境反而碍手碍脚。第三种是 Windows 原生安装。结论很明确不推荐纯属浪费时间。我的建议是第一次接触 vLLM、想快速看效果用 Docker准备长期使用、或者后面要接别的 Python 项目用 WSL2 手动装。这篇教程默认走 WSL2 手动安装路线因为步骤最完整能帮你把每个环节都搞清楚。1.3 硬件门槛与显存预算先确认你的硬件够不够。显卡必须是 NVIDIA这是硬性要求AMD 在 vLLM 上只有实验性的 ROCm 路径一线使用基本没有维护别碰。显存方面Qwen3-8B-FP8 的 FP8 权重大约占 8GB再加上 CUDA context、KV cache、运行时激活12GB 显存属于勉强能跑需要把上下文长度压到很低16GB 比较舒适24GB如 RTX 3090/4090基本随便造。Windows 系统版本建议 Windows 10 21H2 以上或 Windows 11老版本 WSL2 的 GPU 透传支持不完整容易出现“装好了但检测不到显卡”的诡异情况。如果不确定自己系统版本WinR 输winver看一眼就行。2. 环境搭建WSL2 GPU 透传 Python 全流程2.1 五分钟装好 WSL2 与 Ubuntu安装 WSL2 现在非常简单管理员身份打开 PowerShell 或 CMD执行一条命令wsl --install这条命令会自动启用 WSL2 功能、安装虚拟化平台、下载并安装 Ubuntu 发行版。装完按提示重启电脑重启后 Ubuntu 会自动弹出初始化窗口设置 Linux 用户名和密码。注意这个账号密码只在 WSL 内部生效和 Windows 登录账号无关但一定要记好后面sudo安装软件都要用。如果你的机器以前装过旧版 WSL先手动升级到最新再继续wsl --update wsl --set-default-version 2装完验证一下版本wsl -l -v看到 Ubuntu 的 VERSION 列是 2说明 WSL2 正常。如果显示 1执行wsl --set-version Ubuntu 2手动转换。首次转换可能要几分钟耐心等。2.2 让 WSL2 识别你的 NVIDIA 显卡这一步很多人栽跟头。WSL2 里不需要单独装 NVIDIA 驱动驱动是通过 Windows 侧透传进去的但前提是 Windows 侧的驱动版本足够新。Windows Update 自动推送的驱动经常偏旧WSL 的 GPU 透传功能对驱动版本有要求旧驱动会导致 Ubuntu 里根本看不到显卡。建议直接去 NVIDIA 官网下载最新的 Game Ready 或 Studio 驱动手动装完重启。然后进入 Ubuntu 终端nvidia-smi如果你能看到类似这样的输出----------------------------------------------------------------------------- | NVIDIA-SMI 560.94 Driver Version: 560.94 CUDA Version: 12.6 | ----------------------------------------------------------------------------- | GPU Name Persistence-Mode | Bus-Id Display-Active | | 0 NVIDIA GeForce RTX 4090 On | 00000000:01:00.0 On | -----------------------------------------------------------------------------说明 GPU 透传成功。如果提示command not found先确认驱动是不是太旧如果提示No devices were found多半是 Windows 驱动版本不够去升级一次再试。这里有个小坑nvidia-smi里显示的 CUDA Version 是驱动支持的最高 CUDA 版本不是系统里实际安装的 CUDA toolkit 版本。vLLM 的 PyTorch 轮子会自带 CUDA runtime所以其实不一定要手动装 CUDA toolkit但这一步能确认 GPU 可见性非常关键。2.3 Python 环境隔离与文件系统避坑WSL2 的 Ubuntu 自带 Python 3但我不建议直接用系统 Python包管理太混乱。装 Miniconda 是最省心的方式cd ~ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh安装过程中一路 yes装完重开终端让 conda 生效。然后创建一个干净的 Python 环境conda create -n vllm python3.11 -y conda activate vllmPython 3.11 是我测下来和 vLLM 0.8.x 兼容性最好的版本3.12 也能用但某些依赖包在 3.12 上的轮子更新不及时遇到问题排查成本高没必要冒险。文件系统这块必须提醒模型权重一定要放在 WSL2 的 Linux 文件系统里也就是~/目录下不要放到/mnt/c/开头的 Windows 盘路径。WSL2 访问/mnt/c/是跨文件系统操作走的是 9P 协议IO 性能比原生 ext4 慢一个数量级。模型文件动辄 10GB 以上加载时慢到你怀疑人生。我一开始图省事把模型放在 D 盘加载直接卡了二十多分钟后来挪到~/models/下一分钟不到就加载完了。3. 安装 vLLM 与获取 Qwen3-8B-FP8 权重3.1 锁版本安装 vLLM验证 GPU 状态激活 conda 环境后安装 vLLMpip install vllm这条命令会自动拉取 vLLM 主体以及 PyTorch、transformers、tokenizers 等依赖。我的建议是安装时固定一个经过验证的版本比如pip install vllm0.8.5vLLM 版本迭代非常快几乎每个月都有大版本更新偶尔会引入破坏性变更。锁定版本后遇到问题查文档、搜 issue 都方便定位。以后想升级再主动改版本号。安装完做两个验证。先确认 vLLM 本身python -c import vllm; print(vllm.__version__)再确认 PyTorch 能不能调用 GPUpython -c import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))输出True NVIDIA GeForce RTX 4090这类信息说明 PyTorch 已经正确识别显卡整个 GPU 链路彻底打通。注意区分“显卡驱动可用”和“PyTorch 可用”。nvidia-smi正常只能说明驱动层没问题而 PyTorch 能否调用 GPU 取决于 CUDA 运行库是否匹配所以这两个验证都要做。3.2 下载 FP8 权重Hugging Face 与 ModelScope 双通道模型权重的获取国内用户建议优先用 ModelScope下载速度快不需要额外配置。先安装 CLIpip install modelscope然后下载模型这里模型 ID 用Qwen/Qwen3-8B-FP8举例实际下载时以你在 ModelScope 或 Hugging Face 上搜到的仓库名为准modelscope download --model Qwen/Qwen3-8B-FP8 --local_dir ~/models/Qwen3-8B-FP8Hugging Face 命令类似pip install huggingface_hub huggingface-cli download Qwen/Qwen3-8B-FP8 --local-dir ~/models/Qwen3-8B-FP8无论走哪个通道下载完成后都检查一下目录结构ls -lh ~/models/Qwen3-8B-FP8正常情况下你会看到config.json、tokenizer.json、model.safetensors.index.json以及若干分片后的model-00001-of-0000X.safetensors文件。还有个验证技巧看总文件大小。8B 参数用 FP8 存储权重总量应该在 8GB 到 9GB 之间。如果模型文件加起来接近 16GB那这个仓库很可能是 BF16 原版只是名字里带了“FP8”启动参数就要相应调整。3.3 FP8 格式细节与显存占用实测FP8 是 8 位浮点数格式相比 BF1616 位浮点权重占用直接减半。Qwen3-8B 的 BF16 权重约 16GBFP8 权重约 8GB。显存省下来的同时由于数据传输量减少推理速度通常也能提升 20% 到 40%精度损失对对话任务来说几乎感知不到。但这里有个容易踩的坑FP8 量化有几种不同实现格式常见的是 FP8 和 AutoFP8。vLLM 启动时加载 FP8 权重--quantization参数有时要写fp8有时要写auto_fp8具体看模型仓库是用什么工具量化的。最稳妥的办法是下载后打开config.json看有没有quantization_config字段quantization_config: { quant_method: fp8, activation_scheme: static }quant_method是fp8就对应--quantization fp8如果是auto_fp8就写--quantization auto_fp8。有些新版本 vLLM 也能自动识别但显式指定最保险避免启动时报格式不匹配。显存预算方面我用 24GB 显存的 RTX 4090 实测Qwen3-8B-FP8 各部分占用大致如下项目占用估算说明模型权重约 8GBFP8 量化后CUDA context0.5~1GB加载即占用KV cache2~8GB随 max-model-len 增大而增大推理激活0.5~2GB动态变化如果你的显卡只有 12GB优先压缩--max-model-len。比如把 32768 降到 8192能一下省出五六 GB 显存。对普通对话场景8192 上下文长度已经完全够用。4. 启动服务与参数调优把 Qwen3-8B-FP8 跑出最佳性能4.1 最小可用配置一行命令跑通服务环境就绪后启动 vLLM 服务vllm serve ~/models/Qwen3-8B-FP8 \ --quantization fp8 \ --dtype auto \ --max-model-len 8192 \ --gpu-memory-utilization 0.90 \ --served-model-name qwen3-8b \ --host 0.0.0.0 \ --port 8000看到Application startup complete.或Uvicorn running on http://0.0.0.0:8000就是启动成功了。第一次启动时 vLLM 会做 CUDA graph 捕获和 W4A16 / FP8 算子预热耗时一到三分钟期间 GPU 占用率飙到 100% 是正常现象别以为卡死就关了。有个容易被误判的日志启动过程中会打印一行[pynccl.py:113] vllm is using nccl2.30.7。这不是报错只是提示当前 NCCL 版本。很多新手看到带error字样的日志就慌其实要看日志级别ERROR才是真问题INFO和WARNING大多可以忽略。4.2 核心参数逐项拆解与调优建议上面那串命令里每个参数都不是随便写的逐个说下作用参数作用建议--quantization fp8指定 FP8 加载格式按 config.json 的 quant_method 调整--dtype auto权重精度自动匹配固定用 auto 即可--max-model-len 8192最大上下文长度显存不够就先降这个--gpu-memory-utilization 0.90允许使用的显存比例同时跑别的任务就降到 0.7--served-model-name qwen3-8bAPI 里显示的模型名客户端调用时 model 字段要用这个名字--host 0.0.0.0监听所有网卡允许局域网访问注意安全--port 8000服务端口冲突时换一个还有几个进阶参数我建议加上--enable-prefix-caching \ --kv-cache-dtype fp8--enable-prefix-caching开启前缀缓存。如果你做 RAG 或者多轮对话每次请求都会带上同样一大段系统提示词开启后 vLLM 会复用这些 token 的 KV cache首 token 延迟能降 30% 以上。--kv-cache-dtype fp8是把 KV cache 也用 FP8 存储显存占用还能再省一截。这个参数对显存紧张的用户非常友好缺点是极端长上下文下精度可能轻微下降对话场景基本无感。多卡用户会用到--tensor-parallel-size比如两张卡就设 2。但这是进阶玩法单卡不要动它设成 1 就行。4.3 API 联调与吞吐压测实录服务起来后先用 curl 验证最基础的通路curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen3-8b, messages: [{role: user, content: 你好请简单介绍一下你自己}], max_tokens: 256, temperature: 0.7 }能返回 JSON 格式的回复就说明推理链路完全跑通了。日常开发我更推荐用 Python 的 openai 包因为 vLLM 服务完全兼容 OpenAI API 格式所有基于 OpenAI SDK 的代码都可以零改动切换过来from openai import OpenAI client OpenAI( base_urlhttp://localhost:8000/v1, api_keyEMPTY, # vLLM 不校验 key随便填 ) resp client.chat.completions.create( modelqwen3-8b, messages[{role: user, content: 用一句话解释 FP8 量化}], max_tokens256, ) print(resp.choices[0].message.content)跑通了聊天接口再测一下真实性能。vLLM 自带了压测工具新版叫vllm bench servevllm bench serve --model qwen3-8b --tokenizer ~/models/Qwen3-8B-FP8也可以自己写个简单脚本统计首 token 延迟和生成速度。我在 RTX 4090 上的实测参考值单请求、256 tokens 输出首 token 大约 60ms生成速度稳定在 90~110 tokens/s并发 8 路请求时总吞吐能到 400 tokens/s 左右。这个性能跑个人项目、小团队内部工具绰绰有余。5. 常见问题速查与避坑经验5.1 最容易踩的 5 个高频坑我把这次部署遇到的坑和排查思路整理成一张速查表现象原因解决方法WSL2 里nvidia-smi找不到 GPUWindows 驱动过旧去 NVIDIA 官网装最新驱动后重启启动时报 CUDA out of memory显存不够降低--max-model-len和--gpu-memory-utilization加载模型报量化格式不匹配FP8 格式和参数不对应看 config.json 的 quant_method改用auto_fp8API 请求超时无响应端口被防火墙拦截或模型加载未完成检查日志是否已经Application startup complete模型加载极慢CPU 占用 100%模型放在/mnt/c/跨盘读取移到~/models/下第一个坑最隐蔽。你装了最新驱动重启完 Windows 后直接进 WSL2 执行nvidia-smi可能仍然是找不到设备。这时候先确认一下 Windows 侧驱动确实加载了然后在 PowerShell 里执行wsl --shutdown彻底关闭 WSL 再重新进去很多时候 GPU 透传是在 WSL 启动时才建立的不重启 WSL 加载不了新驱动。第二个坑也很常见。有些模型仓库的 config.json 里默认的max_position_embeddings是 32768如果你不手动传--max-model-lenvLLM 会按这个上限预留 KV cache显存小的卡直接 OOM。遇到 OOM 优先降这个参数不要一味调低--gpu-memory-utilization后者是全局限流连权重加载都可能失败。5.2 推理变慢时的排查路径服务能跑但慢是另一类高频问题。我一般按下面顺序排查先确认模型是不是真的以 FP8 加载了。启动日志里找Loading model weights took后面会带实际加载的数据类型如果显示torch.float8_e4m3fn就是 FP8 生效如果显示torch.bfloat16说明--quantization参数写错了或者模型本身就不是 FP8权重会多占一倍显存速度自然上不去。再检查 CUDA graph 是否捕获成功。vLLM 启动完成后日志里会有类似Capturing CUDA graph的记录。如果这一步失败vLLM 会退回到 eager mode推理速度可能掉 50% 以上。CUDA graph 捕获失败多半是因为显存不够给模型留点余量别把--gpu-memory-utilization开到 0.98。最后看看是不是并发设置的问题。默认--max-num-seqs 256意味着最多可以有 256 个序列共享 GPU序列太多时每请求分到的算力会被稀释单请求延迟变高。如果是交互式应用可以调低到 32 或 64换来单请求更低的延迟。5.3 WSL2 内存、交换分区与持久化配置WSL2 默认会占用 Windows 端最多 50% 的内存这在跑大模型时可能不够用。你可以通过C:\Users\你的用户名\.wslconfig文件手动限制[wsl2] memory16GB processors8 swap8GB改完记得在 PowerShell 执行wsl --shutdown重启 WSL 生效。memory是 WSL 可以使用的最大内存processors是 CPU 核心数swap是交换分区大小。如果你机器内存只有 16GB建议给 WSL 分 12GB 左右留 4GB 给 Windows 本体否则整机容易卡死。还有一个容易忽略的点WSL2 的虚拟机不会自动回收已分配的内存。跑完服务后 WSL 进程可能仍然占着大量内存这时候在 PowerShell 里执行wsl --shutdown再重新进入即可释放。至于持久化WSL2 里conda创建的环境和~/models/目录都会持久化保存重启 Windows 也不会丢失。但如果你的 Windows 系统做重大版本更新偶尔会出现 WSL 实例失联的情况建议定期备份~/models/下的模型文件和配置文件省得重新下载。我个人的习惯是模型权重这类大文件放在 WSL2 的 Linux 文件系统里跑服务长期不用的模型再压缩备份到 Windows 磁盘。这样兼顾了性能和容量也是这次实战下来觉得最合理的使用方式。最后再说一句如果你本地显存实在不够用 Docker 镜像跑同样配置能省去很多环境问题但原理和参数调优思路和 WSL2 完全一致先把这篇的细节吃透换到任何环境都能快速上手。