]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/commitdiff
docs: add exception about weight folding (#26168)
authorXuan-Son Nguyen <redacted>
Mon, 27 Jul 2026 10:00:56 +0000 (12:00 +0200)
committerGitHub <redacted>
Mon, 27 Jul 2026 10:00:56 +0000 (12:00 +0200)
* docs: add exception about weight folding

* add example

docs/development/HOWTO-add-model.md
skills/add-new-model/SKILL.md

index 632e79881a4359c33408cc5a48bf355dd6fcd28f..102f479eb02c2b7d2b2167f2719c9cc6f6dacc9c 100644 (file)
@@ -144,6 +144,8 @@ Examples:
 - Gemma 3 folds the `1 +` of its `norm(1 + weight)` normalization into the weights at conversion time, so the graph just does a plain RMS norm.
 - Qwen3-Next applies its tensor permutation during conversion (in `modify_tensors`), so the graph can consume the already-permuted weights directly.
 
+Exception: a plain `weight * scale` with a constant scale is usually better left to inference time rather than folded into the weight at conversion. The scale conceptually applies to the activation, not the weight, so folding it into the weight can hurt numerical stability, and it shifts the weight's value range in a way that can make quantization worse. In this case, write the scale to GGUF as its own metadata key (e.g. `%s.attention.output_scale`, `%s.attention.value_scale`, `%s.embedding_scale`) and apply it in the graph, instead of pre-multiplying the weight tensor during conversion.
+
 ### Working with ggml_rope_ext
 
 PyTorch implementations usually prefer explicitly calculating `freq_cis`/`sin`/`cos` components. However, in llama.cpp, most RoPE operations can be handled via `ggml_rope_ext`, which does not require a sin/cos matrix. This saves memory while allowing the GGML RoPE kernel to be fused with other ops.
index 68be866c7b8d6d3d4ef7aff4408ad8a7ad16b77d..f76d1abfd7688b0d3775381641b558174915c3ab 100644 (file)
@@ -76,6 +76,7 @@ These recur often enough in review comments on past add-model PRs that they're w
 - Don't ship unfinished or unverified speculative-decoding (e.g. MTP) scaffolding in the base model PR - if it hasn't actually been confirmed to work, pull it out and land it as its own follow-up.
 - Conversion code should call into the base class's existing hparam logic (e.g. `super().set_gguf_parameters()`) rather than re-deriving it - large blocks of code that duplicate what `TextModel`/`MmprojModel` already provide will get flagged as redundant.
 - Do constant tensor modifications (e.g. `norm(1 + weight)`) and permutations/chunking at conversion time, not in the graph - see HOWTO-add-model.md's "Prefer conversion-time tensor modifications" tip (Gemma 3 folds its `1 +` into the weights, Qwen3-Next permutes in `modify_tensors`). Doing these at runtime in the graph is very likely to be rejected as over-complicated; if you genuinely can't do it at conversion time, open a discussion first explaining why rather than implementing it in the graph.
+  - Exception: a plain `weight * scale` with a constant scale is usually better applied at inference time instead of being folded into the weight at conversion. The scale conceptually applies to the activation, not the weight, so folding it in can hurt numerical stability, and it shifts the weight's value range in a way that can make quantization worse.
 
 ## Validation checklist