ik_llama.cpp CUDA MMQ 内核扩展:IQ4_KS_R4 与 IQ5_KS_R4 的 block-of-32 矩阵乘实现与性能剖析

发布时间:2026/9/20 0:25:23
ik_llama.cpp CUDA MMQ 内核扩展:IQ4_KS_R4 与 IQ5_KS_R4 的 block-of-32 矩阵乘实现与性能剖析 ik_llama.cpp CUDA MMQ 内核扩展IQ4_KS_R4 与 IQ5_KS_R4 的 block-of-32 矩阵乘实现与性能剖析【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp导读本文围绕 ik_llama.cpp 仓库中 PR 493 MMQ implementation for IQ4_KS_R4 and IQ5_KS_R4 展开剖析 ik_llama.cpp 为两类实验性 i-quant 类型IQ4_KS_R4、IQ5_KS_R4引入 CUDA MMQmul-mat-quantized量化矩阵乘内核的动机、实现路径与实测效果。你将了解到什么是 _R4 行交织量化与 block-of-32 GEMM 内核、MMQ 内核在 CUDA 侧如何按类型分派与实例化、为什么 MMQ 能显著提升 prompt 处理PP吞吐以及如何在 RTX-4080 上使用 sweep-bench 复现和解读 PP/TG 性能数据。背景从 GEMMGEMV 到 MMQIQ4_KS_R4与IQ5_KS_R4是 ik_llama.cpp 在标准IQ4_KS/IQ5_KS基础上引入的行交织row-interleaved后缀_R4量化变体把原本分散在多个 block 中的量化数据按 4 行交织重新排布从而让同一批数据能够套用更高效的 block-of-32 计算内核。在 ggml/include/ggml.h 中可以看到这两个类型有独立的枚举值GGML_TYPE_IQ4_KS_R4 344、GGML_TYPE_IQ5_KS_R4 352对应的 GGUF 文件类型为GGML_FTYPE_MOSTLY_IQ4_KS_R4 337、GGML_FTYPE_MOSTLY_IQ5_KS_R4 341。在此之前这两个类型在 CUDA 上只有 PR 462 CUDA GEMM and GEMV for IQ4_KS_R4 and IQ5_KS_R4 提供的实现——注意 PR 462 的说明当时 GEMM 是通过反量化 cuBLAS实现的并且提示在 DeepSeek-V3/R1 这类大模型上可能需要用-DGGML_CUDA_IQK_FORCE_BF161强制 bf16 运算以规避 fp16 的数值不稳定问题。PR 493 的动机在原文档中表述得很直接These two can use the more efficient block-of-32 MMQ GEMM kernels, so having MMQ implementation for them makes sense.即这两个 _R4 类型的数据布局天然适配 block-of-32 的 MMQ GEMM 内核与其继续走反量化 cuBLAS的通用路径不如为它们补齐专用 MMQ 内核从而获得更高的 prompt 处理性能。这也体现了 ik_llama.cpp 在量化内核上按类型逐项精雕的工程路线从 README.md 可以看到IQ4_KS_R4/IQ5_KS_R4的 CPU 实现分别来自 PR 150 与 PR 426CUDA GEMM/GEMV 来自 PR 462而 MMQ 内核正是 PR 493 的增量贡献。MMQ 内核的代码组织与类型分派MMQ 是 ggml CUDA 后端中负责量化权重 × 量化激活矩阵乘的一族模板内核。与直接反量化后交给 cuBLAS 不同MMQ 在 GPU 上以 tile分块方式加载量化权重 x 与量化激活 y利用 dp4a 或张量核心MMA完成整数点积累加再统一写回浮点结果。相关代码集中在 ggml/src/ggml-cuda/mmq.cu普通 GEMM 路径与 ggml/src/ggml-cuda/mmq_id.cu按行 id 分组的 MoE 路径。主机端类型分派在 ggml/src/ggml-cuda/mmq.cu 中ggml_cuda_mul_mat_q按type_x把调用分发到具体的模板实例case GGML_TYPE_IQ4_KS_R4: mul_mat_q_caseGGML_TYPE_IQ4_KS_R4(ctx, args, stream); break; case GGML_TYPE_IQ5_KS_R4: mul_mat_q_caseGGML_TYPE_IQ5_KS_R4(ctx, args, stream); break;对应的 MoE 路径用于按专家 id 做子矩阵乘如 DeepSeek 系列在 ggml/src/ggml-cuda/mmq_id.cu 中同样补上了两个 casecase GGML_TYPE_IQ4_KS_R4: mul_mat_q_case_idGGML_TYPE_IQ4_KS_R4(ctx, args, stream); break; case GGML_TYPE_IQ5_KS_R4: mul_mat_q_case_idGGML_TYPE_IQ5_KS_R4(ctx, args, stream); break;模板实例化文件CUDA 模板必须在编译期显式实例化。仓库采用每个类型一个实例文件 Python 脚本生成的组织方式例如ggml/src/ggml-cuda/template-instances/mmq-instance-iq4_ks_r4.cu内容为#include ../mmq.cuh与DECL_MMQ_CASE(GGML_TYPE_IQ4_KS_R4);ggml/src/ggml-cuda/template-instances/mmq-instance-iq5_ks_r4.cu内容为DECL_MMQ_CASE(GGML_TYPE_IQ5_KS_R4);MoE 变体见 ggml/src/ggml-cuda/template-instances/mmq-instance-iq4_ks_id.cu 与 mmq-instance-iq5_ks_id.cu这些实例文件由 ggml/src/ggml-cuda/template-instances/generate_cu_files.py 自动生成文件头部有 This file has been autogenerated 注释新增量化类型时只需扩展生成脚本与 mmq.cuh 中的类型特征表即可批量产出实例代码。类型特征表MMQ 如何知道怎么加载 IQ4_KS_R4MMQ 之所以能做到一核多类型关键在于 ggml/src/ggml-cuda/mmq.cuh 中的mmq_type_traits类型特征模板。PR 493 为两个新类型补充了特化template int mmq_x, int mmq_y, int nwarps, bool need_check struct mmq_type_traitsmmq_x, mmq_y, nwarps, need_check, GGML_TYPE_IQ4_KS_R4 { static constexpr load_tiles_mmq_t load_tiles load_tiles_iq4_ks_r4mmq_y, nwarps, need_check; static constexpr vec_dot_mmq_t vec_dot_mma vec_dot_q8_0_q8_1_mmammq_x, mmq_y, nwarps, MMQ_Q8_1_DS_LAYOUT_D4; static constexpr vec_dot_mmq_t vec_dot_dp4a vec_dot_q8_0_q8_1_dp4ammq_x, mmq_y, nwarps; };IQ5_KS_R4的结构与之完全相同仅load_tiles换成load_tiles_iq5_ks_r4。这条特化表达了三层信息load_tilesload_tiles_iq4_ks_r4...负责把分块的量化权重从全局内存搬运到共享内存 tile并完成反量化预处理vec_dot_mma在有 int8 MMA张量核心能力的架构上使用vec_dot_q8_0_q8_1_mma按MMQ_Q8_1_DS_LAYOUT_D4的block_q8_1数据布局计算vec_dot_dp4a在无张量核心或禁用 MMA时回退到 dp4a 整数点积路径。数据布局选择mmq_get_q8_1_ds_layout决定 y激活侧block_q8_1_mmq的 scale/partial-sum 排布。在 mmq.cuh 的 switch 中GGML_TYPE_IQ4_KS_R4与GGML_TYPE_IQ5_KS_R4均被映射到MMQ_Q8_1_DS_LAYOUT_D4每 32 个值 1 个 32 位 scale无部分和与IQ4_KS、IQ5_KS等保持一致x 侧的 tile 尺寸则统一采用MMQ_DP4A_TXS_Q8_0dp4a 路径与MMQ_MMA_TILE_X_K_Q8_0MMA 路径。load_tiles 中的 _R4 解交织_R4布局的读取与标准IQ4_KS的关键差异在 ggml/src/ggml-cuda/mmq_id_common.cuh 的load_tiles_iq4_ks_r4中体现由于数据按 4 行交织存储线程先算出i4 i/4、ir i%4再以(const block_iq4_ks_r4 *)(dptr 4) kbx0定位块并从scales[4*kqsx ir]与qs的16*kqsx 4*j ir偏移处取数——即每个交织行只贡献 1/4 的数据4 个交织行拼成一个完整的量化块。这正是 PR 493 所称block-of-32 MMQ GEMM kernels得以成立的数据前提交织后每个线程束能连续加载 32 值粒度QK8_1 32的数据从而让 dp4a/MMA 路径的访存与累加更紧凑。实测性能RTX-4080 上的 LLama-3-8B sweep原文档给出了作者在 RTX-4080 上、用 LLama-3-8B 模型跑 sweep-bench 的完整数据PP2048 个 prompt token、TG512 个生成 token、N_KV 从 0 递增到 14336。sweep-bench 是仓库中的基准工具见 examples/sweep-bench/sweep-bench.cpp其输出表头PP / TG / N_KV / T_PP s / S_PP t/s / T_TG s / S_TG t/s分别对应 prompt 长度、生成长度、KV 缓存 token 数、prompt 处理耗时与吞吐、生成耗时与吞吐。IQ4_KS_R4prompt 处理吞吐显著提升分支S_PP t/sN_KV0S_PP t/sN_KV8192S_TG t/sN_KV0S_TG t/sN_KV14336MainGEMM/GEMV5910.025052.95126.3492.05PR 493MMQ7277.255263.35129.8692.14提升幅度23.1%4.2%2.8%0.1%解读PP 是主战场空 KV 缓存时 S_PP 从 5910 t/s 提升到 7277 t/s约 23%短上下文的 prompt 处理提速最明显随 KV 增长收益递减N_KV8192 时提升收窄到约 4%N_KV14336 时基本持平4212.60 → 4330.80约 2.8%——长上下文下预填充阶段逐步让位于注意力计算与 KV 读写GEMM 占比下降TG 变化很小生成阶段 S_TG 基本持平最大约 2.8%长上下文时几乎无差这与 MMQ 主要优化大 K 维 GEMM 的特征一致与生成阶段访存受限的现状相符。IQ5_KS_R4同样以 PP 增益为主分支S_PP t/sN_KV0S_PP t/sN_KV8192S_TG t/sN_KV0S_TG t/sN_KV14336MainGEMM/GEMV6052.155041.40109.5581.41PR 493MMQ7118.135193.25109.6681.30提升幅度17.6%3.0%0.1%-0.1%IQ5_KS_R4 的趋势与 IQ4_KS_R4 完全一致空缓存下 PP 提升约 17.6%随着 N_KV 增大提升收窄TG 基本不变。两个量化档位在长上下文下的 TG 数值约 81-92 t/s与 PP 趋势相互印证说明 PR 493 的收益集中且确定地落在 prompt 处理路径上。使用与验证要亲自复现上述数据需要具备 CUDA 能力的构建环境并确保这两个类型被启用。结合仓库现状可归纳如下构建IQ4_KS_R4/IQ5_KS_R4的 MMQ 实例代码在 ggml/src/ggml-cuda/template-instances/ 下随 CUDA 后端一并编译如需强制走 MMQ 而非 cuBLAS可参考 mmq.cuh 中关于GGML_CUDA_FORCE_MMQ与 Volta 上限MMQ_DP4A_MAX_BATCH_SIZE的注释默认情况下主机端会按架构自动选择 MMQ 或 cuBLASVolta 上批次上限 64Ampere 及以后可达 128。量化模型GGML_FTYPE_MOSTLY_IQ4_KS_R4337与GGML_FTYPE_MOSTLY_IQ5_KS_R4341是这两个类型在 GGUF 中的落盘形式见 ggml/include/ggml.h可使用 examples/quantize/quantize.cpp 将模型量化到对应档位。基准复现使用 examples/sweep-bench/sweep-bench.cpp 的 sweep 模式设定 PP2048、TG512 并遍历 N_KV即可产出与原文档同格式的表格对比 main 分支与本 PR 数据时需保证模型、GPU 与驱动环境一致避免引入无关变量。总结PR 493 是 ik_llama.cpp 对IQ4_KS_R4/IQ5_KS_R4CUDA 支持的一次精准补强在已有 GEMM反量化 cuBLAS与 GEMV 基础上利用 _R4 行交织布局天然适配 block-of-32 的便利为其补齐 MMQ GEMM/GEMM-id 内核。从 RTX-4080 的 sweep-bench 数据看收益集中体现在 prompt 处理阶段空 KV 下 S_PP 提升约 17%~23%而生成阶段基本持平随着 KV 缓存增长PP 收益逐步收窄。这一结果也解释了 ik_llama.cpp 在 i-quant 内核上的整体策略——对每个量化类型按 CPU 后端、CUDA GEMV、CUDA GEMM/MMQ、MoE 路径逐项补齐让实验性量化格式在真实推理链路中真正可用、可用得高效。【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询