DeepSeek V3/V3.1/R1 使用#

SGLang 提供了许多专为 DeepSeek 模型设计的优化,使其从发布首日(Day 0)起就成为 DeepSeek 官方团队 推荐的推理引擎。

本文档概述了当前针对 DeepSeek 的优化。有关已实现功能的概览,请参阅已完成的 路线图 (Roadmap)

使用 SGLang 启动 DeepSeek V3.1/V3/R1#

运行 DeepSeek V3.1/V3/R1 模型,建议设置如下:

权重类型

配置

全精度 FP8
(推荐)

8 x H200

8 x B200

8 x MI300X

2 x 8 x H100/800/20

Xeon 6980P CPU

全精度 (BF16) (由原始 FP8 转换)

2 x 8 x H200

2 x 8 x MI300X

4 x 8 x H100/800/20

4 x 8 x A100/A800

量化权重 (INT8)

16 x A100/800

32 x L40S

Xeon 6980P CPU

4 x Atlas 800I A3

量化权重 (W4A8)

8 x H20/100, 4 x H200

量化权重 (AWQ)

8 x H100/800/20

8 x A100/A800

量化权重 (MXFP4)

8, 4 x MI355X/350X

量化权重 (NVFP4)

8, 4 x B200

重要提示

官方 DeepSeek V3 已经是 FP8 格式,因此您不应使用任何如 --quantization fp8 的量化参数运行。

详细参考命令

下载权重#

如果您在启动服务器时遇到错误,请确保权重已下载完成。建议预先下载,或多次重启直到所有权重下载完毕。请参考 DeepSeek V3 官方指南下载权重。

在单节点 8 x H200 上启动#

请参考 该示例

多节点运行示例#

优化措施#

多头潜变量注意力 (MLA) 吞吐量优化#

描述MLA 是 DeepSeek 团队推出的一种创新注意力机制,旨在提高推理效率。SGLang 为此实现了特定优化,包括:

  • 权重吸收 (Weight Absorption):通过应用矩阵乘法的结合律重新排列计算步骤,该方法平衡了计算与内存访问,提高了解码阶段的效率。

  • MLA 注意力后端:目前 SGLang 支持不同的 MLA 注意力优化后端,包括 FlashAttention3, Flashinfer, FlashMLA, CutlassMLA, TRTLLM MLA(专为 Blackwell 架构优化)以及 Triton 后端。默认的 FA3 在广泛的工作负载中表现出色。

  • FP8 量化:W8A8 FP8 和 KV Cache FP8 量化实现了高效的 FP8 推理。此外,我们实现了批量矩阵乘法 (BMM) 算子,以促进带权重吸收的 MLA FP8 推理。

  • CUDA Graph & Torch.compile:MLA 和 混合专家模型 (MoE) 均兼容 CUDA Graph 和 Torch.compile,这在小批量(Batch Size)下能显著降低延迟并提升解码速度。

  • 分块前缀缓存 (Chunked Prefix Cache):该优化通过将前缀缓存切成块,并使用多头注意力处理后合并状态来提高吞吐量。在处理长序列的分块预填充(Chunked Prefill)时,其提升非常显著。目前此优化仅适用于 FlashAttention3 后端。

总的来说,通过这些优化,与之前的版本相比,我们的输出吞吐量实现了高达 7 倍 的加速。

Multi-head Latent Attention for DeepSeek Series Models

用法:MLA 优化默认开启。

参考资料:查看 博客幻灯片 获取更多细节。

数据并行注意力#

描述:该优化涉及 DeepSeek 系列模型 MLA 注意力机制的数据并行 (DP),它允许显著减小 KV 缓存大小,从而支持更大的 Batch Size。每个 DP 工作进程独立处理不同类型的 Batch(预填充、解码、空闲),然后在处理 MoE 层之前和之后进行同步。如果不使用 DP 注意力,KV 缓存将在所有 TP 排名(Rank)中重复。

Data Parallelism Attention for DeepSeek Series Models

启用数据并行注意力后,解码吞吐量较先前版本提升了高达 1.9 倍

Data Parallelism Attention Performance Comparison

用法:

  • 在 8 张 H200 GPU 上,请在服务器参数中添加 --enable-dp-attention --tp 8 --dp 8。此优化可在服务器受 KV 缓存容量限制的高 Batch Size 场景下提升峰值吞吐量。

  • DP 和 TP 注意力可以灵活组合。例如,要在 2 个各含 8 张 H100 GPU 的节点上部署 DeepSeek-V3/R1,您可以指定 --enable-dp-attention --tp 16 --dp 2。此配置将以 2 个 DP 组运行注意力,每组包含 8 张 TP GPU。

