news 2026/10/22 11:15:02

端侧LLM推理性能排查实录:0.5到30 token/s的优化之路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
端侧LLM推理性能排查实录:0.5到30 token/s的优化之路

别人手机跑 7B 模型轻轻松松 40 token/s,我手机装上同一个推理框架、同一个模型文件,测出来 0.5 token/s 出头。两个数字摆一起,差了 80 倍。

这不是夸张,是我最近调端侧推理时真实踩过的坑。当时第一反应是手机太老、硬件不行,但仔细扒完日志才发现,硬件只背了一小半锅,真正的问题出在量化格式、线程配置和系统调度上。如果你也遇到过"同一个模型,在不同设备上速度天差地别"的情况,这篇排查实录应该能帮你少走不少弯路。

先说结论:端侧 LLM 的性能瓶颈从来不是"手机不够好",而是"你的推理栈到底有没有跑在正确的路径上"。下面我把这次排查的完整过程、对比数据、修复手段和事后整理的速查清单全部写出来,照着做,大部分性能问题都能在半小时内定位。

1. 先搞清楚:端侧跑 LLM 的"正常"到底是多少

在排查之前,得先建立一条基线。没有基线,"80 倍慢"就没有参照物,后面所有改动也说不清有没有效。

1.1 端侧推理的两个阶段:预填充与解码

大模型推理分成两个明显不同的阶段。第一个是**预填充(Prefill)阶段,模型一次性吃进你输入的整段上下文,所有 token 并行计算,这个阶段是典型的计算密集型操作。第二个是解码(Decode)**阶段,模型一个一个往外蹦 token,每蹦一个都要把全部权重从头读一遍,所以这个阶段卡在内存带宽上。

举个直观例子:假设一个 7B 规模的模型,int4 量化后权重大约是 3.5GB,你手机内存带宽如果是 25GB/s,解码阶段每蹦一个 token 就得花 3.5GB ÷ 25GB/s ≈ 0.14 秒,换算过来也就 7 token/s 左右。带宽砍一半,速度跟着砍一半。如果你用的还是 fp16 精度,权重直接奔 14GB 去,速度更是断崖式下跌。

这就是为什么我测速时一定要把两个阶段分开看。很多框架默认打印的数字是"prefill + decode 混在一起的平均值",上下文越长越失真。排查性能问题时,只看 decode 阶段的 token/s 才是公平对比。

1.2 建立对照设备基线

我这次手里有两台设备。参考设备 A 是近两年的旗舰芯片,对比设备 B 是台老款中端芯片,系统、内存、存储都不太一样。同一个 int4 量化模型文件,同一套推理框架,放在两台设备上分别测。

设备 A 用默认参数跑,decode 稳定在 43~45 token/s,设备 B 用同样参数跑,只有 0.5~0.6 token/s。当时差点就把锅甩给硬件差距了,但冷静算一下:即便设备 B 芯片算力、带宽都弱一截,再怎么样老款芯片跑 int4 7B 模型也不会只有 0.5 token/s。这个数字低得太反常,反而说明问题不在硬件,在软件栈。

注意:排查性能问题,第一件事永远是建基线。找一台你心里有底的设备,跑同一份模型文件、同一套框架版本,把两个阶段的耗时分别记下来,再开始动配置。没有基线的调优都是瞎猜。

2. 慢 80 倍的根源:从算子到系统的三层检查

拿到异常数据后,我按"从代码到硬件"的顺序一层层往下查,总共锁定到三个层面的问题。这种自顶向下的排查方式推荐大家都试试,比盲改配置高效得多。

2.1 第一层:框架状态与量化格式核对

我第一个怀疑对象是量化格式。端侧推理框架为了压速度,都会对 4bit 权重做特殊的内存布局和算子优化,比如按组打包、矩阵分块等。如果模型文件虽然是 int4 命名,但实际加载时框架没有走加速路径,权重就可能在运行时被"展开"成 fp16 甚至 fp32 来计算。

怎么验证?框架启动后看到日志里其实写得很明白。正常走量化加速路径时,日志会标注类似"加载 4bit 权重,已启用整型矩阵乘加速算子";异常时通常会有一行警告,提示"当前算子不支持 int4,回退到 fp16 展开",或者干脆静默回退。

我这次就撞上了第二种。设备 A 的芯片有完整的整型加速指令集,框架自动走最优路径;设备 B 的老款芯片缺了关键指令,框架直接静默回退到 fp16 展开。一个 int4 模型实际跑出来是 fp16 的权重和算子,内存开销翻到接近 3.5 倍,速度自然按比例崩掉。

排查方式很简单:

  • 打开框架日志,搜"revert""fallback""unsupported"关键字,看有没有算子回退告警
  • 加载模型后看内存占用。7B int4 模型理论占用约 3.5~4GB,如果看到 7GB 以上,基本可以断定实际在跑 fp16
  • 对比 CPU 占用特征。fp16 展开时多个大核都会接近满载,int4 加速路径下占用率通常没这么夸张

2.2 第二层:线程数与调度策略

第二层我查的是线程配置。推理框架的线程数不是越多越好,尤其手机上的大小核混合架构,线程要是全都轰到小核上,速度能慢得让你怀疑人生。

框架默认的线程数有两种极端:一种是把 CPU 核数全部劈开用,比如检测到 8 核就开 8 线程;另一种是保守起见只开 2 线程。两种在我这台设备 B 上都会出问题——开满了线程会被系统调度到一堆小核上,开少了矩阵乘算力又吃不满。

而且这次还抓到一个隐蔽点:框架把线程固定到了某个 CPU 分组里,而设备 B 的大核和小核分属不同的调度域。明明有 4 个大核,框架偏只认了默认组里的 2 个,剩下几个线程全挤在小核上跑。0.5 token/s 里有相当一部分就是这么来的。

排查办法:

  • 用系统命令实时看每个线程跑在哪个核心上,确认线程是不是都挤在小核
  • 看单线程和多线程的实际速度差异。如果 8 线程比 4 线程还慢,说明调度出问题了

2.3 第三层:功耗与散热策略带来的隐形降频

最后一个大坑在系统功耗管理。设备 B 当时处于默认的智能省电模式,系统检测到持续高负载后,直接把大核频率往死里压,甚至短时间全核降频。我跑推理的时候,核心频率被锁到标称的一半不到。

这种问题最坑,因为你看软件层完全正常,量化也对、线程也对,但帧率就是上不去。手机厂商为了续航和温控,往往对"持续重负载"非常敏感,而跑大模型恰恰是最典型的持续重负载。

排查思路:先排除软件层问题,再怀疑散热降频。如果代码没有任何变化,把设备放在冰袋上跑一次,速度明显提升,那基本就是温度墙在捣鬼。注意别把冷凝水弄进设备,我就因為这个废过一台测试机。

3. 逐步复现与修复:把 0.5 token/s 拉回正常水平

问题锁定之后,剩下的工作就是一个个修。这个过程我强烈建议一次只改一个变量,改完立刻测速,记录在案,再改下一个。不然多个变量混在一起,你根本不知道是谁起了作用。

3.1 第一步:建立隔离环境

在动手之前,我先把设备 B 恢复成"干净状态":关掉所有后台应用,切到性能模式,关闭自动亮度,把屏幕调暗,开启飞行模式,拔掉充电线。原因很简单——跑模型本身就是重负载,后台刷信息流的 app、无线传输、充电发热都会干扰测试结果。

然后我对模型文件做了一次 SHA 校验,确认两台设备上跑的是同一个文件,二进制级别一致。这个步骤很多人会跳过,但我排查过不止一次"设备 A 正常、设备 B 异常",最后发现是两台设备上的模型文件根本不一样,一个是 int4 一个是 fp16。

3.2 修复一:强制启用量化加速路径

设备 B 的框架默认回退到 fp16,我需要确认框架是否提供"强制走加速路径"的开关。翻了框架文档后发现确实有关联的编译选项,但这个选项是编译期决定的,设备 B 上跑的是别人预编译的包,没法现场改。

