Skip to content

kolibri1 TT: generalize the B1 stream envelope to multi-token forwards; the device-side router op - #3448

Merged
lu-zero merged 4 commits into
localai-org:mainfrom
lu-zero:row/tt-kolibri-b1-routing
Oct 11, 2026
Merged

lu-zero merged 4 commits into
localai-org:mainfrom
lu-zero:row/tt-kolibri-b1-routing

Conversation

@lu-zero

@lu-zero lu-zero commented Oct 11, 2026

Copy link
Copy Markdown
Collaborator

Two results from the kolibri1 P150 dispatch-overhead work.

The B1 per-token stream envelope (kolibri1_tt.cpp:292: 50 layers x topk 6 x 3,933,120 expert bytes = 1,179,936,000 B/forward — a RAM-bandwidth envelope, not a physical buffer) is now scaled by the forward's token count, identity at t=1. That admits multi-token forwards and makes CHUNKED PREFILL implementable: an 8-token-chunked prefill walk measured 156.3 -> 72.1 s (2.2x). NOT adopted in this change: the greedy chain moves, and the investigation surfaced the decisive fact that the P150 chain is not bit-reproducible run to run even on IDENTICAL code (three same-code runs: first tokens 346, 30686, 10; the b2ii gate's hard flips move between runs on origin/main alone). Chain identity is therefore not an adjudicable criterion on this path — the gate is a band gate, and adopting chunking owes band-class equivalence evidence of its own, recorded in ISSUE-LOCAL-01M4NS6D2GCD5WXBFN24XGXYQ4. Gates: b2ii 15/16 both before and after (the failing case moves run to run on main alone); TT suite 104/106 = the 2 known failures.

The device-side router op: new shared vt::SigmoidBiasTopK (OpId::kSigmoidBiasTopK) — kolibri's exact routing, selection on the RAW logit plus bias, which vt::MoeRouterTopK's noaux_tc contract cannot express. TT arm implemented, unit-tested (127 new assertions), wired behind the not-default state recorded in ISSUE-LOCAL-01M4NZA9B3DBKS3MD0M4TGRVES. Measured honestly: decode 57.7-59.8 s host vs 60.1-67.2 s device-router — NOT faster on the host path today. Its value is structural: it removes the per-layer full-tail logits download that blocks trace capture, and it is a prerequisite step the capture path needs.

Also recorded: the bench's greedy chain is not bit-reproducible run to run in ANY arm (consistent with #3447's record); test_tenstorrent_backend has one order-dependent RAC flake that passes in isolation and appeared in the red run without this change's kernel.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:zai/glm-5.3-flash [maki]

…en forwards

The B1 per-step stream guard was a one-token window: the forward charged
every layer's fetch against per_token_stream_bytes, so any multi-token
prefill forward refused loudly (whole-prompt 128: 1,404,123,840 B against
the 1,179,936,000 B bound at layer 3; the b2ii gate recorded 1,242,865,920 B
at layer 15). The bound is a per-token envelope, not a per-step buffer: the
guard now scales the window by the forward's token count, both the
per-forward charge window (kolibri1_tt_forward.cpp) and the per-layer
check inside BuildKolibri1TTSlotFetchList. One-token forwards are
unchanged — the scale factor is 1.

Chunked prefill was measured with the generalization (8-token chunks,
bench arm): the 128-token prefill walk dropped 156.3 s -> 72.1 s with the
decode split unchanged. It is NOT adopted as the default: the greedy chain
could not be proven equivalent, because this instrument is not
bit-reproducible run to run — three runs of the same one-token walk gave
three different chains (first token 346, 30686, and 10 under chunking),
and the b2ii golden gate's HARD flips move between runs (it is a band
gate, not a bit gate). Adopting chunked prefill owes band-class
equivalence evidence of its own; the decode bench comment records the
evidence and the decode bench keeps the faithful one-token walk.

Gate evidence (P150, tt-smi reset before every run):
- decode bench, chunked arm: prefill 72.1 s vs 156.3 s baseline; decode
  59.1 s vs 59.8 s (within run-to-run noise).
- b2ii device gate: 15/16 both on origin/main and with this change (the
  failing golden-chain case flips different prompts per run on
  origin/main alone) — verdict class unchanged.
- test_tenstorrent_backend: 104/106, failing exactly the two known
  kGdnDecode and kMatmulBTQuantGrouped cases, unchanged.

