WSL2 + vLLM 本地大模型部署实战指南

从零开始在 Windows 上用 WSL2 搭建 vLLM 推理服务,部署 Qwen2.5 系列模型

作者:z2096 | 日期:2026-07-29

环境:Windows 11 + WSL2 (Ubuntu 24.04) + NVIDIA GeForce RTX 4060 Laptop GPU (8GB)


目录

  1. 环境概览
  2. WSL2 配置
  3. Python 环境搭建
  4. vLLM 安装与版本选择
  5. 模型下载
  6. 启动推理服务
  7. 交互式对话脚本
  8. 常见问题与排错
  9. 后续方向

1. 环境概览

组件版本/规格
操作系统Windows 11 + WSL2
Linux 发行版Ubuntu 24.04.4 LTS
内核6.6.87.2-microsoft-standard-WSL2
GPUNVIDIA GeForce RTX 4060 Laptop GPU
显存8188 MiB (~8 GB)
Python3.12.3 (conda 环境)
vLLM0.10.1 (V0 引擎)
transformers4.55.0
CUDA系统自动检测
$ nvidia-smi
# 显示 RTX 4060, 8GB 显存, CUDA 驱动正常

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04.4 LTS
Release:        24.04
Codename:       noble

2. WSL2 配置

2.1 安装 WSL2

在 Windows 管理员 PowerShell 中:

# 一键安装 WSL2
wsl --install

# 重启电脑后,安装 Ubuntu 24.04
wsl --install Ubuntu-24.04

2.2 设置用户名和密码

首次进入 Ubuntu 后,会提示创建用户名和密码。

# 更新系统
sudo apt update && sudo apt upgrade -y

2.3 确认 GPU 可用

# 在 WSL2 中检查 GPU
nvidia-smi

如果能看到 GPU 信息,说明 NVIDIA 驱动和 WSL2 GPU 直通已正确配置。

在这里插入图片描述[nvidia-smi 输出 + lsb_release -a 输出]


3. Python 环境搭建

使用 Miniconda 管理 Python 环境,避免依赖混乱。

# 创建 vLLM 专用环境(Python 3.12)
conda create -n vllm python=3.12 -y

# 激活环境
conda activate vllm

在这里插入图片描述
[conda create 完成 + conda activate vllm 后终端前缀显示 (vllm)]

$ conda env list
# conda environments:
base    *  /home/z2096/miniconda3
vllm       /home/z2096/miniconda3/envs/vllm

4. vLLM 安装与版本选择

4.1 版本兼容性分析(关键!)

这是本篇最重要的部分。vLLM 版本和 WSL2 的兼容性经历三个阶段:

vLLM 版本引擎WSL2 兼容说明
≤ 0.7.x仅 V0不依赖 UVA
0.8 ~ 0.24V0 + V1 双引擎✅ (需 VLLM_USE_V1=0)V0 可选,WSL2 可用
≥ 0.25仅 V1V1 强制 UVA,WSL2 不支持

UVA (Unified Virtual Addressing) 是 CUDA 特性,让 CPU 和 GPU 共享同一虚拟地址空间。WSL2 的 GPU-PV 虚拟化层不暴露 UVA 接口,这是架构级限制,不是 bug。

4.2 选择 vLLM 0.10.1

我们选择 0.10.1,原因是:

  • V0/V1 双引擎共存时代,加 VLLM_USE_V1=0 可退回 V0
  • 和 transformers 4.55.0 兼容
conda activate vllm

# 安装 vLLM 0.10.1
pip install "vllm==0.10.1" -i https://pypi.tuna.tsinghua.edu.cn/simple

# 安装兼容版本的 transformers(必须!)
# vLLM 0.10.1 要求 transformers>=4.55.0,但不能用 5.x(API 不兼容)
pip install "transformers==4.55.0" -i https://pypi.tuna.tsinghua.edu.cn/simple

# 验证版本
pip show vllm | grep Version
# Version: 0.10.1

pip show transformers | grep Version
# Version: 4.55.0

