Skip to content

magpie: §6.3 host-owned-cache decoder_step — ANE-safe + ~40% faster/step#78

Open
Alex-Wengg wants to merge 2 commits into
mainfrom
feat/magpie-decoder-step-ane-hostcache
Open

magpie: §6.3 host-owned-cache decoder_step — ANE-safe + ~40% faster/step#78
Alex-Wengg wants to merge 2 commits into
mainfrom
feat/magpie-decoder-step-ane-hostcache

Conversation

@Alex-Wengg

Copy link
Copy Markdown
Member

Follow-up to the top open item in models/tts/magpie/SWIFT_PORT_FINDINGS.md ("try rank-3 K/V + int32 position to unblock decoder_step on ANE"). Applies the Surgical Inference §6.3 boundary to the autoregressive decoder_step.

The change

The current decoder_step does two ANE-hostile things per the paper: an in-graph full-cache read-modify-write blend (new_k = kv_k*(1-mask) + k_new*mask) and runtime-position-driven mask compares (positions_range == position), ×12 layers. The §6.3 rewrite (HostCacheDecoderStep):

  • reads the past cache read-only, concatenates the current-step K/V, attends against a host-supplied additive mask, and outputs only the current-step K/V slice [1,1,H,D];
  • the host owns the cache append and the mask — no in-graph state write, no position compares.

This mirrors the falsification-ladder rung that compiled ANE-clean in the paper: cache reads + current-token update outputs are admissible; the in-graph state write is the cliff.

Results (M5 Pro, coremltools 9.0; random weights — ANE admission is structural)

Equivalence (torch fp32): max |Δlogits| across 8 decode steps = 9.5e-7 → pure restructuring, not a new model.

Graph CPU_AND_NE p50 Placement (device-assigned ops)
OLD (in-graph blend + pos compares) 10.2 ms 100% ANE (752/752)
NEW (§6.3 host-owned cache) 6.0 ms 100% ANE (555/555)
  1. The documented M2 ANECCompile -14 does not reproduce on M5 Pro — the current graph already runs 100% on the ANE here through the full incrementing-position loop. The block was older-compiler-specific.
  2. The §6.3 rewrite is ~40% faster/step anyway, still 100% ANE, fewer ops, and far smaller I/O (current-slice outputs vs the [1,512,12,64]×24 full-cache re-emit the old graph does every step — the ~19 MB cache-out PERF.md flags). Decode runs 50–200×/utterance, so this is a direct RTFx lever.

Scope

Proof-of-concept under experiments/ane_host_cache/ (no NeMo / gated download): proves ANE admission, placement, latency, and torch equivalence — not CoreML fp16 end-to-end parity with real weights or the Swift host-side plumbing. Productionizing = port the boundary into traceable_decoder_step.py/convert_decoder_step.py with real weights, move the cache append + mask into MagpieModelStore.swift, and validate audio parity.

Build artifacts + logs gitignored.

… 40% faster)

Follow-up to SWIFT_PORT_FINDINGS.md's open decoder_step ANE item. Applies
the Surgical Inference §6.3 boundary: no in-graph cache mutation, no
position-driven mask compares — reads past cache read-only, concatenates
current K/V, attends against a host-supplied mask, outputs only the
current-step K/V slice; host owns append + mask.

Results on M5 Pro (random weights; ANE admission is structural):
- torch equivalence to current graph: max |Δlogits| = 9.5e-7 over 8 steps
- NEW: 100% ANE (555 ops), CPU_AND_NE p50 6.0ms
- OLD: 100% ANE (752 ops), 10.2ms — and the documented M2 ANECCompile -14
  does NOT reproduce on M5 Pro (older-compiler-specific)
- ~40% faster/step + far smaller cache I/O (current-slice vs full-cache out)

Proof-of-concept (no NeMo/gated download); productionizing = port boundary
into traceable/convert + Swift host cache/mask + real-weight audio parity.
…he ANE blocker

exp_unroll.py reconverts the Trial-4a N=2 AR unroll with the §6.3 decoder
to find the real blocker. Result (M5 Pro, random weights):
- N=1 fused (decoder + LT sampler): 74% ANE, ~200 ops on CPU (the LT
  sampling tail: topk/cumsum/argmax/one-hot); CPU_AND_NE fails to bind.
- N=2: 71% ANE, same bind failure; CPU-only amortizes to 5.3ms/frame.

So §6.3 makes the decoder 100% ANE + 40% faster, but does NOT unblock
the unroll — the sampler does. Correct architecture is §6.3 decoder on
ANE (6.0ms) + host sampler (1.6ms), unfused. ~2.4x->3.0x RTFx is the
ANE ceiling; beating it needs an ANE-friendly sampler or frame-stacking
(retraining), neither a reconversion.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant