1. 先说清楚:AutoGLM 这类手机 Agent,为什么成了 AI 芯片的"场景级裁判"
1.1 AutoGLM 场景到底在跑什么负载
AutoGLM 是智谱推出的手机操作智能体,说白了就是让 AI 像人一样看手机屏幕、分析界面、模拟点击和滑动,把一个完整任务(比如订外卖、查航班、填表单)自动跑完。它跟普通的大模型应用有本质区别:普通应用是"一次对话,一次生成",而手机 Agent 是一条长链路、多模型接力、反复执行的过程。
具体拆开,每一个操作步骤都包含三个阶段:
- 视觉感知:把当前手机截图送入视觉模型,识别按钮、文本框、列表项的位置和语义。
- 意图规划:把"当前屏幕状态 + 用户目标"送给语言模型,决定下一步该点哪里、该输入什么。
- 动作执行:把决策结果映射成可执行的动作序列,输出到手机 UI 自动化框架,等待界面变化后回到第一步。
这意味着,跑一个 Agent 任务不是在跑一个模型,而是在连续跑无数个小模型推理。每点一次屏幕,可能就要做一次视觉推理、一次语言模型推理、一次动作分类。整个会话维持几分钟甚至更久,期间模型不能中断、不能卡顿、不能越来越热。
这个负载特征,和传统的单模型端侧推理完全不同,也就决定了芯片适配的思路要换一套。
1.2 为什么说它是 AI 芯片的"场景级裁判"
以往芯片评估大多围绕单模型跑分,比如跑一个 7B 量化模型,看每秒能生成多少个 token、内存占用多少、功耗多少。这种评估有一个致命短板:单模型场景可以靠"堆算力"掩盖问题,而 Agent 场景不行。
手机 Agent 是典型的"多重负载叠加 + 长时间连续运行"场景:
- 视觉模型、语言模型、动作模型在一个进程里反复切换;
- 屏幕截图受分辨率影响,视觉输入的张量尺寸不稳定;
- 用户操作有等待时间,AI 推理必须赶在界面动画结束前完成,否则会出现点击错位;
- 长时间运行下,芯片发热降频,最后几个步骤的体验会明显劣化。
所以只要把 AutoGLM 的场景搬到某颗芯片上,跑完整任务、记录全程表现,就能暴露出这颗芯片在调度能力、内存带宽、算子兼容性、功耗管理多个维度上的真实水平。这比任何单模型跑分都有说服力。
我这次评估的目标,就是要对一颗移动端 AI 芯片给出结论:它能不能撑住 AutoGLM 的典型任务,适不适合做手机 Agent 的端侧部署载体,以及必须做哪些适配才能达到"可用"标准。
2. 评估维度设计:别上来就跑分,先定"什么样算能用"
做芯片适配评估最忌讳的就是直接拿模型去跑,跑出来一堆分数却不知道好不好。正确做法是先定义可用性标准,再拆解成可量化的指标。
2.1 端到端延迟预算拆解
手机 Agent 对延迟极其敏感。我先把一次完整操作的时间预算拆成四段:
| 阶段 | 动作 | 参考预算 | 说明 |
|---|---|---|---|
| T1 | 截图 + 预处理 | 50~100ms | 截图采集、缩放、归一化 |
| T2 | 视觉模型推理 | 150~300ms | 实时识别界面元素 |
| T3 | 语言模型推理 | 200~500ms | 决策下一步动作 |
| T4 | 动作执行 + 界面反馈 | 200~400ms | 等待 UI 响应和动画完成 |
单轮操作总预算控制在 1 秒左右。这是基于常见实践补充的参考值,实际产品可以根据交互频率调整,但整体量级不会差太多。
这里有个容易被忽略的点:T2 和 T3 不能简单相加。视觉模型输出后,语言模型拿到的输入包含了对屏幕元素的描述,两个模型之间有中间数据处理。如果芯片的异构调度做得好,T2 和 T3 之间可以部分重叠;调度不好,这里会产生额外损耗。
2.2 内存与带宽约束
手机 Agent 端侧跑,模型权重和激活值必须全部待在内存里。我这次评估采用的模型组合大约是:
- 视觉编码模型(量化后约 400~600MB)
- 语言模型 7B 级别,Q4 量化后约 3.5~4GB
- 动作分类层和临时缓存,约 200~500MB
整体常驻内存接近 4.5~5.5GB。对内存带宽的压力更为严峻:每一步操作都要反复读取语言模型的权重,7B 模型即使量化后,每生成一个 token 也要搬运接近 4GB 的权重数据。这个量意味着,如果芯片的内存带宽不够,再强的算力也发挥不出来。
2.3 功耗与热约束
手机和开发板不同,没有主动散热,芯片必须在功耗预算内稳定运行。我在评估时限定:
- 平均功耗不超过 3W(不含屏幕)
- 峰值功耗不超过 6W(持续不超过 5 秒)
- 连续跑 10 分钟以上,核心温度不允许触发大幅降频
功耗指标直接决定了这个方案的落地可能性。跑分芯片再强,如果连续满负载运行三分钟就开始降频,那在真实 Agent 场景里就是不可用的。
2.4 关键角色:稳定性和确定性
最后还得把稳定性纳入核心指标。Agent 场景里,模型推理结果直接影响 UI 操作,一个 token 的错误可能导致点击错位、重复提交、甚至应用崩溃。
我统计了"任务成功率"和"异常操作率"两个指标:
- 任务成功率:完整跑完一个预定义任务的比例;
- 异常操作率:推理过程中出现超时、返回空结果、输出非法动作的比例。
这两个指标往往被人忽略,但它们才是 Agent 能不能真正商用的关键。
3. 适配策略拆解:按负载类型分派到不同的计算单元
明确评估维度之后,下一步就是设计适配方案。手机 Agent 的负载不是单一类型,硬塞到某一个计算单元里往往效果最差。
3.1 三层负载的硬件特性分析
我把 AutoGLM 场景的负载分成三类,每一类对硬件的诉求完全不同。
第一类,视觉感知负载。输入是 1080P 级别的手机截图,经过缩放后通常是 384×384 或 448×448 左右的分辨率。视觉模型以卷积和注意力混合结构为主。这个负载的特点是数据量巨大、单次推理延迟要求高、模型参数量相对小。NPU 的矩阵乘法和卷积加速能力在这里能发挥最大价值。
第二类,语言理解负载。7B 级别的语言模型,Q4 量化后权重约 3.6GB。这是整个链路里计算量最大的部分,也是内存带宽消耗的大头。GPU 和 NPU 都能跑,但差异很大:NPU 对整数精度的支持通常较强,GPU 对浮点计算更友好,CPU 则胜在兼容性。
第三类,动作决策负载。这部分主要是从语言模型的输出映射成具体的操作坐标和类型。计算量小,但对确定性和实时性要求极高,需要在毫秒级内完成,且不允许出错。这部分我倾向于用 CPU 完成,原因很简单:CPU 调度最确定,不会被其他计算单元的任务挤占。
3.2 三种适配方案的设计思路
我基于这个分层设计了三种方案对比:
方案 A:全 CPU 执行。作为一个基线方案,把所有模型跑在 CPU 上,用多线程优化。这个方案的优点是零适配成本,模型随便跑;缺点是视觉模型在 CPU 上的效率偏低,整体延迟很难压住。
方案 B:NPU 卸载策略。把视觉模型和语言模型都部署到 NPU 上,CPU 只负责数据预处理、动作执行和调度。这是理论上最优的方案,但依赖 NPU 对模型的算子支持情况,需要做量化校准和算子适配。
方案 C:异构混合策略。视觉模型走 NPU,语言模型走 GPU,动作决策走 CPU。这个方案在理论上兼顾了各计算单元的优势,但多单元之间的数据拷贝和调度同步会成为新的瓶颈,需要精细优化。
评估下来,我发现一个反直觉的结论:方案 B 的理论性能最高,但在真实任务里反而最容易出问题。原因后面会详细说。
3.3 量化方案与精度取舍
端侧跑大模型,量化是绕不开的。我这次的量化策略是分模型区别对待:
- 视觉模型用 INT8 量化,特征提取对精度相对不敏感,INT8 足够;
- 语言模型用 INT4 量化,但保留了部分敏感层为 INT8,避免质量劣化;
- 动作输出层保留 FP16,确保操作指令的准确性。
光说超出量化精度:语言模型直接全 INT4 量化后,我测试了几个典型任务,发现"识别界面元素位置"这类需要细粒度空间感知的任务,错误率会明显上升。后来我在量化校准数据集里补充了大量手机截图样本,错误率才降回去。
这里分享一个经验:校准数据集一定要用目标场景的真实数据。用通用文本数据集做校准,量化出来的模型在手机截图识别场景里通常会"水土不服"。
4. 评估执行:把 AutoGLM 场景搬到芯片上的完整流程
4.1 环境搭建与评估脚本
我把评估环境拆成三部分:模型运行时、UI 自动化框架、指标采集模块。UI 自动化使用开源手机控制框架,通过 ADB 协议与设备通信;指标采集模块负责记录每步推理的耗时、内存、功耗和温度。
下面是评估脚本的核心骨架,用 Python 写的,关键在采集每个阶段的耗时:
import time import threading from dataclasses import dataclass @dataclass class StepMetrics: stage: str elapsed_ms: float memory_mb: float power_mw: float class AgentEvaluator: def __init__(self, runtime): self.runtime = runtime self.metrics = [] def run_task(self, task_desc: str): max_steps = 50 for step in range(max_steps): start = time.perf_counter() # 1. 截图与预处理 screenshot = self.runtime.capture_screen() preprocess_done = time.perf_counter() # 2. 视觉模型推理 visual_result = self.runtime.visual_infer(screenshot) visual_done = time.perf_counter() # 3. 语言模型决策 action = self.runtime.llm_decide(visual_result, task_desc) llm_done = time.perf_counter() # 4. 动作执行 self.runtime.execute_action(action) exec_done = time.perf_counter() self.metrics.append(StepMetrics( stage=f"step_{step}", elapsed_ms=(exec_done - start) * 1000, memory_mb=self.runtime.current_memory_mb(), power_mw=self.runtime.current_power_mw(), )) # 检查任务是否完成 if self.runtime.check_task_done(): return True return False实际评估时,我还会用perfetto做细粒度的耗时抓取,区分算子级耗时和调度耗时。这个脚本只负责业务层的指标采集,两者配合才能定位真正的瓶颈。
4.2 实测数据:三种方案的差异
我手里的测试平台是 2024 年款旗舰级移动芯片,跑的项目是"自动在外卖 App 里完成一单下单流程",步骤数大约 20 步。实测结果如下:
| 指标 | 方案 A(全 CPU) | 方案 B(全 NPU) | 方案 C(混合) |
|---|---|---|---|
| 单步平均耗时 | 1.8s | 0.9s | 0.7s |
| 首 token 延迟 | 420ms | 180ms | 150ms |
| 平均内存占用 | 4.8GB | 5.1GB | 4.9GB |
| 峰值功耗 | 7.5W | 5.2W | 6.8W |
| 任务成功率 | 100% | 78% | 95% |
| 异常操作率 | 0% | 11% | 2% |
注意这里的功耗数字包含整机功耗,但不包含屏幕和外设,只做相对比较。
看完这个表,你大概能理解我前面说的"方案 B 反直觉"了:它的速度快、功耗低,但任务成功率只有 78%。这在真实的 Agent 场景里是不可接受的——跑十次任务,有两次会在中途卡住或点错。
4.3 方案 B 翻车的根因分析
我抓了详细日志,发现方案 B 的问题集中在两处:
第一处,NPU 上视觉模型的输出存在少量数值偏差。这些偏差不是随机的,而是集中在图像边缘的低对比度区域。手机截图里的按钮边缘、半透明背景,恰好都是低对比度区域,结果就是视觉模型把不该识别的元素识别出来了,或者漏掉了关键按钮。
第二处,NPU 与 CPU 之间的任务切换不稳定。NPU 在执行长任务时,偶尔会出现任务排队延迟,尤其是手机同时有系统更新等后台任务时。这个排队延迟直接导致某一步推理超时,Agent 的状态机就会误判当前界面状态,产生错误操作。
方案 C 之所以成功率高,是因为它把最容易出错的视觉模型放到了 NPU——这部分算子简单、适配成熟;把语言模型放到了 GPU,避免 NPU 上的大模型量化精度损失;动作决策放 CPU,保证了确定性。三者的优点都保留了,缺点被隔离开。
5. 最终评估结论:适配的关键是"分工",不是"全塞"
5.1 结论一:纯 CPU 方案不适合长期使用
纯 CPU 方案虽然稳定性最好,但单步 1.8 秒的延迟在真实交互里体验太差。用户点完一个按钮,要等接近两秒才看到下一步动作,这种体验很难被接受。而且长时间高负载下 CPU 的功耗和发热问题最严重,续航和手持舒适度都会受影响。
纯 CPU 方案可以当作调试手段和基线参考,但它不具备产品落地价值。
5.2 结论二:NPU 全卸载是"看起来很美"
方案 B 的理论优势最强,但实际可用性被两个因素拖累:一是量化精度损失在视觉任务上的放大效应,二是 NPU 调度不确定性引入的偶发错误。这两个问题不是单靠软件优化就能完全解决的,需要芯片层面提供更稳定的任务调度保证。
如果芯片厂商后续能在 NPU 上解决"长时间任务调度抖动"的问题,同时把视觉模型的量化精度做到可接受范围,方案 B 的潜力是最大的。目前来看,它更适合作为离线处理场景的方案,不适合直接用于对成功率要求极高的在线操作场景。
5.3 结论三:混合异构是最稳妥的落地路径
我在多轮测试里反复验证,按负载类型分派计算单元的思路在这个场景里是最稳的:
- 视觉感知放 NPU:算子适配成熟,充分利用卷积加速能力;
- 语言模型放 GPU:避免量化精度损失,生成质量更有保障;
- 动作决策放 CPU:保证确定性和低延迟;
- 调度和数据中转由一个轻量级运行时统一管理。
这种方案的核心价值在于"故障隔离"。任何一个计算单元出问题,其他部分依然可以工作,Agent 至少不会完全失控。这在真实场景里非常重要——宁可慢一点,也不能出幺蛾子。
5.4 适配评估的总表
把这次评估的结论压缩成一张决策表:
| 计算单元 | 适合的负载 | 主要优势 | 主要劣势 |
|---|---|---|---|
| CPU | 数据预处理、动作决策、调度 | 确定性强,兼容性最好 | 大模型推理效率低 |
| NPU | 视觉感知、定长小模型 | 能效比高,延迟低 | 量化精度损失,调度偶发抖动 |
| GPU | 大语言模型生成 | 浮点精度好,吞吐高 | 功耗偏高,驱动开销大 |
我的结论很明确:在手机 Agent 场景下,AI 芯片适配的关键不是把整个模型塞进最快的计算单元,而是让每个环节的负载跑到最合适的计算单元上,同时用软件把不确定性隔离掉。
这个结论也侧面说明了一个趋势:AI 芯片的评估标准正在从"单模型跑分"转向"复杂场景完成度"。谁能在真实 Agent 任务里交出稳定的成功率,谁才是真正适合端侧智能体的芯片。
6. 实测路上踩过的坑:给同样在做适配的开发者一些参考
6.1 坑一:NPU 量化模型"看着正常,用着踩雷"
我最初把视觉模型全量 INT8 量化后部署到 NPU,单看跑分数据非常好,延迟直接降了 40%。但实际跑 Agent 任务时,发现问题集中在"半透明弹窗"和"页面刷新动画"两个场景:AI 频繁误判弹窗位置,或者把动画中的残影当作可点击按钮。
后来排查,发现是量化校准集里缺少这类"界面过渡状态"的样本。解决方法是把手机自动化测试跑到一半强制暂停,采集 500 张中间状态的截图,加入校准集重新量化。处理后误判率显著下降。
6.2 坑二:算子回退导致"隐形性能陷阱"
有一次我把语言模型部署到 GPU,单看每个算子的耗时都正常,但整体任务延迟却比预期高了一倍。用 profiler 抓了之后才发现,模型里有个LayerNorm算子在 GPU 驱动里没有优化实现,运行时悄悄回退到了 CPU 执行。
这个回退本身不慢,但它在每一层 transformer 都会发生一次,GPU 和 CPU 之间的数据同步就成了最大的开销。解决方法是把这个算子融合到前面的矩阵乘算子中,或者换一个等效实现绕开它。
6.3 坑三:冷启动和热切换的性能差一倍
同一个模型,在设备刚开机、内存干净的"冷启动"状态下跑,和在一堆后台应用运行着、内存紧张的"热切换"状态下跑,性能差异可以接近一倍。
在做评估时如果只测冷启动状态,拿到的结论会过于乐观。正确的评估姿势是:先把设备折腾到典型用户状态——后台挂着微信、消息推送开着、屏幕亮着——再开始跑测试。这样得到的指标才能反映真实用户体验。
6.4 坑四:别只看平均功耗,要看温度曲线
平均功耗 3W 看起来很美,但如果功耗曲线不平滑,呈"锯齿状"波动,芯片温度就会被推上去。我测过一台设备,平均功耗才 2.8W,但每 30 秒就出现一次 6W 的尖峰,连续跑 8 分钟温度直接触及降频阈值。
解决方向有两个:一是调整模型调度策略,把大推理任务拆开,避免多个计算单元同时进入高负载;二是用芯片的 DVFS 接口做功耗整形,把尖峰磨平。
6.5 一个值得留意的方向:长会话稳定性测试
手机 Agent 场景天然是长会话。我测试过跑 50 步以上的任务,发现内存泄漏比想象中普遍——有些中间结果没有被及时释放,导致任务越跑越慢,最终触发系统 OOM。
建议做评估时,任务步骤数一定要覆盖到实际使用上限的两倍以上。如果 50 步没问题,就测 100 步;如果 100 步没问题,试试连续跑多个任务。长会话稳定性大概率会成为端侧 Agent 落地的关键瓶颈。
最后说几句我自己的体会
做这次评估下来,最深的感触是:跑 Agent 和跑单个模型完全是两种心态。单模型推理追求峰值性能,Agent 场景追求的是持续、稳定、可预期。芯片再强,如果不能保证连续十分钟的稳定输出,那就只能当一个跑分工具,做不了生产力。
如果各位手头也在做类似的端侧 Agent 适配,我的建议是从混合异构做起,先保证成功率,再优化速度。同时一定要把"长会话稳定性"和"温度曲线平滑度"纳入核心评估指标,这两个东西在早期容易被忽略,但到了产品阶段几乎是决定生死的因素。后续如果芯片厂商的 NPU 调度能做到任务级别的确定性保证,我觉得全 NPU 方案会重新变成最优解,那一天应该不会太远。