Most inference engines carry one big file per architecture. coco reduces every model to a config row plus a single pluggable per-layer seam — so supporting a new architecture is an afternoon, not a rewrite.
One seam, many mixers
Modern architectures only really differ in how they mix information between tokens. In coco everything else is generic code written once; the only swappable part is a SequenceMixer — a plug where any attention variant fits. Three fit today, dispatched per layer:
✓ What works today
- 4 architectures end-to-end: Qwen2, Qwen3, Qwen3-MoE, DeepSeek V2/V3 (MLA)
- turboquant: pure-Rust, data-free 3-bit — 3.15× smaller, byte-for-byte identical output
- Weights stay GPU-resident & compressed; fused Metal kernels decode in-register
- GatedDeltaNet oracle-validated to 1.8e-7
⚠ Honest gaps
- Qwen3.5 recognized but not runnable yet (per-layer dispatch WIP)
- Speed wins are short-context only (prefill still O(n²))
- MLA runs the candle fallback (no fused kernel yet)
- Thin test coverage — a real ≥1200-case suite (overflow + security) is planned, not written
turboquant fidelity (Qwen2.5-1.5B, vs fp16)
Compression only counts if the model still behaves. Whole model 2944 → 934 MB (3.15×), and the output is byte-for-byte identical to fp16 on the checked cases.
Try it
git clone https://github.com/KikoCis/coco
cd coco && cargo build --release
cargo run --release --bin gdn_ref # validate the GatedDeltaNet port vs its oracle
Read the story
coco is written up, for humans, on the Bitácora — the design decisions, the wins, and the honest dead-ends, each with interactive demos:
- Every new AI model breaks the tooling. I built an engine that shrugs it off.
- How I ported a new kind of "attention" to Rust without missing a single decimal
- Shrinking an AI model 3× with no data and no quality loss
- Why a 3 GB model runs faster than a 14 GB one (and when it stops)
- The GPU trick: multiplying straight from compressed data, without unpacking it
- I optimized the GPU and it came out 20× slower. The lesson.
- When the honest thing is for your program to say "not yet"
