×
Community Blog El inicio de la revolución de la IA: un viaje con RAG y LangChain

El inicio de la revolución de la IA: un viaje con RAG y LangChain

En este artículo, se presenta una investigación detallada sobre el proceso de la revolución de la IA generativa y una mirada profunda sobre los concep...

En la era de la inteligencia artificial (IA), la extracción de información significativa de grandes bases de datos tomó mayor importancia para las empresas y los individuos. Aquí es cuando entra en juego la generación aumentada por recuperación (RAG), un descubrimiento que aceleró al máximo las capacidades de la IA y potenció los sistemas para que generen textos de calidad humana y obtengan información en tiempo real. Esta fusión genera respuestas contextualmente completas y detalladamente precisas.

Al comenzar nuestra travesía en el mundo de la inteligencia artificial (IA), es importante comprender los tres ejes que nos guiarán: la IA generativa, los modelos de lenguaje grande (LLM), LangChain, Hugging Face y la aplicación útil en esta RAG (generación aumentada por recuperación)

Los modelos de lenguaje grande y la IA generativa: los motores de la innovación

El centro de nuestra travesía son los modelos de lenguaje grande (LLM) y la IA generativa, dos motores poderosos que potencian la innovación.

Modelos de lenguaje grande (LLM)

1

Los LLM, como Qwen, GPT, entre otros, son los titanes del texto, capaces de entender y generar lenguaje de calidad humana y a escala masiva. Estos modelos se entrenaron con una enorme cantidad de datos textuales, lo que les permite predecir y producir cadenas textuales coherentes y contextualmente relevantes. Son el pilar fundamental de varias tareas de procesamiento de lenguaje natural, como la traducción y la creación de contenido.

IA generativa (GenAI)

La IA generativa es el gran hechicero de la creación dentro del reino de la IA. Abarca las tecnologías que generan instancias de datos nuevas que se asemejan a los datos de entrenamiento, como las imágenes, la música y, en especial dentro de nuestro viaje, el texto. En este contexto, la IA generativa representa la habilidad de la IA para generar respuestas, historias o ideas nuevas, cargadas de información y que nunca antes se hayan visto. No solo le permite a la IA imitar el pasado, sino también inventar, innovar e inspirar.

LangChain: la orquesta de la sinfonía de IA

2

LangChain es el arquitecto del flujo de trabajo de IA, el cual diseña meticulosamente la estructura que permite la integración y la interacción fluida entre varios componentes de IA. Este esquema simplifica los procesos complejos de encadenamiento de flujos de datos de subsistemas inteligentes, incluidos los LLM y los sistemas de recuperación. Esto genera que las tareas como la extracción de la información y la comprensión del lenguaje natural sean más accesibles que nunca.

Hugging Face: La metrópolis de modelos de IA

3

Hugging Face es una metrópolis bulliciosa en la que prosperan los modelos de IA. Este centro ofrece una gran variedad de modelos entrenados previamente, los cuales representan una gran oportunidad para la investigación y la aplicación del machine learning. Para poder acceder a este centro y a sus recursos, debe crearse una cuenta de Hugging Face. Luego de crearla, se le abrirán las puertas al extenso mundo de la IA. Visite Hugging Face y regístrese para iniciar la aventura.

RAG: aprovechar las bases de datos vectoriales para la inteligencia acelerada

4

La generación aumentada por recuperación (RAG) es una técnica de IA sofisticada que une el poder inventivo de la IA generativa y la precisión de la recuperación de información, lo que crea un sistema articulado y completamente informado. Integra bases de datos vectoriales, una herramienta potente para filtrar, de manera rápida, grandes repositorios de información, para acceder a todo potencial y a la eficiencia de RAG. Aquí se presenta un análisis mejorado sobre cómo RAG opera con bases de datos vectoriales:

  1. Recuperación con bases de datos vectoriales: El proceso de RAG comienza con una consulta a una base de datos vectorial, en la cual se almacenan representaciones incrustadas de grandes conjuntos de información. Estas incrustaciones son vectores de alta dimensión que capturan la esencia semántica de los documentos y los fragmentos de datos. Las bases de datos vectoriales le permiten a RAG realizar búsquedas ultra rápidas entre estas incrustaciones para identificar el contenido más relevante según las consultas, similar a una navegación fluida de una IA a través de una librería digital para encontrar el libro correcto.
  2. Aumento con el contexto: La información relevante recuperada de las bases de datos vectoriales se brinda a un modelo generativo como aumento contextual. En este paso, se le brinda a la IA una dosis concentrada de conocimiento, lo que mejora su capacidad para generar respuestas creativas, contextualmente completas y precisas.
  3. Generación de respuestas informadas: Luego de recibir este contexto, el modelo generativo genera el texto. A diferencia de los modelos generativos estándar, que se basan únicamente en patrones aprendidos, RAG unifica los detalles de los datos recuperados, lo que resulta en productos imaginativos y fundamentadas por la información recuperada. La generación se eleva y produce respuestas que son más que precisas, informativas y que reflejan un contexto verdadero.

