TensorFlow Lite 核心功能:量化方式、硬件委托与算子兼容性
TensorFlow Lite 核心功能:量化方式、硬件委托与算子兼容性
TFLite 的能力可以概括成三条主线:把模型变小(量化)、把计算挪到更合适的硬件(delegate)、把算子控制在运行时支持的范围内(OpsSet 与算子兼容性)。三条线互相牵制,任何一条走极端都会在端上翻车。
量化方式对比
| 方式 | 权重 | 激活 | 体积 | 需要校准集 | 适用场景 |
|---|---|---|---|---|---|
| Float32(基准) | FP32 | FP32 | 1x | 否 | 精度优先、对体积不敏感 |
| FP16 量化 | FP16 | FP32 | 约 1/2 | 否 | GPU 上收益明显,精度损失很小 |
| 动态范围量化 | INT8 | 运行时动态量化 | 约 1/4 | 否 | 改动最小,适合先跑通再深挖 |
| 全整数量化 INT8 | INT8 | INT8 | 约 1/4 | 是 | 要上 NNAPI / Hexagon / Edge TPU 时必须 |
| INT16 激活 + INT8 权重 | INT8 | INT16 | 介于两者之间 | 是 | 实验特性,精度与体积的折中 |
先记住结论:只要想用 NPU、DSP 或 Edge TPU 这类定点加速器,就绕不开全整数量化,也就绕不开准备校准集。量化不是打开一个开关就完事,它是用少量真实样本换来的数值近似。
硬件委托(Delegate)对比
| Delegate | 平台 | 硬件 | 主要限制 |
|---|---|---|---|
| XNNPACK | 全平台 CPU | ARM / x86 | 默认启用,通常无需手动干预 |
| GPU Delegate | Android / iOS | OpenCL、OpenGL ES、Metal | 首次初始化有开销;部分算子不支持时会回退,并把计算图切成多段 |
| NNAPI Delegate | Android(较新系统版本) | 厂商 NPU / DSP / GPU | 实际表现强依赖驱动质量与设备型号 |
| Hexagon Delegate | Android | 高通 DSP | 仅部分骁龙平台,需要额外下发 skel 库 |
| Core ML Delegate | iOS / macOS | ANE / GPU | 对算子与模型结构有约束,不满足则回退 |
| Edge TPU | Linux(Coral 设备) | Edge TPU | 必须全整数量化,且所有算子都要能被编译到 TPU |
| Flex Delegate | 全平台 | CPU | 允许使用 TF 原生算子,代价是二进制体积明显增大 |
关键配置项
| 配置项 | 作用 | 实践建议 |
|---|---|---|
| converter.optimizations | 打开默认优化,即权重量化 | 设为 [tf.lite.Optimize.DEFAULT] |
| converter.representative_dataset | 提供校准样本 | 覆盖真实分布,数百条量级,必须包含难例 |
| target_spec.supported_ops | 限定可用的算子集 | 尽量只用 TFLITE_BUILTINS;混入 SELECT_TF_OPS 会拖累体积与可移植性 |
| inference_input_type / inference_output_type | 指定端侧输入输出张量类型 | 全整数模型常设为 tf.uint8 或 tf.int8 |
| per-channel 量化 | 卷积权重按输出通道分别量化 | 一般保持默认开启,精度更稳 |
| Interpreter.set_num_threads | CPU 推理线程数 | 避开小核,常用 2–4;线程过多反而互相抢核 |
| Interpreter.Options(Android) | 设置线程数与 delegate | 先探测设备能力再挂 delegate,失败立刻回退 |
算子兼容性要单独盯。转换时可以用官方分析器工具打印模型里每个算子的分布,确认是否全部落在纯 TFLite 算子集内:
python -c '
import tensorflow as tf
model = open("model.tflite", "rb").read()
tf.lite.experimental.Analyzer.analyze(model_content=model)
'
若某个算子只能在 Flex 下工作,它就会成为整张图里最慢的一环,还会让 NNAPI 把计算图切碎,反而更慢。

