ai官小西

在 Apple Neural Engine 上训练神经网络:maderix 如何撬开了苹果最封闭的芯片

在 Apple Neural Engine 上训练神经网络:maderix 如何撬开了苹果最封闭的芯片

Apple 的 Neural Engine(ANE)是 M 系列芯片中最神秘的组件。自 2017 年 A11 首次搭载以来,ANE 始终只有一个官方入口:CoreML 推理。苹果从未公开过 ANE 的指令集架构(ISA),从未提供直接编程接口,甚至在开发者文档中几乎不提它——它只是一行技术规格中的数字:"M4: 38 TOPS"。

2026 年 2 月 28 日,一个叫 Manjeet Singh(GitHub ID: maderix)的工程师在 Substack 上发布了《Inside the M4 Apple Neural Engine, Part 1: Reverse Engineering》。这不是普通的博客——他直接调用了 _ANEClient_ANECompiler 这两个 Apple 私有 API,在 ANE 上跑了一个完整的 Transformer 训练循环

截至 2026 年 7 月底,项目的 GitHub 仓库获得 7,196 Star、963 Fork。HN 上关于 Part 1 的讨论累积了 376 点、117 条评论。MIT 许可证。

最让人意外的是作者的开场白:Claude Opus 4.6 是他这次逆向工程的联合开发者——"we"(我们)指代的是人类 Manjeet Singh 和 Claude 两个人一起工作。一个人提出直觉和方向,AI 写代码和实验。


一、Apple 为什么把 ANE 锁死?

ANE 不是 GPU,也不是 CPU。它是一个图执行引擎(graph execution engine)——固定功能的加速器,接收一个已编译的神经网络计算图,作为一次原子操作执行完毕,返回结果。你不能像写 CUDA 那样向它发出单个乘加指令。你只能提交一个描述整个计算图的已编译程序,硬件从头跑到尾。

Apple 的设计意图很清晰:ANE = 推理专用。他们提供 CoreML 作为唯一入口,屏蔽了硬件细节,也屏蔽了任何训练的可能性。API 层面的限制比硬件能力的限制更早到位。

为什么不开放训练?几种可能的解释:

  • 稳定性优先。 ANE 的软件栈没有为频繁的权重更新做优化——见后文编译缓存的困境。
  • 碎片化恐惧。 一旦允许自定义计算图,iOS/macOS 生态的 API 表面就可能碎片化。
  • 商业护城河。 ANE 是 Apple Silicon 的差异化力量。开放编程意味着竞争对手能更容易地分析芯片设计。

但 maderix 证明了第三条最值得质疑:屏障一直是软件,不是硬件。


二、全栈逆向:从 CoreML 到硅片的完整路径

maderix 花了数天时间,从最上层的 CoreML API 一路向下,完整映射了 ANE 的软件栈:

┌─────────────────────────────────────────────────┐
│  CoreML (公开 API)                               │
│  mlmodel → 编译 → 推理                            │
├─────────────────────────────────────────────────┤
│  Espresso (Apple 内部推理引擎)                      │
│  图优化、算子调度                                  │
├─────────────────────────────────────────────────┤
│  AppleNeuralEngine.framework                    │
│  _ANEClient, _ANEModel, _ANERequest,            │
│  _ANEIOSurfaceObject, _ANEInMemoryModel...      │
│  40+ 私有类                                      │
├─────────────────────────────────────────────────┤
│  ANECompiler.framework                          │
│  MIL 文本 → E5 二进制 (FlatBuffer)                │
├─────────────────────────────────────────────────┤
│  IOKit (内核驱动)                                  │
│  AppleANEDriver → ANE 硬件寄存器                   │
├─────────────────────────────────────────────────┤
│  M4 ANE (H16G)                                  │
│  16 核, 127 深度队列, 独立 DVFS                    │
└─────────────────────────────────────────────────┘

关键发现:CoreML 不是唯一的门。AppleNeuralEngine.framework 中的 _ANEClient 类直接提供了 compile → load → evaluate 的完整管线。CoreML 只是这之上的一个便利层。

发现过程结合了四种技术:

  1. Class-dump 提取私有框架的头文件
  2. LLDB 动态调试 跟踪 CoreML 到内部的调用路径
  3. IOKit 探测 识别硬件寄存器映射和 DVFS(动态电压频率调节)通道
  4. 汇编级分析 反编译 E5 二进制格式

共发现 40+ 个私有类,包括 _ANEInMemoryModelDescriptor——这个类直接接受内存中的 MIL 文本,完全绕过了基于文件系统的编译路径。


三、MIL:苹果为 ANE 设计的中间语言

CoreML 并不以 ONNX 或 protobuf 格式向 ANE 发送神经网络。它使用 MIL(Machine Learning Intermediate Language)——一种类型化的 SSA(静态单赋值)中间表示:

function main(float<fp32>[1, 1024, 1, 1024] A,
              float<fp32>[1, 1024, 1, 1024] B)
              -> (float<fp32>[1, 1024, 1, 1024]) {
  %1 = conv(input=A, weight=B, stride=[1, 1],
            pad_type=valid, groups=1,
            dilation=[1, 1])
      // shape: [1, 1024, 1, 1024]
  function_return %1
}

MIL 出奇地可读。每个值都有类型标注(精度 + 形状),操作以命名关键字的函数调用形式出现。张量布局遵循 ANE 原生的 NCDHW + 交织(Interleave) 格式:[Batch, Channels, Depth, Height, Width]。一个 1024×1024 的矩阵变成 [1, 1024, 1, 1024]

最关键的发现:ANE 的原生计算原语是卷积(conv),不是矩阵乘法。 将 matmul 表达为 1×1 卷积,吞吐量显著提高——这在 Part 2 的性能基准中得到了验证。

E5 二进制:微码,而非机器码

ANECompiler 处理 MIL 程序后,生成 E5 二进制——一个 FlatBuffer 结构的编译产物。一个令人震惊的事实:

  • 1024×1024 的 matmul → 2,688 字节
  • 128×128 的 matmul → 2,680 字节

几乎完全相同。E5 二进制不是在编码矩阵乘法的算法——它在编码一个参数化程序,行为由运行时的张量描述符控制。这种"微码"更像是配置,而非传统机器码。ANE 硬件内部有一个固定的计算原语集合(conv、matmul、element-wise),E5 二进制描述的是如何将它们链接起来。


四、训练的实现:动态权重内核与六个反直觉的工程决策

拿到直接 ANE 访问后,maderix 进入了训练的实现阶段。目标:在 ANE 上运行完整的 Transformer 训练——前向 + 反向传播 + 优化器更新。结果是两个模型跑通了:

模型 参数量 每步耗时 层数 每层内核数
Stories110M (12L, dim=768, MHA) 109M 91 ms 12 6 (MHA)
Qwen3-0.6B (28L, dim=1024, GQA) 596M 412 ms 28 10 (GQA)

核心技巧:权重打包到空间维度

训练的最大障碍是:每次权重更新后重新编译 MIL 程序太慢了(首次编译 ~20-40ms)。maderix 的解决方案很美:

  • 激活和权重视为一个空间输入维度的连续切片
  • 在 MIL 内核中通过 slice/reshape 操作分离开来
  • 权重变化时替换 IOSurface 中的权重数据,不重新编译

这意味着一次编译,无限次评估——每次只需替换权重 I/O 缓冲。

六个工程决策

训练代码中有几个值得详述的设计:

1. 通道优先(NCDHW 格式)。 ANE IOSurface 的原生布局是 [N, C, D, H, W],而 PyTorch 和大多数深度学习框架使用 [N, H, W, C][B, T, H, D]。直接在 ANE 原生格式下工作,消除了所有转置开销。

2. GPU↔ANE 零拷贝管线。 iOSurface 是 GPU 纹理所用的同一共享内存机制。maderix 在 GPU 上跑 prefill(一次性处理完整提示),然后通过共享的 IOSurfaceRef 将中间状态传给 ANE 做逐 token 解码。

GPU Prefill (Stories110M, seq=256): 6.7ms
         ↓ (zero-copy IOSurface)
ANE Decode: 1.9ms
         ↓
Total: 8.8ms

3. CPU-ANE 并行。 dW 权重梯度的 sgemm 运算在 CPU 上执行,与 ANE 的前向/反向评估在一个串行 dispatch 队列上并行。ANE 的 wait_until_completed 被推到下一步的前向传播中,实现最大化重叠。

4. RMSNorm 折叠入内核。 RMSNorm 的前向和反向操作被折叠为 MIL 内核中的 reduce_sum + pow + mul 操作,而不是作为独立的 ANE 评估运行。

5. 中间值曝光绕过 CPU 重算。 ANE 内核的前向传播通过 concat 输出暴露 Q、K、V、注意力分数、隐藏状态等中间值,反向传播直接读取——完全避免了 CPU 端的重新计算。

6. Process pooling 绕过 119 编译限制。 ANE 编译器限制每个进程约 119 次编译。maderix 通过将训练循环包装在 exec() 重新启动中来绕过——每次重启继承 IOSurface 文件描述符,无缝恢复训练状态。


五、性能真相:5-9% 利用率——但这不是失败

这是 maderix 最坦诚的部分。他直接在 README 中写道:

Training works, but utilization is low (~5-9% of peak) with significant engineering challenges remaining. Many element-wise operations still fall back to CPU. This does not replace GPU training for anything beyond small research models today.

M4 ANE 的峰值吞吐量:

精度 峰值 TOPS 配置
FP16 18.6 128x conv, 512ch, 64×64
INT8 W8A8 35.1 128x conv, 512ch, 64×64

INT8 量化带来 1.88× 加速(通过 MIL 的 quantize/dequantize 操作将 L2 SRAM 带宽减半),但实际训练利用率仅 5-9%。为什么?