注意

数据并行注意力不推荐用于低延迟、小 Batch Size 的场景。它专为大 Batch Size 的高吞吐量场景而优化。

参考资料:查看 博客

多节点张量并行#

描述:对于单节点显存有限的用户,SGLang 支持使用张量并行跨多个节点提供 DeepSeek 系列模型(包括 DeepSeek V3)的服务。这种方法将模型参数划分到多个 GPU 或节点上,以处理超过单节点显存容量的模型。

用法:查看 此处 的使用示例。

分块 FP8 (Block-wise FP8)#

描述:SGLang 实现了具有两个关键优化的分块 FP8 量化:

  • 激活:E4M3 格式,使用每 Token 每 128 通道的子向量缩放以及在线转换。

  • 权重:每 128x128 块量化,以获得更好的数值稳定性。

  • DeepGEMM:针对 FP8 矩阵乘法优化的 DeepGEMM 内核库。

用法:上述激活和权重优化在 DeepSeek V3 模型中默认开启。DeepGEMM 在 NVIDIA Hopper/Blackwell GPU 上默认开启,在其他设备上默认禁用。也可以通过设置环境变量 SGLANG_ENABLE_JIT_DEEPGEMM=0 手动关闭 DeepGEMM。

提示

在提供 DeepSeek 模型服务之前,请预编译 DeepGEMM 内核以提升首次运行性能。预编译过程通常需要约 10 分钟。

python3 -m sglang.compile_deep_gemm --model deepseek-ai/DeepSeek-V3 --tp 8 --trust-remote-code

多 Token 预测 (Multi-token Prediction)#

描述:SGLang 基于 EAGLE 投机采样解码 实现了 DeepSeek V3 多 Token 预测 (MTP)。在 H200 TP8 配置下,该优化可使 Batch Size 1 的解码速度提升 1.8 倍,Batch Size 32 的解码速度提升 1.5 倍

用法:添加 --speculative-algorithm EAGLE。其他标志如 --speculative-num-steps, --speculative-eagle-topk--speculative-num-draft-tokens 是可选的。例如:

python3 -m sglang.launch_server \
  --model-path deepseek-ai/DeepSeek-V3-0324 \
  --speculative-algorithm EAGLE \
  --trust-remote-code \
  --tp 8
  • DeepSeek 模型的默认配置为 --speculative-num-steps 3 --speculative-eagle-topk 1 --speculative-num-draft-tokens 4。可以使用 bench_speculative.py 脚本针对特定 Batch Size 寻找最佳配置。最小配置为 --speculative-num-steps 1 --speculative-eagle-topk 1 --speculative-num-draft-tokens 2,这在大 Batch Size 下也能实现加速。

  • 大多数 MLA 注意力后端完全支持 MTP。详见 MLA 后端

注意

要为大 Batch Size (>48) 启用 DeepSeek MTP,您需要调整一些参数(参考 此讨论):

  • --max-running-requests 调大。MTP 的默认值为 48。对于更大的 Batch Size,您应该将此值调高至默认值以上。

  • 设置 --cuda-graph-bs。这是一个用于 CUDA Graph 捕获的 Batch Size 列表。投机解码默认捕获的 Batch Size 是 48。您可以通过包含更多 Batch Size 来进行自定义。

DeepSeek R1 & V3.1 的推理内容 (Reasoning Content)#

请参阅 推理解析器DeepSeek V3.1 思考参数

DeepSeek 模型的函数调用 (Function calling)#

添加参数 --tool-call-parser deepseekv3--chat-template ./examples/chat_template/tool_chat_template_deepseekv3.jinja (推荐) 以启用此功能。例如(在 1 * H20 节点上运行):

python3 -m sglang.launch_server \
  --model deepseek-ai/DeepSeek-V3-0324 \
  --tp 8 \
  --port 30000 \
  --host 0.0.0.0 \
  --mem-fraction-static 0.9 \
  --tool-call-parser deepseekv3 \
  --chat-template ./examples/chat_template/tool_chat_template_deepseekv3.jinja

请求示例

