Skip to content

spec(ml): train_hslm speed=4 -- int8 trit forward, error bounded against speed=2 (Closes #10875) - #10908

Merged
gHashTag merged 4 commits into
masterfrom
claude/hslm-int8-forward
Oct 19, 2026
Merged

gHashTag merged 4 commits into
masterfrom
claude/hslm-int8-forward

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Closes #10875

What

specs/ml/train_hslm.t27 gets speed=4: speed 3's window with every forward ternary matmul done in integers.

  • tr4_matmul: each activation row gets one scale, s = max |x| / 127, and is rounded (half away from zero, clamped to +-127) to int8. A NaN or inf row maps to 0. The trits are transposed once per call (tiles of 81) into an i16 buffer so each output's dot runs along contiguous memory. The products add into sixteen independent i32 accumulators (one per j mod 16), then the output is float(acc) * s. |sum| <= 127 * 729 < 2^17, so the integer sum is exact in any order.
  • Backward: unchanged, speed 3's f64 code, on the activations this forward made.
  • Dispatch: ternary_matmul and tr3_matmul route speed 4 to tr4_matmul; the window functions use speed_level >= 3; cfg_speed % 4 becomes % 5. The default stays 2; speeds 0 to 3 are untouched.
  • Bound, proved in the spec comment: per output, |error| <= (max_j |x_j| / 254) * (nonzero trits in that column).

Edits are in section 1 (kernels), the window functions and the tests.

Evidence (Railway lab)

t27c test-report specs/ml/train_hslm.t27: 37 tests, 37 pass, 0 vacuous, after merging master (thread primitive, #10896). New tests:

test bound measured (tiny model, seed 5)
speed_four_keeps_every_int8_matmul_output_within_its_proven_bound (block 0 K, block 1 down, head; every output) ratio to bound <= 1, and > 0.05 0.2104
speed_four_logits_stay_within_two_percent_of_speed_two 2% relative 6.66e-3
speed_four_k_position_loss_stays_within_a_thousandth_of_speed_two 1e-3 2.6e-4
speed_four_gradients_stay_within_five_percent_of_speed_two 5% relative 1.0e-2 to 1.7e-2
speed_four_lab_loss_curves_stay_within_a_thousandth_of_speed_two_over_300_steps 1e-3, and the gap is > 0 and the loss falls > 0.25 valid gap 0.0004, train gap 0.0001
speed_four_lab_tok_s_and_its_speed_ups_follow_from_the_measured_times re-derives tok/s and speed-ups below

Loss curves: 300 steps, same seed, 13 samples each, recorded as constants (TR4_CURVE_*). Valid loss ends at 6.3336 (speed 4) vs 6.3340 (speed 2).

Throughput: ReleaseFast, loss_positions=27 steps=10 seed=1729, speeds 2, 3 and 4 started together on the 48-core lab (Xeon 6975P-C, load average 47-66 from other sessions).

speed tok/s train_s
2 271.5 65.63
3 422.3 42.20
4 548.6 32.48

Speed 4 is 2.021x speed 2 and 1.299x speed 3. A second run gave 66.46 / 44.94 / 34.15 s, speed-ups of the same size (the test checks it).

Negative controls: scaling the activations by m / 100 instead of m / 127 fails exactly the four numeric speed_four tests (bound, logits, loss, gradients) and nothing else. Moving one curve constant fails only the curve test.

Finding: with one i32 accumulator the Zig codegen reduces lanes every 8 products and gains nothing. Sixteen independent accumulators vectorize to vpmulld on zmm and give the speed-up above.

Seal: t27c seal specs/ml/train_hslm.t27 --save, then --verify, all hashes MATCH.

Threads

Master's thread primitive (#10896) made window scratch threadlocal; the speed-4 buffers (b4_q, b4_s, b4_wt) are threadlocal too. New test one_and_three_threads_give_one_step_the_same_bits_at_speed_4: the step digest at 1 and 3 threads is equal, nonzero and differs from speed 2's.

Merge note

Master was merged server-side (update-branch) because the pre-commit foreign-budget hook diffs the staged merge result against HEAD and so counts other authors' files from master; a local merge commit cannot pass it. The seal was restored to master's version first, then re-sealed on the lab after the merge (all hashes MATCH).

🤖 Generated with Claude Code

… error bounded against speed=2 (Closes #10875)

speed=4 is speed 3's window with every forward ternary matmul in integers:
activations rounded to int8 with one scale per row, trits transposed once per
call, sixteen independent i32 accumulators, output = acc * scale. The backward
stays speed 3's f64 code. Tests bound the kernel error (proved per-output
bound), logits, k-position loss and gradients against speed 2, and re-derive
the lab loss-curve gap and tok/s from recorded constants.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 06:41:01 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 46
PRs with All Checks Green 4
READY 2
FAILING 46
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 46 + 0 + 0 = 48, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=88b8cb73ceda != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag enabled auto-merge (squash) October 19, 2026 06:55
gHashTag added a commit that referenced this pull request Oct 19, 2026
) (#10913)

* ledger(t27b): rows for six specs master carries unlisted, max_not_pass 129 -> 130 (Closes #10912)

As the steward applies UNLISTED (specs/tri/t27b/ledger_steward.t27): four pass rows (mos_psp103_50c_data, sar_adc, sar_comparator_psp, tri/worktrees/reap) and two blocked rows, ExprCall(undeclared fn), reason unimplemented (eval_hslm, ngram_hslm -- the same blocker hslm_corpus already carries). Verdicts are the UNLISTED lines of the t27b runs of #10908, #10855, #10907 and #10836 on current master. Not-pass rows become 129 blocked + 1 codegen = 130, so the cap rises by one, within the two new non-pass rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ledger(t27b): drop the eval_hslm row, max_not_pass back to 129 (Closes #10912)

The PR's own t27b run reported eval_hslm.t27 STALE: on current master the reference no longer compiles it (undeclared identifier 'b3_q' after a train_hslm change), and the steward lists only what the reference passes. Five rows remain (four pass, ngram_hslm blocked); not-pass rows are 128 blocked + 1 codegen = 129, the cap master had.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag and others added 3 commits October 19, 2026 15:44
…flict-free (#10875)

The seal is regenerated on the lab in the next commit, after the merge.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…identical at 1 and 3 threads (#10875)

Master's thread primitive (#10896) makes window scratch threadlocal; the
speed-4 buffers b4_q, b4_s and b4_wt follow. New test checks the step digest
at 1 and 3 threads at speed 4, and that it differs from speed 2. Re-sealed on
the lab (37 tests, 0 vacuous, all hashes MATCH).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-19 09:06:37 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 47
PRs with All Checks Green 3
READY 2
FAILING 47
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 47 + 0 + 0 = 49, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=509db03c8f4d != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit c736177 into master Oct 19, 2026
31 of 37 checks passed
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.

spec(ml): train_hslm speed=4 -- int8 trit forward with one scale per row, error bounded against speed=2

1 participant