根本原因有三个:

  1. 因果注意力被分解。 ANE 硬件在 SDPA 操作中忽略 causal_mask。因果注意力被迫分解为 Q@K^T(ANE)→ mask+softmax(CPU)→ scores@V(ANE)三个阶段,引入了大量 CPU-ANE 同步开销。
  2. 编译器资源泄漏。 ANE 编译器在多次编译后会泄漏资源——只能通过 exec() 重启来解决。
  3. fp16 反向传播下溢。 反向 matmul 在 fp16 下频繁下溢——需要全局 loss scaling(scale=65536)来维持梯度精度。

但这些限制的存在本身,正是这个项目最有价值的地方。它用实验数据回答了一个从未被回答的问题:如果给 ANE 训练能力,它的真正瓶颈在哪里?


六、社区反应与作者立场

HN 上的 117 条评论揭示了几个有趣的视角:

  • 前 Apple Xcode 团队成员称深知 Apple 在让逆向工程变得困难上投入的精力,称赞这是"出色的工作"。
  • 关于 Apple 是否主动混淆代码的争论在评论区展开——有人认为 ANE 编译器代码"肯定没有混淆",另一名 Apple 前员工则列举了控制流平坦化、混合布尔-算术变换等技术。
  • 这个项目也引来了对 ANE 训练实际价值的合理质疑——7K Star 中相当一部分是"这很酷但没用"的情绪。

maderix 本人的态度非常清醒。他在 README 中明确声明:

I don't intend to grow this into a large community project. My focus is on original research (compiler infrastructure for edge AI optimization), and maintaining an open-source framework takes time away from that.

他不是在做一个产品。他是在发表一篇研究论文——代码就是论文。项目的 MIT 许可证和"Fork it, build on it"的邀请,本身就是这种"研究优先"姿态的延伸。


七、评分与判断

维度 评分 说明
技术新奇度 10/10 首次实现 ANE 上的完整训练,突破 Apple 长期封锁
工程质量 7/10 精巧的设计(动态权重内核、零拷贝管线),但利用率低
文档完整性 9/10 三篇 Substack 深度系列 + 详尽的 README + 带注释源码
实用价值 4/10 当前不替代任何 GPU 训练方案,也无法用于推理部署
研究价值 10/10 系统性地回答了 ANE 的可编程性和真实性能边界
生态影响 8/10 7.2K Star 表明这触动了开发者对封闭硬件的长期不满

这个评分表本身就说明了问题:一个 4/10 实用价值的项目,拿到了 10/10 的研究价值。 maderix/ANE 的价值不在于"你现在能用 ANE 训练模型"——你绝对不能,也不应该。它的价值在于证明了"训练是可能的",并系统性地记录了当前的所有瓶颈。

我们的判断

这个项目值得仔细读,但不值得直接用。

说"仔细读",因为 maderix 的 Substack 三篇系列文章是 ANE 逆向工程领域目前最完整、最系统的公开文档。如果你对 Apple Silicon 的底层有任何好奇心,这是必读材料。

说"不直接用",因为用 5-9% 的利用率在一台 M4 MacBook 上训练一个 110M 的模型,从时间/精力/效果来看都不如直接用 GPU。这个项目的实际用户是未来的 NPU 工具链开发者——今天 maderix 踩过的坑,就是未来 MLX 或 CoreML 团队需要填的坑。

一个更深层的问题:Apple 会怎么回应? 历史上 Apple 对私有 API 滥用有两种反应——要么封堵(iOS 越狱),要么视而不见(Mac 上的非官方硬件访问)。ANE 位于两个极端之间:它是消费者设备上的硬件,本身不涉及 iOS 安全模型。但 Apple 可能通过未来的 macOS 更新使 ANE 编译器的某些路径不可用——尤其是内存中编译路径。

maderix 自己写道:

The goal was to demonstrate that training on the Apple Neural Engine — and potentially other NPUs — is possible, and that the barrier has always been software support, not hardware capability.

这句话,可能比整个 GitHub 仓库里所有的代码都更有分量。


参考资料

  1. maderix (Manjeet Singh) — ANE GitHub 仓库(7.2K+ Star, MIT 许可证)
  2. Manjeet Singh — Inside the M4 Apple Neural Engine, Part 1: Reverse Engineering(2026-02-28, Substack)
  3. Manjeet Singh — Inside the M4 Apple Neural Engine, Part 2: ANE Benchmarks(2026-03, Substack)
  4. Manjeet Singh — Inside the M4 Apple Neural Engine, Part 3: Training(2026-03, Substack)
  5. Hacker News — Inside the M4 Apple Neural Engine, Part 1: Reverse Engineering(376 点, 117 评论, 2026-03-01)
  6. hollance — neural-engine: ANE 社区文档
  7. mdaiter — ane: 早期 ANE 逆向工程
  8. Asahi Linux 项目 — eiln/ane: ANE Linux 驱动