Conceptos básicos de la cuantificación del modelo de aprendizaje profundo

artículo de referencia

Introducción a la Cuantización de Redes Neuronales-Principios Básicos-Conocimientos

Cuantificación y entrenamiento de redes neuronales para una inferencia eficiente de aritmética entera únicamente

Cuantificación de enteros para inferencia de aprendizaje profundo: principios y evaluación empírica

Un estudio de los métodos de cuantificación para la inferencia eficiente de redes neuronales

Resumen de Cuantificación de modelos e implementación de aterrizaje

Cuantificación Int8 - Introducción (1) bzdww

Cuantificación y entrenamiento de redes neuronales para una inferencia eficiente de aritmética entera únicamente

Introducción a los últimos avances en la cuantificación de modelos de transformadores:

Optimización de inferencia de modelos de transformadores grandes | pequeño tronco

Método de cuantificación del modelo de lenguaje grande LLM (1)

Conceptos básicos de cuantificación

Cuantificación posterior al entrenamiento Cuantificación posterior al entrenamiento (PTQ)

El proceso de cuantificación solo cuantifica los pesos y los valores de activación infiriendo algunos datos de muestra fuera de línea, sin entrenamiento de ajuste fino.

PTQ se puede dividir en cuantificación uniforme y cuantificación no uniforme (la diferencia es si los valores fp32 e int antes y después de la cuantificación son lineales, y la cuantificación uniforme se usa más comúnmente):

La cuantificación uniforme permite el uso de canalizaciones matemáticas enteras o de punto fijo, lo que permite realizar cálculos en el dominio cuantificado.

La cuantificación no uniforme requiere descuantificación, por ejemplo, una búsqueda en el libro de códigos, antes de realizar el cálculo con mayor precisión, lo que limita sus beneficios a la compresión del modelo y la reducción del ancho de banda. 

La cuantificación uniforme se divide además en cuantificación afín y cuantificación de escala, que también pueden llamarse cuantificación asimétrica y cuantificación simétrica.La relación de mapeo entre fp32 e int antes y después de la cuantificación es solo una relación múltiple, y no hay sesgo, por lo que el cálculo es más simple

PTQ también se puede dividir en cuantificación dinámica y cuantificación estática:

Cuantificación dinámica: la escala y el punto cero solo se calculan durante la inferencia. En comparación con la cuantificación estática, la cantidad de cálculo es mayor y la precisión puede ser mayor. Se considera que se utiliza el modelo NLP.

Cuantificación estática: use el conjunto de datos de calibración para calcular los parámetros de cuantificación por adelantado, y la cantidad de cálculo es significativamente menor que la de la cuantificación dinámica.

Entrenamiento consciente de la cuantización (QAT)

En el proceso de cuantificación, la red se entrena para que los parámetros de la red puedan adaptarse mejor a la pérdida de información causada por la cuantificación. Este enfoque es más flexible, por lo que la precisión suele ser mayor que la cuantificación posterior al entrenamiento. La desventaja es que no es conveniente operar. En la mayoría de los casos, la precisión de la cuantificación es mayor que después del entrenamiento, y algunas escenas no son necesariamente mucho mejores que la cuantificación de precisión parcial/mixta.

Fórmula de cálculo cuantitativo

(La imagen está tomada de Introducción a la cuantificación de redes neuronales-Principios básicos-Conocimiento )

La fórmula anterior es la forma de cuantificación afín. Scale Quantization es el caso donde Affine Quantization Z es 0.

El coeficiente de compensación z debe garantizar que 0 del número real corresponda a un valor después de la cuantificación, por lo que z debe ser un número entero.

La fórmula anterior no es absolutamente correcta, y aún debe tener cuidado al usarla : si un tensor tiene todos los mismos valores o el contenido min max difiere muy poco, encontrará que la fórmula anterior no se puede usar. Porque cuando todo el tensor tiene el mismo elemento o solo un elemento, la escala se convierte en 0. En este momento, se requieren otras soluciones para enfrentarlo. Por ejemplo, puede elegir s = r / N, N es un número entero positivo, esto teóricamente no es un error de cuantificación, y luego el problema es elegir el N apropiado

Por ejemplo, scale = r/int(max(sqrt(abs(r)), 1)), donde N toma int(max(sqrt(abs(r)), 1)). El tamaño de la escala y Z puede ser moderado. Aquí, r = 0 debe tratarse especialmente para que la escala no sea 0.

