本地部署DeepSeek:vLLM高性能推理

vLLM 是当前最流行的大模型推理框架之一,本文记录使用 vLLM 本地部署 DeepSeek 模型的完整过程,包括安装、配置、性能调优和与 llama.cpp 的对比。

一、vLLM 简介

vLLM 是加州大学伯克利开源的高性能 LLM 推理引擎,核心技术是 PagedAttention——一种受操作系统虚拟内存管理启发的 KV Cache 管理机制。

传统推理框架给每个请求分配连续的 KV Cache 内存,导致大量碎片。PagedAttention 将 KV Cache 切分为固定大小的块(类似内存页),通过块表(类似页表)进行间接寻址。这样做的好处:

  • 减少内存浪费:不需要预分配最大长度的连续内存
  • 支持高并发:多个请求可以共享 KV Cache 的公共前缀(比如相同的 system prompt)
  • 动态内存分配:随着生成长度增长动态分配新的块

二、环境准备与安装

硬件要求

部署 DeepSeek-R1-Distill-Qwen-32B(BF16)需要约 64GB 显存。推荐配置:

  • 2×A100 80GB(宽裕),或 4×RTX 4090 24GB(tensor parallel)
  • 如果用量化版本(AWQ/GPTQ 4bit),单张 A100 或 2×RTX 4090 即可

部署满血 DeepSeek-R1 671B 至少需要 8×A100 80GB。

安装 vLLM

# 推荐用 conda/venv 隔离环境
python -m venv vllm-env
source vllm-env/bin/activate

# 安装 vLLM(需要 CUDA 12.1+)
pip install vllm

# 验证安装
python -c "import vllm; print(vllm.__version__)"

如果 pip 安装遇到编译问题,可以用预编译的 wheel:

# 指定 CUDA 版本安装
pip install vllm --extra-index-url https://download.pytorch.org/whl/cu121

三、启动 DeepSeek 模型

方式一:命令行启动 API Server

vLLM 内置了兼容 OpenAI API 的 HTTP Server:

# 单卡部署 32B 量化版
python -m vllm.entrypoints.openai.api_server \
    --model deepseek-ai/DeepSeek-R1-Distill-Qwen-32B \
    --dtype bfloat16 \
    --max-model-len 8192 \
    --port 8000

# 多卡部署(tensor parallel)
python -m vllm.entrypoints.openai.api_server \
    --model deepseek-ai/DeepSeek-R1-Distill-Qwen-32B \
    --dtype bfloat16 \
    --tensor-parallel-size 2 \
    --max-model-len 16384 \
    --port 8000

# 部署 AWQ 量化版本(显存占用约 18GB)
python -m vllm.entrypoints.openai.api_server \
    --model deepseek-ai/DeepSeek-R1-Distill-Qwen-32B-AWQ \
    --quantization awq \
    --max-model-len 8192 \
    --port 8000

方式二:Python SDK

from vllm import LLM, SamplingParams

# 初始化模型
llm = LLM(
    model="deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
    dtype="bfloat16",
    tensor_parallel_size=2,
    max_model_len=8192,
)

# 设置采样参数
params = SamplingParams(
    temperature=0.6,
    top_p=0.95,
    max_tokens=2048,
)

# 批量推理
prompts = [
    "解释一下 TCP 三次握手的过程",
    "用 Python 实现一个 LRU Cache",
    "什么是 CAP 定理?",
]
outputs = llm.generate(prompts, params)

for output in outputs:
    print(f"Prompt: {output.prompt[:50]}...")
    print(f"Output: {output.outputs[0].text[:200]}")
    print("---")

四、OpenAI 兼容 API 使用

vLLM 启动后提供与 OpenAI 完全兼容的 API,可以直接用 openai SDK 或 curl 调用:

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed",  # vLLM 默认不需要 key
)

response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
    messages=[
        {"role": "system", "content": "你是一个有帮助的助手。"},
        {"role": "user", "content": "解释 Rust 的所有权系统"},
    ],
    temperature=0.7,
    max_tokens=1024,
    stream=True,
)