La integración de las bases de datos vectoriales es de suma importancia para la eficiencia de RAG. Los métodos tradicionales de búsqueda de metadatos pueden ser lentos y poco precisos, pero las bases de datos vectoriales facilitan la recuperación casi instantánea de información contextualmente relevante, incluso de conjunto de datos extremadamente grandes. Este enfoque ahorra tiempo valioso y asegura que las respuestas de la IA se basen en la información disponible más apropiada y actualizada.

La destreza de RAG es especialmente ventajosa en aplicaciones como los chatbots, los asistentes digitales, las herramientas de investigación sofisticadas y en cualquier otra aplicación en la que la precisión de entrega, la fiabilidad y la información basada en el contexto es de suma importancia. No solo se trata de elaborar ideas que parezcan convincentes, sino también de generar contenido que se base en datos verificados y en información del mundo real.

Gracias a la comprensión enriquecida de LangChain, Hugging Face, los LLM, la IA generativa y la RAG mejorada para las bases de datos vectoriales, estamos por comenzar una aventura de codificación que hará posible estas tecnologías. El script de Python en el que nos adentraremos representa la sinergia de estos elementos y demuestra un sistema de IA capaz que puede responder con creatividad, contexto y una gran comprensión que solo se creía que existía en la ciencia ficción. Prepárese para codificar y experimentar el poder transformador de RAG con bases de datos vectoriales.

El comienzo del proceso de codificación

Antes de comenzar: lo esencial

Antes de comenzar este viaje tecnológico, asegurémonos de que cuente con todos los requisitos:

  • Un servidor Linux, mejor si tiene una tarjeta GPU; la velocidad es esencial, tenemos que aceptarlo.
  • Python 3.6 o superior; la varita mágica de la programación.
  • pip o Anaconda; los administradores de paquetes más prácticos.
  • si tiene una tarjeta GPU, entonces utilice los controladores NVIDIA, el kit CUDA y cuDNN; la santísima trinidad de la aceleración de GPU

¿Tiene todo? ¡Maravilloso! Pongamos las manos en la masa (de manera figurada, por supuesto).

Ejecución del código

Al administrar de manera cuidadosa las dependencias de Python, se asegura de que el proyecto de IA se cree sobre una base estable y fiable. Al tener las dependencias en su lugar y con el entorno configurado de manera correcta, está listo para ejecutar el script y ser testigo del poder de RAG y LangChain en acción.

Ahora, puede ejecutar el script de Python para ver a RAG en acción.

Configuración del escenario: la importación de las bibliotecas y la carga de las variables

Antes de iniciar nuestro descubrimiento de la IA con el esquema de LangChain y la librería de transformadores de Hugging Face, es de suma importancia que se establezca un entorno seguro y bien configurado. Esta preparación implica la importación de las bibliotecas necesarias y la administración de información confidencial, como las claves de API con variables de entorno.

from torch import cuda
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_community.embeddings.huggingface import HuggingFaceEmbeddings
from transformers import AutoModelForCausalLM, AutoTokenizer
from langchain_community.llms.huggingface_pipeline import HuggingFacePipeline
from transformers import pipeline
from dotenv import load_dotenv

load_dotenv()

A veces, cuando se trabaja con modelos de IA de Hugging Face, se necesita acceder a la API de Hugging Face, la cual requiere una clave de API. Esta clave es un identificador único para realizar solicitudes a los servicios de Hugging Face y que le permite cargar y utilizar los modelos en las aplicaciones.

