model: add Poolside Laguna XS.2 support#1911
Conversation
337c70d to
260eef9
Compare
| // Laguna's MoE path adds a shared expert beside the routed experts. | ||
| // Keep both on CPU for --cpu-moe; mixing CUDA-host routed experts with | ||
| // GPU shared experts currently produces non-parity logits. | ||
| pattern = "blk\\." + std::to_string(i) + "\\.ffn_((up|down|gate|gate_up)_exps|(up|down|gate)_shexp)\\.(weight|scale)"; |
There was a problem hiding this comment.
No, we don't want to have this. For partial offload it needs to work with shared experts on the GPU.
| Qcur = ggml_rope_multi(ctx0, Qcur, inp_pos, rope_factors, | ||
| n_rot_l, sections, rope_type, n_ctx_orig, freq_base_l, freq_scale_l, | ||
| ext_factor, attn_factor, beta_fast, beta_slow); | ||
| ext_factor_l, attn_factor_l, beta_fast_l, beta_slow_l); |
There was a problem hiding this comment.
So, either you make the Laguna implementation work with build_std_attention, then perhaps you can make changes to it, or you don't use build_std_attention (as the PR currently stands), and in that case you don't modify build_std_attention.
There was a problem hiding this comment.
Gah! Apologies, I'll clean that up, and investigate where non-parity in GPU shared experts is coming from. It looks like CUDA-vs-host execution for up/down_shexp on the offloaded layers.
|
Hi, @ikawrakow! I cleaned up the Changed code:
|
| return scale <= 1.0f ? 1.0f : (0.1f * mscale * logf(scale) + 1.0f); | ||
| }; | ||
|
|
||
| if (cparams.yarn_ext_factor != 0.0f) { |
There was a problem hiding this comment.
This code here will run for all models. On a scale of 1 to 10, how confident are you that this will not break other models? If it was copy-pasted from mainline llama.cpp, things are different there.
| float yarn_attn_factor = 1.0f; | ||
| float yarn_beta_fast = 32.0f; | ||
| float yarn_beta_slow = 1.0f; | ||
| float yarn_ext_factor_swa = -1.0f; |
There was a problem hiding this comment.
Here we set it to 1.0f. But in the Laguna section in llama-hparams.cpp we set it to 0.0f. Why? The *_swa values have been added to llama_hparams specifically for the Laguna architecture and are not used for anything else, so we might as well set them to their final value and discard the corresponding code in llama-hparams.cpp.
|
Understood! New commit: With this cleanup, I’m much more confident, at least 9/10, that this won’t affect other models because the SWA-specific YaRN values are no longer being globally inferred in The regular YaRN mscale logic was adapted from the existing |
ikawrakow
left a comment
There was a problem hiding this comment.
As far as I can tell, you can delete everything related to YaRN and SWA, and you get the exact same result.
| if (cparams.yarn_ext_factor < 0.0f) { // negative indicates 'not set' | ||
| cparams.yarn_ext_factor = rope_scaling_type == LLAMA_ROPE_SCALING_TYPE_YARN ? 1.0f : 0.0f; | ||
| } | ||
| static auto get_mscale = [](float scale, float mscale) { |
There was a problem hiding this comment.
Remove lines 6819-6845 from here and do this in build_laguna(). We really do not want the addition of a new model to affect other models. And we are not a copy of llama.cpp, so there is no need to copy/paste code from there.
There was a problem hiding this comment.
Agreed, thanks. New commit: 2f7e43968 model: localize Laguna SWA RoPE constants.
I removed the copied global mscale block from llama.cpp and removed the SWA-only hparams/cparams fields. build_laguna() now uses the SWA RoPE constants directly for SWA layers, so this no longer adds global initialization behavior for other models.
I also tested this against the previous PR commit b63a5c174 with the Q4 Laguna GGUF using a deterministic short completion/probability probe. The generated text and full completion_probabilities JSON were identical.
One note: I kept Laguna’s model-level YaRN key reads. I tested removing those too, but that changed output probabilities materially, so the narrower cleanup appears to be the parity-preserving version.
Summary
This adds support for Laguna-architecture GGUFs matching the public Laguna XS.2 schema. It has been validated on Q6_K and Q4_K_M GGUFs generated from official Laguna XS.2 weights. Other Laguna XS.2-derived GGUFs may work if they preserve the same metadata and tensor layout, but are not separately validated here. This compatibility PR includes:
lagunaarchitecture registration and model metadata loadingtokenizer.ggml.pre = lagunapoolside/Laguna-XS.2weights--cpu-moehandling where routed experts are CPU-hosted while shared experts remain on their normal split deviceThis PR does not include DFlash, MTP, speculation, performance tuning, custom quantization work, or broad chat/server UX changes.
Architecture Notes
Laguna-XS.2 is close to existing Step-style hybrid MoE/SWA models, but it is not a pure alias.
The correctness-sensitive parts are:
50000010000[48, 64, 64, 64, ...]pattern512softplusThe converter preserves the source checkpoint's Laguna metadata. The runtime then applies Laguna-specific global-vs-SWA RoPE/YaRN semantics in the graph path instead of requiring users to disable or rewrite the model's intended scaling metadata.
Validation
Official Poolside source revision:
Reviewer/community convenience GGUFs generated from official Poolside BF16 weights:
Files:
These GGUFs require an
ik_llama.cppbuild with this Laguna-XS.2 support, or another runtime with equivalent Laguna architecture handling. They are not expected to load or decode correctly with currentikawrakow/mainwithout this PR.Validation highlights:
{% include %}stubyarn_ext_factor=64llama-quantizellama-serverpython3 -m py_compilepassesValueErrorpy_compilegit diff --checkpasses locallyRepresentative local server shapes used for the fresh artifacts:
Partial-offload work after addressing #1911 comments:
The mixed placement and the shared-experts-on-host control both repeat exactly within placement, but their top-token probabilities differ by
0.0357007384on the same prompt. Treat--cpu-moepartial offload as stable-but-non-exact.Further bisection narrowed the delta to the shared expert
up/down_shexpmatmuls for the eight GPU-offloaded layers under-ngl 8. Disabling fused MoE/multi-add/up-gate paths did not restore parity,gate_shexpplacement was irrelevant, and the-ngl 0control was exact. Current evidence suggests a CUDA-vs-host shared-expertup/downexecution delta rather than a routed/shared add-reduce bug./completionharness:max_abs_common_top_prob_delta=0.0013219118118286133, same selected tokens (Paris,.).max_abs_common_top_prob_delta=0), so the short-prompt delta does not follow that matrix-matrix selector.GGML_CUDA_FORCE_DMMVdoes not bypass the earlier MMVQ/MMQ fast return inggml_cuda_mul_mat, so treat that as a weak/inconclusive DMMV scout rather than proof that DMMV was fully exercised.build-cuda/bin/llama-serverreproduced the same short-prompt delta exactly. Hosting onlyblk\..*\.ffn_gate_shexp.weightwas identical to mixed placement (max_abs_common_top_prob_delta=0), while hosting onlyblk\..*\.ffn_(up|down)_shexp.weightwas identical to hosting all shared expert tensors. This confirms thatgate_shexpand the routed/shared add are not the source of the observed drift.laguna-xs2-official-Q6_0.ggufcontrol also showed nonzero mixed-vs-up/down_shexp-host probability drift on the same short harness (max_abs_common_top_prob_delta=0.00404695887118578, same selected tokens). This makes a Laguna-specific Q6_K-only issue less likely and supports treating the remaining delta as quantized CPU-vs-CUDA matmul drift for the shared expertup/downprojections.llama-perplexity --kl-divergencerun over18chunks /270evaluated positions compared mixed placement against a shared-host base:Mean PPL(Q)/PPL(base)=1.004195 ± 0.001132Mean KLD=0.000056 ± 0.000003Maximum KLD=0.000269RMS Δp=0.089 ± 0.006%Maximum Δp=0.228%Same top p=100.000 ± 0.000%The partial-offload path is stable and keeps shared experts on GPU as requested, but it is not exact probability parity against a shared-experts-on-host control. The remaining evidence looks like small deterministic CUDA-vs-host numeric drift localized to offloaded shared expert
up/down_shexp, rather than Laguna graph-composition bug.Notes / Caveats
Q6_K is the primary reviewer-facing validation artifact.
Q4_K_M is provided as a smaller secondary artifact.
No performance claims are made.
The local validation profile intentionally uses explicit conservative placement (
-ngl 8) rather than--fit;--fittuning is left out of scope for this PR.The
--cpu-moepartial-offload path is stable but not exact parity: current mixed routed-host/shared-GPU placement loads and decodes, while deterministic probability comparisons against a shared-experts-on-host control show small nonzero drift.The implementation focuses on Laguna architecture correctness rather than speculative decoding, DFlash, or server UX changes.
GitHub may show a hidden/bidirectional Unicode warning on
src/llama-vocab.cpp. Audit result: this PR adds no Unicode format or direction-control characters; the warning comes from pre-existing tokenizer regex Unicode in that file, while the Laguna-added lines are ASCII-only and needed for GGUFs withtokenizer.ggml.pre = laguna.I have read the contributing guidelines
Self-reported review complexity: