24GB 显存笔记本
跑 177B MoE 模型
用 llama.cpp 的专家卸载把 79GB 的模型拆到显存、内存、固态三层, 配合上下文调优与 KV 量化,把生成速度推到 27 tok/s, 同时保留完整的图像识别能力。
它是怎么跑起来的
模型 79GB、显存 24GB。核心思路是按访问频率把模型拆成三层,而不是简单按层切分:
| 位置 | 放什么 | 原因 | 占用 |
|---|---|---|---|
| 显存 24GB | 注意力层 + 16 层专家 + KV 缓存 + 图像投影 | 每 token 都要用,带宽最高(1.8 TB/s) | 23.2 GB |
| 内存 64GB | 其余 32 层专家 | 稀疏激活(每 token 只用 10/512 个),带宽够用 | ~33 GB |
| 固态 NVMe | n-gram 查表(35.8GB) | dio 模式直读,不占内存 | 35.8 GB |
注意力每 token 都要用,必须放带宽最高的显存;专家层稀疏激活,可以放带宽低但容量大的内存里由 CPU 计算。这样 79GB 的模型才能在 24GB 显存上跑起来。
瓶颈在哪
实测推理期间 GPU 利用率约 25%,CPU 接近满载 —— 这是"专家由 CPU 计算"的必然:GPU 算完注意力段就得等 CPU 算专家段。
在"模型 79GB > 显存 24GB"的前提下,GPU 等待 CPU 是物理必然。增加内存解决不了(瓶颈是显存容量),唯一办法是换更大显存的显卡。
先下载模型
本方案使用的模型与配套文件,全部来自公开的 Hugging Face 仓库(按 Qwen Community License 1.0 发布):
| 文件 | 说明 | 大小 | 来源 |
|---|---|---|---|
| AD-3.84bpw-IQ4_XS-M64 | 主模型(28 分片) | 84.9 GB | AtomicChat/Qwen3.8-Flash-Next-GGUF → |
| mmproj-Qwen3.8-Flash-Next-F16.gguf | 视觉投影(图像识别,可选) | 0.85 GB | 同一仓库 → |
| llama.cpp | 推理引擎(需支持 Qwen3.8-Flash-Next 架构的构建) | — | github.com/ggml-org/llama.cpp → |
| Qwen/Qwen3.8-Flash-Next | 原始权重(仅作参考,不需要下载) | — | Qwen 官方 → |
区别不在位宽,而在分片布局:只有 AtomicChat 的 -M64 版本把 N-gram 表(35.8GB)
放进独立分片。其他发布方(如 unsloth 的 UD 系列)把表与专家混装在同一分片里 ——
一旦这片被访问,整片(几十 GB)都会被锁进内存,在 64GB 机器上直接压垮。
实测对比:同一台机器上,混淆分片的量化会出现"长对话到 60K~100K token 时静默崩溃", 而 AtomicChat 版本可以塞满整个 256K 上下文稳定运行。
下载方式(任选)
# 方式 1:huggingface-cli(推荐,支持断点续传) pip install -U "huggingface_hub[cli]" hf download AtomicChat/Qwen3.8-Flash-Next-GGUF --include "*AD-3.84bpw-IQ4_XS-M64*" --local-dir D:\models\Qwen3.8-Flash-Next # 方式 2:同时下载主模型 + 视觉投影 hf download AtomicChat/Qwen3.8-Flash-Next-GGUF --include "*3.84bpw*" --include "*mmproj*" --local-dir D:\models\Qwen3.8-Flash-Next # 方式 3:网页端 # 打开 https://huggingface.co/AtomicChat/Qwen3.8-Flash-Next-GGUF # → Files and versions → 下载 28 个分片
24GB 显存 + 64GB 内存 + NVMe SSD 是本方案的实测配置。
内存少于 64GB 时,模型无法完整驻留(需要更小的量化,但质量会下降);
显存少于 24GB 时需要提高 --n-cpu-moe,速度会明显下降。
快速开始
核心启动命令(推荐配置)
# 112K 上下文 + 图像识别 + 优化配置(27 tok/s)
cd D:\llama.cpp
.\llama-server.exe -m "D:\models\Qwen3.8-Flash-Next\Qwen3.8-Flash-Next-AD-3.84bpw-IQ4_XS-M64\Qwen3.8-Flash-Next-AD-3.84bpw-IQ4_XS-M64-00001-of-00028.gguf" `
-ngl 99 --n-cpu-moe 32 -fa on -fit off `
-c 114688 -np 1 --jinja --alias qwen3.8-flash-next `
--temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0 `
--host 127.0.0.1 --port 8080 `
-ctk q8_0 -ctv q8_0 --load-mode dio `
-mm "D:\models\Qwen3.8-Flash-Next\mmproj-Qwen3.8-Flash-Next-F16.gguf"
约 30~60 秒。看到 listening on http://127.0.0.1:8080 即就绪。
停止
D:\llama.cpp\stop-qwen38.ps1
或在启动窗口按 Ctrl+C。关掉启动窗口 = 服务停止(前台进程)。
按场景调整
| 场景 | 改动 | 实测 |
|---|---|---|
| 极速 | -c 114688 --n-cpu-moe 32 | 27.12 tok/s |
| 均衡 | -c 163840 --n-cpu-moe 33 | 25.83 tok/s |
| 长文档(推荐) | -c 262144 --n-cpu-moe 36 | 25.08 tok/s |
客户端接入
| 配置项 | 值 |
|---|---|
| API 类型 | OpenAI 兼容 |
| Base URL | http://127.0.0.1:8080/v1 |
| 模型名 | qwen3.8-flash-next |
| API Key | 任意(如 sk-local) |
| 流式输出 | 务必开启 |
| 上下文长度 | 114688(按启动档位填) |
| max_tokens | 16000 |
思考强度:默认即最高档
实测不传 reasoning_effort 时,服务端默认按 xhigh 处理(思考量 95 字 vs low 的 28 字)。客户端没有该选项时无需任何操作。
实测复杂推理题思考量可达 5700+ 字符(约 3000 token)。设成 500 会出现"模型想完了但一个字答案都没输出"。建议 16000 —— 它是上限而非消耗。
性能实测
数据来自服务端日志的 eval time(只计纯生成时间),temperature=0 固定输出长度保证可比。
本轮关键发现:关掉 MTP 反而更快
| 配置 | 显存 | decode | 说明 |
|---|---|---|---|
| MTP 开 + ncmoe=36 | 23.5 GB | 22.0 tok/s | 起点 |
| MTP 关 + ncmoe=36 | 20.2 GB | 25.4 tok/s | 关 MTP 省 3.5GB、快 15% |
| MTP 关 + ncmoe=34 | 21.1 GB | 26.93 tok/s | 省下的显存换专家层 |
| MTP 关 + ncmoe=32 | 23.2 GB | 27.12 tok/s | 当前最优 |
推测解码的验证批要读取"多个 token 激活专家的并集" —— 在专家大部分驻留内存的架构下,这会把内存流量放大,省下的前向次数抵不过多读的权重。
上下文 vs 速度(无 MTP,实测)
| 上下文 | ncmoe | decode | 显存 |
|---|---|---|---|
| 32K | 35 | 26.61 tok/s | 22.6 GB |
| 64K | 35 | 25.81 tok/s | 23.3 GB |
| 80K | 36 | 25.37 tok/s | 22.9 GB |
| 112K | 32 | 27.12 tok/s | 23.2 GB |
| 128K | 32 | 25.44 tok/s | 23.5 GB |
| 144K | 32 | 23.93 tok/s | 23.6 GB |
| 160K | 33 | 25.83 tok/s | 23.3 GB |
| 192K | 34 | 25.31 tok/s | 23.1 GB |
| 256K(全长) | 36 | 25.08 tok/s | 23.4 GB |
曲线整体很平(21~27 tok/s 区间),说明上下文容量几乎不影响生成速度 —— 真正的决定因素是显存里的专家层数。需要长文档时直接开满 256K。
首字节等待(决定"感觉快不快")
| 输入长度 | 首字节 | 说明 |
|---|---|---|
| 1K token | 1~3 秒 | 日常短问,体验流畅 |
| 8K token | 约 25 秒 | 中等文档 |
| 12.6K token | 约 40 秒 | 长文档 |
| 112K token | 约 350 秒 | 极限(整本书) |
prefill 阶段要把文档"读"一遍并建 KV 缓存,速度约 320~400 tok/s,不是故障。多轮对话中第 2 轮起会快很多(prompt cache 复用)。
调优历程
从 22.0 tok/s 到 27.12 tok/s,以及一路试错的经验。
✅ 有效(按贡献排序)
| 优化 | 贡献 | 原理 |
|---|---|---|
| 关闭 MTP 推测解码 | +23% | MoE + CPU 专家下验证批放大内存流量,得不偿失 |
| 减小上下文(128K→112K) | +15.6% | 释放显存压力,越过"临界点" |
--n-cpu-moe 精调(40→32) | +10~15% | 更多专家进显存,减轻 CPU 负担 |
--load-mode dio | 约 +10% | 绕页缓存直读 SSD,可用内存 7GB→20GB |
| 换 3.84bpw 小模型 | 约 +10% | 体积小 8.9GB,省出的显存多放专家 |
| KV 量化 q8_0 | 约 +6% | 省约 1GB 显存换专家层(本机验证精度无损) |
❌ 无效(别再折腾)
| 尝试 | 结果 | 原因 |
|---|---|---|
| MTP 推测解码 | −15% | 见上 |
| MTP 模型挪到 CPU | −11% | 草稿生成变慢,拖累整体 |
| MTP 的 KV 量化 | −19% | 草稿精度下降,接受率 0.49→0.37 |
| ncmoe 低于 30 | OOM | 显存不够 |
-ub 1024 | OOM | 计算缓冲随 ubatch 增大 |
--poll 0 | −2% | 无改善 |
| KV 降到 q4_0 | 不更快 | 量化开销抵消显存收益 |
--cpu-strict 1 | +0.2% | 核心绑定,噪声范围 |
--prio 2 | −0.8% | 进程优先级,无改善 |
-b 4096 | ±0% | 更大批处理,无改善 |
| 关闭 VBS / HVCI | ≈0 | VBS 开销在系统调用/页表,瓶颈是 CPU 矩阵运算 |
累计排除 12 项优化方向。剩余提升路径只在硬件侧:更快内存(+7.7%)、更小量化(+10~15%,质量待验证)、换更大显存显卡(唯一大幅提升)。
GPU 利用率为什么只有 25%
decode 是串行接力:每生成一个 token 都要走完 48 层,每层是「GPU 算注意力 → CPU 算专家」。GPU 在 CPU 算专家时只能干等。要填满 GPU 只能把更多专家放进显存,而显存已经满了。
对比:若 79GB 模型能全放显存(约需 4 张 5090),利用率可达 80%+。
常见问题
服务起不来 / 报 OOM
- 关掉其他占用显存的程序
- 提高
--n-cpu-moe(如 32→34) - 检查残留进程:任务管理器搜
llama-server
速度比预期慢
- 刚启动?前几次推理慢(缓存冷)
- 在处理长文档?见首字节表
- 用的是 xhigh 思考?复杂题思考久属正常
- GPU 被占用?
nvidia-smi查看
能不能提升 GPU 利用率
当前硬件上不能。显存 24GB 已满载,无法再往 GPU 塞专家。增加内存也没用(瓶颈是显存容量)。
加内存到 128GB 有帮助吗
| 收益 | 程度 |
|---|---|
| 系统更从容 | 明显 |
| 提速 | 几乎没有 |
| 提高 GPU 利用率 | 不能 |
注意:本机 4 个内存插槽全满,升级需整组替换(4×32GB)。
NVFP4 量化有帮助吗
对生成速度没有。NVFP4 加速的是 prefill(首字节 +43~68%),decode 完全不变(~0%) —— decode 是带宽受限,FP4 张量核帮不上。此外该模型目前也无 NVFP4 版本。
想改参数
编辑 D:\llama.cpp\start-best-*.ps1:
$NCMOE = 32 # CPU 侧专家层数(调低=更快,但会 OOM) $CTX = 114688 # 上下文容量 $KVQUANT = "q8_0" # KV 量化 $LOADMODE = "dio" # 加载模式 $NMAX = 4 # MTP 草稿长度(当前已停用 MTP)
参数速查
| 参数 | 当前值 | 作用 |
|---|---|---|
-ngl 99 | 99 | 所有层上 GPU(注意力必须留显存) |
--n-cpu-moe | 32 | 前 32 层的专家权重放 CPU |
-c | 114688 | 上下文(112K) |
-ctk / -ctv | q8_0 | KV 缓存量化 |
-fa on | on | FlashAttention(必开) |
--load-mode | dio | 绕过页缓存直读 SSD |
-mm | mmproj-F16 | 图像识别 |
--spec-type | 不使用 | MTP 在此架构下为负收益 |
-np | 1 | 并发槽位 |
环境
| 项 | 值 |
|---|---|
| GPU | RTX 5090 Laptop 24GB(Blackwell sm_120) |
| CPU | Intel Core Ultra 9 275HX |
| 内存 | 64GB DDR5-5200(4×16GB,最大可扩 128GB) |
| 引擎 | llama.cpp b10840 |
| 模型 | Qwen3.8-Flash-Next AD-3.84bpw-IQ4_XS-M64(79.1GB / 28 分片) |
| 视觉 | mmproj-F16(0.85GB) |
| 系统优化 | Defender 排除模型目录;VBS/HVCI 已关闭(实测无影响) |
三条纪律
- 只开一个实例 —— 多开必爆显存,速度跌到个位数
- 用完就关 —— 常驻占 23GB 显存
- 改配置后必须重启进程 —— 参数只在启动时读取