在这里插入图片描述

[pip show vllm + pip show transformers 输出]

4.3 版本不匹配的坑

坑 1: vLLM 0.25.x 启动报 UVA 错误

$ vllm serve Qwen/Qwen2.5-0.5B-Instruct-AWQ --port 8000
# RuntimeError: UVA is not available

原因:V1 引擎在 buffer_utils.py 硬编码 uva_instead_of_gpu=True,WSL2 没有 UVA。

坑 2: transformers 太新(5.x)导致 AttributeError

$ VLLM_USE_V1=0 vllm serve ...
# AttributeError: Qwen2Tokenizer has no attribute 'all_special_tokens_extended'

原因:transformers 5.x 删掉了旧 API,vLLM 0.10.1 还在调用。降级到 4.55.0 解决。

坑 3: pip 默认装最新版

pip install "vllm>=0.8.5" 没有加 <0.25 上限,直接装了 0.25.1。正确写法:

pip install "vllm==0.10.1"  # 精确版本
# 或
pip install "vllm>=0.8.5,<0.25"  # 范围版本

5. 模型下载

5.1 已下载的模型

$ ls ~/.cache/huggingface/hub/

models--Qwen--Qwen2.5-0.5B-Instruct         # 0.5B 原始版(约 1GB)
models--Qwen--Qwen2.5-0.5B-Instruct-AWQ     # 0.5B AWQ 量化(约 0.5GB)
models--Qwen--Qwen2.5-7B-Instruct-AWQ       # 7B AWQ 量化(约 5.2GB)

在这里插入图片描述

[ls -la ~/.cache/huggingface/hub/ 输出]

5.2 下载新模型的方法

# 方式1: vLLM 启动时自动下载(首次启动较慢)
vllm serve Qwen/Qwen2.5-3B-Instruct-AWQ --port 8000

# 方式2: 用 huggingface-cli 手动下载
huggingface-cli download Qwen/Qwen2.5-3B-Instruct-AWQ \
  --local-dir ~/models/Qwen2.5-3B-Instruct-AWQ

# 方式3: 用 modelscope(国内快)
pip install modelscope
modelscope download --model Qwen/Qwen2.5-3B-Instruct-AWQ

6. 启动推理服务

6.1 启动 0.5B 模型(测试用)

conda activate vllm
cd ~  # 重要:不要在 /mnt/ 下执行,I/O 极慢

VLLM_USE_V1=0 vllm serve Qwen/Qwen2.5-0.5B-Instruct-AWQ \
  --host 0.0.0.0 --port 8000 \
  --max-model-len 2048

参数说明:

参数含义
VLLM_USE_V1=0强制使用 V0 引擎(WSL2 必需)
--host 0.0.0.0监听所有网络接口
--port 8000服务端口
--max-model-len 2048最大上下文长度(token 数)

启动成功日志:

(APIServer pid=XXXX) INFO: Application startup complete.

在这里插入图片描述

[7B AWQ模型启动成功后的终端输出]

6.2 测试推理

curl -s http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen/Qwen2.5-0.5B-Instruct-AWQ",
    "messages": [{"role": "user", "content": "你好,你是谁?"}]
  }' | python3 -c "import sys,json; print(json.load(sys.stdin)['choices'][0]['message']['content'])"

输出:

我是通义千问,由阿里云研发的预训练语言模型。与Qwen同属一个系列,我专注于提供广泛的知识和技能支持,帮助用户获得准确的信息和解决问题。如果您有任何问题或需要帮助,请随时告诉我!

[curl 命令返回的 JSON + 解码后的中文回复]

6.3 启动 7B 模型(主力模型)

0.5B 验证通过后,启动 7B 模型获得更好的回答质量。

conda activate vllm
cd ~

VLLM_USE_V1=0 vllm serve Qwen/Qwen2.5-7B-Instruct-AWQ \
  --host 0.0.0.0 --port 8000 \
  --max-model-len 2048 \
  --gpu-memory-utilization 0.90

参数新增:

参数含义
--gpu-memory-utilization 0.90GPU 显存使用率上限(90%)

⚠️ 8GB 显存跑 7B AWQ 非常极限。模型权重占 5.20 GiB,PyTorch 激活峰值 1.40 GiB,其他开销 0.23 GiB,合计 6.83 GiB。
0.85 × 8 = 6.80 GiB差 0.03 GiB,会报 No available memory
0.90 × 8 = 7.20 GiB完全够用。这就是为什么 --gpu-memory-utilization 必须设在 0.90。
在这里插入图片描述
在这里插入图片描述
[ 7B 模型启动成功日志,包含显存分配详情]

6.4 GPU 显存分析

vLLM 启动时打印的显存使用:

model weights take 5.20GiB;           ← 模型文件本身
non_torch_memory takes 0.23GiB;       ← CUDA 运行时等开销
PyTorch activation peak memory takes 1.40GiB;  ← CUDA graph + 临时计算缓冲
--------------------------------------------------
total = 6.83 GiB

可用显存 = 8.00 GiB × 0.90 = 7.20 GiB  ✅
可用显存 = 8.00 GiB × 0.85 = 6.80 GiB  ❌ 差 0.03 GiB

关键发现max-model-len(上下文长度)几乎不影响 PyTorch 激活峰值。那 1.40 GiB 是 CUDA graph 和固定缓冲,跟模型架构绑定,不随上下文变化。


7. 交互式对话脚本

每次用 curl 太麻烦,写一个 Python 脚本实现连续对话:

#!/usr/bin/env python3
"""vLLM 本地大模型交互式对话脚本"""
import requests

URL = "http://localhost:8000/v1/chat/completions"
MODEL = "Qwen/Qwen2.5-7B-Instruct-AWQ"
messages = []

print("=== 本地 Qwen2.5-7B 对话 ===")
print("输入 quit 退出,输入 clear 清空历史\n")

while True:
    user = input("你: ").strip()
    if not user:
        continue
    if user.lower() == "quit":
        print("再见!")
        break
    if user.lower() == "clear":
        messages.clear()
        print("-- 对话历史已清空 --")
        continue

    messages.append({"role": "user", "content": user})
    
    print("AI: ", end="", flush=True)
    r = requests.post(URL, json={
        "model": MODEL,
        "messages": messages,
        "stream": False
    })
    reply = r.json()["choices"][0]["message"]["content"]
    print(reply)
    
    messages.append({"role": "assistant", "content": reply})

保存为 ~/chat.py,使用:

conda activate vllm
python3 ~/chat.py

效果演示:
在这里插入图片描述
[ 终端中交互式对话的效果]

7.1 用手机访问(可选)

让手机通过局域网访问电脑上的模型:

第一步:Windows 端口转发(管理员 PowerShell)

# 获取 WSL2 的 IP
wsl hostname -I
# 假设输出: 172.24.238.128

# 添加端口转发
netsh interface portproxy add v4tov4 listenport=8000 listenaddress=0.0.0.0 connectport=8000 connectaddress=172.24.238.128

# 开放防火墙
netsh advfirewall firewall add rule name="vLLM" dir=in action=allow protocol=tcp localport=8000

第二步:查看电脑局域网 IP

ipconfig
# 找到无线网卡的 IPv4 地址,如 192.168.1.105

第三步:手机访问

手机和电脑连同一 WiFi,浏览器打开:

http://192.168.1.105:8000/docs

或使用 ChatBox APP 对接:

设置项
API 类型OpenAI 兼容
API 地址http://192.168.1.105:8000/v1
API KeyEMPTY(随便填)
模型名Qwen/Qwen2.5-7B-Instruct-AWQ

8. 常见问题与排错

Q1: 为什么不用最新版 vLLM?

vLLM 0.25+ 的 V1 引擎强制依赖 UVA(统一虚拟寻址),WSL2 的 GPU-PV 虚拟化层不提供此特性。这是 NVIDIA WSL2 驱动的架构级限制,与模型大小、量化格式无关。

