ik_llama.cpp 的 Llama 4 支持落地:iRoPE 架构解析、MoE 专家调优与量化实战
发布时间:2026/9/19 1:55:25来源:尧图网络
ik_llama.cpp 的 Llama 4 支持落地iRoPE 架构解析、MoE 专家调优与量化实战【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp本文以仓库内 issue #314Llama 4 Support? 为骨架结合关闭该 issue 的 PR #321LlaMA-4 support, text only、后续长上下文缺陷修复 PR #342Fix LLaMA-4 attention 及相关源码完整还原 ik_llama.cpp 从是否支持 Llama 4的社区疑问到架构适配、专家数量调优、混合量化配方、长上下文缺陷修复的全过程并给出可直接复用的命令行与量化配方。导读Llama 4Scout / Maverick发布之初社区最大的疑问集中在两点其一模型宣称的 10M 超长上下文背后是全新的 iRoPE 架构llama.cpp 生态能否适配其二模型未采用 MLA且部分层为稠密层是否存在与 DeepSeek 类似的混合卸载空间。本文以 ik_llama.cpp 仓库内 issue #314 及其后续 PR 为线索讲解 Llama 4 的架构差异如何在 src/graphs/build_llama.cpp 与 src/llama-hparams.cpp 中落地并给出通过--override-kv调节激活专家数、通过--custom-q构造混合量化配方、以及用llama-perplexity验证量化质量的完整实战方案。读完本文你将掌握在 ik_llama.cpp 中运行、调优与量化 Llama 4 系列模型的具体方法以及理解长上下文场景下 SWA滑动窗口注意力缺陷的来龙去脉。一、issue #314社区对 Llama 4 支持的最初疑虑2025-04-05用户 Downtown-Case 在仓库提交了 issue #314核心诉求与疑问有三点能否像 DeepSeek 一样做层卸载offloading——作者当时还在等待模型 config 文件与论文但直觉认为模型宣称 10M 上下文架构上必然与 Llama 3.3 有本质区别期望出现 MLAMulti-head Latent Attention——作者坦言没有 MLA 是我微弱的希望破灭No MLA, which was my faint hope但随即指出有些层是稠密的所以这可能是一个不错的卸载候选Some layers are dense though, so maybe this is a good offloading candidate10M 上下文到底意味着什么——issue 中引用了官方 cookbook 的说法Scout 宣称支持最高 10M 上下文在 8 张 H100、bf16 精度下可达约 1.4M tokens社区对此的普遍疑问是各服务商最终会提供多长的上下文毕竟支持 10M 实在困难。值得注意的是issue 讨论中社区成员 saood06 引用了 Meta 官方对 Llama 4 架构的一段描述直接点出了后续适配工作的核心Llama 4 架构的一个关键创新是使用了交错注意力层interleaved attention layers其中部分层不使用位置编码同时采用推理期温度缩放inference time temperature scaling来增强长度泛化。我们称之为 iRoPE 架构i代表interleaved交错注意力层凸显了支持无限上下文长度的长期目标而 RoPE 指的是大多数层中使用的旋转位置编码。该讨论还指出这种部分层滑窗、部分层全局的设计与 Cohere Command-A 有相似之处Command-A 采用三层窗口大小为 4096 的滑动窗口注意力SWA RoPE 做局部建模第四层则是不带位置编码的全局注意力允许 token 在整条序列上自由交互。issue 最终于 2025-04-10 关闭关闭它的正是作者 ikawrakow 在 2025-04-09 提交的 PR #321Closes #314。二、iRoPE 架构在 ik_llama.cpp 中的落地证据PR #321 明确说明实现派生自主线 llama.cpp 的 PR 12791但由于两个代码库分歧太大the code bases have diverged so much移植花了相当精力。现在从当前仓库源码可以直接印证 Llama 4 架构的适配细节。2.1 架构注册与模型识别src/llama-arch.h 中新增LLM_ARCH_LLAMA4枚举src/llama-arch.cpp 将其映射为字符串llama4convert_hf_to_gguf.py 已通过 tokenizer 哈希识别meta-llama/Llama-4-Scout-17B-16E-Instruct并归类为llama4架构。需要说明的是PR #321 落地时作者曾明确表示未修改 convert 脚本与 Gemma-3 支持时相同当时需要用主线 llama.cpp 生成 GGUF而当前仓库的 convert_hf_to_gguf.py 中已经包含了针对 Scout 17B-16E 的架构识别逻辑读者可自行查阅确认。2.2 超参数SWA 模式与温度缩放src/llama-hparams.cpp 中LLM_ARCH_LLAMA4分支直接写死了 Llama 4 的关键结构参数ml.get_key(LLM_KV_ATTENTION_LAYERNORM_RMS_EPS, hparams.f_norm_rms_eps); ml.get_key(LLM_KV_EXPERT_FEED_FORWARD_LENGTH, hparams.n_ff_exp); ml.get_key(LLM_KV_INTERLEAVE_MOE_LAYER_STEP, hparams.n_moe_layer_step); hparams.n_swa_pattern 4; // pattern: 3 chunked - 1 full hparams.n_attn_chunk 8192; // 目前 Scout 与 Maverick 相同 hparams.n_swa 1; // 触发 SWA 分支chunked attn mask 存在 SWA tensor 中n_swa_pattern 4即每 4 层中 3 层为 chunked分块注意力、1 层为 full全局注意力的模式n_attn_chunk 8192定义了 chunk 的大小注释明确写着该值对 Scout 与 Maverick 相同当前未作为 GGUF KV 暴露。专家数量的识别同样在这个分支里完成switch (hparams.n_expert) { case 16: model.type MODEL_17B_16E; break; // Scout case 128: model.type MODEL_17B_128E; break; // Maverick default: model.type MODEL_UNKNOWN; } if (model.type MODEL_17B_128E) { hparams.use_kq_norm false; }此外src/llama-hparams.h 中还有一组对 llama4 来说似乎是固定值的字段正是 issue 中提到的 iRoPE 温度缩放的实现参数uint32_t n_moe_layer_step 0; bool use_kq_norm true; uint32_t n_attn_chunk 0; // values below seems to be fixed on llama4 uint32_t n_no_rope_layer_step 4; // 每 4 层中有 1 层不使用 RoPE uint32_t n_attn_temp_floor_scale 8192; // 温度缩放生效的上下文下限 float f_attn_temp_scale 0.1; // 温度缩放系数n_no_rope_layer_step 4与n_swa_pattern 4的一致性说明不做位置编码的全局注意力层恰好就是 4 层一循环中的那 1 层这正是iRoPEinterleaved RoPE在实现层面的直接体现。2.3 计算图无 RoPE 层、温度缩放与 SWA masksrc/graphs/build_llama.cpp 中build_llama()对LLM_ARCH_LLAMA4的处理非常清晰if (model.arch LLM_ARCH_LLAMA4) { inp_attn_scale build_input_scale(n_tokens); // 推理期温度缩放输入 } // 按 4 层一循环决定是否使用 RoPE bool use_rope model.arch LLM_ARCH_LLAMA4 ? (il 1) % hparams.n_no_rope_layer_step ! 0 : true; // 3 chunked 1 full 的 SWA mask 切换 auto this_KQ_mask hparams.n_swa 0 hparams.n_swa_pattern 0 il % hparams.n_swa_pattern (hparams.n_swa_pattern - 1) ? KQ_mask_swa : KQ_mask;不使用 RoPE 的层use_rope falseQ/K 不做 rope 旋转而是乘以inp_attn_scale对应温度缩放使用 RoPE 的层若use_kq_norm为真Q、K 会额外过一次 RMS NormLlama4TextL2Norm见 build_llama.cpp前 3 层使用KQ_mask_swachunked 分块 mask第 4 层使用完整KQ_mask。2.4 MoEsigmoid 门控 共享专家shared experts从 build_llama.cpp 可以看到 Llama 4 与常规 MoE 的差异其 FFN 分支使用LLM_EXPERT_GATING_FUNC_SIGMOID门控且在路由专家之外还有一个共享专家分支shared experts最终输出是两者的加和ggml_tensor * moe_out llm_build_moe_ffn(..., n_expert, n_expert_used, LLM_FFN_SILU, false, false, 0.0, LLM_EXPERT_GATING_FUNC_SIGMOID, ...); ggml_tensor * shexp_out llm_build_ffn(..., ffn_up_shexp, ffn_gate_shexp, ffn_down_shexp, ...); cur ggml_add(ctx0, moe_out, shexp_out);而 src/llama-load-tensors.cpp 中create_llama4_tensors()则揭示了 Llama 4 的交错 MoE 层结构——并非每一层都是 MoEGGML_ASSERT(hparams.n_moe_layer_step 0 Llama 4 requires n_moe_layer_step 0); for (int i 0; i n_layer; i) { bool is_moe_layer (i 1) % hparams.n_moe_layer_step 0; ... if (is_moe_layer) { // ffn_gate_inp 三组共享专家张量 ffn_gate_shexp / ffn_down_shexp / ffn_up_shexp } else { create_std_ffn(i, tn, layer, n_ff, n_embd, ctx_split); // 稠密层 } }这从源码层面印证了 issue 中部分层是稠密的这一观察非 MoE 层是标准稠密 FFNMoE 层则包含共享专家 路由专家。正因如此issue 中密集层适合做卸载候选的猜测是成立的——把庞大的专家张量留在 CPU、只把稠密层与注意力卸载到 GPU正是 PR #321 实测时采用的混合推理策略。三、首次实测Q6_K 下的 CPU/GPU 混合推理PR #321 中作者给出了第一份真实硬件测试数据Ryzen-5975WX CPU RTX-4080 GPUQ6_K 量化模型当时尚未跑 imatrix 因此用较高 bit 数排除量化干扰./bin/llama-perplexity -m Llama4-Scout-Q6_K.gguf \ -ot expsCPU -rtr -fmoe -t 32 -ngl 100 ...结果perplexity 测试达到221 t/s生成 128 tokens 的常规问答约10.5 t/s。作者评价这相当不错了This is not bad at all。该命令涉及的三个关键参数详见 docs/parameters.md值得逐一说明参数含义说明-ot, --override-tensor用正则覆盖张量存放位置expsCPU把名字含exps的专家张量全部留在 CPU 内存实现稠密层/注意力上 GPU、专家留 CPU的混合卸载正是 issue 所讨论的 DeepSeek 式卸载思路-rtr, --run-time-repack若存在交错row-interleaved变体则运行时重打包张量在某些系统上可提升性能但 README.md 明确警告MoE 混合 CPU/GPU 推理时不要随意使用 -rtr因为 k-quantsK2_K、Q3_K、Q4_K、Q5_K、Q6_K没有 CUDA 交错实现重打包会把本该卸载到 GPU 的矩阵乘法钉死在 CPU 上反而降低 prompt 处理速度-fmoe, --fused-moe融合 MoE 的 ffn_up 与 ffn_gate对 MoE 模型有提速效果仓库 PR 229 引入README 中记录另外 PR #321 也如实记录了当时模型的局限——未能通过终极 AGI 测试问它 strawberry 里有几个 r回答是 2 个实际应为 3 个。这个细节也呼应了 issue 中初始反应大多是负面的the initial reactions to LlaMA-4 are mostly negative这一社区氛围。四、激活专家数量调优1 个 vs 2 个 vs 3 个Llama 4 的 MoE 默认按模型参数激活 1 个专家但作者在 PR #321 的讨论中用--override-kv直接改写 GGUF 元数据llama4.expert_used_count做了对照实验Q8_0、n_ctx512 的 Wikitext2 PPL# 默认 1 个专家 PPL(Q8_0, n_ctx 512) 9.0644 # 激活 2 个专家 --override-kv llama4.expert_used_countint:2 PPL(Q8_0, n_ctx 512) 8.7030结论非常明确2 个专家比 1 个专家 PPL 更低8.7030 vs 9.0644但速度从 211 t/s 降到 133 t/s继续尝试 3 个专家跑了 172 个 chunk 后 PPL 反而比 2 个专家高约 0.1作者判断2 个专家似乎是甜点区2 experts seems to be the sweet spot作者特别指出这与 Mixtral 8x7B 的经验相反——Mixtral 在 2 个专家时效果更好、3 个反而变差除非用极低 bpw 量化。从实现角度llama4.expert_used_count是仓库已定义的 GGUF KVsrc/llama-arch.cpp 中LLM_KV_EXPERT_USED_COUNT映射为%s.expert_used_count在 src/llama-hparams.cpp 中被读入hparams.n_expert_used并带有一致性断言n_expert_used n_expert见 llama-hparams.cpp。也就是说--override-kv是在运行时安全地改变参与计算的专家数这正是 docs/parameters.md 中--override-kv KEYTYPE:VALUE参数类型支持 int/float/bool/str可多次指定的典型用法。调优建议追求生成质量且显存/算力允许时可尝试--override-kv llama4.expert_used_countint:2追求吞吐则保持默认 1 个专家。五、量化实战超越官方 Unsloth 配方的混合量化PR #321 讨论中最有价值的部分是作者基于 imatrix 与--custom-q为 LlaMA-4-Scout 设计的系列混合量化配方。核心思路可以总结为一条经验法则shared experts共享专家与 attention 张量用较高精度路由专家ffn_*_exps用极低 bpw——因为共享专家每层都被激活、对输出质量贡献最大。5.1 4-bit 配方IQ4_KS 反超 Q8_0./bin/llama-quantize --imatrix l4_scout_imat_512.out --custom-q \ ffn_gate_shexpiq4_ks,ffn_up_shexpiq4_ks,ffn_down_shexpiq5_k,attniq4_ks,token_embd.weightq4_K,output.weightq6_K,ffn_.*_expsiq4_ks \ Llama4-Scout-16x17B-BF16.gguf junk1.bin iq4_ks结果PPL 9.0554甚至优于 Q8_0模型体积 54.003 GiB。作者据此认为4-bit 完全没有必要再做更高精度。5.2 低 bit 配方逐个击败 Unsloth 的 UD 系列下表汇总了 PR #321 中的三组对照结果均为 Wikitext2n_ctx512目标ik_llama.cpp 配方 PPL / 体积Unsloth UD PPL / 体积对标 UD-Q2_K_XL9.4736 / 39.090 GiB9.6535 / 39.654 GiB对标 UD-IQ2_XXS10.1506 / 34.871 GiB10.3454 / 35.904 GiB对标 UD-IQ1_S10.9640 / 31.121 GiB11.0173 / 31.510 GiB对应的三条命令公共前缀--imatrix l4_scout_imat_512.out基础量化分别用 q2_K / iq1_s / iq1_s# UD-Q2_K_XL 的配方含前 6 层共享专家的特殊处理 --custom-q ffn_gate_shexpiq4_ks,ffn_up_shexpiq4_ks,ffn_down_shexpiq5_k,attniq4_ks,token_embd.weightq4_K,output.weightq6_K,blk\.[0-5]\.ffn_down_expsiq4_ks,ffn_down_expsq3_K,ffn_up_expsq2_K,ffn_gate_expsq2_K # UD-IQ2_XXS 配方 --custom-q ffn_gate_shexpiq4_ks,ffn_up_shexpiq4_ks,ffn_down_shexpiq5_k,attniq4_ks,token_embd.weightq4_K,output.weightq6_K,blk\.[0-5]\.ffn_down_expsiq4_ks,ffn_down_expsq3_K,ffn_up_expsiq1_s,ffn_gate_expsiq1_s # UD-IQ1_S 配方 --custom-q ffn_gate_shexpiq4_ks,ffn_up_shexpiq4_ks,ffn_down_expsiq5_k,attniq4_ks,token_embd.weightq4_K,output.weightq6_K,blk\.[0-5]\.ffn_down_expsiq4_ks,ffn_down_expsiq3_k,ffn_up_expsiq1_s,ffn_gate_expsiq1_s5.3 50GB 以内高价值配方iq3_xxs作者还给出了一个体积约 45.05 GiB48.38 GB的 iq3_xxs 配方适合单卡 50GB 显存以内的场景./bin/llama-quantize --imatrix l4_scout_imat_512.out --custom-q \ ffn_gate_shexpiq4_ks,ffn_up_shexpiq4_ks,ffn_down_shexpiq5_k,attniq4_ks,token_embd.weightq4_K,output.weightq6_K,ffn_down_expsiq4_ks,ffn_.*_expsiq3_xxs \ Llama4-Scout-16x17B-BF16.gguf junk1.bin iq3_xxs最终 Wikitext2 PPL 为 9.2462仅比 Q8_0 高约 2%若按外部 shoot-out 的 300-chunk 口径计算为 8.8937。5.4 反直觉发现attention 张量上 iq4_K 反而更差作者在实验中报告了一个反直觉的现象把 attention 张量从 q4_K 换成 iq4_K 会导致 PPL 变高约 9.5668 → 9.4895 的改善来自把ffn_down_exps换成 iq4_K而 attention 上的同类替换反而恶化。作者的长期观察是iq4_k/iq5_k/iq6_k 在 FFN 部分明显优于对应 k-quant质量收益主要来自 FFN但在 attention 张量上并无明显优势且这是第一次出现变差的情况token embedding 也有少数情况用对应 k-quant 更合适。性能优化提示如果你追求速度而非极致质量可以尝试把 attention 张量从 iq4_k 换回 q4_K——这会提升推理速度而几乎不损失质量。5.5 用 KL 散度验证量化质量对于 iq3_xxs 配方作者用llama-perplexity --kl-divergence输出了更精细的质量统计详见 examples/perplexity/README.md需先以--kl-divergence-base path/to/base.kld生成基准 logit 文件Mean PPL(Q) : 8.894160 ± 0.099641 Cor(ln(PPL(Q)), ln(PPL(base))): 97.61% Mean KLD: 0.106186 ± 0.001075 99.0% KLD: 1.098310 Median KLD: 0.033228 Mean Δp: -0.695 ± 0.033 % RMS Δp : 9.177 ± 0.076 % Same top p: 87.280 ± 0.120 %作者评价该配方与 shoot-out 里的模型不在一个档次a different league than the shoot-out models。此外仓库还支持 docs/development/on-demand-tensor-reload.md 描述的运行时张量重载机制可在不重新量化的情况下按专家逐个试验不同量化级别如将单个ffn_down_exps.weight替换为 IQ1_KT 并观察 PPL 变化适合做量化消融实验。六、长上下文缺陷SWA 缺失导致 64K 输出乱码issue #314 关闭后另一个相关缺陷很快浮出水面issue #335 报告Llama 4Maverick 与 Scout在 64K 长上下文下输出完全乱码0: 0000: 0:00: 0:00: //:0:00:00:之类的重复碎片而主线 llama.cpp 正常。进一步缩小范围后确认Scout 在约 10K-14K 开始劣化18K 仍可连贯23K 左右开始明显崩坏32K 输出基本不可用与模型拆分tensor-split无关单 GPU 可复现用户给出的启动参数示例llama-serverissue #335./build/bin/llama-server \ --model Llama-4-Scout-17B-16E-Instruct-UD-Q4_K_XL.gguf \ --ctx-size 81920 --n-gpu-layers 49 --tensor-split 25,25,25,25 \ -fa -ctk q8_0 -ctv q8_0 --threads 64 --host 0.0.0.0 --port 5000作者排查时排除了-amb 1024docs/parameters.md 中-amb/--attention-max-batch限制单次注意力计算的 K*Q 大小默认 256MB的因素最终定位并修复于 PR #342Fix LLaMA-4 attention根因SWA 部分漏掉了。由于 SWA 只在超过 8k tokens 后才真正起作用而缺失 SWA 的影响在接下来 8k 内相对较小所以模型在 16k 以内看起来还正常超过之后便逐层累积出错。修复后模型能够正确总结 23.5k tokens 的维基百科文章PR #342 给出了完整的多段结构化摘要输出作为验证。作者同时披露了一个有趣的权衡修复后 16k 上下文的 PPL 反而从 7.18 上升到 7.27——我们用预测能力换取了处理更长上下文的能力。这个案例也提供了一个可复现的验证手段作者在 issue #335 中给出./bin/llama-perplexity -m Llama-4-Scout-17B-16E-Instruct-UD-Q2_K_XL.gguf \ -f wiki.test.raw -ub 2048 -t 32 -ngl 100 -c 16384 \ -ot blk\.[0-8]\.ffn_up_expsCUDA0,blk\.[0-8]\.ffn_down_expsCUDA0,expsCPU \ -rtr -fmoe -fa最终 16k 上下文 PPL 为 7.1819 ± 0.04765这是修复前的数值修复后该口径 PPL 为 7.27 左右。另外作者强调 llama.cpp 与 ik_llama.cpp 在相同种子、零温度下输出不可能逐 token 一致因为两边计算方式不同、浮点运算不可结合——这解释了社区观察到的输出差异。七、实践要点总结模型获取历史版本PR #321 时期需用主线 llama.cpp 的 convert 脚本生成 GGUF当前仓库的 convert_hf_to_gguf.py 已内置 Scout 17B-16E 的架构识别基于 tokenizer 哈希。issue 讨论中还提到官方下载工具在大文件上易失败社区建议使用带哈希校验与失败重试的下载器。混合卸载-ot expsCPU配合-fmoe是 Llama 4 的典型混合 CPU/GPU 玩法结合-ngl、--cpu-moe、-ooae仅卸载激活专家见 docs/parameters.md可进一步微调。若不加-rtr时专家张量留在 CPU 走 CUDA 卸载路径一般不要启用-rtrk-quants 无 CUDA 交错实现。专家数--override-kv llama4.expert_used_countint:2是质量优先时的甜点配置PPL 显著下降、速度约降 1/3吞吐优先保持默认 1。量化优先保证ffn_*_shexp共享专家与 attention 的精度推荐 iq4_ks/iq5_k 档路由专家ffn_*_exps可压低至 q2_K / iq1_s / iq3_xxs--imatrix--custom-qdocs/parameters.md 中--custom-q支持正则匹配张量名是复现上述配方的前提可用--dry-run快速预览张量类型与体积后再实际量化。长上下文当前版本已修复 SWA 缺失问题16K 上下文可用若在旧版本遇到 64K 乱码应升级到包含 PR #342 修复的版本并用llama-perplexity做回归验证。多模态从源码看examples/mtmd/mtmd.cpp 已包含PROJECTOR_TYPE_LLAMA4与MTMD_SLICE_TMPL_LLAMA4分支说明仓库后续对 Llama 4 的多模态投影器也有对应处理但 PR #321 落地时仅为纯文本支持使用多模态能力时请以当前仓库 mtmd 示例与文档为准。结语从 issue #314 的能不能支持、怎么卸载、10M 上下文怎么做到 PR #321 的纯文本支持落地、专家数调优与系列量化配方再到 PR #342 对 SWA 长上下文缺陷的修复ik_llama.cpp 对 Llama 4 的支持完整覆盖了跑起来—调快—压小—跑长四个阶段。仓库中的 src/llama-hparams.cpp、src/graphs/build_llama.cpp 与 src/llama-load-tensors.cpp 是理解 iRoPE/SWA/MoE 实现的最佳入口而 github-data 目录下的 issue 与 PR 记录则为每个关键决策提供了第一手的实测数据与调参思路。【免费下载链接】ik_llama.cppllama.cpp fork with additional SOTA quants and improved performance项目地址: https://gitcode.com/GitHub_Trending/ik/ik_llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网