想象你刚从巴黎出差回来,大行李箱里塞满了 20 公斤的衣物和纪念品,但登机箱只允许 7 公斤、20 寸。机场安检前你必须面对“要么扔、要么留”的残酷抉择——把一个大模型塞进手机,和这个场景几乎一模一样。手机的运存不到服务器的百分之一,用户却期待差不多的智能、及时的响应和流畅的体验。 于是,我们得像精明的旅行者一样:先想清楚这趟出门要带什么(模型选型),再用真空压缩袋把衣服压薄(量化压缩),把一路占地方却没用的纪念品扔掉(剪枝稀疏),向收纳大师偷学轻装诀窍(知识蒸馏),按登机口标准重新打包(格式转换),选择合适的托运传送方式(推理引擎),调整背包背法让身体更省力(端侧优化),最后真正出门经历一次风雨(真机测试)。目标只有一个:让大模型在巴掌大的设备里跑得动、跑得快、不发热、不崩溃。
掌握端侧压缩部署全流程,你就能把百亿参数大模型装进用户口袋,成为打通 AI 最后一公里的核心落地工程师。
可视化演示
展示大模型通过剪枝、蒸馏、量化等压缩技术部署到移动端的完整流程及压缩前后性能对比。
本节配有交互动效(进入视口后自动加载,约 3KB)。
移动端压缩部署 模型压缩:剪枝移除冗余参数 知识蒸馏:小模型学习大模型 量化部署:INT4/INT8降低显存占用 Size_final = Size_raw × (1 - prune) × distill_ratio × bits/16 压缩技术在移动端部署中的协同应用
模型选型
出发前,你绝不会拖着一个塞满土特产的大箱子直冲机场,而是先想清楚目的地、天数和预算,再决定带登机箱还是托运箱。把大模型部署到手机上也一样:别急着压缩,先想清楚用户到底要在手机上干什么。是识图、翻译,还是聊天?场景不同,适合的模型架构完全不同。
场景定了,路线就定了。接下来要面对的是手机的硬约束:内存、算力、电池。选型这一步的核心任务是挑出一个精度够用、体积可接受的基础模型,比如 7B、1.5B 还是 300M 的参数规模。判断标准不是“参数越多越厉害”,而是“够用就好、跑得动才算数”。
工程上最值得先算的一笔账,就是内存。FP32 格式下每个参数占 4 字节,量化到 INT8 后只占 1 字节;推理时还要考虑激活值和临时缓冲。所以业内习惯按 1.5 倍余量做预估算。
选对行李箱,后面才有收拾的余地。内存预算如果超了,后面量化、剪枝再花哨,也救不回“超重”的结局——选型是全局的第一颗扣子。
- 内存估算用模型参数量乘以单参数存储字节数,再乘余量系数,快速预估端侧模型需要占用的内存。
- 参数量 N模型所有可学习参数的总个数,比如 7B 模型就是约 70 亿个参数。
- 字节数 B每个参数用多少字节存储,FP32 占 4 字节,FP16 占 2 字节,INT8 占 1 字节。
- 余量系数把激活值、临时张量和推理引擎缓冲一并预留出来,避免运行到一半内存溢出。
量化压缩
冬天把羽绒服塞进真空压缩袋,体积直接缩成三分之一,保暖性却不打折。量化就是模型界的真空压缩袋:把 FP32 浮点数“挤”成 INT8 整数,体积缩小 4 倍,精度尽量不掉。
量化要解决一个核心问题:怎么把连续的浮点范围映射到离散的整数范围。这里需要两个关键参数:scale(缩放系数)和 zero_point(零点偏移)。scale 有点像压缩袋压得有多紧,决定浮点每单位对应多少整数步长;zero_point 则像刻度尺的起点,保证浮点 0 能在整数域找对自己的位置。
PTQ(后训练量化)是“压缩完再适应”:用少量校准数据算出量化参数,不重新训练参数,速度快、成本低;QAT(量化感知训练)则是“边训练边压缩”:把量化误差当噪声让模型自己适应,精度修复能力更强,但需要训练资源和时间。
把羽绒服压进真空袋,保暖虽有轻微损失,但登机箱装得下了。量化后模型精度通常有微小下降,却换来约 4 倍的体积缩减,这是端侧部署性价比最高、最优先考虑的一步。
- 缩放系数 scale把浮点数范围与整数范围对齐的映射间隔。
- 零点偏移 zero_point让浮点的 0 在整数域中也有准确对应的位置。
- 量化结果 q把浮点 r 除以 scale,四舍五入后再加零点偏移,得到的 INT8 整数。
- 反量化推理计算时把整数还原回浮点,保证数值分布恢复原貌。
剪枝稀疏
整理行李时,总有些纪念品占了一路却从没被翻过,果断扔掉,箱子立刻轻下来。剪枝就是这个思路:找出神经网络里“不重要的”权重连接或通道,把它们删掉,让模型变轻变快。
非结构化剪枝像随手从包里掏出一把碎石子扔掉,位置零散,虽然参数数量少了,但硬件难以有效加速;结构化剪枝像整个抛弃一个重复用途的化妆包,按通道、行、块整片移除,模型体积下降的同时,CPU/NPU 能真正获得速度收益。
剪枝之后,模型变得更稀疏。稀疏率越高,说明被删除的权重比例越大。但剪得太狠,模型可能像行李箱底被掏空,一走就散架。所以要用重要度排序决定先删哪些权重,并持续观察任务指标。
聪明地“舍弃”比硬塞更有用。扔掉用不上的东西,行李箱才能真正轻下来;剪掉冗余权重,手机跑模型才能真正快起来。但记住:舍得扔,不等于乱扔。
- 保留参数 N_keep剪枝后仍然保留的非零权重数量。
- 总参数 N_total剪枝之前的全部权重数量。
- 稀疏率 S用 1 减去保留比例,得到被移除参数的比例。
知识蒸馏
想学收纳大师的登机箱诀窍,不必搬走他的整箱行李,只需要偷学他的分类叠法、卷放顺序、空间取舍。知识蒸馏就是这样:让一个小模型(学生)去学习大模型(老师)的“判断习惯”。
老师输出的概率分布叫软标签。它不仅说出正确答案,还包含对被否决选项的犹豫程度。比如识别猫时给出“猫 0.9、老虎 0.08、狗 0.02”,这份纠结点是极有价值的教学材料——它告诉学生“猫和老虎有多像”。
学生模型训练时,一方面要用真实标签(硬标签)算交叉熵损失,确保方向正确;另一方面要用老师的软标签算 KL 散度损失,学习老师的“手感”。两份损失通过权重系数 α 调配。
大模型的“收纳智慧”被小模型偷师之后,你得到的是一个体积小、但思维方式很像老师的学生模型。它是移动端部署中实现精度与速度兼得的一种温柔解法。
- 硬标签损失 L_CE学生输出与真实标签的交叉熵,保证模型能答对客观事实。
- 软标签损失 L_KL学生分布与教师分布的 KL 散度,用来学习老师对易混淆项的判断梯度。
- 权重系数 α控制硬标签或软标签谁占主导,工程上通常取 0.5 附近再按任务微调。
格式转换
行李在机场要适应不同航空公司的行李规格:有的要求 20 寸以下,有的要求 18 寸以下。想让同一个行李箱适配所有航班,最稳妥的做法是换成一个“通用标准箱”。ONNX 就是模型界的通用标准箱。
PyTorch 或 TensorFlow 训练出来的模型是“私有收纳风格”,要扔进端侧引擎(TFLite、NCNN、MNN)里跑,得先导出为 ONNX 通用格式,再转换为目标引擎格式。格式转换不改变模型大小,但它决定模型能否被下游引擎识别和加速。
转换过程最大的坑是算子不支持。每个引擎维护自己的算子库,模型里如果有一个引擎实现不了的算子,轻则转换报错,重则运行到一半崩溃。因此动手前先查算子覆盖率,再决定要不要做算子替换或重新搭图。
换行李箱标准不是改箱子本身,而是换一套能过安检的尺寸。格式转换本身不减少体积,但它是连接“训练好的大模型”与“手机能跑的小模型”的必经桥梁,桥断了,后面寸步难行。
- 支持算子数 N_supported目标引擎能正常执行并加速的算子类型数量。
- 总算子数 N_total模型里出现过的全部算子类型数量。
- 覆盖率 C支持算子数除以总算子数,用来预判转换失败的风险。
推理引擎
行李过了安检,还得靠行李车、转盘和传送带送上飞机。推理引擎就是手机里的“行李传送系统”:它把模型文件解析成硬件指令,指挥 CPU、GPU、NPU 完成计算。
TFLite、NCNN、MNN 都是常见的端侧推理引擎,各有擅长:有的包体积极小,有的算子覆盖全,有的在特定芯片上速度飞快。选引擎不能光看文档,要在自己的模型和真机上做基准测试。
同一个 ONNX 模型在不同引擎上推理时延可能相差数倍。因此工程上习惯用加速比来量化:把优化后的时延和原始时延放在同一把尺子上量,一目了然。
好的托运系统能让你比同行早 20 分钟到登机口。选对推理引擎,既是耐心做基准测试,也是让压缩后的模型在手机上真正“跑飞”的关键临门一脚。
- 原始时延 T_原基准环境(比如 PyTorch CPU 或裸 ONNX Runtime)完成单次推理所需时间。
- 优化时延 T_新目标引擎完成同一模型、同一输入所需时间。
- 加速比 Speedup两者相除得到性能增益倍数。
端侧优化
同样一个登机箱,会背的人把重物贴近背部、收紧肩带、左右轮换肩膀,走一天也不累。模型部署后也一样:不优化也能跑,但优化之后更省电、少发热、更跟手。
端侧优化有几个主要抓手。第一是多线程:把计算拆到多个 CPU 核上并行;第二是异构计算:把能下沉的算子交给 NPU 或 GPU,CPU 只做调度;第三是内存复用:避免推理过程中频繁申请和释放内存。
移动端处理器的小核与大核能力差距很大,盲目开满大核会让手机迅速发热降频。成熟做法是“大小核调度”:轻任务跑小核,重任务开大核;同时把数据排成向量化友好的内存布局,减少访存等待。
会整理背包的人走得远。端侧优化不是制造奇迹,而是让每一瓦电、每一个核心都花在刀刃上,让模型在手机上长跑不累、发热可控。
- 计算时延 T_compute单个计算核心完成全部计算指令所需时间。
- 并行核数 n_cores推理过程中真正同时参与计算的 CPU/GPU/NPU 单元数量。
- 访存时延 T_mem权重、激活、中间结果在不同内存层级间搬运的额外开销。
真机测试
在家门口试走两步不算旅行,真到机场才发现安检排队、值机延误、登机口变更才是常态。真机测试是部署前最后一道关,也是模拟器永远替代不了的验收环节。
真机测试要盯住的指标包括:首帧时延、P95 延迟、内存峰值、掉帧率、耗电速度、机身温度,以及长期运行的崩溃率。不能只跑一两次就下结论,要连续压测几小时,观察发热后性能是否会“跳水”。
P95 延迟是工程上最常用的稳健性指标。它不像平均值那样容易被少数超快样本拉低,而是直接告诉你:绝大多数请求最坏会慢到什么程度。
一次彻底的真机测试就是一次完整的旅行验收。只有经历过弱网、发热、待机唤醒、后台切换这些真实场景,你才有底气说:这个模型,真的落地了。
- 延迟采样在真机上连续跑 N 次推理,记录每一次的耗时。
- 升序排序把全部延迟从小到大排序。
- 取第 95 分位读取排序后第 95% 位置的延迟,意味着只有 5% 的请求比它更慢。
AI 应用场景
端侧智能客服意图识别
阶段:模型压缩与部署推理
解决的问题:传统做法是把所有请求发给云端大模型,一旦弱网或断网,用户消息石沉大海。把意图识别模型量化、蒸馏后放到手机端,离线也能秒级响应,同时保护用户隐私。
具体案例:某银行 App 的「还款日查询」对话机器人,原本 500MB 的 BERT 模型经蒸馏量化后压缩到 40MB,在骁龙 8 系手机端侧推理首 次响应约 80ms,弱网环境下用户体验大幅提升。
工业手持终端缺陷检测
阶段:模型选型与格式转换适配
解决的问题:工厂网络不稳定,质检图片又涉及产线机密,无法全部上云。需要把检测模型转换到端侧推理引擎,并适配 NPU,做到无网实时检测。
具体案例:某电子元件厂用手持式工业终端检测插针缺陷,YOLO 小模型从 120MB 压缩到 15MB,转换到 NCNN 并完成 NPU 算子适配后,单帧检测 30ms,每分钟可抽检 300 个元件。
智能手表健康问答
阶段:端侧优化与真机测试
解决的问题:手表电池只有几百毫安时,无法承载高功耗的云端通信和大型模型推理。需要把模型压到极小,并做好能耗调度和真机压力验证。
具体案例:某运动手表部署蒸馏后的 1.3B 健康问答模型,通过大小核调度和 NPU 下沉,问询响应低于 500ms,日常待机功耗仅增加约 2mA,连续工作时间几乎不受影响。
Python 演示
import numpy as np def quantize_weights(weights_fp32, bits=8): """对称量化:把 FP32 权重映射到 INT8 整数域""" qmax = 2 ** (bits - 1) - 1 scale = np.max(np.abs(weights_fp32)) / qmax weights_int = np.clip(np.round(weights_fp32 / scale), -qmax, qmax) return weights_int.astype(np.int8), scale def main(): np.random.seed(42) weights = np.random.randn(128, 128).astype(np.float32) mem_fp32 = weights.nbytes w_int8, scale = quantize_weights(weights) mem_int8 = w_int8.nbytes w_dequant = w_int8.astype(np.float32) * scale mse = float(np.mean((weights - w_dequant) ** 2)) print(f"FP32 大小: {mem_fp32 / 1024:.1f} KB") print(f"INT8 大小: {mem_int8 / 1024:.1f} KB") print(f"压缩比: {mem_fp32 / mem_int8:.1f}x") print(f"重建误差 MSE: {mse:.6f}") if __name__ == "__main__": main()
qmax = 2 ** (bits - 1) - 1算出 INT8 能表示的最大正整数 127,作为量化上限。scale = np.max(np.abs(weights_fp32)) / qmax用权重绝对值最大值除以 127,得到每次整数步进代表的浮点大小。weights_int = np.clip(np.round(weights_fp32 / scale), -qmax, qmax)把浮点权重除以 scale 后四舍五入,并裁剪到合法整数范围。w_dequant = w_int8.astype(np.float32) * scale反量化回浮点,用于计算压缩带来的精度损失。mse = float(np.mean((weights - w_dequant) ** 2))计算重建误差,MSE 越小说明量化保真度越高。
常见误区
误区我刚接触量化时以为,把 FP32 直接切成 INT8,模型肯定废了,所以一直不敢用。
正解量化并不是简单截断,而是通过 scale 和 zero_point 把浮点分布整体映射到整数域,让离散化误差尽量小。对于多数权重分布接近正太的模型,PTQ 校准后精度损失往往在 1% 以内,QAT 甚至能进一步逼近原精度。
为何常见:人很容易从直觉出发,认为位数少了信息就丢了,但没意识到量化做的是“全局重映射”,而不是粗暴丢位。
误区为了把模型压到最小,我把 80% 的权重都置零,结果模型直接变成“人工智障”。
正解剪枝要根据重要度排序,优先删掉对输出影响最小的连接。并且要区分结构化与非结构化:非结构化剪枝稀疏率再高,硬件不支持也难加速;结构化剪枝要控制粒度,过度剪枝会造成不可逆精度坍塌。
为何常见:把“稀疏率”当作目标来追求,把手段当成了目的,忽略了任务性能才是真正要守住的指标。
误区模型在 PyTorch 里导出 ONNX 顺利通过,我就以为所有端侧引擎都能直接跑。
正解ONNX 只是统一交换格式,TFLite、NCNN、MNN 等引擎的算子支持库各不相同。转换后还要做算子核验、精度对齐、跑通真机,任何一个环节失败都会让部署卡壳。
为何常见:看着“转换成功”四个字就以为大功告成,忽略了从“能导出”到“能高效运行”之间还有很长的工程链路。
误区在电脑模拟器上测延迟和内存都很好,想着真机肯定也没问题。
正解真机上有热降频、内存带宽、NPU 驱动、后台进程抢占等多重干扰,模拟器跑不出来的卡顿和崩溃在真机上原形毕露。必须做长时间真机压测,关注 P95 延迟、温度拐点和崩溃率。
为何常见:模拟器环境高效可控,但它无法复现真实硬件的散热行为和调度策略,让人误以为“环境没问题”。
面试题
Q1. 某个 7B 模型以 FP32 格式存储,权重大约占用多少内存?
- A.28GB← 正确答案
- B.14GB
- C.7GB
- D.3.5GB
答案:A。7B 参数即 70 亿个参数,FP32 每个占 4 字节,所以 7e9×4≈28GB。这就是为什么模型必须经过量化压缩才有机会部署到手机上。
Q2. 量化公式中 scale 的主要作用是什么?
- A.提升模型精度
- B.浮点映射整数← 正确答案
- C.增加模型参数量
- D.删除冗余权重
答案:B。scale 决定浮点范围如何映射到整数范围,类似压缩袋压紧的程度。它本身不提升精度,也不改变参数量,只是做数值域的等比例映射。
Q3. 关于 PTQ(后训练量化),下列说法正确的是?
- A.必须重新训练模型
- B.借助少量校准数据确定 scale 和 zero_point← 正确答案
- C.完全不需要任何数据
- D.只适用于图像分类模型
答案:B。PTQ 用少量校准数据统计权重和激活的分布,从而确定量化参数。它不重新训练模型,也不限图像场景,因此 B 正确,A、C、D 都错。
Q4. 下列哪种剪枝属于结构化剪枝?
- A.把某个卷积核整体置零← 正确答案
- B.把权重矩阵里随机元素置零
- C.只保留负权重
- D.对权重做四舍五入
答案:A。结构化剪枝按通道、卷积核等整块结构移除,硬件能真正获得加速。随机置零属于非结构化剪枝,只保留负权重和四舍五入都不是剪枝。
Q5. 知识蒸馏里,学生模型能从老师模型身上学到什么?
- A.最终预测结果之外的概率分布信息← 正确答案
- B.中间层特征表示← 正确答案
- C.训练数据的原始标签
- D.更深的网络结构
答案:AB。蒸馏的核心是让学生学老师的“判断手感”,包括软标签分布和中间层特征。原始标签是数据集自带的,不是从老师学的;网络结构是学生自己定义的,也不能从老师继承。
Q6. 为什么部署链路中常用 ONNX 作为中间格式?
- A.ONNX 推理速度最快
- B.方便模型从 PyTorch 转换到多种端侧引擎← 正确答案
- C.只有 ONNX 格式才能部署
- D.ONNX 会自动缩小模型体积
答案:B。ONNX 是开放中间表示,连接训练框架和推理引擎,相当于通用的“标准行李箱”。它不保证最快,也不自动压缩,更不是唯一能部署的格式。
Q7. 在移动端做推理引擎选型时,应该重点对比哪些维度?
- A.算子覆盖率← 正确答案
- B.CPU/GPU/NPU 支持情况← 正确答案
- C.包体积与社区生态← 正确答案
- D.训练集损失函数
答案:ABC。引擎选型看它能不能跑全模型的算子、能不能用上手机上的异构算力、以及包体积和生态是否友好。训练集损失函数是训练阶段的事,与引擎选型无关。
Q8. 某模型推理延迟的 P95 是指?
- A.5% 的请求延迟超过该值
- B.平均延迟加 95 毫秒
- C.95% 的请求延迟低于该值← 正确答案
- D.95% 的请求会失败
答案:C。P95 表示把 N 次延迟升序排列后取第 95% 位置的值,即 95% 的请求延迟低于该值。它比平均值更能反映真实卡顿情况,是端侧性能验收的重要指标。
Q9. 端侧推理优化中,哪些手段能有效降低时延?
- A.多线程并行计算← 正确答案
- B.算子下沉到 NPU← 正确答案
- C.减少内存拷贝次数← 正确答案
- D.盲目增大 batch size
答案:ABC。多线程、NPU 异构加速、减少内存拷贝都是端侧优化常用手段。盲目增大 batch size 反而会抬高峰值内存并显著增加时延,在手机端通常不可取。
Q10. 某 INT8 量化模型在真机上推理时发热严重,最可能的原因是?
- A.模型精度过高
- B.部分算子未下沉 NPU 导致 CPU 高负载← 正确答案
- C.输入图片尺寸太小
- D.预处理数据增强过弱
答案:B。发热通常源于高功耗计算。如果模型有算子跑不到 NPU 而上 CPU 大核密集执行,功耗会明显上升。精度高低、输入尺寸和增强策略与发热没有直接因果关系。