写在前面:本文记录在一台双卡机器上完成 DeepSeek-V4-Flash-0731 部署、工具调用修复和性能验收的全过程。目标是让后续维护者能够复现当前服务,并快速判断常见故障发生在哪一层。


1. 最终状态

项目 当前配置
模型 DeepSeek-V4-Flash-0731(本地权重目录:/data/USER/models/DeepSeek-V4-Flash-0731
权重规模 48 个 safetensors 分片,155.43 GiB
GPU 2 × NVIDIA B300 SXM6 AC
单卡显存 275040 MiB,约 288 GB 标称容量
推理框架 SGLang 0.5.16
Python / PyTorch Python 3.12.13 / PyTorch 2.11.0+cu130
NVIDIA 驱动 590.48.01
CUDA 编译器 CUDA 13.3
并行策略 TP=2
MoE 后端 flashinfer_mxfp4
推测解码 DSPARK
API OpenAI compatible,http://127.0.0.1:30000/v1
工具解析器 deepseekv4
推理解析器 deepseek-v4
最大模型上下文 1,048,576 tokens

服务启动脚本为 serve.sh。经验证的核心命令如下:

CUDA_VISIBLE_DEVICES=5,7 \
  /usr/local/deploy/deepseek-v4-flash/serve.sh

当前完整参数:

sglang serve \
  --trust-remote-code \
  --model-path /data/models/DeepSeek-V4-Flash-0731 \
  --tp 2 \
  --reasoning-parser deepseek-v4 \
  --tool-call-parser deepseekv4 \
  --moe-runner-backend flashinfer_mxfp4 \
  --speculative-algorithm DSPARK \
  --mem-fraction-static 0.90 \
  --chunked-prefill-size 4096 \
  --swa-full-tokens-ratio 0.1 \
  --disable-custom-all-reduce \
  --host 0.0.0.0 \
  --port 30000

workbuddy使用部署的deepseekv4flash:
在这里插入图片描述

2. “满血”与精度说明

当前部署加载的是完整官方 DeepSeek-V4-Flash-0731 checkpoint,不是蒸馏模型,也没有在本地做二次量化。因此从模型身份和官方发布形态看,这是完整的官方 Flash 部署。

不过,官方 Flash checkpoint 本身并不是全 BF16 权重。模型 config.json 明确记录:

  • MoE routed expert 权重为 FP4:expert_dtype: fp4
  • 其他量化矩阵采用 FP8 E4M3,动态 activation scheme;
  • torch_dtype: bfloat16 表示未量化部分和默认计算路径,并不表示所有权重以 BF16 存储;
  • SGLang 对 DeepSeek V4 自动选择 fp8_e4m3 KV cache。

本地权重约对应 304B 参数。若全部换成 BF16,仅权重理论占用就约为 608 GB,已经超过两张 B300 合计约 576 GB 的标称显存,还没有计入 KV cache、CUDA Graph、DSPARK draft、激活与通信缓冲。因此两张 B300 不适合全 BF16 常规部署

结论:当前是“官方完整 Flash 精度”,不是“全 BF16 权重”。这不是部署过程中额外牺牲的精度。

3. 部署前检查

3.1 确认权重完整

du -sh /data/models/DeepSeek-V4-Flash-0731
find /data/models/DeepSeek-V4-Flash-0731 \
  -maxdepth 1 -name '*.safetensors' | wc -l

本次结果为约 156G、48 个权重分片。

3.2 找到真正空闲的物理卡

nvidia-smi --query-gpu=index,name,memory.total,memory.used,utilization.gpu \
  --format=csv,noheader

本次选择物理 GPU 5 和 7,并通过 CUDA_VISIBLE_DEVICES=5,7 映射为进程内逻辑 GPU 0 和 1。排查显存问题时要注意区分物理编号进程内编号

3.3 核对软件版本

/data/miniconda3/envs/sglang/bin/python -c \
  'import sglang, torch; print(sglang.__version__, torch.__version__)'

本次使用已安装好的 /data/miniconda3/envs/sglang 环境,没有重新安装或升级依赖。

4. 环境修复

4.1 DeepGEMM 找不到 CUDA_HOME

现象:启动或执行 SGLang benchmark 时,导入 deep_gemm 报错:

AssertionError
... deep_gemm/cuda_helpers.py ... find_cuda_home()

根因:当前 Conda 环境包含 CUDA 组件,但 CUDA_HOME 未指向它。

修复

SGLANG_ENV=/data/miniconda3/envs/sglang
CUDA_ROOT="$SGLANG_ENV/lib/python3.12/site-packages/nvidia/cu13"
export CUDA_HOME="$CUDA_ROOT"
export PATH="$CUDA_HOME/bin:$PATH"

这也是为什么单独运行 python -m sglang.benchmark.serving 时,必须带上与服务一致的 CUDA 环境变量。

4.2 CUDA 13.3 编译器与 CUDA 13.0 runtime headers 混用

当前环境的 nvcc 为 CUDA 13.3,而 PyTorch runtime 是 cu130。CCCL 会检查 toolkit compatibility,首次 JIT 编译时需要:

export NVCC_PREPEND_FLAGS=-DCCCL_DISABLE_CTK_COMPATIBILITY_CHECK

这是针对当前环境组合的兼容开关,不应无条件复制到版本完全一致的其他机器

4.3 FlashInfer 固定寻找 lib64

现象:FlashInfer 编译阶段找不到 CUDA lib64,而 NVIDIA Python CUDA 包实际提供的是 lib

修复

ln -s \
  /data/miniconda3/envs/sglang/lib/python3.12/site-packages/nvidia/cu13/lib \
  /data/miniconda3/envs/sglang/lib/python3.12/site-packages/nvidia/cu13/lib64

当前软链接已经存在。重复创建前应先用 ls -ld 检查,避免覆盖真实目录。

5. 首次启动与缓存

第一次启动会经历以下阶段:

  1. 加载 48 个 target 权重分片;
  2. 加载 checkpoint 内附带的 DSPARK draft head;
  3. 重排 FP4 expert 权重;
  4. DeepGEMM JIT 预编译;
  5. FlashInfer MoE autotune;
  6. target 和 draft CUDA Graph 捕获;
  7. 服务 warmup 后才开放 ready 状态。

本机一次完整冷启动约 21 分钟,其中 DSPARK draft 对应的 FlashInfer autotune 和 CUDA Graph 捕获耗时最长。过程中长时间没有 HTTP ready 不代表卡死,应观察日志中的 autotune 进度、GPU 利用率和显存变化。

生成的缓存位于用户 cache 目录,例如:

/home/USER/.cache/sglang/flashinfer/autotune/

不要随意删除 DeepGEMM、FlashInfer 和 CUDA Graph 相关缓存,否则下次可能重新承担十几分钟的预热成本。缓存是否可复用取决于 SGLang、CUDA、GPU 架构和启动参数是否一致。

6. 工具调用故障与修复

6.1 原始故障

客户端按照 OpenAI 协议发送 tools,模型也生成了原生工具标记,但响应表现为:

  • message.tool_callsnull
  • 原生 <invoke> 或 DSML 标记泄漏到 message.content
  • finish_reasonstop,不是 tool_calls
  • 客户端在工具标记附近停止正常渲染,看起来像回答被截断。

这说明模型生成了调用意图,但 SGLang 没有把模型原生格式翻译成 OpenAI tool_calls

6.2 正确修复

SGLang 0.5.16 内置 DeepSeek V4 专用工具解析器和 Python chat encoder。启动时加入:

--tool-call-parser deepseekv4 \
--reasoning-parser deepseek-v4

tool_call_parser=deepseekv4 或架构为 DeepseekV4ForCausalLM 时,SGLang 会自动选择内置 dsv4 encoder,不需要手写或下载 Jinja chat template

日志中的:

No HuggingFace chat template found

对这个 checkpoint 是预期现象。官方模型本身提供 Python encoding,而非 Hugging Face Jinja template。

6.3 DSPARK 与 tool_choice=required

tool_choice: "required" 会触发 grammar-constrained decoding,而当前 DSPARK speculative backend 返回:

DFLASH speculative decoding does not support grammar-constrained decoding yet.

因此客户端应使用:

{
  "tool_choice": "auto"
}

若业务必须强制 required,需要另行评估关闭 DSPARK 后的性能和兼容性,不能只改客户端参数。

6.4 工具调用验收结果

已验证:

  • 非流式响应返回标准 message.tool_calls
  • 流式 SSE 返回标准 delta.tool_calls
  • 最终 finish_reason=tool_calls
  • 工具执行结果以 role=tool 回传后,模型能够完成最终回答;
  • 10 个不同城市的强指令工具调用测试全部通过,成功率 10/10;
  • 这 10 个短工具调用请求的非流式平均端到端延迟为 370.66 ms,P95(nearest-rank)为 435.28 ms。

7. 性能基准

7.1 测试方法

测试时间:2026-08-04。服务已完成 warmup,在本机 loopback 地址测试,不包含公网、反向代理或客户端网络开销。

使用 SGLang 自带 serving benchmark:

python -m sglang.benchmark.serving \
  --backend sglang-oai \
  --base-url http://127.0.0.1:30000 \
  --model DeepSeek-V4-Flash-0731 \
  --tokenizer DeepSeek-V4-Flash-0731 \
  --dataset-name random \
  --random-input-len 512 \
  --random-output-len 128 \
  --random-range-ratio 1 \
  --request-rate inf

短上下文测试分别使用并发 1、4、8;长上下文测试使用 8192 输入、128 输出、并发 1。每组包含 1~2 个 warmup 请求,主测试固定生成 token 数,避免 EOS 和回答差异影响结果。

指标含义

  • TTFT:Time To First Token,从请求发出到收到第一个 token;
  • TPOT:除首 token 外,每个输出 token 的平均耗时;
  • ITL:相邻流式 token 的间隔;
  • E2E:完整请求端到端耗时;
  • output throughput:整个服务在测试窗口内每秒输出 token 数;
  • accept length:DSPARK 每轮平均接受的草稿长度,越高通常表示推测解码命中更好。

7.2 测试结果

输入/输出 并发 请求数 平均 TTFT P95 TTFT 平均 E2E 平均 TPOT P95 ITL 输出吞吐 请求吞吐 DSPARK accept
512 / 128 1 8 344.77 ms 351.86 ms 609.68 ms 2.09 ms 4.77 ms 209.27 tok/s 1.63 req/s 3.29
512 / 128 4 16 506.09 ms 870.36 ms 1430.77 ms 7.28 ms 56.97 ms 346.98 tok/s 2.71 req/s 3.59
512 / 128 8 24 910.54 ms 1462.16 ms 2113.15 ms 9.47 ms 57.16 ms 478.80 tok/s 3.74 req/s 3.81
8192 / 128 1 4 455.39 ms 484.64 ms 673.14 ms 1.71 ms 2.12 ms 189.08 tok/s 1.48 req/s 3.88

8K 输入场景报告的整体 input throughput 为 12101.42 tok/s。该数值按完整 benchmark 时长计算,不是隔离 decode 后的纯 prefill kernel 吞吐,因此只适合同配置横向比较。

7.3 结果解读

  • 交互型单请求表现较好:512-token prompt 平均 TTFT 约 345 ms,128-token 响应平均约 610 ms 完成。
  • 并发 8 时输出吞吐提升到约 479 tok/s,是并发 1 的约 2.29 倍;代价是平均 TTFT 上升到约 911 ms。
  • 如果目标是交互体验,建议前置调度层把常态并发控制在 1~4;如果目标是批量吞吐,可以使用更高并发。
  • P95 ITL 明显高于中位数,说明 continuous batching 下偶发 token 间隔会被 prefill/调度拉长。对强实时流式体验,应持续观察 P95/P99,而不是只看平均 tokens/s。
  • DSPARK accept length 随并发约为 3.29~3.88,推测解码在当前 workload 下确实产生了有效接受。
  • 8K prompt 平均 TTFT 约 455 ms,说明当前 DSV4 attention 和 chunked prefill 路径工作正常。

7.4 测试边界

本轮属于部署验收 benchmark,不等于模型质量评测或生产容量规划

  • 使用 synthetic random tokens,而非 ShareGPT、代码仓库或真实 agent trace;
  • 样本量较小,适合发现明显退化,不适合承诺严格 SLA;
  • 服务已经 warmup,冷启动时间不计入请求延迟;
  • loopback 测试不包含 TLS、网关和跨机网络;
  • throughput 测试走 OpenAI completions 路径,工具调用正确性另用 chat completions 验证;
  • 未测试 64K、128K、384K 和 1M 上下文,也未测试多轮 radix cache 命中收益;
  • 未运行 HumanEval、SWE-bench、Toolathlon 等模型能力基准。

原始 benchmark JSONL 建议单独保存(如 benchmarks/ 目录),便于后续与升级后的 SGLang、驱动或参数配置比较。

8. 常用检查与运维

检查服务:

curl http://127.0.0.1:30000/v1/models

检查实际启动参数:

ps -eo pid,etime,args | \
  rg '[s]glang serve.*DeepSeek-V4-Flash-0731'

检查两张卡:

nvidia-smi --query-gpu=index,memory.used,memory.free,utilization.gpu,power.draw \
  --format=csv,noheader | sed -n '6p;8p'

当前 --mem-fraction-static 0.90 会主动为权重、CUDA Graph 和大容量 KV pool 占用大部分显存。空闲时每张卡占约 261 GB 是正常现象,不代表显存泄漏

停止服务时应先通过 ps 定位唯一 PID,再发送 SIGTERM

kill -TERM <sglang-pid>

不要在机器上广泛 pkill python,避免影响同机其他训练或推理任务。

9. 后续建议

  1. 将脚本接入 systemd、Supervisor 或现有集群编排,补充日志轮转与异常拉起。
  2. 若需要生产 SLA,按真实 prompt 长度、输出长度和到达率至少持续压测 30 分钟,采集 P95/P98 TTFT、ITL、错误率、GPU 功耗和显存。
  3. 为 agent 场景补充真实多轮工具 trace 测试,包括并行 tool calls、工具报错、超时和长 tool result。
  4. 若升级 SGLang、PyTorch、CUDA 或驱动,先保留当前结果作为基线,再查找 parser、DSPARK accept length 和 CUDA Graph 是否退化。
  5. 启动日志中的 “FP8 KV cache 未提供 scaling factors,使用 1.0” 警告需要在未来官方 checkpoint 或 SGLang 更新后复核;当前功能与性能均通过,但它是值得持续跟踪的精度风险提示。

如果本文对你有帮助,欢迎点赞收藏。也欢迎在评论区交流你的部署经验。

更多推荐