Revelando RAG: “RAG Simples e Local”

RAG LLM

Já se questionou como aqueles chatbots com os quais conversa online conseguem parecer tão bem informados? Tudo isso graças aos grandes modelos de linguagem (LLMs), programas de IA que podem produzir texto, traduzir idiomas e até escrever diferentes tipos de conteúdo criativo. Contudo temos um problema: os LLMs contam com as informações nas quais foram treinados, que nem sempre são as mais recentes. Para superar isso, precisa de ajustar seu modelo para atualizar o LLM, o que é um trabalho árduo. É aí que entra o RAG!

RAG (Retrieval-Augmented Generation)

Pense no RAG como um confirmador de factos superpoderoso para o LLM para a sua vizinhança. O RAG vai um passo além, permitindo que os LLMs acedam a informações em tempo real de fontes confiáveis. Isso significa que obtém o melhor dos dois mundos: a capacidade do LLM de compreender e responder às suas perguntas de forma natural, combinada com a precisão e atualização do conhecimento do mundo atual.

Aqui está um resumo da magia por trás do RAG:

  • Retrieval: Quando faz uma pergunta, o RAG primeiro procura informações relevantes em fontes confiáveis, como bancos de dados ou artigos online.
  • Augmentation: Assim que o RAG recolhe informações relevantes, utiliza-os para orientar o LLM na elaboração da sua resposta. Isso garante que a resposta seja baseada em informações reais, não apenas no que o LLM dispõe nos seus dados de treinamento.

Quais são os benefícios do RAG?

  • Precisão factual: Não tem de se preocupar com informações desatualizadas ou enganosas. RAG garante que seu LLM permaneça sempre atualizado com as ultimas informações.
  • Melhoramento do Contexto: O RAG ajuda os LLMs a entender melhor o contexto das questões, gerando respostas mais relevantes e informativas.
  • Mais abrangente: O RAG abre portas para que os LLMs sejam usados ​​em mais áreas que exigem precisão factual, como chatbots para atendimento ao cliente ou ferramentas educacionais.

Ok, mas como é que posso implementar essa ferramenta na minha empresa e localmente?

Ótima pergunta! Aqui está uma implementação RAG simples que você pode executar em sua máquina local com algum conhecimento básico de Python.

O plano é ter três scripts Python: um para ingerir documentos e outro para interagir com seu chatbot, e o último para ajustar seu RAG.

Para este projeto, vamos usar algumas bibliotecas e frameworks Python, como:

  • ChromaDB (banco de dados de armazenamento de vetores): Para armazenar representações vetoriais dos documentos para recolha eficiente.
  • Langchain: Esta estrutura simplifica a construção de pipelines de PNL baseados em recolha.
  • Transformers: Esta biblioteca fornece modelos pré-treinados para processamento e incorporação de texto.
  • Embeddings: Convertem texto em representações numéricas para uma pesquisa eficiente no armazenamento de vetores.
  • CharacterTextSplitter: Divide o texto em caracteres para alguns modelos.
  • Document loaders: Essas bibliotecas ajudam a carregar e pré-processar seus documentos.

Primeiro a ingestão

Para treiná-lo com informações atualizadas, você precisa fazer um "finetunning" ou, neste caso, vamos enganá-lo para que leia alguns de nossos dados, e faremos isso com um script de ingestão, convertendo pedaços de dados de texto em representações numéricas (vetores). Isso permite que o LLM compreenda e utilize as informações de forma eficaz.

import chromadb  # Import the ChromaDB vector store database
from langchain.embeddings import HuggingFaceEmbeddings  # Import HuggingFace embeddings
from langchain.document_loaders import TextLoader, PyPDFLoader  # Import document loaders
from langchain.text_splitter import CharacterTextSplitter  # Import text splitter
from langchain.vectorstores import Chroma  # Import vector store from Langchain
from llmsettings import data_path, embedding_model, llm_model, llm_config, persist_directory # Will import the settings from another file

# Load a PDF document using PyPDFLoader
loader = PyPDFLoader(r"the_path_to_your_file")
documents = loader.load()

# Print basic information about the loaded documents
print(len(documents))
print(documents[0].page_content)
print(documents[1].page_content)

# Split the documents into smaller chunks (characters in this case)
text_splitter = CharacterTextSplitter(chunk_size=128, chunk_overlap=50)
texts = text_splitter.split_documents(documents)

# Create HuggingFace embeddings for the chunks
embeddings = HuggingFaceEmbeddings(model_name=embedding_model, model_kwargs={'device': 'cpu'})

# Create a Chroma search instance for initial retrieval
docsearch = Chroma.from_documents(texts, embeddings)

