
ik_llama.cpp 行交错量化解析IQ3_S_R4 如何把 sub-4bpw i-quants 的 CPU 性能提升近一倍【免费下载链接】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 #162IQ3_S_R4为切入点讲解该项目为解决 sub-4 bpwbits-per-weighti-quants 量化类型在 CPU 上矩阵乘性能低下而引入的行交错row-interleaved重打包思路在不改变权重位宽的前提下通过把IQ3_S的权重按 4 行交错重新布局换取向量化与缓存友好度的大幅提升。读完本文你将理解 R4 系量化类型的来历、它在 ggml.h 与 llama-quantize.cpp 中的落地方式、-rtr/--run-time-repack运行时重打包参数的正确用法与限制以及 PR 162 给出的三平台实测性能数据。一、背景为什么 sub-4 bpw 的 i-quants 在 CPU 上跑不动在 ik_llama.cpp 的量化体系中IQ3_S属于i-quantsimproved quants家族名义位宽 3.44 bpw见 quantize.cpp 中的类型描述它比传统 k-quants 更依赖码本codebook查表与非线性编码来压缩权重。PR #162 的出发点非常直白Sub-4 bpw i-quants have a terrible CPU performance低于 4 bpw 的 i-quants 在 CPU 上性能很差。原因从实现结构上可以推断极低位宽意味着每个 block 中打包了大量细粒度比特信息解包时指令密度高、内存访问模式碎片化导致 SIMD 向量化效率低、缓存利用率差。这在 prompt processingPP即预填充阶段的大矩阵乘法 GEMM中体现得尤为明显因为 PP 是典型的计算密集型负载SIMD 吞吐直接决定吞吐量。作者因此产生了一个直觉如果对权重行做交错interleaving rows重排是否能把性能救回来于是就有了 PR #162 的核心产物——IQ3_S_R4。二、什么是 R4对 IQ3_S 的 4 行交错重打包IQ3_S_R4不是一种新的压缩算法而是IQ3_S权重的 4 行交错4-row interleaved重打包版本。这一点在仓库中有三处相互印证的证据类型定义在 ggml.h 中GGML_TYPE_IQ3_S_R4 221与GGML_TYPE_IQ1_S_R4 219等并列属于独立的张量类型枚举对应文件类型GGML_FTYPE_MOSTLY_IQ3_S_R4 220见 ggml.h。重打包映射表在 llama-quantize.cpp 的interleaved_properties()中有一个全局映射表记录每个交错类型对应的基础类型与交错行数{ GGML_TYPE_IQ3_S_R4, { GGML_TYPE_IQ3_S, 4} }, // 基础类型 IQ3_S4 行交错 { GGML_TYPE_IQ1_S_R4, { GGML_TYPE_IQ1_S, 4} }, { GGML_TYPE_IQ2_K_R4, { GGML_TYPE_IQ2_K, 4} }, { GGML_TYPE_IQ4_KS_R4, { GGML_TYPE_IQ4_KS, 4} }, ...量化工具声明在 quantize.cpp 中IQ3_S_R4被直接描述为IQ3_S repacked位宽仍保持 3.44 bpw——即存储成本不变只是数据布局改变。其原理可以概括为把多个相邻行的量化数据按行交错方式重新排列使得 GEMM 内核在加载权重块时能一次取到更多连续有效数据、更好地利用 SIMD 寄存器与缓存行。类似的 R4 族还包括IQ4_KS_R4、IQ2_K_R4、IQ3_K_R4、IQ4_K_R4、IQ5_K_R4等详见 README.md 的量化列表而 PR #162 是这一思路在 sub-4 bpw i-quants 上的首次验证。三、实测性能PP-512 与 TG-128 三平台数据PR #162 原文PR #162 给出了在 LLaMA-3.1-8B 上、三大 CPU 平台的完整基准数据。以下数据直接继承自该 PR 的 Description单位均为 tokens/s数值格式为均值 ± 标准差。3.1 Prompt ProcessingPP-512核心收益场景平台线程数IQ3_SIQ3_S_R4加速比ARM_NEONM2-Max842.97 ± 1.2880.61 ± 0.411.876Zen4Ryzen-7950X16104.66 ± 0.68159.08 ± 0.571.520AVX2Ryzen-5975WX32132.50 ± 0.37231.41 ± 0.451.746PP 阶段收益显著ARM_NEON 接近 1.9 倍AVX2 约 1.75 倍即使本身吞吐已很高的 Zen4 也有 1.52 倍。这与前面分析的GEMM 对数据布局敏感的推断一致——交错布局直接提升了矩阵乘的向量化效率。3.2 Token GenerationTG-128多线程扩展下的收益TG自回归解码阶段是 GEMV矩阵-向量乘负载瓶颈更偏向访存带宽因此收益普遍小于 PP但依然可观尤其 AVX2平台线程数IQ3_SIQ3_S_R4加速比ARM_NEON23.00 ± 0.003.40 ± 0.001.133ARM_NEON45.74 ± 0.026.60 ± 0.011.150ARM_NEON89.25 ± 0.8312.27 ± 0.331.326Zen424.17 ± 0.004.38 ± 0.011.050Zen447.82 ± 0.058.14 ± 0.011.041Zen4814.29 ± 0.0214.41 ± 0.021.008AVX221.98 ± 0.003.31 ± 0.001.672AVX243.87 ± 0.006.49 ± 0.001.677AVX287.13 ± 0.0111.63 ± 0.021.631AVX21612.97 ± 0.0015.81 ± 0.001.219规律清晰AVX2 平台受益最大TG 加速 1.2~1.7 倍ARM_NEON 次之Zen4 在 TG 阶段几乎无增益约 1.0 倍这是因为 Zen4 的 AVX-512 原生吞吐已足够高GEMV 的访存瓶颈盖过了布局优化收益。这也提醒使用者R4 收益与平台、负载类型强相关PP 是它的主战场。四、仓库落地从类型定义到运行时重打包IQ3_S_R4在仓库中并非孤立实验而是完整的工程链路4.1 张量类型与文件类型张量类型GGML_TYPE_IQ3_S_R4与文件类型GGML_FTYPE_MOSTLY_IQ3_S_R4定义于 ggml.h。GEMM 内核在 iqk_gemm_iquants.cpp 与 iqk_gemm_iquants.cpp 中为该类型提供专门的矩阵乘分支相关量化/解包逻辑分布在 ggml-quants.c 及 iqk 目录 中。模型加载时llama-model-loader.cpp 与 llama-model.cpp 均注册了该类型的处理路径。4.2 两种使用方式方式一直接量化/重打包。使用llama-quantize工具把模型输出为IQ3_S_R4类型或对已有 IQ3_S 模型做纯重打包# 直接从 f16 模型量化为 IQ3_S_R43.44 bpw llama-quantize /models/model-f16.gguf /models/model-iq3-s-r4.gguf IQ3_S_R4 # 或先量化为 IQ3_S再重打包 llama-quantize /models/model-f16.gguf /models/model-iq3-s.gguf IQ3_S llama-quantize /models/model-iq3-s.gguf /models/model-iq3-s-r4.gguf IQ3_S_R4llama-quantize的完整类型清单见 quantize.cpp其中IQ3_S_R4描述为IQ3_S repacked。方式二运行时重打包-rtr。无需重新生成模型文件在推理时通过-rtr, --run-time-repack参数让加载器把支持的量化类型自动重打包为行交错格式见 parameters.mdllama-cli -m /models/model.gguf -rtr注意-rtr是 ik_llama.cpp独有参数见 parameters.md 中 Unique parameters 一节并非 llama.cpp 上游能力。4.3 重要限制混合 CPU/GPU 推理时慎用-rtrREADME.md 给出了明确警告如果 MoE 模型采用混合 CPU/GPU 推理且部分专家留在 CPU 上不要使用-rtr除非你清楚自己在做什么。原因有二-rtr会把留在 RAM 中的所有张量在加载时重打包为行交错格式并非所有量化类型都有行交错的 CUDA 实现典型如Q2_K、Q3_K、Q4_K、Q5_K、Q6_K等 k-quants 缺少 CUDA 行交错内核。一旦张量被重打包而 GPU 侧没有对应内核这些张量的矩阵乘将永远只能在 CPU 上执行——即使原本可以更优地卸载到 GPU最终反而导致 prompt processing 变慢。换句话说-rtr适合纯 CPU 推理或张量确实驻留 CPU 的场景在异构卸载场景下必须谨慎评估。五、后续演进R4 思路与超快 CPU PP的汇合PR #162 于 2024-12-23 提交后被关闭State: Closed但行交错思路在 ik_llama.cpp 中持续生长README 中记录了后续大量同族实现例如IQ4_KS_R4PR 150、IQ2_K_R4PR 146、IQ3_K_R4PR 145、IQ4_K_R4PR 138、IQ4_KSSPR 89等CUDA 端也陆续补齐了IQ1_S_R4PR 492、IQ1_M_R4PR 494、IQ4_KS_R4 / IQ5_KS_R4PR 493等内核。更重要的是PR #515 / #531 提出了对所有非交错量化类型大幅加速 CPU prompt processing的新方案并经由后续多个 PR 推广到全部量化类型与三个受支持的 CPU 平台Zen4 / AVX2 / NEON见 README.md。从代码结构看可以推断R4 系交错布局与非交错类型本身提速两条路线在仓库中是并行演进的——前者通过布局换取收益后者则直接优化解包与向量化路径两者最终都指向同一个目标让低比特量化在 CPU 上真正可用。六、小结何时选择 IQ3_S_R4结合 PR #162 的实测数据与仓库实现可给出如下实用判断优先使用场景纯 CPU 推理、以 prompt processing 为主的工作负载长上下文预填充、批量推理此时IQ3_S_R4相比IQ3_S可获 1.5~1.9 倍 PP 加速而位宽不变仍为 3.44 bpw是零精度代价换性能的布局优化收益有限场景Zen4 平台的 TG 阶段收益接近 1.0 倍若你的负载以长流式生成为主收益将不明显慎用场景混合 CPU/GPU 卸载推理——除非确认相关张量没有 GPU 行交错内核的兼容性问题否则避免-rtr自动重打包工程入口类型定义见 ggml.h重打包映射见 llama-quantize.cpp量化命令见 quantize.cpp运行时参数见 parameters.md。一句话总结IQ3_S_R4 证明了不改精度、只改布局也能在 CPU 上释放近一倍的算力它是理解 ik_llama.cpp 整个 R4 量化家族与-rtr运行时重打包机制的绝佳起点。【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考