为什么模型要量化后推理 – by Cloud 3.5

2024年12月27日 作者 unix2go

这个问题涉及到深度学习中精度和效率的权衡,我从几个方面解释。

  1. 训练时使用浮点型的原因:
  • 梯度计算需要高精度
  • 反向传播时的梯度值通常很小
  • 浮点数能更好地表示小数值变化
  • 避免梯度消失问题
  • 权重更新需要连续性
  • 小步长学习需要精确的小数表示
  • 权重微调需要高精度支持
  • 数值稳定性
  • 避免舍入误差累积
  • 保持训练过程的数值稳定

2. 推理时使用整数型的优势:

    • 计算效率高
    • 整数运算比浮点运算快3-4倍
    • 硬件电路更简单
    • 功耗更低
    • 存储空间小
    • INT8比FP32节省75%空间
    • 更适合边缘设备部署
    • 延迟更低
    • 整数运算延迟更稳定
    • 适合实时推理场景

    3. 精度损失控制:

      # 量化示例:FP32转INT8
      def quantize_model(model, calibration_data):
          # 1. 确定量化范围
          min_val = float('inf')
          max_val = float('-inf')
      
          # 收集激活值范围
          for data in calibration_data:
              output = model.predict(data)
              min_val = min(min_val, output.min())
              max_val = max(max_val, output.max())
      
          # 2. 计算量化参数
          scale = (max_val - min_val) / 255
          zero_point = round(-min_val / scale)
      
          # 3. 量化公式
          def quantize(x):
              return round(x / scale + zero_point)
      
          return quantize, scale, zero_point
      1. 量化前后精度对比:
        典型精度损失参考:
      模型类型    FP32准确率    INT8准确率    精度损失
      图像分类    76.5%        76.1%        0.4%
      目标检测    80.2%        79.8%        0.4%
      语义分割    72.3%        71.8%        0.5%
      1. 实际应用建议:
      • 训练时:
        # 使用浮点训练
        model.fit(
            x_train.astype('float32'),
            y_train,
            batch_size=32,
            epochs=10
        )
      • 推理时:
        # 量化后推理
        quantized_model = tf.lite.TFLiteConverter.from_keras_model(model)
        quantized_model.optimizations = [tf.lite.Optimize.DEFAULT]
        quantized_model.target_spec.supported_types = [tf.int8]
      1. 量化注意事项:
      • 训练时考虑量化感知训练(QAT)
      • 选择合适的校准数据集
      • 关键层可以保持浮点精度
      • 监控量化前后的精度变化
      • 测试不同量化策略的效果