48GB 显存部署 Qwen3.8-27B FP8:我是怎么把单流从 20 tok/s 拉到 31 tok/s 的

如果你手头有一张 48GB 卡,想把 Qwen3.8-27B FP8 做成一个稳定的 OpenAI 兼容推理服务,我的结论很直接:能做,而且双卡 128K 上下文下可以跑到单流约 31 tok/s、总吞吐约 60 tok/s。但前提是,你得先把显存账算清楚,再把磁盘写入点规划好,最后才是调参。

这套配置目前跑的是内部安全自动化、渗透测试辅助、代码审计和小团队共享推理。不是玩具,是每天在用的服务。

一、问题背景:为什么 27B FP8 在 48GB 卡上不是“随便跑跑”

部署对象是 orcarouter/Qwen3.8-27B-Uncensored-FP8,官方 Qwen3.8-27B 的第三方 FP8 量化版本。它保留了长上下文和工具调用能力,同时把显存压力压到了 48GB 卡能接住的范围内。

但“能接住”不等于“随便跑”。FP8 权重约 30.9GB,加载后实测占用 27.6GiB。单卡显存不仅要装权重,还要给 KV 缓存和运行时开销留余量。24GB 常规卡直接放不下,只能走双卡张量并行或更低比特量化。

目标能力很明确:单流解码不低于 30 tok/s、128K 上下文、函数调用、双卡并发。当前生产配置已经满足。

二、核心痛点:显存、磁盘、参数,一个都不能拍脑袋

2.1 显存账算错,后面全是白忙

选型第一依据不是预算,是显存。FP8 权重约 30.9GB,加载后实测 27.6GiB。48GB 卡的意义在于,它能把权重和缓存同时放进可控区间,长上下文才不会被压缩到不可用。

CPU 和内存也不能忽略。vLLM 的调度、分词和编译都依赖主机资源。经验上核数最好达到卡数的 8 到 16 倍,内存不低于权重总量的 2 倍。本次 2 卡配置用 32 核和 220GB 内存,运行期间主机内存占用约 11GB,余量充足。

2.2 系统盘写满,服务就起不来

推理服务启动时会写入多个位置:临时文件、编译缓存、JIT 编译产物。系统盘只有 40GB,任何一处写满,初始化就可能中止。

正确做法是把写入点统一迁到数据盘:

  • TMPDIR 指向 /data/tmp
  • VLLM_CACHE_ROOT 指向 /data/vllm-cache

这里最容易踩的坑是目录属主不对。目录如果是 root 创建的,运行用户可能没有写权限,FlashInfer 的 JIT 编译就会失败。

2.3 参数乱设,性能上不去

max-model-len 不是越大越好,它直接决定 KV 缓存预算。--max-num-seqs 越高,批处理收益越大,但单条序列速度会被摊薄。--gpu-memory-utilization 设得过高会压缩缓存余量,设得过低又会浪费显存。

三、不同方案对比:24GB 双卡张量并行 vs 48GB 数据并行

方案显存占用单流延迟总吞吐工程复杂度适合场景
24GB 双卡张量并行权重分片,KV 缓存紧张较高,跨卡通信有开销中等预算有限,能接受延迟
48GB 单卡数据并行权重完整,缓存充足个人或小团队
48GB 双卡数据并行每卡完整实例近似翻倍小团队共享、自动化流水线
更低比特 GGUF显存最低取决于量化中等牺牲 vLLM 工具调用生态

27B FP8 权重加载后实测占用 27.6GiB,当前更适合数据并行而不是张量并行。数据并行的好处是每张卡独立承载完整实例,互不干扰,整体吞吐更高。如果单卡放不下权重和 KV 缓存,才需要张量并行。张量并行会引入跨卡通信,单流延迟通常高于数据并行。

四、为什么选择 UCloud 48GB GPU 云主机 + 数据并行

4.1 开通流程

以 UCloud 控制台为例,流程是云主机 UHost → GPU 型。

  1. 机型选择 RTX40 系高显存机型,优先挑 48GB 版本;
  2. 地域和可用区优先选择有现货的区域,并提前确认后续扩容时的库存;
  3. 镜像选择 Ubuntu 22.04 且预装 GPU 驱动的版本,可直接省去驱动安装;
  4. 磁盘至少准备 40GB 系统盘和 200GB 以上数据盘;
  5. 安全组默认只放行 SSH,推理端口在验证通过后再按源 IP 放行。

