拓冰建站拓冰建站
首页 / 资讯中心 / 正文

ik_llama.cpp Q2_K_R4 量化:四行交错(R4)布局如何让 2-bit 模型在 ARM_NEON / AVX2 / Zen4 上全面提速

ik_llama.cpp Q2_K_R4 量化四行交错R4布局如何让 2-bit 模型在 ARM_NEON / AVX2 / Zen4 上全面提速【免费下载链接】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 #136Q2_K_R4为线索系统讲解 R44 行交错量化布局的来龙去脉它是什么、如何用llama-quantize把模型转成Q2_K_R4、在三大 CPU 平台上实测能带来多少 PP/TG 提速以及该实现在仓库源码中的落点ggml/include/ggml.h的类型定义、ggml/src/iqk/与ggml/src/ggml-cuda/的计算内核。读完本文你将掌握 R4 家族量化的类型体系、转换命令、性能特征与适用边界并能在自己的 CPU/GPU 环境中复现和验证这些结论。背景从 k-quants 到 R4 交错布局k-quants 是 GGUF 生态中最常用的低比特量化家族Q2_K、Q3_K、Q4_K、Q5_K、Q6_K以及IQ2_K、IQ3_K、IQ4_K、IQ5_K等扩展。它们的量化块通常以单个 256 元素 block 为单位组织权重在内存中按行顺序连续存放。这种布局在矩阵-向量乘法GEMVtoken 生成 TG 阶段中访问友好但在矩阵-矩阵乘法GEMMprompt 处理 PP 阶段中多线程并行计算时会因为访存模式不够紧凑而无法充分发挥 CPU 的向量化能力。ik_llama.cpp 的解法是R4row-interleaved4 行交错布局在量化块内部把 4 行权重的数据交错排布使单次向量加载就能覆盖多行数据从而大幅提升 GEMM 内核的缓存命中率与寄存器利用率。这一思想最先应用于IQ4_KPR #138、IQ5_KPR #149、IQ3_KPR #145、IQ2_KPR #146等新 iqk 量化随后在PR #136 中补全了传统 k-quants 中最后一块拼图Q2_K标志着 R4 实现覆盖了ARM_NEON、AVX2、Zen4三大 CPU 平台上的全部 k-quants。PR #136 核心结论Q2_K_R4 的实测提速PR #136作者ikawrakow创建于 2024-12-11是此前 #118#134 一系列 R4 后续工作的收尾目标是为Q2_K提供 4 行交错实现。原 PR 在 LLaMA-3.1-8B 模型上分别测量了 PP-512512 token prompt 处理与 TG-128128 token 生成两项指标测试平台为Zen4Ryzen-7950XARM_NEONApple M2-MaxAVX2Ryzen-5975WXPP-512prompt 处理吞吐平台线程数Q2_K_S (t/s)Q2_K_R4 (t/s)加速比ARM_NEON873.79 ± 1.92109.07 ± 0.581.478Zen416205.95 ± 0.77256.19 ± 0.261.244AVX232214.42 ± 0.54286.91 ± 0.631.338可以看到PP 阶段三平台均获得 24%48% 的提升其中 ARM_NEON 受益最大约 1.48×。TG-128token 生成速度由于Q2_K是 k-quants 中体积最小的类型TG 阶段在内存带宽饱和前 CPU 仍有余力做更多计算因此 R4 布局在 TG 上也有可观收益平台线程数Q2_K_S (t/s)Q2_K_R4 (t/s)加速比ARM_NEON210.34 ± 0.0112.81 ± 0.011.239419.32 ± 0.0223.40 ± 0.081.211832.36 ± 0.5936.02 ± 0.401.113Zen416.60 ± 0.029.08 ± 0.121.376212.12 ± 0.0116.40 ± 0.001.353419.12 ± 0.5620.72 ± 0.191.084AVX225.93 ± 0.0210.16 ± 0.301.713411.24 ± 0.0017.59 ± 0.011.565818.62 ± 0.0321.44 ± 0.001.151TG 阶段 AVX2 平台低线程数时提速高达 1.71×2 线程Zen4 单线程也有 1.376×。总体上线程数越少、R4 相对收益越大因为交错布局显著降低了单线程 GEMV 的访存开销。作者在 PR 中也坦承Q2_K本身是质量较低的 2-bit 量化方案但它的 R4 性能极佳——It is actually too bad Q2_K is such a low quality quantization as performance is really good。这暗示了后续改进 2 bpw 量化质量的方向事实上仓库后续出现了IQ2_K_R4、IQ1_S_R4、IQ1_M_R4等更高效率的低比特方案。R4 家族类型体系与源码落点ggml 类型定义在 ggml/include/ggml.h 中R4 类型以独立的GGML_TYPE_*_R4枚举出现例如GGML_TYPE_Q2_K_R4 210, // k-quants 的 R4 版本 GGML_TYPE_IQ2_K_R4 337, GGML_TYPE_IQ3_K_R4 338, GGML_TYPE_IQ4_K_R4 339, GGML_TYPE_IQ5_K_R4 340,同时 ggml/include/ggml.h 定义了对应的 GGUF 文件类型常量GGML_FTYPE_MOSTLY_Q2_K_R4210与GGML_FTYPE_MOSTLY_IQ2_K_R4330等。换言之R4 不是运行时临时转换而是一种可持久化存储的正式量化类型可以直接写进 GGUF 模型文件。从普通量化到 R4 的转换映射在 src/llama-quantize.cpp 中可以看到明确的基类型 交错行数映射表R4 即行交错数 4{ GGML_TYPE_Q2_K_R4, { GGML_TYPE_Q2_K, 4} }, { GGML_TYPE_Q3_K_R4, { GGML_TYPE_Q3_K, 4} }, { GGML_TYPE_Q4_K_R4, { GGML_TYPE_Q4_K, 4} }, { GGML_TYPE_Q5_K_R4, { GGML_TYPE_Q5_K, 4} }, { GGML_TYPE_Q6_K_R4, { GGML_TYPE_Q6_K, 4} }, { GGML_TYPE_IQ2_K_R4, { GGML_TYPE_IQ2_K, 4} }, { GGML_TYPE_IQ3_K_R4, { GGML_TYPE_IQ3_K, 4} }, { GGML_TYPE_IQ4_K_R4, { GGML_TYPE_IQ4_K, 4} }, { GGML_TYPE_IQ5_K_R4, { GGML_TYPE_IQ5_K, 4} },llama-quantize内部会先按基类型如Q2_K计算量化数据再按交错参数4 行重排内存布局最终落盘为*_R4类型。CPU 内核实现R4 布局的计算内核集中在ggml/src/iqk/目录ggml/src/iqk/iqk_mul_mat.cpp 中的row_interleaved()函数统一返回各类型的交错行数Q2_K_R4、Q3_K_R4、Q6_K_R4、IQ2_K_R4、IQ3_K_R4、IQ4_K_R4、IQ5_K_R4等返回 4IQ4_NL_R4、Q5_0_R4、Q6_0_R4等返回 8参见该文件第 336-395 行附近。ggml/src/iqk/iqk_quantize.cpp 负责 R4 类型的量化/重排逻辑。ggml/src/iqk/iqk_gemm_kquants.cpp 与 ggml/src/iqk/iqk_gemm_iqk_quants.cpp 提供 GEMM/GEMV 的向量化内核。值得注意iQK 的iqk_mul_mat.cpp中把Q2_K_R4等传统 k-quants 的row_interleaved返回 4但部分注释掉的分支表明传统 k-quants 的 R4 内核与 iqk 类型在代码路径上存在区分从源码结构看传统 k-quants 的 R4 GEMM 由iqk_gemm_kquants.cpp承载而IQ*系列由iqk_gemm_iqk_quants.cpp承载。量化器命令支持在 examples/quantize/quantize.cpp 中Q2_K_R4、IQ2_K_R4等全部出现在可用的量化类型列表里意味着可以直接通过命令行指定./build/bin/llama-quantize --allow-requantize \ /path/to/model-f16.gguf \ /path/to/model-Q2_K_R4.gguf \ Q2_K_R4同样的类型也被 src/llama-quantize.cpp 的is_quantizable()判定接受说明它属于可再量化requantize的类型集合。进阶收益Zen4 整数累加器优化PR #139PR #136 的成果在随后的PR #139Faster R4 quants on Zen4中进一步放大在 superblock 内部的点积计算改用整数累加器。作者最初因 Intel 手册中_mm256_mullo_epi32()极高的延迟而放弃该方案但受 ARM_NEON 上整数点积累加显著提速PR #135的启发最终还是采用结果证明尽管整数乘法延迟高整体依然更快。以 Ryzen-7950X 为例PR #139 对 PP-512 的进一步收益量化线程任务PR #136 (t/s)PR #139 (t/s)加速比Q2_K_R416pp512256.19 ± 0.26272.69 ± 0.131.064Q3_K_R416pp512236.77 ± 0.35255.84 ± 0.201.081Q4_K_R416pp512262.40 ± 0.28268.09 ± 0.121.022IQ4_XS_R416pp512256.80 ± 0.35271.95 ± 0.391.059Q5_K_R416pp512248.30 ± 0.29256.68 ± 0.311.034Q6_K_R416pp512243.25 ± 0.31261.33 ± 0.381.074TG-128 方向Q2_K_R4单线程从 9.08 提升到 9.95 t/s1.096×2 线程从 16.40 提升到 17.44 t/s1.063×。而Q4_K_R4、Q5_K_R4、IQ4_XS_R4的矩阵-向量乘法走的是另一套实现该改动不适用因此 PR #139 未给出这三者的 TG 数据。CUDA 侧R4 的 GPU 实现R4 并非 CPU 专属。仓库 README.md 记录了完整的 CUDA 实现脉络IQ2_K_R4、IQ3_K_R4、IQ4_K_R4、IQ5_K_R4的 CUDA 支持来自 PR #461对应的内核模板实例位于 ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_k_r4.cu及 iq3/iq4/iq5 同系列文件MMVQ 侧则有 mmvq-instance-iq2_k_r4.cu 等。一个重要的实操注意点README.md 明确警告在 CPU/GPU 混合推理中如果部分专家层留在 CPU 上不要随意使用-rtr选项。-rtr会在模型加载时把所有留在 RAM 的张量重打包为行交错格式而并非所有量化类型都有 CUDA 实现——例如传统 k-quantsQ2_K、Q3_K、Q4_K、Q5_K、Q6_K就没有 CUDA 行交错内核这会导致相关矩阵乘法被强制留在 CPU 执行反而拖慢 prompt 处理速度。复现与验证指南1. 构建 ik_llama.cpp按 README.md 的流程构建以 Linux/macOS 为例git clone https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp cd ik_llama.cpp cmake -B build -DGGML_NATIVEON cmake --build build --config Release -j$(nproc)构建产物中会包含build/bin/llama-quantize、build/bin/llama-bench、build/bin/llama-server等工具。2. 生成 Q2_K_R4 模型先准备一个.gguf源模型F16 或任意可再量化类型然后./build/bin/llama-quantize \ /my_local_files/gguf/model-f16.gguf \ /my_local_files/gguf/model-Q2_K_R4.gguf \ Q2_K_R4转换完成后可用llama-quantize --help查看全部可用类型确认Q2_K_R4与IQ2_K_R4均在列表中GGUF 侧的对应常量定义可查 gguf-py/gguf/constants.py。3. 用 llama-bench 复现 PP/TG 对比PR 中的 PP-512 / TG-128 指标对应llama-bench的-p 512与-n 128参数。对比同一模型的Q2_K_S与Q2_K_R4两个文件./build/bin/llama-bench -m /path/to/model-Q2_K_S.gguf -p 512 -n 128 -t 8 ./build/bin/llama-bench -m /path/to/model-Q2_K_R4.gguf -p 512 -n 128 -t 8线程数-t可按平台调整PR 中 ARM_NEON 用 8/2/4/8、Zen4 用 16/1/2/4、AVX2 用 32/2/4/8即可得到与 PR #136 同构的对照表。注意实测加速比会随具体 CPU 微架构、内存带宽与线程数变化低线程数下 R4 收益通常更明显。4. 服务化运行转换后的Q2_K_R4模型可直接用llama-server加载./build/bin/llama-server --model /my_local_files/gguf/model-Q2_K_R4.gguf --ctx-size 4096CPU 纯推理可直接运行若机器有 NVIDIA GPU 且希望卸载部分层到 GPU可加-ngl 999但请先确认所用 R4 类型是否具备 CUDA 内核见上文 CUDA 小节并避免在 MoE 混合推理场景下盲目使用-rtr。总结与展望PR #136 为Q2_K补上了 R4 交错布局使 R4 实现完整覆盖ARM_NEON、AVX2、Zen4上的全部 k-quants实测 PP 阶段最高提速约 1.48×ARM_NEON、TG 阶段最高约 1.71×AVX2 低线程。随后的 PR #139 又通过 Zen4 整数累加器把 PP 进一步提升了 2%8%而 PR #146 之后IQ2_K_R4等更高效率低比特方案的加入也印证了作者在 PR #136 中以今日知识重做 2 bpw的判断——R4 布局已成为 ik_llama.cpp 低比特量化的通用性能底座并延伸到 CUDA 侧。延伸阅读仓库内R4 系列其他成员IQ4_K_R4github-data/pull_requests/138 - IQ4_K_R4.md、IQ2_K_R4github-data/pull_requests/146 - IQ2_K_R4.md、Zen4 加速github-data/pull_requests/139 - Faster R4 quants on Zen4.md量化类型体系ggml/include/ggml.h、src/llama-quantize.cpp、examples/quantize/quantize.cppCPU 内核ggml/src/iqk/iqk_mul_mat.cpp、ggml/src/iqk/iqk_gemm_kquants.cppCUDA 内核模板ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_k_r4.cuGGUF 常量gguf-py/gguf/constants.py【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门