Multiplicación de matrices y cuantificación de convolución

 multiplicación de matrices

Aquí B es el peso, que está cuantificado por escala. Si B también usa cuantificación afín, el proceso de cálculo será muy complicado y generalmente no se usa.

La convolución se puede derivar de manera similar

técnicas cuantitativas

Calibración

Cómo seleccionar el rango de valores [b,a] antes de la cuantificación es una de las tareas más importantes en la cuantificación del modelo, que tiene un gran impacto en la precisión. En general, hay un máximo, entropía (divergencia KL utilizada en TensorRT), percentil (como el valor máximo de 99,9 %, 99,99 % y otros elementos proporcionales).

El rango numérico y la precisión después de la cuantificación dependen directamente del rango que el tipo int puede expresar, mientras que los valores de peso y activación antes de la cuantificación pueden tener características similares a la distribución gaussiana. Si max se usa directamente, aunque todos los rangos de punto flotante tienen una representación de tipo int antes de la cuantificación, la precisión de la representación de tipo int es muy aproximada debido al número limitado de muestras de tipo int. Sin embargo, si [b, a] se selecciona demasiado pequeño, se truncará una gran cantidad de datos útiles, lo que también conducirá a una precisión insuficiente. Por lo tanto, debe haber un rango óptimo de valores antes de la cuantificación para optimizar la precisión bajo una distribución específica y una cuantificación de tipo int. El percentil selecciona directamente 99,9 % o 99,99 % de elementos proporcionales después de clasificar todos los elementos de datos como umbral. La divergencia KL utilizada por TensorRT muestra una buena precisión y versatilidad en la mayoría de los modelos CV. Además, se pueden usar diferentes métodos de selección de rango para la cuantificación de peso y activación. Por ejemplo, el peso generalmente puede usar max o Percentil con mayor precisión, mientras que la cuantificación de activación generalmente no puede usar max.

Referencia: https://on-demand.gputechconf.com/gtc/2017/presentation/s7310-8-bit-inference-with-tensorrt.pdf

CUANTIZACIÓN DE ENTEROS PARA LA INFERENCIA DE APRENDIZAJE PROFUNDO: PRINCIPIOS Y EVALUACIÓN EMPÍRICA

El ppt de TensorRT brinda el proceso y el pseudocódigo basado en la divergencia KL. La idea básica del proceso es:

Siempre es una compensación entre el rango y la precisión de la representación INT8.

Queremos minimizar la pérdida de información.
La pérdida de información se mide mediante la divergencia de Kullback-Leibler (también conocida como entropía relativa o divergencia de información).
P, Q - dos distribuciones de probabilidad discretas.
KL_divergence(P,Q):= SUM(P[i] * log(P[i] / Q[i] ), i)
P es el histograma antes de la cuantificación y Q es el histograma después de la cuantificación.

Un método simple es obtener P contando el histograma de los bins originales de número de punto flotante 2048 de acuerdo con los resultados del cálculo de los datos de calibración. Luego use diferentes umbrales para obtener el histograma Q de números de coma flotante cuantificados a través de la cuantificación y la cuantificación inversa. Calcula la KL_divergencia de dos distribuciones. Por supuesto, este enfoque es ligeramente diferente al de TRT PPT.

Cuantificación por tensor : todo el tensor comparte parámetros de cuantificación.

Cuantificación por canal (Conv) o por columna (MatMul) : Cada elemento de canal comparte parámetros, y diferentes canales usan diferentes parámetros. Por lo general, la precisión de la cuantificación es más alta que la de por tensor y tiene menos impacto en la fusión BN. Puede evitar la caída significativa en la precisión causada por el uso de la cuantificación por tensor en profundidad-sabio-conv2d en mobileNet. Esto es Debido a que el rango de valores de ponderación de cada canal varía mucho, el uso del mismo conjunto de parámetros de cuantificación puede conducir a una falta significativa de precisión para los canales con un rango de valores pequeño.

La primera y la última capa del modelo normalmente no se cuantifican o se cuantifican con mayor precisión. (¿Se puede juzgar automáticamente? ¿Se puede juzgar automáticamente en función de las diferencias en los resultados de diferentes datos?)

cuantificación de peso

