Use Transformers para cuantificar el modelo grande de Meta AI LLaMA2 versión china

Este artículo habla sobre cómo usar los transformadores de HuggingFace para cuantificar el modelo grande LLaMA2 producido por Meta AI, de modo que el modelo pueda ejecutarse con solo unos 5 GB de memoria de video.

escrito en frente

En los dos artículos anteriores " Uso de Docker para comenzar con el modelo oficial de código abierto LLaMA2 " y " Uso de Docker para comenzar con la versión china del modelo de código abierto LLaMA2 ", hablamos sobre cómo comenzar rápidamente y usar el modelo Meta AI LLaMA2 recientemente lanzado.

Después de las pruebas reales, ya sea el modelo original (inglés) o la versión china (bilingüe), necesitamos 13-14 GB de memoria de video para poder ejecutarlo.

Para permitir que más estudiantes jueguen con el modelo LLaMA2, intenté usar los Transformers de HuggingFace para cuantificar el modelo. El modelo cuantificado solo necesita alrededor de 5 GB de memoria de video para ejecutarse.

Proyecto de chat LLaMA2

He subido el código completo y el modelo a GitHub y HuggingFace , los estudiantes interesados ​​pueden recogerlo por sí mismos.

Preparación

Puede hacer referencia a todos los métodos de este artículo y usarlos en contenedores que no sean de Docker.

Para evitar problemas, puede consultar los dos primeros artículos y obtener rápidamente la versión original o china del entorno operativo del modelo LLaMA2 y la imagen de Docker. Si su entorno local está completo, ignore Dockerlos comandos relevantes y ejecute directamente varios comandos de programa específicos en Bash.

A continuación, utilizaremos la imagen del modelo chino LLaMA2 como ejemplo para cuantificar el modelo.

En el artículo anterior, usamos el siguiente comando para iniciar rápidamente una aplicación de modelo chino LLaMA2:

docker run --gpus all --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 --rm -it -v `pwd`/LinkSoul:/app/LinkSoul -p 7860:7860 soulteary/llama2:7b-cn bash

Debido a que es necesario guardar el modelo cuantizado, primero hacemos un ajuste simple al comando anterior y agregamos un parámetro:

docker run --gpus all --ipc=host --ulimit memlock=-1 --ulimit stack=67108864 --rm -it -v `pwd`/LinkSoul:/app/LinkSoul -v `pwd`/soulteary:/app/soulteary -p 7860:7860 soulteary/llama2:7b-cn bash

Aquí agregamos un parámetro adicional -v `pwd`/soulteary:/app/soultearypara soultearyasignar el directorio debajo del directorio donde se ejecuta actualmente el comando al contenedor /app/soultearypara guardar futuros archivos de modelo cuantificados.

Después de ejecutar el comando, estaremos en un entorno de línea de comandos interactivo dentro de un contenedor Docker completo.

Cuantización de LLaMA2 usando Transformadores

Aquí, solo usamos Transformers producidos por HuggingFace para completar todo el trabajo requerido sin introducir otros proyectos de código abierto.

La configuración central del modelo de cuantificación de Transformers

La función de cuantificación de Transformers se implementa llamando a bitsandbytes . Si desea llamar correctamente a esta biblioteca de funciones para la cuantificación, debe completar la configuración de parámetros en AutoModelForCausalLM.from_pretrainedel método .quantization_config

En el código fuente de utils/quantization_config.py#L37 de Transformers , podemos ver intuitivamente el modo de operación y la definición de parámetros de la función.La configuración de cuantificación 4BIT más simple es la siguiente:

model = AutoModelForCausalLM.from_pretrained(
	# 要载入的模型名称
    model_id,
	# 仅使用本地模型,不通过网络下载模型
    local_files_only=True,
	# 指定模型精度,保持和之前文章中的模型程序相同 `model.py`
    torch_dtype=torch.float16,
	# 量化配置
    quantization_config = BitsAndBytesConfig(
		# 量化数据类型设置
        bnb_4bit_quant_type="nf4",
		# 量化数据的数据格式
        bnb_4bit_compute_dtype=torch.bfloat16
    ),
	# 自动分配设备资源
    device_map='auto'
)

bnb_4bit_quant_typeLa razón por la que se establece aquí nf4es porque en la práctica de cuantificación del modelo a gran escala QLoRA de HuggingFace , el uso de nf4(NormalFloat) este nuevo tipo de datos puede ahorrar el consumo de memoria tanto como sea posible sin sacrificar el rendimiento.

La bnb_4bit_compute_dtyperazón por la que está configurado torch.bfloat16es debido a otra descripción de HuggingFace , podemos usar este nuevo formato de datos para reducir el "desperdicio de espacio" del FP32 tradicional y evitar el posible problema de desbordamiento de la conversión de FP32 a FP16.

Escribir un programa de cuantización modelo

En resumen, no es difícil escribir un programa simple de menos de 30 líneas para completar la cuantización del modelo LLaMA2 (subí el programa relacionado a soulteary/docker-llama2-chat/llama2-7b-cn-4bit/quantization_4bit.py ):

import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

# 使用中文版
model_id = 'LinkSoul/Chinese-Llama-2-7b'
# 或者,使用原版
# model_id = 'meta-llama/Llama-2-7b-chat-hf'

model = AutoModelForCausalLM.from_pretrained(
    model_id,
    local_files_only=True,
    torch_dtype=torch.float16,
    quantization_config = BitsAndBytesConfig(
        bnb_4bit_quant_type="nf4",
        bnb_4bit_compute_dtype=torch.bfloat16
    ),
    device_map='auto'
)

import os
output = "soulteary/Chinese-Llama-2-7b-4bit"
if not os.path.exists(output):
    os.mkdir(output)

model.save_pretrained(output)
print("done")

Realizar operaciones de cuantificación en el modelo.

Guardamos el contenido anterior como quantization_4bit.py, lo ubicamos en el directorio del mismo nivel que el directorio del modelo LLaMA2 meta-llamao , y luego usamos para ejecutar el programa para comenzar la cuantificación del modelo:LinkSoulpython quantization_4bit.py

# python quantization_4bit.py

Loading checkpoint shards: 100%|██████████████████████████████████████████████████████████████████| 3/3 [00:15<00:00,  5.01s/it]
done

Espere un momento y podrá encontrar el nuevo directorio de pares de modelos creado y guardado automáticamente en el directorio del programa actual soulteary/Chinese-Llama-2-7b-4bit/:

# du -hs soulteary/Chinese-Llama-2-7b-4bit/

13G	soulteary/Chinese-Llama-2-7b-4bit/

# ls -al soulteary/Chinese-Llama-2-7b-4bit/

total 13161144
drwxr-xr-x 2 root root       4096 Jul 21 18:12 .
drwxr-xr-x 3 root root       4096 Jul 21 18:11 ..
-rw-r--r-- 1 root root        629 Jul 21 18:11 config.json
-rw-r--r-- 1 root root        132 Jul 21 18:11 generation_config.json
-rw-r--r-- 1 root root 9976638098 Jul 21 18:12 pytorch_model-00001-of-00002.bin
-rw-r--r-- 1 root root 3500316839 Jul 21 18:12 pytorch_model-00002-of-00002.bin
-rw-r--r-- 1 root root      26788 Jul 21 18:12 pytorch_model.bin.index.json

Complete el archivo de ejecución del modelo

El cálculo de cuantificación del modelo ha terminado, pero el modelo en este momento no se puede usar porque faltan los archivos de programa relacionados con el tokenizador. Similar a la versión oficial de LLaMA2 y la versión china son todas compatibles, la versión cuantificada del modelo y el modelo antes de la cuantificación también son compatibles.

Resolver este problema es muy simple, solo necesitamos copiar los archivos en el modelo antes de la cuantificación al directorio del nuevo modelo:

cp LinkSoul/Chinese-Llama-2-7b/tokenizer.model soulteary/Chinese-Llama-2-7b-4bit/

cp LinkSoul/Chinese-Llama-2-7b/special_tokens_map.json soulteary/Chinese-Llama-2-7b-4bit/

cp LinkSoul/Chinese-Llama-2-7b/tokenizer_config.json soulteary/Chinese-Llama-2-7b-4bit/

Ajustar el programa modelo

Como se mencionó anteriormente, no hay diferencia en el uso entre el programa cuantificado y el programa original, por lo que la mayoría de los programas pueden seguir siendo los mismos. Sin embargo, debido a que es un archivo de modelo nuevo, todavía hay que hacer algunos ajustes simples.

Actualizar el corredor modelo

Como se mencionó anteriormente, no hay diferencia en el uso entre el programa cuantificado y el programa original, por lo que la mayoría de los programas pueden seguir siendo los mismos. Para que el modelo se cargue y se ejecute correctamente a través de 4BIT, debemos ajustar dos cosas:

