PNL (68) utiliza Optimum para la cuantificación de modelos

  Este artículo presentará cómo utilizar HuggingFace Optimumpara cuantificar el modelo BERT ajustado.
  En el artículo NLP (67) Cuantización dinámica posterior al entrenamiento del modelo BERT (PTDQ) , utilizamos la estrategia de cuantificación PTDQ (Cuantización dinámica posterior al entrenamiento) que viene con PyTorch para cuantificar el modelo BERT ajustado y logramos una mejora en el razonamiento del modelo. rendimiento (aproximadamente 1,5 veces). Este artículo intentará utilizar Optimumherramientas cuantitativas.

Introducción a Optimum

  Optimumes Transformersuna extensión de , que proporciona un conjunto de herramientas de optimización del rendimiento para entrenar y ejecutar modelos con la máxima eficiencia en el hardware de destino.
  OptimumSe proporcionan diferentes soluciones de optimización para diferentes hardware, como se muestra en la siguiente tabla:

hardware Comando de instalación
Tiempo de ejecución de ONNX python -m pip instalación óptima[onnxruntime]
Compresor neuronal Intel (INC) python -m pip instalar óptimo[compresor-neural]
Intel OpenVINO python -m pip instalar óptimo[openvino,nncf]
UIP Graphcore python -m pip instalación óptima[graphcore]
Procesador Habana Gaudí (HPU) python -m pip instalar óptimo[habana]
GPU python -m pip instalación óptima[onnxruntime-gpu]

  Este artículo presentará la tecnología de cuantificación de modelos basada en ONNX. ONNX (inglés: Open Neural Network Exchange) es un formato de archivo abierto diseñado para que el aprendizaje automático almacene modelos entrenados. Permite que diferentes marcos de inteligencia artificial (como Pytorch, MXNet) almacenen datos del modelo e interactúen en el mismo formato.

Cuantificación del modelo

  El modelo BERT ajustado que utilizamos utiliza el modelo de clasificación de texto proporcionado en el artículo NLP (66) en HuggingFace para el ajuste fino del modelo BERT .
  Primero, primero cargamos el dispositivo (CPU) en PyTorch.

# load device
import torch

device = torch.device("cpu")

  A continuación, usamos optimum.onnxruntimeel módulo para cargar el modelo y el tokenizador, y guardamos el modelo en formato onnx.

from optimum.onnxruntime import ORTModelForSequenceClassification
from transformers import AutoTokenizer
import torch

model_id = "./sougou_test_trainer_256/checkpoint-96"
onnx_path = "./sougou_test_trainer_256/onnx_256"

# load vanilla transformers and convert to onnx
model = ORTModelForSequenceClassification.from_pretrained(model_id, from_transformers=True)
tokenizer = AutoTokenizer.from_pretrained(model_id)

# save onnx checkpoint and tokenizer
model.save_pretrained(onnx_path)
tokenizer.save_pretrained(onnx_path)

En este momento, habrá una carpeta onnx_256 adicional y el modelo se guardará como model.onnx.
Guardar como modelo onnx
La salida es:

('./sougou_test_trainer_256/onnx_256\\tokenizer_config.json',
 './sougou_test_trainer_256/onnx_256\\special_tokens_map.json',
 './sougou_test_trainer_256/onnx_256\\vocab.txt',
 './sougou_test_trainer_256/onnx_256\\added_tokens.json',
 './sougou_test_trainer_256/onnx_256\\tokenizer.json')

  Utilice transfomersla canalización en curso para inferir rápidamente el modelo.

from transformers import pipeline

vanilla_clf = pipeline("text-classification", model=model, tokenizer=tokenizer)
vanilla_clf("这期节目继续关注中国篮球的话题。众所周知,我们已经结束了男篮世界杯的所有赛程,一胜四负的一个成绩,甚至比上一届的世界杯成绩还要差。因为这一次我们连奥运会落选赛也都没有资格参加,所以,连续两次错过了巴黎奥运会的话,对于中国篮协,还有对于姚明来说,确实成为了他任职的一个最大的败笔。对于球迷非常关注的一个话题,乔尔杰维奇是否下课,可能对于这个悬念来说也都是暂时有答案了。")

El resultado es el siguiente:

[{'label': 'LABEL_0', 'score': 0.9963239431381226}]

  Optimice el modelo ONNX.

from optimum.onnxruntime import ORTOptimizer
from optimum.onnxruntime.configuration import OptimizationConfig

# create ORTOptimizer and define optimization configuration
optimizer = ORTOptimizer.from_pretrained(model)
optimization_config = OptimizationConfig(optimization_level=99) # enable all optimizations

# apply the optimization configuration to the model
optimizer.optimize(
    save_dir=onnx_path,
    optimization_config=optimization_config,
)

En este momento, el modelo optimizado es model_optimized.onnx.

  Realizar inferencias sobre el modelo optimizado.

from transformers import pipeline

# load optimized model
optimized_model = ORTModelForSequenceClassification.from_pretrained(onnx_path, file_name="model_optimized.onnx")

# create optimized pipeline
optimized_clf = pipeline("text-classification", model=optimized_model, tokenizer=tokenizer)
optimized_clf("今年7月,教育部等四部门联合印发了《关于在深化非学科类校外培训治理中加强艺考培训规范管理的通知》(以下简称《通知》)。《通知》针对近年来校外艺术培训的状况而发布,并从源头就校外艺术培训机构的“培训主体、从业人员、招生行为、安全底线”等方面进行严格规范。校外艺术培训之所以火热,主要在于高中阶段艺术教育发展迟滞于学生需求。分析教育部数据,2021年艺术学科在校生占比为9.84%,高于2020年的9.73%;2020至2021年艺术学科在校生的年增长率为5.04%,远高于4.28%的总在校生年增长率。增长的数据,是近年来艺考招生连年火热的缩影,在未来一段时间内,艺考或将在全国范围内继续保持高热度。")

La salida es:

[{'label': 'LABEL_3', 'score': 0.9926980137825012}]

  Cuantifique nuevamente el modelo ONNX optimizado, el código es:

from optimum.onnxruntime import ORTQuantizer
from optimum.onnxruntime.configuration import AutoQuantizationConfig

# create ORTQuantizer and define quantization configuration
dynamic_quantizer = ORTQuantizer.from_pretrained(optimized_model)
dqconfig = AutoQuantizationConfig.avx2(is_static=False, per_channel=False)

# apply the quantization configuration to the model
model_quantized_path = dynamic_quantizer.quantize(
    save_dir=onnx_path,
    quantization_config=dqconfig,
)

En este momento, el modelo cuantificado es model_optimized_quantized.onnx. Para comparar el tamaño del modelo antes y después de la cuantificación, el código es:

import os

# get model file size
size = os.path.getsize(os.path.join(onnx_path, "model_optimized.onnx"))/(1024*1024)
quantized_model = os.path.getsize(os.path.join(onnx_path, "model_optimized_quantized.onnx"))/(1024*1024)

print(f"Model file size: {
      
      size:.2f} MB")
print(f"Quantized Model file size: {
      
      quantized_model:.2f} MB")

La salida es:

Model file size: 390.17 MB
Quantized Model file size: 97.98 MB

  Finalmente cargue el modelo cuantificado, el código es:

# load quantization model
from optimum.onnxruntime import ORTModelForSequenceClassification
from transformers import pipeline, AutoTokenizer

quantized_model = ORTModelForSequenceClassification.from_pretrained(onnx_path, file_name="model_optimized_quantized.onnx").to(device)
tokenizer = AutoTokenizer.from_pretrained(onnx_path)

experimento de razonamiento

  Antes de realizar experimentos de inferencia de modelos, primero cargue el conjunto de datos de prueba.

import pandas as pd

test_df = pd.read_csv("./data/sougou/test.csv")

  Utilice el modelo antes de la cuantificación para la inferencia y registre el tiempo de inferencia. El código es el siguiente:

# original model evaluate
import numpy as np
import time

cost_time_list = []
s_time = time.time()
true_labels, pred_labels = [], [] 
for i, row in test_df.iterrows():
    row_s_time = time.time()
    true_labels.append(row["label"])
    encoded_text = tokenizer(row['text'], max_length=256, truncation=True, padding=True, return_tensors='pt')
    # print(encoded_text)
    logits = model(**encoded_text)
    label_id = np.argmax(logits[0].detach().numpy(), axis=1)[0]
    pred_labels.append(label_id)
    cost_time_list.append((time.time() - row_s_time) * 1000)
    if i % 100:
    	print(i, (time.time() - row_s_time) * 1000, label_id)

print("avg time:", (time.time() - s_time) * 1000 / test_df.shape[0])
print("P50 time:", np.percentile(np.array(cost_time_list), 50))
print("P95 time:", np.percentile(np.array(cost_time_list), 95))

La salida es:

0 710.2577686309814 0
100 477.72765159606934 1
200 616.3530349731445 2
300 509.63783264160156 3
400 531.57639503479 4

avg time: 501.0757282526806
P50 time: 504.6522617340088
P95 time: 623.9353895187337

Para realizar la calificación del indicador en los resultados de salida, el código es:

from sklearn.metrics import classification_report

print(classification_report(true_labels, pred_labels, digits=4))

  Repita el código anterior, reemplace el modelo con el modelo ONNX antes de la cuantificación (model.onnx), el modelo ONNX después de la optimización (model_oprimized.onnx), el modelo ONNX después de la cuantificación (model_optimized_quantized.onnx) y realice la inferencia del tiempo (unidad: ms ) Evaluación de indicadores de estadística e inferencia, los resultados se muestran en la siguiente tabla:

Modelo tiempo promedio de inferencia P95 Tiempo de razonamiento ponderado F1
Modelo ONNX antes de la cuantificación 501.1 623,9 0.9717
Modelo ONNX optimizado 484,6 629,6 0.9717
Modelo ONNX cuantificado 361,5 426,9 0.9738

  En comparación con los resultados de inferencia en la cuantificación dinámica posterior al entrenamiento (PTDQ) del modelo BERT en el artículo NLP (67) , el tiempo de inferencia promedio del modelo original es 666,6 ms y el valor F1 ponderado es 0,9717. siguientes conclusiones:

  • El modelo ONNX no afecta el efecto de razonamiento, pero el tiempo promedio de razonamiento es aproximadamente 1,33 veces más rápido.
  • La optimización del modelo ONNX no afecta el efecto de inferencia, pero el tiempo de inferencia promedio es aproximadamente 1,38 veces más rápido.
  • El modelo ONNX cuantificado afecta el efecto de inferencia, que generalmente disminuye ligeramente. El resultado de este experimento es una mejora, pero el tiempo de inferencia promedio aumenta aproximadamente 1,84 veces, debido al PTDQ (cuantización dinámica después del entrenamiento del modelo) de PyTorch.

Resumir

  Este artículo presenta cómo utilizar HuggingFace Optimumpara cuantificar el modelo BERT ajustado. En optimum.onnxruntimeel módulo, el tiempo de inferencia promedio se acelera aproximadamente 1,8 veces.
  Este artículo se ha abierto en Github en: https://github.com/percent4/dynamic_quantization_on_bert .
  Este artículo ha abierto un blog personal, bienvenido a visitar: https: //percent4.github.io/ .

  Bienvenido a seguir mi viaje de fantasía oficial de PNL , y los artículos técnicos originales se publicarán lo antes posible.

  Bienvenido a seguir mi planeta del conocimiento " El viaje de fantasía del procesamiento del lenguaje natural " El autor está trabajando arduamente para construir su propia comunidad técnica.

### referencias
  1. PNL (sesenta y seis) utiliza el Entrenador en HuggingFace para ajustar el modelo BERT: https://blog.csdn.net/jclian91/article/details/132644042
  2. Cuantización dinámica posterior al entrenamiento (PTDQ) del modelo BERT de PNL (sesenta y siete): https://blog.csdn.net/jclian91/article/details/132644042
  3. Óptimo: https://huggingface.co/docs/optimum/index
  4. Optimización de transformadores con Hugging Face Optimum: https://www.philschmid.de/optimizing-transformers-with-optimum

Supongo que te gusta

Origin blog.csdn.net/jclian91/article/details/132725144
Recomendado
Clasificación