文档导航

Neural Engine 速度与能耗测量

FP16 ANE 重写相对编译后的 MLX FP16,把完整预测速度提升 1.39×,把每个决策的估计整机能耗降低 2.78×。单独验证的 W8 K-means 候选分别达到 1.42× 和 3.19×。两者都没有达到所要求的 10× 目标。 这些是本地 M3 Max 结果,存在下文列出的精度与功耗测量限制。

实现和转换实验见 ANE_ENGINEERING.md;数学边界和保真度契约见 ANE_MATH.md。

最终的持续短决策对比

M3 Max,40 个 GPU 核心,128 GiB,macOS 27.2。相同的多语言源 checkpoint、相同的八个 invoice-state 变体、每个请求一个四选项问题、91 个真实 token 补齐到 96。无输出缓存、无生成 token。三个模型都常驻;加载、编译和预热都在测量区间之外。

基线启用了 mx.compile、prompt 前缀缓存和 32-token 形状分桶。它比历史的 eager MLX 基线更快。FP16 ANE 候选保留原始权重,包含完整的 Core ML transformer 主体、主机端 embedding 查找和 FP32 的 CPU action tail。W8 使用分组 K-means 的 weight-only 调色板压缩,不是 W8A8 算术;它的激活仍使用 FP16,主机端 action tail 仍是 FP32。

指标 编译后的 MLX GPU FP16 ANE FP16 ANE W8 K-means
完成的决策 17,184 23,961 24,453
实测活动时长 120.02 s 120.02 s 120.02 s
端到端 P50 6.937 ms 4.976 ms 4.879 ms
端到端 P95 7.393 ms 5.307 ms 5.227 ms
每决策平均耗时 6.984 ms 5.009 ms 4.908 ms
平均整机功耗估计 61.39 W 30.75 W 27.39 W
每决策整机能耗 0.4288 J 0.1540 J 0.1344 J
扣除空闲后的每决策能耗 0.3393 J 0.0888 J 0.0715 J
相对编译后 MLX 的速度提升 1× 1.394× 1.423×
相对编译后 MLX 的整机能耗提升 1× 2.784× 3.189×
相对编译后 MLX 的扣除空闲能耗提升 1× 3.823× 4.749×

比值使用区间均值,包含全部已完成的工作:

FP16: speed 1.394 × average system-power ratio 1.997 = energy gain 2.784
W8:   speed 1.423 × average system-power ratio 2.241 = energy gain 3.189

再把能耗比乘以速度就是重复计算时间。扣除空闲的那一行使用不同的测量边界;它并不意味着整台笔记本的功耗下降 3.8–4.7×。这些是饱和吞吐区间。要做出固定 FPS 的功耗结论,需要等请求速率的实验。W8 在本次会话中相对 FP16 只把平均速度提升了约 2.1%,而它的主体包从 251.91 缩小到 129.29 十进制 MB。包体积不含原始 checkpoint/主机端 embedding 表,也不等于运行时的总内存。

每种实现都在三个平衡循环 MLX, ANE FP16, ANE W8, ANE W8, ANE FP16, MLX 中跑了六个 20 秒区块。区块之间隔十秒的空闲采样;前三个空闲秒被丢弃,相邻的稳定空闲功耗取平均。各后端的区块功耗范围为 MLX 60.32–62.38 W、FP16 ANE 29.28–35.14 W、W8 ANE 26.68–27.95 W。当时有其他桌面应用打开;交替和相邻空闲采样会减少但不能消除后台负载与传感器的不确定性。

全部 65,598 次预测都与各自后端对相应状态的四舍五入预热输出一致。三个后端在这八个状态上都选出相同答案。单独的保真度套件更广:FP16 L96 通过 59/59 个适配问题,最大概率漂移 0.002925;W8 在不变的 0.02 门槛下以 0.014393 的漂移通过同样这 59 个。完整的 63/63 结果属于单独导出的 FP16 L1024 模型。这些是回归夹具,不是对通用任务准确率或任意输入上保持校准的说法。

该运行保留了 1,101 个功耗采样;最大间隔为 0.510 秒,记录到的最大系统功耗为 74.47 W。没有采样被丢弃。每个区块的 RSS 是针对共享进程记录的,此时所有模型和录制缓冲都常驻;这些值不能归给单个后端的模型内存。当前的运行时和包指纹随报告一起存储。

