paint-brush
Crie seu próprio aplicativo RAG: um guia passo a passo para configurar o LLM localmente usando Ollama, Python e ChromaDBpor@nassermaronie
6,499 leituras
6,499 leituras

Crie seu próprio aplicativo RAG: um guia passo a passo para configurar o LLM localmente usando Ollama, Python e ChromaDB

por Nasser Maronie13m2024/07/04
Read on Terminal Reader

Muito longo; Para ler

Este tutorial irá guiá-lo através do processo de criação de um chatbot personalizado usando [Ollama], [Python 3 e [ChromaDB]. Hospedar seu próprio aplicativo Retrieval-Augmented Generation (RAG) localmente significa que você tem controle total sobre a configuração e personalização.
featured image - Crie seu próprio aplicativo RAG: um guia passo a passo para configurar o LLM localmente usando Ollama, Python e ChromaDB
Nasser Maronie HackerNoon profile picture
0-item
1-item

Numa era em que a privacidade dos dados é fundamental, configurar o seu próprio modelo de idioma local (LLM) proporciona uma solução crucial tanto para empresas como para indivíduos. Este tutorial foi desenvolvido para guiá-lo através do processo de criação de um chatbot personalizado usando Ollama , Python 3 e ChromaDB , todos hospedados localmente em seu sistema. Aqui estão os principais motivos pelos quais você precisa deste tutorial:


  • Personalização total: hospedar seu próprio aplicativo Retrieval-Augmented Generation (RAG) localmente significa que você tem controle total sobre a configuração e personalização. Você pode ajustar o modelo para atender às suas necessidades específicas sem depender de serviços externos.
  • Privacidade aprimorada: ao configurar seu modelo LLM localmente, você evita os riscos associados ao envio de dados confidenciais pela Internet. Isto é especialmente importante para empresas que lidam com informações confidenciais. Treinar seu modelo com dados privados localmente garante que seus dados permaneçam sob seu controle.
  • Segurança de dados: o uso de modelos LLM de terceiros pode expor seus dados a possíveis violações e uso indevido. A implantação local mitiga esses riscos, mantendo seus dados de treinamento, como documentos PDF, em seu ambiente seguro.
  • Controle sobre o processamento de dados: Ao hospedar seu próprio LLM, você tem a capacidade de gerenciar e processar seus dados exatamente como deseja. Isso inclui incorporar seus dados privados em seu armazenamento de vetores ChromaDB, garantindo que seu processamento de dados atenda aos seus padrões e requisitos.
  • Independência da conectividade com a Internet: Executar seu chatbot localmente significa que você não depende de uma conexão com a Internet. Isso garante atendimento ininterrupto e acesso ao seu chatbot, mesmo em cenários offline.


Este tutorial irá capacitá-lo a construir um chatbot local robusto e seguro, adaptado às suas necessidades, sem comprometer a privacidade ou o controle.

Modelo de ajuste fino


Geração Aumentada de Recuperação (RAG)

A geração aumentada de recuperação (RAG) é uma técnica avançada que combina os pontos fortes da recuperação de informações e da geração de texto para criar respostas mais precisas e contextualmente relevantes. Aqui está um resumo de como o RAG funciona e por que é benéfico:

O que é RAG?

RAG é um modelo híbrido que aprimora as capacidades dos modelos de linguagem incorporando uma base de conhecimento externa ou armazenamento de documentos. O processo envolve dois componentes principais:

  • Recuperação: Nesta fase, o modelo recupera documentos ou informações relevantes de uma fonte externa, como um banco de dados ou armazenamento de vetores, com base na consulta de entrada.
  • Geração: A informação recuperada é então usada por um modelo de linguagem generativa para produzir uma resposta coerente e contextualmente apropriada.

Como funciona o RAG?

  • Entrada de consulta: o usuário insere uma consulta ou pergunta.
  • Recuperação de Documentos: O sistema utiliza a consulta para pesquisar uma base de conhecimento externa, recuperando os documentos ou trechos de informações mais relevantes.
  • Geração de Resposta: O modelo generativo processa a informação recuperada, integrando-a ao seu próprio conhecimento para gerar uma resposta detalhada e precisa.
  • Saída: A resposta final, enriquecida com detalhes específicos e relevantes da base de conhecimento, é apresentada ao usuário.

Benefícios do RAG

  • Precisão aprimorada: ao aproveitar dados externos, os modelos RAG podem fornecer respostas mais precisas e detalhadas, especialmente para consultas específicas de domínio.
  • Relevância Contextual: O componente de recuperação garante que a resposta gerada seja baseada em informações relevantes e atualizadas, melhorando a qualidade geral da resposta.
  • Escalabilidade: Os sistemas RAG podem ser facilmente dimensionados para incorporar grandes quantidades de dados, permitindo-lhes lidar com uma ampla variedade de consultas e tópicos.
  • Flexibilidade: Estes modelos podem ser adaptados a vários domínios simplesmente atualizando ou expandindo a base de conhecimento externa, tornando-os altamente versáteis.

Por que usar o RAG localmente?

  • Privacidade e segurança: a execução local de um modelo RAG garante que os dados confidenciais permaneçam seguros e privados, pois não precisam ser enviados para servidores externos.
  • Personalização: você pode adaptar os processos de recuperação e geração para atender às suas necessidades específicas, incluindo a integração de fontes de dados proprietárias.
  • Independência: Uma configuração local garante que seu sistema permaneça operacional mesmo sem conectividade com a Internet, fornecendo um serviço consistente e confiável.

Ao configurar um aplicativo RAG local com ferramentas como Ollama, Python e ChromaDB, você pode aproveitar os benefícios de modelos de linguagem avançados enquanto mantém o controle sobre seus dados e opções de personalização.

Aplicativo RAG


GPU

A execução de grandes modelos de linguagem (LLMs), como os usados na Retrieval-Augmented Generation (RAG), requer um poder computacional significativo. Um dos principais componentes que permitem o processamento eficiente e a incorporação de dados nesses modelos é a Unidade de Processamento Gráfico (GPU). Veja por que as GPUs são essenciais para esta tarefa e como elas afetam o desempenho da configuração local do LLM:

O que é uma GPU?

Uma GPU é um processador especializado projetado para acelerar a renderização de imagens e vídeos. Ao contrário das Unidades Centrais de Processamento (CPUs), que são otimizadas para tarefas de processamento sequencial, as GPUs são excelentes no processamento paralelo. Isso os torna particularmente adequados para os cálculos matemáticos complexos exigidos pelo aprendizado de máquina e pelos modelos de aprendizado profundo.

Por que as GPUs são importantes para LLMs

  • Poder de processamento paralelo: as GPUs podem lidar com milhares de operações simultaneamente, acelerando significativamente tarefas como treinamento e inferência em LLMs. Esse paralelismo é crucial para as pesadas cargas computacionais associadas ao processamento de grandes conjuntos de dados e à geração de respostas em tempo real.
  • Eficiência no tratamento de modelos grandes: LLMs como os usados no RAG requerem memória e recursos computacionais substanciais. As GPUs são equipadas com memória de alta largura de banda (HBM) e múltiplos núcleos, tornando-as capazes de gerenciar multiplicações de matrizes em grande escala e operações de tensores necessárias para esses modelos.
  • Incorporação e recuperação de dados mais rápidas: em uma configuração RAG local, incorporar dados em um armazenamento de vetores como o ChromaDB e recuperar documentos relevantes rapidamente é essencial para o desempenho. GPUs de alto desempenho podem acelerar esses processos, garantindo que seu chatbot responda com rapidez e precisão.
  • Tempos de treinamento aprimorados: treinar um LLM envolve ajustar milhões (ou até bilhões) de parâmetros. As GPUs podem reduzir drasticamente o tempo necessário para esta fase de treinamento em comparação com as CPUs, permitindo atualizações e refinamentos mais frequentes em seu modelo.

Escolhendo a GPU certa

Ao configurar um LLM local, a escolha da GPU pode impactar significativamente o desempenho. Aqui estão alguns fatores a serem considerados:

  • Capacidade de memória: Modelos maiores requerem mais memória GPU. Procure GPUs com VRAM (RAM de vídeo) mais alto para acomodar conjuntos de dados extensos e parâmetros de modelo.
  • Capacidade de computação: quanto mais núcleos CUDA uma GPU tiver, melhor ela poderá lidar com tarefas de processamento paralelo. GPUs com maiores capacidades computacionais são mais eficientes para tarefas de aprendizagem profunda.
  • Largura de banda: Maior largura de banda de memória permite transferência de dados mais rápida entre a GPU e sua memória, melhorando a velocidade geral de processamento.

Exemplos de GPUs de alto desempenho para LLMs

  • NVIDIA RTX 3090: Conhecida por seu alto VRAM (24 GB) e núcleos CUDA poderosos, é uma escolha popular para tarefas de aprendizagem profunda.
  • NVIDIA A100: Projetado especificamente para IA e aprendizado de máquina, oferece desempenho excepcional com grande capacidade de memória e alto poder computacional.
  • AMD Radeon Pro VII: Outro forte concorrente, com alta largura de banda de memória e capacidades de processamento eficientes.

Investir em uma GPU de alto desempenho é crucial para executar modelos LLM localmente. Ele garante processamento de dados mais rápido, treinamento eficiente de modelos e geração rápida de respostas, tornando seu aplicativo RAG local mais robusto e confiável. Ao aproveitar o poder das GPUs, você pode aproveitar plenamente os benefícios de hospedar seu próprio chatbot personalizado, adaptado às suas necessidades específicas e requisitos de privacidade de dados.


Pré-requisitos

Antes de mergulhar na configuração, certifique-se de ter os seguintes pré-requisitos em vigor:

  • Python 3: Python é uma linguagem de programação versátil que você usará para escrever o código do seu aplicativo RAG.
  • ChromaDB: Um banco de dados vetorial que irá armazenar e gerenciar a incorporação de nossos dados.
  • Ollama: Para baixar e servir LLMs personalizados em nossa máquina local.

Etapa 1: instale o Python 3 e configure seu ambiente

Para instalar e configurar nosso ambiente Python 3, siga estas etapas: Baixe e configure o Python 3 em sua máquina. Em seguida, certifique-se de que seu Python 3 esteja instalado e executado com sucesso:

 $ python3 --version # Python 3.11.7

Crie uma pasta para o seu projeto, por exemplo, local-rag :

 $ mkdir local-rag $ cd local-rag

Crie um ambiente virtual chamado venv :

 $ python3 -m venv venv

Ative o ambiente virtual:

 $ source venv/bin/activate # Windows # venv\Scripts\activate

Etapa 2: instale o ChromaDB e outras dependências

Instale o ChromaDB usando pip:

 $ pip install --q chromadb

Instale as ferramentas Langchain para funcionar perfeitamente com o seu modelo:

 $ pip install --q unstructured langchain langchain-text-splitters $ pip install --q "unstructured[all-docs]"

Instale o Flask para servir seu aplicativo como um serviço HTTP:

 $ pip install --q flask

Etapa 3: instalar o Ollama

Para instalar o Ollama, siga estas etapas: Vá para a página de download do Ollama e baixe o instalador para o seu sistema operacional. Verifique a instalação do Ollama executando:

 $ ollama --version # ollama version is 0.1.47

Puxe o modelo LLM que você precisa. Por exemplo, para usar o modelo Mistral:

 $ ollama pull mistral

Puxe o modelo de incorporação de texto. Por exemplo, para usar o modelo Nomic Embed Text:

 $ ollama pull nomic-embed-text

Em seguida, execute seus modelos Ollama:

 $ ollama serve

Crie o aplicativo RAG

Agora que você configurou seu ambiente com Python, Ollama, ChromaDB e outras dependências, é hora de construir seu aplicativo RAG local personalizado. Nesta seção, examinaremos o código Python prático e forneceremos uma visão geral de como estruturar seu aplicativo.

app.py

Este é o arquivo principal do aplicativo Flask. Ele define rotas para incorporar arquivos ao banco de dados vetorial e recuperar a resposta do modelo.

 import os from dotenv import load_dotenv load_dotenv() from flask import Flask, request, jsonify from embed import embed from query import query from get_vector_db import get_vector_db TEMP_FOLDER = os.getenv('TEMP_FOLDER', './_temp') os.makedirs(TEMP_FOLDER, exist_ok=True) app = Flask(__name__) @app.route('/embed', methods=['POST']) def route_embed(): if 'file' not in request.files: return jsonify({"error": "No file part"}), 400 file = request.files['file'] if file.filename == '': return jsonify({"error": "No selected file"}), 400 embedded = embed(file) if embedded: return jsonify({"message": "File embedded successfully"}), 200 return jsonify({"error": "File embedded unsuccessfully"}), 400 @app.route('/query', methods=['POST']) def route_query(): data = request.get_json() response = query(data.get('query')) if response: return jsonify({"message": response}), 200 return jsonify({"error": "Something went wrong"}), 400 if __name__ == '__main__': app.run(host="0.0.0.0", port=8080, debug=True)

embed.py

Este módulo cuida do processo de incorporação, incluindo salvar arquivos carregados, carregar e dividir dados e adicionar documentos ao banco de dados vetorial.

 import os from datetime import datetime from werkzeug.utils import secure_filename from langchain_community.document_loaders import UnstructuredPDFLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from get_vector_db import get_vector_db TEMP_FOLDER = os.getenv('TEMP_FOLDER', './_temp') # Function to check if the uploaded file is allowed (only PDF files) def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1].lower() in {'pdf'} # Function to save the uploaded file to the temporary folder def save_file(file): # Save the uploaded file with a secure filename and return the file path ct = datetime.now() ts = ct.timestamp() filename = str(ts) + "_" + secure_filename(file.filename) file_path = os.path.join(TEMP_FOLDER, filename) file.save(file_path) return file_path # Function to load and split the data from the PDF file def load_and_split_data(file_path): # Load the PDF file and split the data into chunks loader = UnstructuredPDFLoader(file_path=file_path) data = loader.load() text_splitter = RecursiveCharacterTextSplitter(chunk_size=7500, chunk_overlap=100) chunks = text_splitter.split_documents(data) return chunks # Main function to handle the embedding process def embed(file): # Check if the file is valid, save it, load and split the data, add to the database, and remove the temporary file if file.filename != '' and file and allowed_file(file.filename): file_path = save_file(file) chunks = load_and_split_data(file_path) db = get_vector_db() db.add_documents(chunks) db.persist() os.remove(file_path) return True return False

query.py

Este módulo processa consultas de usuários gerando múltiplas versões da consulta, recuperando documentos relevantes e fornecendo respostas com base no contexto.

 import os from langchain_community.chat_models import ChatOllama from langchain.prompts import ChatPromptTemplate, PromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnablePassthrough from langchain.retrievers.multi_query import MultiQueryRetriever from get_vector_db import get_vector_db LLM_MODEL = os.getenv('LLM_MODEL', 'mistral') # Function to get the prompt templates for generating alternative questions and answering based on context def get_prompt(): QUERY_PROMPT = PromptTemplate( input_variables=["question"], template="""You are an AI language model assistant. Your task is to generate five different versions of the given user question to retrieve relevant documents from a vector database. By generating multiple perspectives on the user question, your goal is to help the user overcome some of the limitations of the distance-based similarity search. Provide these alternative questions separated by newlines. Original question: {question}""", ) template = """Answer the question based ONLY on the following context: {context} Question: {question} """ prompt = ChatPromptTemplate.from_template(template) return QUERY_PROMPT, prompt # Main function to handle the query process def query(input): if input: # Initialize the language model with the specified model name llm = ChatOllama(model=LLM_MODEL) # Get the vector database instance db = get_vector_db() # Get the prompt templates QUERY_PROMPT, prompt = get_prompt() # Set up the retriever to generate multiple queries using the language model and the query prompt retriever = MultiQueryRetriever.from_llm( db.as_retriever(), llm, prompt=QUERY_PROMPT ) # Define the processing chain to retrieve context, generate the answer, and parse the output chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() ) response = chain.invoke(input) return response return None

get_vector_db.py

Este módulo inicializa e retorna a instância do banco de dados vetorial usada para armazenar e recuperar embeddings de documentos.

 import os from langchain_community.embeddings import OllamaEmbeddings from langchain_community.vectorstores.chroma import Chroma CHROMA_PATH = os.getenv('CHROMA_PATH', 'chroma') COLLECTION_NAME = os.getenv('COLLECTION_NAME', 'local-rag') TEXT_EMBEDDING_MODEL = os.getenv('TEXT_EMBEDDING_MODEL', 'nomic-embed-text') def get_vector_db(): embedding = OllamaEmbeddings(model=TEXT_EMBEDDING_MODEL,show_progress=True) db = Chroma( collection_name=COLLECTION_NAME, persist_directory=CHROMA_PATH, embedding_function=embedding ) return db

Execute seu aplicativo!

Crie o arquivo .env para armazenar suas variáveis de ambiente:

 TEMP_FOLDER = './_temp' CHROMA_PATH = 'chroma' COLLECTION_NAME = 'local-rag' LLM_MODEL = 'mistral' TEXT_EMBEDDING_MODEL = 'nomic-embed-text'

Execute o arquivo app.py para iniciar seu servidor de aplicativos:

 $ python3 app.py

Quando o servidor estiver em execução, você poderá começar a fazer solicitações aos seguintes endpoints:

  • Exemplo de comando para incorporar um arquivo PDF (por exemplo, resume.pdf):
 $ curl --request POST \ --url http://localhost:8080/embed \ --header 'Content-Type: multipart/form-data' \ --form file=@/Users/nassermaronie/Documents/Nasser-resume.pdf # Response { "message": "File embedded successfully" }
  • Exemplo de comando para fazer uma pergunta ao seu modelo:
 $ curl --request POST \ --url http://localhost:8080/query \ --header 'Content-Type: application/json' \ --data '{ "query": "Who is Nasser?" }' # Response { "message": "Nasser Maronie is a Full Stack Developer with experience in web and mobile app development. He has worked as a Lead Full Stack Engineer at Ulventech, a Senior Full Stack Engineer at Speedoc, a Senior Frontend Engineer at Irvins, and a Software Engineer at Tokopedia. His tech stacks include Typescript, ReactJS, VueJS, React Native, NodeJS, PHP, Golang, Python, MySQL, PostgresQL, MongoDB, Redis, AWS, Firebase, and Supabase. He has a Bachelor's degree in Information System from Universitas Amikom Yogyakarta." }

Conclusão

Seguindo estas instruções, você pode executar e interagir efetivamente com seu aplicativo RAG local personalizado usando Python, Ollama e ChromaDB, adaptado às suas necessidades. Ajuste e expanda a funcionalidade conforme necessário para aprimorar os recursos do seu aplicativo.

Ao aproveitar os recursos de implantação local, você não apenas protege informações confidenciais, mas também otimiza o desempenho e a capacidade de resposta. Esteja você melhorando as interações com os clientes ou simplificando processos internos, um aplicativo RAG implantado localmente oferece flexibilidade e robustez para se adaptar e crescer de acordo com suas necessidades.

Verifique o código-fonte neste repositório:

https://github.com/firstpersoncode/local-rag


Boa codificação!