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.
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 Docker
los 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/soulteary
para soulteary
asignar el directorio debajo del directorio donde se ejecuta actualmente el comando al contenedor /app/soulteary
para 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_pretrained
el 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_type
La razón por la que se establece aquí nf4
es 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_dtype
razón por la que está configurado torch.bfloat16
es 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-llama
o , y luego usamos para ejecutar el programa para comenzar la cuantificación del modelo:LinkSoul
python 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.py
utilizada por los proyectos relevantes en los dos artículos anteriores model_id
y AutoModelForCausalLM.from_pretrained
agregar 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.
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