Esto es lo que se necesita hacer para configurar, de manera segura, el entorno:

  1. Obtener una clave de API de Hugging Face: Luego de crear la cuenta de Hugging Face, puede encontrar la clave de API en la configuración de la cuenta en la sección “Tokens de acceso”.
  2. Asegurar la clave de API: La clave de API es información confidencial y debe mantenerse privada. En lugar de codificarlo en los scripts, debería utilizar variables de entorno.
  3. Crear un archivo .env: Cree un archivo con el nombre .env. Este archivo almacenará las variables del entorno.
  4. Agregar la clave de API al archivo .env: Abra el archivo .env con un editor de textos y agregue la clave de API de Hugging Face con el siguiente formato:
HUGGINGFACE_API_KEY=la_clave_de_api_aquí

Reemplace “la_clave_de_api_aquí” con la clave de API real que consiguió en Hugging Face.

Definición de la ruta y la configuración del modelo

modelPath = "sentence-transformers/all-mpnet-base-v2"
device = 'cuda' if cuda.is_available() else 'cpu'
model_kwargs = {'device': device}

Aquí, se establece el camino al modelo entrenado previamente que se utilizará para las incrustaciones. También, configuramos los ajustes del dispositivo con una GPU, si está disponible, para una computación más rápida, o, de lo contrario, por defecto a la CPU.

Inicialización de las encrustaciones de Hugging Face y la tienda de vectores de FAISS

embeddings = HuggingFaceEmbeddings(
    model_name=modelPath,
    model_kwargs=model_kwargs,
)

# Información inventada; solo por diversión, pero quién sabe en un futurovectorstore = FAISS.from_texts(
    ["Harrison trabajó en Alibaba Cloud"], embedding=embeddings
)

retriever = vectorstore.as_retriever()

Inicializamos una instancia de “HuggingFaceEmbeddings” con el modelo y la configuración que elegimos. Luego, creamos una “vectorstore” con FAISS, la cual nos permitirá realizar búsquedas eficientes de similitudes en espacios de alta dimensión. También, instanciamos un recuperador que buscará la información según las incrustaciones.

Configuración de la plantilla de prompts del chat

template = """Answer the question based only on the following context:
{context}
Question: {question}
"""

prompt = ChatPromptTemplate.from_template(template)

Aquí, definimos una plantilla de prompts de chat que se utilizará para estructurar la interacción con la IA. Incluye marcadores de posición para el contexto y una pregunta, que se rellenará dinámicamente durante la ejecución de la cadena.

Preparación del tokenizador y del modelo de lenguaje

En el mundo del procesamiento del lenguaje natural y de la IA, el tokenizador y el modelo de lenguaje son el dúo dinámico que convierte el texto en una acción concreta. El tokenizador descompone el lenguaje en piezas que el modelo puede entender, mientras que el modelo de lenguaje predice y genera el lenguaje según estas entradas. En nuestro viaje, utilizaremos las clases “AutoTokenizer” y “AutoModelForCausalLM” para aprovechar estas capacidades. Es importante recordar que, al momento de elegir un modelo de lenguaje, un solo tamaño no siempre es suficiente.

El tamaño del modelo y los recursos computacionales

El tamaño del modelo es un factor crítico que se debe considerar. Los modelos más grandes como Qwen-72B tienen más parámetros, lo que generalmente significa que pueden comprender y generar textos más cargados de información. Sin embargo, también requieren más potencia computacional. Si cuenta con un GPU de alta gama y la memora suficiente, puede elegir estos modelos más grandes para aprovechar al máximo sus capacidades.

Por otro lado, los modelos más pequeños, como Qwen1.8B, son más administrables para los entornos de computación estándar. Incluso este modelo pequeño debería poder ejecutarse en dispositivos móviles y de IoT. Si bien es posible que no capturen las complejidades del lenguaje tan bien como las contrapartes más grandes, ofrecen un rendimiento excelente y son más accesibles para quienes no poseen un hardware especializado.

Modelos específicos para una tarea

Otro punto que se debe considerar es la naturaleza de la tarea. Utilizar un modelo específico para un chat, como Qwen-7B-Chat, al momento de crear una IA conversacional puede generar resultados mejores, ya que estos modelos están configurados para los diálogos y pueden administrar la carga de información en las conversaciones mejor que los modelos base.

Costo de inferencia

Los modelos más grandes no solo requieren más hardware, sino que también pueden incurrir en costos elevados si se utilizan servicios basados en la nube para ejecutar los modelos. Cada inferencia ocupa tiempo y recursos de procesamiento, lo cual puede agravarse al trabajar con modelos masivos.

