DeepSeek 用法#

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

本文档概述了 DeepSeek 的当前优化。此外,SGLang 团队正在根据此 路线图 积极开发增强功能。

使用 SGLang 启动 DeepSeek V3#

要运行 DeepSeek V3/R1 模型,要求如下

模型权重类型

配置

全精度 FP8
(推荐)

8 x H200

8 x MI300X

2 x 8 x H100/800/20

全精度 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/800

32 x L40S

详细命令参考

下载模型权重#

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

缓存 torch.compile#

DeepSeek 系列模型权重庞大,如果您添加了 --enable-torch-compile 标志,首次使用 torch.compile 编译模型需要一些时间。您可以参考 此处 优化编译结果的缓存,以便下次启动时可以使用缓存来加速。

使用 8 x H200 的单节点启动#

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

在多节点上运行示例#

优化#

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

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

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

  • MLA Attention 后端: 目前 SGLang 支持不同的优化 MLA attention 后端,包括 FlashAttention3FlashinferFlashMLACutlassMLATriton 后端。默认的 FA3 在广泛的工作负载中提供了良好的性能。

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

  • CUDA Graph & Torch.compile: MLA 和专家混合 (MoE) 都与 CUDA Graph 和 Torch.compile 兼容,这降低了延迟并加速了小批量解码速度。

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

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

Multi-head Latent Attention for DeepSeek Series Models

用法: MLA 优化默认启用。

参考资料: 查看 博客幻灯片 以了解更多详情。

数据并行 Attention#

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

Data Parallelism Attention for DeepSeek Series Models

启用数据并行 attention 后,与以前的版本相比,我们实现了高达 1.9倍 的解码吞吐量提升。

Data Parallelism Attention Performance Comparison

用法:

  • 在使用 8 块 H200 GPU 时,将 --enable-dp-attention --tp 8 --dp 8 添加到服务器参数中。此优化提高了在高批量场景下的峰值吞吐量,这些场景下服务器受 KV 缓存容量限制。但是,不建议将其用于低延迟、小批量使用情况。

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

参考资料: 查看 博客

多节点张量并行#

描述: 对于单节点内存有限的用户,SGLang 支持使用张量并行将包括 DeepSeek V3 在内的 DeepSeek 系列模型部署到多个节点上。此方法将模型参数分配到多个 GPU 或节点上,以处理对于单个节点内存而言过大的模型。

用法: 查看 此处 获取使用示例。

分块 FP8#

描述: SGLang 实现了分块 FP8 量化,并包含两个关键优化

  • 激活: 使用每令牌每 128 通道子向量尺度,并采用在线转换的 E4M3 格式。

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

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

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

在部署 DeepSeek 模型之前,使用以下命令预编译 DeepGEMM 内核

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

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

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

多令牌预测#

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

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
  • 用法: 添加参数 --speculative-algorithm--speculative-num-steps--speculative-eagle-topk--speculative-num-draft-tokens 来启用此功能。例如

  • 可以使用 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 后端对 MTP 的支持仍在开发中。

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

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

设置 --cuda-graph-bs。这是用于 CUDA Graph 捕获的批量大小列表。推测解码的默认捕获批量大小在此 设置。您可以在其中包含更多批量大小。

DeepSeek R1 的推理内容#

参见 独立推理

DeepSeek 模型的函数调用#

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 --disable-cuda-graph --tool-call-parser deepseekv3 --chat-template ./examples/chat_template/tool_chat_template_deepseekv3.jinja

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

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. 使用较低的 "temperature" 值以获得更好的结果。

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

  1. 常见问题解答#

    问题: 如果模型加载时间过长并发生 NCCL 超时,我应该怎么办?

回答: 您可以尝试在启动模型时添加 --dist-timeout 3600,这将允许 1 小时的超时。