使用 SGLang + DFlash 加速 Qwen3-8B 非思考模式
本文介绍如何使用 SGLang 构建镜像,在 Qwen3-8B 推理服务中启用 DFlash speculative decoding。该方案适合已经完成 Qwen3-8B 基础部署,并希望在非思考模式下验证低延迟生成效果的用户。
警告
DFlash 是版本敏感方案。本文使用已包含 DFlash 支持的 SGLang 包版本作为默认路径。若您验证的 DFlash 模型说明要求尚未发布到包管理器的 SGLang 变更,再按模型说明改用 GitHub 源码或指定 PR 安装。构建或启动失败时,请优先检查 SGLang 版本、目标模型路径、DFlash draft 模型路径和 GPU 显存。
推荐配置
| 配置项 | 建议 |
|---|---|
| 推理类型 | 推理服务 |
| 资源类型 | 包年包月资源或 Spot 资源 |
| GPU 起步配置 | H100、H800、H200;不建议将 RTX 4090 或 A100 作为默认性能验证配置 |
| 推理引擎 | SGLang 0.5.14 或更新版本 |
| 镜像 | 按本文 Dockerfile 构建 DFlash 专用 SGLang 镜像 |
| 目标模型 | Qwen3-8B,例如 /infini-data/Qwen3-8B |
| Draft 模型 | Qwen3-8B-DFlash-b16,例如 /mnt/models/Qwen3-8B-DFlash-b16 |
| 监听端口 | 30000 |
| 监控端口 | 30000,并在启动命令中开启 --enable-metrics |
信息
DFlash draft 模型需要与目标模型 Qwen3-8B 配合使用。本文只把它作为 Qwen3-8B 的 speculative decoding draft model,不建议把 DFlash draft 模型单独作为普通聊天模型部署。
准备模型路径
本文启动命令默认读取两个模型路径:
/infini-data/Qwen3-8B
/mnt/models/Qwen3-8B-DFlash-b16/infini-data/ 是平台公共数据的容器内挂载路径,用于只读访问平台维护的公共模型和数据集。公共数据仅在部分可用区提供;创建推理服务时,还需要在存储配置中勾选挂载公共数据,容器内才会出现该路径。
DFlash draft 模型不随 Qwen3-8B 目标模型自动提供,需要单独下载并放到推理服务可挂载的位置。建议使用同一可用区的 AICoder 或开发机,将 draft 模型下载到共享高性能存储中,而不是放入推理服务容器系统盘。例如:
python3 -m pip install -U modelscope
modelscope download \
--model z-lab/Qwen3-8B-DFlash-b16 \
--local_dir /mnt/models/Qwen3-8B-DFlash-b16如果当前可用区没有公共数据,或公共数据中没有 Qwen3-8B 目标模型,也需要将 Qwen3-8B 放到共享高性能存储中。例如:
/mnt/models/Qwen3-8B
/mnt/models/Qwen3-8B-DFlash-b16随后在启动命令中把 TARGET_MODEL_PATH 和 DRAFT_MODEL_PATH 改为实际路径。
构建 DFlash 专用镜像
参考以下 Dockerfile 构建 SGLang DFlash 专用镜像。该镜像基于已经准备好的 CUDA 基础镜像继续安装包含 DFlash 支持的 SGLang 版本。
警告
该 Dockerfile 会下载 SGLang、PyTorch、FlashInfer、FlashAttention、NVIDIA CUDA 运行库等多组大体积 wheel,构建过程可能持续较久,并且对镜像中心的网络、Python 包源、缓存和基础镜像拉取能力比较敏感。Dockerfile 使用 BuildKit cache mount 缓存 uv 下载内容,因此不要在安装命令中添加 --no-cache;在开发机中使用 docker buildx build 反复调试时,这有助于复用已经下载的依赖。在镜像中心构建时,缓存是否保留以平台实际构建环境为准。若构建长时间卡在依赖下载、包源访问失败、GHCR 拉取失败或 CUDA 相关 wheel 解析失败,请不要反复无缓存重试;建议改用在开发机中使用 Dockerfile 构建镜像,或在网络条件稳定的外部环境完成构建后导入镜像。
将 YOUR_CUDA13_BASE_IMAGE 替换为团队已经验证过的 CUDA 13 + cuDNN 9 基础镜像。先按以下规则选择基础镜像:
- 如果目标 GPU 环境的 Linux NVIDIA 驱动版本为
580.65.06或更高,并且应用进程中的cuDriverGetVersion显示 CUDA Driver API13.0或更高,请使用不含兼容包的 CUDA 13.0 + cuDNN 9 Dockerfile构建基础镜像,并直接使用下方 Dockerfile。 - 如果目标 GPU 环境的 Linux NVIDIA 驱动版本低于
580.65.06,或应用进程中的cuDriverGetVersion仍显示12.8,但当前应用栈必须使用 CUDA 13,请先参考包含 CUDA 13.0、cuDNN 9 与兼容包的实验 Dockerfile构建并验证基础镜像,然后按本文后面的兼容包说明修改ENV。
FROM ghcr.io/astral-sh/uv:latest AS uv-builder
FROM YOUR_CUDA13_BASE_IMAGE
COPY --from=uv-builder /uv /uvx /bin/
ENV PATH=/opt/sglang-env/bin:/usr/local/cuda/bin:/usr/local/cuda-13.0/bin${PATH:+:${PATH}} \
LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda-13.0/lib64:/usr/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} \
CUDA_HOME=/usr/local/cuda \
VIRTUAL_ENV=/opt/sglang-env \
UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy \
UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \
PYTHONUNBUFFERED=1
WORKDIR /app
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates \
git \
python3 \
python3-dev \
python3-venv \
python-is-python3 \
&& rm -rf /var/lib/apt/lists/*
RUN --mount=type=cache,target=/root/.cache/uv \
uv venv "$VIRTUAL_ENV" \
&& uv pip install --prerelease=allow \
"sglang[all]==0.5.14" \
&& uv pip check
RUN python - <<'PY'
import torch
import sglang
print("torch:", torch.__version__)
print("torch cuda:", torch.version.cuda)
print("sglang:", getattr(sglang, "__version__", "unknown"))
PY
CMD ["bash"]Dockerfile 使用 /opt/sglang-env 虚拟环境,而不是 uv pip install --system 直接写入 /usr,以避免 Ubuntu 24.04 等基础镜像的 externally managed Python 限制。
--prerelease=allow 用于允许安装 SGLang 0.5.14 依赖的 flash-attn-4 预发布版本。如果删除该参数,uv 可能提示 flash-attn-4==4.0.0b15 无可用版本。
如果基础镜像包含 CUDA 13 兼容包
如果 YOUR_CUDA13_BASE_IMAGE 是基于 CUDA 13 兼容包实验 Dockerfile 构建的基础镜像,请把上方 Dockerfile 中的 ENV 块替换为以下内容。关键差异是把 /usr/local/cuda-13.0/compat 放在 LD_LIBRARY_PATH 最前面,让 SGLang、PyTorch 和 FlashInfer 优先加载兼容包中的 libcuda.so.1。
ENV PATH=/opt/sglang-env/bin:/usr/local/cuda/bin:/usr/local/cuda-13.0/bin${PATH:+:${PATH}} \
LD_LIBRARY_PATH=/usr/local/cuda-13.0/compat:/usr/local/cuda/lib64:/usr/local/cuda-13.0/lib64:/usr/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} \
CUDA_HOME=/usr/local/cuda \
VIRTUAL_ENV=/opt/sglang-env \
UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy \
UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \
PYTHONUNBUFFERED=1使用未发布 SGLang 版本
如果您正在验证的 DFlash 模型说明要求使用尚未发布的 SGLang 源码或指定 PR,可将 Dockerfile 中的安装命令替换为模型说明提供的 GitHub 安装命令。不要在没有版本要求时默认使用未发布源码分支。
创建推理服务
进入推理服务创建页。
按以下方式填写关键配置:
- 推理类型:选择推理服务。
- 资源类型:选择包年包月资源或 Spot 资源。使用 Spot 资源时,请确认调用方具备超时、重试或降级策略。
- 实例规格:优先选择 H100、H800 或 H200 单卡规格。若需要更高并发或更长输出,请选择更多 GPU 或更大显存规格。
- 镜像:选择已构建的 DFlash 专用 SGLang 镜像。
- 存储:挂载公共数据或包含 Qwen3-8B、Qwen3-8B-DFlash-b16 的共享高性能存储。
- 内网配置:监听端口填写
30000。如需 LLM 场景业务监控,监控端口也填写30000。
启动命令
以下命令会启动 OpenAI 兼容的 SGLang 服务,并启用 DFlash speculative decoding。若模型路径不同,请修改 TARGET_MODEL_PATH 和 DRAFT_MODEL_PATH。
#!/bin/bash
set -euo pipefail
export PYTHONUNBUFFERED=1
export TARGET_MODEL_PATH="${TARGET_MODEL_PATH:-/infini-data/Qwen3-8B}"
export DRAFT_MODEL_PATH="${DRAFT_MODEL_PATH:-/mnt/models/Qwen3-8B-DFlash-b16}"
export SERVED_MODEL_NAME="${SERVED_MODEL_NAME:-Qwen3-8B-DFlash}"
exec sglang serve \
--model-path "${TARGET_MODEL_PATH}" \
--speculative-algorithm DFLASH \
--speculative-draft-model-path "${DRAFT_MODEL_PATH}" \
--tp-size 1 \
--dtype bfloat16 \
--attention-backend fa3 \
--mem-fraction-static 0.75 \
--trust-remote-code \
--served-model-name "${SERVED_MODEL_NAME}" \
--host 0.0.0.0 \
--port 30000 \
--enable-metrics信息
DFlash draft 模型用于非思考模式。调用时建议显式传入 chat_template_kwargs.enable_thinking=false。
服务启动日志中出现 Initialized DFLASH draft runner、DFLASH draft runner ready 或 DFLASH fused KV materialization enabled,通常说明 DFlash draft runner 已加载。若日志中只有 draft 模型缺少 generation_config.json 的告警,但服务继续完成模型加载并开始监听端口,通常不需要因为该告警中止验证。
调用验证
推理服务运行后,按以下顺序验证服务。
Step 1 获取调用地址和认证方式
- 进入推理服务详情页。
- 点击调用,复制推理服务调用地址。
- 如果使用外网访问,请准备 API Key。默认情况下,请求需要使用
Authorization: Bearer <API Key>。 - 如果创建服务时将 Auth Header 配置为
X-Infini-Auth,请把下面示例中的AuthorizationHeader 改为X-Infini-Auth。
export BASE_URL="<推理服务调用地址>"
export API_KEY="<API Key>"Step 2 检查模型列表
curl -X GET "${BASE_URL}/v1/models" \
-H "Authorization: Bearer ${API_KEY}"如果返回中能看到 Qwen3-8B-DFlash,说明服务已经暴露 OpenAI 兼容接口。
Step 3 验证非思考模式代码生成
使用 chat_template_kwargs.enable_thinking=false 验证非思考模式请求。
curl -X POST "${BASE_URL}/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${API_KEY}" \
--data '{
"model": "Qwen3-8B-DFlash",
"messages": [
{
"role": "user",
"content": "Write a quicksort function in Python."
}
],
"temperature": 0,
"max_tokens": 1024,
"chat_template_kwargs": {
"enable_thinking": false
}
}'这一步用于确认服务可以正常接收请求、加载 DFlash draft 模型并返回非思考模式结果。单次 curl 请求不适合判断 tokens per second 是否足够快。
性能对比验证指引
如需评估 DFlash 是否带来性能收益,建议准备一个普通 Qwen3-8B 服务作为基线,再与本文的 Qwen3-8B + DFlash 服务对比。对比时保持 GPU 规格、可用区、目标模型、提示词、max_tokens、并发数和非思考模式设置一致。
不要使用第一次请求的结果做结论。先预热服务,再重复发送相同请求或使用压测工具,观察输出 tokens/s、首 token 延迟、每 token 延迟、请求成功率和服务监控。若只需要确认部署是否可用,完成 Step 3 即可;若需要证明加速效果,请基于相同条件下的多次请求结果做比较。
Step 4 排查常见问题
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 服务启动失败,日志提示缺少 DFlash 或 speculative 参数不识别 | SGLang 版本不正确 | 确认镜像使用本文 Dockerfile 安装了支持 DFlash 的 SGLang 版本 |
服务启动失败,日志提示 found version 12080、NVIDIA driver 太旧或 No accelerator ... available | 应用进程没有优先加载 CUDA 13 兼容包中的 libcuda.so.1,或宿主机驱动不支持当前 CUDA 13 应用栈 | 按包含 CUDA 13.0、cuDNN 9 与兼容包的实验 Dockerfile重新验证 LD_DEBUG 和 cuDriverGetVersion |
| Draft 模型加载失败 | DRAFT_MODEL_PATH 错误,未挂载包含 draft 模型的存储,或未提前下载 DFlash draft 模型 | 检查存储挂载和模型目录 |
| 目标模型加载失败 | TARGET_MODEL_PATH 错误,或公共数据未挂载 | 检查公共数据可用区和存储配置 |
| 显存不足 | 上下文、并发或静态内存比例过高 | 降低请求长度,或调整 --mem-fraction-static,或换更大显存规格 |