开源llama.cpp Releases·原文 2026年9月25日

llama.cpp CUDA后端合并RMS_NORM与SCALE内核,投机解码预填充提速约 4%

b11177版本为rms_norm_f32增加do_scale标志,把GDN层的l2norm两步运算融进一个内核;在 2 张GTX 1080 Ti上,draft-mtp投机解码的 20000 token冷预填充从 322.0 tok/s升至 337.4 tok/s。

AI解读:这次改动的核心是把RMS_NORM和SCALE两个GPU内核合成一个。此前GDN层的q/k l2norm被拆成ggml_scale(ggml_rms_norm(x, eps/n), 1/sqrt(n)),每个GDN层多出 2 个SCALE节点,在 48 层GDN的Qwen3.8-27B上每个ubatch多出 96 次内核启动。这些内核几乎不占GPU时间,但每次启动都要付主机和驱动的开销。

真正受影响的是用CUDA跑投机解码的人。普通批量处理时这部分开销很小,但report里说draft-mtp场景下大约是前者的 10 倍,所以合并在冷预填充上有感。实测 20000 token预填充提升 4.8%,普通llama-bench生成只快 0.4% 到 1.3%。换句话说,这不是让模型变聪明,是让等待变短,而且只在特定配置下明显。

融合只在SCALE不带bias且rms_norm输出只有一个消费者时才触发,数值上声称与未融合版本逐位一致:困惑度 3.2030 不变,draft接受计数也一致。Metal和SYCL后端此前已经做了同样的融合,这次是CUDA补上。如果你不用CUDA或不做投机解码,这个版本的收益有限,不必专门升级。

llama.cpp发布b11177版本,CUDA后端把RMS_NORM与SCALE融合为单个内核(#29393)。改动给rms_norm_f32增加do_scale标志,沿用do_multiply/do_add的既有模式,融合路径与未融合版本共享内核、归约和启动器。

为什么多出来 96 次内核启动

版本说明指出,#28068 把GDN的q/k l2norm构造为ggml_scale(ggml_rms_norm(x, eps/n), 1/sqrt(n))。这会让每个GDN层增加 2 个SCALE节点,在拥有 48 个GDN层的Qwen3.8-27B上,每个ubatch多出 96 次内核启动。

这些额外内核本身不消耗可测量的GPU时间,但每次启动都有主机与驱动成本。该成本在普通批处理下很小,在draft-mtp投机解码下大约是前者的 10 倍。

融合后的内核计算scale * (rsqrt(mean + eps) * x),与未融合的rms_norm + scale逐位一致,因此 #28068 的数值结果得以保留。融合仅在SCALE没有bias且rms_norm输出只有一个消费者时触发(ggml_can_fuse)。Metal(#28948)和SYCL(#28931)此前已经融合了相同模式。

2 张GTX 1080 Ti上的实测数据

测试平台为 2 张GTX 1080 Ti(sm_61,PCIe 3.0 x16 + x4)、i7-13700KF、Windows 11、驱动 582.66、CUDA 12.9,模型Qwen3.8-27B-UD-Q4_K_XL,参数 -ngl 99 -ts 53,47 -ot token_embd=CPU,基线master fee39dd92。

llama-bench -ub 128,512 -p 512,2048 -n 128 -r 5的结果(tok/s):master在pp512@128、pp2048@128、pp2048@512、tg128上分别为 367.7、419.1、385.4、12.90;应用修复后为 372.6、420.6、388.6、12.98,分别提升 1.3%、0.4%、0.8%、0.6%。

llama-server冷预填充,参数 -c 56000 -ub 128 -b 2048,draft-mtp n-max 3、p-min 0.5,2 轮x 3次重复取均值:master在 8000 token和 20000 token预填充上为 356.5 和 322.0;修复后为 371.4(+4.2%)和 337.4(+4.8%)。

每个ubatch的启动次数从 1032.9 + 841.7(CUDA0 + CUDA1)回落到 978.9 + 799.7,即b10828时的计数,GPU算子总和不变。

  • 测试项test-backend-ops的RMS_NORM_SCALE、NORM_SCALE、RMS_NORM_MUL_ADD、RMS_NORM_MUL_ROPE、RMS_NORM、RMS_NORM_BACK、NORM、L2_NORM和SCALE在两张GPU上全部通过。
  • 困惑度与未融合版本相同:在 -c 2048、16 个chunk下为 3.2030 +/- 0.0559。
  • 每个请求的draft接受计数与未融合版本一致。

信息来源

llama.cpp Releases原始来源