Core AI model zoo

Compute units (ANE / GPU / CPU) & on-device authoring rules

Foundation note: the empirical do’s/don’ts for making a model run correctly + fast on each compute unit. The single most important framing: iOS/ANE = static-shape, BC1S, Conv2d, per-head, fp16-only; macOS/GPU = dynamic-shape, standard layout, fused, custom kernels. These are Apple’s two first-class modes. Sources: coreai-models/skills/.../model-authoring/references/{neural_engine_rules,gpu_rules,common_issues}.md, .../working-with-coreai/{SKILL.md,references/guidance.md}, and the official primitives coreai-models/python/src/coreai_models/primitives/{ios,macos}/ + export/{ios,macos}.py.

The three compute units

| | ANE (Neural Engine) | GPU | CPU (BNNS) | |—|—|—|—| | Best for | energy-efficient inference, fixed shapes, iOS foreground | large models, dynamic shapes, batch, max throughput | validation, fallback | | Shapes | fully static (one fn per shape config) | dynamic OK | any | | Layout | BC1S (B, C, 1, S) | standard (B,S,D) / (B,H,S,D) | any | | Projections | 1×1 Conv2d (Conv engine accumulates fp32) | nn.Linear, fused QKV | any | | Attention | per-head, sequential (no fused SDPA) | fused native SDPA (all heads) | either | | KV cache | readonly functional I/O (host writes), seq on dim 4 | stateful (mutable_slice_update), seq on dim 3 | — | | Custom MSL kernels | NO (fixed ops only) | YES (TorchMetalKernel) | no | | Precision | fp16 only (no fp32 literals/intermediates) | fp16 weights, fp32 intermediates OK | fp32/fp16 |

The “ANE can’t run custom MSL” row is why the GPU speed track exists — see custom-metal-kernels.md (project memory: project_ane_vs_gpu_premise).

ANE authoring rules (the high-leverage ones)

GPU authoring rules

macOS vs iOS export (the official split)

export/pipeline.py picks dynamic (macOS) vs static (iOS). | | iOS (export/ios.py) | macOS (export/macos.py) | |—|—|—| | Shapes | static buckets (query [8,16,64] × cache 256,512,1024,…) | dynamic torch.export.Dim | | KV | state_names + in_step data-tensor write + IOSurface/interleave | state_names + shape-symint offset | | Engine | CoreAIStaticShapeEngine (host owns KV NDArray, passes state views each step) | CoreAIPipelinedEngine (GPU) | | Target | Neural Engine | GPU |

Runtime compute-unit selection — auto-derived from STRUCTURE, preferred-not-forced, overridable

The official runtime does NOT hard-pin a compute unit; export/ios.py/export/macos.py bake none. Instead the Swift runtime probes the model’s structure and derives a preference (CoreAIShared/Runtime/ModelStructure.swift:57-66):

PreparedModel.prepare(at:)probeStructureAIModel(contentsOf: url, options:) (:137-141). Notes:

Verification gates (PSNR)

working-with-coreai/SKILL.md:94-99, guidance.md:145-153:

Localize divergence with REAL inputs — degenerate constant-input probes lie (they said an ANE chunk was exact when real inputs showed it diverged from layer 1). This project’s hardest-won ANE lesson.

Decision guidance