Fine-Tuning de Llama-3 para Obtener el 90% del Rendimiento de GPT-4 a una Fracción del Costo

El éxito de Llama-3 ha sido increíble, demostrando que los modelos de código abierto están alcanzando rápidamente a los modelos cerrados sin comprometer la propiedad privada. Nuestros clientes han estado utilizando sus propios datos propietarios para ajustar modelos OSS pequeños como Llama-3 y ejecutar sus tareas con mayor precisión que incluso los principales modelos de código cerrado. Su modelo ajustado es pequeño, preciso y totalmente propio y controlado por ellos.

Aprovechando la Plataforma de Together AI

Descubre cómo aprovechar la plataforma de Together AI para ajustar Llama-3-8B con tus datos propietarios, creando un modelo personalizado que supera a las alternativas OSS líderes como Llama-3-70B y es comparable a las alternativas cerradas líderes como GPT-4 a una fracción del costo. Esta guía paso a paso demuestra cómo un modelo Llama-3 8B ajustado pasó del 47% de precisión en el modelo base al 65% de precisión, superando incluso a Llama-3-70B (64%) y acercándose a GPT-4o (71%). Aprende cómo puedes crear soluciones de IA más rápidas, precisas y totalmente propias para tus casos de uso específicos, todo mientras reduces costos significativamente en comparación con el uso de GPT-4.

Transformación del Conjunto de Datos

Lo primero que haremos es descargar el conjunto de datos Math Instruct. Navega a MathInstruct en HuggingFace y haz clic en descargar junto a MathInstruct.json. Después de esto, ejecutaremos un script rápido de limpieza para eliminar duplicados, eliminar 1,000 problemas para guardarlos para evaluaciones y renombrar el archivo final a MathInstruct-207k.json. Si quieres seguir, puedes clonar el repositorio de GitHub y usar el archivo TrainMathInstruct-500.json para ajustar un conjunto de datos más pequeño.

A continuación, necesitamos transformar este conjunto de datos en un archivo .jsonl, ya que ese es el formato de archivo que admite Together. Podemos usar algo de código Python y el formato de instrucción de Llama-3 para hacer esto:

import json

dataset = "MathInstruct-207k"
old_file_path = f"{dataset}.json"
new_file_path = f"Formatted{dataset}.jsonl"

with open(old_file_path, "r", encoding="utf-8") as old_file:
old_data = json.load(old_file)

llama_format = """
system
{system_prompt}user
{user_question}assistant
{model_answer}
"""
formatted_data = []
system_prompt = "You're a helpful assistant that answers math problems."

with open(new_file_path, "w", encoding="utf-8") as new_file:
for piece in old_data:
temp_data = {
"text": llama_format.format(
system_prompt=system_prompt,
user_question=piece["instruction"],
model_answer=piece["output"],
)
}
new_file.write(json.dumps(temp_data))
new_file.write("\n")

Luego, podemos usar la función check_file del SDK de Together para verificar que nuestro conjunto de datos sea válido y esté en el formato correcto:

from together.utils import check_file

report = check_file(new_file_path)
print(report)
assert report["is_check_passed"] == True

Si la afirmación pasa, ¡estás listo para subir tu conjunto de datos a Together AI!

Subida y Verificación de tu Conjunto de Datos

Ahora que tenemos un conjunto de datos válido, lo subiremos a Together AI a través del SDK de Python. Asegúrate de pip install together, guarda tu clave API como una variable de entorno llamada TOGETHER_API_KEY, luego ejecuta el siguiente código para subirlo y verificar que se haya subido correctamente.

También puedes subir un conjunto de datos a través de nuestra CLI.

import os
from together import Together

client = Together(api_key=os.environ.get("TOGETHER_API_KEY"))
dataset = "MathInstruct-207k"

response = client.files.upload(file=f"Formatted{dataset}.jsonl")
fileId = response.model_dump()["id"]

file_metadata = client.files.retrieve(fileId)
print(file_metadata)

Inicio de un Trabajo de Fine-Tuning

Ahora estamos listos para ajustar un modelo usando nuestro conjunto de datos subido. Crearemos un trabajo de fine-tuning usando Llama-3-8B como nuestro modelo base, especificaremos nuestro conjunto de datos como el training_file, usaremos 5 épocas y, opcionalmente, agregaremos una clave API de Weights and Biases si queremos monitorear el trabajo de fine-tuning con gráficos como una curva de pérdida.

import os
from together import Together

client = Together(api_key=os.environ.get("TOGETHER_API_KEY"))
dataset = "MathInstruct-207k"

resp = client.fine_tuning.create(
suffix="mathinstruct-207k-v2",
model="meta-llama/Meta-Llama-3-8B-Instruct",
training_file=fileId,
n_epochs=5,
batch_size=8,
learning_rate=1e-5,
wandb_api_key=os.environ.get("WANDB_API_KEY"),
)

Después de ejecutar este código, tu trabajo de fine-tuning se iniciará. Podrás verlo en tu panel de trabajos de Together AI.

Ejecución de tu Modelo Ajustado

Cuando tu trabajo de fine-tuning haya terminado (este conjunto de datos tarda entre ~2 y 14 horas dependiendo del número de épocas), podrás verlo y lanzarlo desde tu panel en Together AI.

