RTX 3080 Laptop 上 llama.cpp 跑 MoE:CPU 卸载层数实测
2026-07-22
测评笔记
00

目录

环境
怎么测
卸载层数 vs 速率 / 显存
大上下文(64K)稳不稳
瓶颈
编码向参数
别的显存怎么套
故障
复现
小结

RTX 3080 Laptop(16GB)上用 llama.cpp 跑 Qwen3.6‑35B‑A3B(Q4_K_M,19.7GiB)这种 MoE。权重装不满显存,只能部分层卸到 CPU。下面扫了一圈 -ngl,看速率、显存和大上下文会不会崩,给编码助手定一组能长期用的参数。

MoE 每 token 只激活一小部分专家,decode 比同参数 dense 省算力,但权重还是要全驻留。16GB 塞不下 19.7GiB,混合卸载免不了。

环境

规格
GPURTX 3080 Laptop,16GB,约 90W,sm_86
CPU11 代 Intel,8 核 16 线程(AVX‑512)
内存64GB ECC
系统Ubuntu 22.04
驱动595.71.05(CUDA 运行时上限 13.2)
llama.cppCUDA 版,build 571d0d5,Toolkit 12.4
二进制~/llama.cpp/bin/llama-server / llama-cli / llama-bench
模型Qwen3.6-35B-A3B-…-Q4_K_M.gguf,19.70 GiB,34.66B,MoE(约 3B 激活)

怎么测

速率用官方 llama-bench(pp / tg,带标准差,无 HTTP 干扰)。显存和稳定性用 llama-server 实测。

这版 server 默认不怎么打逐请求 tok/s,大上下文时 HTTP 还可能先回 "Loading model",所以速率不以 curl 为准。

指标:

  • pp512:喂 512 token 的 prefill 吞吐
  • tg128:生成 128 token 的 decode 吞吐
  • VRAM:加载后 nvidia-smi 占用
  • 稳定性:目标 ctx 下能否真正完成一次生成

顺带记下几个坑:

  1. pkill -f llama-server 会把含这段字样的 shell 自己干掉,写成 pkill -f '[l]lama-server'
  2. -fa auto 不会开 Flash Attention,要 -fa on
  3. 本构建里 --n-gpu-layers auto 几乎不往 GPU 卸(只占约 335MiB),必须写死数字。
  4. /health 在模型还在加载时就可能 200,就绪以真实生成拿到 choices 为准。

卸载层数 vs 速率 / 显存

llama-bench,pp512 + tg128,-fa 1 -t 16,重复 2 次取均值:

nglpp512 (tok/s)tg128 (tok/s)状态
16470.56 ± 7.4925.11 ± 0.13OK
24582.11 ± 5.1232.50 ± 0.71OK
28670.28 ± 3.8439.14 ± 0.39OK
30723.46 ± 7.9342.88 ± 0.63OK(小上下文)
32加载失败(OOM)

原始片段:

| model | size | params | backend | ngl | threads | fa | test | t/s | | qwen35moe 35B.A3B Q4_K | 19.70GiB | 34.66 B | CUDA | 16 | 16 | 1 | pp512 | 470.56 ± 7.49 | | qwen35moe 35B.A3B Q4_K | 19.70GiB | 34.66 B | CUDA | 16 | 16 | 1 | tg128 | 25.11 ± 0.13 | | ... | | | | 30 | 16 | 1 | tg128 | 42.88 ± 0.63 | llama_bench: error: failed to load model '...Q4_K_M.gguf' # ngl=32

llama-server 加载,ctx=8192,-fa on

nglVRAM (MiB)VRAM (GB)余量 (GB)
06330.6215.36
843194.2211.76
1681517.968.02
241191111.634.35
281386313.542.44
301476914.421.56
321574715.380.60
34+OOM

粗算每层权重大约 0.46 GiB(8151→11911,跨 8 层约 3760MiB)。ngl 16→30,decode 25.1→42.9 tok/s(+71%),prefill 470→723(+54%)。ngl=32 余量只剩 0.6GB,bench 直接加载失败。ngl=30 小上下文最快,但余量只有 1.56GB,大上下文另说。

大上下文(64K)稳不稳

编码会塞文件和历史。ctx=65536,对 ngl=24/28/30 各起一次 server,加载后发约 5441 token 的 prompt 再生成:

ngl进程生成VRAM (MiB)prefill(5441 tok)结论
24成功131857.65s,约 711 tok/s稳,约余 2.7GB
28成功152716.57s,约 828 tok/s稳,约余 0.7GB
30失败169段错误,core dumped

ngl=30 在 bench 里能到 42.9 tok/s,一上 64K 就崩。权重已经占约 14.4GB,KV 再分配时显存不够。

ngl=24 下,5441 token 让 VRAM 从 11911 涨到 13185,KV 大约 0.234 MiB/token。KV 主要跟着卸到 GPU 的层走,ngl 越高,大上下文越吃紧。

瓶颈

  • 16GB 显存:ngl≥34 加载就 OOM;19.7GiB 权重只能混合卸。
  • KV:ngl=30 + 64K 直接崩;上下文一涨,高 ngl 先死。
  • 90W 功耗墙:小上下文 decode 上限大约就在 43 tok/s 附近,再抬 ngl 也突破不了多少。
  • CPU 卸载带宽:ngl 越低,decode 越慢(25→43)。
  • ngl auto:本构建基本不可用。