En general, el peso utiliza la cuantificación de la escala y la precisión suele ser suficiente. El uso de cuantificación afín conducirá a un aumento significativo en la complejidad computacional. La cuantificación de activación puede usar cuantificación afín o de escala, y la complejidad computacional de la cuantificación afín es ligeramente mayor. (Conclusión basada en la fórmula de cuantificación calculada por MatMul y Conv2D)

Por canal es generalmente más preciso que por tensor.

Como los parámetros de BN se aprenden por canal, su plegamiento puede dar como resultado distribuciones de valor de peso significativamente diferentes entre canales. Afortunadamente, como muestra la Tabla 3, la granularidad de cuantificación por canal mantiene la precisión del modelo incluso con plegamiento de BN. Granularidad nnel, calibración máxima La pérdida de
precisión es muy pequeño (la mayoría de ellos son menos de 0,5 puntos porcentuales), y el tamaño del modelo se convierte en 1/4 del original.

vectores de sesgo, se cuantifican como enteros de 32 bits
 

Referencia de código Python de simulación cuantificada

Se puede encontrar que es mejor usar un conjunto de coeficientes de cuantificación en la misma columna para el peso de la multiplicación de matrices.

import numpy as np
import copy

weight = np.load("tensor1.npy")


def round_near(data):
    """Round data to nearest int
    For example, 0.1 to 0, 0.5 to 1
    """
    if data >= 0:
        data += 0.5
    else:
        data -= 0.5
    return int(data)


def get_u8_quant_coef(np_tensor):
    max_val = np.max(np_tensor)
    min_val = np.min(np_tensor)

    dst_max = 255
    dst_min = 0

    scale = (max_val-min_val)/(dst_max-dst_min)
    zero_point = dst_max - max_val / scale
    zero_point_i8 = np.rint(zero_point)
    return scale, zero_point_i8


def quant_u8(np_tensor, scale, zero_point):
    quanted_tensor = (np_tensor / scale + zero_point)
    quanted_tensor_1d = quanted_tensor.reshape([-1])
    for i, elem in enumerate(quanted_tensor_1d):
        quanted_tensor_1d[i] = np.rint(elem)
    quanted_tensor = quanted_tensor_1d.reshape(quanted_tensor.shape)
    return quanted_tensor


def dequant(np_tensor, scale, zero_point):
    dequant_tensor = np_tensor.astype("float32")
    dequant_tensor = (dequant_tensor-zero_point)*scale
    return dequant_tensor


def get_error(tensor1, tensor2):
    return np.sum(np.abs(tensor1 - tensor2))


def get_dequant(np_tensor):
    scale, zero_point = get_u8_quant_coef(np_tensor)
    quanted_tensor = quant_u8(np_tensor, scale, zero_point)
    dequant_tensor = dequant(quanted_tensor, scale, zero_point)
    return dequant_tensor, scale, zero_point


dequant_tensor, scale, zero_point = get_dequant(weight)

error = get_error(weight, dequant_tensor)

weight1 = copy.deepcopy(weight)
weight2 = copy.deepcopy(weight)


col = weight1.shape[1]
row = weight1.shape[0]


for i in range(col):
    line_data = weight[:, i]
    dequant_tensor_i, scale_i, zero_point_i = get_dequant(line_data)
    weight1[:, i] = dequant_tensor_i


for i in range(row):
    line_data = weight[i, :]
    dequant_tensor_i, scale_i, zero_point_i = get_dequant(line_data)
    weight2[i, :] = dequant_tensor_i

error1 = get_error(weight, weight1)
error2 = get_error(weight, weight2)

cuantificación de activación

La calibración máxima generalmente no está disponible. El modelo de clase CV Entropy y 99% (99.9% 99.99% 99.999% 99.9999%) precisión de calibración no son muy diferentes, y Entropy es mejor en la mayoría de los casos. La precisión de la calibración de entropía de algunos modelos NLP se ha reducido significativamente del 99 %.

La calibración del percentil del 99,9 % recorta los valores de gran magnitud demasiado agresivos y conduce a caídas de precisión significativas en la mayoría de las redes.

Los mejores resultados de cuantificación posteriores al entrenamiento se logran con calibraciones de percentil de entropía, 99,99 % o 99,999 %, aunque ninguna calibración individual es la mejor para todas las redes.

其他算子量化
Los trabajos de cuantificación solo enteros notables incluyen [154], que fusiona la normalización por lotes en la capa de convolución anterior, y [113], que propone un método de cálculo solo entero para redes residuales con normalización por lotes. Sin embargo, ambos métodos están limitados a la activación de ReLU. El trabajo reciente de [132] aborda esta limitación al aproximar GELU [94], Softmax y Layer Normalization [6] con aritmética de enteros y amplía aún más la cuantificación de solo enteros a las arquitecturas Transformer [243].

La cuantificación de algunos operadores puede tener un gran impacto en la precisión, como softmax, etc., sin cuantificación.

Un modelo simple de cuantificación de subgrafos:

Optimización del coeficiente de cuantificación

La cuantización diádica es otra clase de cuantización de solo números enteros, donde todo el escalado se realiza con números diádicos, que son números racionales con valores enteros en su numerador y una potencia de 2 en el denominador.Sustituye, y el divisor es una potencia de 2, por lo que el cálculo de escala no necesita usar división)

El impacto de diferentes modelos de redondeo

Técnicas para recuperar la precisión

Cuantificación parcial: no cuantice capas que tengan un gran impacto en la precisión.

Cuantificación de precisión mixta: las diferentes capas utilizan una cuantificación de precisión diferente, como fp16, int8, etc.

La exclusión de una pequeña cantidad de capa puede reducir la pérdida de precisión entre un 0,05 % y un 0,1 %.

Se puede considerar la adición: cada vez que se encuentra el grupo con el menor impacto en la precisión para la cuantificación. También puede considerar hacer restas, cuantificar todo y luego eliminar la capa que tiene el mayor impacto en la precisión. Este último puede ser más eficiente, ya que la proporción de eliminación es una pequeña proporción de la cuantización total.

Cuantificación sin datos a través de ecualización de peso y corrección de sesgo

CV, transformador disponible, el modelo bert es único

Para BERT, el análisis de sensibilidad no revela ninguna capa en particular que contribuya más a la caída de la precisión. Como resultado, no podemos identificar un pequeño subconjunto de capas para dejar en punto flotante.
Para abordar esto, debemos considerar diferentes enfoques. La sección 5.2 incorpora la cuantificación con entrenamiento para recuperar la precisión. Además, el Apéndice D examina la función de activación de GELU en BERT y presenta un aumento simple para mejorar significativamente la precisión de cuantificación posterior al entrenamiento.

Hay artículos que investigan que otros métodos de ronda además de la ronda de redondeo pueden tener una mejor precisión.

Método de búsqueda de parámetros de cuantificación de precisión mixta

Los parámetros de cuantificación de precisión mixta se pueden buscar mediante aprendizaje de refuerzo, algoritmos genéticos, NAS y más.
A diferencia de estos enfoques basados ​​en la exploración y la regularización, HAWQ [51] introduce una forma automática de encontrar la configuración de precisión mixta basada en la sensibilidad de segundo orden del modelo. 

En HAWQv2, este método se amplió a la cuantificación de activación de precisión mixta [50], y se demostró que es más de 100 veces más rápido que los métodos de precisión mixta basados ​​en RL [246].

Recientemente, en HAWQv3, se introdujo [267] una cuantificación con reconocimiento de hardware solo de enteros que proponía un método rápido de programación lineal de enteros para encontrar la precisión de bits óptima para una restricción específica de la aplicación (por ejemplo, tamaño del modelo o latencia).

Flujo de trabajo recomendado

recomendamos lo siguiente para la cuantificación int8:
Pesos :
    – Use la cuantificación de escala con granularidad por columna/por canal
    – Use un rango de enteros simétricos para la cuantificación [-127, 127]) y calibración máxima
Activaciones :
    – Use la cuantificación de escala con con granularidad por tensor

La activación puede ser mejor con afín, y el documento no tiene una evaluación detallada. Debido a que la capa superior puede estar conectada a relu, el rango de valores no es simétrico.
Recomendamos el siguiente procedimiento para cuantificar una red neuronal previamente entrenada:
• PTQ: Cuantifique todas las capas computacionalmente intensivas (convolución, lineal, multiplicación de matrices, etc.) y ejecute la calibración de activación, incluido el máximo, la entropía y el percentil 99,99%, 99,99 9%. . Si ninguna de las calibraciones produce la precisión deseada, continúe con la cuantificación parcial o QAT.
• Cuantificación parcial: Realice un análisis de sensibilidad para identificar las capas más sensibles y déjelas en punto flotante. Si el impacto en el rendimiento computacional no es aceptable o no es aceptable no se puede alcanzar la precisión, continúe con QAT.
• QAT: Partir del modelo cuantificado mejor calibrado. Use QAT para ajustar con precisión alrededor del 10 % del programa de capacitación original con un programa de tasa de aprendizaje de recocido que comienza en el 1 % de la tasa de aprendizaje de capacitación inicial. Consulte el Apéndice A.2 para conocer las opciones de hiperparámetros específicos.