Navega a la página de Modelos, haz clic en tu modelo ajustado y haz clic en Deploy para crear un endpoint con una de las configuraciones de hardware disponibles. Para este tutorial, desplegaremos en 1 A100-80GB. (Si no te importa la menor latencia, también puedes desplegar en hardware más barato como L40s o RTX-6000s).

Después de que tu endpoint se inicie, puedes probarlo en el playground de Together AI haciendo clic en el botón verde Play, o puedes llamarlo directamente desde tu código usando nuestra API. Lo llamaremos a través de nuestra API en la siguiente sección para evaluarlo completamente.

Evaluaciones para Ver Resultados

Ahora que tenemos nuestro modelo ajustado, queremos ver si funciona mejor que el modelo base (y otros modelos disponibles). Usaremos un LLM para juzgar los resultados (también conocido como LLM-as-a-judge) ya que es directo, pero hay formas más sofisticadas y deterministas que también puedes usar para evaluar tu modelo.

Para hacer esto, tomaremos 1000 problemas matemáticos que el LLM nunca ha visto antes y los pasaremos tanto por el modelo base Llama-3-8B como por nuestro Llama-3-8B ajustado, y evaluaremos la precisión de cada uno. También los pasaremos por LLama-3-70B y GPT-4o para ver la precisión de los principales modelos OSS y propietarios para ponerlo en perspectiva.

import json
from together import AsyncTogether
import os
import asyncio

async_together_client = AsyncTogether(api_key=os.environ.get("TOGETHER_API_KEY"))

base_model = "meta-llama/Llama-3-8b-chat-hf"
top_oss_model = "meta-llama/Llama-3-70b-chat-hf"
finetuned_model = "FINETUNED_MODEL_ID"
evaluator_model = "meta-llama/Llama-3-70b-chat-hf"
eval_dataset = "EvalDataset-1000.json"

async def chatCompletion(model, instruction):
completion = await async_together_client.chat.completions.create(
messages=[
{"role": "user", "content": instruction},
],
model=model,
max_tokens=1500,
)
return completion.choices[0].message.content

async def main():

with open(eval_dataset, "r", encoding="utf-8") as eval_file:
eval_data = json.load(eval_file)

results = []

for example in eval_data:
(
baseModelCompletion,
topOSSModelCompletion,
finetunedModelCompletion,
) = await asyncio.gather(
chatCompletion(base_model, example["instruction"]),
chatCompletion(top_oss_model, example["instruction"]),
chatCompletion(finetuned_model, example["instruction"]),
)
results.append(
{
"groundTruthAnswer": example["output"],
"baseModelAnswer": baseModelCompletion,
"topOSSModelAnswer": topOSSModelCompletion,
"fineTunedModelAnswer": finetunedModelCompletion,
}
)

with open("results.json", "w", encoding="utf-8") as results_file:
json.dump(results, results_file, indent=4)

Resultados

Evaluamos un conjunto de datos de 1000 problemas matemáticos en el modelo base, nuestro modelo ajustado y los principales modelos grandes como Llama-3-70B y GPT-4o. Aquí están los resultados en términos de precisión:

ModeloPrecisión (%)
Modelo base (Llama-3-8B)47.2%
Modelo ajustado (Llama-3-8B)65.2%
Principal modelo OSS (Llama-3-70B)64.2%
Principal modelo propietario (GPT-4o)71.4%

Nuestro pequeño modelo ajustado de 8B superó al modelo base en casi un 20%, venció al principal modelo OSS (Llama-3-70B) y alcanzó más del 90% de la precisión de GPT-4o. Además, es mucho más rápido, 50 veces más económico que GPT-4o y ofrece al usuario final la propiedad total del modelo y sus pesos (puedes descargar y ejecutar el modelo tú mismo).

No solo es nuestro modelo ajustado más preciso, sino que sus respuestas son más concisas y organizadas, lo que se traduce en menores costos y tiempos de respuesta más rápidos al ejecutar tareas.

Comparando Respuestas de los Modelos Base y Ajustado

Para la siguiente pregunta (donde C es la respuesta correcta), observa la diferencia en las respuestas del modelo base y el modelo ajustado.

Pregunta: Una suma de dinero se va a distribuir entre A, B, C y D en la proporción de 5:2:4:3. Si C recibe Rs. 1000 más que D, ¿cuál es la parte de B?

Opciones de respuesta: (A) 1000 (B) 3000 (C) 2000 (D) 4000 (E) 5000

El modelo base dio una respuesta incorrecta y usó 311 tokens, mientras que el modelo ajustado respondió correctamente utilizando solo 100 tokens.

Conclusión

Nuestro tutorial demuestra que ajustar modelos pequeños de código abierto como Llama-3-8B puede resultar en un modelo personalizado que es más pequeño, rápido, económico y preciso para realizar tareas específicas. Además, no tuvimos que comprometer la flexibilidad o la propiedad, lo que significa que podemos usar nuestros propios datos propietarios para ajustar un modelo, y luego usar Together para alojarlo, o descargarlo y ejecutarlo nosotros mismos.

El modelo Llama-3-8B que entrenamos en problemas matemáticos en esta publicación de blog superó a los modelos OSS líderes y se acercó al rendimiento de GPT-4o, costando menos de $100 en total para ajustarlo en Together AI. Para obtener más información, consulta nuestras guías sobre el Fine-tuning en Together AI, o ponte en contacto con nosotros para hacernos cualquier pregunta.

vía: Together.ai y Finetuning GitHub.

Scroll al inicio