# ANE routes by expression, not arithmetic

A 64-shape primitive matrix and ANE counters reveal routing follows operation form, with a ~0.77 bytes-per-token law holding across fp16, int8, and 2-bit…

Canonical page: https://makerportal.ai/blog/on-device-ai-arxiv-260822110v1
Author: Joshua Hrisko, Principal Engineer — MakerPortal
Published: 2026-08-25
Section: Paper / On-Device AI · 6 min read
Tags: on-device-ai, metal-ane

---

The study establishes that ANE placement is governed by how a computation is expressed rather than what it computes, and that decode throughput follows a bytes-per-token bandwidth law (~0.77 × nominal encoding width) that holds across fp16, int8, and 2-bit precisions. What it does not establish: whether models optimised for ANE residency retain task accuracy relative to their fp16 counterparts at any of the tested parameter counts.

## Study design

Three measurement paths. A 64-shape matrix of LLM primitives varied the expression of each operation while holding its arithmetic output fixed, recording per-operation device placement. Matched models were trained across size and precision; their quantized checkpoints are byte-identical in structure to the fp16 counterparts, so placement comparisons don't carry confounds from graph restructuring. The third path is the ground truth: ANE memory-controller byte counters read during inference, capturing what actually executed on the engine rather than what the CoreML compiler reported as intended placement.

| What was measured | Compared against | Sample | Conditions |
|---|---|---|---|
| Per-operation ANE device placement | Arithmetically identical alternative expressions of the same operation | 64 expression shapes across LLM primitives | CoreML compiler; specific Apple chip generation not stated in source |
| ANE residency (% bytes through engine) and decode speed (ms/token) | Conv-heavy fp16 design at 25.85M parameters | 22.29M all-attention fp16; 25.85M conv-heavy in fp16, int8, 2-bit; 25M and 50M ternary variants | ANE memory-controller byte counters read during inference; serving batch size not stated in source |
| Bytes streamed per token | Nominal encoding width per precision | fp16, int8, 2-bit models | Measured via ANE memory-controller counters; hardware generation not stated in source |

For the result to transfer to your case, the following must hold: your target SoC shares the ANE generation used in the study (not stated in source); your model uses operations covered by the 64-shape primitive matrix; and your CoreML version compiles the same graph structures. None of these are verified externally.

## Results

**Placement is expression-sensitive, not arithmetic-sensitive.** A fused RMSNorm is fully ANE-eligible; its arithmetically identical decomposition routes entirely to CPU. The 64-shape matrix was built to isolate exactly this variable. The authors attribute the routing difference to the CoreML graph compiler responding to operation form rather than numerical equivalence.

**The conv-heavy fp16 design at 25.85M parameters receives zero ANE bytes.** Memory-controller counters confirm it. Quantizing the same graph to int8 or 2-bit returns ANE residency to approximately 83%, and under those conditions the decode speedup over the fp16 CPU-only baseline is 1.8–2.2×. The source does not state a minimum detectable effect size for the residency measurement. ~83% is a reported measurement, not a bound.

**Architecture determines fp16 residency independently of quantization.** The 22.29M all-attention fp16 model hits 98.9% ANE residency without quantization. The attribution goes to the all-attention architecture presenting a different operation mix to the compiler. No intermediate architecture is reported between 0% and 98.9%; the transition point is not established.

**Decode cost follows a single bandwidth law across tested precisions.** Bytes streamed per token land at approximately 0.77 of nominal encoding width, and that fraction is constant across fp16, int8, and 2-bit. No variance or confidence interval is stated in the source for this figure.

**25M ternary models cluster tightly in memory and latency.** Every 25M ternary model measured lands within 10.0–10.8 MB and 0.62–0.64 ms/token. The half-attention ternary at 25M: 10.5 MB, 0.63 ms/token. The 50M variant: 16.8 MB, 0.86 ms/token. Relative to the conv-heavy fp16 design the work began with, the 25M half-attention ternary is 9.8× smaller and 3.0× faster; the 50M is 6.1× smaller and 2.2× faster. These ratios are relative to one specific baseline. They describe nothing about speedups over other fp16 architectures.