for chunk in response:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
# curl 调用
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
    "messages": [{"role": "user", "content": "Hello"}],
    "temperature": 0.7,
    "max_tokens": 256
  }'

五、性能调优

Tensor Parallelism

多卡部署时 --tensor-parallel-size 是最关键的参数。它将模型的权重切分到多张 GPU 上并行计算。

# 2卡
--tensor-parallel-size 2

# 4卡
--tensor-parallel-size 4

# 跨节点(需要 Ray)
--tensor-parallel-size 8 --pipeline-parallel-size 2

tensor parallel 的数量必须能整除模型的 attention head 数量。DeepSeek-R1-Distill-Qwen-32B 有 40 个 head,所以 TP=2/4/5/8 都可以。

Batch Size 与吞吐量

vLLM 使用 continuous batching(连续批处理),不需要手动设置 batch size。关键参数:

# 最大并发请求数
--max-num-seqs 256

# 最大 token 数(影响 KV Cache 占用)
--max-model-len 8192

# GPU 显存利用率(预留给 KV Cache 的显存比例)
--gpu-memory-utilization 0.9

--gpu-memory-utilization 设得越高,能容纳的并发请求越多,但要留出余量防止 OOM。一般 0.85-0.92 是安全范围。

量化

如果显存紧张,量化是最有效的手段:

# AWQ 量化(推荐,速度快且质量损失小)
--model deepseek-ai/DeepSeek-R1-Distill-Qwen-32B-AWQ
--quantization awq

# GPTQ 量化
--quantization gptq

# FP8 量化(H100/Ada 架构支持)
--quantization fp8

AWQ 4bit 量化后,32B 模型显存占用从约 64GB 降到约 18GB,推理质量在大多数任务上几乎无损。

六、与 llama.cpp 对比

llama.cpp 是另一个常用的本地部署方案,基于 GGUF 格式和 CPU/GPU 混合推理。

维度 vLLM llama.cpp
主要场景 服务端高并发推理 本地/边缘单用户推理
硬件要求 NVIDIA GPU(CUDA) CPU / Apple Silicon / NVIDIA GPU
并发能力 continuous batching,高并发 单请求或少量并发
量化支持 AWQ, GPTQ, FP8 GGUF (Q2-Q8 多级量化)
部署复杂度 需要 CUDA 环境 编译即用,依赖少
Apple Silicon 不支持 原生支持 Metal
单请求延迟 略高(框架开销) 更低
吞吐量 远高于 llama.cpp 受限于单请求模型

简单总结:

  • 如果你要搭建 API 服务给多人/多应用使用,选 vLLM
  • 如果你在本地单人使用或在 Mac 上运行,选 llama.cpp
  • 如果你需要在消费级硬件上跑大模型,llama.cpp 的 GGUF 量化灵活性更高

七、部署 DeepSeek-R1 满血版

671B MoE 模型的部署复杂度要高得多。推荐配置:

# 8×A100 80GB
python -m vllm.entrypoints.openai.api_server \
    --model deepseek-ai/DeepSeek-R1 \
    --dtype bfloat16 \
    --tensor-parallel-size 8 \
    --max-model-len 4096 \
    --gpu-memory-utilization 0.92 \
    --trust-remote-code \
    --port 8000

注意 MoE 模型的特殊性:虽然总参数 671B,但每次推理只激活约 37B 参数,所以实际计算量不像参数量那么恐怖。但 KV Cache 占用仍然按完整模型计算,所以 --max-model-len 不能设太大。

总结

vLLM + DeepSeek 是目前本地/私有化部署大模型推理的最佳组合之一。vLLM 的 PagedAttention 和 continuous batching 让 GPU 利用率达到很高的水平,DeepSeek 的开源模型提供了优秀的推理能力。对于大多数开发者,从 DeepSeek-R1-Distill-Qwen-32B 的 AWQ 量化版开始是最务实的选择。