curl "http://127.0.0.1:30000/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{"temperature": 0, "max_tokens": 100, "model": "deepseek-ai/DeepSeek-V3-0324", "tools": [{"type": "function", "function": {"name": "query_weather", "description": "Get weather of an city, the user should supply a city first", "parameters": {"type": "object", "properties": {"city": {"type": "string", "description": "The city, e.g. Beijing"}}, "required": ["city"]}}}], "messages": [{"role": "user", "content": "Hows the weather like in Qingdao today"}]}'

预期响应

{"id":"6501ef8e2d874006bf555bc80cddc7c5","object":"chat.completion","created":1745993638,"model":"deepseek-ai/DeepSeek-V3-0324","choices":[{"index":0,"message":{"role":"assistant","content":null,"reasoning_content":null,"tool_calls":[{"id":"0","index":null,"type":"function","function":{"name":"query_weather","arguments":"{\"city\": \"Qingdao\"}"}}]},"logprobs":null,"finish_reason":"tool_calls","matched_stop":null}],"usage":{"prompt_tokens":116,"total_tokens":138,"completion_tokens":22,"prompt_tokens_details":null}}

流式请求示例

curl "http://127.0.0.1:30000/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{"temperature": 0, "max_tokens": 100, "model": "deepseek-ai/DeepSeek-V3-0324","stream":true,"tools": [{"type": "function", "function": {"name": "query_weather", "description": "Get weather of an city, the user should supply a city first", "parameters": {"type": "object", "properties": {"city": {"type": "string", "description": "The city, e.g. Beijing"}}, "required": ["city"]}}}], "messages": [{"role": "user", "content": "Hows the weather like in Qingdao today"}]}'

预期流式分块(为清晰起见已简化)

data: {"choices":[{"delta":{"tool_calls":[{"function":{"arguments":"{\""}}]}}]}
data: {"choices":[{"delta":{"tool_calls":[{"function":{"arguments":"city"}}]}}]}
data: {"choices":[{"delta":{"tool_calls":[{"function":{"arguments":"\":\""}}]}}]}
data: {"choices":[{"delta":{"tool_calls":[{"function":{"arguments":"Q"}}]}}]}
data: {"choices":[{"delta":{"tool_calls":[{"function":{"arguments":"ing"}}]}}]}
data: {"choices":[{"delta":{"tool_calls":[{"function":{"arguments":"dao"}}]}}]}
data: {"choices":[{"delta":{"tool_calls":[{"function":{"arguments":"\"}"}}]}}]}
data: {"choices":[{"delta":{"tool_calls":null}}], "finish_reason": "tool_calls"}
data: [DONE]

客户端需要拼接所有参数片段以重构完整的工具调用 (Tool Call)。

{"city": "Qingdao"}

重要提示

  1. 使用较低的 "temperature" 值以获得更好效果。

  2. 为了获得更一致的工具调用结果,建议使用 --chat-template examples/chat_template/tool_chat_template_deepseekv3.jinja。它提供了一个改进的统一 Prompt。

DeepSeek R1 的思考预算 (Thinking Budget)#

在 SGLang 中,我们可以使用 CustomLogitProcessor 来实现思考预算。

启动服务器时开启 --enable-custom-logit-processor 标志。

python3 -m sglang.launch_server --model deepseek-ai/DeepSeek-R1 --tp 8 --port 30000 --host 0.0.0.0 --mem-fraction-static 0.9 --disable-cuda-graph --reasoning-parser deepseek-r1 --enable-custom-logit-processor

请求示例

import openai
from rich.pretty import pprint
from sglang.srt.sampling.custom_logit_processor import DeepSeekR1ThinkingBudgetLogitProcessor


client = openai.Client(base_url="http://127.0.0.1:30000/v1", api_key="*")
response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-R1",
    messages=[
        {
            "role": "user",
            "content": "Question: Is Paris the Capital of France?",
        }
    ],
    max_tokens=1024,
    extra_body={
        "custom_logit_processor": DeepSeekR1ThinkingBudgetLogitProcessor().to_str(),
        "custom_params": {
            "thinking_budget": 512,
        },
    },
)
pprint(response)

常见问题 (FAQ)#

问:模型加载时间过长,并且遇到了 NCCL 超时,该怎么办?

答:如果您遇到模型加载时间过长和 NCCL 超时,可以尝试增加超时持续时间。在启动模型时添加参数 --dist-timeout 3600。这会将超时设置为一小时,通常可以解决该问题。