Saltar al contenido principal

Cómo desplegar aplicaciones LLM utilizando Docker: Guía paso a paso

Este tutorial te enseña a utilizar Docker para crear y desplegar una aplicación de preguntas y respuestas sobre documentos en la Nube de Cara Abrazada.
Actualizado 27 nov 2024  · 25 min de lectura

Docker te permite crear entornos consistentes, portátiles y aislados, lo que lo hace esencial para las LLMOps (Large Language Models Operations). Al encapsular varias aplicaciones LLM y sus dependencias en contenedores, Docker simplifica el despliegue, garantiza la compatibilidad entre sistemas y agiliza las pruebas.

En este tutorial, aprenderás a crear una aplicación chatbot de "preguntas y respuestas sobre documentos" y a desplegarla en la nube utilizando Docker. Utilizaremos Gradio para la interfaz de usuario, LlamaIndex para la orquestación, LlamaParse para analizar documentos, Mixedbread AI para las incrustaciones, Groq para acceder a grandes modelos lingüísticos, Docker para empaquetar la aplicación y sus dependencias, y Hugging Face Spaces para desplegar la aplicación en la nube.

Este tutorial está diseñado para ser sencillo, permitiendo que cualquier persona con un conocimiento limitado de cómo funcionan las aplicaciones de IA pueda construirlo gratis.

Descripción del proyecto

Hay dos enfoques principales para desarrollar e implantar aplicaciones de IA:

  • Código totalmente abierto: Este enfoque hace hincapié en la privacidad y la protección de datos.
  • Fuente totalmente cerrada: Este método implica integrar múltiples API y servicios en la nube.

Ambos enfoques tienen ventajas e inconvenientes. En nuestro caso, hemos optado por el segundo enfoque, integrando múltiples servicios de IA. Esto nos permite construir una aplicación de IA rápida que sólo tarda unos segundos en construirse y desplegarse. Nuestro principal objetivo es reducir el tamaño de la imagen Docker, lo que puede lograrse eficazmente integrando múltiples servicios de IA.

Consulta el tutorial Local AI with Docker, n8n, Qdrant, and Ollama para crear una aplicación LLM utilizando herramientas y marcos de trabajo de código abierto para mejorar la privacidad.

Construiremos un chatbot de preguntas y respuestas de uso general que permita a los usuarios subir documentos y chatear con ellos en tiempo real. Es bastante similar al NotebookLM de Google.

Doc Q&A LLM Diagrama de solicitud

Diagrama del proyecto. Imagen del autor

Éstas son las herramientas que utilizaremos en este proyecto:

  1. Bloques Gradio: Para crear una interfaz de usuario que permita a los usuarios cargar cualquier documento de texto y chatear con él fácilmente.
  2. LlamaCloud: Sirve para analizar archivos y extraer datos de texto al estilo Markdown.
  3. MixedBread AI: Se utiliza para convertir documentos cargados y mensajes de chat en incrustaciones para la recuperación del contexto.
  4. Groq Cloud: Esto es para acceder a respuestas rápidas LLM. En este proyecto, utilizaremos el modelo llama-3.1-70b.
  5. LlamaIndex: Crear la canalización RAG (Generación Aumentada de Recuperación) que orquesta todos los servicios de IA. La canalización utilizará el archivo cargado y los mensajes del usuario para generar respuestas adaptadas al contexto.
  6. Docker: Se utiliza para encapsular la aplicación, las dependencias, el entorno y las configuraciones.
  7. Nube de Caras Abrazadas: Empujaremos todos los archivos al repositorio de Spaces, y Hugging Face construirá automáticamente la imagen utilizando el Dockerfile y la desplegará en el servidor.

Si eres nuevo en el campo de los LLM, considera la posibilidad de realizar el curso Conceptos de los Modelos de Grandes Lenguajes (LLM) para aprender las terminologías básicas, las metodologías, las consideraciones éticas y las últimas investigaciones.

¿Quieres iniciarte en la IA Generativa?

Aprende a trabajar con LLMs en Python directamente en tu navegador

