18982 Commits

Author SHA1 Message Date
Rocky
c46ec4734d fix(mlperf-edu): anomaly-ae-train model-size gate impossible to pass (#1937)
max_model_size_kb: 32 could never be satisfied by the reference model it
gates: AnomalyDetectionAE (640/784 -> 128x4 -> 8 -> 128x4 -> 640) has
~266K parameters -- matching this same file's own `params: 0.3M` -- which
is ~1.03MB at FP32 and ~260KB even fully INT8-quantized. A submitter who
trains exactly this reference model and reports the true model size would
automatically fail the size gate regardless of reconstruction quality.

Corrected the budget to 300KB, consistent with the file's own stated 0.3M
parameter count at 1 byte/param (INT8), the standard deployment target for
this suite's "microcontroller" framing.
2026-07-15 11:47:33 +02:00
Rocky
3cb000e780 fix(mlperf-edu): SLM decode metrics polluted by generate()'s internal prefill (#1935)
run_decode() measures prefill_latency with a standalone model() call, then
calls model.generate() separately without handing it the prefill's KV
cache. generate() therefore redoes its own prefill pass internally before
decoding, so generation_latency includes a second, redundant prefill on top
of the actual decode work -- understating output_tokens_per_sec and
inflating inter_token_latency_s, worse for longer contexts since prefill
cost grows with context length while decode_tokens stays small (8-16 by
default).

time_to_first_token_s also incorrectly added a full decode-step latency on
top of prefill_latency instead of just reporting prefill time.

Fixed by subtracting the already-measured prefill_latency from
generation_latency before computing decode-only metrics, and reporting
time_to_first_token_s as prefill_latency alone.
2026-07-15 11:47:29 +02:00
Farhan Asghar
a9039df6de a11y(shared): make subscribe modal a real dialog for keyboard and screen-reader users (#1948)
The subscribe modal (shared across the book, site, labs, kits, and
mlsysim subsites) was a plain div overlay:

- No role="dialog", aria-modal, or accessible name, so screen readers
  never announced it as a dialog and could wander into the page
  behind the overlay.
- No focus trap: Tab walked out of the modal into the visually hidden
  background page.
- Focus was never returned to the triggering element on close, dropping
  keyboard users at the top of the document.
- Open/close animations played regardless of prefers-reduced-motion.

Changes to the canonical shared/scripts/subscribe-modal.js:

- role="dialog" aria-modal="true" aria-labelledby on the container,
  with an id on the existing title.
- Tab/Shift+Tab now cycle within the modal's visible, enabled controls
  (computed per keypress, so the trap also works on the post-submit
  success view).
- The opener element is saved on openModal() and refocused on close.
- Animations are disabled under prefers-reduced-motion: reduce.

Mirrors regenerated with shared/scripts/sync-mirrors.sh (CI drift
check). Escape-to-close and overlay-click behavior unchanged.
2026-07-15 11:47:26 +02:00
Rocky
e027d8d1ee fix(tinytorch): unguarded accuracy_retention division crashes on zero baseline (#1954)
_calculate_improvements() guards latency/memory/energy division against
opt_metrics[metric] <= 0 with a documented "fallback to 1.0", but
accuracy_retention = opt_metrics['accuracy'] / base_metrics['accuracy']
had no such guard on the denominator. A baseline model with 0.0 accuracy
(a broken/failing baseline -- exactly the kind of input a benchmarking
suite should handle gracefully) raises ZeroDivisionError and crashes the
whole comparison, while the sibling metrics computed two lines above
degrade gracefully.

Added the same guard pattern already used for the other three metrics.
The function's own docstring already promised "Handle division by zero
with fallback to 1.0" as a general rule -- this fix makes the accuracy
branch actually honor it.

Verified: the old code raises ZeroDivisionError for
base_metrics={'accuracy': 0.0}; the fixed code returns
accuracy_retention=1.0 instead, and the normal (non-zero) case is
unaffected (0.6/0.5 = 1.2, unchanged).
2026-07-15 11:47:23 +02:00
Rocky
c7021f29cb fix(mlperf-edu): stop silently bypassing anti-cheat when mlperf CLI is missing (#1933)
_process_zip() ran `mlperf verify` as the only anti-cheat check, then caught
FileNotFoundError and silently passed through to grading the submission's
self-reported JSON metrics verbatim with "Cheating": "NO" -- meaning any
environment without the mlperf CLI on PATH (the common case for a bare
grading checkout) accepted hand-forged submissions with no verification at
all.

Reproduced: built a zip with forged metrics (accuracy 0.99, throughput
99999) and confirmed _process_zip() returned Status: VALIDATED,
Cheating: NO. Now it returns Status: VERIFY_UNAVAILABLE, Cheating:
UNVERIFIED and logs the failure instead of grading blind.
2026-07-15 11:47:18 +02:00
github-actions[bot]
3283c8aa20 docs: add @coyaSONG as contributor for bug, code, doc (instructors) instructors-v0.1.1 2026-07-15 09:09:44 +00:00
github-actions[bot]
bb89312236 docs: add @coyaSONG as contributor for doc (instructors) 2026-07-15 09:09:19 +00:00
coyaSONG
81ca75f92b Fix instructor lab links (issue #1810) (#1959) 2026-07-15 11:06:00 +02:00
Vijay Janapa Reddi
75c25583ee fix(vol1): correct camera-ready technical content 2026-07-15 06:37:14 +02:00
Vijay Janapa Reddi
e85f0262ea fix(vol1): correct camera-ready quizzes 2026-07-15 06:21:30 +02:00
github-actions[bot]
7515b33c3a Update contributors list [skip ci] 2026-07-12 15:51:50 +00:00
Vijay Janapa Reddi
852b59401b Format Vol1 Python blocks; fix Fig 7.6 caption widow; tighten Listing 6.7
Bring Vol1 display code blocks into Black display-70 compliance so the CI pre-commit pass makes no modifications. Tighten Listing 6.7 by putting the attention-scores comment on its own line above the single-line computation and dropping the redundant Core computational pattern comment. Trim the Figure 7.6 caption to pull utilization onto the previous line and remove a one-word widow. Shorten the training Step 3 comment to avoid a wrapped line.
vol1-pr1957-merged
2026-07-12 17:30:35 +02:00
Vijay Janapa Reddi
e4a2e40a82 Remove research-questions callouts, fix ml_ops cascade figure, standardize figure font
Builds on the PR #1957 merge (Zeljko's Vol1 layout), otherwise byte-for-byte his version:

- Remove the end-of-chapter research-questions callouts from all chapters.
- ml_ops correction-cascade figure: keep Zeljko's Model A-D chain TikZ drawing,
  and rewrite the caption, alt-text, and lead-in to describe the chain (they
  carried a stale 'timeline' description that no longer matched the figure),
  plus an operations-impact line.
- Standardize the matplotlib figure font on a bundled TeX Gyre Heros (a free,
  redistributable Helvetica-metric clone) registered at runtime in
  book/tools/figures/style.py, so figures render with a real bold identically
  on macOS, Linux, and CI instead of falling back to DejaVu Sans or an
  unreachable macOS .ttc bold face.
2026-07-12 15:29:07 +02:00
Vijay Janapa Reddi
5a5c195a8b Merge PR #1957: Finalize Volume I layout for full PDF draft
# Conflicts:
#	book/quarto/contents/vol1/ml_ops/ml_ops.qmd
2026-07-12 11:03:48 +02:00
Zeljko Hrcek
c926e57d91 Finalize Volume I layout for full PDF draft 2026-07-12 10:48:27 +02:00
github-actions[bot]
aba8eb197b Update contributors list [skip ci] 2026-07-10 22:03:33 +00:00
github-actions[bot]
cb086df960 docs: add @Shashank-Tripathi-07 as contributor for bug, code, doc (designgrammar) 2026-07-10 21:50:59 +00:00
github-actions[bot]
045895a30e docs: add @Shashank-Tripathi-07 as contributor for bug, code, test (designgrammar) 2026-07-10 21:50:46 +00:00
Vijay Janapa Reddi
e1e15702e6 Merge pull request #1911 from farhan523/fix/footer-hydration-utc
fix(staffml): format Footer build date in UTC to avoid hydration mismatch
2026-07-10 23:43:27 +02:00
Vijay Janapa Reddi
e7fbd500b1 Merge pull request #1912 from farhan523/fix/practice-stale-userAnswer
fix(staffml): keep practice-page Cmd+Enter handler fresh via latest-callback refs
2026-07-10 23:43:24 +02:00
Vijay Janapa Reddi
6b9bdaf724 Merge pull request #1913 from farhan523/fix/stargate-clear-verify-timeout
fix(staffml): cancel StarGate's verify-delay timer on unmount
2026-07-10 23:43:21 +02:00
Vijay Janapa Reddi
cb55316d7d Merge pull request #1931 from Shashank-Tripathi-07/fix/compliance-quality-target-lookup
fix(mlperf-edu): quality-target check silently skipped for real submissions
2026-07-10 23:43:19 +02:00
Vijay Janapa Reddi
5e29161632 Merge pull request #1932 from Shashank-Tripathi-07/fix/compliance-quick-check-vacuous-seed-check
fix(mlperf-edu): remove vacuous deterministic-seed check from quick_check_model
2026-07-10 23:43:16 +02:00
Vijay Janapa Reddi
eb9432374e Merge pull request #1934 from Shashank-Tripathi-07/fix/grader-csv-fieldnames-crash
fix(mlperf-edu): CSV leaderboard export crashes on mixed grade result shapes
2026-07-10 23:43:13 +02:00
Vijay Janapa Reddi
2d6a79f780 Merge pull request #1936 from Shashank-Tripathi-07/fix/nanogpt-decode-p99-percentile
fix(mlperf-edu): p99 decode-latency formula wrong for small sample counts
2026-07-10 23:43:11 +02:00
Vijay Janapa Reddi
7db5bcf3f3 Merge pull request #1938 from Shashank-Tripathi-07/fix/auto-trainer-plateau-history-reset
fix(mlperf-edu): plateau detection mixes losses across NAS attempts
2026-07-10 23:43:08 +02:00
Vijay Janapa Reddi
12684731dc Merge pull request #1939 from Shashank-Tripathi-07/fix/auto-trainer-load-failure-nameerror
fix(mlperf-edu): NameError masks real model-load failure in auto_trainer
2026-07-10 23:43:05 +02:00
Vijay Janapa Reddi
4890e230bb Merge pull request #1940 from Shashank-Tripathi-07/fix/assets-download-race-condition
fix(mlperf-edu): dataset download race on shared fixed temp filename
2026-07-10 23:43:02 +02:00
Vijay Janapa Reddi
b9acfd47db Merge pull request #1941 from Shashank-Tripathi-07/fix/design-grammar-rewrite-rules-validation
fix(design-grammar): rewrite-rules.yml was never validated at all
2026-07-10 23:43:00 +02:00
Vijay Janapa Reddi
81d1c69d0f Merge pull request #1943 from Shashank-Tripathi-07/fix/design-grammar-fc-sharding-symbol
fix(design-grammar): Fc incorrectly bundled into sharding's symbols
2026-07-10 23:42:57 +02:00
Vijay Janapa Reddi
a3e6bd7d27 Merge pull request #1942 from Shashank-Tripathi-07/fix/design-grammar-collision-notes
fix(design-grammar): known_collisions notes cite wrong (row, col) coordinates
2026-07-10 23:42:54 +02:00
Vijay Janapa Reddi
b2c7e582f5 Merge pull request #1946 from farhan523/fix/socratiq-incorrect-questions-store
fix(socratiq): correct IndexedDB store name and key in getIncorrectQuestions()
2026-07-10 23:42:52 +02:00
Vijay Janapa Reddi
6ca08f66b8 Merge pull request #1947 from farhan523/fix/sidebar-quiz-numbering-perf
perf(book): stop unbounded full-document rescans in quiz numbering fix
2026-07-10 23:42:49 +02:00
Vijay Janapa Reddi
ed535a7269 Merge pull request #1949 from farhan523/fix/allreduce-game-defects
fix(site): make All-Reduce Rhythm chunks animate, taps flash, and game clean up
2026-07-10 23:42:46 +02:00
Vijay Janapa Reddi
b017ad4d5a Merge pull request #1950 from Shashank-Tripathi-07/fix/nbgrader-notebook-overwrite
fix(tinytorch): nbgrader generate can silently overwrite a student's notebook
2026-07-10 23:42:43 +02:00
Vijay Janapa Reddi
0ec4233917 Merge pull request #1952 from Shashank-Tripathi-07/fix/submission-unbound-error-body
fix(tinytorch): UnboundLocalError when reading an HTTP error body fails
2026-07-10 23:42:41 +02:00
Vijay Janapa Reddi
74a2b82cca Merge pull request #1953 from Shashank-Tripathi-07/fix/memoization-cached-generation-missing-self-attention
fix(tinytorch): cached generation step excludes current token from self-attention
2026-07-10 23:42:38 +02:00
Vijay Janapa Reddi
842d5c3d11 Merge pull request #1955 from Shashank-Tripathi-07/fix/capstone-latency-zero-division
fix(tinytorch): capstone latency divisions crash on coarse timer resolution
2026-07-10 23:42:35 +02:00
github-actions[bot]
9e01d1fb41 Update contributors list [skip ci] 2026-07-10 16:48:15 +00:00
Vijay Janapa Reddi
34c3c72ec8 Merge remote-tracking branch 'origin/dev' into dev 2026-07-10 18:31:02 +02:00
Vijay Janapa Reddi
6109d117de Merge fix/sdc-figure-dedup: ml_ops correction-cascade figure + SDC photo dedup + orphan image cleanup 2026-07-10 18:27:29 +02:00
Vijay Janapa Reddi
e0760a3ec7 fix(figures): give ml_ops its own correction-cascade figure; dedup SDC photo
ml_ops "Correction Cascades" reused data_engineering's Sambasivan data-cascade
timeline under a wrong label (and no source credit). Replace it with a
purpose-built SVG showing the actual mechanism: a Model A->B->C->D correction
chain where an upstream change cascades downstream and forces every dependent
correction to be redone. Rewrite the lead-in, caption, and alt text to match,
matching the section's own "model A's outputs influence model B's training
data" framing.

fault_tolerance and robust_ai both rendered the same Jeff Dean SDC keynote
photo, and fault_tolerance captioned it as a "shuffle and merge database"
block diagram it never showed. Remove robust_ai's duplicate (folding the
Dean citation into prose) and correct fault_tolerance's caption + lead-in to
describe the photo that is actually there.
2026-07-10 18:24:49 +02:00
Vijay Janapa Reddi
d5ba6a5acf chore(images): remove 114 orphan duplicate images
Byte-duplicate image files that are referenced in zero .qmd files across the
book, mostly _-prefixed shelved hyphen/underscore name variants plus a few
unused placeholder and old cover exports. No rendered figure changes.
2026-07-10 18:24:28 +02:00
Rocky
49033c73f4 fix(tinytorch): capstone latency divisions crash on coarse timer resolution
benchmark_model()'s throughput_samples_per_sec (float(1000 / avg_latency))
and generate_submission()'s speedup (float(baseline_latency /
optimized_latency)) both divide by a latency measured with time.time()
around a single tiny forward pass, with no zero-guard. time.time() has
coarse resolution on Windows (commonly ~15.6ms); for a small model, a
fast forward pass can legitimately measure 0.0 elapsed time across all
runs, making avg_latency (and therefore optimized_latency downstream)
exactly 0.0 and raising ZeroDivisionError.

An existing test (line ~1347) asserts throughput_samples_per_sec > 0, and
another (line ~1564) asserts speedup > 0, so the fix floors each
denominator at a small epsilon (1e-6) rather than returning 0.0 or None --
both of which would fail those assertions and would also misrepresent an
immeasurably-fast result as zero throughput.

Verified: reproduced ZeroDivisionError for avg_latency=0.0 and
optimized_latency=0.0 with the old expressions; confirmed the floored
versions return large-but-finite positive numbers instead, and that
normal (non-zero) latency values are unaffected.
2026-07-08 01:48:44 +05:30
Rocky
267a53476f fix(tinytorch): cached generation step excludes current token from self-attention
_cached_generation_step() writes the new token's K/V into the cache via
update(), then calls cache_obj.get() and uses its result directly as
K_all/V_all for the attention computation. But KVCache.get() is designed
(and tested in test_unit_kvcache) to return only tokens already made
visible by advance() -- exactly NOT the token just written by update(),
since advance() is meant to run once per token after all layers finish.
So the new token's own K/V was never included in its own attention
computation, and on the very first generation step (cache empty, nothing
advanced yet), cache.get() returns a zero-length sequence, crashing the
matmul with "zero-size array to reduction operation maximum which has no
identity" -- cached generation was broken from the first token onward.

Fixed by concatenating the current step's own K_heads/V_heads (already
computed, no extra work needed) onto cache.get()'s history, instead of
using the cache's history alone.

Verified with a stub attention module (identity projections) against the
real KVCache: reproduced the crash with the old logic on the first
token (zero-length K/V from cache.get()), and confirmed the fixed
function produces the correct self-attention output ([1,0,0,0], the
token attending fully to itself) instead of crashing.
2026-07-08 01:43:26 +05:30
Rocky
a53c941dda fix(tinytorch): UnboundLocalError when reading an HTTP error body fails
In the HTTP-error handler, error_body was only assigned inside the try
block (e.read().decode('utf-8')). If that read/decode itself raised
(network hiccup mid-read, or a non-UTF-8 error body from the server), the
broad except (json.JSONDecodeError, Exception) still ran and referenced
error_body unconditionally, raising UnboundLocalError -- a confusing crash
in the middle of tito module complete's auto-sync step, instead of the
clean "Upload failed" message this code is trying to produce.

Initialize error_body = "" before the try, and only print it in the
except block when it's non-empty, so a read/decode failure degrades to
"nothing to print" instead of crashing.

Verified with two scenarios: (1) the read/decode call raising before
error_body is ever set -- old code crashed with UnboundLocalError, new
code handles it silently; (2) read succeeding but json.loads failing
(the normal case this except block exists for) -- both old and new code
correctly print the error body.
2026-07-08 01:39:30 +05:30
Rocky
2d0e5ac67c fix(tinytorch): nbgrader generate can silently overwrite a student's notebook
_ensure_module_notebook() regenerates modules/<name>/<name>.ipynb from
src/<name>.py whenever the source file's mtime is newer -- but that exact
path is the same notebook tito module start/resume open for students to
edit. A routine `git pull` that bumps a source file's mtime, followed by
an instructor running `tito nbgrader generate --all` on a shared checkout,
silently overwrote any student notebook whose file mtime was older, with
no backup and no warning beyond a benign "Source file is newer; converting"
message.

Fixed by never writing to the student-facing notebook path once it
exists: if it needs regenerating from a newer source, stage the fresh
conversion into a private .nbgrader_staging/ cache instead, and read from
there for nbgrader's own assignment staging. First-time creation (no
notebook yet) and the already-up-to-date case are unaffected.