最终原始调用与 PSTR 采样 · 审计后的摘要与会话内 bootstrap 区间

更早的 仅 FP16 的试点 测得 1.410× 速度和 2.939× 的总系统能耗提升。它早于最后的输入检查和逐调用稳定性插桩;上面这次全新的三臂运行才是最终运行时的已发布对比。最终原始报告里有一处元数据说明最初无条件地描述了历史上 macmon 的 component-sum 下限;一条附加的 metadata_corrections 条目澄清本次运行只用了 PSTR。原始字段和所有测量都保留。

Snake 兼容性是一个单独的工作负载

同一个已发布的 Snake 规划器、紧凑 prompt 和安全策略同时跑在 FP16 ANE adapter 和编译后的 MLX 上,在相同的实时状态上交替评估顺序。种子 101 和 102 各完成 300 步:600/600 个建议动作与执行动作一致,零死亡、零护盾干预。最终分数为 9 和 10,蛇长 15 和 16。最大移动概率差为 0.0036。这验证的是这次 FP16 轨迹对比,不是压缩模型的 Snake 行为或无限期存活。

种子 ANE 完整决策 P50 / P95 编译后 MLX 完整决策 P50 / P95
101 23.45 / 27.10 ms 17.14 / 23.58 ms
102 17.68 / 27.30 ms 19.18 / 33.27 ms

ANE adapter 在 B1/L96 上顺序运行三个问题;MLX 在最高 L64 上批处理这三个问题。这些计时包含规划器特征和完整预测,不含另一个后端的工作、游戏步和终端渲染,且波动很大。它们并不能证明有稳定的 Snake 加速或最大稳定渲染速率。单问题的 4.98 ms 结果不得被宣传为完整的 Snake 帧时间。专门的 B3/L64 ANE 导出将是一项单独的优化与验证任务。

原始 Snake 状态、输出与计时

python -m benchmarks.snake artifacts/ane-repro/body96/model.mlpackage \
  /path/to/original/laya-multilingual --ane --mlx-compiled \
  --steps 300 --seeds 101 102 --output artifacts/ane-snake.json

测量边界与遥测限制

每次计时的调用都包含 prompt 构造、分词、数组构造、适用时的主机端 embedding 查找、同步模型执行、action 特征、校准和输出格式化。MLX 会求值它的惰性输出;Core ML 返回已完成的 NumPy 数组。这比较的是未缓存的预测,不是孤立的模型 kernel。

最终对比使用小巧、非特权的 仅 PSTR 的采样器。它钉住 macmon 0.8.2 的底层 SMC API,打开一个只读连接,每 500 ms 采样一次原始 PSTR 值。它不读取 IOReport 的组件计数器。这是整机传感器估计,不是外部的墙插功耗或电池测量。可执行文件哈希和源码来源随原始结果一起记录。

之所以需要这个单独的采样器,是因为官方 macmon CLI 按 sys_power = max(PSTR, component_sum) 计算,如它的 源码 所示。CPU 和 ANE 计数器在本操作系统上通常返回零,随后一个采样跳到约 38,021 W CPU 和 2,068 W ANE。component 下限把这个故障传播成了 40,089 W 的系统读数。IOReport 异常的确切原因未解决;无法从那个采样中恢复原始 PSTR 值。整个受影响的能耗运行都被拒绝,但没有删除或裁剪那个坏采样。它的 原始记录 仍然可用,但其存储的能耗聚合不得当作结果使用。

更早的仅 FP16 运行使用官方 macmon v0.8.2 发布版,其归档 SHA256 被验证为 588d5bde79885ba36f693e5150911c10c3ad208a2e418a3f2aa827ac84a2d973。它通过了后来的健全性检查,仍是历史证据。最终的仅 PSTR 运行用一个一致的采样器重新测量每个后端。

