Skip to content

perf(model): batched causal-mask native_train_step (~10.75x), gradient-checked#669

Merged
InauguralPhysicist merged 1 commit into
mainfrom
perf/native-train-batched
Jul 18, 2026
Merged

perf(model): batched causal-mask native_train_step (~10.75x), gradient-checked#669
InauguralPhysicist merged 1 commit into
mainfrom
perf/native-train-batched

Conversation

@InauguralPhysicist

Copy link
Copy Markdown
Collaborator

The transformer trainer native_train_step — the model-extension kernel iLambdaAi's ~24-hour training runs on — re-ran a full forward+backward over the growing prefix for every target position in each window: ~31 nested passes over prefixes of length 1…31 per 32-token window.

The attention is causal (model_infer.c masks j > i), so each position's activations are independent of prefix length — all 31 passes recompute identical work. Standard transformer training does all positions in one causal-masked pass.

Fix

One causal-masked forward over the whole window + a cheap per-position loss/seed loop + one backward. Same forward/backward kernels, called once instead of seq times. Gradient-identical, because every position already trains against the same start-of-step weights, so the masked batch computes the identical summed gradient.

Measured

EIGS_TRAIN_PROFILE, d=32/L=4 model:

per-position batched
ms/window 179 16.65
speedup 10.75×
~24h run ~2.2h

The profiler showed 97% of the old cost was the redundant forward+backward compute (3% alloc/update), so the win is realized, not eaten by overhead.

Verified against its own oracle

The per-position path is the gradient-check oracle. From a common checkpoint, both paths produce float-identical, non-diverging loss sequences — and that's the decisive test, because a real gradient error compounds exponentially and would visibly diverge within a few steps. It doesn't.

  • EIGS_TRAIN_PERPOS=1 restores the oracle path.
  • New test_native_train_gradcheck.sh (suite [47c], model build): tiny model, six steps each path, asserts max loss diff < 1e-3 — pins the two paths together so the equivalence can't silently regress.

Gates

  • Full http+model suite 3164/3164 (includes [47c])
  • Default (non-model) build unaffectedmodel_train.c isn't compiled there, so the standard suite and ASan legs are untouched
  • Gated profiler (EIGS_TRAIN_PROFILE) kept as the A/B instrument, zero-cost off

Note: this makes the search for a working iLambdaAi model ~10× cheaper per experiment — the point is A/B iteration speed, not a faster working model (there isn't one yet).

🤖 Generated with Claude Code

…t-checked

The transformer trainer (native_train_step, model extension — the iLambdaAi
24-hour training kernel) re-ran a FULL forward+backward over the growing prefix
for every target position in each window: ~31 nested passes over prefixes of
length 1..31 per 32-token window. Since the attention is causal (model_infer.c
masks j>i), each position's activations are independent of how long the prefix
is, so all 31 passes recompute identical work.

Replaced with one causal-masked forward over the whole window + a cheap
per-position loss/seed loop + one backward. Same backward/forward kernels,
called once instead of seq times. Gradient-identical: every position already
trains against the same start-of-step weights, so the masked batch computes the
identical summed gradient.

Measured (d=32/L=4, EIGS_TRAIN_PROFILE): 179 -> 16.65 ms/window = 10.75x,
turning a ~24h run into ~2.2h. Profiler confirmed 97% of the old cost was the
redundant forward+backward compute (3% alloc), so the win is realized, not
eaten by overhead.

Verified against the per-position path as its own gradient-check oracle:
identical loss sequences to float precision from a common checkpoint (a real
gradient error compounds exponentially and would diverge within a few steps;
instead the sequences stay float-identical and non-diverging). Locked in by
test_native_train_gradcheck.sh (suite [47c], model build): a tiny model, six
steps each path, max loss diff must stay < 1e-3.

Dispatch: batched is the default; EIGS_TRAIN_PERPOS=1 restores the oracle.
Gated profiler (EIGS_TRAIN_PROFILE) kept as the A/B measurement instrument,
zero-cost when off.

Full http+model suite 3164/3164. Default (non-model) build unaffected —
model_train.c is not compiled there.
@InauguralPhysicist
InauguralPhysicist merged commit 49c9d29 into main Jul 18, 2026
18 checks passed
@InauguralPhysicist
InauguralPhysicist deleted the perf/native-train-batched branch July 18, 2026 09:09
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