Verified with three scenarios against the real _ensure_module_notebook
(jupytext call mocked, real file I/O): (1) notebook missing -> created
directly at the notebook path as before; (2) notebook up to date -> no
conversion happens at all, matching prior behavior; (3) notebook exists
but source is newer -> notebook content is left untouched, fresh content
is staged separately instead.
2026-07-08 01:35:43 +05:30
farhan
4924dbad53 fix(site): make All-Reduce Rhythm chunks animate, taps flash, and game clean up
Three defects in the All-Reduce Rhythm mini-game:

1. Gradient chunks never moved. tween() was called with a two-element
   array as the target and ["x","y"] as props, so the multi-prop
   branch assigned x/y onto the array itself instead of chunk.position.
   Chunks sat frozen at the source GPU for the whole beat, then burst
   at the destination — the ring-transfer visual (the point of the
   game) never rendered. Now uses tween(chunk, ["position.x",
   "position.y"], ...) like moe.mjs, and cancels the tween before
   destroying the chunk so the final tick can't touch a destroyed
   object.

2. Tap highlight was a no-op. The box was filled with COL.gpu and the
   'flash' set tint to 0xffffff — the identity tint — then 'reset' it
   to the same value. Pixi tints can only darken, so the box is now
   filled white and tinted down to COL.gpu at rest; the white tint on
   tap genuinely flashes it, and the reset restores COL.gpu.

