尧图精选

ik_llama.cpp 的 Q6_K_R4 行交错量化:源码实现、性能提升与使用指南

🕒 发布时间:2026/9/19 14:56:12 📁 来源:尧图网络
ik_llama.cpp 的 Q6_K_R4 行交错量化源码实现、性能提升与使用指南【免费下载链接】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 #130「Q6_K_R4」系统解析一种新型行交错row-interleaved量化格式在保持Q6_K精度特征的前提下将相邻 4 行数据交错重排从而让 ARM_NEON、Zen4/AVX2 等 SIMD 后端的矩阵乘GEMM与向量点积GEMV实现获得大幅加速。你将了解到该格式在源码中的完整落地方式量化、重打包、类型注册、向量点积掌握如何在当前仓库中通过llama-quantize把模型转换为Q6_K_R4并理解 PR 中给出的 PP-512 与 TG-128 实测数据的真实含义与适用边界。一、背景为什么需要 Q6_K_R4Q6_K是 llama.cpp 体系中块大小为 256QK_K的 K 系量化类型长期被用于模型的核心张量。正如 PR #130 开篇所指出的If nothing elseQ6_Kis routinely used for the output tensor, so having a betterQ6_Kperformance would be useful.即即使其他张量不使用Q6_K模型的output tensor输出张量也通常会采用Q6_K来保证最终 logits 的精度因此提升Q6_K的计算性能对几乎所有量化模型都有实际收益。Q6_K_R4并不是一种新的比特率量化方案而是行交错row-interleaved内存布局优化把 4 行Q6_K块的数据按 SIMD 友好的方式交错排列使 CPU 后端尤其是 ARM_NEON、AVX2/Zen4的 GEMM/GEMV 内层循环能以更少的加载、更连续的内存访问完成计算。它属于 PR #118~#123、#129 这一系列 R44 行交错量化工作的延续——之前已覆盖Q4_0_R4、Q8_0_R4、Q5_0_R4、Q6_0_R4、IQ4_XS_R4、Q4_K_R4等PR #130 则是把同一思路应用到Q6_K上。二、源码中的实现细节2.1 类型注册与基础属性在 ggml/include/ggml.h 中GGML_TYPE_Q6_K_R4 214被注册为独立的量化类型对应的文件格式标记为GGML_FTYPE_MOSTLY_Q6_K_R4 214except 1d tensors即除一维张量外的所有张量均使用该格式。在 ggml/src/ggml.c 中该类型的核心属性如下属性值说明type_nameq6_k_r4GGUF 与命令行中使用的名称blck_sizeQK_K256块大小与原Q6_K一致type_sizesizeof(block_q6_K)单行块大小与原类型一致不额外占用空间is_quantizedtrue属于量化类型to_floatdequantize_row_q6_k_r4反量化入口from_floatquantize_row_q6_k_r4量化入口vec_dotvec_dot_q6_k_r4_q8_k向量点积与Q8_K激活配合vec_dot_typeGGML_TYPE_Q8_K激活向量按Q8_K量化nrows/row_meta_size1/0单行元数据值得强调的是type_size与原Q6_K完全相同——R4 重排不增加任何存储开销纯收益来自更优的访存与计算布局。2.2 量化与重打包实现量化入口quantize_q6_k_r4位于 ggml/src/iqk/iqk_quantize.cpp。其策略是先按标准Q6_K逐行量化再执行 4 行重打包auto q_func [] (const float * x, void * vy, int n_per_row, const float * imatrix, [[maybe_unused]] const quantize_user_data * user_data) { quantize_q6_K(x, (char *)vy, 1, n_per_row, imatrix, user_data); }; return quantize_repack16, block_q6_K, block_q6_k_r4, 4(GGML_TYPE_Q6_K, src, dst, nrows, n_per_row, imatrix, user_data, q_func, repack_q6_k);即通过模板quantize_repack16, block_q6_K, block_q6_k_r4, 4以 16 行为一组、4 行为一步进行重排。核心重排函数repack_q6_kiqk_quantize.cpp完成三件事断言约束nrows % 4 0且n_per_row % QK_K 0要求行数与每行块数都能被 4 整除元数据d/scale交错将 4 行中同一位置块的d全局缩放与scales子块缩放按交错索引写入目标块block_q6_k_r4形成y[ibl].d[k]、y[ibl].scales[8*ibk0/4]的布局量化值交错对每个 6-bit 量化值通过convert_q6_k拆分为 4-bit 低位ql与高位qh再将 4 行中同一位置的低位/高位按位打包进y[ibl].ql[64*ib4*ki...]与y[ibl].qh[32*ib4*ki...]。反量化dequantize_row_q6_k_r4则按n_per_row k/4切分 4 个输出行指针逐块还原。这种逐行量化 重排的路径有一个工程上的好处量化的数值结果与标准Q6_K完全一致只是布局不同因此在精度上没有任何妥协可以直接复用已有的Q6_K量化质量。2.3 向量点积与多后端适配vec_dot绑定为vec_dot_q6_k_r4_q8_k即 R4 权重与Q8_K激活的逐块点积。它在多个后端均有实现CPU 通用路径注册于 ggml/src/ggml.cIQK 优化路径在 ggml/src/iqk/iqk_mul_mat.cpp 的 GEMM/GEMV 调度中GGML_TYPE_Q6_K_R4被显式列入支持列表如第 338、376、890、988 行等处走iqk_mul_mat的快路径CUDA 路径在 ggml/src/ggml-cuda.cu 中GGML_TYPE_Q6_K_R4被映射为 4 路展开{ GGML_TYPE_Q6_K_R4, 4 }并在第 1216 行附近被纳入支持 MMQ/GEMV 的 R4 类型集合。也就是说Q6_K_R4从 CPUNEON/AVX2/Zen4到 CUDA 的推理链路是完整的这与 PR #127Q4_0_R4 on CUDA之后形成的R4 全平台支持路线一致。2.4 运行时重打包repack能力除静态量化外仓库还支持在运行时把标准张量重打包为 R4 布局。在 iqk_quantize.cpp 的重打包注册表中{ GGML_TYPE_Q6_K, { GGML_TYPE_Q6_K_R4, 4, (Repack::repack_func)repack_q6_k } },即运行时可把GGML_TYPE_Q6_K张量在线重打包为Q6_K_R44 行交错并可使用-ot/--override-tensor相关机制指定对哪些张量生效参见 PR #272、#274 的后续工作。这为下载标准Q6_K模型、加载时按需转 R4的工作流提供了支持而无需重新量化整个模型。三、性能表现PR #130 的实测数据PR #130 使用 LLaMA-3.1-8B 模型在三种 CPU 平台、两种场景下对比了Q6_K与Q6_K_R4。以下数据均引自 github-data/pull_requests/130 - Q6_K_R4.md测量单位均为 tokens/s。3.1 Prompt 处理PP-512512 token 的 prompt 批量处理平台线程数Q6_KQ6_K_R4加速比ARM_NEONM2-Max857.57 ± 0.6183.25 ± 0.811.446Zen4Ryzen-7950X16195.20 ± 0.74243.25 ± 0.311.246AVX2Ryzen-5975WX32194.51 ± 0.35264.16 ± 0.441.358可以看到 PP 场景下三个平台均有显著收益其中ARM_NEON 提升最大约 44.6%AVX2 约 35.8%Zen4 约 24.6%。3.2 Token 生成TG-128平台线程数Q6_KQ6_K_R4加速比ARM_NEON27.46 ± 0.037.35 ± 0.010.985ARM_NEON413.88 ± 0.0213.80 ± 0.010.994ARM_NEON818.31 ± 0.1618.57 ± 0.141.014Zen415.38 ± 0.007.94 ± 0.001.476Zen428.93 ± 0.0010.38 ± 0.001.162Zen449.97 ± 0.2710.18 ± 0.011.021AVX224.75 ± 0.005.78 ± 0.011.217AVX247.57 ± 0.008.47 ± 0.001.119AVX288.23 ± 0.009.14 ± 0.001.111TG 场景的结论需要细分Zen4 / AVX2 全面受益即使线程数较少也有 1.1~1.5 倍提升。PR 特别指出With this Zen4 implementation, for TG the available memory bandwidth is fully saturated with just 2 threads!——即 Zen4 实现只需2 个线程就能打满可用内存带宽这解释了为何单线程 TG 能获得 1.476 倍的最大加速比ARM_NEON 基本持平2~4 线程时略有回退0.985~0.9948 线程时略升1.014。PR 原文也明确说明了这一例外Except on ARM_NEON, where TG performance is slightly lower for small numbers of threads。四、如何生成与使用 Q6_K_R4 模型4.1 使用 llama-quantize 转换在examples/quantize/quantize.cpp的量化类型表中Q6_K_R4被注册为{ Q6_K_R4, LLAMA_FTYPE_MOSTLY_Q6_K_R4, Q6_K repacked, },因此可以用与其它类型完全一致的方式量化# 从已有 GGUF 重新量化为 Q6_K_R4 ./llama-quantize --allow-requantize model.gguf model-q6_k_r4.gguf Q6_K_R4 # 或直接指定输出类型结合 imatrix 提升量化质量 ./llama-quantize --imatrix imatrix.dat model.gguf model-q6_k_r4.gguf Q6_K_R4转换完成后可直接交给llama-cli、llama-server等运行时加载推理。Q6_K_R4的blck_size与Q6_K相同256因此不需要额外的对齐处理即可用于标准矩阵乘。4.2 运行时重打包无需重新量化如果你已经持有标准Q6_K模型可以通过运行时的张量重打包机制见上文 2.4 节的注册表按需转为 R4 布局而无需重新量化整份模型文件。具体张量选择可通过 tensor 名称正则表达式控制适合只想加速 output tensor 等特定张量的场景。4.3 适用前提与注意事项精度无损由于 R4 只是布局重排、数值路径与原Q6_K完全一致无需重新评估困惑度perplexity平台差异PP 场景所有平台都受益TG 场景 Zen4/AVX2 显著受益、ARM_NEON 小线程数基本持平是否启用取决于你的硬件与主要负载类型编译开关R4 的 CPU 快路径依赖项目的 IQK 相关实现iqk_mul_mat构建时请保持默认的量化/矩阵乘组件完整编译参见 ggml/src/iqk 目录行数约束重打包要求nrows % 4 0且n_per_row % QK_K 0绝大多数模型张量满足该条件一维张量如 token embeddings 之外的偏置类张量不受影响因为文件格式标记为 except 1d tensors。五、在 R4 系列中的定位Q6_K_R4并非孤立存在它是 ik_llama.cpp 2024 年末构建的R4 行交错量化体系的一部分。完整脉络包括块级 R4 先行PR #118~#123、#125~#128 完成了IQ4_NL_R4、Q4_0_R4、Q8_0_R4、Q5_0_R4、Q6_0_R4、IQ4_XS_R4以及 ARM_NEON/CUDA 上的相应实现K 系 R4 跟进PR #129Q4_K_R4、#130Q6_K_R4、#132Q5_K_R4、#134Q3_K_R4、#136Q2_K_R4逐步补齐 K 系I 系 R4 深化PR #138、#145、#146、#149、#150 等把 R4 布局扩展到IQ4_K、IQ3_K、IQ2_K、IQ5_K、IQ4_KS等 I 系类型后续演进PR #189 之后部分类型进一步演进为 8 行交错_R8PR #272、#274 引入运行时重打包与张量正则选择能力。从源码结构看这一体系的核心收益机制是统一的通过把多行数据交错到同一缓存行/寄存器批次内减少 SIMD 内层循环的访存开销并提升内存带宽利用率。Q6_K_R4作为其中唯一被 routinely used for the output tensor 的类型具有最普适的实战价值。结语Q6_K_R4是 ik_llama.cpp 在不改变量化语义、仅重排内存布局这一约束下做出的典型性能优化数值路径与标准Q6_K完全一致却在 PP-512 场景为 ARM_NEON 带来约 1.45 倍、AVX2 约 1.36 倍、Zen4 约 1.25 倍的加速在 TG 场景Zen4 单线程可达 1.48 倍并仅需 2 线程即可饱和内存带宽。对于任何以Q6_K作为输出张量或整体权重量化的模型部署切换到Q6_K_R4都是低成本、高回报的一步。【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →