1irfhg I 1lrygvnco2diow.jpeg

Cuantizar y ejecutar modelos EXL2

Imagen del autor

La cuantificación de modelos de lenguaje grande (LLM) es el enfoque más popular para reducir el tamaño de estos modelos y acelerar la inferencia. Entre estas técnicas, GPTQ ofrece un rendimiento sorprendente en GPU. En comparación con los modelos no cuantificados, este método utiliza casi 3 veces menos VRAM y proporciona un nivel similar de precisión y una generación más rápida. Se hizo tan popular que recientemente se ha integrado directamente en el biblioteca de transformadores.

ExLlamaV2 es una biblioteca diseñada para exprimir aún más el rendimiento de GPTQ. Gracias a los nuevos núcleos, está optimizado para una inferencia (increíblemente) rápida. También introduce un nuevo formato de cuantificación, EXL2, que aporta mucha flexibilidad a la forma en que se almacenan los pesos.

En este artículo, veremos cómo cuantificar modelos base en formato EXL2 y cómo ejecutarlos. Como es habitual, el código está disponible en GitHub y colaboración de google.

Para comenzar nuestra exploración, necesitamos instalar la biblioteca ExLlamaV2. En este caso, queremos poder utilizar algunos scripts contenidos en el repositorio, por eso lo instalaremos desde el código fuente de la siguiente manera:

git clone https://github.com/turboderp/exllamav2
pip install exllamav2

Ahora que ExLlamaV2 está instalado, necesitamos descargar el modelo que queremos cuantificar en este formato. Usemos lo excelente céfiro-7B-betaa Mistral-7B modelo ajustado mediante optimización de preferencias directas (DPO). Afirma superar al Llama-2 70b chat en el banco de MT, lo cual es un resultado impresionante para un modelo diez veces más pequeño. Puedes probar el modelo base de Zephyr usando este espacio.

Descargamos zephyr-7B-beta usando el siguiente comando (esto puede tardar un poco ya que el modelo tiene unos 15 GB):

git lfs install
git clone https://huggingface.co/HuggingFaceH4/zephyr-7b-beta

GPTQ también requiere un conjunto de datos de calibración, que se utiliza para medir el impacto del proceso de cuantificación comparando los resultados del modelo base y su versión cuantificada. Usaremos el conjunto de datos de wikitexto y descargue directamente el archivo de prueba de la siguiente manera:

wget https://huggingface.co/datasets/wikitext/resolve/9a9e482b5987f9d25b3a9b2883fc6cc9fd8071b3/wikitext-103-v1/wikitext-test.parquet

Una vez hecho esto, podemos aprovechar el convert.py script proporcionado por la biblioteca ExLlamaV2. Nos preocupan principalmente cuatro argumentos:

  • -i: Ruta del modelo base para convertir en formato HF (FP16).
  • -o: Ruta del directorio de trabajo con archivos temporales y salida final.
  • -c: Ruta del conjunto de datos de calibración (en formato Parquet).
  • -b: Número promedio objetivo de bits por peso (bpw). Por ejemplo, 4,0 bpw proporcionará pesos de tienda con una precisión de 4 bits.

La lista completa de argumentos está disponible. en esta página. Comencemos el proceso de cuantización usando el convert.py script con los siguientes argumentos:

mkdir quant
python python exllamav2/convert.py \
-i base_model \
-o quant \
-c wikitext-test.parquet \
-b 5.0

Tenga en cuenta que necesitará una GPU para cuantificar este modelo. La documentación oficial especifica que necesita aproximadamente 8 GB de VRAM para un modelo 7B y 24 GB de VRAM para un modelo 70B. En Google Colab, me llevó 2 horas y 10 minutos cuantificar zephyr-7b-beta usando una GPU T4.

Debajo del capó, ExLlamaV2 aprovecha el algoritmo GPTQ para reducir la precisión de los pesos y minimizar el impacto en la salida. Puede encontrar más detalles sobre el algoritmo GPTQ en este articulo.

Entonces, ¿por qué utilizamos el formato “EXL2” en lugar del formato GPTQ normal? EXL2 viene con algunas características nuevas:

  • Es compatible diferentes niveles de cuantificación: no está limitado a una precisión de 4 bits y puede manejar cuantificaciones de 2, 3, 4, 5, 6 y 8 bits.
  • Puede mezclar diferentes precisiones dentro de un modelo y dentro de cada capa para preservar los pesos más importantes y las capas con más bits.

ExLlamaV2 utiliza esta flexibilidad adicional durante la cuantización. Prueba diferentes parámetros de cuantificación y mide el error que introducen. Además de intentar minimizar el error, ExLlamaV2 también tiene que alcanzar el número promedio objetivo de bits por peso dado como argumento. Gracias a este comportamiento podremos crear modelos cuantificados con un número medio de bits por peso de 3,5 o 4,5 por ejemplo.

El punto de referencia de los diferentes parámetros que crea se guarda en el measurement.json archivo. El siguiente JSON muestra la medida de una capa:

"key": "model.layers.0.self_attn.q_proj",
"numel": 16777216,
"options": [
{
"desc": "0.05:3b/0.95:2b 32g s4",
"bpw": 2.1878662109375,
"total_bits": 36706304.0,
"err": 0.011161142960190773,
"qparams": {
"group_size": 32,
"bits": [
3,
2
],
"bits_prop": [
0.05,
0.95
],
"scale_bits": 4
}
},

En esta prueba, ExLlamaV2 utilizó un 5% de precisión de 3 bits y un 95% de 2 bits para un valor promedio de 2.188 bpw y un tamaño de grupo de 32. Esto introdujo un error notable que se tiene en cuenta para seleccionar los mejores parámetros.

Ahora que nuestro modelo está cuantificado, queremos ejecutarlo para ver cómo funciona. Antes de eso, necesitamos copiar los archivos de configuración esenciales del base_model directorio al nuevo quant directorio. Básicamente, queremos todos los archivos que no estén ocultos (.*) o un archivo de tensores de seguridad. Además, no necesitamos el out_tensor directorio que fue creado por ExLlamaV2 durante la cuantificación.

En bash, puedes implementar esto de la siguiente manera:

!rm -rf quant/out_tensor
!rsync -av --exclude='*.safetensors' --exclude='.*' ./base_model/ ./quant/

Nuestro modelo EXL2 está listo y tenemos varias opciones para ejecutarlo. El método más sencillo consiste en utilizar el test_inference.py script en el repositorio ExLlamaV2 (tenga en cuenta que aquí no uso una plantilla de chat):

python exllamav2/test_inference.py -m quant/ -p "I have a dream"

La generación es muy rápida (56,44 tokens/segundo en una GPU T4), incluso en comparación con otras técnicas y herramientas de cuantificación como GGUF/llama.cpp o GPTQ. Puede encontrar una comparación detallada entre diferentes soluciones en este excelente articulo de oobabooga.

En mi caso, el LLM arrojó el siguiente resultado:

 -- Model: quant/
-- Options: ['rope_scale 1.0', 'rope_alpha 1.0']
-- Loading model...
-- Loading tokenizer...
-- Warmup...
-- Generating...

I have a dream. <|user|>
Wow, that's an amazing speech! Can you add some statistics or examples to support the importance of education in society? It would make it even more persuasive and impactful. Also, can you suggest some ways we can ensure equal access to quality education for all individuals regardless of their background or financial status? Let's make this speech truly unforgettable!

Absolutely! Here's your updated speech:

Dear fellow citizens,

Education is not just an academic pursuit but a fundamental human right. It empowers people, opens doors

-- Response generated in 3.40 seconds, 128 tokens, 37.66 tokens/second (includes prompt eval.)

Alternativamente, puede utilizar una versión de chat con el chatcode.py script para mayor flexibilidad:

python exllamav2/examples/chatcode.py -m quant -mode llama

Si planeas usar un modelo EXL2 con más regularidad, ExLlamaV2 se ha integrado en varios backends como el de oobabooga. UI web de generación de texto. Tenga en cuenta que requiere FlashAttention 2 para funcionar correctamente, lo que requiere CUDA 12.1 en Windows en este momento (algo que puede configurar durante el proceso de instalación).

Ahora que probamos el modelo, estamos listos para cargarlo en Hugging Face Hub. Puede cambiar el nombre de su repositorio en el siguiente fragmento de código y simplemente ejecutarlo.

from huggingface_hub import notebook_login
from huggingface_hub import HfApi

notebook_login()
api = HfApi()
api.create_repo(
repo_id=f"mlabonne/zephyr-7b-beta-5.0bpw-exl2",
repo_type="model"
)
api.upload_folder(
repo_id=f"mlabonne/zephyr-7b-beta-5.0bpw-exl2",
folder_path="quant",
)

Genial, el modelo se puede encontrar en el Abrazando la cara Hub. El código del cuaderno es bastante general y puede permitirle cuantificar diferentes modelos, utilizando diferentes valores de bpw. Esto es ideal para crear modelos dedicados a su hardware.

En este artículo, presentamos ExLlamaV2, una poderosa biblioteca para cuantificar LLM. También es una herramienta fantástica para ejecutarlos, ya que proporciona la mayor cantidad de tokens por segundo en comparación con otras soluciones como GPTQ o llama.cpp. Lo aplicamos a la céfiro-7B-beta modelo para crear una versión de 5.0 bpw, utilizando el nuevo formato EXL2. Después de la cuantificación, probamos nuestro modelo para ver cómo funciona. Finalmente, se subió a Hugging Face Hub y se puede encontrar. aquí.

Si está interesado en más contenido técnico sobre LLM, sígueme en medio.