Decisions

Newest first. Long-form records live in docs/adr/.

Date Decision Why
2026-10-22 Exactness tests run on mx.cpu; GPU tests use ~1e-3 tolerance Measured on the M5 Pro: Metal fp32 matmul differs from float64 by ~1.4e-2 absolute on unit-variance 16-dim dot products (CPU: ~2e-6). A per-level vs full-sequence forward therefore differs by ~5e-4 on GPU purely from precision; on CPU it is exact.
2026-10-22 Character-level AR baseline with KV cache, same width/depth as generator Speed claims need a baseline measured on the same data and hardware; the paper's numbers are vs. diffusion LMs on GPUs.
2026-10-22 Synthetic TinyWorld grammar as the first corpus 15,360 sentences, automatically checkable (form + number agreement), held-out sentences measure generalisation vs. memorisation, no licensing or privacy questions.
2026-10-22 Character tokenizer, fixed length 32, levels 1,2,4,8,16,32, 128 codes per level Reconstruction accuracy is directly interpretable; levels divide the length so area pooling is exact.
2026-10-22 Contextual encoder (2 blocks) instead of upstream's lookup-only encoder With a lookup encoder, coarse codes can only average local embeddings; a contextual encoder lets level 0 carry sentence-level content. Listed as a modification in research/upstream-map.md.
2026-10-22 EMA codebook update applied after the optimiser step, from statistics returned by the loss function MLX value_and_grad is functional; in-place buffer mutation inside the traced loss is not an option.
2026-10-22 Dead-code restart on by default (restart_threshold=0.05) Small dataset, 128 codes per level; collapse risk is higher than upstream's.
2026-10-22 Resampling as precomputed dense matrices One batched matmul per level, no custom kernels; semantics pinned by tests to PyTorch's area and linear interpolation.
2026-10-22 Option A (native independent implementation) for v0 See adr/0001-native-independent-implementation.md.
2026-10-22 MIT license Dependencies are MIT (MLX) and BSD (NumPy); upstream is MIT and no upstream code is copied.
2026-10-22 Python 3.12.14 via mise, mlx==0.32.3 pinned via uv Same versions model-lab already uses on this machine: no new global installs.
2026-10-23 Learned level-0 sampler is one conv each way, codec lr 2e-4 A four-layer cascade and a single layer both diverged at lr 1e-3; upstream's own Sudoku codec (L = 89, prime) also uses a single layer.
2026-10-23 Keep the name ncm-mlx It says what the project is (an MLX implementation of NCM) and is what people would search for; a new name would only rename paths and docs.