Разобрать Apple изнутри: как исследователь вскрыл Neural Engine M4
Разработчик взломал закрытые API Apple Neural Engine на M4, обошёл CoreML и добился прямого доступа к железу. А помог ему Claude Opus 4.6.

Apple не публикует архитектуру Neural Engine. Не документирует его внутреннее устройство. Не даёт никакого способа программировать его напрямую — всё идёт через CoreML, который добавляет столько абстракций и накладных расходов, что понять что происходит на уровне железа практически невозможно.
Поэтому Манджит Сингх решил разобраться самостоятельно. 28 февраля 2026 года он опубликовал первую часть своего трёхсерийного расследования: как обойти CoreML и напрямую разговаривать с Apple Neural Engine.
Любопытная деталь: напарником в этом исследовании выступил Claude Opus 4.6. Человек — как архитектор с интуицией, AI — как инженер, пишущий код и анализирующий данные.
Что такое Neural Engine и почему к нему нет прямого доступа
ANE — не GPU и не CPU. Это машина исполнения графов: специализированный ускоритель, который принимает скомпилированный граф нейросети и выполняет его целиком как одну атомарную операцию. Никаких индивидуальных инструкций — только цельный скомпилированный граф.
Apple ввела Neural Engine в A11 (2017) как 2-ядерный блок. В M4 (кодовое имя H16G) он вырос до 16 ядёр, глубина очереди — 127 запросов, независимая система управления питанием DVFS, и жёсткое отключение питания до нуля ватт в режиме простоя.
Apple заявляет 38 TOPS производительности. Как выяснилось в ходе исследования, это число в лучшем случае вводит в заблуждение — реальная картина намного сложнее. Но об этом будет Часть 2.
Как устроена атака
Сингх применил несколько техник одновременно.
Сначала — dyld_info -objc на AppleNeuralEngine.framework, чтобы вытащить все скрытые Objective-C классы и методы. Это дало карту: 40+ приватных классов, включая _ANEClient, _ANEModel, _ANERequest, _ANEIOSurfaceObject, _ANEInMemoryModel. Дальше — метод swizzling, чтобы перехватывать вызовы CoreML к этим классам и смотреть, что реально происходит. Параллельно — бинарный анализ скомпилированных E5-файлов.
Ключевое открытие: CoreML — не единственный путь к ANE. Класс _ANEClient в AppleNeuralEngine.framework даёт прямой доступ к пайплайну компиляции → загрузки → выполнения. CoreML — просто удобная обёртка сверху.
Последовательность прямого запуска программы на ANE оказалась вполне доступной: получить соединение с клиентом, создать модель, скомпилировать MIL-текст, загрузить программу на железо, создать IOSurface-буферы, построить запрос, выполнить. Всё через приватные API.
MIL: язык, на котором говорит Neural Engine
CoreML отправляет нейросети на ANE не в ONNX или protobuf, а в MIL — Machine Learning Intermediate Language. Это типизированное SSA-представление:
func main<ios18>(
tensor<fp16, [1, 1024, 1, 1024]> x,
tensor<fp16, [1, 1024, 1, 1024]> w
) {
tensor<fp16, [1, 1024, 1, 1024]> out =
matmul(x = x, y = w);
}
Тензоры хранятся в формате NCDHW + Interleave: [Batch, Channels, Depth, Height, Width]. Для матрицы 1024×1024 это [1, 1024, 1, 1024].
Скомпилированный E5-бинарник — это FlatBuffer. Здесь исследователи наткнулись на занятное: матмул 1024×1024 компилируется в 2688 байт. Матмул 128×128 — в 2680 байт. Почти одинаково. E5 кодирует не алгоритм вычисления — он кодирует параметризованную программу, поведение которой контролируется дескрипторами тензоров в рантайме.
Иными словами: ANE имеет небольшой набор фиксированных примитивов (свёртка, матмул, поэлементные операции), параметризованных формой тензора. E5 описывает, какие примитивы соединить и как, а не само вычисление.
Инмемори-путь и три засады
Путь через файловую систему работал, но для обучения — где нужно перекомпилировать граф каждые несколько шагов — filesystem round-trip неприемлем. Сингх обнаружил _ANEInMemoryModelDescriptor, принимающий MIL-текст напрямую в памяти.
На этом пути их ждали три ловушки, которые съели несколько дней:
Параметр milText принимает NSData* с UTF-8 байтами, а не NSString*. Передача строки фейлится молча. Параметр weights — словарь, а не единый буфер данных. И даже «инмемори» путь внутри пишет во временную директорию — если нет доступа на запись, компиляция падает с непрозрачной ошибкой.
Бонусная находка: в одном из классов Apple написали Desctiptor вместо Descriptor. Опечатка в приватном API крупнейшей технокомпании мира.
Что это меняет
Прямой доступ к ANE без CoreML открывает несколько возможностей, которые Apple не планировала.
Во-первых, измерение реальной производительности — без накладных расходов CoreML. Bypassing CoreML даёт 2-4× больше пропускной способности. Именно это будет детально разобрано в Части 2.
Во-вторых, IOSurfaces для I/O — тот же механизм, что используется для GPU-текстур. Теоретически это открывает нулевое копирование между GPU и ANE.
В-третьих — и это главное — обучение на ANE. ANE проектировался исключительно для инференса. Никто не должен был на нём обучать модели. Сингх это сделал. Результаты — в Части 3.
Найденные, но ещё не изученные классы намекают на дополнительные возможности: _ANEChainingRequest (цепочка моделей в одном диспатче), _ANESharedEvents (Metal-style синхронизация GPU↔ANE), _ANEVirtualClient (виртуализированный доступ для нескольких процессов).
Весь код доступен на github.com/maderix/ANE. Протестировано на M4 Mac Mini, macOS 15.x.
Зачем это важно
Apple намеренно изолировала ANE за CoreML. Это даёт компании полный контроль над тем, как используется железо, и позволяет оптимизировать всю систему вертикально. Для большинства разработчиков CoreML достаточен.
Но когда исследователи получают прямой доступ к железу, выясняется, что 38 TOPS — это маркетинг, CoreML съедает значительную долю реальной производительности, и чип изначально умеет то, о чём Apple молчит.
Любой, кто запускает локальные модели на Mac и хотел понять, почему ANE часто работает медленнее ожидаемого — вот часть ответа.


