MacBrains LabsApple Silicon research

MacBrains Labs / Research / Evidence E/001

Placement, with the tools to check it.

This bundle holds what is needed to rerun the operator-placement count behind 2,090 ANE / 79 CPU, and says plainly which parts of the original run were not recorded. On 30 October 2026, an archived copy of the June model reproduced those counts exactly.

Bundle
E/001
Finding
ANE-RE FINDINGS §2
Method
MLComputePlan
Function
infer
Source
ane-re @ ffd1a3c

01Recorded result

MLComputePlan was loaded for the infer function with compute units set to CPU and Neural Engine. Each operation was counted by the device MLComputePlan reports as preferred for it. Operations with no reported device usage are counted as none.

BucketOpsOf all opsOf assigned compute
ANE2,09032.6%96.4%
CPU791.2%3.6%
GPU00.0%0.0%
none4,24266.2%n/a
Total6,411100%2,169 assigned

Recorded in ANE-RE FINDINGS §2 and in the output block reproduced in the ANE-RE structural gate source. The 79 CPU operations are the lm_head argmax tail.

The same placement and state-primitive counts are published as qwen-placement.csv and qwen-state-primitives.csv in the MacBrains Labs ANE Research Records, archived at Zenodo under DOI 10.5281/zenodo.23798037. This bundle adds the tools that produced the counts. Raw experimental data, private fixtures and model weights remain unpublished.

KV-state machinery in the same function, counted by kv_placement.swift:

OperatorANECPU
slice_update560
read_state570
write_state560
slice_by_index2250

The recorded output, as transcribed: recorded_output.txt. Machine-readable provenance: provenance.json.

02Model under test

The measured artifact is qwen25_monolithic_full_lut4.mlmodelc. It is a Core ML conversion of Qwen/Qwen2.5-1.5B-Instruct produced with ANEMLL's Qwen2.5 converter: monolithic export, 512-token context, LUT4 palettization, argmax output. The model's metadata records coremltools 9.0 and ANEMLL v0.3.5.

Credit

The conversion that makes this model ANE-resident is ANEMLL's work. This record measures where that model's operations are assigned and what that says about the KV-state path. It does not claim the converter.

The compiled model is not distributed here. It is derived from the Qwen weights; its stored weight file is about 893 MB.

03Tools

Both tools are short Swift programs that use only the public MLComputePlan API (macOS 14.4 or later). They are byte-for-byte copies from the ane-re repository at commit ffd1a3c.

FileCountsSHA-256
ane_compute_plan.swiftEvery operation by assigned device557d158d…7e6226a*
kv_placement.swiftKV-state operators by assigned devicea69752ac…9da6148c*

* Full hashes are in provenance.json.

04Rerun it

  1. Convert Qwen/Qwen2.5-1.5B-Instruct with ANEMLL's convert_monolith.sh at context 512 with LUT4 weights and argmax output, then compile the package with xcrun coremlcompiler compile.
  2. Build and run both tools against the compiled model's infer function:
swiftc -O ane_compute_plan.swift -o ane_compute_plan
swiftc -O kv_placement.swift -o kv_placement
./ane_compute_plan qwen25_monolithic_full_lut4.mlmodelc infer
./kv_placement qwen25_monolithic_full_lut4.mlmodelc infer

Compare the output with recorded_output.txt. These build commands are the standard way to compile a single Swift file. They were not rerun for this bundle.

Different converter flags can change the graph and therefore the counts. If your counts differ, the model's ANEMLL version, LUT settings and argmax setting are the first things to compare.

05Reruns, 30 October 2026

Three runs were made on 30 October 2026 with the two tools in this bundle, on Mac17,5 (Apple A18 Pro), macOS 27.2 build 26B123, with the tools built by Apple Swift 6.4.2.

The archived June artifact

A copy of qwen25_monolithic_full_lut4.mlmodelc sits in two project archives dated 12 and 23 June 2026, with the same model.mil in both. Its metadata records ANEMLL v0.3.5 and coremltools 9.0, and its weight file is 893,118,592 bytes. Run on the current OS, its infer function gave the recorded June counts exactly, including the KV-state counts.

The June record holds no model hash, so it cannot confirm that this copy is the file measured on 18 June. That is inferred from the archive dates and the identical counts.

The current shipped build

The same tools were also run on the current shipped build of the same model line, which has an infer function and a 64-token prefill function. It is a different artifact from the June one, so its counts are reported beside the June result and do not replace it.

BucketJune recordJune copy, rerunShipped, inferShipped, prefill
ANE2,0902,0902,1472,360
CPU79798213
GPU0000
none4,2424,2424,0224,735
Total6,4116,4116,2517,108
ANE share of assigned compute96.4%96.4%96.3%99.5%
slice_update / read_state / write_state on ANE56 / 57 / 5656 / 57 / 5656 / 57 / 5656 / 56 / 56
slice_by_index on ANE225225281281

No KV-state operator was assigned to the CPU in either infer function. In the shipped prefill function, one of the 57 read_state operations was assigned to the CPU.

Artifactmodel.milweight.binRaw output
June copy9c8dccb6…94d4c72f004eef01…a73fa30b94infer
Shipped build9e8630d4…918e3fef5d465d50b…c5a662a10dinfer, prefill

Full hashes, including each output file's, are in provenance.json. Each output file is the tools' stdout as captured; the shipped infer file also carries start and end timestamps and the OS and device lines.

The shipped artifact's release notes record how it was built: ANEMLL at commit cc818aeb, convert_monolith.sh with context 512, batch 64, LUT 4 and 8, LUT4 embeddings and LM head, and argmax output, converted on 21 October 2026. Its prefill function was post-processed to make the batched KV writes compile for the ANE; infer was not changed. That build record is quoted, not re-derived. Only the file hashes and the counts were checked on these runs.

06What it shows

MLComputePlan is the compiler's assignment, not a hardware trace. These counts show where Core ML planned each operation of this build. They do not prove zero CPU work across the whole inference stack, and they do not transfer automatically to a different Core ML build.

The KV-state counts correct an earlier claim in the same research record. An earlier note said slice_update and write_state were an irreducible CPU floor. That came from a hand-written toy graph, not from a hardware limit. In the infer function of this production graph, all four KV-state operators are assigned to the ANE.

07Gaps in the record

A reader should know what this bundle cannot supply.

  • No raw, timestamped log of the June run is in the record. Its numbers come from the findings document, the output block reproduced in the gate source, and a project archive entry dated 18 June 2026.
  • The archive gives Mac17,5 and macOS 26 beta 26A5353q in the same dated section as the result, but not on the result line itself.
  • The exact conversion command and ANEMLL commit for the June artifact were not recorded, and the June record holds no model hash. The archived copy rerun here is identified by its archive dates and matching counts, not by a recorded hash.
  • All 30 October runs record their raw output, OS build, device and model hashes. The compiled models themselves are not distributed.

Corrections and independent reruns are welcome at research@macbrainslabs.org.