于是换了个思路:换成有对应版本指令集优化的构建。同一套框架,设备 A 的构建是完整版,设备 B 我之前图省事装了个兼容性构建,两者内部算子实现完全不同。换掉之后,日志里终于出现了"整型矩阵乘加速已启用"的标记,内存占用也从 7GB 多降回了 3.8GB——量化路径通了。

实操心得:端侧推理框架在不同处理器上的性能差异,很大程度取决于你用的是哪个构建版本。全功能构建体积大,但算子优化完整;兼容性构建什么芯片都能跑,但性能可能差数十倍。追求性能就选针对你芯片优化的版本,别图省事。

3.3 修复二:手动绑定大核与调整线程数

量化路径修好之后,速度已经起来了一截,但离设备 A 还有很大差距。接下来处理线程调度问题。

框架支持通过配置文件或环境变量指定线程数和 CPU 亲和性。我直接指定"优先使用高性能核心"的策略,并把线程数从默认值调到一个更合理的值。这里有个细节值得说一下:线程数不是越大越好,对于 4 个高性能核的手机,推理线程设 4,再留一两个线程给系统做调度、渲染,效果往往比全开要好。

调完之后运行 top,确认推理线程确实都跑在大核上,CPU 频率也稳定在较高档位,速度又往上走了一截。

3.4 修复三:电源策略与模型加载优化

最后处理散热和功耗策略。设备 B 性能模式下,系统对大核频率的限制会放宽,但代价是发热更快,跑长文本时会撞到温度墙。

另外一个容易被忽略的点是模型加载速度。设备 B 用的是慢速存储,模型加载花了 30 多秒,期间框架界面卡死。后来我把模型文件换成加载到内存后缓存权重的方式,第二次加载只要 1~2 秒。

最后看数据:设备 B 从最初的 0.5 token/s,一路修到 7 token/s,再到 30+ token/s。虽然没有完全追平设备 A 的 43 token/s,但已经从"完全不可用"变成了"能正常对话"的水平。后端几个问题叠加起来,还真能凑出 80 倍的差距。

配置阶段速度 (token/s)主要瓶颈
初始状态0.5~0.6fp16 展开、线程挤小核、降频
更换量化版本约 7线程调度仍不理想
绑核+调线程约 22功耗/散热限制
性能模式+缓存30+硬件上限

4. 端侧推理性能排查清单与常用工具

这次排查完之后,我把经验整理成了一份快速自查清单。以后遇到类似的问题,直接按顺序走一遍,大多数情况 20 分钟内能定位。

4.1 5 分钟快速自查表

  1. 模型文件是否一致:比文件大小、SHA、量化位数。两台设备跑不同精度还对比速度,是排查里最常见的乌龙。
  2. 日志搜回退告警:找"revert""fallback""unsupported""unsupported kernel"字样。
  3. 看内存占用:int4 模型却占用 fp16 级别的内存,说明走了展开路径。
  4. 看线程分布:用监控工具实测推理线程是否都在大核,还是挤在小核。
  5. 关省电模式:切到性能模式再测试,排除频率墙。
  6. 测温度:设备发热严重时先降温再测,避免把温度墙误判成代码问题。
  7. 跑三次取中位数:单次测速受后台任务、系统调度影响很大,至少跑三次。

4.2 排查过程中最常用的几个工具

  • 系统自带的 CPU 频率和核心状态查看命令,实时看每个核的运行频率
  • top/ 增强版进程监控,看线程 CPU 占用率和进程状态
  • 日志抓取命令,观察框架运行时的告警输出
  • 基准测试脚本,反复压测,记录 prefill 和 decode 的耗时分布

独家技巧:测速时不要用第一次的结果。模型加载后会有权重预热、缓存命中的过程,直接测第一次通常偏慢。先空跑几轮把推理链路热起来,再正式记录数据,这样得到的数值才有参考价值。

5. 复盘:影响端侧 LLM 推理速度的几个底层因素