Necesitamos ajustar la variable model.pyutilizada por los proyectos relevantes en los dos artículos anteriores model_idy AutoModelForCausalLM.from_pretrainedagregar a la llamada load_in_4bit=True:

model_id = 'soulteary/Chinese-Llama-2-7b-4bit'

if torch.cuda.is_available():
    model = AutoModelForCausalLM.from_pretrained(
        model_id,
        load_in_4bit=True,
        local_files_only=True,
        torch_dtype=torch.float16,
        device_map='auto'
    )
else:
    model = None
tokenizer = AutoTokenizer.from_pretrained(model_id)

El código completo de esta parte se puede encontrar en soulteary/docker-llama2-chat/llama2-7b-cn-4bit/model.py .

Ejecute la aplicación modelo

Subí la aplicación modelo a soulteary/docker-llama2-chat/llama2-7b-cn-4bit , porque no hay diferencia con los dos artículos anteriores, así que no la expandiré.

Si elige no ejecutar en el contenedor y usarlo directamente python app.py, el programa modelo se ejecutará rápidamente.

Crear una nueva imagen de contenedor

Para construir una imagen de 4BIT, ejecute el script como en el artículo anterior y espere a que se construya la imagen:

bash scripts/make-7b-cn-4bit.sh

Si ha seguido los dos primeros artículos antes, entonces esta operación debe completarse en 1 a 2 segundos.

Lanzar una aplicación modelo usando un contenedor

No hay diferencia entre usar el contenedor para iniciar la aplicación y el artículo anterior, simplemente ejecute el comando y llame al siguiente script:

bash scripts/run-7b-cn-4bit.sh

A la espera de que aparezca el registro Running on local URL: http://0.0.0.0:7860, podemos usar y probar normalmente.

El proyecto LLaMA2 chino cuantificado en ejecución

Uso de recursos de memoria

Los recursos de memoria de video siempre han sido la parte a la que todos prestan más atención. El inicio del modelo probablemente requiera recursos de memoria de video a principios de 5G.

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.125.06   Driver Version: 525.125.06   CUDA Version: 12.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  Off  | 00000000:01:00.0 Off |                  Off |
| 31%   61C    P2   366W / 450W |   5199MiB / 24564MiB |     99%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      1396      G   /usr/lib/xorg/Xorg                167MiB |
|    0   N/A  N/A      1572      G   /usr/bin/gnome-shell               16MiB |
|    0   N/A  N/A      8595      C   python                           5012MiB |
+-----------------------------------------------------------------------------+

Después de usarlo durante un período de tiempo, todavía está dentro de los 6 GB. ¿Se siente bien?

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.125.06   Driver Version: 525.125.06   CUDA Version: 12.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  Off  | 00000000:01:00.0 Off |                  Off |
| 32%   50C    P8    35W / 450W |   5725MiB / 24564MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      1402      G   /usr/lib/xorg/Xorg                167MiB |
|    0   N/A  N/A      1608      G   /usr/bin/gnome-shell               16MiB |
|    0   N/A  N/A     24950      C   python                           5538MiB |
+-----------------------------------------------------------------------------+

por fin

No todos los estudiantes tienen uno o varios 4090 o A100, por lo que incluso si la cuantización traerá alguna reducción del efecto, es mejor que no poder ejecutar el modelo o jugar juntos debido a una memoria de video insuficiente.

Además, incluso si el efecto disminuye, sigue siendo adecuado para su uso en muchos escenarios. En el siguiente artículo lo ampliaremos.

El arte de la ingeniería está en el "trade-off", escuché a un nuevo amigo mencionarlo por casualidad hace un tiempo, y tengo la sensación de despertar algo que ha estado escondido en mi corazón durante mucho tiempo.

–EOF


Este artículo utiliza el acuerdo de licencia "Signature 4.0 International (CC BY 4.0)". Le invitamos a reimprimirlo o reutilizarlo, pero debe indicar la fuente. Reconocimiento 4.0 Internacional (CC BY 4.0)

Autor de este artículo: Su Yang

Tiempo de creación: 22 de julio de 2023
Contar palabras: 8491 palabras
Tiempo de lectura: 17 minutos para leer
Enlace a este artículo: https://soulteary.com/2023/07/22/quantizing-meta-ai-llama2-chinese-version-large-models-using-transformers.html

Supongo que te gusta

Origin blog.csdn.net/soulteary/article/details/131865966
Recomendado
Clasificación