paint-brush
Cree su propia aplicación RAG: una guía paso a paso para configurar LLM localmente usando Ollama, Python y ChromaDBpor@nassermaronie
7,828 lecturas
7,828 lecturas

Cree su propia aplicación RAG: una guía paso a paso para configurar LLM localmente usando Ollama, Python y ChromaDB

por Nasser Maronie13m2024/07/04
Read on Terminal Reader

Demasiado Largo; Para Leer

Este tutorial lo guiará a través del proceso de creación de un chatbot personalizado usando [Ollama], [Python 3 y [ChromaDB]. Alojar su propia aplicación de generación aumentada de recuperación (RAG) localmente significa que tiene control total sobre la configuración y personalización.
featured image - Cree su propia aplicación RAG: una guía paso a paso para configurar LLM localmente usando Ollama, Python y ChromaDB
Nasser Maronie HackerNoon profile picture
0-item
1-item

En una era en la que la privacidad de los datos es primordial, configurar su propio modelo de idioma local (LLM) proporciona una solución crucial tanto para empresas como para individuos. Este tutorial está diseñado para guiarlo a través del proceso de creación de un chatbot personalizado usando Ollama , Python 3 y ChromaDB , todos alojados localmente en su sistema. Estas son las razones clave por las que necesita este tutorial:


  • Personalización total: alojar localmente su propia aplicación de generación aumentada de recuperación (RAG) significa que tiene control total sobre la configuración y personalización. Puede ajustar el modelo para que se ajuste a sus necesidades específicas sin depender de servicios externos.
  • Privacidad mejorada: al configurar su modelo LLM localmente, evita los riesgos asociados con el envío de datos confidenciales a través de Internet. Esto es especialmente importante para las empresas que manejan información confidencial. Entrenar su modelo con datos privados localmente garantiza que sus datos permanezcan bajo su control.
  • Seguridad de los datos: el uso de modelos LLM de terceros puede exponer sus datos a posibles violaciones y uso indebido. La implementación local mitiga estos riesgos al mantener sus datos de capacitación, como documentos PDF, dentro de su entorno seguro.
  • Control sobre el procesamiento de datos: cuando organiza su propio LLM, tiene la capacidad de administrar y procesar sus datos exactamente como desee. Esto incluye incorporar sus datos privados en su almacén de vectores ChromaDB, asegurando que su procesamiento de datos cumpla con sus estándares y requisitos.
  • Independencia de la conectividad a Internet: ejecutar su chatbot localmente significa que no depende de una conexión a Internet. Esto garantiza un servicio y acceso ininterrumpidos a su chatbot, incluso en escenarios fuera de línea.


Este tutorial le permitirá crear un chatbot local sólido y seguro, adaptado a sus necesidades, sin comprometer la privacidad ni el control.

Modelo de ajuste fino


Recuperación-Generación Aumentada (RAG)

Recuperación-Generación Aumentada (RAG) es una técnica avanzada que combina las fortalezas de la recuperación de información y la generación de texto para crear respuestas más precisas y contextualmente relevantes. Aquí hay un desglose de cómo funciona RAG y por qué es beneficioso:

¿Qué es RAG?

RAG es un modelo híbrido que mejora las capacidades de los modelos de lenguaje incorporando una base de conocimiento externa o un almacén de documentos. El proceso involucra dos componentes principales:

  • Recuperación: en esta fase, el modelo recupera documentos o piezas de información relevantes de una fuente externa, como una base de datos o un almacén de vectores, en función de la consulta de entrada.
  • Generación: la información recuperada se utiliza luego mediante un modelo de lenguaje generativo para producir una respuesta coherente y contextualmente apropiada.

¿Cómo funciona RAG?

  • Entrada de consulta: el usuario ingresa una consulta o pregunta.
  • Recuperación de documentos: el sistema utiliza la consulta para buscar en una base de conocimiento externa, recuperando los documentos o fragmentos de información más relevantes.
  • Generación de respuesta: el modelo generativo procesa la información recuperada, integrándola con su propio conocimiento para generar una respuesta detallada y precisa.
  • Resultado: se presenta al usuario la respuesta final, enriquecida con detalles específicos y relevantes de la base de conocimientos.

Beneficios del RAG

  • Precisión mejorada: al aprovechar datos externos, los modelos RAG pueden proporcionar respuestas más precisas y detalladas, especialmente para consultas de dominios específicos.
  • Relevancia contextual: el componente de recuperación garantiza que la respuesta generada se base en información relevante y actualizada, mejorando la calidad general de la respuesta.
  • Escalabilidad: los sistemas RAG se pueden escalar fácilmente para incorporar grandes cantidades de datos, lo que les permite manejar una amplia gama de consultas y temas.
  • Flexibilidad: estos modelos se pueden adaptar a diversos dominios simplemente actualizando o ampliando la base de conocimientos externos, lo que los hace muy versátiles.

¿Por qué utilizar RAG localmente?

  • Privacidad y seguridad: ejecutar un modelo RAG localmente garantiza que los datos confidenciales permanezcan seguros y privados, ya que no es necesario enviarlos a servidores externos.
  • Personalización: puede adaptar los procesos de recuperación y generación para satisfacer sus necesidades específicas, incluida la integración de fuentes de datos patentadas.
  • Independencia: una configuración local garantiza que su sistema permanezca operativo incluso sin conectividad a Internet, brindando un servicio consistente y confiable.

Al configurar una aplicación RAG local con herramientas como Ollama, Python y ChromaDB, puede disfrutar de los beneficios de los modelos de lenguaje avanzados mientras mantiene el control sobre sus datos y opciones de personalización.

Aplicación RAG


GPU

La ejecución de modelos de lenguaje grandes (LLM) como los utilizados en Recuperación-Generación Aumentada (RAG) requiere una potencia computacional significativa. Uno de los componentes clave que permite el procesamiento e incorporación eficiente de datos en estos modelos es la Unidad de procesamiento de gráficos (GPU). He aquí por qué las GPU son esenciales para esta tarea y cómo afectan el rendimiento de su configuración LLM local:

¿Qué es una GPU?

Una GPU es un procesador especializado diseñado para acelerar la renderización de imágenes y vídeos. A diferencia de las Unidades Centrales de Procesamiento (CPU), que están optimizadas para tareas de procesamiento secuencial, las GPU destacan en el procesamiento paralelo. Esto los hace particularmente adecuados para los complejos cálculos matemáticos requeridos por el aprendizaje automático y los modelos de aprendizaje profundo.

Por qué las GPU son importantes para los LLM

  • Potencia de procesamiento paralelo: las GPU pueden manejar miles de operaciones simultáneamente, lo que acelera significativamente tareas como la capacitación y la inferencia en los LLM. Este paralelismo es crucial para las pesadas cargas computacionales asociadas con el procesamiento de grandes conjuntos de datos y la generación de respuestas en tiempo real.
  • Eficiencia en el manejo de modelos grandes: los LLM como los utilizados en RAG requieren memoria sustancial y recursos computacionales. Las GPU están equipadas con memoria de gran ancho de banda (HBM) y múltiples núcleos, lo que las hace capaces de gestionar las multiplicaciones de matrices y operaciones tensoriales a gran escala que necesitan estos modelos.
  • Incrustación y recuperación de datos más rápida: en una configuración RAG local, incrustar datos en un almacén de vectores como ChromaDB y recuperar documentos relevantes rápidamente es esencial para el rendimiento. Las GPU de alto rendimiento pueden acelerar estos procesos, garantizando que su chatbot responda con rapidez y precisión.
  • Tiempos de formación mejorados: formar un LLM implica ajustar millones (o incluso miles de millones) de parámetros. Las GPU pueden reducir drásticamente el tiempo necesario para esta fase de entrenamiento en comparación con las CPU, lo que permite actualizaciones y mejoras más frecuentes de su modelo.

Elegir la GPU adecuada

Al configurar un LLM local, la elección de la GPU puede afectar significativamente el rendimiento. Aquí hay algunos factores a considerar:

  • Capacidad de memoria: los modelos más grandes requieren más memoria GPU. Busque GPU con mayor VRAM (RAM de video) para acomodar conjuntos de datos extensos y parámetros de modelo.
  • Capacidad de computación: cuantos más núcleos CUDA tenga una GPU, mejor podrá manejar tareas de procesamiento paralelo. Las GPU con mayores capacidades informáticas son más eficientes para tareas de aprendizaje profundo.
  • Ancho de banda: un mayor ancho de banda de memoria permite una transferencia de datos más rápida entre la GPU y su memoria, lo que mejora la velocidad de procesamiento general.

Ejemplos de GPU de alto rendimiento para LLM

  • NVIDIA RTX 3090: Conocida por su alta VRAM (24 GB) y potentes núcleos CUDA, es una opción popular para tareas de aprendizaje profundo.
  • NVIDIA A100: Diseñado específicamente para IA y aprendizaje automático, ofrece un rendimiento excepcional con gran capacidad de memoria y alta potencia informática.
  • AMD Radeon Pro VII: Otro fuerte contendiente, con gran ancho de banda de memoria y capacidades de procesamiento eficientes.

Invertir en una GPU de alto rendimiento es crucial para ejecutar modelos LLM localmente. Garantiza un procesamiento de datos más rápido, un entrenamiento de modelos eficiente y una generación de respuestas rápida, lo que hace que su aplicación RAG local sea más sólida y confiable. Al aprovechar el poder de las GPU, puede aprovechar plenamente los beneficios de alojar su propio chatbot personalizado, adaptado a sus necesidades específicas y requisitos de privacidad de datos.


Requisitos previos

Antes de sumergirse en la configuración, asegúrese de cumplir con los siguientes requisitos previos:

  • Python 3: Python es un lenguaje de programación versátil que usará para escribir el código de su aplicación RAG.
  • ChromaDB: Una base de datos vectorial que almacenará y gestionará las incrustaciones de nuestros datos.
  • Ollama: Para descargar y servir LLM personalizados en nuestra máquina local.

Paso 1: instale Python 3 y configure su entorno

Para instalar y configurar nuestro entorno Python 3, siga estos pasos: Descargue y configure Python 3 en su máquina. Luego asegúrese de que Python 3 esté instalado y se ejecute correctamente:

 $ python3 --version # Python 3.11.7

Crea una carpeta para tu proyecto, por ejemplo, local-rag :

 $ mkdir local-rag $ cd local-rag

Cree un entorno virtual llamado venv :

 $ python3 -m venv venv

Activar el entorno virtual:

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

Paso 2: instale ChromaDB y otras dependencias

Instale ChromaDB usando pip:

 $ pip install --q chromadb

Instale las herramientas Langchain para trabajar perfectamente con su modelo:

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

Instale Flask para ofrecer su aplicación como un servicio HTTP:

 $ pip install --q flask

Paso 3: Instalar Ollama

Para instalar Ollama, siga estos pasos: Diríjase a la página de descarga de Ollama y descargue el instalador para su sistema operativo. Verifique su instalación de Ollama ejecutando:

 $ ollama --version # ollama version is 0.1.47

Extraiga el modelo LLM que necesita. Por ejemplo, para utilizar el modelo Mistral:

 $ ollama pull mistral

Extraiga el modelo de incrustación de texto. Por ejemplo, para utilizar el modelo Nomic Embed Text:

 $ ollama pull nomic-embed-text

Luego ejecuta tus modelos de Ollama:

 $ ollama serve

Construya la aplicación RAG

Ahora que ha configurado su entorno con Python, Ollama, ChromaDB y otras dependencias, es hora de crear su aplicación RAG local personalizada. En esta sección, analizaremos el código Python práctico y brindaremos una descripción general de cómo estructurar su aplicación.

app.py

Este es el archivo principal de la aplicación Flask. Define rutas para incrustar archivos en la base de datos de vectores y recuperar la respuesta del 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 maneja el proceso de incrustación, incluido guardar archivos cargados, cargar y dividir datos y agregar documentos a la base de datos vectorial.

 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 procesa las consultas de los usuarios generando múltiples versiones de la consulta, recuperando documentos relevantes y proporcionando respuestas basadas en el 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 y devuelve la instancia de base de datos vectorial utilizada para almacenar y recuperar incrustaciones 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

¡Ejecute su aplicación!

Cree un archivo .env para almacenar sus variables de entorno:

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

Ejecute el archivo app.py para iniciar su servidor de aplicaciones:

 $ python3 app.py

Una vez que el servidor se esté ejecutando, puede comenzar a realizar solicitudes a los siguientes puntos finales:

  • Comando de ejemplo para incrustar un archivo PDF (por ejemplo, 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" }
  • Comando de ejemplo para hacerle una pregunta a su 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." }

Conclusión

Si sigue estas instrucciones, podrá ejecutar e interactuar de manera efectiva con su aplicación RAG local personalizada utilizando Python, Ollama y ChromaDB, adaptadas a sus necesidades. Ajuste y amplíe la funcionalidad según sea necesario para mejorar las capacidades de su aplicación.

Al aprovechar las capacidades de la implementación local, no solo protege la información confidencial sino que también optimiza el rendimiento y la capacidad de respuesta. Ya sea que esté mejorando las interacciones con los clientes o optimizando los procesos internos, una aplicación RAG implementada localmente ofrece flexibilidad y solidez para adaptarse y crecer con sus requisitos.

Consulte el código fuente en este repositorio:

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


¡Feliz codificación!