Curso
A maioria dos LLMs (Large Language Models), como o GPT-4, é treinada em conjuntos de dados generalizados e, muitas vezes, desatualizados. Embora sejam excelentes em responder a perguntas gerais, eles têm dificuldades com consultas sobre notícias recentes, desenvolvimentos mais recentes e tópicos específicos do domínio. Nesses casos, eles podem ter alucinações ou fornecer respostas imprecisas.
Apesar do surgimento de modelos de melhor desempenho, como o Claude 3.5 Sonnet, ainda precisamos modelar o ajuste fino para gerar respostas personalizadas ou usar os sistemas Retrieval-Augmented Generation (RAG) para fornecer contexto extra ao modelo básico.
Neste tutorial, exploraremos o RAG e o ajuste fino, duas técnicas distintas usadas para melhorar as respostas do LLM. Examinaremos suas diferenças e colocaremos a teoria em prática, avaliando os resultados.
Além disso, vamos nos aprofundar em técnicas híbridas que combinam modelos ajustados com sistemas RAG para aproveitar o melhor dos dois mundos. Por fim, aprenderemos a escolher entre essas três abordagens com base em casos de uso e requisitos específicos.
Visão geral do RAG e ajuste fino
As técnicas de RAG e de ajuste fino melhoram a geração de respostas para consultas específicas de domínio, mas são inerentemente técnicas completamente diferentes. Vamos aprender sobre eles.
Geração Aumentada por Recuperação (RAG)
O Retrieval-Augmented Generation é um processo em que grandes modelos de linguagem, como o GPT-4o, tornam-se conscientes do contexto usando fontes de dados externas. Ele é uma combinação de um retriever e um gerador. O recuperador obtém dados da Internet ou de um banco de dados vetorial e os fornece ao gerador com a consulta do usuário original. O gerador usa contexto adicional para gerar uma resposta altamente precisa e relevante.
Para saber mais, leia nosso artigo, O que é Retrieval Augmented Generation (RAG)? A Guide to the Basics e entender o funcionamento interno do aplicativo RAG e vários casos de uso .
Ajuste fino
O ajuste fino é o processo de ajuste do modelo pré-treinado usando o conjunto de dados específico do domínio. O modelo pré-treinado é treinado em vários corpos grandes de conjuntos de dados gerais retirados da Internet. Eles são bons em responder a perguntas gerais, mas terão dificuldades ou até mesmo alucinações ao responder a perguntas específicas do domínio.
Por exemplo, um modelo pré-treinado pode ser proficiente em habilidades gerais de conversação, mas pode produzir respostas erradas quando perguntado sobre procedimentos médicos complexos ou precedentes jurídicos.
O ajuste fino em um conjunto de dados médicos ou jurídicos permite que o modelo compreenda e responda a perguntas nesses campos com maior precisão e relevância.
Siga o Guia introdutório para ajuste fino de LLMs para saber mais sobre como personalizar o modelo pré-treinado com guias visuais.
RAG vs. Ajuste fino
Aprendemos sobre cada metodologia para melhorar a geração de respostas dos LLMs. Vamos examinar as diferenças para que você possa entendê-las melhor.
1. Estilo de aprendizagem
O RAG usa um estilo de aprendizado dinâmico, que permite que os modelos de linguagem acessem e usem os dados mais recentes e precisos de bancos de dados, da Internet ou até mesmo de APIs. Essa abordagem garante que as respostas geradas estejam sempre atualizadas e sejam relevantes.
Ajuste fino envolve aprendizado estático, em que o modelo aprende por meio de um novo conjunto de dados durante a fase de treinamento. Embora esse método permita que o modelo se adapte à geração de respostas específicas do domínio, ele não pode integrar novas informações pós-treinamento sem retreinamento.
2. Adaptabilidade
O RAG é melhor para generalizações. Ele usa o processo de recuperação para extrair informações de diferentes fontes de dados. O RAG não altera a resposta do modelo; ele apenas fornece informações adicionais para orientar o modelo.
Fine-tuning personaliza a saída do modelo e melhora o desempenho do modelo em um domínio especial que está intimamente associado ao conjunto de dados de treinamento. Ele também muda o estilo de geração de respostas e, às vezes, fornece respostas mais relevantes do que os sistemas RAG.
3. Intensidade de recursos
O RAG consome muitos recursos porque é realizado durante a inferência do modelo. Em comparação com LLMs simples sem RAG, o RAG requer mais memória e computação.
O ajuste fino do exige muita computação, mas é realizado uma vez. Ele requer várias GPUs e muita memória durante o processo de treinamento, mas, depois disso, é bastante econômico em termos de recursos em comparação com os sistemas RAG.
4. Custo
O RAG requer modelos de incorporação e LLMs de primeira linha para uma melhor geração de respostas. Ele também precisa de um banco de dados vetorial rápido. Os custos de API e de operação podem aumentar rapidamente.
Ajuste fino terá um custo alto apenas uma vez durante o processo de treinamento, mas, depois disso, você pagará pela inferência do modelo, que é bem mais barata que o RAG.
Em geral, em média, o ajuste fino custa mais do que o RAG se tudo for considerado.
5. Complexidade de implementação
Os sistemas RAG podem ser criados por engenheiros de software e exigem conhecimento técnico médio. Você precisa aprender sobre projetos LLM, bancos de dados vetoriais, embeddings, prompt engineers e muito mais, o que requer tempo, mas é fácil de aprender em um mês.
Ajuste fino o modelo exige alto conhecimento técnico. Desde a preparação do conjunto de dados até a definição dos parâmetros de ajuste e o monitoramento do desempenho do modelo, são necessários anos de experiência no campo do processamento de linguagem natural.
Colocando a teoria à prova com exemplos práticos
Vamos testar nossa teoria fornecendo o mesmo prompt a um modelo ajustado, ao aplicativo RAG e a uma abordagem híbrida e, em seguida, avaliar os resultados. A abordagem híbrida combinará o modelo ajustado com o aplicativo RAG. Para este exemplo, usaremos o arquivo ruslanmv/ai-medical-chatbot do Hugging Face, que contém conversas entre pacientes e médicos sobre várias condições de saúde.
Criação do aplicativo RAG usando o Llama 3
Começaremos criando o aplicativo RAG usando o ecossistema Llama 3 e LangChain.
Você também pode aprender a criar um aplicativo RAG usando o LlamaIndex seguindo o código, Geração aumentada de recuperação com o LlamaIndex.
1. Instale todos os pacotes Python necessários.
%%capture
%pip install -U langchain langchainhub langchain_community langchain-huggingface faiss-gpu transformers accelerate
2. Carregue as funções necessárias das bibliotecas LangChain e 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 acessar modelos e conjuntos de dados restritos, é recomendável que você faça login no hub Hugging Face usando a chave de 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. Carregue o conjunto de dados fornecendo o nome do conjunto de dados e o nome da coluna para HuggingFaceDatasetLoader
. As colunas "Doctor" serão nosso documento principal, e o restante das colunas serão os metadados.
5. Limitando nosso conjunto de dados às primeiras 1.000 linhas. A redução do conjunto de dados nos ajudará a reduzir o tempo de armazenamento de dados no banco de dados vetorial.
# 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 você pode ver, a coluna "Doctor" é o conteúdo da página, e as demais são consideradas metadados.
6. Carregue o modelo de incorporação do Hugging Face usando parâmetros específicos, como a ativação da aceleração da GPU.
7. Teste o modelo de incorporação fornecendo a ele o texto de amostra.
# 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. Converta os dados em embeddings e salve-os no banco de dados de vetores.
9. Salve o banco de dados de vetores no diretório local.
10. Faça uma pesquisa de similaridade usando o prompt de amostra.
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. Converta a instância do banco de dados vetorial em um retriever. Isso nos ajudará a criar a cadeia RAG.
retriever = vector_db.as_retriever()
12. Carregue o tokenizador e o modelo usando o modelo do Llama 3 8B Chat.
13. Use-os para criar o pipeline de geração de testes.
14. Converta o pipeline no cliente LangChain LLM.
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. Crie uma cadeia de perguntas e respostas usando o retriever, a consulta do usuário, o prompt do RAG e o 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. Teste a cadeia de perguntas e respostas fazendo perguntas ao médico.
question = "Hi Doctor, I have a headache, help me."
result = qa_chain.invoke(question)
print(result.split("Answer: ")[1])
Ele é bastante semelhante ao conjunto de dados, mas não capta o estilo. Você entendeu o contexto e o utilizou para escrever a resposta em seu próprio estilo.
Vamos tentar novamente com outra pergunta.
question = "Hello doctor, I have bad acne. How do I get rid of it?"
result = qa_chain.invoke(question)
print(result.split("Answer: ")[1])
Essa é uma resposta muito direta. Talvez seja necessário ajustar o modelo em vez de usar a abordagem RAG para o chatbot do médico e do paciente.
Se você estiver encontrando dificuldades para executar o código, consulte o notebook do Kaggle: Criação do aplicativo RAG usando o Llama 3.
Saiba como melhorar o desempenho do sistema RAG com técnicas como Chunking, Reranking e Query Transformations seguindo o site How to Improve RAG Performance: 5 técnicas principais com exemplos tutorial.
Ajuste fino do Llama 3 em dados médicos
Não faremos o ajuste fino do modelo no conjunto de dados do médico e do paciente porque já fizemos isso em um tutorial anterior: Ajustando o Llama 3 e usando-o localmente: Um guia passo a passo. O que faremos é carregar o modelo ajustado e fornecer a ele a mesma pergunta para avaliar os resultados. O modelo ajustado está disponível no Hugging Face e no Kaggle.
Se estiver interessado em fazer o ajuste fino do modelo GPT-4 usando a API da OpenAI, você pode consultar o tutorial fácil de seguir do DataCamp Fine-Tuning OpenAI's GPT-4: Um guia passo a passo.
Fonte: kingabzpro/llama-3-8b-chat-doctor
1. Carregue o tokenizador e o modelo usando a biblioteca do transformador.
2. Certifique-se de que você use os parâmetros corretos para carregar o modelo no ambiente GPU T4 x2 do Kaggle.
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. Aplique o modelo de bate-papo às mensagens.
4. Crie um pipeline de geração de texto usando o modelo e o tokenizador.
5. Forneça ao objeto do pipeline um prompt e gere a resposta.
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"])
A resposta é bastante semelhante ao conjunto de dados. O estilo é o mesmo, mas em vez de dar uma resposta direta, ele sugere que o paciente faça mais exames.
6. Vamos fazer a segunda pergunta.
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"])
O estilo é o mesmo, e a resposta é bastante empática e explicativa.
Se você estiver encontrando dificuldades para executar o código, consulte o notebook do Kaggle: Inferência de alta frequência da Llama 3 com ajuste fino.
Abordagem híbrida (RAG + ajuste fino)
Agora, forneceremos ao modelo ajustado um contexto adicional para ajustar ainda mais a resposta e encontrar o equilíbrio.
Em vez de escrever todo o código novamente, vamos nos aprofundar diretamente na geração de respostas usando a cadeia de perguntas e respostas. Se você quiser ver o código completo de como combinamos um modelo de ajuste fino com uma cadeia RAG de perguntas e respostas, dê uma olhada em Abordagem híbrida (RAG + ajuste fino) Caderno do Kaggle.
Forneça à cadeia as mesmas perguntas que fizemos ao RAG e ao modelo ajustado.
question = "Hi Doctor, I have a headache, help me."
result = qa_chain.invoke(question)
print(result.split("Answer: ")[1])
A resposta é bastante precisa, e a resposta é gerada no estilo do médico.
Vamos fazer a segunda pergunta.
question = "Hello doctor, I have bad acne. How do I get rid of it?"
result = qa_chain.invoke(question)
print(result.split("Answer: ")[1])
Isso é estranho. Nunca fornecemos contexto adicional sobre o fato de a acne estar cheia de pus ou não. Talvez o modelo Hybrid não se aplique a algumas consultas.
No caso de um chatbot médico-paciente, o modelo ajustado é excelente em termos de adoção de estilo e precisão. No entanto, isso pode variar para outros casos de uso, e é por isso que é importante realizar testes extensivos para determinar o melhor método para seu caso de uso específico.
O termo oficial para a abordagem híbrida é RAFT (Retrieval Augmented Fine-Tuning). Para saber mais sobre o assunto, leia . O que é RAFT? Combinando RAG e ajuste fino para adaptar LLMs a domínios especializados blog.
Como escolher entre RAG, ajuste fino ou RAFT
Tudo depende do seu caso de uso e dos recursos disponíveis. Se você for uma startup com recursos limitados, tente criar uma prova de conceito de RAG usando a API Open AI e a estrutura LangChain. Para isso, você precisará de recursos, conhecimentos e conjuntos de dados limitados.
Se você for uma empresa de nível médio e quiser fazer um ajuste fino para melhorar a precisão da resposta e implantar o modelo de código aberto na nuvem, precisará contratar especialistas como cientistas de dados e engenheiros de operações de machine learning. O ajuste fino requer GPUs de primeira linha, memória grande, um conjunto de dados limpo e uma equipe técnica que entenda de LLMs.
Uma solução híbrida consome muitos recursos e computação. Isso também requer um engenheiro de LLMOps que possa equilibrar o ajuste fino e o RAG. Você deve considerar isso quando quiser melhorar ainda mais a geração de respostas, aproveitando as boas qualidades do RAG e de um modelo ajustado.
Consulte a tabela abaixo para obter uma visão geral das soluções RAG, de ajuste fino e RAFT.
RAG |
Ajuste fino |
RAFT |
|
Vantagens |
Compreensão contextual, minimiza alucinações, adapta-se facilmente a novos dados, é econômico. |
Conhecimento específico da tarefa, personalização, precisão aprimorada, maior robustez. |
Combina os pontos fortes do RAG e do ajuste fino, com compreensão e contexto mais profundos. |
Desvantagens |
Gerenciamento de fontes de dados, complexidade. |
Viés de dados, uso intensivo de recursos, altos custos de computação, requisitos substanciais de memória, uso intensivo de tempo e conhecimento. |
Complexidade na implementação, requer o equilíbrio dos processos de recuperação e ajuste fino. |
Complexidade de implementação |
Superior à engenharia imediata. |
Superior ao RAG. Requer especialistas altamente técnicos. |
O mais complexo dos três. |
Estilo de aprendizagem |
Dinâmico |
Estático |
Dinâmico + Estático |
Adaptabilidade |
Adapta-se facilmente a novos dados e fatos em evolução. |
Personalize os resultados para tarefas e domínios específicos. |
Adapta-se a dados em tempo real e a tarefas específicas. |
Custo |
Baixa |
Moderado |
Alta |
Intensidade de recursos |
Baixo. Os recursos são usados durante a Inferência. |
Moderado. Os recursos são usados durante o ajuste fino. |
Alta |
Conclusão
Os modelos de linguagem grandes estão no centro do desenvolvimento da IA atualmente. As empresas estão procurando várias maneiras de aprimorar e personalizar esses modelos sem gastar milhões de dólares em treinamento. Eles começam com a otimização de parâmetros e a engenharia imediata. Eles selecionam o RAG ou ajustam o modelo para obter uma resposta ainda melhor e reduzir as alucinações. Embora existam outras técnicas para melhorar a resposta, essas são as opções mais populares disponíveis.
Neste tutorial, aprendemos sobre as diferenças entre RAG e ajuste fino por meio de teoria e exemplos práticos. Também exploramos modelos híbridos e comparamos qual método pode funcionar melhor para você.
Para saber mais sobre a implementação de LLMs e as várias técnicas envolvidas, confira nosso code-along sobre RAG com LLaMAIndex e nosso curso sobre implantação de aplicativos LLM com LangChain.