ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

ik_llama.cpp CPU 提示词处理提速第三弹:非交错量化类型的 Q8 行交错重打包 GEMM 优化解析

ik_llama.cpp CPU 提示词处理提速第三弹:非交错量化类型的 Q8 行交错重打包 GEMM 优化解析 人工智能大模型推理引擎本地部署模型量化模型优化【免费下载链接】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 #534《Much faster CPU prompt processing (part 3)》所实现的 CPU 端 prompt processingPP加速方案。该 PR 是此前 #531、#533 两个提速工作的延续目标是为剩余的非交错non-interleaved量化类型——Q2_K、IQ4_XS、IQ4_NL、Q4_0、Q4_1、Q5_0、Q5_1、Q6_0、Q8_0——提供高速 GEMM 内核。读完本文你将理解这套运行时重打包 行交错 Q8 内核加速流水线的底层原理、三类重打包目标类型与三档性能差异的成因掌握在真实硬件上复现与验证效果的方法含llama-sweep-bench完整命令并了解非 256 整除张量维度如 Kimi-Dev-72B 的ffn_down29568 列在量化与推理时的正确选型策略。一、PR 背景CPU 提示词处理提速三部曲ik_llama.cpp 在 2025 年 6 月前后针对 CPU 推理的提示词处理PP性能发起了一轮系统性的 GEMM 内核重构#531 与 #533先行为部分量化类型引入了新的高速 GEMM 路径#534本文主题作为第三部分把剩余的、此前尚未覆盖的非交错量化类型全部纳入新的高性能内核体系。该 PR 于 2025-06-18 创建、2025-06-19 更新作者为ikawrakow最终以Closed状态收尾其成果已合入主线。从仓库现状看这一系列工作已经固化为 ggml/src/iqk/iqk_mul_mat.cpp 等iqk/目录下的核心实现本文后续的源码印证均取自当前仓库实际内容。二、加速原理非交错量化类型的三大重打包路径PR #534 的核心贡献是为下列 9 种非交错量化类型分别实现运行时重打包 专用 GEMM 内核量化类型重打包目标类型使用的 GEMM 内核组合Q2_K、IQ4_XSQ8_K_R8Q8_K_R8 x Q8_KIQ4_NL、Q4_0、Q5_0、Q6_0、Q8_0Q8_0_R8Q8_0_R8 x Q8_2_X4Q4_1、Q5_1Q8_1_R8type-1 量化强制Q8_1_R8 x Q8_2_X4其中_R8后缀代表row-interleaved行交错重打包格式。这种格式把同一行内若干 block 的数据按向量友好方式交错排布使得 SIMD 内核对连续内存的访问更规整从而大幅提升乘加吞吐。2.1 源码层面的直接印证k-quants 家族Q2_K/IQ4_XS在 ggml/src/iqk/iqk_gemm_kquants.cpp 中iqk_convert_kquants_q8X_r8()将GGML_TYPE_Q2_K走iqk_convert_q2_k_q8_k_r8、GGML_TYPE_IQ4_XS走iqk_convert_iq4_xs_q8_k_r8统一重打包到Q8_K_R8格式随后iqk_set_kernels_kquants()为GGML_TYPE_Q8_K_R8注册mul_mat_q8_k_r8_q8_k内核对应上表第一行。传统量化家族Q4_0/Q4_1/Q5_0/Q5_1/Q6_0/Q8_0/IQ4_NL在 ggml/src/iqk/iqk_gemm_legacy_quants.cpp 中iqk_convert_legacy_quants_q8_r8()的分支清晰对应上表Q4_0、Q5_0、Q6_0、IQ4_NL、Q8_0→ 各自iqk_convert_qX_q80_r8/iqk_convert_q80_q80_r8目标Q8_0_R8Q4_1、Q5_1→ 走iqk_convert_qX_1_q8_1_r8目标Q8_1_R8iqk_set_kernels_legacy_quants()要求 B 矩阵类型统一为GGML_TYPE_Q8_2_X4并注册mul_mat_q8_0_r8_q8_2、mul_mat_q8_1_r8_q8_2等内核。统一的调度入口iqk_convert_repack()见 ggml/src/iqk/iqk_mul_mat.cpp按 A 矩阵类型分发到上述转换函数iqk_set_kernels_*系列在 mul_mat 执行前完成内核选择。整个体系由 CMake 选项GGML_IQK_MUL_MAT控制开启后定义GGML_USE_IQK_MULMAT宏并编入全部iqk_*源文件见 ggml/src/CMakeLists.txt。2.2 为什么重打包能带来约 2 倍收益核心洞察在于提示词处理阶段的 A 矩阵激活每次前向都会变化但 B 矩阵权重固定不变。因此可以把每次都要做的、昂贵的按 block 解量化 点积工作改造成一次性的重打包在首次接触权重时或每次前向开始时将权重按行交错格式重组为Q8_K_R8/Q8_0_R8/Q8_1_R8后续 GEMM 只需做高效的已重打包权重 × 重打包激活运算规避了逐 block 解量化的串行依赖让 SIMD 流水线满载。三、实测性能PP-512 全线约 2 倍提速PR 中给出了 LLaMA-3.1-8B-Instruct 在Ryzen 7950X CPU上的 PP-512batch512 的提示词处理对比数据main 分支 vs 本 PR量化类型main (t/s)PR (t/s)加速比Q2_K202.1364.21.802IQ4_XS178.0363.22.040IQ4_NL136.6293.52.149Q4_0155.6300.91.934Q4_1135.1253.51.876Q5_0147.5293.41.989Q5_1124.9253.52.030Q6_0129.0296.22.296Q8_0145.9293.52.012三档性能差异的成因作者在 PR 中明确指出与重打包目标类型一一对应高档约 360 t/sQ2_K、IQ4_XS重打包为Q8_K_R8命中更快的Q8_K_R8 x Q8_KGEMM中档约 290–300 t/sIQ4_NL、Q4_0、Q5_0、Q6_0、Q8_0重打包为Q8_0_R8走Q8_0_R8 x Q8_2_X4GEMM低档约 250 t/sQ4_1、Q5_1因属于带偏移的 type-1 量化必须重打包为Q8_1_R8其 GEMM 吞吐相对较低。也就是说同一批优化内核对不同量化类型的效果并不完全一致Q6_0拿到了最高的 2.296 倍加速而Q2_K因原本基数就高202.1 t/s绝对增益仍很可观。需要说明的是以上数字是 PR 提交者在特定硬件Ryzen 7950X、AVX2 指令集上的实测结果不代表所有平台且这些数据属于 2025 年 6 月的仓库状态具体数值请以你本地构建的实际测速为准。四、开发与兼容性细节4.1 MSVC 编译修复__m128除法运算符问题PR 评审中开发者Nexesenex报告在 MSVC 2022Windows 11启用 AVX2 FMA下ggml/src/iqk/iqk_gemm_kquants.cpp 第 2077 行附近出现编译错误binary /: __m128 does not define this operator or a conversion to a type acceptable to the predefined operator.问题根源是代码中直接对__m128类型做除法max4 / 127.f——MSVC 不像 GCC/Clang 那样接受对 SIMD 向量类型的标量除法运算符重载。作者随即以_mm_cvtss_f32(...)等显式 intrinsic 方式修复将标量除法改为先转换标量再除法评审确认修复生效。这一细节提醒跨平台尤其 MSVC使用 SIMD intrinsic 时避免依赖编译器特定的运算符重载行为。4.2 非 256 整除张量维度与 block size 32 的量化社区成员ubergarm在使用 moonshotai/Kimi-Dev-72BQwen2.5-72B 架构微调时发现其ffn_down.weight形状为{29568, 8192}列数 29568 不是 256 的整数倍29 568 / 256 115 full blocks (115 × 256 29 440) remainder 128 elements (padded to 256)而 k-quants/i-quants 的 super-block 通常为 256若列数非 256 倍数则无法直接使用。作者给出的选型建议必须改用block size 32的量化类型追求更低 bits-per-weight 用IQ4_NL4-bit 非线性、block 32追求更高 bpw 用Q5_0或Q6_0。作者同时解释了历史背景ggml 早期曾有 super-block 64 的 k-quants 变体但因维护成本被移除trellis 类量化iqN_kt等见 PR #529 合入的iq3_kt/iq4_kt也曾考虑做 block 32 版本但因 block scales 处理繁琐而未实施。从源码看Q8_0/Q5_1/IQ4_NL等 block 32 类型在 ggml/src/iqk/iqk_gemm_legacy_quants.cpp 中均有对应的iqk_convert_legacy_quants_q8_r8()分支可正常进入本 PR 的加速路径。五、实战复现用 llama-sweep-bench 验证 PP 提速5.1 标准 PP 测速命令社区实测中使用的llama-sweep-bench位于 examples/sweep-bench/sweep-bench.cpp命令如下numactl -N 0 -m 0 \ ./build/bin/llama-sweep-bench \ --model $model \ --ctx-size 6144 \ -ctk q8_0 -ctv q8_0 \ -fa \ --no-mmap \ -ub 2048 -b 2048 \ --warmup-batch \ --threads 128 \ --threads-batch 128 \ --numa numactl关键参数说明--ctx-size 6144上下文长度决定 KV cache 规模-ctk q8_0 -ctv q8_0K/V cache 量化类型选择q8_0可降低 cache 带宽占用-fa启用 flash attentionCPU 侧即iqk的 flash attention 实现见 ggml/src/iqk/iqk_flash_attn.cpp-ub 2048 -b 2048ubatch 与 batch 均为 2048用于放大提示词处理阶段的吞吐--threads 128 --threads-batch 128分别控制 TG 与 PP 阶段的线程数注意在 Thread RipPer Pro 等平台上作者建议移除 numactl 并只用物理核线程数如 24 线程以获得公平对比。5.2 MoE 模型DeepSeek-R1-0528混合卸载实测针对 DeepSeek-R1-0528 这类 MoE 模型社区使用的命令展示了 ik_llama.cpp 的专家级卸载-ot能力./build/bin/llama-sweep-bench \ --model $model \ --no-mmap \ --ctx-size 8704 \ -ctk f16 \ -mla 3 -fa \ -fmoe \ -amb 512 \ -ngl 99 \ -ot blk\.(3|4|5|6|7|8|9)\.ffn_.*CUDA0 \ -ot blk\.(10|11|12|13|14|15|16)\.ffn_.*CUDA1 \ -ot expsCPU \ --warmup-batch \ --threads 24其中-otoffload type/pattern将部分层的 FFN 专家张量按正则模式分别卸载到 CUDA0/CUDA1其余专家留在 CPUexpsCPU-mla 3启用 MLA 优化、-fmoe启用 MoE 相关内核优化。该命令在 ThreadRipper Pro 7965WX24 核上测得 DeepSeek-R1-0528IQ3_KS_R4300.9 GiB3.847 BPW约 12.39 t/s TGIQ3_KT272.5 GiB3.483 BPW约 8.61 t/s TG。5.3 从带宽角度理解 TG 上限社区数据揭示了 TGtoken generation受内存带宽约束的规律。以 7965WX约 256 GB/s运行 DeepSeek-R1-0528激活参数约 37B为例理论 TG 上限可按带宽 / (激活参数量 × BPW/8)估算量化理论值 (tok/s)实测 (tok/s)达成率IQ3_KS_R414.412.486.0%IQ3_KT15.98.654.1%同理70B 稠密模型在 6980P约 512 GB/s上Q4_0的理论值约 13.4 tok/s、实测 5.47 tok/s达成率 40.8%而 7965WX 上Q4_0理论 6.7、实测 4.74达成率 70.7%——可见稠密大模型在 CPU 上的 TG 瓶颈在于内存带宽与 NUMA 配置而非 PP 内核。这正是本 PR 专注优化 PP而非 TG的原因也是 MoE 模型在混合推理中更受欢迎的原因TG 阶段只有少量专家被激活。六、总结从 PR #534 到当前仓库的落地性能9 种非交错量化类型在 PP-512 下获得约 1.8–2.3 倍提速且加速比与重打包目标类型Q8_K_R8/Q8_0_R8/Q8_1_R8严格对应原理通过激活重打包 行交错 Q8 内核把权重从原始量化格式转为 SIMD 友好布局是 CPU GEMM 提速的关键完整实现可查阅 ggml/src/iqk/iqk_gemm_kquants.cpp 与 ggml/src/iqk/iqk_gemm_legacy_quants.cpp兼容性修复了 MSVC 下__m128运算符重载的移植性问题block size 32 的量化IQ4_NL/Q5_0/Q6_0可覆盖非 256 整除的张量列维度验证使用llama-sweep-bench配以-fa -ub/-b大 batch 与--threads-batch即可复现 PP 吞吐MoE 模型可结合-ot专家级卸载做混合推理调优。需要提醒的是上述性能数字均为特定硬件Ryzen 7950X / ThreadRipper Pro / Xeon 6980P与特定模型在 PR 时期的实测实际收益受 CPU 指令集AVX2/FMA、内存带宽、NUMA 拓扑与量化配置共同影响建议以自身环境下的llama-sweep-bench结果为准。赞分享人工智能大模型推理引擎本地部署模型量化模型优化【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp点击查看免费下载相关推荐ik_llama.cpp 的 Q5_0_R44 行交错重打包量化如何让 prompt 处理提速 1.6 倍ik_llama.cpp 的 Q5_0_R44 行交错重打包量化如何让 prompt 处理提速 1.6 倍 Q5_0_R4 是 ik_llama.cpp 引入人工智能大模型推理引擎本地部署模型量化模型优化ik_llama.cpp 的 IQ4_KS_R4 量化4 行交错重打包如何让 CPU 预填充提速近 2 倍ik_llama.cpp 的 IQ4_KS_R4 量化4 行交错重打包如何让 CPU 预填充提速近 2 倍 ik_llama.cpp 在原有 IQ4_KS 基人工智能大模型推理引擎本地部署模型量化模型优化ik_llama.cpp CPU 预填充加速三部曲二IQK 量化家族的即时重打包 GEMM 优化解析ik_llama.cpp CPU 预填充加速三部曲二IQK 量化家族的即时重打包 GEMM 优化解析 导读 本文聚焦 ik_llama.cpp 中编号为人工智能大模型推理引擎本地部署模型量化模型优化上一篇10分钟掌握untrunc开源视频修复工具完全指南下一篇DALL-E2 PyTorch模型融合如何结合多个扩散先验提升生成多样性创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表