Getting 50 GB/S Back from the Apple Neural Engine
TL;DR Highlight
Splitting 1 MiB ANE weight transfers lifted Llama 3.2 1B on M3 from 10 to 24.3 tok/s
Who Should Read
A developer running on-device LLMs on Apple M3 with ANEMLL who is puzzled by lower-than-expected token throughput
Core Mechanics
- 1 MiB multiples crash bandwidth
- On the M3 Neural Engine, DRAM weight streaming falls to 17–19 GB/s when per-core weight bytes are an integer multiple of 1 MiB.
- Normal throughput is 45–60 GB/s, and 7 of ANEMLL's 15 models are affected.
- D=2048 is far slower than D=2016
- On an M3 Air over 40 runs, D=2016 reached 44.5 GB/s while D=2048 reached 16.93 GB/s.
- Only address and size changed in the register file, and transfers still complete correctly, so it is a performance problem.
- Not core count, not address layout
- Latency was the same with 1 to 16 active cores, so the throttle exists at the per-core level.
- Randomly scrambling addresses gave medians of 31.37 vs 32.29 GB/s, which ruled out DRAM bank conflicts.
- 1 MiB per core triggers it for any D and N
- Sweeping D and N inversely to keep 1 MiB per core still gave 17 GB/s.
- 1 MiB is 0x4000 64-byte lines, and recovery happens within ±256 lines, which is one 16 KiB page.
Community Reactions
- Not all chips are affected
- A comment shared a link saying M1 and M5 Max are fine.
- Question about software fixes
- One commenter asked whether M3 users are stuck unless apps work around it.
- They found the 10 to 24 tok/s jump from a workaround remarkable.
- Is the RTL real or hypothetical
- A commenter asked whether the SystemVerilog is the author's guess or actual RTL source.
- Terminology objection
- Someone argued 'erratum' usually means a correction notice for a document, so it may not fit here.
How to Apply
- Compute per-core weight size and find 1 MiB multiples
- Today, calculate Cin×Cout×2 bytes÷16 for each projection and check for exact 1 MiB multiples.
- Llama 3.2 1B's 2048×8192 layers are examples.
- Split 1 MiB-multiple projections into several tasks
- At compile time, break any kernel DMA task that is 1 MiB per core into chunks of 512 KiB or less.
- The article splits Llama 3.2 1B into 4 chunks of 0.5 MiB per lane.
- Compare tok/s and GB/s before and after under equal conditions
- Alternate original and split runs on the same device and thermal state.
- Include a non-1 MiB layer as a control to confirm the effect.
- Use padding only when splitting is hard
- Moving the transfer size at least ±8 KiB (256 lines) from 1 MiB restores speed.
- It changes the computation graph, so try splitting first.
Try It
# Paste into Claude or ChatGPT (simplified version of the article's method: a model-size check)
I run LLMs on the Apple M3 Neural Engine. The ANE reads weights across 16 cores, and a reported issue slows DRAM reads to 17-19 GB/s when per-core weight bytes are an exact integer multiple of 1 MiB. Normal speed is 45-60 GB/s.
For the projection list below, compute bytes per core as (Cin × Cout × 2 ÷ 16). Tabulate the entries that are integer multiples of 1 MiB (1048576 bytes), and suggest how many chunks of 512 KiB or less to split each into.
{{projection list: name, Cin, Cout}}
Next: write a measurement plan to compare tok/s before and after splitting under identical conditions.Terminology
Related Papers
Mercury 3: Diffusion at scale
Scaling diffusion LLM 40x gives Mercury 3: 4–8x faster than speed-tier models, similar quality
Timestral: Mistral's time-series foundation models
A 209M time-series model ranks first on three benchmarks and runs on CPU.
DeepSeek V4.1 Flash 1017 (Max)
DeepSeek V4.1 Flash 1017 Max scores 45 on the Intelligence Index at 211 tok/s and $0.30 input.
If you don't run your own LLM proxy, how do you know whats going on?
Running your own LLM proxy shows which keys, models, and cache misses drive your usage.
DeepSeek: DeepSeek v4.1 Flash 1017
DeepSeek V4.1 Flash 1017: $0.05/M input, 1M context, built for agents
DeepSeek-v4.1-Flash-1017
DeepSeek V4.1 Flash minor update lifts coding and agent benchmarks while cutting run time and output length
Show HN: Llmspeed – feel how fast a local LLM runs before you buy the hardware