要聊端侧推理(edge inference / on-device inference),绕不开功耗和热这两个硬约束。跑在手机、机器人、智能摄像头、可穿戴设备上的神经网络模型,和云端 GPU 集群完全不同——云端顶多考虑电费和散热成本,端侧直接面对的是“电池能用多久”和“芯片会不会热到降频”这两个生存级问题。动态调频、热节流、持续能效评估,这三个词串起来,其实是端侧推理性能真实水平的全部真相。
这篇文章的缘起,是我去年帮一个团队做智能相机的端侧检测模型落地。模型在开发板规格页上写着 2.7 TOPS,号称跑 YOLOv8s 能到 30 FPS。结果装进产品外壳、盖上防尘罩、连续跑 20 分钟后,帧率掉到 21 FPS,机身表面温度冲到 58 度。规格书上的数字没错,但它写的是瞬时峰值,不是持续推理能达到的水平。那段时间我基本都在跟热节流(thermal throttling)和调频器(governor)较劲。
这篇文章适合三类人:正在做端侧模型部署的工程师、需要选型硬件平台的架构师、负责功耗评测的测试人员。我会从动态调频的原理讲起,再拆热节流的触发机制,最后完整讲一遍持续能效评估的测试方法和参数选择。全程不写云端,不写抽象理论,只讲端侧设备上你直接能用的工程经验。
1. 端侧推理为什么绕不开功耗与热约束
1.1 端侧和云端性能概念完全不同
很多刚从云端转到端侧的工程师,第一个掉进去的坑就是把 GPU 集群的思维方式带过来。云端推理追求的是“低成本算力规模”,瓶颈是吞吐和批量大小;端侧推理追求的是“每瓦特能出多少有效帧”,瓶颈是电池、散热、裸片温度和实时性。
以手机上的 NPU(神经网络处理器)为例,它的峰值算力通常能到 10 TOPS 以上,但持续满负载跑几秒钟就会触碰到热约束。这里面的物理原理不复杂:任何半导体芯片在工作时的功耗,主要分为动态功耗和漏电功耗两部分,动态功耗与频率成正比,与电压的平方成正比;漏电功耗则和结温强相关。频率拉高,电压就要跟着拉高,功耗曲线是指数级的,不是线性的。所以频率从 1.0GHz 提到 1.4GHz,性能可能只提升 1.4 倍,功耗却可能是原来的 2.3 倍。
端侧的散热条件天然受限。手机内部是一块半导体制冷片都塞不下的密闭空间,智能摄像头要防水防尘,机器人控制器要过车载振动标准。这些因素决定了设备存在一个“热预算”——在不超过结温和壳温限制的前提下,能够从机身内部传导出去的热量上限。热预算不足,就意味着算力平台无法持续跑在峰值状态。
1.2 热约束如何决定端侧真实性能
端侧设备的热约束一般体现在四个层级:
- 结温限制(Tj max):芯片裸片允许的最高结温,通常在 85~105 度之间,超过就触发硬件级保护。
- 壳温限制(skin temperature):人手能接触到的外壳温度,消费电子一般限制在 45 度左右,烫手属于安全设计缺陷。
- 功耗墙(power budget):产品定义的持续功耗上限。比如手机主板给 NPU 的功耗预算是 3W,持续超过会和 CPU、GPU 互相抢功率输出。
- 热平衡点(thermal equilibrium):设备在特定负载和环境温度下,最终达到的稳定温度。这个点决定了长时间运行的稳态性能。
我一直跟团队强调一句话:规格书上的 TOPS 是实验室的瞬时值,热平衡点的 TOPS 才是产品的真实值。评估一个端侧平台能不能用,不是看它在空冷、25 度环境下跑出来多少帧,而是看在产品外壳、40 度环境温度、连续运行的条件下,稳态帧率还能剩多少。持续能效评估(sustained efficiency evaluation)解决的问题,恰恰就是这个。
2. 动态调频:端侧算力的油门控制
2.1 DVFS 的基本工作机制
动态调频在工程上称为 DVFS(Dynamic Voltage and Frequency Scaling),也就是动态电压频率调节。端侧平台上的 CPU、GPU、NPU 各有各自的频率域,操作系统的 cpufreq 子系统负责 CPU 域调频,NPU 的频率通常由厂商私有驱动管理,通过 sysfs 节点向上暴露给应用层。
DVFS 的触发逻辑可以分两类:响应式调频和主动式调频。响应式调频最常见,调度器发现 CPU 或者 NPU 负载升高,就向调频器申请提高性能等级;负载下降后再逐步回落。主动式调频是 SoC 内部的系统级控制器根据温度传感器、电流传感器以及任务特征,主动对频率做限制或者抬升。
其中有一个细节容易被忽视:不同调频器(governor)的决策周期差别很大。Linux 自带的 ondemand、conservative、userspace 等 governor,决策周期通常是毫秒级到几十毫秒。而 NPU 驱动的频率管理往往是以“帧”为单位做决策的,比如连续 3 帧推理时间低于预算,就降一档频率省电;连续 5 帧超时,就抬一档频率保性能。这种频率切换本身也要消耗能量,如果系统在最高频和最低频之间频繁抖动,反而会增加动态功耗。我自己实测过,把调频器的迟滞参数调大之后,同样的负载下整机功耗能降 8% 左右,帧率反而更稳定。
2.2 频率选择背后的功耗与散热权衡
我实测过一块 8 TOPS 级边缘 AI 模组,它的 NPU 有四个频率档位:最低 550MHz,常态 880MHz,高频 1.1GHz,峰值 1.3GHz。在室温裸板条件下,分别跑同一个检测模型,功耗和帧率的数据非常典型:
| NPU 频率 | 整机功耗(W) | 平均帧率(FPS) | 每帧功耗(J) |
|---|---|---|---|
| 550 MHz | 4.2 | 18 | 0.233 |
| 880 MHz | 5.6 | 25 | 0.224 |
| 1.1 GHz | 7.1 | 30 | 0.237 |
| 1.3 GHz | 9.3 | 32 | 0.291 |
这张表的信息量很大。从 880MHz 提到 1.1GHz,性能提升了 5 帧,每帧功耗只增加 0.013 焦耳,性价比很高。但从 1.1GHz 提到 1.3GHz,帧率只提升 2 帧,每帧功耗却从 0.237 涨到 0.291,能效下降了 22%。这说明端侧存在一个“能效甜点频率”,也就是每帧能耗最低的工作点。工程上做调频策略,目标不是让设备一直跑最高频,而是找到功耗和性能曲线交点上最划算的那一档。
如果把这个测试放到密闭外壳里再跑一遍,结果会更有意思:1.3GHz 持续跑 5 分钟后,结温升到接近降频阈值,NPU 自动跳回 1.1GHz 甚至 880MHz,峰值档位的意义只剩“短时爆发”。所以做产品定义时,必须明确区分两种需求:持续负载型应用(视频流检测)需要的是热平衡点上的稳态性能;突发型应用(点击后的单次识别)可以使用峰值性能。
2.3 调频策略的实际配置与验证
在 Linux 端侧平台上,调频配置的可操作性很强。CPU 域通过 cpufreq 节点配置:
# 查看当前可用的 governor cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors # 切换到 performance(固定最高频)或 schedutil(基于调度器负载) echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor # 限制最大频率,比如 1.5GHz echo 1512000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freqNPU 域通常由厂商 SDK 管理,但一般也会暴露 devfreq 节点。以瑞芯微 RK3588 的 NPU 为例,可以在 /sys/class/devfreq/ 下找到 fdab0000.rknn 节点:
# 查看当前 NPU 频率和可用频率表 cat /sys/class/devfreq/fdab0000.rknn/cur_freq cat /sys/class/devfreq/fdab0000.rknn/available_frequencies # 查看当前调频策略 cat /sys/class/devfreq/fdab0000.rknn/governor我踩过的一个坑是:只调了 CPU 的 governor,忘了 NPU 的 devfreq 节点。结果 CPU 频率跑满了,NPU 却一直在低档位,推理时间完全被 NPU 拖住。排查了半天才发现 devfreq 的默认 governor 是 powersave,直接把 NPU 锁死在最低频率。解决方式是让 NPU 使用 performance 或 simple_ondemand,并且把 upthreshold 调低一点,让 NPU 更快响应负载升高。
更细一层的调参,要考虑掉帧检测。比如在视频检测场景中,我会在应用的推理循环里维护一个“近期推理耗时”的滑动窗口,窗口平均耗时超过目标帧间隔的 90%,就主动抬高 NPU 频率档位;低于目标帧间隔的 70%,就降到下一档省电。这种方式比完全依赖内核 governor 更能贴合业务特征。
提示:调频参数的修改要配合功耗计来验证,不能只看帧率。有些场景下帧率没掉,但整机功耗已经涨了 20% 以上。功耗和帧率必须一起评估,否则会调出“高性能高耗电”的错误方案。
3. 热节流:性能释放的隐形天花板
3.1 热节流的触发与恢复机制
热节流(thermal throttling)是芯片自我保护的最后一道防线。SoC 内部集成了多个温度传感器,分布在 CPU 核心、GPU、NPU 和内存控制器附近。当任意传感器温度超过设定的多级阈值时,芯片会逐级下调频率和电压,降低功耗,从而让温度回落。
以常见的移动端 SoC 为例,调温逻辑大致分四个阶段:
- 温和阶段(约 85 度):轻微调整调度策略,限制大核频率,降频步长约 5%~10%。
- 明显阶段(约 90 度):CPU、GPU、NPU 频率大幅下调,系统开始出现可感知的性能下降。
- 强制阶段(约 95 度):强制锁定到最低频,各模块功耗降到最低保障水平。
- 保护阶段(超过 100 度):触发关机或强制休眠,避免物理损坏。
热节流的“恢复”不是立刻回到峰值。温度降到阈值以下后,芯片要维持一段时间的降频状态,确保温度有足够回落余量,然后再阶梯式恢复频率。这导致一个很隐蔽的问题:如果温度在阈值附近来回震荡,频率就会忽高忽低,推理延迟抖动变得非常大。这在机器人控制、自动驾驶辅助类应用里是无法接受的,因为控制周期的不稳定比性能偏低更危险。
3.2 从结温到壳温:散热路径上的每个环节
端侧设备的热管理不能只盯着 SoC 的温度传感器,要关注从裸片到外壳的整条散热路径。这条路径上有几个关键节点:
第一是导热界面材料。裸片和散热片之间如果用了劣质硅脂,或者厚度不均匀,导热系数差异可能超过 30%。我在一台设备上实测过,换掉原厂硅脂,改用 6W/m·K 的导热垫并加装铜箔,同样的持续负载下结温下降了 8 度,频率保持时间翻倍。
第二是结构件的热传导路径。铝合金中框比塑料中框导热好得多,但很多产品的结构设计没把“导热”考虑进去,导致 SoC 高负荷运行时热量堆积在主板背面,无法传递到外壳。一个常见做法是在 SoC 背面和屏幕支架之间加导热铜箔或者石墨片,把热量引导到更大的散热面积上。
第三是对流条件。密闭设备内部空气不流动,单靠金属外壳辐射散热效率很低。如果产品允许开散热孔,务必在 SoC 附近开对流孔;如果必须全密封,就要把散热铜块直接顶到外壳内壁,尽量缩短热传导距离。
另外补充一个新观点:环境温度对端侧性能的影响被普遍低估。同一个设备,室温 25 度时能持续跑 30 FPS,环境温度到 40 度(夏天的室外机柜),热平衡点会显著上移,稳态帧率可能掉到 22 FPS。这就是为什么做持续能效评估时,环境温度必须作为受控变量。测试报告上不写环境温度的 FPS 数据,基本没有参考价值。
3.3 温度监测与降频预警的工程实现
在我的移动机器人控制器项目里,温度信号不是只交给驱动层的热节流,而是接进业务逻辑做了“主动式负载整形”。我设计了一套三层温度响应逻辑:
- 温度低于 70 度:正常运行,NPU 使用能效甜点频率。
- 温度在 70~80 度:切换“性能保持模式”,把 NPU 频率锁在甜点频率,禁止往更高档跳,预留给散热系统反应时间。
- 温度高于 80 度:触发“帧率保底模式”,动态降低输入分辨率或检测帧间隔,优先保住每帧推理质量,而不是追求帧率。
这套逻辑的优势是行为可预测:不会出现某次温度波动后帧率突然从 30 掉到 20 的情况,而是提前、平滑地调低负载。缺陷是要自己管理负载的升降级,代码复杂度高一些。但做过端侧产品的人都有体会,让用户看到“平滑的稳定帧率”,比“忽高忽低的帧率峰值”体验好得多。
注意:不要在产品逻辑里频繁读写温度传感器节点。有些 SoC 的温度传感器读取会触发其他模块从低功耗状态唤醒,读太频繁反而增加静态功耗。温度巡检频率 1 秒一次足够,需要快响应的场景,可以用中断方式让散热控制 IC 主动上报。应用层做温度监控时,也别忘了对温度数据做平滑滤波,原始传感器读数跳变很常见,直接拿来驱动业务逻辑容易造成误触发。
4. 持续能效评估:端侧推理的真实水平测试
4.1 评估指标:从 TOPS 到 FPS per Watt
持续能效评估的核心,是“在热平衡条件下,单位功耗能维持多少有效推理吞吐”。常用指标包括:
- TOPS/W:算力芯片的理论能效,适合芯片选型时的横向对比。但它是峰值工况值,不能直接等于产品持续表现。
- FPS/W:端到端推理帧率除以整机功耗,更贴近产品表现。
- FPS/J:每焦耳能量能处理的帧数,适合做任务级能效对比。
- P95 延迟与延迟抖动:推理耗时的稳定性指标,持续运行时热节流最容易放大 P95 延迟。
我最常用的核心指标是“稳态能效比”,定义是设备进入热平衡后连续运行 30 分钟的帧率平均值,除以这段时间的整机平均功耗,单位是 FPS/W。这个指标能一次性暴露三个问题:调频策略是否合理、散热设计是否充分、模型算力利用是否高效。
这里有个陷阱必须提醒:TOPS 和 FPS/W 不在同一个评价维度。一个 6 TOPS 的平台理论上比 4 TOPS 的平台算力高 50%,但如果功耗高出 80%,在电池供电的产品中反而更差。选型阶段一定要列“能效对比表”,把负载、功耗、帧率、价格四个参数放在同一张表里做综合决策,不要被厂商 PPT 上的峰值 TOPS 迷惑。
4.2 测试环境与负载模型设计
做持续能效评估,测试环境比测试脚本更关键。我列一下我的标准测试条件供参考:
- 环境温度控制在 25±1 度,使用恒温箱或恒温空调房,避免自然室温波动干扰。
- 设备放入目标产品外壳中测试,不用裸板。裸板散热条件远好于实际产品,两者稳态帧率可能差 30% 以上。
- 供电使用直流电源并监测电压电流,记录整机功耗,而不是只看主板功耗。
- 负载模型和真实业务保持一致:视频检测就连续推流 2 小时,语音识别就持续唤醒 500 次,机器人就用运动控制模型跑完整任务循环。
- 每个工况至少持续 30 分钟,确保设备进入热平衡后再记录数据。
负载模型设计有个细节值得展开:模拟负载要包含“空转-推理”的交替模式,而不是让推理线程 100% 满负荷跑。真实应用里,模型推理之间总有图像采集、通信、控制逻辑的间隙。满负荷连续推理容易把系统推到极限热状态,会高估降频程度;而空转和推理交替的模型更接近产品真实散热过程。我几乎每次都准备两种脚本,分别跑极限性能曲线和典型业务负载曲线,这两条曲线的差异本身就是散热设计优劣的体现。
4.3 完整测试流程与数据解读
持续能效评估的完整流程,我会分成五个阶段:
- 基线采集:设备静置冷机到室温,记录环境温度。跑 5 分钟满载,记录峰值帧率和最大功耗,这组数据称为“冷启动峰值”。
- 热平衡确认:持续运行满载负载,监控温度曲线和帧率曲线,直到两者波动小于 2% 后继续保持 10 分钟,记录此时的稳态帧率和稳态功耗。
- 调频策略验证:分别用不同 governor 配置跑相同的热平衡测试,对比稳态帧率差异。这一步能看出厂商默认调频策略是否适合你的业务。
- 温度梯度测试:把环境温度从 25 度逐步调到 35、40 度,每个温度点做一次热平衡数据采集,形成“环境温度-稳态帧率”关系曲线。
- 恢复测试:从满载态转入空闲态,记录温度回落到常温的时间和帧率恢复情况。这个阶段数据可以评估产品“冷热交替使用”时的体验。
数据解读上有一个常见误区:只看平均值,不看曲线趋势。我建议每次都画出“时间-帧率”和“时间-温度”两条曲线,放在同一张图里看。你会发现帧率掉点往往发生在温度曲线拐点之后的几分钟,这是热节流生效的时间延迟。这个延迟如果需要几分钟才显现,说明设备热容较大或散热路径有效,产品更适合短时爆发型任务;如果一升温就掉帧,说明散热设计有缺陷,持续负载型任务会被严重影响。
下面是我项目中一份简化版“持续能效评估汇总表”,用于跨方案对比:
| 方案 | 峰值帧率(FPS) | 稳态帧率(FPS) | 稳态功耗(W) | 稳态能效(FPS/W) | 降频幅度 |
|---|---|---|---|---|---|
| 方案 A:默认配置 + 裸板 | 32 | 28 | 9.5 | 2.95 | 12.5% |
| 方案 B:甜点频率 + 裸板 | 30 | 29 | 7.0 | 4.14 | 3.3% |
| 方案 C:甜点频率 + 外壳 | 30 | 24 | 7.2 | 3.33 | 20% |
这张表一眼就能看出:方案 B 的持续能效最高,但一旦装入外壳(方案 C),由于散热变差,稳态帧率掉了 5 帧。结论很明确——这个产品需要改进散热设计,或者调低甜点频率,而不是继续追求峰值性能。
5. 端侧功耗热管理常见问题与排查技巧
5.1 问题速查表
我把实际项目中高频遇到的问题整理成了速查表,方便直接对照排查:
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 运行 5 分钟后帧率明显下降 | 热节流触发,散热不充分 | 检查结温曲线、外壳温度、导热界面材料 |
| 帧率低但温度不高 | NPU devfreq governor 为 powersave | 检查 /sys/class/devfreq/ 下的 governor 配置 |
| 温度高但频率仍然很高 | 温度传感器校准偏移,或传感器位置离热点远 | 对比多个传感器读数,检查温度节点布局 |
| 帧率波动大,忽高忽低 | 调频策略在阈值附近抖动 | 检查频率切换日志,增加迟滞带或锁频 |
| 功耗高但性能提升有限 | 已经越过能效甜点,处于高频低效区 | 降低频率档位,改用甜点频率 |
| 裸板性能好,外壳产品性能差 | 散热设计不足,热路径不畅通 | 增加导热材料,优化结构散热路径 |
| 长时间运行后内存占用升高 | 推理线程未复用内存,缓冲区泄漏 | 检查推理框架的输出内存释放逻辑 |
| 切换负载时出现卡顿 | 调频响应太慢,跟不上负载变化 | 调低 upthreshold,或改用 schedutil |
第七行关于“裸板好外壳差”是产品化阶段的最典型问题。很多时候不是调频参数的问题,而是机械设计没同步考虑热设计。软件团队和硬件结构团队必须在项目早期就坐在一起,讨论“持续功耗目标”和“散热方案”,否则等项目进入外壳设计阶段再改,成本会高出很多。
5.2 我在实测中积累的几个坑
再多聊几个实测里踩过坑才总结出来的经验。
第一个坑是误以为“温度没到阈值就没有热问题”。事实上,温度没到降频阈值时,芯片的频率调度已经可能在悄悄改变。很多 SoC 的强制降频启动温度是 85 度,但频率的微调从 75 度就开始了。只看驱动层的降频标志位,看不到微调过程,必须记录完整的频率曲线才能发现问题。
第二个坑是忽略电压调节器(VRM)的电流限制。有些主板设计为了控制物料成本,给 NPU 供电的 VRM 输出电流余量不足。满载推理时电流需求超过 VRM 上限,电压被拉低,导致芯片不稳定或自动降频。排查这类问题时,用示波器测供电电感的纹波和电压跌落是有效手段,光看温度传感器是找不到原因的。
第三个坑是测试脚本和真实业务负载模型不一致。比如只测纯推理负载,忽略了图像采集和预处理(缩放、归一化)的 CPU 开销。当这些附加负载叠加到 CPU 上时,整机功耗比纯推理测试高出很多,热平衡点也会明显上移。正确做法是先做一次完整业务链路分析,确认哪些模块会同时运行,再写等效负载脚本。
第四个坑是跨设备一致性差。同一批次的模组,由于硅片体质差异,相同频率下的功耗和温度可能相差 10% 以上。做持续能效评估时至少要测 3 台以上样机,取中位数作为评估基准,否则会因为样机体质差异得出错误结论。我遇到过开发板体质好、运行稳定,而量产板体质一般、同样温度曲线下帧率掉了 15% 的情况。做批次对比时,一定要把硅片体质因素考虑进去。
5.3 关于能效优化的进一步建议
能效优化并不是调完调频就结束了,它和算法、模型结构直接挂钩。同一个模型,如果用推理框架做更激进的算子融合、通道重排和量化,推理时间可能缩短 20%~30%,意味着相同算力下功耗更低地完成同一个任务。换句话说,能效优化的空间有很大一部分在模型侧,而不全在硬件侧。量化感知训练、算子替换、输入分辨率选型,这些模型层面的决策对功耗的影响,往往比调整几个 governor 参数更明显。
另外,推理框架的内存复用策略对功耗也有影响。频繁的 CPU 与 NPU 之间的数据搬运,不仅延长推理延迟,也会增加内存控制器的功耗。在驱动支持的情况下,尽量让输入数据通过零拷贝方式直接送到 NPU,避免多次内存拷贝。端侧推理的高效落地,从来不是单点优化,而是软硬件协同的系统工程。
最后分享一个我自己的小习惯:每次拿到一块新端侧平台,我不急着跑业务模型,而是先跑一个固定的高负载矩阵乘任务,把温度曲线、频率曲线、功耗曲线同时记录下来,确认这条平台的“热底色”。之后再叠加业务模型,对比纯算力负载和业务负载的行为差异。这套基线数据保存下来,后面的性能问题排查都会快很多。
我个人在实际操作中的体会是,端侧推理的功耗与热约束问题,从来没有一个“调一次就一劳永逸”的标准答案。每块板子的体质、每个外壳的散热能力、每种业务的负载形态都不一样。把动态调频、热节流和持续能效评估这套方法用熟,遇到新设备时先量化再优化,不凭感觉调参,产品才能稳定地释放出真实水平。