WSL2+lmdeploy部署大模型

我的电脑上长期运行了一个 Qwen3 4B 模型,用于沉浸式翻译和 Cherry Studio 中的话题命名以及翻译任务。在过去的约半年时间内,我一直使用 llama.cpp 来部署 Q4 量化的 GGUF 模型。最近,为了获得更好的并发性能,我计划将推理框架改为 vLLM/SGLang。

我的环境如下:

  • CPU: AMD Ryzen 7 7700
  • RAM: 48G DDR5 6000 MHz
  • GPU: Tesla T10 (Turing 架构,SM75)
  • OS: Windows 11, WSL 2 Arch Linux

摸索之后发现:

  • vLLM 和 SGLang 仅支持 Linux,于是 WSL 成为唯一的选择。
  • SGLang 安装需要 FlashInfer,而 FlashInfer 安装又需要 CUDA Tool Kit。尽管在 WSL 中调用 CUDA 仅需在 Windows 宿主系统中安装 NVIDIA 显卡驱动,但想要编译 CUDA 程序还是需要在 WSL 中安装 CUDA Tool Kit 的。而它高达 7 GB 的安装包体令我望而却步。
  • vLLM 主要支持 SM80(Ampere 架构,30 系显卡),对于更老旧的显卡支持有限。我在尝试运行 cpatonn/Qwen3-4B-Instruct-2507-AWQ-4bit 时遇到错误信息,表明此模型仅在 SM80 或更新的架构上受支持,而 vLLM 的硬件支持页面里分明写着 AWQ 量化在 SM75 及之后的架构上受支持。后来推测可能是新的 AWQ 量化模型都改用了 llm-compressor 导致的。因为耐心被消耗的差不多了,所以我转向了据说对老显卡支持较好的 lmdeploy。

环境准备

想要在 WSL 中使用 lmdeploy,需要在 Windows 中安装显卡驱动,然后安装一个 WSL 2 的发行版。在 WSL 中无需安装任何显卡驱动/CUDA 环境。

Windows 宿主系统中安装的显卡驱动应当支持 CUDA 12,方可使用 lmdeploy 的预编译包。如果仅支持 CUDA 11,则可能需要手动编译 lmdeploy。我的驱动最高支持到 CUDA 12.8。

然后,在 WSL 中安装 uv:https://docs.astral.sh/uv/getting-started/installation/ 或者安装 miniconda,都可以,用来管理 Python 环境。

安装 lmdeploy

在 WSL 中执行

uv tool install lmdeploy

这会将 lmdeploy 安装为一个全局可用的工具,安装后,应当可以直接在命令行中使用 lmdeploy。

量化模型

这里是问题的关键。根据我的使用需求,最合适的模型是 Qwen3-4B-Instruct-2507,lmdeploy 支持 AWQ 和 GPTQ 量化,而找了两个 AWQ 量化,发现都是用 llm-compressor 量化的,根据 这个 issue,lmdeploy 尚未支持 llm-compressor。

于是我只好自己量化模型了。谢天谢地,已经被 archive 的 AutoAWQ 仍然支持 Qwen3,因此我们直接用 AutoAWQ 来量化。

不是很懂大模型量化,但是 AWQ 应该是比 GPTQ 先进一点。AWQ 量化的时候需要一个校准数据集,理论上这个数据集应该和量化模型实际处理的数据尽可能接近。这里我选用了 Qwen3-235B-2507-Instruct 在 liucong/Chinese-DeepSeek-R1-Distill-data-110k-SFT 数据集上产生的蒸馏数据集进行校准:https://modelscope.cn/datasets/swift/Chinese-Qwen3-235B-2507-Distill-data-110k-SFT

量化代码如下(放的是 Thinking 版本的代码):

from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
import os
import json

calib_data_path = "/root/.cache/modelscope/hub/datasets/swift/Chinese-Qwen3-235B-Thinking-2507-Distill-data-110k-SFT/qwen3_235b_thinking_2507_distill_110k.jsonl"

model_path = '/root/public/ckpts/Qwen3-4B-Thinking-2507'
quant_path = '/root/public/ckpts/Qwen3-4B-Thinking-2507-AWQ'
quant_config = { "zero_point": True, "q_group_size": 128, "w_bit": 4, "version": "GEMM" }

# Load model
model = AutoAWQForCausalLM.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)

# 准备校准数据集
data = []
with open(calib_data_path, 'r', encoding='utf-8') as f:
    for line in f:
        line = line.strip()
        if not line:  # 跳过空行
            continue
        record = json.loads(line)
        msg = record["messages"]
        text = tokenizer.apply_chat_template(msg, tokenize=False, add_generation_prompt=False)
        data.append(text.strip())

# Quantize
model.quantize(tokenizer, quant_config=quant_config, calib_data=data)

# Save quantized model
model.save_quantized(quant_path)
tokenizer.save_pretrained(quant_path)

print(f'Model is quantized and saved at "{quant_path}"')

我将 Qwen3-4B-2507 的 Instruct 和 Thinking 版本都量化并上传到了 Hugging Face:

启动

我使用以下的脚本启动:

lmdeploy serve api_server ./Qwen3-4B-Instruct-2507-AWQ \
    --server-name 0.0.0.0 \
    --server-port 8080 \
    --backend turbomind \
    --api-keys xxxxx \
    --model-name model \
    --tool-call-parser qwen3 \
    --session-len 16384 \
    --cache-max-entry-count 0.4 \
    --enable-prefix-caching \
    --quant-policy 8 \
    --model-format awq

执行 lmdeploy serve api_server --help 可以查看所有可用的参数和对应的解释。上面的几个参数需要注意一下:

  • cache-max-entry-count 用于控制 KV 缓存最多占用显存的百分比。我这里设为 40%,因为打游戏还要占一点显存。lmdeploy 启动之前,系统占了大约 2 GB,启动之后占用大约 11 GB,还有 5 GB 的显存用来打游戏。
  • quant-policy 是 KV 缓存的量化级别。我们这里将 KV 缓存量化到 8 bit,有助于减少 KV 缓存的显存占用。最低可以设置到 4,但是之前在 LocalLLaMA 社区看到 4 bit 量化的损失比较高,就没用。
posted @ 2025-08-13 20:42  Eslzzyl  阅读(257)  评论(0)    收藏  举报