图 1: image-1.png

图 2: image-2.png

图 3: image-3.png

图 4: image-4.png

图 5: image-5.png

4.2 计费方式的取舍

  • 先试后买:适合先跑通下载、部署和验证流程。
  • 按量计费:适合夜间批处理、临时压测和短周期任务。
  • 包月或包年:适合常驻推理服务,也是这套部署的实际选择。

双卡 48GB 常驻运行时,按量跑满一个月的成本通常明显高于包月,因此常驻场景没有必要长期按量。

4.3 系统初始化

先确认卡数、显存、驱动版本和 CUDA 工具链,再进入部署。

  • nvidia-smi
  • nvcc --version
  • cat /etc/os-release

本次镜像环境为两张 RTX 4090、驱动 570.133.07、CUDA 12.8、Ubuntu 22.04.4。若驱动或 CUDA 不完整,应优先按云厂商官方文档处理,不要直接套用第三方脚本。

数据盘已自动挂载到 /data 时,直接确认即可:

  • lsblk -f

如果没有自动挂载,就手动格式化并写入 fstab,避免重启后模型“消失”。

图 6: image-7.png

4.4 模型下载与校验

该仓库在 Hugging Face 上是 gated 状态,下载前要先完成页面授权,再在服务器上登录同一账号的 token。账号不一致时仍会被拒绝。

下载前建议关闭 Xet 协议解析,避免镜像环境里出现解析失败。数据量约 31GB,下载中偶发断连属于正常现象,hf 支持续传。

模型目录中的 model.safetensors.index.json 声明了权重总字节数。把声明值和本地分片大小求和比对,就能快速判断权重是否完整。本模型的期望值为 30866867136 字节。这个检查只需几秒钟,但能避免服务起不来时才发现权重损坏。

图 7: image-8.png

五、实际使用建议:启动配置与验证

5.1 推理环境

在数据盘单独创建虚拟环境,避免污染系统 Python。安装完成后,要先确认框架能识别模型架构文件,再进入启动阶段。

5.2 启动配置

当前有效配置的核心参数如下:

--max-model-len 131072
--max-num-seqs 8
--gpu-memory-utilization 0.9

5.3 验证

启动后先跑一次单流请求,确认延迟和吞吐达标,再开放给团队使用。

参数 当前值 作用 --data-parallel-size 2 每张卡跑一个完整实例,吞吐近似翻倍 --max-model-len 131072 提供 128K 上下文上限 --max-num-seqs 4 控制单实例并发

max-num-batched-tokens 16384 控制预填充批量大小 --gpu-memory-utilization 0.95 给权重和 KV 缓存分配主要显存预算 --speculative-config MTP 投机解码 这是提速最明显的优化 --enable-prefix-caching 开启 提升重复前缀的预填充效率 --host 127.0.0.1 只接受本机流量,外部通过代理访问

服务以 systemd 托管后,可实现自动拉起和失败重启。推理进程本身不直接暴露公网,只把本机端口交给前置代理转发,这样暴露面更小。

5.3 启动验证

首次启动通常需要 4 到 8 分钟,主要耗时在 Inductor 编译和 CUDA Graph 捕获。缓存写入数据盘后,后续启动会明显变快。

验证时先确认模型列表能正常返回,再做一次短对话请求:

图 8: image-10.png

图 9: image-6.png

5.4 关键参数解读

并行方式:27B FP8 权重加载后实测占用 27.6GiB,当前更适合数据并行。数据并行每张卡独立承载完整实例,互不干扰,整体吞吐更高。

上下文长度:这个模型采用混合注意力结构,只有一部分层使用全注意力,因此每 token 的 KV 开销明显低于同规模纯注意力模型。实测可用预算约 14.2GiB,单卡总容量报告约 221,880 tokens。重点不是把上限设得越大越好,而是让上限和实际任务长度匹配。

吞吐相关参数:--max-num-seqs 越高,批处理收益越大,但单条序列速度会被摊薄。--max-num-batched-tokens 影响长输入的分块预填充粒度。--gpu-memory-utilization 设得过高会压缩缓存余量,设得过低又会浪费显存。