<figure class="my-8 rounded-2xl border border-border bg-card-bg p-6" data-quantity-figure="comparison">
  <div class="flex items-center justify-between text-xs font-mono uppercase tracking-widest text-primary-cta">
    <span>Reported by 2608.22110</span>
    <span>x<span class="ml-2 sm:hidden">· scroll →</span></span>
  </div>
  <div class="mt-4 overflow-x-auto">
  <svg class="w-full min-w-[600px]" viewBox="0 0 600 216" role="img" aria-label="Figure: values as 2608.22110 reports them, drawn from the quantities this post cites. Bars are proportional within their shared unit; condition cells are exact values and are not scaled against one another. The studio has not re-measured them." xmlns="http://www.w3.org/2000/svg">
    <rect width="600" height="216" rx="12" fill="var(--mp-canvas, #0d0f12)"/>
    <text x="20" y="33" fill="var(--mp-text, #fff)" font-size="13" font-family="monospace"><tspan x="20">25M half-attention ternary</tspan><tspan x="20" dy="15">size reduction</tspan></text>
    <rect x="268" y="24" width="292" height="22" rx="4" fill="#1e40af" opacity="0.85"/>
    <text x="550" y="40" fill="#fff" font-size="12" font-family="monospace" text-anchor="end">9.8 x</text>
    <text x="20" y="79" fill="var(--mp-text, #fff)" font-size="13" font-family="monospace"><tspan x="20">50M half-attention ternary</tspan><tspan x="20" dy="15">size reduction</tspan></text>
    <rect x="268" y="70" width="182" height="22" rx="4" fill="#1d4ed8" opacity="0.85"/>
    <text x="440" y="86" fill="#fff" font-size="12" font-family="monospace" text-anchor="end">6.1 x</text>
    <text x="20" y="125" fill="var(--mp-text, #fff)" font-size="13" font-family="monospace"><tspan x="20">25M half-attention ternary</tspan><tspan x="20" dy="15">speedup</tspan></text>
    <rect x="268" y="116" width="89" height="22" rx="4" fill="#2563eb" opacity="0.85"/>
    <text x="367" y="132" fill="var(--mp-text, #fff)" font-size="12" font-family="monospace">3 x</text>
    <text x="20" y="171" fill="var(--mp-text, #fff)" font-size="13" font-family="monospace"><tspan x="20">50M half-attention ternary</tspan><tspan x="20" dy="15">speedup</tspan></text>
    <rect x="268" y="162" width="66" height="22" rx="4" fill="#3b82f6" opacity="0.85"/>
    <text x="344" y="178" fill="var(--mp-text, #fff)" font-size="12" font-family="monospace">2.2 x</text>
  </svg>
  </div>
  <div class="mt-5 border-t border-border/70 pt-4">
    <div class="flex items-center justify-between gap-3">
      <p class="text-[0.65rem] font-mono uppercase tracking-widest text-muted-text">Conditions around the comparison</p>
      <span class="shrink-0 font-mono text-[0.6rem] uppercase tracking-wider text-muted-text sm:hidden">scroll →</span>
    </div>
    <div class="mt-3 overflow-x-auto">
    <dl class="grid min-w-[600px] grid-cols-4 gap-px overflow-hidden rounded-xl border border-border bg-border">
      <div class="min-w-0 bg-card-bg p-4">
        <dd class="font-mono text-lg font-semibold text-primary-text">25.85M</dd>
        <dt class="mt-1.5 text-xs leading-5 text-muted-text">conv-heavy fp16 model parameter count</dt>
      </div>
      <div class="min-w-0 bg-card-bg p-4">
        <dd class="font-mono text-lg font-semibold text-primary-text">22.29M</dd>
        <dt class="mt-1.5 text-xs leading-5 text-muted-text">all-attention fp16 model parameter count</dt>
      </div>
      <div class="min-w-0 bg-card-bg p-4">
        <dd class="font-mono text-lg font-semibold text-primary-text">~83%</dd>
        <dt class="mt-1.5 text-xs leading-5 text-muted-text">conv-heavy int8/2-bit residency</dt>
      </div>
      <div class="min-w-0 bg-card-bg p-4">
        <dd class="font-mono text-lg font-semibold text-primary-text">~0.77</dd>
        <dt class="mt-1.5 text-xs leading-5 text-muted-text">bytes streamed per token fraction of nominal encoding width</dt>
      </div>
    </dl>
    </div>
  </div>
  <figcaption class="mt-3 text-xs leading-5 text-muted-text">Figure: values as 2608.22110 reports them, drawn from the quantities this post cites. Bars are proportional within their shared unit; condition cells are exact values and are not scaled against one another. The studio has not re-measured them.</figcaption>