Owes: the chunked-prefill equivalence adjudication
(ISSUE-LOCAL-01M4NS6D2GCD5WXBFN24XGXYQ4).

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:zai/glm-5.3-flash [maki]
@lu-zero
lu-zero force-pushed the row/tt-kolibri-b1-routing branch from bd195ae to f71b7e8 Compare October 11, 2026 17:46
…gate-verified, measured, not default

New shared op vt::SigmoidBiasTopK (OpId::kSigmoidBiasTopK): the Kolibri-1
router of kolibri1.py:126-142 as a registered kernel — selection score =
RAW logit + e_score_correction_bias (NOT the DeepSeek noaux_tc
sigmoid+bias form; vt::MoeRouterTopK cannot express it, its contract
routes bias through the grouped path), weight = sigmoid of the UNBIASED
logit, no renormalization, ties to the lower expert index. The CPU kernel
(cpu_ops.cpp) is the exact port of SigmoidLogitAddRouting and the
reference; the TT kernel (tenstorrent_ops.cpp) is a device composite —
broadcast add, top-k via ttnn::experimental::topk_large_indices, dim-1
gather of the unbiased logit, ttnn::sigmoid — that downloads only the
[T,K] ids + weights instead of the full [T,E] logits tail.

Substrate constraints recorded in the kernel: topk_large_indices (the
ONLY top-k op on this tt-metal) requires ROW_MAJOR BFLOAT16 input and k
in multiples of 16, so the selection rounds the biased scores to bf16
(the router GEMM is already bf16 compute; the weights stay f32) and
slices a k-bucket down to top_k.

RED-FIRST evidence: the focused unit gate
(test_tenstorrent_backend.cpp "kTENSTORRENT kSigmoidBiasTopK matches the
CPU reference") ran red before the TT registration — REQUIRE(OpRegistered)
failed — and green after: expert SETS equal to the CPU reference on
random [4,384] logits, each weight within 2e-3 of sigmoid(unbiased logit
at its own id) AND of the CPU weight for the same id. Recorded
deviation: the ORDER within the top-k can swap on bf16 near-ties
(selection precision), benign to the model math (the combine sums
weight x expert over the k slots; the dispatch dedups).

kolibri1_tt_forward.cpp wires the op into MoeBlock behind
VT_KOLIBRI1_TT_DEVICE_ROUTER=1; the host path stays DEFAULT because the
composite MEASURED NO WIN at this shape (P150, 2026-10-11, tt-smi reset
recipe): decode median 60.9 s/64 steps (952 ms/step) over three runs
against the host path's 59.1 s (924 ms/step) in-session — inside the
run-to-run band, with the b2ii teacher-forced drift slightly WORSE (4
HARD flips vs the default path's 3-4, gaps -7.1/-7.4/-12.7/-4.4). The
extra eager op launches per layer cost what the full-tail drain saved;
the lever needs a captured/graphed region to amortize the launches.

Gate evidence (P150, reset before every device run):
- b2ii device gate: 15/16 BOTH on origin/main and with this change; the
  failing golden-chain case and its HARD flips move run to run on
  origin/main alone. Verdict class unchanged (issue:
  ISSUE-LOCAL-01M4NZA9B3DBKS3MD0M4TGRVES records the not-default state).
- test_tenstorrent_backend: the new gate passes; the suite is 104/107 —
  the two known kGdnDecode and kMatmulBTQuantGrouped failures plus one
  order-dependent RAC flake that passes in isolation and also appeared
  in the red run without this change's TT kernel.
- test_kolibri1_tt 16/16, test_kolibri1 27/27.
- decode bench, host path: decode 57.7-59.8 s/64 steps; device router:
  60.1/60.9/67.2 s.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:zai/glm-5.3-flash [maki]
@lu-zero
lu-zero force-pushed the row/tt-kolibri-b1-routing branch from f71b7e8 to 7454f07 Compare October 11, 2026 17:48
…k CPU arm shifted cpu_ops.cpp

The new op's CPU reference arm added ~33 lines ahead of DFlashBlockAttentionKernel; the anchor ratchet correctly flagged the stale line. Re-pointed 3619 -> 3652; check-agent-record green.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:zai/glm-5.3-flash [maki]
The device-router opt-in from the kSigmoidBiasTopK commit is an engineering A/B switch, same class as the other TT diagnostic knobs on the allowlist. Pre-push checks (env-doc + agent-record) are now run before pushing.

FOLLOWING_AGENTS_PROTOCOL

Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:zai/glm-5.3-flash [maki]
@lu-zero
lu-zero merged commit 4035294 into localai-org:main Oct 11, 2026
21 of 27 checks passed
@lu-zero
lu-zero deleted the row/tt-kolibri-b1-routing branch October 12, 2026 14:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant