Windows10 WSL 中安装 vLLM 部署 Deepseek

9 阅读3分钟

Windows10 WSL 中安装 vLLM

  • 需求:个人电脑 Windows10 系统体验 vLLM 部署大语言模型,但是 vLLM 只能运行在 Linux 系统中。
  • 思路:需要借助 Windows 系统的子系统 WSL 功能,优先使用 WSL2,因为 WSL2 完全运行在 Linux 内核中,功能支持完全可以省去很多麻烦,具体 Windows 版本及 WSL2 安装详见官方文档。
  • 实验配置:Windows10 + 3070Ti
  • 注意事项:
    1. WSL 子系统默认安装在 C 盘,如果 C 盘空间有限,后期可能导致读写异常;
    2. WSL 子系统最好从 Windows store 下载,避免部分发行版的兼容性问题;
    3. cuda-toolkit 尽量只保留一个版本,多个版本可能导致冲突。

参考资料

安装 cuda

Download Installer for Windows 10 x86_64

Download Installer for Linux WSL-Ubuntu 2.0 x86_64

# 卸载旧版本
# sudo apt purge nvidia-* cuda-* -y
# sudo rm -rf /usr/local/cuda*
# sudo apt autoremove -y

# 添加 CUDA 12.4 的官方仓库源
# nvidia 官网安装代码默认提供最新的版本,vllm 最新支持的 cuda 版本为 12.4
wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda-repo-wsl-ubuntu-12-4-local_12.4.0-1_amd64.deb
sudo dpkg -i cuda-repo-wsl-ubuntu-12-4-local_12.4.0-1_amd64.deb
sudo cp /var/cuda-repo-wsl-ubuntu-12-4-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda-toolkit-12-4

配置环境变量

# 确认具体路径
# /usr/local/cuda-12.4 实际安装的 CUDA 12.4 版本文件,包含二进制、库和头文件等 
# /usr/local/cuda-12 指向 cuda-12.4 的符号链接(方便版本管理,如未来升级到 12.5 时切换) 
# /usr/local/cuda 指向 cuda-12 的符号链接(默认路径,兼容性设计,简化环境变量配置) 
ls /usr/local/cuda*  

# 在配置文件末尾添加环境变量
nano ~/.bashrc
# CUDA Toolkit
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
# 立即生效
source ~/.bashrc

# 验证安装
nvidia-smi  # 应显示与 windows 驱动版本一致
nvcc --version  # 输出 cuda 版本号
$CUDA_HOME/bin/nvcc --version
python -c "import torch;print([torch.__version__,torch.cuda.is_available(),torch.cuda.device_count(),torch.cuda.current_device()])"

安装 Miniconda 并创建环境 vllm

# 下载安装 Miniconda
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh
Miniconda3-latest-Linux-x86_64.sh
source ~/.bashrc

# 添加镜像
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.bfsu.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
conda config --set show_channel_urls yes

# 创建虚拟环境
conda create -n vllm python=3.12 -y 
conda activate vllm 

# 安装 vllm: https://docs.vllm.ai/en/latest/getting_started/installation/gpu.html
# 注意:vllm 默认使用 cuda 12.4,vllm 版本与 cuda 版本严格对应
pip install vllm

测试 vllm

import os
from vllm import LLM, SamplingParams
from modelscope import snapshot_download

# 下载模型到指定目录
# cache_dir = os.path.expanduser('~/models')
# model_path = snapshot_download('tclf90/deepseek-r1-distill-qwen-7b-gptq-int4',cache_dir=cache_dir)
# 预先下载的模型路径
model_path = os.path.expanduser("~/models/tclf90/deepseek-r1-distill-qwen-7b-gptq-int4")

# 加载模型
# gpu_memory_utilization 控制显存占用
# max_model_len 限制最大序列长度以减少显存占用
model = LLM(model=model_path,gpu_memory_utilization=0.95,max_model_len=8192)
sampling_params = SamplingParams(temperature=0.8, top_p=0.9)
convs = model.generate("你好,你是谁?", sampling_params)
print(convs[0].outputs[0].text)

作为服务启动 vllm

# 默认服务为 http://localhost:8000
# 可以使用 --host --port 修改主机和端口
vllm serve ~/models/tclf90/deepseek-r1-distill-qwen-7b-gptq-int4

# curl http://localhost:8000/v1/chat/completions 
curl http://localhost:8000/v1/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "Qwen/Qwen2.5-1.5B-Instruct",
        "prompt": "San Francisco is a",
        "max_tokens": 7,
        "temperature": 0
    }'

修改 vllm 服务模型名称

# 使用自定义的模型名
# 传入的参数下划线转为短横线:https://docs.vllm.ai/en/latest/serving/engine_args.html
vllm serve ~/models/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B \
    --gpu-memory-utilization 0.95 \
    --max-model-len 2048 \
    --served-model-name deepseek-1.5b

# 查看服务可以访问的模型
http://localhost:8000/v1/models
# 使用自定义模型名称请求服务
curl http://localhost:8000/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{"model": "deepseek-1.5b", "messages": [{"role": "user", "content": "hi"}]}'

异常处理

ERROR 04-21 19:50:20 [core.py:387] CUTLASS_FP8_SUPPORTED = cutlass_fp8_supported() ERROR 04-21 19:50:20 [core.py:387] ^^^^^^^^^^^^^^^^^^^^^^^
...
ERROR 04-21 19:50:20 [core.py:387] vllm.third_party.pynvml.NVMLError_NotSupported: Not Supported

# FP8 需 Compute Capability ≥ 9.0,如 H100/A100
# 查看 gpu 计算能力
nvidia-smi --query-gpu=compute_cap --format=csv

WSL 系统移动到 D 盘

# 导出 WSL 发行版为 .tar 文件 
wsl --export <发行版名称> D:\wsl-backup.tar
# 注销原发行版
wsl --unregister <发行版名称>
# 重新导入到 D 盘
wsl --import <发行版名称> D:\WSL\Ubuntu D:\wsl-backup.tar --version 2
# 设置默认用户
echo -e "[user]\ndefault=newuser" | sudo tee -a /etc/wsl.conf