</figure>

## Where results stop

**Hardware generation.** The specific Apple SoC is not stated in the source. ANE implementations differ across A-series and M-series generations; placement rules, compiler behaviour, and bandwidth characteristics may not transfer.

**Scale.** The largest model tested is 50M parameters. The bandwidth law and placement patterns are not established above that. Larger models simply weren't in scope.

**Task quality.** This is a measurement study of placement and decode speed. Whether ternary or 2-bit quantization at these parameter counts preserves accuracy on downstream tasks is not addressed. The study holds "what is computed" fixed at the arithmetic level, which is distinct from task-level equivalence.

**Precision coverage.** The ~0.77 fraction is measured across fp16, int8, and 2-bit. 4-bit is not included. The source does not state whether this was underpowered to test or simply not run.

**Primitive matrix coverage.** Operations outside the 64-shape matrix were neither tested nor cleared. The source does not enumerate which operations are absent.

**Null result note.** No arm in the supplied results is reported as finding no effect. The conv-heavy fp16 model's zero ANE residency is a finding, not a null. The study does not report any comparison that failed to detect a difference between conditions.

## What to do with this

If you are compiling LLMs for CoreML, the primary practical point is that compiler placement annotations and actual ANE byte traffic are not the same thing. The memory-controller counter approach is the ground-truth method here; any profiling tool that reports only "intended" device may misrepresent what executed. A conv-heavy fp16 model routing entirely to CPU with no placement telemetry? Quantizing to int8 or 2-bit is the first lever. It recovered ~83% residency in the authors' measurement.

The tight clustering of 25M ternary models (10.0–10.8 MB, 0.62–0.64 ms/token) suggests that at this parameter scale, weight encoding dominates architecture choice in reaching the ANE bandwidth floor. The [ANEForge 2.28× speculative decode result](/blog/biquadia-github-1267734215) reached a different optimisation axis on the same hardware class; the two measurement approaches are not directly comparable.

If your target is a different ANE generation, a parameter scale above 50M, or a precision not covered here, this study does not give you a number to use.

---

*Method: this note was drafted by us.anthropic.claude-sonnet-4-6 from a single source — the arXiv abstract for [2608.22110](http://arxiv.org/abs/2608.22110v1). The claims and quantities it worked from were extracted from that document by qwen/qwen3.8-27b. Before publication an automated gate re-checked every extracted claim against the source document (13 claim(s) and 17 quantity(ies) verified) and every claim-shaped number in the draft against that evidence (0 derived from it, no rows from our own tables were supplied to the draft). The studio has not re-run 2608.22110's benchmarks; figures attributed to it are its own.*

## Questions this note answers

### Does the 0.77 bandwidth fraction let me predict decode latency from model size?

The study reports ~0.77 as the ratio of bytes streamed per token to nominal encoding width, held constant across fp16, int8, and 2-bit. If you know nominal encoding width and ANE memory bandwidth for your SoC, the relationship holds as described — but the SoC bandwidth figure must come from your own measurements; the study does not supply it. The fraction applies only to the three precisions tested. 4-bit is not covered, and the source does not extend the claim there.

### Why does the all-attention fp16 model reach 98.9% residency while the conv-heavy fp16 model reaches 0%?

The attribution goes to the operation mix each architecture presents to the CoreML compiler. Conv-heavy graphs include operations that, in fp16 form, route to CPU; all-attention graphs do not trigger the same routing. The 64-shape matrix and matched model comparisons establish the pattern, but the exact operation or graph threshold responsible for the switch is not identified.

### Is ternary quantization distinct from 2-bit quantization in these measurements?

The study reports ternary models and 2-bit models as separate conditions. Ternary weights use three discrete values rather than arbitrary 2-bit integers, so the encoding and ANE mapping may differ even at the same nominal bit width. The tight ternary cluster (10.0–10.8 MB, 0.62–0.64 ms/token for all 25M ternary variants) is reported separately from the ~83% residency result for the conv-heavy graph in 2-bit. The source does not state whether those 2-bit models are also ternary.

### How do I verify what is actually running on the ANE versus CPU?

ANE memory-controller byte counters read during inference. That's the method the authors describe as establishing what actually ran rather than what the compiler intended. The source states the method but does not specify the API or tooling path used to access those counters. Xcode Instruments' CoreML performance template is the obvious candidate, but the study does not name it and this note does not supply that inference.