Tres operadores importantes

Cuantizar: cuantizar fp32 a int8.

Descuantificar: Descuantificar int8 a fp32.

Recuantificar: ambas entradas de operadores como Conv2d/MatMul son int8 y el tipo de salida es int32 para evitar el desbordamiento. En este momento, debe usar Requantize: Conv2d para cuantificar la salida int32 mediante operadores como Conv2d/MatMul en int8 como la entrada del siguiente operador de cuantificación. Es decir, convertir el tipo int representado por un conjunto de parámetros de cuantificación de entrada al tipo int representado por otro conjunto de parámetros de cuantificación, y los valores de punto flotante antes y después de la conversión son equivalentes. s1(q1-z1)=s2(q2-z2), el proceso de encontrar q2 a partir de otros parámetros conocidos.

herramientas cuantitativas

Cuantificación TensorRT

Cuantización fp16: config configura fp16 sin datos adicionales

config.set_flag(trt.BuilderFlag.FP16)
 

La cuantificación Int8 puede usar la poligrafía como auxiliar y requiere datos adicionales, pero no requiere una etiqueta como base para la evaluación de la precisión.

https://github.com/NVIDIA/TensorRT/tree/main/tools/Polygraphy

https://developer.download.nvidia.cn/compute/redist/polygraphy/polygraphy-0.33.2-py2.py3-none-any.whl

TensorRT admite el uso de números enteros de 8 bits para representar valores de punto flotante cuantificados. El
esquema de cuantificación es cuantificación uniforme simétrica : los valores cuantificados se representan
en INT8 con signo, y la transformación de valores cuantificados a valores no cuantificados es simplemente una
multiplicación. En la dirección inversa, la cuantificación utiliza la escala recíproca, seguida de
redondeo y sujeción.
Para habilitar el uso de cualquier operación cuantificada, el indicador INT8 debe establecerse en la
configuración del generador.
 

TensorRT solo admite la cuantificación por tensor para tensores de activación, pero admite la cuantificación de peso por canal para convolución, deconvolución, capas totalmente conectadas y MatMul,
donde la segunda entrada es constante y ambas matrices de entrada son bidimensionales.


En las redes cuantificadas explícitamente, las operaciones de escalado para transformar entre los
valores cuantificados y no cuantificados están representadas explícitamente por los
nodos IQuantizeLayer (C++, Python) e IDequantizeLayer (C++, Python) en el gráfico; en adelante, se denominarán
nodos Q/DQ.

Cuantificación posterior al entrenamiento mediante calibración

En la cuantificación posterior al entrenamiento, TensorRT calcula un valor de escala para cada tensor en la red.
Este proceso, llamado calibración, requiere que proporcione datos de entrada representativos en los que
TensorRT ejecuta la red para recopilar estadísticas para cada tensor de activación.
La cantidad de datos de entrada necesarios depende de la aplicación, pero los experimentos indican que
unas 500 imágenes son suficientes para calibrar las redes de clasificación de ImageNet.

TensorRT proporciona múltiples calibradores diferentes que calculan la escala de diferentes maneras.

