Skip to content

train: flush the trailing partial grad-accum window - #8

Merged
dtch1997 merged 1 commit into
mainfrom
accum-flush
Jul 16, 2026
Merged

train: flush the trailing partial grad-accum window#8
dtch1997 merged 1 commit into
mainfrom
accum-flush

Conversation

@dtch1997

Copy link
Copy Markdown
Contributor

Fixes the tail-drop quirk flagged in #7.

The bug

total_steps = n_micro // grad_accum (floor) meant any trailing partial accumulation window ran backward() on its microbatches but never got an optimizer step — those examples silently contributed nothing. The worst case: a run with fewer microbatches than grad_accum (easy to hit in smoke configs) trained zero steps and returned an empty loss list.

The fix

total_steps uses ceil, and after the epoch loop a non-empty partial window is flushed: clip, step, scheduler step, loss appended. Gradient scaling stays the uniform 1/grad_accum, so the short window takes a proportionally smaller step rather than an up-weighted one — matching common practice for hand-rolled accumulation loops.

Reproducibility note

This intentionally changes training numerics relative to the banked lr3e-5_ep1 / lr1e-4_ep2 results whenever n_micro % grad_accum != 0: one extra small optimizer step and a one-step shift in the lr schedule. For the full config (2000 rows, batch 8, accum 4 → 250 microbatches) that's a 2-microbatch flush after 62 full steps — negligible, but a fresh run is no longer bit-identical to the banked ones.

Tests

  • test_partial_accum_window_flushes: 3 microbatches / accum 2 → 2 optimizer steps (was 1 + dropped tail).
  • test_run_shorter_than_one_window_still_trains: 1 microbatch / accum 4 → 1 step, and asserts the adapter's B matrices actually moved (this returned [] and trained nothing before the fix).

17 tests, all green locally; CI covers both ends of the peft range.

🤖 Generated with Claude Code

Floor division dropped any trailing partial accumulation window: its
microbatches ran backward() but the grads were never stepped. Worst case, a
run with fewer microbatches than grad_accum (tiny smoke runs) trained ZERO
steps and returned []. Now total_steps uses ceil and the partial window is
flushed after the loop, keeping the uniform 1/grad_accum grad scaling (the
short window takes a proportionally smaller step, matching common practice).

NB: changes training numerics slightly vs the banked lr3e-5_ep1 /
lr1e-4_ep2 runs whenever n_micro % grad_accum != 0 — one extra (small)
optimizer step and a one-step shift in the lr schedule.

Tests: partial-window flush now expects the extra step; new test pins the
shorter-than-one-window case (1 microbatch, grad_accum=4 -> 1 step, adapter
actually moves).

Co-Authored-By: Claude Fable 5 <[email protected]>
@dtch1997
dtch1997 merged commit bc2d9b1 into main Jul 16, 2026
2 checks passed
@dtch1997
dtch1997 deleted the accum-flush branch July 16, 2026 20:40
dtch1997 added a commit that referenced this pull request Jul 17, 2026
Full pipeline re-run on main (post PRs #6/#7/#8) — all six reproduction
criteria pass. Fresh summary/ia_validation/figures + REPRO.md committed.

Verdict: REPRODUCED

Co-authored-by: dtch1997 <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
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