Read the workspaceLLM/AGENTS.mdand the parentCoreProjects/AGENTS.md
first. Higher-level rules are authoritative; this file adds project-specific
rules only (and wins on DiffusionGemma-Lite-specific conflicts).
Quick checks (run before claiming work is done)#
bash
cd LLM/DiffusionGemma-Lite
python3 -m pytest -m "not gpu and not slow" # CPU-friendly suite
# GPU gates (CUDA required, A100 pod):
# python scripts/microbench_a100.py ; python scripts/step_time_a100.py ; python scripts/e2e_gpu_smoke.pyProject:LLM/DiffusionGemma-Lite/· Type: block-AR discrete
diffusion LM (uniform-state) · Scale: 343,516,160 params (~343.5M — NOT
the "~380M" of early planning docs; their table counted full-MHA K/V) ·
8.0B Chinchilla-optimal tokens · ~40–50 h on A100 80GB at 35–40% MFU (pending).
Stack: PyTorch only — no diffusion library, no custom CUDA, no Triton.
Hardware: A100 80GB (no offloading).
Architecture detail:DIFFUSION.mdis authoritative;docs/README.md
is the doc map; SDD rulings live in.superpowers/sdd/EXECUTION-PLAN-diffusiongemma-lite/progress.md.
1. What this model is (know cold)#
- Block-AR discrete diffusion. 256-token canvases denoised in parallel
from uniform noise (D3PM-style, cosine schedule), committed under the
unchanged-or-stronger rule, re-encoded into the KV cache; causal across
canvases, bidirectional within (models/mask.py:build_block_causal_mask). - x0 prediction. The loss is cross-entropy against the clean tokens —
the plan'sxtwording is a recorded typo (Ruling 19). The sampler's
logits are the x̂0 posterior. - Self-conditioning with zero-init equivalence (bit-exact at init,
atol=0, rtol=0):models/selfcond.py:SelfConditioning; the add happens
exactly once per path; the training pre-pass is detached (no second
gradient path). - Sampler invariants (SDD Rulings 15–17): finalized canvases re-encode
under the ALL-ONESmodels/mask.py:build_canvas_decode_mask(not the
superseded §2.5 "zero-mask" wording); the sampler redraws pure uniform
(q_sampleis train-time only); committed positions are never overwritten;
eval passestime_steps=SamplerConfig.n_diffusion_steps(not the model's
train-time 16). - GQA 16Q/4KV head_dim 64 · rope rotate-half (cached fp32 cos/sin tables) ·
FlexAttention fused path (attn_impl: "flex",models/mask.py:flex_block_causal_attention)
with an sdpa bool-mask fallback and an eager ground-truth twin
(models/mask.py:eager_block_causal_attention) — do not delete the "duplicate".
2. Hard rules#
- Pure PyTorch. No HuggingFace Trainer/Lightning, no diffusion
libraries, no custom CUDA/Triton kernels. The eager-vs-SDPA-vs-flex
attention branches and the eager CE reference
(models/diffusion.py:x0_ce_loss) are deliberate regression oracles —
never consolidate them away. - Never materialize full-vocab training logits. The production loss is
training/losses.py:chunked_x0_ce(andchunked_p_embedfor the
self-cond pre-pass);x0_ce_lossis the eager test reference only. At
micro_bs 8 / seq 4096 / V 50,257 the full fp32 logits tensor is ~6.6 GB. - Commit rule is monotone. A committed canvas position is never
overwritten; uncommitted positions redraw pure uniform. Do not "fix" the
sampler to overwrite confident-but-changed tokens without re-deriving the
DESIGN §2.5 posterior argument and updating the pinning tests. - Sampler ↔ single-shot equivalence is sacred. The KV-chained decode
must equal a fresh single-shot block-causal forward (fp64, bit-exact) —
tests/test_sampler.py::test_block_ar_chaining_matches_single_shot.
Any change to attention/KV plumbing re-runs this test. - Resume determinism. All train-time draws come from the per-micro-step
generator (training/pretrain.py:Pretrainer._step_rng); data order from
data/dataset.py:ShuffledRangeSampleroffsets. Never introduce global RNG
into the training step without updating the bitwise-resume test. - Shard-path contract: the data shim pins
LLM_DATA_ROOTto
data/pretrain_chinchilla(theshared_datapack stage runs as a
subprocess honoring only that env var) and consumers read
data/pretrain_chinchilla/shards/. Pinned by
tests/test_data.py::test_producer_consumer_shard_path_wiring. - Doc anchors. Docs cite code as
file.py:Symbol— never line numbers.
scripts/check_docs.py --coveragemust stay clean; stale docs fail CI
(see §4). - Concise comments only. Docstrings justify non-obvious code; no
comment-per-line narration; section banners ≤ 3 per file (house rule, as
in sibling Lites).
3. Numerical-stability rules#
- NaN guard: 5 consecutive NaN/Inf optimizer steps → rollback to the last
complete checkpoint (utils/checkpoint.py:CheckpointManager— a step is
resumable only when weights + optimizer + meta all exist). - Chunked-CE does fp32 logsumexp per chunk; loss combines via global lse.
Keep fp32 boundaries inside chunks; don't "simplify" to BF16 lse. - Bitwise-equality tests pin zero-init self-cond equivalence (fp64, atol=0)
and rope norm preservation — treat any relaxation as a regression. utils/memory.py:assert_fits_in_available_gpuraises before an
oversized run starts; a probe failure is logged, never silent.
4. Files#
models/—mask.py(masks + eager/SDPA paths),diffusion.py
(schedule, q_sample, eager loss),attention.py,selfcond.py,
time_embed.py,block.py,transformer.py(model +from_yaml).training/—losses.py(chunked-CE),pretrain.py(loop).data/—prepare_data.py(shared_data shim),dataset.py(ShardWindows).inference/—generate.py(sampler),evaluate.py(headline harness).utils/—checkpoint.py,logging.py,memory.py.scripts/— eval CLIs + docs tooling;docs/— concepts/guides/references
(docs/README.mdis the map;tests/test_doc_refs.pythe checker).DIFFUSION.md,README.md,SKILLS.md,pytest.ini,LICENSE.
5. Known caveats#
- No trained checkpoint yet. The 8.0B-token A100 run has not started;
GPU gates (MFU ≥ 33%, peak VRAM < 15 GB, wall-clock speedup vs AR, loss
parity) are pending the pod session (Task 15). - ~343.5M, not ~380M. Config filename and early docs say 380M; the
architecture pins 343,516,160. Don't "correct" one side without the other. - Tiny-model eval numbers are misleading.
tokens/forwardof fixed_T is
L/(T+1): at canvas 32, fixed_T32 < 1. Quote production-canvas numbers. - Adaptive stopping is inert on untrained weights (entropy never drops
below threshold); only meaningful post-training. - Eval
T ≤ 32stays within the time-embedding normalization range;
raisingeval_diffusion_stepsneeds the §4.3 normalization re-checked. - Phase-1–4 review minors deferred to the final whole-branch review are
tracked in the SDD ledger; consult it before "cleaning up" flagged spots.
6. Docs rule#
Docs ship with code; stale docs fail CI. Any change that adds, renames,
or removes a public symbol must update the docs citing it.
scripts/check_docs.py parses every file.py:Symbol anchor in docs/,
DIFFUSION.md, README.md, AGENTS.md, SKILLS.md and fails on unknown
files or symbols; --coverage additionally requires every public symbol in
models/, training/, data/, inference/, utils/ to be cited at least
once. tests/test_doc_refs.py runs the same gate under pytest.