La serie Qwen

  • Qwen-1.8B: Este es un modelo más pequeño, ideal para las tareas que requieren menos potencia computacional. Es bueno para crear prototipos y ejecutarse en máquinas sin GPU potentes.
  • Qwen-7B: Este es un modelo mediano que equilibra el rendimiento con las demandas computacionales. Es ideal para varias tareas, como la generación de textos y la respuesta a preguntas.
  • Qwen-14B: Este es un modelo más grande que puede administrar tareas más complejas con una mayor carga de información para la comprensión y la generación de lenguaje.
  • Qwen-72B: Este es el modelo más grande de la serie y ofrece un rendimiento de última generación para las aplicaciones de IA avanzadas que requieren una comprensión profunda del lenguaje.
  • Qwen-1.8B-Chat: Este es un modelo conversacional diseñado específicamente para construir chatbots y otros sistemas de diálogo.
  • Qwen-7B-Chat: Este es similar a Qwen-1.8B-Chat, pero con una capacidad aumentada para la administración de diálogos más complejos.
  • Qwen-14B-Chat: Este es un modelo conversacional de alto nivel capaz de generar interacciones sofisticadas de diálogo.
  • Qwen-72B-Chat: Este es el modelo conversacional más avanzado de la serie Qwen, el cual ofrece un rendimiento excepcional para las aplicaciones de chat exigentes.

La elección

Al momento de elegir un modelo, compare los beneficios de los modelos más grandes con los recursos disponibles y los requisitos específicos del proyecto. Si recién empieza o si desarrolla en pequeña escala, la mejor opción es un modelo más pequeño. A medida que las necesidades aumenten o si necesita capacidades más avanzadas, puede migrar a un modelo más grande.

Recuerde que la serie Qwen es de código abierto, por lo que puede experimentar con los diferentes modelos para ver cuál es el que mejor se adapta al proyecto. Si decide utilizar un modelo distinto, la sección del script para la selección del modelo se vería así:

# Puede cambiarse a cualquiera de los modelos Qwen según las necesidades y los recursos
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen-7B", trust_remote_code=True)
model_name_or_path = "Qwen/Qwen-7B"
model = AutoModelForCausalLM.from_pretrained(model_name_or_path,
                                             device_map="auto",
                                             trust_remote_code=True)

Con la clase “AutoTokenizer” cargamos un tokenizador y con “AutoModelForCausalLM, un modelo de lenguaje causal. Estos componentes son importantes para el procesamiento de las entradas de lenguaje natural y la generación de salidas.

Creación de la canalización para la generación de textos

La canalización está diseñada para generar textos con un modelo de lenguaje y un tokenizador cargado previamente. Desglosemos los parámetros y comprendamos los roles al momento de controlar el comportamiento de la generación de textos:

pipe = pipeline(
    "text-generation",
    model=model,
    tokenizer=tokenizer,
    max_new_tokens=8192,
    do_sample=True,
    temperature=0.7,
    top_p=0.95,
    top_k=40,
    repetition_penalty=1.1
)

hf = HuggingFacePipeline(pipeline=pipe)

Explicación de los parámetros en la canalización para la generación de textos:

  • max_new_tokens (8192): Este parámetro especifica el número máximo de tokens que se pueden generar en la salida. Los tokens pueden ser palabras, caracteres o subpalabras, según el tokenizador.
  • do_sample (True): Cuando se establece en “True”, el parámetro habilita el muestreo probabilístico de la distribución de los posibles tokens siguientes generados por el modelo. Esto introduce aleatoriedad y variedad al texto generado. Si se establece en “False”, el modelo siempre elegirá el token siguiente más probable, lo que generará salidas deterministas y menos variadas.
  • temperature (0.7): El parámetro de la temperatura controla la cantidad de aleatoriedad que se introduce al proceso de muestreo. Un valor de temperatura más bajo (cerca de 0) hace que el modelo realice elecciones más seguras, lo que resulta en menos salidas aleatorias, mientras que una temperatura más alta (cerca de 1), fomenta la aleatoriedad y la diversidad.
  • top_p (0.95): Este parámetro controla el muestreo de núcleos, una técnica que solo considera los tokens más probables con una probabilidad cumulativa por encima del umbral top_p. Esto ayuda con la generación de textos que sean diversos y coherentes, lo que evita la inclusión de tokens de muy baja probabilidad que podrían alterar el sentido del texto.
  • top_k (40): El muestreo top-k limita el grupo de muestreo de los tokens k siguientes más probables. Esto refina incluso más el conjunto de tokens que el modelo considerará para la generación del siguiente pedazo de texto, lo que asegura que las salidas se mantengan relevantes y coherentes.
  • repetition_penalty (1.1): Este parámetro desalienta al modelo a repetir los mismos tokens o frases, lo que fomenta textos más interesantes y variados. Un valor más alto que 1 penaliza y reduce la probabilidad de tokens que ya se hayan utilizado.

