curso
RAG vs Ajuste fino: Un tutorial completo con ejemplos prácticos
La mayoría de los Grandes Modelos Lingüísticos (LLM), como el GPT-4, se entrenan en conjuntos de datos generalizados, a menudo obsoletos. Aunque son excelentes respondiendo a preguntas generales, tienen problemas con las preguntas sobre noticias recientes, últimos acontecimientos y temas específicos del dominio. En tales casos, pueden alucinar o dar respuestas inexactas.
A pesar de la aparición de modelos de mejor rendimiento, como el Soneto Claude 3.5, seguimos necesitando o bien el ajuste fino del modelo para generar respuestas personalizadas, o bien el uso de sistemas de Generación Mejorada por Recuperación (RAG) para proporcionar un contexto adicional al modelo base.
En este tutorial, exploraremos la RAG y el ajuste fino, dos técnicas distintas utilizadas para mejorar las respuestas LLM. Examinaremos sus diferencias y pondremos en práctica la teoría evaluando los resultados.
Además, nos sumergiremos en técnicas híbridas que combinan modelos afinados con sistemas RAG para aprovechar lo mejor de ambos mundos. Por último, aprenderemos a elegir entre estos tres enfoques en función de casos de uso y requisitos específicos.
Visión general de los GAR y el ajuste fino
Las técnicas RAG y de ajuste fino mejoran la generación de respuestas para las consultas específicas del dominio, pero son técnicas inherentemente completamente distintas. Aprendamos sobre ellos.
Generación Mejorada por Recuperación (RAG)
La Generación Mejorada por Recuperación es un proceso en el que grandes modelos lingüísticos como el GPT-4o se vuelven conscientes del contexto utilizando fuentes de datos externas. Es una combinación de recuperador y generador. El recuperador obtiene datos de Internet o de una base de datos vectorial y los proporciona al generador con la consulta original del usuario. El generador utiliza el contexto adicional para generar una respuesta muy precisa y pertinente.
Para saber más, lee nuestro artículo, ¿Qué es la Generación Aumentada de Recuperación (RAG)? Guía básica y comprender el funcionamiento interno de la aplicación RAG y los distintos casos de uso .
Ajuste fino
El ajuste fino es el proceso de afinar el modelo preentrenado utilizando el conjunto de datos específico del dominio. El modelo preentrenado se entrena en múltiples cadáveres grandes de conjuntos de datos generales desechados de Internet. Son buenos respondiendo a preguntas generales, pero tendrán dificultades o incluso alucinarán al responder a preguntas específicas de un dominio.
Por ejemplo, un modelo preentrenado podría ser competente en habilidades conversacionales generales, pero podría dar respuestas erróneas cuando se le preguntara sobre intrincados procedimientos médicos o precedentes legales.
Afinarlo en un conjunto de datos médicos o jurídicos permite al modelo comprender y responder a preguntas dentro de esos campos con mayor precisión y pertinencia.
Sigue la Guía introductoria al ajuste fino de los LLM para aprender a personalizar el modelo preentrenado con guías visuales.
RAG vs. Ajuste fino
Hemos aprendido sobre cada metodología para mejorar la generación de respuestas de los LLM. Examinemos las diferencias para comprenderlas mejor.
1. Estilo de aprendizaje
RAG utiliza un estilo de aprendizaje dinámico, que permite a los modelos lingüísticos acceder y utilizar los datos más recientes y precisos de las bases de datos, Internet o incluso las API. Este enfoque garantiza que las respuestas generadas estén siempre actualizadas y sean pertinentes.
El ajuste implica un aprendizaje estático, en el que el modelo aprende a través de un nuevo conjunto de datos durante la fase de entrenamiento. Aunque este método permite que el modelo se adapte a la generación de respuestas específicas del dominio, no puede integrar nueva información después del entrenamiento sin volver a entrenar.
2. Adaptabilidad
RAG es mejor para las generalizaciones. Utiliza el proceso de recuperación para extraer información de distintas fuentes de datos. El GAR no cambia la respuesta del modelo; sólo proporciona información adicional para guiarlo.
Ajuste fino personaliza el resultado del modelo y mejora su rendimiento en un dominio especial estrechamente relacionado con el conjunto de datos de entrenamiento. También cambia el estilo de generación de respuestas y a veces proporciona respuestas más pertinentes que los sistemas GAR.
3. Intensidad de los recursos
RAG consume muchos recursos porque se realiza durante la inferencia del modelo. Comparado con los LLM simples sin RAG, el RAG requiere más memoria e informática.
El ajuste fino requiere un gran esfuerzo informático, pero se realiza una sola vez. Requiere varias GPU y mucha memoria durante el proceso de entrenamiento, pero después es bastante respetuoso con los recursos en comparación con los sistemas RAG.
4. Coste
RAG requiere modelos de incrustación y LLM de primera clase para una mejor generación de respuestas. También necesita una base de datos vectorial rápida. Los costes de la API y de funcionamiento pueden aumentar con bastante rapidez.
El ajuste fino sólo te costará mucho una vez durante el proceso de entrenamiento, pero después pagarás por la inferencia del modelo, que es bastante más barata que la RAG.
En general, por término medio, el ajuste fino cuesta más que el GAR si se tiene todo en cuenta.
5. Complejidad de la aplicación
Los sistemas RAG pueden ser construidos por ingenieros informáticos y requieren conocimientos técnicos medios. Tienes que aprender sobre diseños LLM, bases de datos vectoriales, incrustaciones, ingenieros de prontitud, etc., lo que requiere tiempo, pero es fácil de aprender en un mes.
Puesta a punto el modelo exige grandes conocimientos técnicos. Desde la preparación del conjunto de datos hasta el ajuste de los parámetros y la supervisión del rendimiento del modelo, se necesitan años de experiencia en el campo del procesamiento del lenguaje natural.
Poner a prueba la teoría con ejemplos prácticos
Pongamos a prueba nuestra teoría proporcionando la misma indicación a un modelo afinado, a una aplicación RAG y a un enfoque híbrido, y luego evaluemos los resultados. El enfoque híbrido combinará el modelo afinado con la aplicación GAR. Para este ejemplo, utilizaremos el ruslanmv/ai-medical-chatbot de Hugging Face, que contiene conversaciones entre pacientes y médicos sobre diversos problemas de salud.
Crear una aplicación RAG con Llama 3
Empezaremos construyendo la aplicación RAG utilizando el ecosistema Llama 3 y LangChain.
También puedes aprender a construir una aplicación RAG utilizando LlamaIndex siguiendo el código, Generación Aumentada de Recuperación con LlamaIndex.
1. Instala todos los paquetes de Python necesarios.
%%capture
%pip install -U langchain langchainhub langchain_community langchain-huggingface faiss-gpu transformers accelerate
2. Carga las funciones necesarias de las bibliotecas LangChain y Transformers.
from langchain.document_loaders import HuggingFaceDatasetLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from transformers import AutoTokenizer, AutoModelForCausalLM,pipeline
from langchain_huggingface import HuggingFacePipeline
from langchain.chains import RetrievalQA
3. Para acceder a los modelos y conjuntos de datos restringidos, se recomienda que inicies sesión en el hub Cara Abrazada utilizando la clave API.
from huggingface_hub import login
from kaggle_secrets import UserSecretsClient
user_secrets = UserSecretsClient()
hf_token = user_secrets.get_secret("HUGGINGFACE_TOKEN")
login(token = hf_token)
4. Carga el conjunto de datos proporcionando el nombre del conjunto de datos y el nombre de la columna a HuggingFaceDatasetLoader
. Las columnas "Doctor" serán nuestro documento principal, y el resto de columnas serán los metadatos.
5. Limitando nuestro conjunto de datos a las 1000 primeras filas. Reducir el conjunto de datos nos ayudará a reducir el tiempo de almacenamiento de datos en la base de datos vectorial.
# Specify the dataset name
dataset_name = "ruslanmv/ai-medical-chatbot"
# Create a loader instance using dataset columns
loader_doctor = HuggingFaceDatasetLoader(dataset_name,"Doctor")
# Load the data
doctor_data = loader_doctor.load()
# Select the first 1000 entries
doctor_data = doctor_data[:1000]
doctor_data[:2]
Como podemos ver, la columna "Doctor" es el contenido de la página, y el resto se consideran metadatos.
6. Carga el modelo de incrustación de Cara Abrazada utilizando parámetros específicos, como activar la aceleración de la GPU.
7. Prueba el modelo de incrustación proporcionándole el texto de muestra.
# Define the path to the embedding model
modelPath = "sentence-transformers/all-MiniLM-L12-v2"
# GPU acceleration
model_kwargs = {'device':'cuda'}
# Create a dictionary with encoding options
encode_kwargs = {'normalize_embeddings': False}
# Initialize an instance of HuggingFaceEmbeddings with the specified parameters
embeddings = HuggingFaceEmbeddings(
model_name=modelPath,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs
)
text = "Why are you a doctor?"
query_result = embeddings.embed_query(text)
query_result[:3]
[-0.059351932257413864, 0.08008933067321777, 0.040729623287916183]
8. Convierte los datos en incrustaciones y guárdalos en la base de datos vectorial.
9. Guarda la base de datos vectorial en el directorio local.
10. Realiza una búsqueda de similitudes utilizando la consulta de ejemplo.
vector_db = FAISS.from_documents(doctor_data, embeddings)
vector_db.save_local("/kaggle/working/faiss_doctor_index")
question = "Hi Doctor, I have a headache, help me."
searchDocs = vector_db.similarity_search(question)
print(searchDocs[0].page_content)
11. Convierte la instancia de la base de datos vectorial en un recuperador. Esto nos ayudará a crear la cadena RAG.
retriever = vector_db.as_retriever()
12. Carga el tokenizador y el modelo utilizando el modelo de Chat Llama 3 8B.
13. Utilízalos para crear el canal de generación de pruebas.
14. Convierte la tubería en el cliente LLM LangChain.
import torch
base_model = "/kaggle/input/llama-3/transformers/8b-chat-hf/1"
tokenizer = AutoTokenizer.from_pretrained(base_model)
model = AutoModelForCausalLM.from_pretrained(
base_model,
return_dict=True,
low_cpu_mem_usage=True,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True,
)
pipe = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
max_new_tokens=120
)
llm = HuggingFacePipeline(pipeline=pipe)
15. Crea una cadena de preguntas y respuestas utilizando el recuperador, la consulta del usuario, la consulta RAG y el LLM.
from langchain import hub
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
rag_prompt = hub.pull("rlm/rag-prompt")
qa_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| rag_prompt
| llm
| StrOutputParser()
)
16. Pon a prueba la cadena de preguntas y respuestas haciendo preguntas al médico.
question = "Hi Doctor, I have a headache, help me."
result = qa_chain.invoke(question)
print(result.split("Answer: ")[1])
Es bastante similar al conjunto de datos, pero no recoge el estilo. Ha comprendido el contexto y lo ha utilizado para escribir la respuesta con su propio estilo.
Intentémoslo de nuevo con otra pregunta.
question = "Hello doctor, I have bad acne. How do I get rid of it?"
result = qa_chain.invoke(question)
print(result.split("Answer: ")[1])
Esta es una respuesta muy directa. Quizá debamos afinar el modelo en lugar de utilizar el enfoque RAG para el chatbot del médico y el paciente.
Si tienes dificultades para ejecutar el código, consulta el cuaderno Kaggle: Construir una aplicación RAG con Llama 3.
Aprende a mejorar el rendimiento del sistema RAG con técnicas como el Chunking, el Reranking y las Transformaciones de Consulta siguiendo la páginaCómo mejorar el rendimiento de RAG: 5 técnicas clave con ejemplos tutorial.
Puesta a punto de Llama 3 con datos médicos
No vamos a ajustar el modelo en el conjunto de datos de médicos y pacientes, porque ya lo hemos hecho en un tutorial anterior: Afinar Llama 3 y utilizarla localmente: Guía paso a paso. Lo que vamos a hacer es cargar el modelo afinado y plantearle la misma pregunta para evaluar los resultados. El modelo perfeccionado está disponible en Hugging Face y Kaggle.
Si te interesa afinar el modelo GPT-4 utilizando la API de OpenAI, puedes consultar el sencillo tutorial de DataCamp Afinar el GPT-4 de OpenAI: Guía paso a paso.
Fuente: kingabzpro/llama-3-8b-chat-doctor
1. Carga el tokenizador y el modelo utilizando la biblioteca de transformadores.
2. Asegúrate de que utilizas los parámetros correctos para cargar el modelo en el entorno Kaggle GPU T4 x2.
from transformers import AutoTokenizer,AutoModelForCausalLM,pipeline
import torch
base_model = "/kaggle/input/fine-tuned-adapter-to-full-model/llama-3-8b-chat-doctor/"
tokenizer = AutoTokenizer.from_pretrained(base_model)
model = AutoModelForCausalLM.from_pretrained(
base_model,
return_dict=True,
low_cpu_mem_usage=True,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True,
)
3. Aplica la plantilla de chat a los mensajes.
4. Crea un canal de generación de texto utilizando el modelo y el tokenizador.
5. Proporciona al objeto tubería una consulta y genera la respuesta.
messages = [{"role": "user", "content": "Hi Doctor, I have a headache, help me."}]
prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
pipe = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
torch_dtype=torch.float16,
device_map="auto",
)
outputs = pipe(prompt, max_new_tokens=120, do_sample=True)
print(outputs[0]["generated_text"])
La respuesta es bastante similar a la del conjunto de datos. El estilo es el mismo, pero en lugar de dar una respuesta directa, sugiere que el paciente se someta a más pruebas.
6. Hagamos la segunda pregunta.
messages = [{"role": "user", "content": "Hello doctor, I have bad acne. How do I get rid of it?"}]
prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
outputs = pipe(prompt, max_new_tokens=120, do_sample=True)
print(outputs[0]["generated_text"])
El estilo es el mismo, y la respuesta es bastante empática y explicativa.
Si tienes dificultades para ejecutar el código, consulta el cuaderno Kaggle: Inferencia afinada de Llama 3 HF.
Enfoque híbrido (GAR + Ajuste fino)
Ahora proporcionaremos al modelo afinado un contexto adicional para afinar aún más la respuesta y encontrar el equilibrio.
En lugar de volver a escribir todo el código, nos sumergiremos directamente en la generación de respuestas utilizando la cadena P&R. Si quieres ver el código completo de cómo hemos combinado un modelo de ajuste fino con una cadena de preguntas y respuestas RAG, echa un vistazo al documento Enfoque híbrido (GAR + Ajuste fino) Cuaderno Kaggle.
Proporciona a la cadena las mismas preguntas que hicimos al GAR y afina el modelo.
question = "Hi Doctor, I have a headache, help me."
result = qa_chain.invoke(question)
print(result.split("Answer: ")[1])
La respuesta es bastante precisa, y la respuesta se genera al estilo del médico.
Hagamos la segunda pregunta.
question = "Hello doctor, I have bad acne. How do I get rid of it?"
result = qa_chain.invoke(question)
print(result.split("Answer: ")[1])
Esto es extraño. Nunca proporcionamos contexto adicional sobre si el acné está lleno de pus o no. Puede que el modelo Híbrido no se aplique a algunas consultas.
En el caso de un chatbot médico-paciente, el modelo afinado sobresale en adopción de estilos y precisión. Sin embargo, esto puede variar para otros casos de uso, por lo que es importante realizar pruebas exhaustivas para determinar el mejor método para tu caso de uso específico.
El término oficial para el enfoque híbrido es RAFT (Retrieval Augmented Fine-Tuning). Aprende más sobre ello leyendo ¿Qué es el RAFT? Combinación de RAG y ajuste fino para adaptar los LLM a dominios especializados blog.
Cómo elegir entre RAG vs Ajuste fino vs RAFT
Todo depende de tu caso de uso y de los recursos disponibles. Si eres una startup con recursos limitados, entonces intenta construir una prueba de concepto RAG utilizando la API de IA Abierta y el marco LangChain. Para ello, necesitarás recursos, conocimientos y conjuntos de datos limitados.
Si eres una empresa de nivel medio y quieres afinar para mejorar la precisión de la respuesta y desplegar el modelo de código abierto en la nube, necesitas contratar a expertos como científicos de datos e ingenieros de operaciones de aprendizaje automático. El ajuste fino requiere GPU de primera clase, una gran memoria, un conjunto de datos depurado y un equipo técnico que entienda los LLM.
Una solución híbrida consume muchos recursos y recursos informáticos. También requiere un ingeniero LLMOps que sepa equilibrar la puesta a punto y el GAR. Deberías tenerlo en cuenta cuando quieras mejorar aún más tu generación de respuestas aprovechando las buenas cualidades del GAR y un modelo afinado.
Consulta la tabla siguiente para obtener una visión general de las soluciones RAG, de ajuste fino y RAFT.
RAG |
Ajuste fino |
RAFT |
|
Advantages |
Comprensión contextual, minimiza las alucinaciones, se adapta fácilmente a nuevos datos, rentable. |
Experiencia en tareas específicas, personalización, mayor precisión, mayor robustez. |
Combina los puntos fuertes tanto del GAR como del ajuste, la comprensión más profunda y el contexto. |
Disadvantages |
Gestión de fuentes de datos, complejidad. |
Sesgo de datos, uso intensivo de recursos, altos costes computacionales, requisitos sustanciales de memoria, uso intensivo de tiempo y experiencia. |
Complejidad en la aplicación, requiere equilibrar los procesos de recuperación y ajuste. |
Complejidad de la aplicación |
Superior a la ingeniería rápida. |
Superior a RAG. Requiere expertos muy técnicos. |
El más complejo de los tres. |
Estilo de aprendizaje |
Dinámico |
Estática |
Dinámico + Estático |
Adaptabilidad |
Se adapta fácilmente a los nuevos datos y a la evolución de los hechos. |
Personaliza los resultados para tareas y ámbitos específicos. |
Se adapta tanto a los datos en tiempo real como a tareas específicas. |
Coste |
Baja |
Moderado |
Alta |
Intensidad de recursos |
Baja. Los recursos se utilizan durante la Inferencia. |
Moderada. Los recursos se utilizan durante la puesta a punto. |
Alta |
Conclusión
Los grandes modelos lingüísticos son hoy el núcleo del desarrollo de la IA. Las empresas buscan diversas formas de mejorar y personalizar estos modelos sin gastar millones de dólares en formación. Empiezan con la optimización de los parámetros y la ingeniería rápida. Seleccionan la GAR o ajustan el modelo para obtener una respuesta aún mejor y reducir las alucinaciones. Aunque existen otras técnicas para mejorar la respuesta, éstas son las opciones disponibles más populares.
En este tutorial, hemos aprendido las diferencias entre la RAG y el ajuste fino a través de la teoría y de ejemplos prácticos. También exploramos modelos híbridos y comparamos qué método puede funcionar mejor para ti.
Para obtener más información sobre el despliegue de los LLM y las diversas técnicas implicadas, echa un vistazo a nuestro code-along sobre RAG con LLaMAIndex y nuestro curso sobre despliegue de aplicaciones LLM con LangChain.
Los mejores cursos de DataCamp
curso
LLMOps Concepts
curso
Vector Databases for Embeddings with Pinecone
tutorial
Ajuste fino de LLaMA 2: Guía paso a paso para personalizar el modelo de lenguaje grande
tutorial
Guía para principiantes de LlaMA-Factory WebUI: Ajuste de los LLM
tutorial
RAG Con Llama 3.1 8B, Ollama y Langchain: Tutorial
Ryan Ong
12 min
tutorial
Ajuste fino de SAM 2 en un conjunto de datos personalizado: Tutorial
tutorial
RankGPT como Agente de Re-Ranking para RAG (Tutorial)
Ryan Ong
8 min
tutorial