3. No cleanup. Unlike sibling games (cluster.mjs, pipeline.mjs), the
   module registered an anonymous global keydown listener and returned
   no destroy(), stacking dead handlers and leaking a WebGL context on
   any remount without a page reload. The handler is now named and a
   destroy() matching the sibling convention removes it and destroys
   the Pixi app.

Rendering at rest is unchanged (white fill x COL.gpu tint equals the
previous flat fill). No scoring or timing logic touched.
2026-07-07 21:34:00 +05:00
farhan
854c60242d perf(book): stop unbounded full-document rescans in quiz numbering fix
sidebar-auto-collapse.js observed document.body (subtree) and scheduled
a fresh fixQuizNumbering() pass on every DOM mutation with no debounce.
Each pass ran a full-document querySelectorAll over all quiz callouts
and logged per element, so mutation bursts (Bootstrap collapses,
tooltips, math typesetting, SocratiQ) queued dozens of overlapping
full-page scans for the life of every book page. The pass also mutated
textContent, re-triggering the observer it runs under.

Changes:
- Mark processed callouts with data-quiz-number-fixed and exclude them
  from the selector, so repeat passes match nothing and are near-free.
  Callouts whose title element is not rendered yet stay unmarked, so
  the staggered retry passes still pick them up.
- Coalesce mutation bursts into a single debounced pass (one re-armed
  timer instead of one timer per mutation).
- Drop per-element console.log calls from fixQuizNumbering() and
  setNavbarActiveState() hot paths.

No behavior change: same numbering transform, same retry schedule,
dynamically injected callouts are still processed.
2026-07-07 21:21:28 +05:00
farhan
a979097c5a fix(socratiq): correct IndexedDB store name and key in getIncorrectQuestions()
updateIncorrectQuestions() writes incorrect quiz answers to the
'ongoingIncorrectQuestions' store (defined in db_configs_one.js) under
the fixed id 'current', but getIncorrectQuestions() read from a
non-existent 'ongoing-incorrect-questions' store and passed no key.
Opening a transaction on an undefined store throws NotFoundError, so
retrieval could never succeed.

Incorrect questions are recorded on every quiz submission today; this
makes that data actually retrievable and unblocks re-enabling the
'study past incorrect questions' feature (initiateStudyBtn, currently
commented out in index.js).

No bundle rebuild needed: the disabled feature is tree-shaken out of
book/quarto/tools/scripts/socratiQ/bundle.js, so output is unchanged.
2026-07-07 21:16:37 +05:00