端侧AI越跑越慢?功耗、散热与供电三条物理锁链揭秘
跑端侧AI的人,大概率都碰到过这样一个怪现象:模型没换、代码没动、开发板还是同一块,刚开机的时候token刷刷往外蹦,跑个十来二十分钟,速度肉眼可见地往下掉;等电量再低一些,整个推理延迟能翻倍。我见过不少团队把这个现象当成软件bug去排查,查内存泄漏、查缓存策略、查算子实现,忙活半天一无所获。真相不在代码层,在物理层——端侧推理消耗的是电池里的电,电变成热,热又反过来压制芯片的频率,供电、功耗、散热三样东西串在一起,才造成“越跑越慢”。这篇文章不讲模型优化,只讲端侧算力背后这三条物理锁链是怎么一环扣一环的。
1. 越跑越慢不是错觉:先说清楚端侧算力的物理边界
1.1 云侧和端侧最大的差别,不在算力,在“能量环境”
大家习惯把端侧推理和云侧推理放在一起比性能,比来比去总觉得端侧吃亏在算力弱。其实更本质的差异是能量环境完全不同。云端GPU服务器插着几千瓦的电源,房间里空调常年18度,机柜里风扇把热量源源不断带走。负载高了,大不了多开几个实例,单卡跑到降频直接换一台。端侧设备呢?一块电池,几百克重量,没有主动散热,外壳还不能烫手。拿手机来说,整机持续功耗能做到4到8瓦就已经不错了,开发板稍微宽松一些,通常也就是10到15瓦的量级。这个能量输入上限就是"墙"。
很多人忽略的是,AI推理恰恰是所有负载里最"不省油"的那一类。网页浏览、视频播放都有明显的空闲窗口,GPU/CPU可以间歇性歇口气。但端侧跑大语言模型是自回归生成,逐token往前推,每一秒都在持续大功率输出,大核高负载、NPU/GPU满频,连续几分钟、十几分钟不停工。这种负载形态对功耗预算和散热系统的压力,比跑游戏还要极端。所以"端侧推理越来越慢"不是偶发故障,是物理环境决定的必然走向,差别只在于降频的时间点来得早还是晚。
1.2 先给“慢”一个准确定义
排错之前,得先把现象定义清楚。这里的越跑越慢指的是:同一台设备、同一个模型、同一个输入和batch配置,推理吞吐量(token/s)随运行时间持续下降,或者随电量下降,且重启后冷机状态下性能能够恢复。注意两个关键词——同配置、可恢复。如果重启后依然慢,那大概率是软件问题;如果重启冷机马上恢复,问题就出在物理约束上。
还有一点容易混淆:大模型生成长文本时,越往后越慢有一部分是上下文长度增长导致的,KV Cache变大、注意力计算量增加,这是算法原因。但实际端侧场景里,硬件降频往往同时发生,两股效应叠加,速度衰减会比纯算法预估严重得多。我自己调试时遇到过这种情况:按公式算出上下文翻倍应该慢20%,实测却慢了40%,多出来的部分就是烫出来的。
2. 功耗墙:性能先撞上的是看不见的功率红线
2.1 端侧芯片手里的功率预算从哪来
芯片不是想跑多快就跑多快。一颗移动SoC里,CPU、GPU、NPU、DSP、Modem共用同一份功率预算,预算的源头是整机热设计目标和电池放电能力。手机厂商在设计时就会确定一个整机持续功耗上限,比如5瓦、6瓦、8瓦,所有模块在这个上限内互相掰手腕。谁占得多,别人就得让路。端侧AI推理跑起来,NPU/GPU和大核CPU都在抢功率,调度器必须做取舍。
这就能解释很多怪现象:比如跑纯NPU的模型时CPU频率被压低、跑CPU混合模型时GPU被限制,甚至Wi-Fi和屏幕都会在AI负载下被降优先级。做端侧AI开发,不能只看某一颗芯片的频率,要盯着整个SoC的功率分配。
2.2 DVFS:频率不是越高越好,电压必须跟着涨
功耗墙的技术底层是DVFS,动态电压频率调整。芯片频率提高,工作电压也必须相应提高,而功耗和电压的平方成正比、和频率成正比,简单说P约等于C乘以V的平方乘以f。这个关系非常残酷:频率提高10%,为了维持稳定性电压得往上抬一点,实际功耗可能增加20%到30%。也就是说,芯片最后那一点点性能是拿大笔功耗换来的。
这也解释了为什么端侧芯片的频率表通常不是一个连续区间,而是一个个离散档位。芯片不是在任何频率都能工作,而是踩着台阶往上爬。每一级频率对应一个功耗点和发热量。推理负载顶到最高档时,功耗瞬间逼近预算上限,系统后台的功耗管理模块立刻开始权衡。所以你看任务管理器里CPU还能摸到最高频率,不一定是好事,可能只是短暂冲顶,下一秒就被按下去。
2.3 端侧推理特别容易撞墙的三种情形
第一种是持续的大规模矩阵运算。LLM推理主要有两类算子,显存密集型和计算密集型,无论哪一类,都会让NPU/GPU长时间处于高占用状态。第二种是多核协同场景,调度器把任务拆给大核CPU、GPU和NPU同时干活,每个模块单看功耗不高,加起来整机瞬间突破预算。第三种是模型规模超配,本来这个SoC功耗效率只够跑3B模型量级,硬塞一个7B模型,芯片只能在低频率档位勉强维持,速度当然上不去。
我在实际开发板测试中遇到过非常典型的情况:跑同一个7B INT4模型,限制整机功耗8瓦时,大核CPU最高能到2.2GHz;把预算放开到12瓦,频率能多保持一个档位,推理速度提升15%。代价是温度肉眼可见地飙升,几分钟后照样被温控压回来。这就是在功耗墙上做文章:预算给足了,温度墙又来了。
3. 散热链:温度是慢慢追上来的,降频也是逐级发生的
3.1 从芯片节到外壳,热量要过好几道关
芯片工作产生的热量,路径基本是固定的:从硅片内部传导到芯片表面,再经过导热硅脂或相变材料到屏蔽罩,再从屏蔽罩到均热板、石墨片,最后到外壳和空气。这一层一层,每一道都有热阻。热阻大的环节就像管道里的瓶颈,会把热量憋在芯片附近,导致节温快速上升。
端侧设备和云服务器最直观的差别就在这里:服务器里有风扇直吹散热鳍片,气流是主动的;手机和平板只能靠外壳自然辐射加一点内部空气对流。哪怕是开发板,很多也只是被动散热,一块铝合金底板,没有风道。芯片节温冲到85到90度太常见了。这里要区分两个温度:SoC内部的节温(junction temperature)和外壳温度。节温是芯片命脉,过热会损坏器件;降频保护主要看节温。但外壳温度决定用户手感,手机厂商对触感有严格约束,一般控制在45度以内。这两层约束同时存在,散热设计必须两头兼顾。
3.2 降频不是一刀切,而是多传感器各自为政
移动SoC内部不止一个温度传感器。大核CPU一个温区、小核一个、GPU一个、NPU一个,还有充电管理芯片、电源管理芯片各自有温度上报能力。这些传感器各看各的,谁触到自己的危险温度线,谁就先降频。于是你会看到一种很隐蔽的性能退化:NPU触发了温控,频率从最高档掉到中档,但CPU还跑着正常频率,系统整体吞吐量下滑20%,你从上到下查软件,啥问题都查不出来,因为所有元器件频率看起来都“正常”。
降频本身也是分档的。大多数芯片的温控逻辑是阶梯式:温度低于阈值A,全速;超过阈值A,降一档,比如从最高频落到次高频;继续升到阈值B,再降一档。每一档停留一段时间,看温度是不是回落。这个机制类似家用空调的温控,不是一热就制冷,而是阶梯式逼近目标温度。这一特点导致直观感受是速度“一段一段往下掉”,就像人跑步时被逐渐加了负重。
3.3 连续推理的热量累积是个慢变量
为什么刚开机跑同一段任务飞快,跑半小时后变慢?因为热量在设备里累积是个慢过程。芯片的热容、外壳的热容、空气被加热的过程,决定了温度不会瞬间冲到阈值,而是以秒甚至分钟为单位往上爬。打个比方:芯片是刚烧开的水壶,外壳是大水缸,壶里的水先热,大缸的水慢慢升温。整个系统要达到热平衡,可能需要十分钟到二十分钟。
对推理任务来说,这意味着前几轮请求占了大便宜——设备还是凉的,芯片可以顶着高功耗跑满速。等到热量传导开、各处温度传感器显示读数上来了,降频才真正开始。我测过同一台设备冷机和热机状态下的性能差,冷机时跑一个生成任务能有18 token/s,热平衡后只剩12左右,差距高达30%。如果你只把设备放在冷态下做性能验收,那到了真实业务场景被用户连续使用时,性能预期会完全失准。
3.4 散热悖论:散热越好,降频来得越晚但也越集中
有意思的是,“散热好”的设备并不等于不降频。散热路径好,芯片热量能更高效导到外壳,节温升得慢,满频时间更长,总吞吐量一定是更优的。但外壳温度会先到达人的触感上限,于是系统被迫开始限制芯片功率,以降频来保住外壳温度。散热差的设备反而因为芯片早就飙到高温阈值,提前降频,把功耗压下去,外壳反而不那么热。
做硬件选型时一定要把这个悖论想清楚。如果产品形态允许加风扇(比如边缘计算盒子),主动散热能显著推迟降频;如果是手持设备,外壳温度触感上限就是硬约束,再怎么堆均热板也改变不了最终会被温控压制的结局,只能尽量推迟降频的出现时间。
4. 供电侧:电压一抖,吞吐量跟着抖
4.1 电池不是稳定的电压源
很多人把电池当成一个恒定电压的“大电容”,实际完全不是这么回事。锂离子电池的放电曲线从满电接近4.4V一路下滑,放到接近没电时大概3.6V甚至更低。电压下降意味着什么?在输出功率一定的情况下,电压越低,电流就得越大,而电流一大,电池内阻上的压降就更严重,形成一个恶性循环。
对一个2安培左右的常规负载,电池电压波动影响可能不明显;但端侧推理的瞬时电流可以冲到5、6安培,这时候内阻造成的压降就非常可观了。电压一旦低于电源管理芯片的最低工作门槛,整机不是立刻关机,而是触发保护机制,把芯片频率强制往下拉。你在低电量时用手机跑模型觉得特别卡,大概率就是这个原因。
4.2 推理负载的瞬时功率尖峰对供电路径不友好
端侧AI推理对电源的要求和视频编解码不一样,它有明显的功率脉冲。生成一个token的计算密集区间,功率瞬间拉高;token之间的调度、访存区间,功率又回落。这种高频脉冲对电源管理电路是考验:电源路径要有足够的余量去应对瞬时大电流,电容要能稳住电压。
我见过一块设备用普通USB口供电跑LLM推理,一跑就自动限频,以为是固件问题,后来发现是供电功率根本不够。适配器标称5V2A,瞬时电流一突破就开始电流倒灌,电源管理芯片检测到电压跌落就强制降频,推理速度从14掉到8。换成稳压电源后,同样代码性能立马上来。供电这块要是没排查,纯粹在软件层调参,调一个月都白搭。
4.3 电池老化后的真实差距
电池用上半年一年,内阻变大,放电能力下降。同样一个高负载推理请求,新电池电压可能只跌0.15V,老化电池可能跌0.3V以上。在低电量区间,这个差距会被急剧放大。我做过一个简单的对比实验:同一台设备,同一温度环境,新电池90%电量和用了一年的电池20%电量,跑同一个模型的性能差距能到25%。注意,这个差距不是电量本身导致的,而是电压跌落深度不同。
所以在用户侧,你会发现一个规律:设备刚买来跑AI很快,用了一年之后跑同样的模型明显慢,不换电池就回不到当初的性能。这跟系统更新无关,就是供电能力老化。做端侧AI产品如果面向长生命周期设备,必须把电池老化纳入性能规划。
4.4 两条供电路线的现实差异
端侧设备供电有两种典型路线。一是电池供电,接受电压随SOC缓慢下降,适合便携场景;二是外接电源直供(许多开发板、边缘盒子直接接适配器),电压相对稳定,但适配器的功率和纹波质量决定了能不能撑住大电流。还有一类是手机上的旁路充电——适配器直接给系统供电,绕过电池,既减少发热还能稳定电压。
从推理性能稳定性排序:旁路充电/稳压电源直供好于满电电池供电,而低电量电池供电是最差的。如果你在固定场景部署端侧推理设备,强烈建议优先考虑外接稳压电源,别贪图“无线化”让设备用电池顶着跑。
5. 一组实测曲线:看看同一台设备在25分钟里都经历了什么
5.1 测试环境与测试方法
参数说详细的,方便大家自己复现。测试设备是一块搭载中高端移动SoC的安卓式开发板,被动散热(一块较大金属底板,无风扇),室温26度左右。模型是7B参数量的对话大语言模型,INT4量化,推理框架自带高性能后端。测试脚本每一轮生成128个token,生成完休息2秒再进入下一轮,连续运行25分钟。监控链路包括:整机功耗(直流电源分析仪读数)、SoC表面温度、最高频率档位和平均token/s。
这里有几个细节:被动散热开发板模拟的是“没有主动风冷”的真实端侧形态;每轮之间休息2秒模拟真实对话场景,但又让负载有连续性。如果完全无间隔,降频会更早更狠。
5.2 25分钟的温度、功耗、速度变化
下面这组数据虽然来自单次试验,但趋势在我测过的几乎所有端侧设备上都一致。
| 时间点 | 整机功耗 | SoC温度 | 大核最高频率 | 平均生成速度 |
|---|---|---|---|---|
| 第0分钟 | 7.5W | 38摄氏度 | 2.6GHz | 18.4 token/s |
| 第5分钟 | 8.2W | 61摄氏度 | 2.6GHz | 17.9 token/s |
| 第10分钟 | 7.9W | 78摄氏度 | 2.4GHz | 15.6 token/s |
| 第15分钟 | 6.8W | 86摄氏度 | 2.0GHz | 13.2 token/s |
| 第20分钟 | 6.1W | 84摄氏度 | 1.8GHz | 11.9 token/s |
| 第25分钟 | 5.9W | 83摄氏度 | 1.8GHz | 11.4 token/s |
5.3 数据解读:三个阶段非常清晰
第一阶段是前5分钟,满血状态。散热底板还是凉的,芯片可以放开跑到最高频率,功耗爬到8瓦以上,速度和冷机基准值几乎一致。这个阶段最容易给测试人员造成错觉,以为整机性能就是这样。
第二阶段是第10到15分钟,第一次降频。SoC温度越过温控阈值,频率从2.6GHz退到2.4GHz再退到2.0GHz。功耗反而下降了,因为频率降低让动态功耗减小,但温度依然缓慢上升,说明散热系统已经接近承载极限。速度降幅超过25%。
第三阶段是第20分钟后,热平衡稳态。功耗降到6瓦左右,温度稳定在83到85摄氏度之间,频率稳定在1.8GHz,速度稳定在11.4到11.9 token/s。整个系统在一个更低功耗、更高温度的平衡点上运行,无论再跑多久,这个状态都不会有太大变化。除非环境温度变化,或者设备从被动散热改成主动散热,否则这个“稳态速度”就是用户真实体验到的速度。
这组数据让我最有感触的一点是,很多项目验收踩的坑就是只测第一阶段,拿18.4这个数字写在方案里。结果用户真机上一跑,稳态只有11.4,差距40%。测端侧AI性能,请在设备进入热平衡之后再看成绩。
5.4 手机场景比开发板更残酷
同样的负载放到手机上,降频会来得更早,因为手机的外壳面积更小、被动散热路径更受限、外壳触感温度约束更严格。我见过一台量产手机跑小模型,6分钟就进入降频稳态,最终稳定性能只有初始的60%。所以手机端侧AI做性能规划时,最好不要参考那种“只跑三条请求”的快速测试结果,要连续跑至少10分钟取稳态值。
6. 工程上怎么扛:把“热与电”纳入推理系统的设计变量
6.1 先排查:到底是软件病还是物理病
遇到推理性能下降,第一件事不是上模型优化,而是先区分原因。我一般用这个对照表来定位:
| 特征 | 软件问题 | 功耗/散热/供电问题 |
|---|---|---|
| 重启后冷机恢复 | 不一定恢复 | 基本都能恢复 |
| 温度环节 | 温度正常仍慢 | 温度高时必慢 |
| 电量相关性 | 相关性弱 | 低电量显著恶化 |
| 运行时长相关性 | 内存/缓存泄漏会随时间累积 | 持续负载下持续下降,有稳态 |
| 任务类型相关性 | 特定算子/模型才触发 | 各类AI负载都会触发 |
6.2 把温度、频率、功耗监控变成常规手段
做端侧推理优化,没有实时的温度/频率监控基本等于盲飞。早期我调性能时只看耗时,后来发现耗时涨了原因根本看不见,加监控之后数据一目了然。建议把传感器数据采集直接集成到测试脚本里,每2到5秒记录一次。
# 示意代码:定期采样SoC温度、CPU最高频率、整机功耗 # 具体实现依赖具体平台系统接口,这里只展示采集逻辑 import time import os def sample_status(): return { "ts": time.time(), # 温度节点路径、频率节点路径按实际设备调整 "soc_temp": read_sysfs("/sys/class/thermal/thermal_zone0/temp"), "cpu_max_freq": read_sysfs("/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq"), "power": read_power_meter(), # 外接电源分析仪或板载PMIC读数 } def run_benchmark(duration=1500): logs = [] while time.time() - start < duration: logs.append(sample_status()) time.sleep(2) return logs # 跑完一轮后,把 token/s、温度、功耗对齐看曲线这个脚本的价值不在于代码复杂度,而在于让你认识到“性能下降”是一个有先兆的过程。温度爬升、频率掉档、功耗回落,这些现象出现在速度变慢之前,早一点看到,就能早一点干预。
6.3 任务编排:给设备留出“喘气”的窗口
如果业务形态允许,不要在端侧设备上做无间断的高强度连续推理。把长会话拆成多个短轮次,轮次之间插入几十毫秒到几百毫秒的空档,让DVFS有时间把频率降下来喘口气。这个方法看起来不起眼,但对热稳态的改善非常明显。我做过对比:同样20分钟负载,连续跑和无间隔跑的热稳态温度能差4到5度,对应速度差10%左右。
还有一个实操技巧是限制最大生成长度。很多端侧对话模型默认允许输出512或1024个token,但实际上用户经常只读到一两百字。把最大生成长度限制在256甚至128,既能降低单次功耗总量,又能减少设备进入长时间满负载的概率。这个改动产品体验上几乎无感,但对发热控制帮助巨大。
6.4 供电方案:固定场景优先稳压电源
如果你的端侧设备是固定位置部署(边缘网关、智能面板、桌面终端),优先用稳压电源而非电池。注意稳压电源的功率余量,建议按峰值功耗的1.5倍以上选型,别看“标称3A”就以为能顶住瞬时4A,电源的瞬态响应同样重要。
如果必须用电池,至少做好两个监控:电池健康度(通过充放电循环估算内阻)和低电量预警。当电量低于某个阈值(我习惯设为30%),主动降低推理任务优先级,或者切换到更小的模型、更低的精度,而不是等到系统自动降频造成劣质感。手机上的旁路充电接口如果支持,在跑重负载时引导用户插电,也能明显改善稳速。
6.5 散热辅助的性价比排序
给设备加散热,工程上性价比从高到低大致是:加主动风扇大于加大均热板面积大于换高导热硅脂大于贴石墨片。开发板需要跑持续负载时,哪怕一个低速小风扇都有奇效,能把稳态速度拉回15%到20%。手持设备没有风扇选项,只能在结构上增加导热路径,把热量有效传导到外壳大面积区域。注意均热板的方向性,热量要能纵向导到外壳,而不是在芯片周围打转。
还有一个容易被忽略的选项:软件上限制并发度。如果设备同时跑多个推理任务,强制串行化或者限制最大并发数,可以减少功率尖峰重叠,供电压力和热量压力都会小很多。这在边缘盒子多路请求场景里特别实用。
6.6 模型侧降功耗,是在源头削减热量
硬件层面能做的优化终究有上限,真正有效的还是让模型本身更省电。INT4/INT8量化是最直接的,能把单token推理功耗砍掉一半以上;剪枝、蒸馏可以减小模型规模;投机采样能减少大模型实际激活的层数。我见过一个项目,把7B模型从FP16切到INT4之后,稳态温度降了10度,速度反而快了一倍——因为降频发生得晚了很多,甚至没发生。
但要注意,量化精度不是越高越好,量化本身可能带来额外校准和精度损失。工程上的标准做法是先在云端验证精度损失在可接受范围内,再上端侧测发热与速度。
这几年做端侧AI的一个体会是,别把芯片参数表和厂商宣传里的峰值算力太当真。端侧设备在真实环境里的性能,是由功率预算、散热路径、电池状态共同决定的,算力只是上限,物理约束才是那个真正决定体验的下限。设计阶段就把这三条锁链纳入考量,比上线后到处排查要省力得多。