01 — Sprint Cadence¶
One rhythm to rule the 13 months. Two weeks. One deliverable. One retro. No exceptions.
The claim¶
You are not building a “study plan”. You are running 26 back-to-back 2-week sprints for 13 months. Each sprint produces one named artifact. Each sprint ends with a written retro. Everything else — phases, projects, reading — hangs off this scaffolding.
Why 2 weeks? Because 1 week is too short to ship anything non-trivial in kernel/inference work, and 4 weeks is long enough for you to drift for 3 of them and cram the last one. Two weeks is the goldilocks zone that keeps pressure honest without turning into a death march.
Skipping the retro is the first sign of drift. Not the last. The first. When you notice you “didn’t get to it this weekend”, stop. That’s the smoke alarm. Read 06_failure_modes.md and diagnose before you write another line of code.
The sprint template¶
Copy this into every sprint folder. One folder per sprint, named sprint_NN_YYYYMMDD/ inside the relevant phase directory.
sprint_NN_YYYYMMDD/
├── 00_plan.md # Monday morning
├── 01_midcheck.md # Wednesday of week 2
├── 02_deliverable/ # the actual artifact (code, benchmark, writeup)
├── 03_retro.md # Monday morning of next sprint
└── lab_notes/ # experiments during the sprint (see 02_lab_notebook.md)
00_plan.md — Monday morning of Week 1 (30 min)¶
# Sprint NN Plan — [YYYY-MM-DD to YYYY-MM-DD]
## Deliverable (one, named, testable)
> e.g. "Triton FlashAttention-2 forward within 2x of official flash-attn on seq=2048, head=64"
## Definition of done
- [ ] Numerics match torch.nn.functional.scaled_dot_product_attention within 1e-3
- [ ] Benchmark script committed at `bench/fa2_triton.py`
- [ ] p50/p95/p99 reported at seq ∈ {512, 1024, 2048, 4096}
- [ ] 400-word writeup in `deliverable/README.md`
## Predicted numbers (do this BEFORE any coding)
- Expected achieved TFLOPs: ~??? (arithmetic in lab_notes/day1_prediction.md)
- Expected memory: ???
- Expected gap vs official: ???
## Risk / unknown
- The reshape-for-tensor-core trick — haven't done this before
- Autotune config space — might blow up compile time
## Hours budget
- Weekdays: 10h (2h/day)
- Weekend: 6h
- Buffer: 4h
- Total: 20h
01_midcheck.md — Wednesday of Week 2 (15 min)¶
# Mid-sprint check — [date]
## Where I actually am
- Kernel compiles and runs
- Numerics off by 4% at seq=4096 — suspect softmax stability
## Where I planned to be
- Numerics correct, moving to perf tuning
## Delta
- ~2 days behind on the numerics debug
## Decision (pick one, write it down)
- [ ] On track — continue
- [x] Slightly behind — cut autotune scope, ship with fixed config
- [ ] Off the rails — read "when a sprint slips" section below
The mid-check exists because humans are terrible at estimating and excellent at rationalizing. Wednesday of week 2 is the last honest moment to cut scope without it becoming a lie.
Friday Week 2 — Deliverable Freeze (evening)¶
By Friday 9pm, the deliverable is frozen. No more features. Weekend is for:
Writing the deliverable README (400 words, structure in
05_teach_to_learn.md)Running the final benchmark on a locked-clock, warmed-up GPU
Committing everything to git with a signed tag:
sprint-NN-doneNothing else. No “one more optimization.” No.
The freeze rule is non-negotiable. It exists because ML/systems work is a bottomless well of “one more thing”. You will always be able to think of one more thing. The bottom of the well is at the bottom of your grave.
03_retro.md — Monday morning of Week 3 (30 min)¶
# Sprint NN Retro — [date]
## What I measured
- Achieved 178 TFLOPs on 3090, 61% of peak FP16 tensor
- p99 latency at seq=2048: 4.2 ms
## What I predicted
- Predicted 220 TFLOPs (75% of peak) — was too optimistic
- Predicted 3.1 ms p99 — was optimistic
## The gap (this is the whole point)
- Missed the register-pressure ceiling; my inner tile was too big
- Explanation lives in lab_notes/day8_regs_bound.md
- Lesson: for RTX 3090 (Ampere, 65k regs/SM), tile must be ≤ 128x128 for head=64
## What surprised me
- Triton autotune picked a smaller BLOCK_M than I would have
## What I'd tell past-me on Monday of Week 1
- Do the register-pressure calculation before touching the kernel
## Next sprint's candidate
- Extend to backward pass, OR
- Move to Phase 4 (engine internals) — exit criteria for Phase 3 met?
The retro is not for the reader. The retro is for you, six months from now, when you’re stuck on a similar problem and can grep your notes.
Weekly cadence inside a sprint¶
Week 1
Mon: Plan (00_plan.md) + first prediction
Tue: Deepest technical day — the hard bit goes here
Wed: Continue building
Thu: Continue building
Fri: Buffer / re-plan if slipping
Sat: Build (3-4h max, then stop)
Sun: REST or light reading only (see 08_health_burnout.md)
Week 2
Mon: Build
Tue: Build
Wed: MID-CHECK (01_midcheck.md) — decide honestly
Thu: Ship-mode: only what's on the DoD
Fri: DELIVERABLE FREEZE by 9pm
Sat: Writeup + final benchmark
Sun: Publish (see 05_teach_to_learn.md) + rest
Sunday is not a work day. Say it out loud. Sunday is not a work day. You will violate this and I’m not going to pretend you won’t, but every Sunday you take back the compounding is real. See 08_health_burnout.md.
When a sprint slips (and it will)¶
Slippage is fine. Silent slippage is fatal. The rule:
Never carry over silently. Either extend explicitly or cut scope and log it.
Three legal responses when Wednesday-of-week-2 shows you’re behind:
Cut scope. Rewrite the DoD. Ship the smaller thing on time. Write in the retro: “Cut backward pass to fit the sprint; carrying to sprint N+1 explicitly.” This is the default. Choose this 80% of the time.
Extend by exactly one week. Only if the artifact is genuinely one week from done and cutting it would make it useless (e.g. a benchmark without the comparison arm is meaningless). Log the extension. Never extend a sprint twice. If you’d extend twice, you’re actually cutting scope and lying to yourself — go to option 1.
Abort. Kill the sprint, write an honest retro about why it was mis-scoped, start a new sprint Monday with a smaller target. Rare but healthy. Better than a fake shipment.
The illegal response is: “I’ll just work through the weekend and finish it Sunday night.” You will do this once, twice, maybe five times. Each time it works you’ll trust it more. Around month 6 it stops working, and now you have a habit that’s cost you sleep, health, and the retro discipline. Don’t start.
Sprint counter (26 total)¶
Print this. Tick each one when the retro is written (not when the code ships).
Phase 1 Foundations [ ][ ] sprints 1-2
Phase 2 Transformers [ ][ ][ ] sprints 3-5
Phase 3 GPU Kernels [ ][ ][ ][ ][ ] sprints 6-10
Phase 4 Attention [ ][ ][ ] sprints 11-13
Phase 5 Engines [ ][ ][ ][ ] sprints 14-17
Phase 6 Quant [ ][ ][ ] sprints 18-20
Phase 7 Distributed [ ][ ][ ] sprints 21-23
Phase 8 Production [ ][ ][ ] sprints 24-26
Adjust the split to match your actual phase folders. The point is the count: you get 26 shots. Every one you fake costs you one you can never take back.
The one law¶
A sprint without a written retro did not happen.
The code, the benchmarks, the artifact — all of it. If the retro isn’t in git by Monday of the next sprint, that sprint is uncounted. Not because I’m punishing you — because the retro is the compounding. Everything else is just typing.
Write the retro even when you don’t want to. Especially when you don’t want to. That’s the whole game.