Los modelos de lenguaje extenso (LLM) son conocidos por ser costosos de entrenar, ajustar y ejecutar. Se pensó que se necesitan modelos con cientos de miles de millones de parámetros entrenados con millones de dólares en computación para igualar las capacidades de GPT-3.5 y ChatGPT.
Sin embargo, los LLM de código abierto lanzados recientemente han demostrado que no necesita modelos muy grandes para competir con el estado del arte. Los investigadores han entrenado a los LLM con unos pocos miles de millones de parámetros para que funcionen a un nivel comparable al de modelos muy grandes. El éxito de los modelos de lenguaje grande de código abierto ha despertado interés y una actividad creciente en el campo.
Algunos de estos esfuerzos se centran en hacer que el ajuste de los LLM sea más rentable. Una de las técnicas que ayuda a reducir enormemente los costos de ajuste fino es la «adaptación de bajo rango» (LoRA). Con LoRA, puede ajustar los LLM a una fracción del costo que normalmente tomaría.
Esto es lo que necesita saber sobre LoRA.
¿Cómo funciona el ajuste fino de los LLM?
Los LLM de código abierto como LLaMA, Pythia y MPT-7B son modelos básicos que se han entrenado previamente en cientos de miles de millones de palabras. Los desarrolladores y los ingenieros de aprendizaje automático pueden descargar el modelo con los pesos previamente entrenados y ajustarlo para tareas posteriores, como el seguimiento de instrucciones.
Cada LLM es un modelo de transformador que se compone de varios bloques de capas, cada uno de los cuales contiene parámetros que se pueden aprender. El ajuste fino continúa donde lo dejó el entrenamiento previo.
El modelo recibe información del conjunto de datos de ajuste fino. Luego predice los siguientes tokens y compara su salida con la verdad del terreno. Luego ajusta los pesos para corregir sus predicciones. Al hacer esto una y otra vez, el LLM se ajusta a la tarea posterior.
Ahora, hagamos una pequeña modificación en el proceso de ajuste fino. En este nuevo método, congelamos los pesos originales del modelo y no los modificamos durante el proceso de ajuste. En su lugar, aplicamos las modificaciones a un conjunto separado de pesos y agregamos sus nuevos valores a los parámetros originales. Llamemos a estos dos conjuntos de pesos «pre-entrenados» y «afinados».
Separar los parámetros preentrenados y ajustados es una parte importante de LoRA.
Adaptación de bajo rango
Antes de pasar a LoRA, pensemos en los parámetros de nuestro modelo como matrices muy grandes. Si recuerda su clase de álgebra lineal, las matrices pueden formar espacios vectoriales. En este caso, estamos hablando de un espacio vectorial muy grande con muchas dimensiones que modela el lenguaje.
Cada matriz tiene un «rango», que es el número de columnas linealmente independientes que tiene. Si una columna es linealmente independiente, significa que no se puede representar como una combinación de otras columnas en la matriz. Por otro lado, una columna dependiente es aquella que se puede representar como una combinación de una o más columnas en una misma matriz. Puede eliminar columnas dependientes de una matriz sin perder información.
LoRA, propuesto en un artículo de investigadores de Microsoft, sugiere que al ajustar un LLM para una tarea posterior, no necesita la matriz de ponderación de rango completo. Propusieron que se podría conservar la mayor parte de la capacidad de aprendizaje del modelo mientras se reduce la dimensión de los parámetros posteriores. (Es por eso que tiene sentido separar los pesos pre-entrenados y ajustados).
Básicamente, en LoRA, creas dos matrices de peso aguas abajo. Uno transforma los parámetros de entrada de la dimensión original a la dimensión de rango bajo. Y la segunda matriz transforma los datos de rango bajo en las dimensiones de salida del modelo original.
Durante el entrenamiento se realizan modificaciones en los parámetros LoRA, que ahora son mucho menores que los pesos originales. Esta es la razón por la que se pueden entrenar mucho más rápido y a una fracción del costo de hacer un ajuste completo. En el momento de la inferencia, la salida de LoRA se agrega a los parámetros previamente entrenados para calcular los valores finales.
Mejoras adicionales con LoRA
Dado que LoRA requiere que mantengamos los pesos previamente entrenados y ajustados por separado, incurrimos en una sobrecarga de memoria. Además, la operación de agregar los pesos previamente entrenados y ajustados en el momento de la inferencia provoca una pequeña penalización de cálculo. Para superar esta penalización, puede fusionar los pesos ajustados y preentrenados después de ajustar su LLM con LoRA.
Sin embargo, dado que los pesos descendentes solo ocupan una fracción de los pesos originales (a veces hasta una milésima), es posible que desee mantenerlos separados. Hay beneficios al separar los pesos pre-entrenados y los posteriores.
Por ejemplo, supongamos que está alojando un LLM que varios clientes usan para diferentes aplicaciones. Cada cliente quiere ajustar el modelo con sus propios conjuntos de datos específicos y para sus propias aplicaciones. En lugar de crear una versión ajustada por separado del modelo para cada cliente, puede usar LoRA para crear un conjunto de pesos descendentes para cada cliente o aplicación. En el momento de la inferencia, carga el modelo base y los pesos de LoRA de cada cliente para realizar el cálculo final. Tendrá un ligero impacto en el rendimiento, pero las ganancias en almacenamiento serán inmensas.
Implementando LoRA en Python
Esta publicación fue una descripción general muy amplia de cómo funciona LoRA. Tiene más detalles técnicos y matices, como a qué tipos de pesos se aplica y los hiperparámetros que tiene. Sebastian Raschka tiene una publicación extensa en la que brinda detalles técnicos y de implementación de LoRA.
Chris Alexiuk también tiene una serie de videos detallados de dos partes sobre LoRA. El primero profundiza en la teoría y el segundo es una implementación práctica con Python y Google Colab.
LoRA es una de varias técnicas que pueden ayudar a reducir los costos de capacitación de LLM de código abierto. El campo se está moviendo muy rápido. Será interesante ver cómo se desarrolla el campo.