Characterizing Mobile SoC for Accelerating Heterogeneous LLM Inference 【SOSP ’25】这篇文章干了啥1. 它首先回答了一个关键问题为什么手机端不能简单“GPUNPU一起跑”文章指出现有移动端 LLM 推理框架大多只用单一加速器要么偏 GPU要么偏 NPU没有真正把异构 SoC 的潜力用满。原因主要有三点GPU 和 NPU 的真实性能差异很大不能只看理论 TOPS/TFlopsGPU-NPU 同步开销很高文中说一次同步大约可到400 微秒decoding 阶段本质上是内存带宽受限单纯把算子拆给两个加速器不一定更快甚至可能更慢。2. 移动 SoC 的性能刻画它不是直接做系统而是先分析移动端异构处理器的行为特征GPU线性性能特性张量变大后吞吐近似线性增长但同步代价高NPUstage performance张量尺寸若和阵列规模不对齐会出现明显台阶效应NPUorder-sensitive performance同样计算量下仅仅换一下矩阵乘法的输入/权重顺序性能就可能大变文中举例可达6×NPUshape-sensitive performance张量长宽比不同NPU效率也会显著变化内存带宽层面单个处理器吃不满 SoC 带宽而 GPUNPU 并发时带宽利用率能明显上升。3. 基于这些观察文章提出了 HeteroInferHeteroInfer 的基本思想不是“平均分任务”而是按阶段、按张量形状、按硬件特性去决定谁跑什么CPU 只做控制面比如同步和 GPU kernel 调度NPU 作为主要计算单元GPU 作为辅助单元补足 NPU 在某些 shape/order 下的性能短板。一、INTRO1. 作者想解决什么问题1.1 问题定义Introduction 一开始先重申大模型上手机的趋势然后引出问题手机 SoC 已经有 GPU 和 NPU过去也有人做过 heterogenous processors 上的 inference engine但那些方案主要面向云端基础设施或离散加速器它们并不适合移动端平台。不是没人做过异构推理而是别人做的是 cloud/discrete accelerator作者做的是 mobile SoC。1.2 现有 mobile inference engine作者进一步指出即便已有一些移动端推理引擎也仍然没有真正把异构 SoC 的潜力榨干。原因有三类。第一GPU 和 NPU 的性能差异非常大作者举了 Snapdragon 8 Gen 3 的例子GPU 实际大约 1 TFLOPSNPU 实际可达 10 TFLOPS 左右所以问题不是“两个处理器都能算就直接并行”。因为如果分工不合理慢的一方可能变成拖后腿的那一方。异构并行不是“平均分配任务”而是必须考虑不同设备的真实吞吐差异第二GPU-NPU 同步开销很高文中说一次 GPU-NPU 同步大约400 微秒。而这个量级已经和某些单个 kernel 的执行时间接近甚至更大。很多人会觉得“并行一定更快”但如果同步成本已经和计算成本同量级那么异构并行很可能得不偿失。第三decoding 阶段本质是 memory-intensive作者指出 decoding 阶段是天然的内存密集型工作负载。因此单纯把计算扔给 GPU 和 NPU并不能自动带来收益甚至可能因为额外同步而更慢。它说明prefill 和 decoding 不能用同一套优化思路有些阶段是算力瓶颈有些阶段是带宽瓶颈所以系统设计必须是phase-aware的。1.3 所以作者定义的核心挑战是什么如何设计一个真正能在移动设备上高效协调所有异构处理器的 LLM inference engine。2. 作者观察到了什么新机会在指出问题后作者先说他们对 mobile SoC 做了深入分析发现了三个机会。2.1 Tensor-sensitive NPU performance作者说 NPU 虽然理论上很强但它的效率高度依赖张量特征ordersizeshape如果 tensor characteristics 和 NPU 硬件架构不匹配利用率和性能会显著下降。这句话的信息量很大。它意味着NPU 不是“天然比 GPU 快”NPU 的性能是条件性的某些 tensor 放到 NPU 上反而不划算从体系结构角度看这通常和 NPU 的阵列尺寸、dataflow、tiling 和权重驻留机制有关。2.2 Unified memory architecture across processors第二个观察是移动端和云端离散加速器不同移动 SoC 常常有UMAUnified Memory Architecture。CPU、GPU、NPU 在系统内存中共享地址空间这使得跨处理器通信更高效。这说明移动端异构计算既有挑战也有独特优势挑战设备差异大、同步贵优势不是 PCIe 式分离系统而是共享内存所以作者后续设计 fast synchronization正是建立在这个观察上。2.3 Multiple processors can improve memory bandwidth utilization第三个观察是单个处理器并不能吃满 SoC 总带宽。文中给了一个例子GPU 单独大约只能用到40~45 GB/s两个处理单元同时工作时可以接近60 GB/sSoC 理论带宽大约是68 GB/s。这个观察的意义是在 decoding 这种 memory-bound 阶段异构并行的主要收益不一定来自“更多算力”而可能来自更高的带宽利用率。这是非常 systems 的 insight。因为它说明优化目标不再只是 FLOPS而是SoC 整体资源利用率。3. HeteroInfer 的设计思想3.1 CPU、GPU、NPU 三者各自扮演什么角色作者对三种处理器做了明确角色分工CPU作为控制平面负责同步和 GPU kernel 调度不承担主要计算NPU主要计算单元负责大部分计算GPU次级计算单元用来抬高 NPU 的性能下界补足某些情况下 NPU 的短板。这里有两个很重要的系统判断。第一CPU 不适合当主算力单元原因是能效低又承担系统通用任务不适合被 LLM 推理长期占满这很符合移动系统设计逻辑。第二GPU 不是主角但很关键作者没有把 GPU 定位成主计算平台而是说它是辅助计算单元。这说明整篇文章的基调不是“GPU 统治一切”也不是“NPU 统治一切”而是按特性协同。3.2 HeteroInfer 依赖哪些性能特征作者明确说HeteroInfer 会综合考虑 GPU 和 NPU 的性能特征例如stage performanceorder-sensitive performanceshape-sensitive performance它回答了“为什么它能比别人快”不是因为它简单把算子切开而是因为它的切分策略建立在对硬件真实行为的建模上。4. “三个技术点”作者说为了支持 real-world mobile devices 上的 layer-level 和 tensor-level GPU-NPU parallelism他们用了三项技术。4.1 不同阶段用不同 tensor partitioning strategy第一项技术是在 prefill 和 decoding 两个阶段使用不同的 tensor partitioning strategy。这说明作者意识到两个阶段本质不同prefill更偏计算密集decoding更偏内存带宽密集因此分割 tensor 的方式不能一刀切。4.2 基于 predictable kernel waiting time 的快速同步第二项技术是 fast synchronization。作者利用 kernel 等待时间的可预测性实现微秒级同步。这背后的思想是LLM 各层结构重复执行模式高度规律所以可以预测等待时间而不是每次都用昂贵的通用同步机制。这是一种很典型的系统优化思路利用 workload 的结构规律替代通用机制。4.3 借助 profiler 的 tensor partitioning solver第三项技术是一个 solver用硬件 profiler 的结果生成最优切分方案。这说明作者不是手工写死策略而是先 profile再根据 profile 结果决策 partitioning这使系统更像一个hardware-aware runtime planner。5. Implementation作者说他们在Snapdragon 8 Gen 3上实现了一个工业级 LLM inference engineGPU kernel 用 OpenCL 开发NPU 侧接入 Qualcomm 的 QNN没有依赖 activation quantization 和 sparsity 来换速度因为这些可能影响模型精度。二、背景介绍Section 2.1LLM inferenceLLM inference 分成两个阶段prefill phasedecoding phase1.1 Prefill 是什么prefill 指的是用户把整段 prompt 一次性输入模型模型用这个输入批量计算生成第一个输出 token。因为输入序列可能很长所以这一阶段主要依赖matrix multiplication矩阵乘因此它是一个典型的computation-intensive workload。这其实在告诉你prefill 阶段优化的关键不是优先考虑同步或者细粒度调度而是要优先考虑谁的算力更强哪个后端更适合大矩阵乘怎么把计算吞吐拉高。1.2 Decoding 是什么decoding 则是自回归、逐 token 生成一次生成一个 token连续迭代执行。这一阶段主要涉及matrix-vector multiplication矩阵-向量乘因此它是memory-intensive workload。这意味着 decoding 优化目标已经变了不是简单追求更强算力而是要想办法提高内存带宽利用率并且同步开销在这里会更敏感因为单次算子执行时间更短。Prefill 和 decoding 的系统瓶颈不同prefill偏算力瓶颈decoding偏带宽瓶颈所以后面不能用统一策略这意味着后续系统设计一定要是stage-awarephase-specific也就是说prefill 重点考虑谁更适合做大规模 GEMMdecoding 重点考虑谁更适合稳定拿带宽以及怎样重叠执行减少等待。2. 为什么要专门比较“移动端推理引擎”作者先强调一个对比对象云端 LLM inference比如 vLLM、orca 等更关注高吞吐和 SLO移动端 LLM inference 更关注end-to-end latency。2.1 云端和移动端追求的目标不一样云端通常是多请求并发追求吞吐满足一批请求的响应时间目标。但移动端通常是单用户交互更关注首 token 出来得快不快更关注每个 token 生成得稳不稳。2.2 因此作者给出了两个更适合移动端的指标TTFTTime to First TokenTPOTTime per Output Token它们分别对应TTFT主要受 prefill 速度影响TPOT主要受 decoding 速度影响。作者不是只说“快”而是把“快”拆成两个维度首次响应快不快持续生成快不快。而用户体感往往受两者共同决定。Section 2.2Mobile-side Heterogeneous SoC3.1 为什么要把 LLM 放到本地设备作者再次强调为了隐私和安全用户更希望把 LLM 部署在本地而不是把个人数据传到云端。3.2 主流厂商都在往 edge-AI 平台演进作者举了很多主流 SoC 的例子Qualcomm Snapdragon 8 Gen 3Apple A18MediaTek Dimensity 9300Huawei Kirin 9000 等。这说明研究对象不是小众平台而是有现实产业代表性硬件趋势明确具有普遍意义。3.3 这些 SoC 的共同特征是什么作者指出为了满足 LLM 这类 AI 任务的高计算需求移动平台正在演进为heterogeneous SoC architecture即同时拥有CPUGPUNPU。其中 NPU 是专门为 ML workload 优化的处理器计算能力通常强于 CPU 和 GPU。3.4 统一物理内存作者还专门强调这些 heterogeneous processors 常常共享统一物理内存这和离散异构系统不同。它意味着移动端异构系统和服务器上 PCIe 连接的离散 GPU/NPU 不一样数据不一定需要通过昂贵的 host-device copy 才能共享更适合做跨处理器协同也为后面 HeteroInfer 的 fast synchronization 提供了架构基础。所以这篇文章一个很重要的切入点其实就是mobile SoC 的 UMA 让 GPU-NPU 协同成为可能但现有系统没有把它利用好。Table 2Table 2 列的是主流 mobile SoC 的规格。表面上是硬件罗列实际上是为了证明两件事。4.1 NPU 的理论能力已经很强比如表里可以看到Qualcomm 8 Gen 3Hexagon NPUINT8 算力远高于 GPU FP16Apple、MTK、Nvidia、Tesla 也都是类似趋势。也就是说NPU 已经不是“附属单元”而是 AI 计算主力候选。4.2 但 GPU 仍然有不可替代性虽然 NPU 强但 GPU 也有高通用性和成熟的软件栈。这为文章后面提出 GPU-NPU 协同提供了现实基础NPU 不能完全替代 GPUGPU 也不能完全替代 NPU更合理的做法是按 workload 特性协作。表里有一句注释说厂商没有公开 NPU FP16 精确算力文中粗略按 INT8 算力的一半估计。这其实也说明了一个研究现实NPU 相关信息通常不透明真正系统优化不能只靠厂商参数表必须做 runtime characterization。这也是为什么这篇文章要自己 profile 和刻画硬件。Section 2.3研究缺口归纳Table 1 比较维度很多大致包括支持哪些 backendCPU / GPU / NPU支持 INT 还是 FPNPU 的 GEMM typeprefill 用哪个后端decoding 用哪个后端accuracy 是否受影响overall performance 高低。作者系统地说明现有框架在三个维度上都有取舍后端支持不完整精度可能下降性能未必最优。作者自己的方案“Ours” 这一行强调CPU/GPU/NPU 都支持GPU 和 NPU 都支持 INT / FPNPU GEMM type 是 FLOATprefill 和 decoding 都支持 GPU NPUaccuracy 不受影响performance 高。第一个研究缺口缺口一没有真正实现 GPU 与 NPU 的计算并行作者明确说现有研究虽然知道 GPU 和 NPU 都能加速 LLM workload而且它们对不同 operator 有不同 affinity但大多数工作仍只用单一加速器。例如MLC 和 MNN-LLM 基本只用 GPUPowerInfer 和 llm.npu 更偏 NPU。为什么这件事难作者说核心难点在于heterogeneous processors 之间的数据同步困难workload 如何高效切分到不同 backend 也困难。这两个问题合起来本质就是异构并行不是“支持多个 backend”这么简单而是要解决协同执行问题。这里已经能看出后文一定要回答两件事如何 partition computational workloads如何 efficiently synchronize data。第二个研究缺口缺口二没有在“不掉精度”的前提下充分利用 NPU作者指出NPU 是现代 SoC 中最强的计算单元但现有框架大多只利用 NPU 的INT capability来做低精度计算而没有充分利用它的FLOAT capability。为什么这会有问题因为用 INT4/8 做计算会带来明显精度下降。作者举例说 Qualcomm-AI 甚至报告过20% 的精度下降尤其对小型边缘模型影响更明显。这说明很多现有工作本质是在做一种交换用精度换速度但作者想证明的是不一定非要这么交换也可以通过系统级协同在保持精度的前提下提速。llm.npu 为什么仍不够理想作者提到 llm.npu 试图通过找 tensor outliermixed-precision来缓解精度问题。但它的问题在于对输入数据集敏感推理精度可能依赖用户输入。这对于真实用户场景显然不够稳。为什么 FLOAT NPU 也不好直接用作者还提到之前也有人尝试利用 NPU 的 FLOAT capability但效果通常不理想。原因是由于 NPU 的硬件结构特性FLOAT performance 会随着 tensor shape 和 ordering 明显变化。它其实就是下一节“performance characteristics”的前导NPU 慢不是因为 FLOAT 本身不行而是因为如果 tensor 不合适NPU 的 FLOAT 执行效率会崩。三、性能特性作者开头先说为了有效利用 heterogeneous processors他们先分析GPU 的性能NPU 的性能memory system 的性能。并且作者特别强调不同加速器因为硬件架构不同会表现出不同性能特征尤其是 NPU对不同 tensor type 和 operator 的性能波动非常大。1. GPU Characteristics1.1 GPU-1Linear Performance作者先看 GPU 的矩阵乘性能Figure 1 展示了随着 tensor size 变化GPU 性能如何变化。结论是当 tensor 很小时GPU 是memory-bound随着 tensor 变大总 FLOPS 近似线性上升超过某个阈值后GPU 转为computation-bound此时 FLOPS 基本稳定。这意味着 GPU 的性能趋势比较“平滑”和“可预期”小问题上GPU 发挥不出来问题规模一旦上去性能就会稳定它不像 NPU 那样会因为某个 tensor shape 突然掉到很差。所以从系统设计角度看GPU 有两个优点第一GPU 对动态 shape 更友好因为它的性能变化更连续不像 NPU 那样台阶式突变。后面文章在 dynamic-shape 场景里让 GPU 处理不规则部分就是利用这个特性。第二GPU 适合作为“性能兜底”当某些 tensor shape 不适合 NPU 时GPU 能提供更稳的性能下界。这也是作者为什么把 GPU 定位为 secondary computing unit而不是完全边缘化。1.2 GPU-2High-cost Synchronization作者接着说移动 GPU 有两个主要同步开销来源数据拷贝显式同步命令 clFinish 带来的固定延迟。第一类开销数据拷贝虽然移动 SoC 有统一物理内存但现有 GPU framework 仍常维护相对独立的 GPU memory space。因此开发者仍需通过类似clEnqueueWriteBuffer这样的 API把数据从 CPU buffer 传到 GPU memory。这说明架构上可以共享内存但软件栈未必天然把共享能力发挥到最好。第二类开销显式同步作者测到clFinish在他们平台上会引入大约400 微秒固定延迟。它的本质是阻塞后续 GPU kernel 执行同步 GPU driver 的状态保证 CPU 和 GPU 视图一致。400 微秒听起来不大但在移动端尤其在 decoding 阶段非常致命因为decoding 中单个 kernel 的执行时间本来就很短如果一次同步成本已经接近 kernel 计算时间那么异构并行收益会被同步吃掉。如果不能绕开这种昂贵同步GPU-NPU 并行基本没有实用价值。2. NPU Characteristics作者先说明虽然 NPU 实现多种多样但其中最关键的核心通常是matrix computation units典型形式就是systolic array。Figure 2 画的是一个典型的 NPU 结构简单说NPU 最擅长的场景是权重尽可能驻留在阵列里输入不断流过尽量减少反复加载权重的开销。这和 GPU 的通用并行模式不一样。GPU 更像是一个广义吞吐机器而 NPU 更像是一个为矩阵流式计算特化的装置。这个结构直接决定了后面的三种 NPU 性能特征作者说正因为这种计算范式NPU 会呈现三种特性stage performanceorder-sensitive performanceshape-sensitive performance。这不是经验现象而是由硬件数据流方式决定的。2.1 NPU-1Stage Performance作者先讲第一种特性stage performance。现象由于 NPU 内部 systolic array 大小固定Matmul 所用 tensor 的维度不一定和矩阵计算单元尺寸对齐。这种不对齐会导致 NPU 计算资源利用不充分从而出现不同 tensor size 下的“台阶型性能”。Figure 3 就展示了这一点随着 K size 增大执行时间不是平滑变化而是呈现明显“台阶”。为什么会出现台阶作者举例说在 Snapdragon 8 Gen 3 上NPU 配有多个32×32 systolic arrays。因此任何维度小于 32 的 tensor在硬件看来其实占用的是同样一块阵列资源所以 latency 可能几乎一样。更进一步当 tensor dimension 不能被硬件 tile size 整除时编译器还要加 internal padding 来对齐这又会造成额外浪费。这个特性对系统设计的含义这意味着某些短 sequence 或某些小张量放到 NPU 上其实不划算NPU 对 tensor size 的敏感性远大于 GPUruntime 不能只根据“算量多少”决定是否上 NPU还必须看 shape 是否落在好区间。这也是后面为什么decoding 阶段很多时候反而 GPU 更占优prefill 动态长度场景需要 clever partition而不能只 padding。2.2 NPU-2Order-sensitive Performance这一部分是这篇文章最有意思的 insight 之一。作者考虑两个 tensor[M,N][N,K]且满足 MNK普通矩阵乘 [M,N]×[N,K] 的计算量是 2MNK。如果把顺序反过来看成 [K,N]×[N,M]总计算量并没有变。但作者说对 NPU 来说这两种写法性能可能差很多Figure 4 的例子里[14336,4096]×[4096,K]相比 [K,4096]×[4096,14336]可快6×。为什么数学上等价硬件上却不等价原因就在于 NPU 的weight-stall计算范式。理想情况下weight tensor 能很好地驻留在矩阵计算单元中输入流过阵列权重不需要频繁重新加载。但如果weight tensor 比 input tensor 大得多那就意味着权重没法稳定驻留必须频繁从 memory/load buffer 重新送入阵列memory overhead 急剧上升。于是尽管两种 Matmul 的算术操作数一样但由于“谁被当成 weight谁被反复加载”不同性能会完全不同。最极端情况意味着什么作者甚至说如果 weight matrix 无限大matrix computation unit 就无法享受 weight-stall 的优势NPU 性能可能退化到与 GPU 类似甚至更差。它本质上是在说NPU 的高性能不是普适真理而是建立在“权重复用成立”的前提下。2.3 NPU-3Shape-sensitive Performance作者接着讲第三种特性shape-sensitive performance。现象即便在 input tensor 大于 weight tensor 的情况下NPU 的效率仍然受到行数与列数比例的显著影响。更具体地说当 input tensor 的 row size 大于 column size 时NPU 性能更好。在 Figure 4 中蓝线和紫线对比就体现了这一点。为什么会这样因为 input tensor 的 column size 与 weight tensor 共享维度。如果这个 column size 很大就意味着weight tensor 也会随之变大权重驻留难度变高weight-stall 优势被削弱。所以 shape-sensitive 的本质仍然和 weight-stall 有关只不过这里强调的是矩阵长宽比本身会改变 NPU 的数据流效率。这件事为什么很重要这说明就算两个 tensor 的总元素数接近只要长宽比不同NPU performance 也可能差很多。换句话说NPU 对 tensor 的“几何形状”敏感而 GPU 更多是对“问题规模”敏感。这也是为什么文章后面提出weight-centric partitionactivation-centric partitionhybrid partition这些 partition 不只是为了把工作分给两个后端更是为了把 tensor 切成更适合 NPU 的形状。3. SoC Memory Bandwidth前面更多是讲算力侧这一小节则转到 memory system。作者提出一个结论虽然 mobile SoC 采用统一地址空间但在 LLM decoding 中没有任何单个处理器能吃满 SoC 总带宽。3.1 Figure 5作者在 Snapdragon 8 Gen 3 上测得理论峰值带宽68 GB/s实际最大可达带宽约61.9 GB/s这个最大值只有在连续大块内存操作时才能接近获得。但在 decoding workload 下CPU / GPU / NPU 单独运行时都只能达到大约40–45 GB/s。相反GPU 和 NPU 并发执行时总带宽利用率可升到大约60 GB/s。这说明 decoding 里的关键矛盾不是“算力不够”而是单处理器无法把整个 SoC 的 memory channels 利用起来。也就是说一个 processor 不是不能做 decoding而是它只能吃到 SoC 总带宽的一部分。如果能让多个 processor 同时参与并避免相互干扰反而能更接近系统级带宽上限。3.2 为什么 GPU-NPU 共跑能更高作者认为这是因为当代 mobile SoC 配备多个 memory channelsheterogeneous processors 的 co-execution 能更充分利用整个 SoC 带宽其中一个有效案例是75/25 的 workload split可以把 GPU computation 与 NPU computation / synchronization overhead 重叠起来。这句话非常关键。它意味着 decoding 阶段里分工的意义不只是“两个设备分别算一点”而是通过任务切分把不同设备的访存路径和执行时间重叠起来从系统角度把带宽吃满。GPU 的规律GPU 性能随着问题规模增加比较线性但同步成本高。所以 GPU性能平稳适合不规则 / 动态 shape但不能随便和别的后端细粒度交替因为同步太贵。NPU 的规律NPU 强但不稳定强烈依赖 stage、order、shape根源在于 systolic array 和 weight-stall 数据流。所以 NPU适合特定 tensor一旦 tensor 不对性能可能大幅退化不能粗暴把所有 matmul 都交给它。Memory 的规律decoding 时单设备吃不满总带宽多设备协同反而更接近上限。所以 decoding不应只看单核/单设备算力必须看 SoC 级别资源利用。