功能相关参数:--dtype auto 让引擎读取模型量化声明,FP8 模型不应手工改成别的精度。--language-model-only 可跳过视觉塔,节省约 1 到 2GB 显存。--reasoning-parser qwen3 和 --tool-call-parser qwen3_xml 用于解析思考内容和 XML 工具调用。--chat-template 建议显式指向仓库自带模板,避免模板解析不一致。

六、性能优化:MTP 投机解码是收益最高的那一步

6.1 基线

首次测速在单流、固定提示词条件下得到两组结果:

  • 212 tokens,10.5 秒,20.1 tok/s
  • 190 tokens,9.4 秒,20.1 tok/s

这个速度对 27B FP8 加 48GB 4090 来说偏慢,说明还有优化空间。

6.2 启用 MTP 投机解码

收益最大的优化是启用 MTP 投机解码。模型自带 MTP 头,vLLM 对这类结构有原生支持,只需要打开对应配置即可。

启动日志出现 Detected MTP model. Sharing target model lm_head weights with the draft model. 时,说明 MTP 已经生效。启用后,单流速度提升约 55%。

投机解码的机制是先由草稿头预测下一个 token,再由主模型验证。只要验证通过,输出分布就和逐字生成一致,因此这是无损加速。

6.3 其他已启用项

-O3 编译优化、CUDA Graph、异步调度和前缀缓存都已经开启。对于 agent 类负载,前缀缓存对系统提示词和工具定义的重复预填充有实际收益。

6.4 推理侧使用建议

  • 交互式场景可以保留思考模式,批量任务和工具调用建议关闭思考模式,以免输出大量推理 token。
  • 并发请求优于串行请求。双实例总解码能力约 60 tok/s,异步提交比逐个等待更高效。

七、适合 / 不适合场景

场景 典型负载 推荐配置 适合的云主机 个人使用 1 到 2 并发,单轮 8K 以内 --data-parallel-size 1,--max-model-len 32768,--max-num-seqs 4 单张 48GB 卡,8 到 16 核,64GB 内存,200GB 数据盘 小团队共享 5 到 10 人日常使用,峰值约 10 并发 --data-parallel-size 2,--max-model-len 65536,--max-num-seqs 8 2 × 48GB 卡,32 核,220GB 内存,200GB 数据盘 自动化流水线 批量分析、夜间任务、对单条延迟不敏感 --data-parallel-size 2,--max-model-len 16384,--max-num-seqs 16 与小团队共享同档即可,优先再加一台同规格机器做横向扩容 长上下文专项 代码审计、大文档分析、1 到 3 并发 --data-parallel-size 2,--max-model-len 131072,--max-num-seqs 2 与小团队共享同档即可,重点是显存而不是再加卡

超出双卡规模时的处理顺序:

  • 先做水平加机,用负载均衡线性扩容;
  • 再考虑把 KV 缓存改成更低精度,换取更长上下文;
  • 最后才升级到更大的多卡或裸金属规格。

如果预算只够 24GB 卡,当前 FP8 权重单卡放不下,要么走双卡张量并行,要么切换到更低比特 GGUF 方案,但后者会牺牲 vLLM 的工具调用生态。

八、总结建议

这套部署的核心经验只有四条:

  • 云上部署先算显存账,再定卡型;
  • 所有磁盘写入点都要尽量放到数据盘;
  • 混合注意力模型的 KV 开销不能套用纯注意力经验值;
  • MTP 投机解码值得默认开启。

当前线上状态是双实例、128K 上下文、单流约 31 tok/s、总吞吐约 60 tok/s,能够稳定承载内部安全自动化和代码审计负载。

九、FAQ

9.1 为什么优先用数据并行?

因为单卡已经能放下权重和必要缓存时,数据并行的工程复杂度更低,总吞吐也更容易提升。

9.2 为什么把缓存和临时文件都迁到数据盘?

因为系统盘空间太小,模型加载、JIT 编译和缓存写入都可能把它写满,启动失败常常就出在这里。

9.3 128K 上下文会不会浪费显存?

不会。max-model-len 是上限,不是固定预留,KV 缓存按需分配。

9.4 思考模式太慢怎么办?

批量任务和工具调用可以关闭思考模式,只在深度推理任务里开启。