Luego de configurar la canalización según los parámetros deseados, utilizaremos está línea de código:

hf = HuggingFacePipeline(pipeline=pipe)

Con esta línea, el objeto se envuelve en un HuggingFacePipeline. Esta clase forma parte del marco de LangChain y permite que la canalización se integre sin problemas en el flujo de trabajo de LangChain para crear aplicaciones de IA. Al envolver la canalización, podemos utilizarla en conjunto con otros componentes de LangChain, como los recuperadores y los analizadores, para crear sistemas de IA más complejos.

La selección cuidadosa de estos parámetros permite ajustar el comportamiento de la generación de textos para satisfacer las necesidades de la aplicación, ya sea si busca salidas más creativas y variadas o si quiere generar un texto que sea coherente y enfocado.

Construcción y ejecución de la cadena de RAG

El siguiente fragmento de código representa un sistema RAG completo e integral en la que la pregunta inicial comienza una búsqueda de información relevante, la cual se utiliza para aumentar el proceso de generación y genera una respuesta completa y contextualmente relevante para la pregunta de entrada.

1.  Construcción de la cadena:

chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | hf
    | StrOutputParser()
)

Esto es lo que le sucede a esta parte del código:

  • Se utiliza un recuperador para buscar la información relevante según la consulta. El rol del recuperador es buscar entre un conjunto de datos o de documentos para encontrar fragmentos de información que sean los más pertinentes según la pregunta que se hizo. Esto es posible gracias a la utilización de una base de datos vectorial para la eficiencia.
  • RunnablePassthrough() es un componente que simplemente pasa la pregunta sin ninguna modificación. Esto sugiere que la cadena está diseñada para administrar la pregunta de manera directa, probablemente de la forma en que fue ingresada por el usuario.
  • El prompt no se muestra en detalle, pero probablemente funcione como una plantilla o un conjunto de instrucciones que le brinden un formato a la pregunta de entrada y al contexto recuperado de manera tal que se adecúen a la siguiente fase en la canalización, la cual es el modelo de Hugging Face.
  • La variable hf representa la canalización de Hugging Face, la cual se presume que es un modelo de lenguaje entrenado previamente capaz de generar respuestas. Esta canalización tomará la entrada con formato de la fase anterior y utilizará las capacidades generativas para generar una respuesta.
  • StrOutputParser() es un analizador de salidas cuyo trabajo es utilizar la salida en bruto de la canalización de Hugging Face y analizarla hasta convertirla en un formato más fácil de utilizar, posiblemente una cadena.

La utilización del operador | (pipe) sugiere que este código utiliza un estilo de programación funcional, en especial el concepto de composición de funciones o un patrón de canalización en la que la salida de una función se convierte en la entrada de la siguiente.

2.  Invocación de la cadena:

results = chain.invoke(“¿Dónde trabajaba Harrison?”)

En esta línea, se le invoca a la cadena una pregunta específica: “¿Dónde trabajaba Harrison?” Esta invocación desencadena la secuencia completa de operaciones definidas en la cadena. El recuperador busca la información relevante, la cual se pasa junto con la pregunta, en primer lugar, a través del prompt y, luego, al modelo de Hugging Face. El modelo genera una respuesta basada en las entradas que recibe.

3.  Resultados de impresión:

print(results)

StrOutputParser() analiza la respuesta generada y es devuelta como el resultado final, el cual luego se imprime en la consola o en otra salida.

Finalmente, construimos la cadena RAG al conectar el recuperador, la plantilla del prompt, la canalización de Hugging Face y el analizador de la salida. Invocamos la cadena con nuestra pregunta y se imprime el resultado.

6

Conclusión: la puerta de entrada al dominio de la IA

Acaba de adentrarse al mundo de la IA con RAG y LangChain. Al comprender y ejecutar este código, desbloquea el potencial para crear sistemas inteligentes que puedan razonar e interactuar con información de formas nunca antes vistas.


Este artículo fue escrito originalmente en inglés. Puede ver el artículo original aquí.

0 0 0
Share on

Regional Content Hub

82 posts | 3 followers

You may also like

Comments