Empieza Ahora

Antes de construir la aplicación LLM, tenemos que descargar e instalar Docker desde el sitio web oficial

  • Instala Docker en tu sistema local utilizando las opciones por defecto.
  • A continuación, crea un directorio de proyecto utilizando tu IDE favorito y añade un archivo .env. Utilizaremos este archivo para almacenar las claves API de LlamaCloud, MixedBread AI y Groq Cloud.
  • Después, regístrate en LlamaCloud y genera tu clave API. Utilizaremos LlamaCloud para analizar varios formatos de texto, como Excel, txt, Word y PDF.

LlamaCloud dashbord

Generar una nueva clave en LlamaCloud. Fuente de la imagen: LlamaCloud

  • A continuación, regístrate en MixedBread AI y genera tu clave API. Utilizaremos esta clave para acceder gratuitamente a su modelo de incrustación de gama alta.

Cuadro de mandos de MixedBread AI

Crear una clave API en MixedBread. Fuente de la imagen: MixedBread

  • Ve a GroqCloud y regístrate para generar tu clave API sin coste alguno. Utilizaremos GroqCloud para acceder a los LLM de alta velocidad.

Panel de control de Groq Cloud

Crear una clave API en GroqCloud.  Fuente de la imagen: GroqCloud

Aprende todo sobre GroqCloud leyendo el artículo sobre el motor de inferencia Groq LPU. Conocerás la API de Groq y sus funciones con ejemplos de código. Además, aprende a crear aplicaciones de IA conscientes del contexto utilizando la API Groq y LlamaIndex.

Este es el aspecto que debe tener tu archivo .env:

LLAMA_CLOUD_API_KEY=llx-XXXXXX
GROQ_API_KEY=gsk_XXXXXXX
MXBAI_API_KEY=emb_XXXXXX

Recuerda añadir el archivo .env a tu archivo .gitignore para evitar exponer accidentalmente tus claves API al público.

Ahora crearemos un script en Python llamado app.py y añadiremos los componentes de la interfaz de usuario, a la vez que integramos todos los servicios de IA utilizando LlamaParser para desarrollar la tubería de Recuperación-Generación Aumentada (RAG) con LlamaIndex.

El script app.py hará lo siguiente:

  1. Carga todos los paquetes Python necesarios.
  2. Carga de forma segura todas las claves API desde el archivo .env.
  3. Inicializa el LlamaParser utilizando la clave de la API de LlamaCloud.
  4. Define un extractor de archivos que maneje varias extensiones de archivo comunes.
  5. Inicializa el modelo de incrustación utilizando la clave de la API AI de MixedBread, concretamente el modelo denominado mixedbread-ai/mxbai-embed-large-v1.
  6. Inicializa el modelo lingüístico grande utilizando la clave API de Groq Cloud y el modelo llamado llama-3.1-70b-versatile.

A continuación, implementa las siguientes funciones de Python:

  • load_files(): Esta función cargará los archivos, los analizará utilizando LlamaParser, los convertirá en incrustaciones y los almacenará en el almacén de vectores. Se incluirá un tratamiento de excepciones para gestionar los casos en los que se suban archivos que no sean archivos o formatos de archivo no compatibles.
  • respond(): Esta función tomará la entrada del usuario, recuperará el contenido del almacén vectorial y lo utilizará para generar una respuesta utilizando el modelo Groq. La generación de la respuesta será en formato streaming, y se incluirá el manejo de excepciones si no se han subido archivos.

Por último, construirá los componentes de la interfaz de usuario, incluyendo un cargador de archivos, botones, un cuadro de chat y la interfaz general del chat.

Aprende más sobre el marco LlamaIndex siguiendo el tutorial LlamaIndex más directo.

Aquí tienes el guión app.py:

import os

import gradio as gr
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.embeddings.mixedbreadai import MixedbreadAIEmbedding
from llama_index.llms.groq import Groq
from llama_parse import LlamaParse

