SGLang 部署 Qwen3.8-27B 参数调优全记录
硬件: 双 RTX 3090 24GB (GPU1 部署), Ryzen 5950X, 64GB RAM
模型: dbirks/Qwen3.8-27B-W4A16-AutoRound (compressed-tensors W4A16, 19.5GB)
引擎: SGLang 0.5.17 (lmsysorg/sglang:latest), 容器sgl-qwen27b-gpu1
端口: :15433, GPU1 (CUDA_VISIBLE_DEVICES=1)
场景: 单人 coding agent (opencode), 子代理可能并行 2-3 请求
一、背景与选型
1.1 为什么用 SGLang 跑 Qwen3.8-27B
| 维度 | SGLang (GPU1) | llama.cpp (GPU0, 已有) |
|---|---|---|
| 模型格式 | AutoRound W4A16 (19.5GB) | IQ4_XS GGUF (15.7GB) |
| 单请求速度 | 46.1 t/s | ~73 t/s (MTP) |
| 3 并发聚合 | 130 t/s | 73 t/s (串行) |
| 工具调用 | 原生结构化 | ✅ |
| 上下文 (单请求) | 65511 | 131072 |
| 核心优势 | 并发批处理 (coding agent 多子代理) | 单请求速度 + MTP |
结论: 并发是 SGLang 相对 llama.cpp 的核心优势。单人 coding agent 派发多个子代理时, SGLang 的连续批处理可让 3 个请求同时高效运行 (130 vs 73 t/s 聚合)。
1.2 模型格式选型(为什么 AutoRound 而非 AWQ/GGUF)
SGLang 锁定 AWQ/Safetensors 格式 (Marlin kernel)。Qwen3.8-27B 无知名团队官方 AWQ。候选包括 dbirks AutoRound (19.5GB) 和 philbert440 AWQ (19.6GB)。
选定 dbirks AutoRound: 保留 DeltaNet 关键层 (in_proj_a/b) + 视觉塔 + MTP 头为 BF16, 9/9 校验通过。
二、核心参数结论速查
| 参数 | 值 | 说明 |
|---|---|---|
--dtype bfloat16 |
必选 | GDN 混合架构 conv_states 类型 |
--mem-fraction-static |
0.95 | 27B 精确甜点 (0.96+ 推理 OOM) |
--kv-cache-dtype |
fp8_e4m3 | KV 池翻倍 (比 bf16 更快 + 省显存) |
--max-mamba-cache-size |
15 | 3 并发 × S5 (coding agent 子代理场景) |
--context-length |
65536 | 单请求上限 = min(ctx, KV池 66638) |
--attention-backend |
flashinfer | fp8 必须 (triton 崩溃 fp8e4nv) |
--mamba-ssm-dtype |
bfloat16 | GDN state 减半 (79.2MB/slot) |
--mamba-full-memory-ratio |
0.5 | 显式 cache 时是死参数 (auto 模式才生效) |
--reasoning-parser |
qwen3 | 勿用 qwen3-thinking (强制思考) |
--tool-call-parser |
qwen3_coder | 结构化工具调用 |
最终推荐配置 (docker-compose)
sgl-qwen27b-gpu1:
image: lmsysorg/sglang:latest
container_name: sgl-qwen27b-gpu1
ports: ["15433:30000"]
environment:
- CUDA_VISIBLE_DEVICES=1
- SGLANG_MAX_NEW_TOKENS_LIMIT=32000
- PYTORCH_CUDA_ALLOC_CONF=expandable_segments:False
command: >
python3 -m sglang.launch_server
--model-path /models/Qwen3.8-27B-W4A16-AutoRound
--port 30000 --host 0.0.0.0
--dtype bfloat16
--context-length 65536
--mem-fraction-static 0.95
--mamba-full-memory-ratio 0.5
--max-mamba-cache-size 15
--attention-backend flashinfer
--mamba-ssm-dtype bfloat16
--kv-cache-dtype fp8_e4m3
--trust-remote-code
--reasoning-parser qwen3
--tool-call-parser qwen3_coder
--sleep-on-idle
最终性能: 1并发 46.1 / 2并发 88.9 / 3并发 130.2 t/s, KV 池 66638, 单请求上限 65511, CUDA Graph 192s 成功
三、mem-fraction 实验系列(27B 独立验证)
官方定义:
mem_fraction_static = (模型权重 + KV cache 池) / GPU 总显存
35B 的 0.92 甜点不适用 27B (27B 模型轻 1GB, 可到 0.95)
3.1 fp8 KV (32.8KB/token) + flashinfer
| mem-fraction | KV 池 (tokens) | CG 余量 | CUDA Graph | 推理 | 结论 |
|---|---|---|---|---|---|
| 0.92 | 56991 | 1.37GB | ✅ 195s | ✅ | 安全 |
| 0.95 | 78608 | 0.57GB | ✅ 193s | ✅ 48.8 t/s | 精确甜点 |
| 0.96 | 85813 | 0.49GB | ✅ 194s | ❌ OOM | 捕获成功但推理 OOM |
| 0.97 | 93019 | 0.24GB | ✅ 201s | ❌ OOM | 推理完全不可用 |
| 0.98 | 100224 | 0.05GB | ❌ CUBLAS失败 | — | CG 捕获失败 |
关键: 0.96/0.97 捕获成功但推理 OOM (activation 需 256MB) — 这是独立于捕获的失败模式。0.95 = 捕获成功 + 推理可用的精确边界。
3.2 显存边界分析 (0.95 × 24GB = 22.8GB)
| 项目 | 大小 |
|---|---|
| 模型权重 | 17.67 GB |
| Mamba cache | 0.80 GB (15 slots) |
| KV 池 | 2.04 GB (66638 tokens) |
| 边界内余量 | ~1.9 GB (CG buffer + activation) |
用户洞察验证: KV 池被 0.95 边界锁死。定制 CG bs 无法增加 KV (KV 池在 CG 捕获前分配), 0.96+ 的 activation OOM 是硬限制 (无参数可解)。
四、并发 vs 上下文权衡
4.1 max-mamba-cache-size 数据表
> 公式: max_running_requests = cache_size // S (S=5 extra_buffer)
> 每 +1 并发 (5 slots) = -12000 KV tokens
| cache-size | 并发 | KV 池 | 聚合吞吐 | 单请求上下文 |
|---|---|---|---|---|
| 5 | 1 | 90578 | 48.8 | 65536* |
| 10 | 2 | 78608 | 89.4 | 65536* |
| 15 | 3 | 66638 | 130.2 | 65511 |
| 20 | 4 | 54668 | 175.0 | ~54000* |
4.2 关键发现:单请求上下文与并发无关
实测证明: 单请求上下文 = min(context-length, KV 池), 与并发数无关:
3 并发各 48012 tokens (共144K > 池66638) 全部成功 — chunked prefill 动态复用。单请求超过 KV 池 → 报错 (不是截断)。context-length 提到 65536 → 单请求可用满 65511。
这推翻了”2 并发换更长上下文”的假设: cache15 (3并发) + ctx 65536 严格优于 cache10 (2并发) + ctx 49152 (上下文 +33%, 并发 +1)。
4.3 并发基准 (cache15 配置)
| 并发 | 墙钟 | 总 tokens | 聚合吞吐 |
|---|---|---|---|
| 1 | 4.3s | 200 | 46.1 |
| 2 | 4.5s | 400 | 88.9 |
| 3 | 4.5s | 591 | 130.2 |
CUDA Graph 捕获 bs=[1,2,3] = 并发甜点, 第 4 并发超捕获范围退化。
五、fp4 KV cache 慢 4 倍根因分析 (c1skill)
5.1 实验数据
| 配置 | KV dtype | backend | 速度 |
|---|---|---|---|
| fp8 | fp8_e4m3 | flashinfer | 48.8 |
| bf16 | bf16 | triton | 49.1 |
| fp4 | fp4_mx_block16 | triton | 11.6 |
| fp8 | fp8_e4m3 | triton | ❌ 崩溃 (fp8e4nv 不支持) |
5.2 根因:反量化不融合
SGLang: batched_dequantize (torch.compile 逐元素) 每层每次 KV 读取全量反量化 bf16 临时张量。llama.cpp: dequantize_V_q4_0 (forceinline) 融合在 FA kernel 内部, 零开销。
本质: 不是硬件限制, 是框架工程差异。
5.3 反量化 kernel 原型
手写 Triton kernel: diff=0 (bit-identical), 2.4-3.1x 反量化加速。但反量化只占总时间 5%, fp4 总速度仅 11.7 → ~12 t/s。fp4 补丁投入产出比低 (复杂 + 收益 3%)。
六、3090 GDN 突破方案论证
6.1 GDN kernel 硬限制 (SM86)
| kernel | 架构要求 | 3090 |
|---|---|---|
| triton | 任意 | ✅ (唯一可选) |
| flashinfer GDN | SM90+ | ❌ RuntimeError |
| cutedsl | SM100+ | ❌ 启动成功但 decode 卡死 |
| ReplaySSM | batch≥64 | ❌ 单并发无效 |
6.2 为什么 49 vs llama 73 t/s
CUDA Graph 已捕获生效 → 非 launch-bound。差距 = triton kernel GPU 执行效率 vs llama 手写 CUDA (gated_delta_net.cu 273行 1 kernel 融合)。突破需手写 CUDA kernel (成本高, 理论 49→70 t/s)。
6.3 35B 日志的启发(验证无效)
35B 用 –mamba-backend flashinfer 快 (130 t/s), 但:
35B MoE 仅 ~10 层 GDN, 27B dense 48 层。flashinfer GDN 需 SM90+, 3090 不支持。实测 27B: mamba-backend flashinfer 后 GDN 仍 Triton, 更慢 (44 vs 49)。
七、避坑记录
一、fp8 + triton 崩溃: fp8e4nv not supported — fp8 KV 必须 flashinfer
二、cutedsl 假成功: 启动显示 CuteDSLGDNKernel 但 decode 卡死 — 必须实测
三、mamba-backend 不影响 GDN kernel: 需 –linear-attn-decode-backend
四、0.96/0.97 假成功: 捕获成功但推理 OOM (activation 硬限制)
五、context-length 不影响 KV 池: KV 池由 mem-fraction 决定
六、显式 cache 时 ratio 是死参数: –mamba-full-memory-ratio 仅 auto 模式生效
七、单请求超 KV 池报错: context-length 应 = 池容量 (或略低)
八、bs=1 是坑 (llama.cpp): GGML_CUDA_GRAPH_OPT=1 多轮上下文变化致 CG 重录, 65→10-13 t/s
八、双引擎策略
| 场景 | 引擎 | 配置 |
|---|---|---|
| 高并发/多子代理 | SGLang (GPU1) | sgl-qwen27b-gpu1 :15433 |
| 单请求速度 | llama.cpp (GPU0) | lla-qwen27b-gpu0 :11434 |
| 长上下文 | llama.cpp | 131072 ctx |
各取所长: SGLang 3 并发 130 t/s, llama.cpp 单请求 73 t/s + 更长上下文。
相关文档
docs/review/sglang-qwen3.8-27b-parameter-tuning-experiments-2026-08-15.md — 参数优化完整实验记录 (9章)
docs/review/c1skill-sglang-fp4-kv-slow-rootcause-2026-08-15.md — fp4 根因 c1skill 分析
docs/qwen3.8-27b-deployment-research.md — 27B 部署研究总纲
docs/sglang-35b-moe-deployment-and-tuning.md — 35B MoE 权威配置 (对比参考)
docs/24gb-vram-long-context-challenge.md — 35B 长上下文挑战
文档生成: 2026-08-15, 基于当日全部实验数据