IInt8EntropyCalibrator2
La calibración de entropía elige el factor de escala del tensor para optimizar el
contenido teórico de la información del tensor cuantificado y, por lo general, suprime los valores atípicos en la distribución. Este
es el calibrador de entropía actual y recomendado y se requiere para DLA. La calibración
ocurre antes de la fusión de capas por defecto. Se recomienda para redes basadas en CNN.
IInt8MinMaxCalibrator
Este calibrador utiliza todo el rango de la distribución de activación para determinar el
factor de escala. Parece funcionar mejor para tareas de PNL. La calibración ocurre antes de la fusión de capas por
defecto. Esto se recomienda para redes como NVIDIA BERT (una versión optimizada de la
implementación oficial de Google)
Soporte ONNX
Cuando un modelo entrenado en PyTorch o TensorFlow mediante Quantization Aware Training (QAT) se
exporta a ONNX, cada operación de cuantificación falsa en el gráfico del marco se exporta como un
par de operadores QuantizeLinear y DequantizeLinearONNX.
Cuando TensorRT importa modelos ONNX, el operador ONNX QuantizeLinear se importa como
una instancia de IQuantizeLayer y el operador ONNX DequantizeLinear se importa como una
instancia de IDequantizeLayer. ONNX que usa opset 10 introdujo soporte para QuantizeLinear/
DequantizeLinear, y se agregó un atributo de eje de cuantificación en opset 13 (requerido para la cuantificación por canal).
 

Control de precisión a nivel de capa
Las banderas del constructor proporcionan un control permisivo y de granularidad gruesa. Sin embargo, a veces parte
de una red requiere un rango dinámico más alto o es sensible a la precisión numérica. Puede
restringir los tipos de entrada y salida por capa:
C++
capa->setPrecision(DataType::kFP16)
Python
layer.precision = trt.fp16

Esta configuración de precisión de capa no parece ser fácil de usar. El modelo real fp16 tiene una precisión de cuantificación insuficiente. Configurar la precisión de capa de esta manera no resuelve el problema.
Sparsity
Las GPU NVIDIA Ampere Architecture son compatibles con Structured Sparsity. Para hacer uso de esta función
y lograr un mayor rendimiento de inferencia, los pesos del kernel de convolución y/o los pesos completamente conectados deben cumplir con los siguientes requisitos:

Varios esquemas que utilizan la cuantificación TensorRT

Solución 1. Utilice la cuantificación integrada de TensorRT directamente.

Solución 2. TensorRT 8 admite el modelo de cuantificación QDQ fake int 8. Este método se puede usar para la cuantificación del modelo y la cuantificación se puede transferir a TensorRT. Sin embargo, los modelos cuantificados manualmente compuestos por operadores como QLinearConv no se pueden transferir a TensorRT. Después de la cuantificación de QAT, también se puede guardar como modelo de este método de cuantificación. TensorRT fusiona automáticamente los operadores de cuantificación para la cuantificación int8.

El gráfico ONNX generado con las operaciones QuantizeLinear y DequantizeLinear se analiza mediante el analizador ONNX disponible en TensorRT. https://developer.download.nvidia.cn/video/gputechconf/gtc/2020/presentations/s21664-toward-int8-inference-deploying-quantization-aware-trained-networks-using-tensorrt.pdf

Herramientas de cuantificación de inteligencia artificial Intel®

GitHub - IntelAI/herramientas

https://github.com/intel/neural-compresor

https://github.com/IntelAI/tools/blob/master/tensorflow_quantization/quantization/quantize_graph.py

Cuantificación del modelo ONNX

https://github.com/onnx/onnx/blob/master/docs/Operators.md

https://github.com/microsoft/onnxruntime/tree/master/onnxruntime/python/tools/quantization proporciona herramientas de cuantificación modelo

Cuantifique modelos ONNX: onnxruntime  para obtener detalles de uso y  https://github.com/microsoft/onnxruntime-inference-examples/tree/main/quantization  para ver ejemplos.

Formato de representación de cuantificación ONNX

Hay 2 formas de representar modelos ONNX cuantificados:

  • Orientado al operador. Todos los operadores cuantificados tienen sus propias definiciones ONNX, como QLinearConv, MatMulInteger, etc.
  • Orientado al tensor, también conocido como Quantize y DeQuantize (QDQ). Este formato utiliza DQ(Q(tensor)) para simular el proceso de cuantificación y descuantificación, y los operadores QuantizeLinear y DeQuantizeLinear también transportan los parámetros de cuantificación. Los modelos generados como a continuación están en formato QDQ:
    • Modelos cuantificados por la API quantize_static a continuación con quant_format=QuantFormat.QDQ.
    • Modelos de entrenamiento Quantization-Aware (QAT) convertidos desde Tensorflow o exportados desde PyTorch.
    • Modelos cuantificados convertidos de tflite y otro marco.

Cuantificación de un modelo ONNX

API de cuantificación

La cuantificación tiene 3 API principales, que corresponden a los 3 métodos de cuantificación:

  • quantize_dynamic: cuantización dinámica
  • quantize_static: cuantificación estática
  • quantize_qat: cuantificación de entrenamiento consciente de la cuantificación

