feat(inkling): TOPP — adaptive routed-expert trimming, and report what it trims - #704
Merged
Conversation
…t it trims
`colibri.c` has had `TOPP` and `kimi_k3.c` has `K3_TOPP`; `inkling.c` was the
only engine without it, and it is the engine where it matters most. Inkling is
disk-bound on a small host: topk=6 experts x 28 MB x 66 layers is ~11 GB read
per token, and 92% of decode time is expert I/O. Every expert TOPP drops is an
expert not read.
Same semantics as the other two engines: sort the routed (weight, id) pairs
descending, keep them until the cumulative weight crosses `p`, drop the tail,
and do NOT renormalise — the dropped weight simply does not contribute.
si[] is ordered by sigmoid(logit)+bias while the weight is sigmoid(logit)
without the bias, so the weights are not guaranteed descending and the pair is
re-sorted before the cut, exactly as colibri.c does.
This is a QUALITY lever, not a free speed-up: it changes the computation. So it
is opt-in, off by default, announced at startup, and — new here — it reports
its own effect at the end of the run:
[topp] 0.30: 36/72 routed used (50.0% trimmed, 1.00 experts/token avg)
Measured on the tiny fixture at TOPP=0.30: 50% of routed experts trimmed and
expert loads down from 47 to 27 (-43%), which is the mechanism the disk-bound
host needs. A number you can A/B instead of a claim you have to believe.
TOPP=0 (default) leaves the computation bit-identical: the transformers oracle
stays at 36/36 teacher-forced and 24/24 tokens, at cap=4 and cap=1. Values
outside (0,1) are refused with a message rather than silently clamped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
colibri.chas hadTOPPandkimi_k3.chasK3_TOPP(#676).inkling.cwas the only engine without it — and it is the engine where it matters most.Why here
Inkling on a small host is disk-bound, not compute-bound:
topk=6experts × ~28 MB × 66 layers is ~11 GB read per token, and a measured run spent 92% of its time in expert I/O (fill 1533 svsexpert-mm 59 s). Every expert TOPP drops is an expert not read.What it does
Same semantics as the other two engines: sort the routed
(weight, id)pairs descending, keep them until the cumulative weight crossesp, drop the tail, and do not renormalise — the dropped weight simply does not contribute.One detail worth noting:
si[]is ordered bysigmoid(logit) + biaswhile the weight issigmoid(logit)without the bias, so the weights are not guaranteed descending. The pair is re-sorted before the cut, exactly ascolibri.cdoes.It reports its own effect
This is a quality lever, not a free speed-up — it changes the computation. So it is opt-in, off by default, announced at startup, and (new here, not in the other engines) it prints what it actually trimmed:
Measured on the tiny fixture at
TOPP=0.30: 50% of routed experts trimmed, expert loads 47 → 27 (−43%). That's the mechanism the disk-bound host needs — and a number you can A/B rather than a claim you have to believe.Testing
TOPPoff,cap=4TOPPoff,cap=1TOPP=0.30trimmingTOPP=1.5(invalid)inkling,glm,olmoe,kimi_k3all cleanTOPP=0(default) leaves the computation bit-identical. Nobody's existing runs change.Honest note
I have not yet A/B'd output quality on the real 975B — the tiny fixture is random-init, so its argmax happens not to flip when the tail is dropped, which proves the plumbing but says nothing about quality on a trained model. The docs label
TOPPaccordingly, and the per-run report is there so the trade can be measured on a real host instead of assumed. Same caution the GLM side takes with theTOPP=0.75numbers in #693.