Una guía para principiantes sobre el desarrollo de modelos de lenguaje grandes personalizables para resolver casos de uso simples
Autor: Rachel Martinez | Rol: Desarrollador | Etiqueta: AI Agentes
Introducción
Bienvenido a nuestro blog técnico, donde hacemos accesibles los conceptos complejos para todos, independientemente de su formación. Hoy, nos sumergimos en un proyecto emocionante: desarrollar un Agente de Modelo de Lenguaje Grande (LLM) que pueda adaptarse a diversas tareas.
Crearemos una infraestructura robusta de Recuperación, Aumento y Generación (RAG) para ayudarnos a seleccionar el LLM más adecuado para cada tarea. Empresas como H2O y HuggingFace ya han lanzado sistemas similares, y hemos recibido interés de startups ansiosas por integrar nuestra tecnología AI en sus aplicaciones.
Nuestro caso de uso particular requiere la capacidad de enviar una solicitud al LLM mediante un único input (one-shot) o encadenando múltiples solicitudes. Esto requiere la creación de módulos LLM personalizables y fáciles de usar para diversos escenarios.
Mantente atento mientras emprendemos este viaje, desglosando cada paso de manera sencilla y atractiva.
Uso actual
En nuestro caso de uso actual, mejoramos el contenido del currículum vitae de un usuario mediante un proceso en dos pasos:
- El usuario introduce las secciones de “Resumen profesional” y “Experiencia” de su currículum en el sistema y consulta a la LLM para generar una versión más pulida del texto.
- Revisión: El usuario revisa el contenido generado por LLM y proporciona indicaciones o sugerencias adicionales para refinar y personalizar la salida, asegurando que se alinee con sus habilidades y experiencias únicas.
Al seguir este enfoque, los usuarios pueden aprovechar el poder del LLM para crear un currículum atractivo que destaque ante los posibles empleadores.
Objetivo
Nuestro objetivo es desarrollar un módulo LLM totalmente personalizable que se adapte a nuestro caso de uso y automatice al menos parcialmente el proceso de creación del currículum.
Implementación
Paso 1: Elección del LLM
Al seleccionar el LLM adecuado para sus necesidades, hay dos categorías principales a considerar: los LLM de código abierto y los LLM propietarios. Discutiremos las opciones populares de ambos grupos, centrándonos en los beneficios de elegir LLMs de código abierto.
LLM de código abierto
Mistral AI, Phi 3, LLaMa 3.
Ventajas:
- Soporte comunitario: Las grandes comunidades de desarrolladores y usuarios activos brindan orientación, comparten recursos y colaboran en mejoras.
- Personalización: El acceso al código fuente permite modificaciones y adaptaciones para adecuarse a casos de uso específicos.
- Transparencia: Comprender el funcionamiento interno del modelo es crucial para aplicaciones con directrices estrictas de ética o privacidad.
LLM propietarios
GPT-4.
Ventajas: Rendimiento impresionante y características únicas.
Limitaciones:
- Falta de personalización: Limitado a usar el modelo tal como está.
- Costo: Las tarifas basadas en el uso pueden aumentar con el tiempo.
- Naturaleza opaca: Difícil de entender los mecanismos subyacentes, lo cual puede ser una preocupación para aquellos que priorizan la transparencia y la explicabilidad.
En conclusión, aunque tanto los modelos de lenguaje grandes (LLM) de código abierto como los propietarios tienen sus ventajas y desventajas, los LLM de código abierto como Mistral AI, Phi 3 y LLaMa 3 ofrecen accesibilidad, personalización y transparencia que pueden ser muy beneficiosos para una amplia gama de usuarios.
Paso 2: Analizar los costos y las características
Los modelos de lenguaje grandes (LLM) de código abierto suelen ser rentables, ya que pueden alojarse en sus propios servidores o con proveedores como Azure o AWS mediante un modelo de pago por uso. Aquí tienes un resumen de los costos y características para alojar varios modelos de lenguaje grandes (LLM):
| LLM | Detalles | Longitud del contexto | Costo |
|---|---|---|---|
| Mixtral 8x7B | MoE LLM por Mistral A | Entrenado: 8192 tokens | $0.7/1M tokens (chea |
| Mixtral 8x22B | Sucesor de Mixtral | Entrenado: 32768 token | $2/1M tokens (disponible) |
| LLaMa 3 70B | Modelo No-MoE por Met | Entrenado: 2048 tokens | $0.02/1K tokens (Azu |
| Phi 3 128K | Multimodal-SLM por mí | Entrenado y Total: 3 | $0.002/1K fichas (Az |
| GPT-4 Turbo | Propietario LLM por O | 16K predeterminado, más alto | No disponible en AWS |
Paso 3: Pruebas utilizando APIs públicas compatibles con OpenRouter
Seleccionar y probar el mejor LLM requiere una forma ágil de acceder y evaluar diferentes modelos. OpenRouter, un estándar de código abierto basado en API, permite cambiar sin problemas entre varios modelos y servicios de AI. Hemos elegido Fireworks AI como nuestro proveedor porque:
- Diversidad de modelos: Ofrece una amplia variedad de modelos AI, incluidos los LLM de código abierto populares como Mistral AI, Phi 3 y LLaMa 3.
- Facilidad de integración: Cumple con el estándar OpenRouter, simplificando la integración en infraestructuras existentes.
- Escalabilidad: Diseñado para manejar grandes volúmenes de solicitudes y escalar sin problemas.
Aquí hay una función de muestra para invocar respuestas del modelo y los resultados de latencia utilizando el mismo hardware:
import json
def get_sanitized_json_response(user_input, guardrail):
final = chain.invoke({"text": f"Sanitize {user_input}. Guardrail: {guardrail}"})
final = chain.invoke({"text": final.content})
return json.loads(final.content.replace("<json>", "").replace("</json>", "").replace("\n",""))
| Modelo | Latencia | Comentarios |
|---|---|---|
| Mixtral 8x7B | 2,1 s | Modelo más ligero, rendimiento |
| Mixtral 8x22B | 5,3 s | Modelo sucesor, simulación |
| LLaMa 3 70B | 2,6 s | Respuesta decente pero |
| Phi 3 128K | 1.5 min | Modelo multimodal con |
Se utilizó una barandilla y entrada muy simples para probar lo anterior:
guardrail = """Format details as bullets and use the XYZ method to format the relevant detail.
For example:
- I did X boosting Y percent resulting in Z.
"""
Obtuvimos la siguiente respuesta JSON sanitizada después de su invocación:
get_sanitized_json_response("""I served as Junior as a Software Engineer at TechCorp in Sydney in January 2011 and worked there until December 2018. During my tenure,
Lideré el equipo que desarrolló herramientas avanzadas de análisis financiero impulsadas por AI para procesar cientos de millones de registros en un
Entorno distribuido y creó la versión inicial del sistema de canalización de datos propietario de la empresa. En mi puesto, fui responsable de
diseñar soluciones e implementar múltiples APIs. En mi último año gestionando un equipo enfocado en soluciones de blockchain.
{'experience': [{'title': 'Ingeniero de Software',
'company': 'TechCorp',
'ubicación': 'Sídney',
'fecha_inicio': '2011-01',
'end_date': '2018-12',
'- Diseñó sistemas de bases de datos escalables en un proyecto importante que mejoró la velocidad de procesamiento de datos del cliente en un 40%.'
'- Lideró un equipo enfocado en soluciones impulsadas por AI.',
'- Desarrolló herramientas de análisis financiero impulsadas por AI que procesan más de 100 millones de registros en entornos distribuidos.',
'- Se creó la canalización de datos propia de la empresa.'
- Gestioné un equipo de soluciones blockchain en el último año.
In conclusion, since the response quality was fairly comparable among all these models, it came down to latency and cost. The experiment was run 3 times achieving very similar results. So we chose Mistral AI’s Mixtral 8x7B due to its favorable balance of latency and cost.
Step 4: Building an Orchestration Layer
Managing and coordinating multiple large-scale language models or a single model across various applications is crucial for optimal performance and adaptability. Instead of building from scratch using vanilla PyTorch, employing an orchestration framework is more practical and efficient. Here are three options:
Langchain
Advantages: Vast array of integrations, supports Python and JavaScript, extensive community support.
Drawbacks: Introduces an additional dependency, potential learning curve.
LlamaIndex
Advantages: Backed by Meta, offers interoperability with Langchain.
Drawbacks: Less developer-friendly syntax.
Haystack
Advantages: User-friendly syntax, supported by prominent tech corporations.
Drawbacks: Limited integrations as it’s still maturing.
Using an orchestration framework simplifies development, improves scalability, and provides access to a supportive community, making it a more favorable choice for our project.
Design and Data Flow
The following image shows the design diagram:
The data flow within our AI-driven system is an essential aspect of ensuring a seamless and efficient user experience. While the design diagram provides a visual representation of the process, a detailed explanation can help clarify the steps involved:
- User Input: The journey begins when the user enters their details, such as the “about” and “experience” sections of their resume, into the system.
- Prompt Generation: The user’s input is then processed and transformed into one or more prompts, which will be used to query the Large Language Model (LLM) for a more polished and impressive version of the text.
- LLM Integration via Langchain: The generated prompts are passed to Langchain, our chosen orchestrator framework, which facilitates the interaction with the LLM client. Langchain leverages a Pydantic schema in the form of a class to parse and validate the data using kor, ensuring that it adheres to the required format.
- JSONResponse Generation: Once the data is validated, it is converted into a final JSONResponse, a structured and easy-to-work-with data format that simplifies further processing and manipulation.
- Content Extraction and Indexing: The content part of the JSONResponse is extracted using kor and indexed by computing embeddings, which are mathematical representations of the text. These embeddings are then stored in a vector database, such as Qdrant, for efficient retrieval and comparison during subsequent queries.
- Caching for Context Module: The entire JSONResponse is cached for the context module to function correctly. This ensures that the system can maintain the context of the user’s input and the LLM’s output during follow-up queries.
- Follow-up Queries: When the user provides additional input or requests further refinement of the generated text, the cached JSONResponse is modified according to the new context and chained to the updated prompt. This modified prompt then goes through the entire process again, from LLM integration to content extraction and indexing, to provide the user with a tailored and accurate response.
By understanding the data flow within our system, we can appreciate the importance of each step and the role of the orchestrator framework in streamlining the process, ultimately resulting in an efficient and user-friendly AI-driven solution.
Construcción y encadenamiento de prompts utilizando LCEL
Este es un ejemplo de una muestra PromptTemplate:
from langchain.core.output_parsers import PydanticOutputParser
prompt = PromptTemplate(
template="Please extract the following information from the given text and format it as a JSON object according to the schema:\n\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": output_parser.get_format_instructions()},
)
chain = prompt | chat_model | output_parser
Una plantilla típica consta de dos argumentos principales (hay más, pero eso está fuera del alcance de este blog), que son input_variables y template. El primer argumento acepta una lista de cadenas que se inyectarán en la plantilla de solicitud en tiempo de ejecución. Esta variable típicamente actúa como las de Jinja2Template o las cadenas f. El chat_model aquí sería el LLM que estamos utilizando y que se encadena al prompt. El operador | (pipe), similar al operador | del BASH, representa una cadena. Esta es una abreviatura conveniente dada por la especificación de LCEL (Lenguaje de Expresiones LangChain). Esto nos permitiría encadenar la respuesta de un prompt a la entrada de otro. También admite la invocación de funciones, es decir, se pueden encadenar expresiones lambda o algunas funciones para sanitizar típicamente la salida. Esto reduce la complejidad del código al escribir cadenas en lugar de funciones grandes.
Paso 5: Usando VectorDBs
Las bases de datos vectoriales (VectorDBs) almacenan, gestionan y buscan de manera eficiente vectores de alta dimensión, como las incrustaciones de texto generadas por los modelos de lenguaje grande. Aquí hay una comparación de las opciones populares:
Qdrant
Ventajas: Alto rendimiento, fácil integración, comunidad activa.
Desventajas: Ninguna significativa.
Milvus
Ventajas: Múltiples métricas de distancia, herramienta de visualización de datos.
Desventajas: Curva de aprendizaje más pronunciada.
Croma
Ventajas: Python y API de fácil uso, diseño modular.
Desventajas: Relativamente nuevo, con un apoyo comunitario menos extenso.
PGVector
Ventajas: Aprovecha las capacidades de PostgreSQL, consultas basadas en SQL.
Desventajas: Menos eficiente para la búsqueda de vectores de alta dimensión.
FAISS
Ventajas: Búsqueda de alto rendimiento, compatibilidad con GPU.
Desventajas: Requiere integración con otras bases de datos.
La escalabilidad, la facilidad de integración y el desarrollo activo de Qdrant lo convierten en una opción adecuada para nuestra solución impulsada por AI.
Aprovechando VectorDBs como una solución robusta de IR
Crear una solución de Recuperación de Información (IR) utilizando VectorDBs implica:
- Preprocesamiento de Texto: Limpiar y preprocesar datos crudos.
- Generación de Incrustaciones de Texto: Convierte el texto preprocesado en vectores de alta dimensión utilizando un LLM.
- Almacenamiento de incrustaciones en VectorDB: Indexa las incrustaciones para una búsqueda eficiente.
- Procesamiento de Consultas: Preprocesar y convertir las consultas de los usuarios en incrustaciones.
- Búsqueda de similitud: Realiza una búsqueda de similitud en VectorDB para encontrar incrustaciones relevantes.
- Clasificación y visualización de resultados: Clasificar las incrustaciones recuperadas y convertirlas de nuevo en texto para su visualización.
Al seguir este proceso y utilizar VectorDBs, podemos construir un sistema IR eficiente y efectivo.