# API keys
llama_cloud_key = os.environ.get("LLAMA_CLOUD_API_KEY")
groq_key = os.environ.get("GROQ_API_KEY")
mxbai_key = os.environ.get("MXBAI_API_KEY")
if not (llama_cloud_key and groq_key and mxbai_key):
    raise ValueError(
        "API Keys not found! Ensure they are passed to the Docker container."
    )

# models name
llm_model_name = "llama-3.1-70b-versatile"
embed_model_name = "mixedbread-ai/mxbai-embed-large-v1"

# Initialize the parser
parser = LlamaParse(api_key=llama_cloud_key, result_type="markdown")

# Define file extractor with various common extensions
file_extractor = {
    ".pdf": parser,
    ".docx": parser,
    ".doc": parser,
    ".txt": parser,
    ".csv": parser,
    ".xlsx": parser,
    ".pptx": parser,
    ".html": parser,
    ".jpg": parser,
    ".jpeg": parser,
    ".png": parser,
    ".webp": parser,
    ".svg": parser,
}

# Initialize the embedding model
embed_model = MixedbreadAIEmbedding(api_key=mxbai_key, model_name=embed_model_name)

# Initialize the LLM
llm = Groq(model="llama-3.1-70b-versatile", api_key=groq_key)


# File processing function
def load_files(file_path: str):
    global vector_index
    if not file_path:
        return "No file path provided. Please upload a file."
   
    valid_extensions = ', '.join(file_extractor.keys())
    if not any(file_path.endswith(ext) for ext in file_extractor):
        return f"The parser can only parse the following file types: {valid_extensions}"

    document = SimpleDirectoryReader(input_files=[file_path], file_extractor=file_extractor).load_data()
    vector_index = VectorStoreIndex.from_documents(document, embed_model=embed_model)
    print(f"Parsing completed for: {file_path}")
    filename = os.path.basename(file_path)
    return f"Ready to provide responses based on: {filename}"


# Respond function
def respond(message, history):
    try:
        # Use the preloaded LLM
        query_engine = vector_index.as_query_engine(streaming=True, llm=llm)
        streaming_response = query_engine.query(message)
        partial_text = ""
        for new_text in streaming_response.response_gen:
            partial_text += new_text
            # Yield an empty string to cleanup the message textbox and the updated conversation history
            yield partial_text
    except (AttributeError, NameError):
        print("An error occurred while processing your request.")
        yield "Please upload the file to begin chat."


# Clear function
def clear_state():
    global vector_index
    vector_index = None
    return [None, None, None]


# UI Setup
with gr.Blocks(
    theme=gr.themes.Default(
        primary_hue="green",
        secondary_hue="blue",
        font=[gr.themes.GoogleFont("Poppins")],
    ),
    css="footer {visibility: hidden}",
) as demo:
    gr.Markdown("# DataCamp Doc Q&A 🤖📃")
    with gr.Row():
        with gr.Column(scale=1):
            file_input = gr.File(
                file_count="single", type="filepath", label="Upload Document"
            )
            with gr.Row():
                btn = gr.Button("Submit", variant="primary")
                clear = gr.Button("Clear")
            output = gr.Textbox(label="Status")
        with gr.Column(scale=3):
            chatbot = gr.ChatInterface(
                fn=respond,
                chatbot=gr.Chatbot(height=300),
                theme="soft",
                show_progress="full",
                textbox=gr.Textbox(
                    placeholder="Ask questions about the uploaded document!",
                    container=False,
                ),
            )

    # Set up Gradio interactions
    btn.click(fn=load_files, inputs=file_input, outputs=output)
    clear.click(
        fn=clear_state,  # Use the clear_state function
        outputs=[file_input, output],
    )

# Launch the demo
if __name__ == "__main__":
    demo.launch()
  • Ejecuta el archivo Python anterior para iniciar el servidor Gradio utilizando el siguiente comando en tu terminal:
$ python app.py  

Salida:

Ejecutar la aplicación Gradio localmente.

  • Puedes acceder a la interfaz de usuario de Grodio copiando y pegando la URL generada en el navegador. Luego, puedes subir un archivo y empezar a hacer preguntas sobre él.

