Apertus xIELU formula / param-space mismatch — forward pass NaN's on real Apertus-8B Q4_K_S
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 30/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 冷清
- 技术栈
- kotlin
调研方向
Read ApertusXIELU.kt at line 27 and compare its activation formula with the Hugging Face Apertus modeling code; inspect the layer 0 parameters in the reference checkpoint and compare them with the GGUF values. The issue also points to ApertusWeightLoader.kt, the DSL wiring in apertusNetwork(), and ApertusRealGgufLoadingTest for a forward pass probe. Done means identifying the source of the NaNs and confirming the corrected activation produces finite logits.
由索引模型根据 Issue 内容生成。
描述
Summary
After PR #102 the load → convert → fromWeights → forward chain runs to completion against unsloth/Apertus-8B-Instruct-2509-GGUF (Q4_K_S) — but the logit vector is all-NaN at the first forward pass. The propagation source is ApertusXIELU.xielu(buf, params) in layer 0.
Diagnosis
ApertusXIELU.kt evaluates:
alpha_p_eff = softplus(alpha_p)
alpha_n_eff = beta + softplus(alpha_n)
if x > 0: alpha_p_eff * x*x + beta * x
else: (expm1(min(x, eps)) - x) * alpha_n_eff + beta * x
with softplus(x) = if (x > 20) x else ln(1 + exp(x)).
The unsloth GGUF stores per-layer xIELU params (verified via gguf Python lib):
| layer | alpha_p | alpha_n | beta | eps |
|---|---|---|---|---|
| 0 | 166.0 | 40.75 | 0.5 | -9.98e-7 |
| 1 | 174.0 | 31.625 | 0.5 | -9.98e-7 |
| 2 | 128.0 | 22.875 | 0.5 | -9.98e-7 |
| … | (decaying) | (decaying) | 0.5 | -9.98e-7 |
| 11 | -0.477 | … | 0.5 | -9.98e-7 |
| … | (small / negative) | … | 0.5 | -9.98e-7 |
For layer 0, softplus(166) ≈ 166 (the > 20 shortcut applies), so the activation collapses to 166·x² + 0.5·x. Any input value |x| past a few causes the FFN output to overflow, and the post-FFN matmul + residual chain NaN-poisons the rest of the forward.
Hypothesis
Either:
- The unsloth GGUF stores
alpha_p/alpha_nin a different transform space thanApertusXIELU.ktexpects.softplus(stored)may already be applied (i.e. these are the post-softplusalpha_p_effvalues, not the raw learned parameters). In that case the right thing is to drop thesoftpluscalls in the activation and use the stored values directly — which would still leave layer 0 withalpha_p_eff = 166, and the activation would still overflow for any non-trivial input. ApertusXIELU.kt's formula diverges from the Apertus-8B reference. Possible candidates:- The reference may scale
alpha_pby some normalization factor. - The
if x > 0branch might usealpha_p_eff * (e^x - x - 1)(an ELU-like form) rather thanalpha_p_eff * x². beta,eps, etc. may participate in a different combination.
- The reference may scale
- The unsloth converter is upstream-buggy and writes the wrong values in the wrong fields.
What to verify
- Pull the HF reference checkpoint
swiss-ai/Apertus-8B-Instruct-2509and inspect the actualact_fnparameter values for layer 0 — see whether they match the unsloth-stored values or are very different (e.g. small). - Diff
ApertusXIELU.xieluagainst the activation forward in the HF Apertus modeling code (modeling_apertus.pyor similar). - Quick sanity probe: replace
ApertusXIELUwith a no-op linear (or withsilu) and re-run the forward pass. If logits become finite, the failure is fully inside xIELU. - If a different unsloth quant of Apertus is available, repro under it to rule out a unsloth-conversion glitch isolated to Q4_K_S.
Where the formula lives
llm-inference/apertus/src/commonMain/kotlin/sk/ainet/models/apertus/ApertusXIELU.kt:27- The DSL wiring is
apertusNetwork()line 65:stage.xielu(id = \"act_fn\"). The DSL-emitted op is in skainet-lang-core; need to confirm it computes the same thing asApertusXIELU.xielureference. - Per-layer params are loaded by
extractXIELUParams/extractXIELUParamsFromStreamingMetainApertusWeightLoader.kt, then converted to scalar tensors namedblk.N.mlp.act_fn.{alpha_p,alpha_n,beta,eps}byApertusNetworkLoader.applyWeightsToNetwork.
Out of scope
This issue is only about the activation. Loader / module construction / Q4_K dispatch are all correct (PR #102 verified loader + fromGguf().load() end-to-end on real Apertus-8B). When the activation is fixed, forward / generate / tool calling smoke tests in ApertusRealGgufLoadingTest should pass without further loader work.
- 主要语言
- Kotlin
- 星标
- 8
- 派生
- 3
- 平均合并
- 1 天 16 小时
- 30 天内合并 PR
- 48
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
SKaiNET-developers/SKaiNET-transformers 的其他 Issue
-
documentation good first issue size:xs skill:docs sub-issue
难度 2/5 1-3 小时 新手友好度 78/100
SKaiNET-developers/SKaiNET-transformers#478 · 1 条评论 ·
维护者通常 1 天内回复
-
enhancement skill:kotlin-core
难度 4/5 3-5 天 新手友好度 48/100
SKaiNET-developers/SKaiNET-transformers#502 ·
维护者通常 1 天内回复
-
bug
难度 4/5 3-5 天 新手友好度 48/100
SKaiNET-developers/SKaiNET-transformers#483 ·
维护者通常 1 天内回复
-
coding good first issue size:s skill:kotlin-core sub-issue
难度 4/5 1-2 天 新手友好度 64/100
SKaiNET-developers/SKaiNET-transformers#477 · 1 条评论 ·
维护者通常 1 天内回复
-
coding good first issue size:s skill:numerics sub-issue
难度 4/5 3-5 天 新手友好度 55/100
SKaiNET-developers/SKaiNET-transformers#476 · 1 条评论 ·
维护者通常 1 天内回复
查看 SKaiNET-developers/SKaiNET-transformers 的全部 Issue
相似的 Issue
-
Blank screen in Download tab after searching with no results and switching tabs可能已有人在做 @mangod12 今天认领。 未关闭bug good first issue
难度 2/5 1-3 小时 新手友好度 70/100
kiwix/kiwix-android#5211 ·
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 65/100
deniscerri/ytdlnis#1430 ·
维护者通常 1 天内回复
-
[Bug] Lock owned by another client (e.g. Text app) cannot be unlocked from the app可能已有人在做 @falkloewert 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
-
submit-adaption submit-adaption-pre
难度 1/5 1 小时以内 新手友好度 75/100
BetterAndroid/android-notification-icon-project#763 · 1 条评论 ·
维护者通常 1 天内回复