你也会崩溃:SGLang 部署 Qwen3.6-27B 从失败到稳定的全程复盘
我下载了模型,写好启动命令,按回车——不到一秒,终端弹出红色错误并退出。这不是我第一次踩坑,但这回尤其让人头大:一个 dtype 不匹配的崩溃,让我折腾了整整一个下午。
如果你也准备把 Qwen3.6-27B 量化版跑在 SGLang 上,这篇文章就是为你写的。我记录了从模型选择到最终稳定运行的每一步——踩了哪些坑、怎么绕过去的、最终配置长什么样。跟着做,10分钟内你就能跑出第一行输出。
为什么选这个模型
手上硬件:Debian 12,AMD Ryzen 9 5950X,两根 RTX 3090(每张 24GB),64GB 内存。想在单卡上跑一个能打的模型,首选项就是量化版。
Qwen3.6-27B 是阿里最新的密集模型,27B 全激活参数,原生 262K 上下文。三个量化版本中,我选了 cyankiwi 团队的 Qwen3.6-27B-AWQ-INT4:
| 团队 | 模型 | 大小 | 月下载量 |
|---|---|---|---|
| cyankiwi | Qwen3.6-27B-AWQ-INT4 | ~20GB | 103万 |
| QuantTrio | Qwen3.6-27B-AWQ | 21GB | 148万 |
为什么选 cyankiwi?它的文件更小(15-20GB vs 21GB),校准集使用了 STEM + Agentic 数据,理论上质量更好。而且有 INT4、BF16-INT4、NVFP4 多个变体,适配性更强。
下载模型
用 Hugging Face CLI 直接拉,比 Python 脚本更少出网络问题:
# 先登录(第一次)
huggingface-cli login
# 下载整个仓库
huggingface-cli download cyankiwi/Qwen3.6-27B-AWQ-INT4 \
--local-dir /opt/ai-workspace/models/huggingface/cyankiwi/Qwen3.6-27B-AWQ-INT4 \
--local-dir-use-symlinks False
注意:模型有 4 个 safetensors 分片,每个约 5GB,总共约 22GB。如果你的网络不稳定,加上 --resume-download 参数支持断点续传。下载时间约 30 分钟,取决于你的网速。
第一次启动——崩溃
SGLang 官方推荐用 Docker 部署,当前版本 v0.5.14:
docker pull lmsysorg/sglang:latest
然后我写了这个启动命令:
docker run -d \
--gpus device=0 \
--shm-size 32g \
--name sgl-qwen27b \
-p 11434:30000 \
-v /opt/ai-workspace/models:/models:ro \
--ipc=host \
--restart unless-stopped \
lmsysorg/sglang:latest \
python3 -m sglang.launch_server \
--model-path /models/huggingface/cyankiwi/Qwen3.6-27B-AWQ-INT4 \
--reasoning-parser qwen3 \
--tool-call-parser qwen3_coder \
--context-length 65536 \
--host 0.0.0.0 \
--port 30000
结果:没跑起来。错误信息很长,关键一行是:
RuntimeError: Index put requires the source and destination dtypes match,
got BFloat16 for the destination and Half for the source.
原因:cyankiwi 的 compressed-tensors 格式内部有混合精度——模型配置文件写的是 torch_dtype: bfloat16,但某些权重张量以 FP16 存储。启动时 SGLang 的 GDN(Gated DeltaNet)线性注意力层初始化 conv_states 用了 BF16,前向传播输出却是 FP16,写入时 dtype 不匹配,直接崩溃。
第二次启动——解决 dtype 问题
加一个参数就能解决:
docker rm -f sgl-qwen27b && docker run -d \
--gpus device=0 \
--shm-size 32g \
--name sgl-qwen27b \
-p 11434:30000 \
-v /opt/ai-workspace/models:/models:ro \
--ipc=host \
--restart unless-stopped \
lmsysorg/sglang:latest \
python3 -m sglang.launch_server \
--model-path /models/huggingface/cyankiwi/Qwen3.6-27B-AWQ-INT4 \
--dtype bfloat16 \
--reasoning-parser qwen3 \
--tool-call-parser qwen3_coder \
--context-length 65536 \
--host 0.0.0.0 \
--port 30000
关键日志输出:
Load weight end. elapsed=13.30 s, type=Qwen3_5ForConditionalGeneration
quant=compressed-tensors, mem usage=19.05 GB
Mamba Cache: conv_state 0.02GB, ssm_state 1.12GB
KV Cache: dtype=torch.bfloat16, #tokens=21482, K 0.66GB, V 0.66GB
Capture target decode CUDA graph begin. backend=full ✅
注意:启动日志里还有一条看起来吓人的告警:
Acceleration for non-quantized schemes is not supported by Compressed Tensors.
Falling back to UnquantizedLinearMethod
这条信息是正常的。意思是:模型中那些本来就没量化的层(如 embedding、layer norm、lm_head),SGLang 不会强行应用压缩方案。从显存占用 19GB(对比 BF16 原版的 54GB)可以确认 INT4 量化确实生效了。SGLang 还 JIT 编译了 Marlin kernel 专门加速 4-bit 矩阵乘法。
参数调优——花最多的心思
关于 --mem-fraction-static 的血泪史
这个参数控制“模型权重 + KV Cache 池”占显存的比例。文档建议预留 5-8GB,于是我尝试从 0.92 往下降——
第一次尝试 0.80:
RuntimeError: Not enough GPU memory for hybrid (mamba/linear-attention) state cache
max_mamba_cache_size=-2
第二次尝试 0.88:
RuntimeError: Hybrid state cache is too small. max_mamba_cache_size=4
原因:Qwen3.6-27B 是混合 GDN 架构,48 层 Gated DeltaNet 需要额外的 Mamba State 缓存(约 1.14GB)。降低 mem_fraction_static 会先饿死这个 Mamba cache 池。
最终结论:0.92 是 24GB 卡上跑 19GB 模型的极限。文档说的 5-8GB 空闲是针对多用户生产环境的,单卡跑 27B 模型不可能实现。
一条旧告警的真相
旧文档记录了一个问题:RTX 3090(Ampere 架构)上使用 fp8 KV Cache 会禁用 CUDA Graphs,导致速度从 80 t/s 暴跌到 13 t/s。
经过核实,这是旧版本 SGLang 的问题。当前版本使用默认的 bf16 KV Cache(--kv-cache-dtype auto),CUDA Graphs 正常捕获,不存在此问题。核心证据就是日志里的那行绿色“Capture target decode CUDA graph begin. backend=full ✅”。
最终启动命令(复制即用)
docker rm -f sgl-qwen27b && docker run -d \
--gpus device=0 \
--shm-size 32g \
--name sgl-qwen27b \
-p 11434:30000 \
-v /opt/ai-workspace/models:/models:ro \
--ipc=host \
--restart unless-stopped \
lmsysorg/sglang:latest \
python3 -m sglang.launch_server \
--model-path /models/huggingface/cyankiwi/Qwen3.6-27B-AWQ-INT4 \
--dtype bfloat16 \
--reasoning-parser qwen3 \
--tool-call-parser qwen3_coder \
--context-length 65536 \
--mem-fraction-static 0.92 \
--cuda-graph-max-bs-decode 8 \
--host 0.0.0.0 \
--port 30000
参数速查:
| 参数 | 值 | 为什么 |
|---|---|---|
--dtype bfloat16 |
必选 | 解决 compressed-tensors 混合精度 GDN 崩溃 |
--reasoning-parser qwen3 |
推荐 | 分离 thinking/content,流式返回 reasoning_content |
--tool-call-parser qwen3_coder |
按需 | Qwen3.6 原生 tool calling |
--context-length 65536 |
推荐 | 24GB 卡上 64K 是安全上限 |
--mem-fraction-static 0.92 |
必需 | 降低会导致 mamba cache 分配失败 |
--cuda-graph-max-bs-decode 8 |
优化 | 单用户场景减小 CUDA Graph batch 表 |
性能测试
服务启动后,用这个命令验证:
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"qwen3","messages":[{"role":"user","content":"帮我写一封生日贺卡"}],"max_tokens":256}'
非流式测试(3 轮取平均):
| 指标 | 值 |
|---|---|
| 吞吐 | ~44 t/s |
| 单次请求(173 tok) | ~3.9s |
| 首 token 延迟 | ~0.1s |
| 显存占用 | 23.5/24 GB |
与 llama.cpp 对比:同样大小的 GGUF Q4 模型在 llama.cpp 上约 65-70 t/s(含 MTP 推测解码)。SGLang 慢约 30%,原因有三个:
1. 无 MTP:cyankiwi 的 INT4 版不含 mtp 权重(MTP 需要额外的 mtp.safetensors 文件,只有官方 BF16/FP8 版才有)
2. 单用户场景:SGLang 的核心优势(连续批处理、RadixAttention)在单用户下几乎无效
3. decode 瓶颈:27B 模型 decode 阶段 85-90% 时间花在权重矩阵乘法上,attention 只占不到 1%
最终状态
GPU0 跑 SGLang + cyankiwi/Qwen3.6-27B-AWQ-INT4,速度约 44 t/s,占用 23.5GB 显存。GPU1 闲置,计划跑另一个实验模型。
最核心的三件事
- cyankiwi 的 compressed-tensors 格式必须加
--dtype bfloat16,否则 GDN 层会崩溃 --mem-fraction-static别动——0.92 是 24GB 卡的极限,降它就会饿死 Mamba cache- 单用户场景 SGLang 不一定最快——架构决定它在多用户高并发场景下才是王者,单用户不如 llama.cpp
你遇到过类似的问题吗?欢迎留言聊聊。