Acceder a la app Gradio en el navegador.

Acceder a la app Gradio en el navegador. Imagen del autor

Utilizamos LlamaIndex para desplegar y construir nuestra aplicación LLM para este tutorial. Puedes crear una aplicación similar con LangChain siguiendo el curso breve Desarrollo de aplicaciones LLM con LangChain.

3. Crear el archivo Dockerfile

  • En tu proyecto, crea un Dockerfile para empaquetar el script de la aplicación, las dependencias de Python y las configuraciones del servidor mientras se inicializa el servidor Gradio. 

El Dockerfile realizará las siguientes tareas:

  1. Configura un entorno Python 3.9.
  2. Define el directorio de trabajo.
  3. Copia el archivo requirements.txt en el directorio /app. Este archivo contiene los nombres de todos los paquetes de Python necesarios.
  4. Instala todas las dependencias especificadas en el archivo requirements.txt.
  5. Copia el archivo app.py en el directorio /app.
  6. Expón el puerto y establece la URL del servidor Gradio.
  7. Ejecuta el archivo de aplicación para iniciar el servidor.

Este es el aspecto que debe tener Dockerfile:

# Dockerfile

# Use the official Python image with the desired version
FROM python:3.9-slim

# Set the working directory inside the container
WORKDIR /app

# Copy the requirements file to the working directory
COPY requirements.txt /app

# Install the dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy the rest of the application code to the working directory
COPY app.py /app

# Expose the port that Gradio will run on (default is 7860)
EXPOSE 7860

ENV GRADIO_SERVER_NAME="0.0.0.0"

# Command to run your application
CMD ["python", "app.py"]
  • Y así es como queda el archivo requirements.txt. Añádelo también a tu proyecto:
gradio
llama-index-embeddings-mixedbreadai
llama-index-llms-groq
llama-index

4. Construir la imagen Docker y ejecutar el contenedor

  • Escribe el siguiente comando en el terminal para crear la imagen docker docqa. Utilizará la dirección Dockerfile para crear la imagen Docker.
$ docker build -t docqa . 

Podemos ver los registros de los procesos que tienen lugar mientras se construye la imagen Docker:

construyendo la imagen docker LLM

Construir la imagen Docker de LLM. Imagen del autor

  • Una vez que la imagen se haya creado correctamente, ve al Escritorio Docker, haz clic en el botón Imágenes y haz clic en la imagen Docker para ver los registros y varias instrucciones para ejecutar la imagen.

ver la imagen docker en el Escritorio Docker

Visualización de la imagen Docker en el Escritorio Docker. Imagen del autor

Ahora ejecutaremos el contenedor Docker localmente utilizando la imagen. Le proporcionaremos el número de puerto, un archivo .env para configurar las variables de entorno, el nombre del contenedor Docker y la etiqueta de la imagen Docker.

  • Ejecuta el siguiente comando en tu terminal: 
$ docker run -p 7860:7860 --env-file .env --name docqa-container docqa

Una vez que el contenedor empiece a funcionar, puedes acceder a la app Gradio pegando la URL, en este caso, http://0.0.0.1:7860/ en el navegador. 

Probar la aplicación LLM del contenedor Docker.

Probar la aplicación LLM del contenedor Docker. Imagen del autor

  • Para ver la información de todos los contenedores que se ejecutan localmente, escribe el siguiente comando:
$ docker ps

Salida:

CONTAINER ID   IMAGE     COMMAND           CREATED          STATUS          PORTS                    NAMES
ff2a11da13d7   docqa     "python app.py"   17 seconds ago   Up 16 seconds   0.0.0.0:7860->7860/tcp   docqa-container
  • Puedes detener el contenedor Docker utilizando el comando stop:
$ docker stop docqa-container 
  • También puedes eliminarlo utilizando el comando rm:
$ docker rm docqa-container 

Una vez que tenemos una imagen Docker, podemos desplegar nuestra aplicación LLM en cualquier lugar: GCP, AWS, Azure o cualquier servidor en la nube que admita el despliegue de Docker.