Consulte  quantize.py  para ver las opciones de cuantificación para cada método.

Consulte  E2E_example_model  para ver un ejemplo de cuantificación estática.

En general, se recomienda utilizar cuantificación dinámica para RNN y modelos basados ​​en transformadores, y cuantificación estática para modelos CNN.

Selección del tipo de datos

La cuantificación representa un valor con 8 bits, que puede ser int8 y uint8. Combinando con activación y peso, el formato de datos puede ser (activación:uint8, peso:uint8), (activación:uint8, peso:int8), etc.

Modelos basados ​​en transformadores

Hay optimización específica para modelos basados ​​en transformadores, como QAttention para la cuantificación de la capa de atención. Para aprovechar esas optimizaciones específicas, debe optimizar sus modelos con  la herramienta de optimización de modelos de transformadores  antes de cuantificar el modelo.

Este  cuaderno  demuestra el proceso E2E.

Cuantificación en GPU

Se requiere soporte de hardware para lograr un mejor rendimiento con la cuantificación en GPU. Necesita un dispositivo que admita el cálculo Tensor Core int8, como T4, A100. El hardware antiguo no se beneficiará.

ORT aprovecha TRT EP para la cuantificación en GPU ahora. A diferencia de CPU EP, TRT toma el modelo de precisión total y el resultado de calibración para las entradas. Decide cómo cuantizar con su propia lógica. El procedimiento general para aprovechar la cuantificación TRT EP es:

  • Implemente un  CalibrationDataReader .
  • Calcule el parámetro de cuantificación con el conjunto de datos de calibración. Nuestra herramienta de cuantificación admite 2 métodos de calibración: MinMax y Entropy. Nota: Para incluir todos los tensores del modelo para una mejor calibración, primero ejecute simbólico_shape_infer.py. Consulte aquí  para obtener más detalles.
  • Guarde el parámetro de cuantificación en un archivo de búfer plano
  • Cargue el modelo y el archivo de parámetros de cuantificación y ejecútelo con TRT EP.

Tenemos 2 ejemplos E2E  Yolo V3  y  resnet50  para su referencia.

caja de cuantización de cpu onnx resnet50 (bn doblada)

Pero el QLinearConv de onnxruntime parece que solo lo implementa la CPU, y la facilidad de uso no es muy buena.

Referencia de definición de operador

https://github.com/onnx/onnx/blob/main/docs/Operators.md

https://github.com/microsoft/onnxruntime/blob/master/docs/ContribOperators.md

AIMETHerramientas

https://github.com/quic/aimet

Introducción a la instalación de la herramienta AIMET (1)_weixin_38498942's blog-CSDN blog

Insuficiencias de las herramientas cuantitativas existentes

No hay retroalimentación de precisión para guiar la cuantificación: los usuarios pueden tener diferentes tolerancias de precisión, cómo guiar la cuantificación de acuerdo con la precisión, satisfacer la precisión y obtener el mejor rendimiento al mismo tiempo.

Versatilidad y facilidad de uso: el modelo cuantificado puede ser compatible con el marco de razonamiento original o convertirse a TensorRT, etc.

Otros artículos de referencia

https://github.com/Ewenwan/MVision/tree/master/CNN/Deep_Compression/quantization

Introducción a la Cuantización de Redes Neuronales--Cuantización-Conocimiento Posterior al Entrenamiento

Introducción a la cuantificación de redes neuronales - Entrenamiento de percepción de cuantificación

Introducción a la Cuantización de Redes Neuronales-Principios Básicos-Conocimientos

Cuantificación posterior al entrenamiento - Cuantificación libre de datos bzdww

Explicación detallada de la cuantificación de NCNN Conv (1) bzdww

Explicación detallada de la cuantificación NCNN (2) bzdww

https://github.com/google/gemmlowp

GitHub - quic/aimet: AIMET es una biblioteca que proporciona técnicas avanzadas de cuantificación y compresión para modelos de redes neuronales entrenados.

Cuantificación BERT

I-BERT: Cuantificación BERT de solo enteros

PPQ Small Classroom | Principios del Cálculo Cuantitativo (1)

Supongo que te gusta

Origin blog.csdn.net/u013701860/article/details/121627946
Recomendado
Clasificación