
先说个结论vLLM 这套推理框架官方的主战场从来都是 Linux文档、镜像、CUDA 适配全都是优先照顾 Linux 的。但我日常主力开发机就是一台 Windows 工作站显卡是 NVIDIA RTX 409024GB 显存跑 Qwen3-8B-FP8 这种 8B 量化模型完全足够。折腾了一段时间最终在 Windows 上用 WSL2 方案把 vLLM 服务稳定跑通了。这篇文章就是把我踩过的坑、验证过的命令、合理的参数配置全部整理出来给同样想在 Windows 上部署 vLLM 并跑通 Qwen3-8B-FP8 的朋友一份可以直接照着抄的实战笔记。适合三类人看一是想在自己 Windows 电脑上本地跑开源大模型做测试的开发者二是需要在 Windows 开发环境里为应用提供 OpenAI 兼容接口的后端工程师三是刚接触 vLLM、被“Windows 不支持”劝退但又不甘心的人。我后面写到的所有操作在你动手之前把 NVIDIA 驱动更新到最新版基本就能一路走完。1. 先把思路理顺Windows 跑 vLLM 的三种主流方案1.1 为什么 Windows 原生环境步履维艰很多人最开始都想过直接pip install vllm然后在 Windows 的 cmd 或 PowerShell 里启动。理论上 vLLM 是纯 Python 包但它的底层依赖链条非常长PagedAttention、FlashAttention、torch的 CUDA 扩展、nccl通信库等等这些组件大量使用 C/CUDA 编译产物Windows 原生环境下跑构建脚本经常遇到msvc编译失败、CUDA_HOME找不到、torch版本不匹配等一系列问题。我最早也试过这条路卡在flash-attn编译上整整一个晚上最后放弃了。不是说完全不可能而是时间和产出不成正比。vLLM 社区的官方版本基本只保证 Linux 环境可用Windows 原生部署更像是在“逆天改命”除非你想给 vLLM 项目贡献 Windows 适配的 PR否则真没必要在这条路上死磕。1.2 三条路线横向对比我把实践过的可行方案和它们的优劣势整理成了一张表方便你根据自己的情况做选择。方案实现难度GPU 透传启动速度维护成本适合场景Windows 原生 pip 安装高直接快极高不建议尝试WSL2 Ubuntu 虚拟环境中良好中低开发调试、日常使用Docker Desktop vllm 镜像低良好慢低快速部署、迁移方便原生 pip 方案我直接排除剩下两条主流路线WSL2 内建 Python 虚拟环境和 Docker Desktop 跑 Linux 容器。两条路都能让 vLLM 认为自己跑在一台 Linux 机器上从而完美避开编译问题。1.3 我的选择WSL2 直装、不用 Docker我最终选的是 WSL2 Ubuntu Python venv 这条路线原因有三个。第一Docker Desktop 在 Windows 上本质还是依赖 WSL2 后端等于多套了一层镜像拉取动辄几个 GB启动容器还要等 Docker 引擎就绪而 WSL2 直装 vLLM 直接在发行版里跑链路更短出问题的时候排查起来也简单。第二模型文件如果放在 Windows 磁盘上Docker 挂载模型目录是跨文件系统访问在 WSL2 里读/mnt/d/...的模型文件会比 WSL 内部路径慢不少。我实测过加载同一个 8B 模型从/mnt/d读和从~/models读启动耗时能差出几十秒。所以我后来干脆把模型复制到 WSL 内部文件系统里。第三调试 vLLM 的时候经常要看日志、改参数、重启进程WSL2 下就是一个终端操作哪怕启动参数写错了改一下命令回车再来一波就行Docker 容器每次改参数都要docker run重来等镜像启动的那几十秒虽然不长但多来几次也够烦躁的。2. 环境准备先把 WSL2 和 CUDA 理顺2.1 动手前检查硬件与系统版本在开始敲命令之前有几个硬性条件需要先确认缺一个后面都会白忙NVIDIA 显卡且显存不低于 8GB。Qwen3-8B-FP8 权重大约是 8GB加上 KV cache 和激活值16GB 显存才能跑得比较舒服24GB 属于理想状态。Windows 10 22H2 或 Windows 11WSL2 支持比较成熟。官方建议 Windows 11但 Windows 10 更新到位了也能跑。NVIDIA 驱动更新到最新版。这一点特别重要WSL2 里能不能用上 GPU取决于 Windows 侧的驱动驱动太老会导致 WSL 里nvidia-smi直接报错。可以用nvidia-smi在 Windows 的 cmd 里确认一下驱动版本和显存大小。我当时的驱动版本已经支持 CUDA 12.x后面安装 vLLM 就非常顺。2.2 安装 WSL2 Ubuntu 发行版用管理员权限打开 PowerShell 或 cmd执行wsl --install这条命令会默认启用 WSL2并安装 Ubuntu 发行版。如果你之前装过 WSL1建议强制指定一下版本wsl --set-default-version 2安装完成后重启电脑首次进入 Ubuntu 会让你创建用户名和密码。注意 Ubuntu 的密码输入时屏幕上不会显示字符这是正常的别以为键盘坏了。装完之后在开始菜单打开 Ubuntu 终端先做一件小事更新系统软件源和包。sudo apt update sudo apt upgrade -y2.3 确认 WSL 内能看到 GPU这一步是关键。在 WSL2 里输入nvidia-smi如果能看到和你 Windows 侧一致的一张显卡信息表包括显存、驱动版本、CUDA 版本说明 GPU 透传已经正常工作。我看到 RTX 4090 那张表的时候心里基本就踏实了一半。如果提示nvidia-smi: command not found或NVIDIA-SMI has failed because it couldnt communicate with the NVIDIA driver不用急着装驱动。WSL2 里不需要单独装 NVIDIA 驱动驱动是 Windows 宿主侧统一管理的你只需要更新 Windows 侧 NVIDIA 驱动到最新版在 PowerShell 里执行wsl --shutdown让 WSL 重启。重新进入 WSL 后再跑nvidia-smi大概率就好了。2.4 创建 Python 虚拟环境并安装 vLLMUbuntu 自带的 Python 我没直接往外卖装包而是单独建了一个虚拟环境避免把系统 Python 搞脏。sudo apt install -y python3-pip python3-venv mkdir -p ~/vllm-env cd ~/vllm-env python3 -m venv vllm-stable source ~/vllm-env/vllm-stable/bin/activate激活之后先升级 pip再安装 vLLM。vLLM 包会自动拉取匹配的 PyTorch 和 CUDA 运行时所以直接装就行pip install --upgrade pip pip install vllm我实测时 vLLM 已经迭代到 0.9.x 版本对 Qwen3 系列模型的支持非常成熟。安装过程中会下载torch、flashinfer等一堆依赖体积比较大建议保持网络稳定。装完验证一下版本python -c import vllm; print(vllm.__version__)如果这条命令没有报错说明 vLLM 核心已经装好了。很多人会在这里卡住报torch相关错误多半是 Python 版本问题建议用 Python 3.10 或 3.11我用的就是 3.11全程没踩过 python 解释器层面的坑。3. 下载 Qwen3-8B-FP8 并规划模型目录3.1 FP8 到底比其他精度省在哪要搞懂 Qwen3-8B-FP8 这个名字先拆两半看8B 指模型参数量 80 亿FP8 指权重用 8 位浮点数存储也就是每个参数只占 1 个字节。作为对比平时最常见的 BF16 精度是每个参数 2 个字节。所以单看模型权重Qwen3-8B-BF16约 80 亿 × 2 字节 ≈ 16GBQwen3-8B-FP8约 80 亿 × 1 字节 ≈ 8GB同样是 8B 模型FP8 版本在权重上直接省了一半显存。这还没算上运行时需要的 KV cache 和激活值。如果只有 16GB 显存BF16 版本跑长上下文基本会 OOMFP8 版本则能比较从容地跑 8K 到 16K 上下文。这也是我为什么一口咬定要选 Qwen3-8B-FP8 而不是 Qwen3-8B 原版的原因。3.2 从 ModelScope 拉取模型模型下载我是从 ModelScope 拉的。国内环境访问 ModelScope 快很多而且不需要额外的网络配置。装好 modelscope 客户端pip install modelscope然后执行下载命令modelscope download --model Qwen/Qwen3-8B-FP8 --local_dir ~/models/Qwen3-8B-FP8--local_dir指定模型保存目录我建议放到 WSL 内部文件系统也就是~目录下不要放到/mnt/d这种跨盘路径。原因前面提过跨文件系统读模型文件很慢而且文件数量多时比如 safetensors 分片、tokenizer 文件、配置文件每读一个文件都有额外开销启动时间会明显变长。如果你更习惯 HuggingFace也可以用pip install -U huggingface_hub huggingface-cli download Qwen/Qwen3-8B-FP8 --local-dir ~/models/Qwen3-8B-FP8下载完成后进到目录里看一眼ls ~/models/Qwen3-8B-FP8正常情况下会看到config.json、model.safetensors.index.json、若干个model-00001-of-0000x.safetensors、tokenizer.json等文件。其中config.json里的quant_config字段会标记模型是 FP8 量化格式vLLM 启动时会自动读取并做对应处理不需要我们手动指定量化方式。3.3 显存估算与实际规划Qwen3-8B-FP8 在 vLLM 下的显存占用除了权重那 8GB还有运行时开销KV cache取决于max-model-len和 batch 大小。单请求下8K 上下文大约额外吃 1-2GB 显存32K 上下文会吃到 4GB 以上激活值和 CUDA context约 1-2GB 固定开销。所以我自己定下的底线是16GB 显存可以跑max-model-len建议控制在 819224GB 显存是舒适区max-model-len可以开到 32768 也没压力。显存只有 12GB 的卡建议只跑 4K 上下文或者干脆考虑更小的模型。4. 启动 vLLM 服务并完成第一次对话4.1 启动命令长什么样vLLM 新版本提供了非常简洁的vllm serve子命令一行就能启动 OpenAI 兼容的 API 服务。在 WSL2 激活虚拟环境后执行cd ~ vllm serve ~/models/Qwen3-8B-FP8 \ --served-model-name qwen3-8b-fp8 \ --gpu-memory-utilization 0.90 \ --max-model-len 8192 \ --port 8000第一次启动会加载模型分片、构建 CUDA graph这个过程需要 1-2 分钟屏幕会滚动很多日志。看到类似Starting vLLM server on http://0.0.0.0:8000或者Application startup complete的提示就说明服务已经起来了。我在 4090 上从命令执行到服务就绪大约 80 秒供你参考。如果等了一两分钟还没动静可以 CtrlC 停下来检查日志里的报错多半是显存不够或者驱动问题。4.2 关键启动参数逐一讲透这几个参数值得单独拎出来说因为它们直接决定了服务稳不稳、跑得快不快。--served-model-name这是对外暴露的模型名。请求方通过这个字符串指定要调用的模型所以可以随意起名。我起的是qwen3-8b-fp8方便客户端识别。--gpu-memory-utilizationvLLM 允许模型用到多大比例的显存。默认是 0.90。它不是越高越好——设太高CUDA context 和页面缓存没有余量并发一上来反而容易崩设太低能留给 KV cache 的空间变小同窗口下能容纳的并发请求就少。16GB 显存建议 0.8524GB 显存 0.90 没问题。--max-model-len模型能处理的最大上下文长度包括输入和输出 token 总数。这个值不能超过模型的 RoPE 扩展上限Qwen3 系列普通版一般是 32768。设得越大KV cache 越占显存。如果只是做普通问答8192 就够了要处理长文档再上调。另外还有两个高频参数没写进命令但你自己试的时候大概率会用到--enforce-eager关闭 CUDA graph 加速省显存但推理变慢。显存吃紧时可以先救急。--portAPI 监听端口默认 8000如果被占用就改 8001 等。4.3 用 curl 和 Python 客户端调用模型服务起来了先用 curl 打个招呼确认接口通curl -s http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen3-8b-fp8, messages: [{role: user, content: 你好请用一句话介绍你自己}], temperature: 0.7, max_tokens: 256 }返回的 JSON 里choices[0].message.content就是模型回复。如果这一步通了说明整条链路已经跑通剩下的优化都是锦上添花。更常见的方式是在 Python 代码里用 openai 客户端调用因为我后面要接业务系统所以写了一个最小脚本验证from openai import OpenAI client OpenAI( base_urlhttp://localhost:8000/v1, api_keyEMPTY, ) response client.chat.completions.create( modelqwen3-8b-fp8, messages[ {role: system, content: 你是一个乐于助人的助手。}, {role: user, content: 写一段 50 字左右的短文介绍闪电的形成原因。}, ], temperature0.7, max_tokens512, ) print(response.choices[0].message.content)注意base_url一定带/v1api_key随意填一个值就行vLLM 默认不校验鉴权。5. 性能观察与显存优化实践5.1 先看显存和吞吐再谈调优服务跑起来后别急着调参。先在 WSL2 里另开一个终端跑nvidia-smi看显存占用。我第一次启动后看到显存占用 21GB 左右有点意外因为权重只有 8GB。后面逐步往下调max-model-len和gpu-memory-utilization才理解了显存都花在了哪。vLLM 的显存大头其实是预分配的 KV cache 和 CUDA context。gpu-memory-utilization 0.90的意思是 vLLM 会把 90% 的显存都圈给自己做 buffer所以你在nvidia-smi里看到占用高并不等于模型真的吃了那么多而是 vLLM 在给自己留余量。吞吐量的直接观测方式是看 vLLM 启动日志里的指标或者用压测工具发一批并发请求自己数。我没有专门跑复杂压测只是简单统计了一下 20 个并发请求下的表现在 RTX 4090 上单请求首 token 延迟大约 150ms 左右稳定吞吐大概能到 1500 tokens/s 级别。但这个数字受max-model-len、并发数、输入长度影响很大别当成硬指标参考你自己机器上实测为准。5.2 参数怎么调到最优解调参这件事没有银弹但有明确的优先级。我的经验是先保证不 OOM显存 16GBgpu-memory-utilization降到 0.85max-model-len降到 8192再保证并发够用显存还有余量优先把gpu-memory-utilization往上抬不要先拉max-model-len。因为并发上来了KV cache 更吃紧最后才考虑长上下文如果确实需要处理长文档再把max-model-len加大同时接受并发能力下降。显存max-model-lengpu-memory-utilization适用场景16GB81920.85常规对话、后端 API24GB81920.90常规对话、较高并发24GB327680.90长文档、代码分析12GB40960.85轻量测试、单人使用如果你用 16GB 显卡还嫌显存紧张可以加--enforce-eager再降一档显存占用代价是首 token 延迟会变高因为绕过了 CUDA graph 的加速。5.3 一个值得养成的习惯先小后大我每次拿到一个新环境都不会一上来就启动完整模型。而是先用一个 1B 或 3B 的小模型跑通一遍流程确认 WSL2 的 CUDA、vLLM、API 接口全都正常再换 Qwen3-8B-FP8。这样排查问题时能快速区分“模型问题”还是“环境问题”节省大量时间。6. 常见问题与排查技巧实录6.1 启动报错NVIDIA driver not found 或 CUDA unavailable这个排第一高发。现象是在 WSL2 里输入nvidia-smi报错或者 vLLM 启动时提示找不到 CUDA 设备。多数情况是 Windows 侧驱动太旧少部分是wsl --shutdown之后没彻底重启。我的处理顺序是先更新 Windows NVIDIA 驱动 → 执行wsl --shutdown→ 重新进入 WSL →nvidia-smi。三步搞不定再考虑重装 Ubuntu 发行版但基本轮不到那一步。6.2 安装或导入 vLLM 时 flash-attn 编译失败如果你在纯净环境下pip install vllm一般不会触发 flash-attn 手动编译因为 vLLM 的预编译 wheel 会带上匹配的二进制。但如果你换过 Python 版本、或者手动装了其他 torch 版本就容易被卷入源码编译。我的建议不要手动单独装 flash-attn也不要随意换 torch 版本。vLLM 对 torch 版本有严格约束把 torch 和 flash-attn 都交给 vLLM 的依赖解析器去管。一定要装别的 CUDA 版本时用虚拟环境隔离避免污染。6.3 WSL2 内存太小模型加载直接被杀死默认 WSL2 最多使用宿主机一半物理内存。如果你的 Windows 主机只有 16GB 内存再被浏览器、IDE 占掉大半WSL2 里加载模型很容易 OOM进程直接killed日志里还不一定有明确报错。解决办法是手动限制 WSL2 的资源分配。在 Windows 用户目录下新建或编辑.wslconfig文件[wsl2] memory12GB processors8 swap8GB保存后执行wsl --shutdown再重新进入 WSL用free -h确认内存生效。这里注意memory不能超过物理内存留一些给 Windows 本体和宿主程序。6.4 Docker 方案中 GPU 透传不生效如果你选了 Docker Desktop 路线启动容器时一定要加--gpus all同时 Docker Desktop 设置里必须开启 WSL2 backend 和 GPU 支持。很多人漏了第二步导致容器内nvidia-smi报错然后误以为镜像有问题。另一个 Docker 特有的坑是模型挂载。我建议把模型目录复制到 WSL 内部文件系统后再-v挂载不要直接从 Windows 盘挂。否则不仅是加载慢容器频繁读模型文件时还可能触发文件锁问题Windows 侧文件占用会导致容器读取失败。6.5 常见问题速查表现象最可能原因快速处理WSL 内看不到 GPUWindows 驱动旧或 WSL 未重启更新驱动wsl --shutdown重进vLLM 启动被 killedWSL2 内存不足写.wslconfig限制 WSL 可用内存8000 端口被占用Windows 或 WSL 其他进程占用换--port或关掉冲突进程/mnt/d 加载模型极慢跨文件系统访问复制模型到~目录下Docker 内 nvidia-smi 失败Docker Desktop 未开启 GPU 支持设置里开启 WSL2 GPU passthrough并发请求一多就 429 或超时max-model-len太大或显存余量不足降max-model-len调低gpu-memory-utilization最后再分享一个小技巧如果你在 Windows 上开发把代码运行在 WSL2 里一定要用\\wsl$\Ubuntu\...这个路径访问 WSL 内部文件。很多人把模型下载到 WSL 里之后发现 Windows 侧的 IDE 看不到其实在文件资源管理器地址栏输\\wsl$\Ubuntu\home\用户名\models就能直接打开。VSCode 的 WSL 远程插件也能直接连接 Ubuntu 里的仓库开发和调试体验非常顺滑。这套 Windows WSL2 vLLM 的组合我现在已经当成标准环境在用了后续把服务接到 GPT 兼容的 Agent 框架里也只是换个base_url的事。