人工智能大模型推理引擎本地部署模型量化模型优化【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp点击查看免费下载IQ2_XXS 是一种块大小为 256、单值仅 2 比特的极低比特量化格式压缩比极高但在 ik_llama.cpp 的 CPU 推理中一度存在明显的性能短板。本文以仓库内 PR #154IQ2_XXS_R4 为核心讲解该 PR 提出的 4 行行交织4-row interleaved变体IQ2_XXS_R4的设计动机、内存布局与实现位置并结合 PR 中在 Zen4、AVX2、ARM_NEON 三个平台上的实测数据分析行交织对 Prompt ProcessingPP与 Token GenerationTG的加速效果及其瓶颈。读完本文你将理解「为什么亚 2-bit 量化在 CPU 上慢、行交织为什么能提速、以及它依然存在哪些局限」并能在当前仓库中定位到完整的类型注册、量化、反量化与矩阵乘实现。背景为什么 sub-4 bpw 的 i-quants 在 CPU 上性能很差量化模型的 CPU 推理性能很大程度上取决于权重解包unpack与点积计算能否高效利用 SIMD 指令。主流的 k-quants 与 legacy quants如 Q4_0、Q4_K在设计时就考虑了 CPU 向量化而 ik_llama.cpp 的一系列 i-quants如IQ1_S、IQ1_M、IQ2_XXS、IQ2_XS追求极致压缩权重比特数低至 1~2 bit数据排布非常紧凑、且依赖查找表LUT解码。PR #154 的作者 ikawrakow 在描述中直言其动机Sub-4 bpw i-quants have a terrible CPU performance, so I was curious to see if we can improve by interleaving rows.也就是说低于 4 bits-per-weight 的 i-quants 在 CPU 上的性能很差作者因此尝试通过「行交织」来改善。PR 的目标不是改变量化精度而是改变量化数据在内存中的排布方式让 CPU 在取数据时更高效。IQ2_XXS_R44 行交织的 IQ2_XXSIQ2_XXS 基础格式在深入了解IQ2_XXS_R4之前先回顾其基础格式IQ2_XXS。从 gguf-py/gguf/constants.py 可以看到该类型的元数据GGMLQuantizationType.IQ2_XXS 16其块尺寸/字节数为(256, 66)每 256 个值组成一个块仅占 66 字节即平均每值约 2.0625 bit类型名称为iq2_xxs由ggml.c中的类型表注册见下节。由于每个值只有约 2 bitIQ2_XXS的反量化严重依赖查表解码这使其在 CPU 上难以高效喂给int8点积指令。行交织R4的含义IQ2_XXS_R4是IQ2_XXS的4 行交织版本将 4 个连续行的数据重新打包使它们在内存中交错排布。这样矩阵乘法GEMM在遍历权重时能够一次加载 4 行的数据提高缓存利用与访存带宽的饱和程度。在 src/llama-quantize.cpp 中可以找到两者的映射关系{ GGML_TYPE_IQ2_XXS_R4, { GGML_TYPE_IQ2_XXS, 4} },它表明IQ2_XXS_R4是由IQ2_XXS按 4 行打包repack得到的变体行的数量因子为 4。这也是R4后缀的含义所在。类型注册与 GGUF 文件格式当前仓库中IQ2_XXS_R4已作为正式类型注册。在 ggml/include/ggml.h 中GGML_TYPE_IQ2_XXS 16, GGML_TYPE_IQ2_XXS_R4 216, ... GGML_FTYPE_MOSTLY_IQ2_XXS_R4 215, // except 1d tensors在 ggml/src/ggml.c 的类型表中IQ2_XXS_R4被描述为[GGML_TYPE_IQ2_XXS_R4] { .type_name iq2_xxs_r4, .blck_size QK_K, .type_size sizeof(block_iq2_xxs), .is_quantized true, .to_float (ggml_to_float_t) dequantize_row_iq2_xxs_r4, .from_float quantize_row_iq2_xxs_r4, .from_float_ref (ggml_from_float_t)quantize_row_iq2_xxs_r4_ref, .vec_dot vec_dot_iq2_xxs_r4_q8_k, .vec_dot_type GGML_TYPE_Q8_K, ... },注意两点实现事实.type_size与block_iq2_xxs相同——IQ2_XXS_R4不增加任何存储开销压缩率与IQ2_XXS完全一致改变的只是排布.vec_dot_type为Q8_K即点积仍以Q8_K作为激活侧量化类型参与计算。GGUF 侧同样同步支持在 gguf-py/gguf/constants.py 中定义IQ2_XXS_R4 216、MOSTLY_IQ2_XXS_R4 219块尺寸同为(256, 66)因此该格式可以直接写入 GGUF 文件并被解析器识别。源码实现量化、重打包与点积量化与参考实现在 ggml/src/ggml-quants.c 中约 7662 行起注释// iq2_xxs_r4实现了该类型的关键函数void quantize_row_iq2_xxs_r4_ref(const float * x, block_iq2_xxs_r4 * y, int64_t k) { quantize_iq2_xxs_r4(x, (void *)y, 4, k/4, nullptr, nullptr); } void quantize_row_iq2_xxs_r4(const float * x, void * y, int64_t k) { quantize_iq2_xxs_r4(x, y, 4, k/4, nullptr, nullptr); } size_t quantize_iq2_xxs_r4(const float * src, void * dst, int64_t nrows, int64_t n_per_row, const float * imatrix, ...) { return quantize_repack32, block_iq2_xxs, block_iq2_xxs_r4, 4(GGML_TYPE_IQ2_XXS, src, dst, nrows, n_per_row, imatrix, user_data, ...); }这里可以看到quantize_iq2_xxs_r4通过模板函数quantize_repack32, block_iq2_xxs, block_iq2_xxs_r4, 4完成「先按IQ2_XXS量化、再以 4 行为单位重打包」的完整流程。重打包函数为static void repack_iq2_xxs(int nrows, int n_per_row, const block_iq2_xxs * x, block_iq2_xxs_r4 * y, bool online) { ... }该函数把若干行block_iq2_xxs交错重排为block_iq2_xxs_r4是行交织的核心。反量化入口dequantize_row_iq2_xxs_r4同样位于该文件。GEMM 侧的分派在 ggml/src/iqk/iqk_mul_mat.cpp 中IQ2_XXS_R4进入了 iqk 矩阵乘的分派逻辑。一个值得关注的分支是is_dequant_bettercase GGML_TYPE_IQ2_XXS: return nrc_y 32 ? q8_k_type : type; case GGML_TYPE_IQ2_XXS_R4: return nrc_y 32 ? q8_k_type : type;其中q8_k_type在启用HAVE_FANCY_SIMD时为Q8_K_R16否则为Q8_K_R8。含义是当右矩阵行数nrc_y足够大≥32时GEMM 会先把IQ2_XXS_R4解包到行交织的 8-bit 类型Q8_K_R8/Q8_K_R16再用更高效的 8-bit 点积完成计算行数较小时则直接走原生点积路径。这说明行交织不仅提升了数据局部性也为后续「解包到 8-bit 再 GEMM」的优化路线铺平了道路。CUDA 与模型加载的配套支持除 CPU 外IQ2_XXS_R4也出现在 ggml/src/ggml-cuda.cu 与 src/llama-model.cpp、src/llama-model-loader.cpp 中用于 CUDA 端类型识别与模型张量的格式校验examples/quantize/quantize.cpp 中的命令行量化工具也支持将该类型作为量化目标llama-quantize --type可指定IQ2_XXS_R4。实测数据PP 与 TG 的加速效果PR #154 在三个平台上对 LLaMA-3.1-8B 进行了对比测试Zen4Ryzen-7950X、ARM_NEONApple M2-Max、AVX2Ryzen-5975WX。以下数据均来自 PR 描述单位分别为 tokens/sPP与 tokens/sTG。Prompt ProcessingPP-512平台线程数IQ2_XXSIQ2_XXS_R4加速比ARM_NEON856.40 ± 0.9976.34 ± 0.581.354Zen416134.68 ± 0.31153.60 ± 0.231.140AVX232155.48 ± 0.17195.72 ± 0.201.259行交织在 PP 阶段带来约 14%~35% 的提升其中 ARM_NEON 平台收益最大1.354×。Token GenerationTG-128平台线程数IQ2_XXSIQ2_XXS_R4加速比ARM_NEON24.40 ± 0.036.65 ± 0.001.51148.61 ± 0.0112.20 ± 0.021.417815.84 ± 0.3421.76 ± 0.311.374Zen426.59 ± 0.008.66 ± 0.001.314411.62 ± 0.8115.49 ± 0.361.333820.40 ± 0.7023.37 ± 0.031.146AVX222.62 ± 0.005.54 ± 0.002.11545.17 ± 0.0010.81 ± 0.002.09189.49 ± 0.0218.93 ± 0.081.9951616.97 ± 0.0025.70 ± 0.011.514TG 阶段的收益更为显著尤其 AVX2 平台在低线程数下接近翻倍2 线程时 2.115×4 线程时 2.091×。这也符合行交织提升内存带宽利用率的预期——TG 是典型的访存密集型任务权重行数多、单次计算量小。瓶颈分析内存带宽是否饱和PR 描述中给出了一个关键的带宽观察We now manage to saturate the available memory bandwidth on the Ryzen CPUs at 8 (Ryzen-7950X) or 16 (Ryzen-5975WX) threads, but are far from being memory bound on the M2-Max.即行交织之后两款 Ryzen CPU 在各自合理的线程数下7950X 为 8 线程、5975WX 为 16 线程已经能够跑满可用的内存带宽而 Apple M2-Max 距离内存带宽瓶颈还差得很远说明其瓶颈仍主要在解码/计算侧而非访存侧。这个结论解释了为什么不同平台、不同线程数下加速比差异巨大——收益取决于该平台原本的瓶颈位置。已知局限符号与尺度的混洗复杂度PR 同时也坦诚地记录了它的局限。虽然获得了可观的加速但作者指出We get decent performance gains, but still remain much slower than k- or legacy quants. I think there is still potential for optimization, but I was getting constantly confused about shuffling signs and scales, so at the end gave up with this result.两点事实需要明确绝对性能仍落后即便有 1.1~2.1× 的提升IQ2_XXS_R4依然明显慢于 k-quants 或 legacy quants优化空间未耗尽作者认为仍有优化潜力但由于在「符号与尺度的混洗shuffling signs and scales」上反复出错最终以当前结果收尾PR 状态为 Closed。这说明行交织方向本身是有效的但其实现复杂度较高尤其涉及负值符号位与块尺度在交织后如何正确重排的问题。后续演进PR #515 的更高阶思路IQ2_XXS_R4的思路在后续 PR 中得到了进一步深化。PR #515IQ2_XXS: much faster CPU prompt processing 借鉴了 trellis 量化实验PR #505/#511中「先解包若干行到Q8_0_R8再用Q8_0_R8 × Q8_2_X4GEMM 与右矩阵全部列相乘」的做法将其应用于IQ2_XXS仅 AVX2/Zen4We get nearly 3X improvement in PP performance compared toIQ2_XXSon the main branch, and 2X compared toIQ2_XXS_R4!即 PP 性能相对主线IQ2_XXS提升近 3 倍、相对IQ2_XXS_R4再提升 2 倍。PR 还指出同样的方法可直接用于IQ3_XXS而IQ2_XS、IQ2_S、IQ3_S因为使用 16 大小的块需要新的块大小为 16 的行交织 8-bit 类型才能适配。这与 ggml/src/iqk/iqk_mul_mat.cpp 中Q8_K_R8/Q8_K_R16的分派逻辑相互印证——行交织 8-bit 解包重 GEMM 已成为 i-quants 提速的核心路线。如何在本仓库中使用与验证量化模型使用 examples/quantize/quantize.cpp 编译出的llama-quantize以--type指定IQ2_XXS_R4对应LLAMA_FTYPE_MOSTLY_IQ2_XXS_R4见 src/llama-quantize.cpp 的默认类型映射。该格式无需额外存储块尺寸与IQ2_XXS相同推理验证用llama-server或llama-cliexamples/main/main.cpp加载量化后的 GGUF 模型对比相同硬件上IQ2_XXS与IQ2_XXS_R4的 PP/TG 吞吐性能基准可参考 examples/llama-bench/llama-bench.cpp 进行规范化测速注意记录线程数——从上述数据可知行交织收益与线程数强相关查看实现细节量化/重打包/反量化在 ggml/src/ggml-quants.c类型注册在 ggml/src/ggml.cGEMM 分派在 ggml/src/iqk/iqk_mul_mat.cppGGUF 常量在 gguf-py/gguf/constants.py。小结IQ2_XXS_R4是 ik_llama.cpp 针对亚 2-bit i-quants CPU 性能短板的一次成功尝试通过 4 行交织重排数据在不增加任何存储开销的前提下使 PP 提升约 14%~35%、TG 在 AVX2 低线程下接近翻倍并让 Ryzen 平台在合理线程数下达到内存带宽饱和。它同时揭示了该技术路线的边界——绝对速度仍不及 k-quants且符号/尺度混洗的实现复杂度较高。而后续 PR #515 在此基础上引入「解包到行交织 8-bit 再 GEMM」的组合拳将同一思路推向了近 3 倍的 PP 提升构成了 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 的 IQ2_XS_R44 行交错量化如何改善 sub-4 bpw 的 CPU 推理性能深入解析 ik_llama.cpp 的 IQ2_XS_R44 行交错量化如何改善 sub 4 bpw 的 CPU 推理性能 导读 本文以 ik_llama.c人工智能大模型推理引擎本地部署模型量化模型优化ik_llama.cpp 的 IQ2_BN_R44 行交织打包如何将 Bitnet 2-bit 模型在 CPU 上的推理速度推上 834 t/sik_llama.cpp 的 IQ2_BN_R44 行交织打包如何将 Bitnet 2 bit 模型在 CPU 上的推理速度推上 834 t/s 本篇技术指南人工智能大模型推理引擎本地部署模型量化模型优化ik_llama.cpp 新增 IQ3_K_R4基于 4 行交织重打包的 3-bit 量化及其 CPU/GPU 加速原理ik_llama.cpp 新增 IQ3_K_R4基于 4 行交织重打包的 3 bit 量化及其 CPU/GPU 加速原理 导读 本文围绕 ik_llama.c人工智能大模型推理引擎本地部署模型量化模型优化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考