尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ik_llama.cpp 选择性重打包指南:用 `--repack-pattern` 正则精确控制张量的 R4/R8 重打包

ik_llama.cpp 选择性重打包指南:用 `--repack-pattern` 正则精确控制张量的 R4/R8 重打包 ik_llama.cpp 选择性重打包指南用--repack-pattern正则精确控制张量的 R4/R8 重打包【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp在 ik_llama.cpp 中llama-quantize --repack可以将模型中的量化张量重打包为性能更优的_r4/_r8变体如Q4_K_R4、Q8_K_R8等但默认情况下它会对所有可重打包的张量生效。对于混合 GPU/CPU 推理hybrid GPU/CPU inference场景——例如把 DeepSeek MoE 的专家层experts全部留在 CPU 上——我们往往只希望重打包留在 CPU 上的那部分张量而保持 GPU 上的张量原样。PR #274 为此引入了--repack-pattern参数通过一个或多个正则表达式regex精确指定要重打包的张量名称从而实现对重打包粒度的精细化控制。读完本文你将掌握--repack-pattern的完整用法、参数解析与正则匹配的底层实现并能在自己的混合推理方案中正确组合-ot张量覆盖与--repack-pattern一次性生成最适配硬件布局的模型文件。为什么需要选择性重打包ik_llama.cpp 提供了一整套额外的 SOTA 量化格式其中包含大量_R4/_R8后缀的重打包变体。在 examples/quantize/quantize.cpp 中可以看到这些类型的完整清单例如IQ2_XXS_R4、IQ2_XS_R4、IQ2_K_R4IQ3_XXS_R4、IQ3_S_R4、IQ3_K_R4IQ4_KS_R4、IQ5_KS_R4、IQ4_K_R4、IQ5_K_R4Q2_K_R4、Q3_K_R4、Q4_K_R4、Q5_K_R4、Q6_K_R4Q8_K_R8、Q8_KV_R8、MXFP4_R8等这些变体在数值上与原类型等价但数据在内存中的排列方式不同通常能带来更好的推理性能。不过重打包的收益与运行后端密切相关某类张量在 GPU 后端与 CPU 后端上的最优布局可能并不相同。这正是混合 GPU/CPU 推理的痛点当模型过大无法完全装入显存时部分张量尤其是 MoE 模型的专家权重会被分配到 CPU 上执行。此时我们只希望重打包留在 CPU 上的张量让它们以 CPU 最优的_r4/_r8布局运行而 GPU 上的张量保持原布局避免无谓的布局转换开销。PR #274 就是在 PR #272提供整体--repack能力的基础上补充了按张量名正则精确筛选的能力。--repack-pattern基本用法PR #274 给出的核心用法如下命令格式与 examples/quantize/quantize.cpp 中打印的 usage 完全一致./bin/llama-quantize --repack --repack-pattern regex1,regex2,... some_model output_file_name quant_type其中参数说明--repack启用重打包模式等价于设置params.only_repack true将张量重打包为对应的_r4/_r8变体--repack-pattern逗号分隔的正则表达式列表用于匹配需要重打包的张量名称some_model输入模型路径如model.ggufoutput_file_name输出模型路径quant_type输出文件类型如Q4_K_R4、Q8_K_R8等注意重打包是一个无损的过程——_r4/_r8变体保存的数值与原类型一致只是内存排列不同因此quant_type参数需要选择与原模型张量类型对应的重打包类型可参考 examples/quantize/quantize.cpp 中的llama_ftype_name列表。实战示例DeepSeek MoE 专家张量重打包PR #274 中给出的典型场景是 DeepSeek 模型的混合推理。假设推理时通过张量覆盖参数-ot将 MoE 专家层指定到 CPU# 推理时让 DeepSeek MoE 专家留在 CPU 上 ./bin/llama-server -m model.gguf -ot expsCPU ...对应的在重打包模型时只对名称匹配exps的张量即专家权重执行重打包./bin/llama-quantize --repack --repack-pattern exps some_model output_file_name quant_type这样输出的模型只有exps相关的专家张量被重打包为_r4/_r8变体其余张量保持不变恰好与-ot expsCPU的推理配置形成最优配合。参数解析多个正则的逗号分隔处理--repack-pattern的参数解析逻辑位于 examples/quantize/quantize.cpp} else if (strcmp(argv[arg_idx], --repack-pattern) 0) { if (arg_idx argc-1) { auto p string_split(argv[arg_idx], ,); repack_patterns.insert(repack_patterns.end(), p.begin(), p.end()); } else { usage(argv[0]); } }关键行为逗号分隔传入的参数字符串会按,拆分成多个正则因此--repack-pattern regex1,regex2,...可以同时指定多个模式重复指定repack_patterns是一个std::vectorstd::string多次传参的结果会累积追加与--repack配合只有当--repackonly_repack true启用时pattern 才有实际作用。解析完成后在 examples/quantize/quantize.cpp 中把向量指针挂到量化参数上if (!repack_patterns.empty()) { params.repack_pattern repack_patterns; }该指针随后由llama_quantize_internal读取见 src/llama-quantize.cppconst std::vectorstd::string * repack_pattern nullptr; if (params-repack_pattern) repack_pattern (const std::vectorstd::string *)params-repack_pattern;正则匹配的实现原理在重打包流程中正则匹配会在两个阶段应用逻辑完全一致第一阶段统计与早期退出src/llama-quantize.cpp遍历模型所有张量的元信息判断每个张量是否需要重打包iqk_repacked_type返回了不同的类型或需要修改iqk_should_modify_tensor随后用 pattern 过滤if ((repack || modify) repack_pattern) { bool found false; for (auto r : *repack_pattern) { std::regex pattern(r); if (std::regex_search(name, pattern)) { found true; break; } } if (!found) repack modify false; }如果没有任何张量命中程序会输出nothing to do for only_repack option并直接返回src/llama-quantize.cpp。第二阶段实际执行重打包src/llama-quantize.cpp在逐张量写出的循环中对命中 pattern 的张量调用iqk_repack_tensor或iqk_modify_tensor未命中的张量则保持原类型、原数据直接拷贝if (params-only_repack) { ggml_type repacked_type (ggml_type)iqk_repacked_type(tensor); bool modify !is_repacked iqk_should_modify_tensor(tensor); if ((modify || repacked_type ! tensor-type) repack_pattern) { bool found false; for (auto r : *repack_pattern) { std::regex pattern(r); if (std::regex_search(tensor-name, pattern)) { found true; break; } } if (!found) { modify false; repacked_type tensor-type; } } ... }从源码结构看匹配使用的是 C 标准库的std::regex_search——即子串匹配语义只要正则能在张量名称的任意位置命中即可不需要全名精确相等。这也解释了为什么exps这样的简单子串就能覆盖形如blk.0.ffn_gate_exps.weight、blk.0.ffn_up_exps.weight等所有包含exps的专家张量。底层支撑哪些张量可以被重打包重打包的核心映射表定义在 ggml/src/iqk/iqk_quantize.cpp 的get_repack_info中它规定了每个基础量化类型对应的重打包目标类型原类型重打包类型行数对齐IQ2_K/IQ3_K/IQ4_K/IQ5_K对应_R44IQ4_XSIQ4_XS_R88IQ2_XXS/IQ2_XS/IQ2_S/IQ3_XXS/IQ3_S对应_R44Q2_K~Q6_K对应_R44Q4_0/Q5_0/Q6_0对应_R44Q8_0/Q8_K/Q8_KV/MXFP4对应_R88BF16/F16仅 AVX512-BF16 构建BF16_R1616决定一个张量是否可重打包的函数是iqk_repacked_typeggml/src/iqk/iqk_quantize.cpp它有三个限制条件张量必须连续ggml_is_contiguous非连续张量直接跳过张量名不能是禁止名单token_embd.weight和per_layer_token_embd.weight不会被重打包见is_forbidden_tensorggml/src/iqk/iqk_quantize.cpp行数必须能被映射表中的num_rows整除tensor-ne[1] % rptr-num_rows 0。实际的重打包动作由iqk_repack_tensor完成ggml/src/iqk/iqk_quantize.cpp 起它按kChunk 8个重打包块为单位切分张量并利用std::thread::hardware_concurrency()/2个线程并行执行各类型的 repack 函数如repack_iq4_ks、repack_q8_k等最后通过断言确保转换后的类型与预期一致。这些接口的声明统一放在 ggml/src/iqk/iqk_quantize.h在 src/llama-quantize.cpp 中被调用。使用建议与注意事项正则与张量命名约定模型张量名遵循blk.层号.组件.weight的命名规范如blk.0.attn_q.weight、blk.0.ffn_gate_exps.weight。可以利用这一点写出精确的模式例如只重打包注意力部分可以用attn_只重打包专家可以用exps。多个模式用逗号连接--repack-pattern attn_,ffn_会同时匹配所有注意力与 FFN 相关张量任一正则命中即生效OR 语义。与-ot张量覆盖保持一致重打包的目标张量集合应与推理时的-ot分配一致才能让_r4/_r8布局真正作用于目标后端。例如 CPU 上的专家用-ot expsCPU--repack-pattern exps。无法被重打包的张量自动保持原样即使正则命中了token_embd.weight或行数不满足对齐条件的张量iqk_repacked_type也会返回原类型程序会安全地原样拷贝不会报错。匹配命中的空结果如果所有张量都被 pattern 过滤掉llama-quantize会提示nothing to do for only_repack option并直接退出此时应检查正则是否与模型实际的张量命名匹配可用--dry-run先行预览。总结--repack-pattern是 ik_llama.cpp 重打包体系PR #272 的--repack在混合 GPU/CPU 推理场景下的关键补充它把对全部张量重打包细化为按名称正则精确选择张量重打包。配合-ot张量覆盖你可以为每个后端量身定制模型文件——CPU 上的张量使用_r4/_r8布局提升性能GPU 上的张量保持原有布局。其实现贯穿 examples/quantize/quantize.cpp 的参数解析、src/llama-quantize.cpp 的匹配过滤以及 ggml/src/iqk/iqk_quantize.cpp 的底层 repack 映射三者共同构成了完整、可审计的选择性重打包链路。【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表