5. Despliegue de la aplicación LLM en Hugging Face utilizando Docker

Para simplificar las cosas a los principiantes, desplegaremos la aplicación utilizando Docker en la Nube de Caras Abrazadas (Spaces). 

  • Ve al panel de control de Cara Abrazada, haz clic en la imagen de perfil y selecciona + Nuevo espacio.
  • Dale un nombre a tu Espacio, añade una breve descripción, selecciona la licencia y el SDK, y crea el repositorio del Espacio.

Creación del nuevo Espacio de Caras Abrazadas utilizando el Docker

Creación del nuevo Espacio Cara Abrazada utilizando Docker. Fuente de la imagen: Cara de abrazo

Una vez creado el repositorio de Space, recibirás instrucciones sobre cómo clonarlo y añadir los archivos necesarios.

  • Para clonar el repositorio, utiliza el siguiente comando (actualiza la URL a la que apunta a tu Espacio):
$ git clone https://huggingface.co/spaces/kingabzpro/doc-qa-docker
  • Copia y pega todos los archivos del directorio del proyecto en el nuevo repositorio:

Este es el aspecto que debe tener el directorio de tu proyecto con todos los archivos. Asegúrate siempre de no empujar el archivo .env, así que añádelo a .gitignore

Directorio de proyectos.

Estructura de los archivos del proyecto. Imagen del autor

  • Prepara los archivos, envíalos con un mensaje y luego envíalos al Espacio Cara Abrazada:
$ git add .                                                                                            
$ git commit -m "Deploying the App" 
$ git push

Salida:

Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 16 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 7.60 KiB | 7.60 MiB/s, done.
Total 7 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://huggingface.co/spaces/kingabzpro/doc-qa-docker
   afb20ad..5ca6388  main -> main
  • Ve a tu Espacio Cara Abrazada para acceder a la aplicación. Construirá la imagen Docker y luego servirá la aplicación:

Construir la imagen docker en la nube de Cara Abrazada

Construir la imagen Docker en la Nube de Cara Abrazada. Fuente de la imagen: Doc Qa Docker

Si aparece un error como el siguiente, no te preocupes. Se debe a que faltan variables de entorno. Todo lo que tenemos que hacer es establecer esas variables en el Espacio Cara Abrazada.

Error de ejecución en la aplicación desplegada.

Error de ejecución en la aplicación desplegada. Fuente de la imagen: Doc Qa Docker

  • Para añadir una nueva variable de entorno en tu Espacio, ve a Configuración, desplázate hacia abajo y haz clic en el botónNuevo secreto. A continuación, proporciona el nombre y el valor para el valor de entorno, como se muestra a continuación. En este caso, estamos añadiendo las claves API necesarias:

Añade los secretos de la aplicación desplegada.

Añadir secretos a la aplicación desplegada. Fuente de la imagen: Doc Qa Configuración de Docker.

Este es el aspecto que deben tener tus secretos después de añadir todas las claves API necesarias como variables de entorno:

todos los secretos de la aplicación desplegada.

Secretos para la aplicación desplegada. Fuente de la imagen: Doc Qa Configuración de Docker.

Una vez que hayas configurado los secretos, la aplicación se reiniciará automáticamente, y deberías ver la aplicación en funcionamiento. ¡Úsalo y disfruta de tu aplicación de preguntas y respuestas sobre documentos en la nube!

Aplicación LLM en los Espacios Cara Abrazada.

Aplicación LLM en los Espacios Cara Abrazada. Fuente de la imagene: Doc Qa Docker

Para reproducir los resultados, puedes encontrar todos los archivos y configuraciones en el repositorio de GitHubsitory: kingabzpro/Deploy-Doc-QA.

6. Supervisar la aplicación desplegada

Utilizar servicios de IA tiene ventajas: No tienes que desplegar ni gestionar ningún servicio, obtienes un alto rendimiento y un panel de control con los registros. 

Tu panel de control de LlamaCloud registra todos los documentos que se han analizado. Puedes consultar el historial o solicitar y comparar el uso. 

Panel de control de Llama Cloud