如果你把上面所有问题剥开看,真正决定"手机跑 LLM 快不快"的其实是几个底层因素。我顺手整理了一下,方便以后选设备或调框架时心里有底。

  • 量化格式和算子支持:同样的模型,int4 在支持的芯片上是高速路径,在缺指令集的芯片上可能回退成 fp16,速度差可以到 5~10 倍。这个往往是最关键的一环。
  • 单次解码的内存搬运量:解码阶段每生成一个 token 都要把全部权重读一遍,内存带宽直接决定天花板。带宽翻倍,解码速度就有可能翻倍。
  • 大小核调度策略:手机芯片的小核跑 LLM 就是灾难,线程被调度到小核上,再好的量化也发挥不出来。
  • 系统功耗控制:在散热有限的空间里塞进大模型推理,温度墙是绕不开的。性能模式和智能省电模式下的速度差距,实测能差到 3 倍以上。
  • 模型文件加载成本:大模型文件从闪存加载到内存的时间,在慢速存储上会明显放大。首 token 延迟和冷启动体验,往往坏在这上面,而不是推理本身。

顺手再提一个很多人踩过的坑:比较不同设备的性能时,一定要用同一个框架版本、同一个模型文件、同一个量化位数。我见过太多"设备 A 比设备 B 快几十倍"的结论,最后发现一个是 int4 模型、一个是 fp16 模型,根本没可比性。屏蔽掉这些干扰项,设备间真实的硬件差距往往远小于直觉判断。

这次排查给我最大的一个体会是:端侧推理的"慢",绝大多数不是硬件的硬伤,而是软件栈没有吃满硬件。从回退掉型的量化算子,到被调度错位的线程,再到被系统悄悄压掉的频率,任何一环出问题都会让你的手机"看起来"比别人的慢一个数量级。先查日志、再查线程、最后查功耗,这个顺序能筛掉 95% 的问题。希望这份实录能帮你在类似的问题上省下几个通宵。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/22 11:13:30

分治法与合并排序详解:从递归原理到O(n log n)复杂度推导

任何一个认真啃过《算法导论》的人,应该都对“分治法”这个章节记忆犹新。不光是因为合并排序(Merge Sort,也叫归并排序)作为第一个完整展示分治思想的经典算法被反复剖析,更是因为这一章第一次让你感受到“把一个复杂…

作者头像 李华
网站建设 2026/10/22 11:13:29

RMAN备份进程卡住怎么办?等待事件分析与三级处置指南

凌晨2点17分,监控告警把我从值班睡梦中捞起来:RMAN备份任务已经运行了4小时17分钟,是预期备份窗口的两倍还多。登录数据库看了一眼,最后一条RMAN日志停在半小时前,备份集进度卡在85/120的位置,会话状态Acti…

作者头像 李华
网站建设 2026/10/22 11:13:27

AI培训学什么?三大方向技术栈与学习路径全拆解

这两年AI岗位的热度大家有目共睹,身边想转行、想进阶的朋友越来越多,问得最多的一个问题就是:“AI培训到底学什么?是不是学完Python再报个班就能上岗?”说实话,这个问题的答案比大多数人想象的复杂。市面上…

作者头像 李华
网站建设 2026/10/22 11:12:05

AI写Rust为何总卡壳?所有权、生命周期与编译器反馈的结构性错配

前几天我拿代码辅助工具写一个异步日志组件,姑且叫它模拟项目X。同一个需求用某动态语言半天就写完了,换到 Rust 之后,光编译阶段就来回磨了十几轮。最让人头大的是:AI 给的代码一眼看过去完全没有语法毛病,函数签名工…

作者头像 李华
网站建设 2026/10/22 11:11:31

2026年SCRM工具实测:10家AI能力横评,首选这一款

2026年好用的SCRM工具评测:10家实测AI应用报告指引,首选这1款 一说做SCRM评测,很多人第一反应是“这年头还有必要吗?不就是把客户塞进企业微信,群发个朋友圈?” 恰恰是因为抱有这种想法的人太多&#xff…

作者头像 李华
网站建设 2026/10/22 11:11:03

WPF 年月选择器实战:TextBox+Popup+Calendar 实现与避坑指南

1. 从原生 Calendar 的局限说起:为什么需要年月选择器 WPF 自带的 Calendar 控件功能确实完整,日期、月份、年份三个视图层级都支持,点一下标题栏就能切换。但真正在业务系统里用过的人都知道,它有两个绕不开的痛点。 第一个痛…

作者头像 李华