编码向参数

稳态用这一组:

bash
~/llama.cpp/bin/llama-server \ -m ~/guff/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive-Q4_K_M.gguf \ --n-gpu-layers 24 \ --ctx-size 65536 \ -fa on \ -t 16 \ -b 512 \ --host 0.0.0.0 --port 8080 --parallel 1 --metrics
指标实测
decode(小上下文)32.5 tok/s
prefill(约 5.4K)~711 tok/s
VRAM(5.4K 填充)13185 MiB,约余 2.7GB
64K能加载并完成生成

不选 30 是因为会话上下文会涨,必须给 KV 留空;24 在 5.4K 填充后还剩约 2.7GB。

短上下文、想再快点可以用 ngl=28,ctx 建议降到 32768,decode 约 39.1 tok/s。64K 下只剩约 0.7GB,填满容易崩。

不要用:ngl=30 + 大 ctx;ngl≥32-ngl auto-fa auto

还想硬撑上下文:

  1. 再降到 ngl=20,大约再腾出 1.8GB,decode 会掉到约 30 以下。
  2. KV 量化:-ctk q8_0 -ctv q8_0。更狠的 q4_0 本机试过,质量尚可但后来没用;要稳一点用 q8_0
decode tok/s (小上下文) 43 ┤ ● ngl=30 (64K 崩) 39 ┤ ● ngl=28 (余 ~0.7GB) 33 ┤ ● ngl=24 (余 ~2.7GB) ← 编码向 25 ┤ ● ngl=16 └──────────────────────────────────── ngl 16 24 28 30 32(OOM)

粗算:ngl 每加 4 层,decode 大约 +7 tok/s,显存大约 +1.8GB。16GB 这张卡上,编码任务我会停在 24。

别的显存怎么套

情况建议
≥24GB权重可全上 GPU,ngl=999,不必按这套折中
12GBngl 上限差不多,KV 更紧,可试 ngl=20 + ctx=32768 + KV q8_0
8GBngl≈16,ctx≤16384,或换更小模型
CPU 无 AVX‑512卸到 CPU 的层更慢,会更倾向抬高 ngl
不确定上限llama-bench -ngl 16 -ngl 24 -ngl 28 -ngl 30 -ngl 32 …,最后一个能加载的当小上下文上限,再减 4 层做大上下文

顺序:bench 找能加载的最大 ngl → 大上下文用 N_max−4 左右 → 显式 -fa on 和 ngl → 再用真实大 prompt 验一次。

故障

现象处理
failed to load model / OOM降 ngl,每次 −4
Segmentation fault降 ngl / 降 ctx,或开 KV q8_0
速率异常低确认 -fa on、ngl 写对了,看 nvidia-smi
auto 只占几百 MiB改成显式 ngl
一直 "Loading model"等真正生成返回 choices
pkill 把自己干掉pkill -f '[l]lama-server'

复现

速率:

bash
~/llama.cpp/bin/llama-bench \ -m ~/guff/Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive-Q4_K_M.gguf \ -ngl 16 -ngl 24 -ngl 28 -ngl 30 -ngl 32 \ -p 512 -n 128 -fa 1 -t 16 -r 2

显存:

bash
for N in 0 8 16 24 28 30 32; do pkill -9 -f '[l]lama-server' 2>/dev/null; sleep 2 ~/llama.cpp/bin/llama-server -m <MODEL> --n-gpu-layers $N --ctx-size 8192 \ -fa on -t 16 --host 127.0.0.1 --port 8190 > /tmp/v.log 2>&1 & sleep 18 echo "ngl=$N vram=$(nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits)MiB" pkill -9 -f '[l]lama-server' 2>/dev/null done

64K 稳定性:

bash
for NGL in 24 28 30; do pkill -9 -f '[l]lama-server' 2>/dev/null; sleep 3 ~/llama.cpp/bin/llama-server -m <MODEL> --n-gpu-layers $NGL --ctx-size 65536 \ -fa on -t 16 --host 127.0.0.1 --port 8196 > /tmp/stab.log 2>&1 & pid=$!; sleep 50 vram=$(nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits) alive=$(ps -p $pid >/dev/null && echo 1 || echo 0) curl -s http://127.0.0.1:8196/v1/completions -H 'Content-Type: application/json' \ -d '{"prompt":"<5441-token prompt>","max_tokens":32,"temperature":0}' \ | grep -q choices && gen=1 || gen=0 echo "ngl=$NGL alive=$alive gen=$gen vram=${vram}MiB" kill $pid 2>/dev/null; pkill -9 -f '[l]lama-server' 2>/dev/null done

小结

编码向:--n-gpu-layers 24 --ctx-size 65536 -fa on -t 16。小上下文 decode 约 32.5 tok/s,5.4K prefill 约 711 tok/s,还能撑 64K。要速度、上下文不长可以试 28;30 以上配大 ctx 别碰。

bench 上最快的 ngl,不一定能扛大上下文。最终参数要用真实长 prompt 验过再定。

ai协作,人工编辑

本文作者:张老板

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!