iPhone 18 Pro: First Core ML load on Neural Engine up to 65× slower than on iPhone 17 Pro

On iPhone 18 Pro (A20 Pro), the first MLModel load of a model on the Neural Engine can take minutes where an iPhone 17 Pro needs seconds. Cached loads are instant, and once loaded the model runs faster than on the iPhone 17 Pro, so only the on-device specialization is affected. This looks like the same problem as A20 pro devices take too long on CoreML model specialization and iPhone 18 pro takes very long time to load models. The "loading" time there is likely this specialization too: it happens inside MLModel(contentsOf:) for an already compiled .mlmodelc.

I can reproduce it reliably with attention in the form Apple recommends for the Neural Engine (split einsum, as in Deploying Transformers on the Apple Neural Engine). In this example most of the extra time comes from the softmax over the key axis, which in that layout is the channel axis. Other ops and model types may well be affected too; this is simply the smallest case we could build that shows the problem clearly. The repro uses four self-attention layers (10 heads × 64, 4096 tokens, fp16) built with coremltools and loaded cold with .cpuAndNeuralEngine. MLComputePlan places every op on the Neural Engine on all three devices. iOS 27.0.1 (24A446) on both iPhones:

                                     iPhone 18 Pro        iPhone 17 Pro        M3 Pro Mac
                                     cold     predict     cold    predict      cold    predict
Split-einsum attention, 4 layers     53.4 s   21.6 ms     0.8 s   111.4 ms     1.0 s   105.8 ms
Q.K einsum only                       5.1 s   24.0 ms     1.2 s    36.8 ms     1.4 s    41.8 ms
Q.K einsum + softmax                 36.1 s   61.5 ms     1.7 s   141.0 ms     2.0 s   128.3 ms
Scores keys-last (softmax last axis) 10.5 s  109.0 ms     0.6 s   198.4 ms     0.7 s   180.2 ms
scaled_dot_product_attention          1.4 s  140.4 ms     0.4 s   184.9 ms     0.5 s   148.1 ms

Cached loads take 0.01–0.03 s everywhere.

What I observed:

  • Compile time grows linearly with the number of attention layers.
  • Every alternative attention layout I tried that compiles quickly runs 5–6× slower on the A20 Pro, so I found no workaround that keeps its speed.
  • During the slow load, ANECompilerService runs almost entirely on the efficiency cores. Requesting a higher QoS, MLOptimizationHints (.fastPrediction, reshapeFrequency), computeUnits = .all and dense instead of palettized weights don't help.
  • Loading several models in parallel additionally gets ANECompilerService killed by jetsam (per-process-limit).
  • The specialization cache doesn't survive reinstalling the app.

In our app (Stable Diffusion XL), each UNet chunk with attention takes 110–150 s instead of 6–16 s, so the first launch takes about 25 minutes in the foreground, and in our tests again after every reinstall. The same networks converted to Core AI specialize normally on this device (see our Core AI porting notes).

Filed as FB25106520 with a self-contained repro: a coremltools script, an iOS app and a Mac runner, plus results from all three devices.

Environment: iPhone 18 Pro (iPhone19,2) and iPhone 17 Pro (iPhone18,1) on iOS 27.0.1 (24A446), M3 Pro on macOS 27.0.1 (26A434), Xcode 27.0, coremltools 8.3.0.

Is this a known A20 Pro issue, and is there a recommended way to avoid it until it's fixed? Falling back to the GPU or CPU isn't a good option for us: it avoids the slow load, but gives up the Neural Engine's efficiency, which matters for on-device generation on a phone, and its speed (a full SDXL UNet step on the iPhone 18 Pro takes 509 ms on the Neural Engine vs 1,639 ms with .cpuAndGPU). We'd also like to hear from others which ops their slow first loads involve, to see whether this is specific to attention and softmax or broader.

Happens to me as well, I opened my thread here: https://developer.apple.com/forums/thread/848590

No response from Apple.

But this is definitely confirmed. Not sure how they missed this and didnt bother testing anything coreml related.

This also happens on M6 devices as well. great job Apple.

Some further info on M6, (but also expeiencing the same issue on A20):

Same issue here on an M6 Mac mini (Mac18,5, Core AI architecture h18g), macOS 27.0 (26A425), Xcode 27.0, so it isn’t limited to A20 Pro. In our case, attention isn’t involved: the slow graphs are long unrolled LSTM recurrences.

Model: a music source-separation network split into 22 FP16 Core ML components, loaded with .cpuAndNeuralEngine. MLComputePlan places every device-assigned operation on the Neural Engine.

Cold first load on M6, per component (cached reloads are 0.01–0.04 s):

6 stage prefixes (57-step bidirectional LSTM): 12.7–12.9 s each
3 recurrent cells (52 steps): 8.0–8.2 s each
3 recurrent cells (34 steps): 4.9–5.0 s each
Conv encoders/decoder: 1.1–3.1 s each
Whole model (22 components): about 123–145 s
The same compiled .mlmodelc files on M4:

An isolated 26-step LSTM: 1.3 s on M4 vs 4.4 s on M6.
The 26/17-step variant of the whole model: about 25 s on M4 vs about 103 s on M6.
Compile time grows with the number of unrolled steps. For one LSTM: 8 steps 1.2 s, 19 steps 3.1 s, 57 steps 11.7 s. Almost all of it is ANECompilerService CPU time. Loading components in parallel only reduced the total from 145 s to 121 s, because the compiler largely processes them one at a time.

Compiler crash: a 338-step LSTM graph that loads in 21 s on M4 crashes ANECompilerService on M6, with “Thread stack size exceeded due to excessive recursion” in SubgraphIdentification::ComputeReachableMap (called from ComputeReachabilityMaps / AddBoundaryTensorsForAcyclicCluster). Core ML retries, caches nothing, and every later load takes about 113 s again.

Core AI didn’t help us. For the 57-step prefix component:

Core ML: 12.8 s
Core AI precompiled with coreai-build compile --architecture h18g --preferred-compute neural-engine: 16.3 s (still runs ANECompilerService on first load)
Core AI source .aimodel specialized on device: 161.6 s

Just to note, model specialization on an iphone 16 pro max finished in about 30 seconds (iOS 27)

I'm actually the author of the post you linked! I've also contacted DTS about this, using one of our company's two annual code-level support requests lol.

From my limited testing, models with large activation maps seem to be particularly affected, or at least those were the ones I had the most trouble with.

I also had an agent help me dig into the Instruments call tree for ANECompilerService. On the iPhone 18 Pro, the compiler consumed around 68.6 CPU-seconds, compared to roughly 1.2–1.6 on the iPhone 17e.

Some of the major hotspots were:

  • EvaluateComputeCostForTileHeightCandidates (~20.4 CPU-s)
  • TileWithGlobalRefinement (~15.6 CPU-s)
  • ZinCpBasedAllocator::Execute (~15.6 CPU-s)
  • DetermineClusteringFromCostModelDynamicProgramming (~12.8 CPU-s)

These are call-tree measurements, so some of the timings may overlap.

From what I can tell, a significant amount of time is being spent exploring and evaluating different optimization strategies during ANE compilation. My suspicion is that the compiler might be exploring a much larger optimization space on the newer hardware, though I haven't established why.

Unfortunately, the only workaround I've found so far is to avoid the ANE entirely lol. I'm currently running the affected models on the GPU instead, which obviously isn't ideal.

I'd also be interested to know if anyone has found a better temporary workaround. Hope this helps narrow things down a bit!

got the same problem with our custom models. Tried various formats (mlmodel, mlpackage, and min deploy target for coremltools conversions, 16-bit and 32-bit floats).

First load time takes over 60s on iPhone 18 Pro, where it is normally < 0.5s on other iPhones, next load read from cache (it's immediate). The Xcode console shows this at the end of the load:

E5RT: MILCompilerForANE error: failed to compile ANE model using ANEF. Error=_ANECompiler : ANECCompile() FAILED (11)

These are small models with nothing fancy, I guess we have to check the iPhone model to revert to GPU instead of ANE. Can't do it globally, as ANE brings real improvements on all other devices.

Thank you folks for reporting the issue.

Now that iOS 27.2 Beta 4 is out, we expect that the model loading performance is improved, though it is still not at parity with the old devices. You might give it a try.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

I did additional testing yesterday with iOS 27.2b4, iPhone 18 Pro. Out of 4 models, 2 are affected in our apps (so probably specific layer types cause that). The 120s load time is now ~20s, vs. <1s on other devices (.all / ANE).

Please keep going, so that we can realistically use the ANE on that device. Once loaded, performance is very good. The current workarounds are not satisfactory (either long load time, or GPU loading with worse performance than older devices).

Seeing the same on iPhone 18 Pro Max (iPhone19,7), iOS 27.2 and it also affects Apple’s own Vision framework, not only custom Core ML models. We use both.

Vision: the first VNDetectFaceLandmarksRequest on a 2316×3088 photo took about 678 s (11 min) in my app. Afterwards it takes 0.1 s, including from a brand-new test app, so it seems like the compiled cache is shared across apps.

I tried to fallback to CPU but forcing the request to the CPU via Forcing VNDetectFaceLandmarksRequest onto the CPU with setComputeDevice(.cpu, for:) fails immediately with com.apple.Vision Code=9: “Could not create/add network to inference plan – Espresso exception: ‘I/O error’: Missing weights path landmarksflow-…_quantized.espresso.weights_nonane.”

Our own model: loading an enumerated-shape .mlmodelc with computeUnits = .all didn’t return for >10 minutes. The same model with .cpuAndGPU loads in 0.02 s.

Is Vision’s face model expected to be covered by the 27.2 improvement? Happy to attach a sysdiagnose.