# Create a Chroma vector database for persistent storage
vectordb = Chroma.from_documents(
    documents=texts,
    embedding=embeddings,
    persist_directory=persist_directory,
)

# Print the number of chunks stored in the vector database
print(f"Number of Chunks (chunks) at the VectorDB: {vectordb._collection.count()}")

Agora vamos ao script com o qual interagimos com nosso LLM

from langchain.vectorstores import Chroma  # Import Chroma vector store
from langchain.embeddings import HuggingFaceEmbeddings  # Import HuggingFace embeddings
from langchain.chains import RetrievalQA  # Import RetrievalQA chain
from langchain.llms import CTransformers  # Import CTransformers LLM
from llmsettings import data_path, embedding_model, llm_model, llm_config, persist_directory # Will import the settings from another file


# Create HuggingFace embeddings for text processing
embedding = HuggingFaceEmbeddings(model_name=embedding_model, model_kwargs={'device': 'cpu'})

# Load Chroma vector database from persistent storage
vectordb = Chroma(persist_directory=persist_directory, embedding_function=embedding)

# Print commented-out line for potential future use (uncomment if desired)
# print(f"Loaded {vectordb._collection.count()} data")

# Build a RetrievalQA chain
qa_chain = RetrievalQA.from_chain_type(
    llm=CTransformers(  # Initialize LLM using CTransformers
        model=llm_model,
        model_type="llama",  # Assuming "llama" is the correct model type
        config=llm_config,
    ),
    chain_type="stuff",  # Placeholder chain type (might need adjustment)
    retriever=vectordb.as_retriever(search_kwargs={'k': 1}),  # Retriever using ChromaDB
)

# User input for the question
question = input("Ask the BOT: ")

# Pass the question to the RetrievalQA chain for processing
result = qa_chain({"query": question})

# Access and print the answer from the result
print(result["result"])

Só mais uma coisa e você poderá usar o llm, mas agora deixe-me explicar o código:

  1. Importamos as bibliotecas necessárias: Importamos os módulos necessários para armazenamentos de vetores, incorporações, cadeia de recolha, integração LLM e configurações.
  2. Create embeddings: Embeddings HuggingFace semelhantes ao código anterior.
  3. Carregamos a ChromaDB: Carregamos a base de dados vetorial Chroma do diretório persistente usando os embeddings criados anteriormente.
  4. Linha comentada: A linha comentada (# print(f"Loaded {vectordb._collection.count()} data")) é usado para debugging, ela imprime o número de vetores carregados. Pode descomentar se necessário.
  5. Construímos a cadeia RetrievalQA: Constrói uma cadeia RetrievalQA. Esta cadeia combina os seguintes elementos:
    • LLM: Isso usa o CTransformers classe para integrar o grande modelo de linguagem especificado por llm_modelmodel_type, e configuração de llm_config.
    • Tipo de Cadeia: "stuff" é um espaço reservado e pode ser necessário ajustá-lo com base na funcionalidade específica da cadeia RetrievalQA.
    • Retriever: Isso usa o vectordb.as_retriever método para criar um componente do banco de dados vetorial Chroma. O search_kwargs={'k': 1} argumento especifica a recuperação apenas do documento mais relevante durante a pesquisa.
  6. Questão do utilizador: Solicita ao utilizador que insira uma pergunta para o bot usando input("Ask the BOT: ").
  7. Process question: Pass the user’s question wrapped in a dictionary ({"query": question}) to the qa_chain for processing.
  8. Imprime a resposta: Extrai e imprime a resposta com o resultado do processamento usando "result["result"]".

E por fim o arquivo que podemos ajustar no RAG:

data_path = r"path_to_your_dir"
embedding_model = "sentence-transformers/distiluse-base-multilingual-cased-v1"
llm_model = "TheBloke/zephyr-7B-beta-GGUF"
llm_config = {'max_new_tokens': 128, 'repetition_penalty': 1.1, 'temperature': 0.2}
persist_directory = 'your_db_dir'

Como pode ver no primeiro e no segundo script de python nomeei o ficheiro de configuração de llmsettings.py, pode alterá-lo, mas também é necessário fazer essas alterações em todos os restantes ficheiros.

No terminal basta executar o script da ingestão. Este script irá processar seus documentos e armazenar as informações no banco de dados.
Assim a ingestão tiver concluída, execute o segundo script. Este script iniciará a interface onde você pode interagir com o BOT.

RAG é uma ferramenta poderosa que preenche a lacuna entre os LLMs e o mundo real. Ao fornecer um fluxo constante de novas informações, o RAG abre caminho para uma nova geração de IA que não é apenas inteligente, mas também confiável.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *

pt_PT