DeepSeek V3/V3.1/R1 使用指南#

SGLang 提供了许多专门为 DeepSeek 模型设计的优化,使其成为官方 DeepSeek 团队从第一天起就推荐的推理引擎。

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

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

要运行 DeepSeek V3.1/V3/R1 模型,推荐的设置如下:

权重类型

配置

全精度 FP8
(推荐)

8 x H200

8 x MI300X

2 x 8 x H100/800/20

Xeon 6980P CPU

全精度 BF16

2 x 8 x H200

2 x 8 x MI300X

4 x 8 x H100/800/20

4 x 8 x A100/A800

量化权重 (AWQ)

8 x H100/800/20

8 x A100/A800

量化权重 (int8)

16 x A100/A800

32 x L40S

Xeon 6980P CPU

2 x Atlas 800I A3

详细命令供参考:

下载权重#

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

使用单节点 8 x H200 启动#

请参考 示例请注意 Deepseek V3 已经是 FP8 格式,因此不应使用任何量化参数(如 --quantization fp8 --kv-cache-dtype fp8_e5m2)运行它。

在多节点上运行示例#

优化#

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

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

  • 权重吸收:通过应用矩阵乘法的结合律来重新排序计算步骤,此方法平衡了计算和内存访问,并在解码阶段提高了效率。

  • MLA 注意力后端:目前 SGLang 支持不同的优化 MLA 注意力后端,包括 FlashAttention3FlashinferFlashMLACutlassMLATRTLLM MLA(针对 Blackwell 架构优化)和 Triton 后端。默认的 FA3 在广泛的工作负载下提供良好的性能。

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

  • CUDA 图 & Torch.compile:MLA 和混合专家 (MoE) 都兼容 CUDA 图和 Torch.compile,这减少了延迟并加速了小批量场景下的解码速度。

  • 分块前缀缓存:分块前缀缓存优化可以通过将前缀缓存切分成块,使用多头注意力处理它们并合并其状态来提高吞吐量。在长序列上进行分块预填充时,其改进效果可能非常显著。目前此优化仅适用于 FlashAttention3 后端。

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

DeepSeek 系列模型的多头潜在注意力

使用:MLA 优化默认启用。对于 Blackwell 架构上的 MLA 模型(如 B200),默认后端是 FlashInfer。要使用优化的 TRTLLM MLA 后端进行预填充和解码操作,请明确指定 --attention-backend trtllm_mla

参考:有关更多详细信息,请查看 BlogSlides

数据并行注意力#

描述:此优化涉及 DeepSeek 系列模型的 MLA 注意力机制的数据并行性 (DP),这可以显著减少 KV 缓存大小,从而支持更大的批量大小。每个 DP 工作进程独立处理不同类型的批次(预填充、解码、空闲),然后在通过混合专家 (MoE) 层处理前后进行同步。如果不使用 DP 注意力,KV 缓存将在所有 TP rank 之间复制。

DeepSeek 系列模型的数据并行注意力

启用数据并行注意力后,与前一个版本相比,我们实现了高达 1.9 倍的解码吞吐量改进。

数据并行注意力性能比较

使用

  • 使用 8 个 H200 GPU 时,在服务器参数中附加 --enable-dp-attention --tp 8 --dp 8。此优化在服务器受 KV 缓存容量限制的大批量场景下提高了峰值吞吐量。但是,它不适用于低延迟、小批量场景。

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

参考:查看 Blog

多节点张量并行#

描述:对于单节点内存有限的用户,SGLang 支持使用张量并行在多个节点上提供服务,包括 DeepSeek V3 在内的 DeepSeek 系列模型。这种方法将模型参数分布在多个 GPU 或节点上,以处理单个节点内存无法容纳的大型模型。

使用:使用示例请查看 这里

分块 FP8#

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

  • 激活:使用每个标记每个 128 通道子向量尺度的 E4M3 格式进行在线转换。

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

  • DeepGEMM:专用于 FP8 矩阵乘法的 DeepGEMM 内核库。

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

在提供 DeepSeek 模型之前,使用以下命令预编译 DeepGEMM 内核:

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

预编译过程通常需要约 10 分钟才能完成。

多标记预测#

描述:SGLang 基于 EAGLE 推理解码 实现了 DeepSeek V3 多标记预测 (MTP)。通过此优化,在 H200 TP8 设置下,对于批量大小 1 可解码速度可提高1.8倍,对于批量大小 32 可提高1.5倍

使用: 添加参数 --speculative-algorithm--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 \
  --speculative-num-steps 1 \
  --speculative-eagle-topk 1 \
  --speculative-num-draft-tokens 2 \
  --trust-remote-code \
  --tp 8
  • 对于给定批量大小,可以使用 bench_speculative.py 脚本搜索 --speculative-num-steps--speculative-eagle-topk--speculative-num-draft-tokens 的最佳配置。最小配置是 --speculative-num-steps 1 --speculative-eagle-topk 1 --speculative-num-draft-tokens 2,可以实现大批量场景下的加速。

  • FlashAttention3、FlashMLA 和 Triton 后端完全支持 MTP 使用。对于带推理解码的 FlashInfer 后端 (--attention-backend flashinfer),应将 --speculative-eagle-topk 参数设置为 1。CutlassMLA 和 TRTLLM MLA 后端的 MTP 支持仍在开发中。

  • 要为大批量 (>32) 启用 DeepSeek MTP,需要更改一些参数(参考 此讨论):

    • --max-running-requests 调整为更大的数值。MTP 的默认值为 48。对于大批量,应将此值增加到大于默认值。

    • 设置 --cuda-graph-bs。这是用于 cuda 图捕获的批量大小列表。推理解码的默认捕获批量大小 在此处 设置。您可以向其中添加更多批量大小。

DeepSeek R1 & V3.1 的推理内容#

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

DeepSeek 模型的函数调用#

添加参数 --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]

客户端需要连接所有参数片段以重建完整的函数调用:

{"city": "Qingdao"}

重要说明:

  1. 使用较低的温度值以获得更好的结果。

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

DeepSeek R1 的思考预算#

在 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)

常见问题#

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

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