Salpicadero de la Nube Llama. Imagen source: LlamaCloud 

Del mismo modo, también puedes comprobar el número de tokens que hemos utilizado para el modelo de incrustación y el número de solicitudes generadas. 

Panel de control de Mixedbread

Tablero de pan mixto. Fuente de la imagene: Mixedbread

Los registros más detallados de cada API se pueden encontrar en GroqCloud, con información sobre la latencia, el número de tokens, la clave AI y el ID de solicitud para que puedas depurar el sistema.

Registros de Groq Cloud

Registros de GroqCloud. Imagen tanurce: GroqCloud

Reflexiones finales

Esta guía nos enseñó a combinar varios servicios para crear una aplicación eficiente de preguntas y respuestas sobre documentos con un uso mínimo de recursos y una sobrecarga computacional. Todos los servicios y herramientas que hemos utilizado están disponibles gratuitamente para que pruebes y construyas tu propia aplicación.

Hemos reducido el tamaño de nuestra imagen Docker en 600 MB utilizando múltiples servicios de IA listos para usar. Si hubiéramos desplegado todo por nuestra cuenta, el tamaño de la imagen habría sido de unos 20 GB o más. 

Te recomiendo que tomes el curso LLMOps Concepts: From Ideation to Deployment curso como siguiente paso en tu viaje de aprendizaje. Este curso te ayudará a comprender mejor el ciclo de vida del desarrollo LLM y los retos que plantea el despliegue de aplicaciones. También te enseñará a aplicar estos conceptos con eficacia.

Desarrolla hoy tus habilidades MLOps

Empieza desde cero y adquiere habilidades MLOps para desarrollar tu carrera profesional.

Photo of Abid Ali Awan
Author
Abid Ali Awan
LinkedIn
Twitter

Soy un científico de datos certificado que disfruta creando aplicaciones de aprendizaje automático y escribiendo blogs sobre ciencia de datos. Actualmente me centro en la creación de contenidos, la edición y el trabajo con grandes modelos lingüísticos.

Temas

¡Aprende más sobre los LLM con estos cursos!

curso

Developing LLM Applications with LangChain

3 hr
11.2K
Discover how to build AI-powered applications using LLMs, prompts, chains, and agents in LangChain.
Ver detallesRight Arrow
Comienza El Curso
Ver másRight Arrow
Relacionado

blog

12 proyectos LLM para todos los niveles

Descubre 12 ideas de proyectos LLM con guías visuales fáciles de seguir y códigos fuente, adecuados para principiantes, estudiantes de nivel intermedio, estudiantes de último curso y expertos.
Abid Ali Awan's photo

Abid Ali Awan

12 min

tutorial

Tutorial sobre cómo crear aplicaciones LLM con LangChain

Explore el potencial sin explotar de los grandes modelos lingüísticos con LangChain, un marco Python de código abierto para crear aplicaciones avanzadas de IA.
Moez Ali's photo

Moez Ali

12 min

tutorial

RAG Con Llama 3.1 8B, Ollama y Langchain: Tutorial

Aprende a crear una aplicación RAG con Llama 3.1 8B utilizando Ollama y Langchain, configurando el entorno, procesando documentos, creando incrustaciones e integrando un recuperador.
Ryan Ong's photo

Ryan Ong

12 min

tutorial

Ajuste fino de LLaMA 2: Guía paso a paso para personalizar el modelo de lenguaje grande

Aprende a ajustar Llama-2 en Colab utilizando nuevas técnicas para superar las limitaciones de memoria y computación y hacer más accesibles los grandes modelos lingüísticos de código abierto.
Abid Ali Awan's photo

Abid Ali Awan

12 min

tutorial

Guía para principiantes de LlaMA-Factory WebUI: Ajuste de los LLM

Aprende a afinar los LLM en conjuntos de datos personalizados, evaluar el rendimiento y exportar y servir modelos sin problemas utilizando el marco de trabajo de bajo/ningún código de LLaMA-Factory.
Abid Ali Awan's photo

Abid Ali Awan

12 min

See MoreSee More