Edge Inference — Apple Neural Engine, Qualcomm Hexagon, WebGPU/WebLLM, Jetson
The core edge constraint is memory bandwidth, not compute. Mobile DRAM sits at 50-90 GB/s and datacenter HBM3 clears 2-3 TB/s, a 30-50x gap, and because decode is memory-bound that gap decides throughput. In 2026 the landscape splits four ways. Apple M4/A18 Neural Engine peaks at 38 TOPS with unified memory (no CPU↔NPU copy). Qualcomm Snapdragon X Elite / 8 Gen 4 Hexagon hits 45 TOPS. WebGPU + WebLLM runs Llama 3.1 8B (Q4) at ~41 tok/s on M3 Max (roughly 70-80% of native), with 17.6k GitHub stars, an OpenAI-compatible API, and ~70-75% mobile coverage. NVIDIA Jetson Orin Nano Super (8GB) fits Llama 3.2 3B / Phi-3, AGX Orin runs gpt-oss-20b via vLLM at ~40 tok/s, and Jetson T4000 (JetPack 7.1) is 2x AGX Orin. TensorRT Edge-LLM supports EAGLE-3, NVFP4, and chunked prefill, and was shown at CES 2026 by Bosch, ThunderSoft, and MediaTek.
Learning Objectives
- Explain why mobile LLM inference is memory-bandwidth-bound and compute is secondary.
- Enumerate the four edge targets (Apple ANE, Qualcomm Hexagon, WebGPU/WebLLM, NVIDIA Jetson) and match each to a use case.
- Name the 2026 WebGPU coverage gap (Firefox Android catching up) and the Safari iOS 26 landing.
- Pick a quantization format per target (Core ML INT4 + FP16 for ANE, QNN INT8/INT4 for Hexagon, WebGPU Q4 for browser, NVFP4 for Jetson Thor).
The Problem
A customer wants an on-device chatbot: voice-first, private by default, works offline. On a MacBook Pro M3 Max, Llama 3.1 8B Q4 runs at ~55 tok/s, which is fine. On an iPhone 16 Pro the same model runs at 3 tok/s, which is not. A mid-range Android with Snapdragon 8 Gen 3 gets 7 tok/s. In the browser via WebGPU on Chrome Android v121+, expect 4-8 tok/s depending on the device.
The variance is not a porting issue. It comes from the bandwidth gap, the quantization format, and whether the NPU is reachable from user-space at all. Edge inference in 2026 is four different problems with four different solutions.
The Concept
Bandwidth is the real ceiling
Decode reads the full set of weights for every token. A 7B model in Q4 is 3.5 GB. Reading 3.5 GB at 50 GB/s takes 70 ms, which caps you at ~14 tok/s. At 90 GB/s (high-end mobile DRAM) the cap moves to ~25 tok/s. Faster compute does not lift it.
Datacenter HBM3 at 3 TB/s clears the same 3.5 GB in 1.2 ms, a ceiling of 830 tok/s. Same model, same weights, different memory subsystem.
Apple Neural Engine (M4 / A18)
- Up to 38 TOPS. Unified memory (CPU and ANE share the same pool), so there is no copy overhead.
- Access via Core ML +
.mlmodelcompiled models, or via Metal Performance Shaders (MPS) through PyTorch. - The llama.cpp Metal backend uses MPS, not the ANE directly. Native ANE use requires Core ML conversion.
- Best practical path for iOS apps in 2026: Core ML with INT4 weights + FP16 activations.
Qualcomm Hexagon (Snapdragon X Elite / 8 Gen 4)
- Up to 45 TOPS. Integrated with CPU and GPU in the SoC but separate memory domain.
- QNN (Qualcomm Neural Network) SDK and AI Hub provide conversion from PyTorch/ONNX.
- Chat templates, Llama 3.2, Phi-3 all ship as first-class artifacts on AI Hub.
Intel / AMD NPUs (Lunar Lake, Ryzen AI 300)
- 40-50 TOPS. Software lags behind Apple/Qualcomm; OpenVINO is improving but niche.
- Best for Windows ARM copilot apps; native on AMD/Intel desktops for local-first.
WebGPU + WebLLM
- Run models in the browser via WebGPU compute shaders, with no install.
- Llama 3.1 8B Q4 at ~41 tok/s on M3 Max, roughly 70-80% of native via the same backend.
- 17.6k GitHub stars on WebLLM; OpenAI-compatible JS API; Apache 2.0.
- 2026 coverage: Chrome Android v121+, Safari iOS 26 GA, Firefox Android still catching up. Overall ~70-75% mobile coverage.
NVIDIA Jetson family
- Orin Nano Super (8GB): fits Llama 3.2 3B, Phi-3 at good tok/s.
- AGX Orin: runs gpt-oss-20b via vLLM at ~40 tok/s.
- Thor / T4000 (JetPack 7.1): 2x AGX Orin performance, EAGLE-3 and NVFP4 supported.
- TensorRT Edge-LLM (2026) supports EAGLE-3 speculative decoding, NVFP4 weights, and chunked prefill. These are the datacenter optimizations ported to edge.
Quantization choice per target
| Target | Format | Notes |
|---|---|---|
| Apple ANE | INT4 weights + FP16 activations | Core ML conversion path |
| Qualcomm Hexagon | QNN INT8 / INT4 | AI Hub converters |
| WebGPU / WebLLM | Q4 MLC (q4f16_1) | Use mlc_llm convert_weight + compiled .wasm; GGUF is not supported |
| Jetson Orin Nano | Q4 GGUF or TRT-LLM INT4 | Memory-bound |
| Jetson AGX / Thor | NVFP4 + FP8 KV | Edge-LLM path |
The long-context trap on edge
Llama 3.1's 128K context is a datacenter feature. On a phone with 8 GB RAM, 4 GB model + 2 GB KV cache for 32K tokens + OS overhead = OOM. Edge deployments keep context at 4K-8K unless you accept aggressive KV quantization (Q4 KV).
Voice is the killer app
Voice agents are latency-sensitive (first token < 500 ms), and local inference removes the network round trip from that budget. Pair it with speech-to-text (Whisper Turbo variants run on edge) and you have a production-quality voice loop.
Numbers you should remember
- Apple M4 / A18 ANE: 38 TOPS.
- Qualcomm Hexagon SD X Elite: 45 TOPS.
- WebLLM M3 Max: ~41 tok/s on Llama 3.1 8B Q4.
- AGX Orin: ~40 tok/s on gpt-oss-20b via vLLM.
- Datacenter-edge bandwidth gap: 30-50x.
- WebGPU mobile coverage: ~70-75% (Firefox Android lagging).
Use It
code/main.py computes theoretical decode throughput ceilings from bandwidth-bound math across nine edge targets, using Llama 3.1 8B Q4 at 4.7 GB. It prints each ceiling next to an observed benchmark and an efficiency percentage, then reruns the math on an iPhone 16 for BF16, INT8, Q4, and Q3 weights. Where observed throughput sits far below the ceiling, the runtime is the problem. Where it sits near the ceiling, bandwidth is.
Ship It
This lesson produces outputs/skill-edge-target-picker.md. Given platform (iOS/Android/browser/Jetson), model, and latency/memory budget, picks a quantization format and conversion pipeline.
I'd run main.py and read the efficiency column before anything else. The ceiling is just model_gb / bandwidth_gb_s inverted, so the interesting part is how far each target lands below it. The H100 row is lowest at 24%, then WebGPU on Pixel 9 at 37%, Snapdragon 8 Gen 3 at 43%, and WebGPU on M3 Max at 48%. For the browser and Android rows I'd look at the runtime before blaming the hardware.
Don't take the table as measured truth. The Jetson AGX Orin row prints 103%, which is above its own ceiling, so one of the bandwidth or observed figures is loose. The script also prices only the weights. It ignores the KV cache, which is the same blind spot the long-context section describes, so on a phone the real ceiling at 4K or 8K context is lower than what it prints.
One mismatch to watch for: the script uses an 8B model at 4.7 GB, while the worked example in the concept section uses a 7B at 3.5 GB. Both are Q4, and the arithmetic is the same. My bet is that the quantization loop at the bottom is the most useful output, because it shows on one device how much of the ceiling you buy back by shrinking the weights.
Exercises
- Run
code/main.py. For a 7B model in Q4 on a Snapdragon 8 Gen 3 (~77 GB/s bandwidth), compute the decode ceiling. Compare to observed 6-8 tok/s. Is the runtime efficient? - WebGPU on Android requires Chrome v121+. Design a fallback for older browsers: server-side via the same OpenAI-compatible API.
- Your iOS app needs 4K-context streaming. Which model/format combination lets you stay under 4 GB active memory on an iPhone 16?
- Jetson AGX Orin runs gpt-oss-20b at 40 tok/s. Jetson Nano fits only a 3B. If your product targets both, how do you unify the inference stack?
- Argue whether "WebLLM is production-ready in 2026." Cite the coverage, performance, and the Firefox Android gap.
Key Terms
| Term | What people say | What it actually means |
|---|---|---|
| ANE | "Apple neural engine" | On-device NPU in M-series and A-series; unified memory |
| Hexagon | "Qualcomm NPU" | Snapdragon NPU; QNN SDK for access |
| WebGPU | "browser GPU" | W3C-standardized browser GPU API; Chrome/Safari 2026 |
| WebLLM | "browser LLM runtime" | MLC-LLM project; Apache 2.0; OpenAI-compatible JS |
| Jetson | "NVIDIA edge" | Orin Nano / AGX / Thor / T4000 family |
| TRT Edge-LLM | "edge TensorRT" | 2026 edge port of TensorRT-LLM; EAGLE-3 + NVFP4 |
| Unified memory | "shared pool" | CPU and NPU see same RAM; no copy overhead |
| Bandwidth-bound | "memory limited" | Decode gated by bytes/sec reading weights |
| Core ML | "Apple conversion" | Apple framework for ANE-native models |
| QNN | "Qualcomm stack" | Qualcomm Neural Network SDK |
Further Reading
- On-Device LLMs State of the Union 2026: landscape and benchmarks.
- NVIDIA Jetson Edge AI: Orin / AGX / Thor.
- NVIDIA TensorRT Edge-LLM: 2026 edge port announcement.
- WebLLM (arXiv:2412.15803): design and benchmarks.
- Apple Core ML: ANE-native conversion.
- Qualcomm AI Hub: pre-converted models for Hexagon.
Code
- main.py (python, 75 lines)