Q2: 为什么 0.5B 能跑但 7B 报显存不足?

8GB 显存跑 7B AWQ 非常极限。关键在于 --gpu-memory-utilization 必须设为 0.90,0.85 差 0.03 GiB 就会报 No available memory for the cache blocks

Q3: 为什么要在 ~ 目录下跑,不能在 /mnt/ 跑?

/mnt/ 是 WSL 挂载的 Windows 文件系统,跨文件系统 I/O 比 Linux 原生文件系统(/home/)慢 5-10 倍。大量写临时文件和加载模型时会严重拖慢甚至卡死。

Q4: transformers 版本应该怎么选?

vLLM 版本transformers 要求推荐版本
0.10.1>=4.55.0, <5.04.55.0
0.25.1>=4.55.05.x(但 WSL2 跑不了 0.25+)

Q5: 启动命令中 VLLM_USE_V1=0 是什么?

告诉 vLLM 使用 V0 引擎。V0 引擎不依赖 UVA,在 WSL2 上能正常工作。此环境变量在 vLLM 0.8~0.24 版本有效,0.25+ 已移除 V0 支持。

Q6: 如何查看当前有几个 conda 环境?

conda env list

Q7: 如何释放被僵尸占用的 GPU 显存?

vLLM 崩溃后显存可能没有被释放:

# 在 Windows PowerShell 中
wsl --shutdown

重启 WSL2 后重新操作。


9. 后续方向

9.1 垂直领域应用(RAG)

不需要训练模型,通过检索增强生成实现专业知识问答:

用户问题 → 从知识库检索相关文档 → 拼入 prompt → 发给模型 → 返回结果

推荐工具:DifyAnythingLLM

9.2 模型微调(QLoRA)

如果 RAG 满足不了,可以用 QLoRA 微调(8GB 显存刚好够):

conda create -n train python=3.12 -y
conda activate train

git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
pip install -e ".[torch,metrics]"

# 启动 Web 训练界面
llamafactory-cli webui

需要准备 1000+ 条领域问答对,训练约 2-6 小时。

9.3 尝试更强的模型

模型大小说明
Qwen2.5-Coder-7B-Instruct-AWQ~4GB代码生成专用
DeepSeek-R1-Distill-Qwen-7B-AWQ~4GB推理链强化,需 HuggingFace 登录下载

9.4 探索 Ollama(备选方案)

如果 vLLM 折腾累了,Ollama 在 WSL2 上一键就能跑:

curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen2.5:7b
ollama serve  # API 在 http://localhost:11434

缺点是模型格式不同(GGUF),需要重新下载。


附录:完整命令速查

# ========== 环境管理 ==========
conda activate vllm                         # 激活推理环境
conda deactivate                            # 退出当前环境
conda env list                              # 查看所有环境

# ========== 启动服务 ==========
# 0.5B 模型(轻量测试)
VLLM_USE_V1=0 vllm serve Qwen/Qwen2.5-0.5B-Instruct-AWQ \
  --host 0.0.0.0 --port 8000 --max-model-len 2048

# 7B 模型(主力)
VLLM_USE_V1=0 vllm serve Qwen/Qwen2.5-7B-Instruct-AWQ \
  --host 0.0.0.0 --port 8000 --max-model-len 2048 \
  --gpu-memory-utilization 0.90

# ========== 测试推理 ==========
# 查看模型列表
curl http://localhost:8000/v1/models

# 单次对话
curl -s http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"Qwen/Qwen2.5-7B-Instruct-AWQ","messages":[{"role":"user","content":"你好"}]}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['choices'][0]['message']['content'])"

# 交互对话
python3 ~/chat.py

# ========== 故障恢复 ==========
# Windows PowerShell: 重启 WSL2 释放僵尸显存
# wsl --shutdown

本文完整记录了从零开始到成功部署本地大模型的全过程,包含所有踩坑经验和解决方案。

如果对你有帮助,欢迎 ⭐ Star、收藏、转发。

有问题欢迎留言交流!

更多推荐