测试装置在单调接收时间戳上用插值边界对瓦特做积分。缺失、非正、非有限或高于 500 W 的系统读数都会使该运行被拒绝。500 W 上限是为此 M3 Max 刻意设定的宽松健全性检查,不是校准过的准确度边界。超过 max(2 seconds, 3 × sample interval) 的间隔也会使该运行被拒绝。摘要会对照原始采样,验证完整的平衡循环、逐调用稳定性、调用计数、活动能耗、两个相邻空闲区间以及由此得到的扣除空闲后的能耗。增量能耗保留其符号;它绝不会被钳制去制造一个大比值。

直接采样器省略 CPU/GPU/ANE 功耗字段,因为它不测量它们。历史上缺失或为零的组件计数器不能证明零能耗或 ANE 未执行。bootstrap 对完整的平衡循环重采样;一次桌面会话的三个循环不能刻画所有后台负载、未来的运行或传感器准确度。所测得的比值没有一个接近 10×。

Neural Engine 真的在执行工作吗?

重写后的 B1/L96 图的 Core ML 计算计划把全部 6,390 个非常量算子放在 MLNeuralEngineComputeDevice 上;其余 3,809 个未知条目是常量。这是预期的放置,单凭它本身不足以作为硬件证据。普通的 SDPA 导出在本系统上没有任何 NE 首选算子。

在候选模型以 CPU_AND_NE 运行时,另取了一份 15.97 秒的 Instruments Core ML trace,捕获到 3,124 个活动的 “Neural Engine Prediction” 区间和一次无关的缓存系统模型加载。因此,导出的硬件表在计算计划之外,还提供了运行时 ANE 活动的正面证据。该表是全局的,并没有给每次预测附上 PID 或模型身份;本次录制中 Core ML 的 model-signpost 表为空。我们不会把每个硬件区间都单独归给 Laya,也不声称主机端工作在 ANE 上运行。

列入允许清单的硬件事件 只包含时间戳、时长、设备、标签和状态。完整的 Instruments 归档和进程环境元数据留在被忽略的 artifacts/ 目录中。追踪与能耗测试是分开的,插桩得到的硬件区间不用作端到端延迟结果。

复现

先用 工程报告 中的命令创建并验证固定的 L96 FP16 和 W8 K-means 包。这些命令会写入 artifacts/ane-repro/ 下的新目录。在本地构建直接传感器采样器;不安装系统守护进程或特权服务。

pip install -e '.[convert,dev,compare,research]'
cargo build --release --locked --manifest-path benchmarks/pstr_sampler/Cargo.toml
python -m benchmarks.energy \
  --source /path/to/original/laya-multilingual \
  --candidate artifacts/ane-repro/body96-w8km/model.mlpackage \
  --fp16-candidate artifacts/ane-repro/body96/model.mlpackage \
  --candidate-factory experiments.ane_engineering.runtime:ANEAgent \
  --sampler benchmarks/pstr_sampler/target/release/pstr-sampler --pstr-only \
  --cycles 3 --seconds 20 --idle-seconds 10 \
  --output artifacts/energy.json

python -m benchmarks.energy_summary artifacts/energy.json \
  --output artifacts/energy-summary.json

要做独立的运行时诊断,请启动 benchmarks.trace_ane,等它的 ready PID 文件出现,然后在没有其他模型工作负载运行时附加 Instruments:

python -m benchmarks.trace_ane \
  --source /path/to/original/laya-multilingual \
  --package artifacts/ane-repro/body96/model.mlpackage \
  --seconds 90 --ready artifacts/trace.pid
# From another terminal; use the PID written to that file.
xcrun xctrace record --template 'Core ML' --attach <PID> \
  --time-limit 15s --output artifacts/ane.trace
xcrun xctrace export --input artifacts/ane.trace --toc \
  --output artifacts/toc.xml
xcrun xctrace export --input artifacts/ane.trace \
  --xpath '/trace-toc/run[@number="1"]/data/table[@schema="ane-hw-intervals"]' \
  --output artifacts/hardware.xml
python -m benchmarks.trace_summary --hardware-xml artifacts/hardware.xml \
  --toc-xml artifacts/toc.xml --output artifacts/hardware-summary.json

原始 checkpoint 和较短的导出有各自的上下文上限。L96 运行时会拒绝放不下的输入;一个短负载的速度结果不能证明在 512/1024 token 或跨全部三个 Laya checkpoint 的性能。