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:
- https://huggingface.co/Eslzzyl/Qwen3-4B-Instruct-2507-AWQ
- https://huggingface.co/Eslzzyl/Qwen3-4B-Thinking-2507-AWQ
启动
我使用以下的脚本启动:
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 量化的损失比较高,就没用。

浙公网安备 33010602011771号