Langchain 101: Modelos

Langchain 101: Modelos

En este tutorial te brindaré una visión general sobre los diferentes tipos de modelos que se utilizan en Langchain

Introducción

Esta sección de la documentación trata de los diferentes tipos de modelos que se utilizan en LangChain. En esta página repasaremos los tipos de modelos en un nivel alto, pero tendremos artículos e hilos en Twitter individuales para cada tipo de modelo.

Uno de los principales valores de LangChain es que proporciona una interfaz estándar para los modelos. Esto permite intercambiar fácilmente entre modelos. A alto nivel, hay dos tipos principales de modelos:

  • Modelos lingüísticos: buenos para la generación de texto

  • Modelos de incrustación de texto: buenos para convertir texto en una representación numérica.



Modelos lingüísticos

Existen dos subtipos diferentes de modelos lingüísticos:

  • LLMs: envuelven APIs que reciben y devuelven texto.

  • ChatModels: modelos que reciben mensajes de chat y devuelven un mensaje de chat.

Se trata de una diferencia sutil, pero un valor añadido de LangChain es que proporciona una interfaz unificada para todos ellos. Esto es bueno porque, aunque las API subyacentes son en realidad muy diferentes, a menudo se desea utilizarlas indistintamente.

Para ver esto, echemos un vistazo a OpenAI (un wrapper del LLM de OpenAI) vs ChatOpenAI (un wrapper alrededor del ChatModel de OpenAI).

from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
llm = OpenAI()
chat_model = ChatOpenAI()

text -> text interfaz

llm.predict("say hi!")
'\n\nHi there!'
chat_model.predict("say hi!")
'Hello there!'

messages -> message interfaz

from langchain.schema import HumanMessage

llm.predict_messages([HumanMessage(content="say hi!")])

AIMessage(content='\n\nHello! Nice to meet you!', additional_kwargs={}, example=False)

chat_model.predict_messages([HumanMessage(content="say hi!")])

AIMessage(content='Hello! How can I assist you today?', additional_kwargs={}, example=False)

LLMs

Los grandes modelos lingüísticos (LLM) son un componente central de LangChain. LangChain no es un proveedor de LLMs, sino que proporciona una interfaz estándar a través de la cual se puede interactuar con una variedad de LLMs.

Cómo empezar

En este artículo y en su respectivo cuaderno explicamos cómo utilizar la clase LLM en LangChain.

La clase LLM es una clase diseñada para interactuar con LLMs. Hay un montón de proveedores LLM (OpenAI, Cohere, Hugging Face, etc) - esta clase está diseñada para proporcionar una interfaz estándar para todos ellos. En esta parte de la documentación, nos centraremos en la funcionalidad genérica de los LLM.

Para este cuaderno, trabajaremos con un wrapper LLM de OpenAI, aunque las funcionalidades destacadas son genéricas para todos los tipos de LLM.

from langchain.llms import OpenAI

llm = OpenAI(model_name="text-ada-001", n=2, best_of=2)

Generar texto: La funcionalidad más básica de un LLM es sólo la capacidad de llamarlo, pasando una cadena y obteniendo de vuelta una cadena.

llm("Tell me a joke")

'\n\nWhy did the chicken cross the road?\n\nTo get to the other side.'

Generar: En términos más generales, puedes llamarlo con una lista de inputs, obteniendo de vuelta una respuesta más completa que sólo el texto. Esta respuesta completa incluye cosas como múltiples respuestas principales, así como información específica del proveedor de LLM.

llm_result = llm.generate(["Tell me a joke", "Tell me a poem"]*15)

len(llm_result.generations)

30

llm_result.generations[0]

[Generation(text='\n\nWhy did the chicken cross the road?\n\nTo get to the other side!'),
 Generation(text='\n\nWhy did the chicken cross the road?\n\nTo get to the other side.')]

llm_result.generations[-1]

[Generation(text="\n\nWhat if love neverspeech\n\nWhat if love never ended\n\nWhat if love was only a feeling\n\nI'll never know this love\n\nIt's not a feeling\n\nBut it's what we have for each other\n\nWe just know that love is something strong\n\nAnd we can't help but be happy\n\nWe just feel what love is for us\n\nAnd we love each other with all our heart\n\nWe just don't know how\n\nHow it will go\n\nBut we know that love is something strong\n\nAnd we'll always have each other\n\nIn our lives."),
 Generation(text='\n\nOnce upon a time\n\nThere was a love so pure and true\n\nIt lasted for centuries\n\nAnd never became stale or dry\n\nIt was moving and alive\n\nAnd the heart of the love-ick\n\nIs still beating strong and true.')]

También puede acceder a la información específica del proveedor que se devuelve. Esta información NO está estandarizada entre proveedores.

llm_result.llm_output

{'token_usage': {'completion_tokens': 3903,
  'total_tokens': 4023,
  'prompt_tokens': 120}}

Número de tokens: También puedes estimar cuántos tokens tendrá un trozo de texto en ese modelo. Esto es útil porque los modelos tienen una longitud de contexto (y cuestan más por más tokens), lo que significa que necesitas ser consciente de lo largo que es el texto que estás pasando.

Ten en cuenta que, por defecto, los tokens se estiman utilizando tiktoken (excepto para la versión heredada <3.8, donde se utiliza un tokenizador Hugging Face)

llm.get_num_tokens("what a joke")
3

Funcionalidad general

Todos los ejemplos aquí expuestos abordan ciertas guías "prácticas" para trabajar con LLM

Todas las guías aquí mencionadas son en inglés, de la documentación oficial de Langchain.

Si veo apoyo en el contenido y ⭐ el repo de Github iré trayendo "How To's" en castellano

Integraciones

Los ejemplos que aquí se presentan son guías prácticas sobre cómo integrarse con distintos proveedores de LLM.

Todas las guías aquí mencionadas son en inglés, de la documentación oficial de Langchain.

https://python.langchain.com/en/latest/modules/models/llms/integrations.html



Chat Models

Los modelos de chat son una variación de los modelos lingüísticos. Aunque los modelos de chat utilizan modelos de lenguaje, la interfaz que exponen es un poco diferente. En lugar de exponer una API de "entrada de texto, salida de texto", exponen una interfaz en la que los "mensajes de chat" son las entradas y salidas.

Las API de los modelos de chat son bastante nuevas, por lo que aún estamos tratando de encontrar las abstracciones correctas.

Cómo empezar

En este artículo y en su respectivo cuaderno explicamo cómo empezar con los modelos de chat. La interfaz se basa en mensajes y no en texto sin formato.

from langchain.chat_models import ChatOpenAI
from langchain import PromptTemplate, LLMChain
from langchain.prompts.chat import (
    ChatPromptTemplate,
    SystemMessagePromptTemplate,
    AIMessagePromptTemplate,
    HumanMessagePromptTemplate,
)
from langchain.schema import (
    AIMessage,
    HumanMessage,
    SystemMessage
)
chat = ChatOpenAI(temperature=0)

Puedes obtener finalizaciones de chat pasando uno o más mensajes al modelo de chat. La respuesta será un mensaje. Los tipos de mensajes actualmente soportados en LangChain son AIMessage, HumanMessage, SystemMessage, y ChatMessage - ChatMessage toma un parámetro de rol arbitrario. La mayoría de las veces, sólo tendrás que tratar con HumanMessage, AIMessage y SystemMessage.

chat([HumanMessage(content="Translate this sentence from English to French. I love programming.")])

AIMessage(content="J'aime programmer.", additional_kwargs={})

El modelo de chat de OpenAI soporta múltiples mensajes como input. Ver aquí para más información. He aquí un ejemplo de envío de un mensaje de sistema y de usuario al modelo de chat:

messages = [
    SystemMessage(content="You are a helpful assistant that translates English to French."),
    HumanMessage(content="I love programming.")
]
chat(messages)

AIMessage(content="J'aime programmer.", additional_kwargs={})

Puedes ir un paso más allá y generar terminaciones para múltiples conjuntos de mensajes utilizando generate. Esto devuelve un LLMResult con un parámetro de message adicional.

batch_messages = [
    [
        SystemMessage(content="You are a helpful assistant that translates English to French."),
        HumanMessage(content="I love programming.")
    ],
    [
        SystemMessage(content="You are a helpful assistant that translates English to French."),
        HumanMessage(content="I love artificial intelligence.")
    ],
]
result = chat.generate(batch_messages)
result
LLMResult(generations=[[ChatGeneration(text="J'aime programmer.", generation_info=None, message=AIMessage(content="J'aime programmer.", additional_kwargs={}))], [ChatGeneration(text="J'aime l'intelligence artificielle.", generation_info=None, message=AIMessage(content="J'aime l'intelligence artificielle.", additional_kwargs={}))]], llm_output={'token_usage': {'prompt_tokens': 57, 'completion_tokens': 20, 'total_tokens': 77}})

PromptTemplates

Puedes hacer uso de las plantillas utilizando un MessagePromptTemplate. Puedes construir un ChatPromptTemplate a partir de uno o más MessagePromptTemplates. Puedes utilizar el format_prompt de ChatPromptTemplate - esto devuelve un PromptValue, que puede convertir en una cadena o en un objeto Message, dependiendo de si desea utilizar el valor formateado como entrada a un modelo llm o chat.

Para mayor comodidad, existe un método from_template expuesto en la plantilla. Si utilizas esta plantilla, esto es lo que parecería:

template="You are a helpful assistant that translates {input_language} to {output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template="{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])

# obten una finalización de chat a partir de los mensajes formateados
chat(chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages())
AIMessage(content="J'adore la programmation.", additional_kwargs={})

Si quisieras construir el MessagePromptTemplate más directamente, podrías crear un PromptTemplate fuera y luego pasarlo, ej:

prompt=PromptTemplate(
    template="You are a helpful assistant that translates {input_language} to {output_language}.",
    input_variables=["input_language", "output_language"],
)
system_message_prompt = SystemMessagePromptTemplate(prompt=prompt)

LLMChain

Puede utilizar la LLMChain existente de una forma muy similar a la anterior: proporcione un indicador y un modelo.

chain = LLMChain(llm=chat, prompt=chat_prompt)
chain.run(input_language="English", output_language="French", text="I love programming.")
"J'adore la programmation."

Streaming

ChatOpenAI soporta streaming a través del manejo de callbacks.

from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
chat = ChatOpenAI(streaming=True, callbacks=[StreamingStdOutCallbackHandler()], temperature=0)
resp = chat([HumanMessage(content="Write me a song about sparkling water.")])
Verse 1:
Bubbles rising to the top
A refreshing drink that never stops
Clear and crisp, it's pure delight
A taste that's sure to excite

Chorus:
Sparkling water, oh so fine
A drink that's always on my mind
With every sip, I feel alive
Sparkling water, you're my vibe

Verse 2:
No sugar, no calories, just pure bliss
A drink that's hard to resist
It's the perfect way to quench my thirst
A drink that always comes first

Chorus:
Sparkling water, oh so fine
A drink that's always on my mind
With every sip, I feel alive
Sparkling water, you're my vibe

Bridge:
From the mountains to the sea
Sparkling water, you're the key
To a healthy life, a happy soul
A drink that makes me feel whole

Chorus:
Sparkling water, oh so fine
A drink that's always on my mind
With every sip, I feel alive
Sparkling water, you're my vibe

Outro:
Sparkling water, you're the one
A drink that's always so much fun
I'll never let you go, my friend
Sparkling

Guías prácticas

Todos los ejemplos aquí expuestos abordan ciertas guías "prácticas" para trabajar con modelos de chat

Todas las guías aquí mencionadas son en inglés, de la documentación oficial de Langchain.

Si veo apoyo en el contenido y ⭐ el repo de Github iré trayendo "How To's" en castellano

Integraciones

Todos estos ejemplos muestran cómo integrarse con distintos modelos de chat.

Modelos de incrustación de texto (Text Embedding Models)

Esta parte de la documentación oficial explica cómo utilizar la clase Embedding en LangChain.

La clase Embedding es una clase diseñada para interactuar con embeddings. Hay muchos proveedores de Embedding (OpenAI, Cohere, Hugging Face, etc) - esta clase está diseñada para proporcionar una interfaz estándar para todos ellos.

Las incrustaciones crean una representación vectorial de un fragmento de texto. Esto es útil porque significa que podemos pensar en el texto en el espacio vectorial, y hacer cosas como la búsqueda semántica donde buscamos piezas de texto que son más similares en el espacio vectorial.

La clase base Embedding en LangChain expone dos métodos: embed_documents y embed_query. La mayor diferencia es que estos dos métodos tienen interfaces diferentes: uno trabaja sobre múltiples documentos, mientras que el otro trabaja sobre un único documento. Además de esto, otra razón para tenerlos como dos métodos separados es que algunos proveedores de incrustación tienen diferentes métodos de incrustación para documentos (para ser buscados) vs consultas (la consulta de búsqueda en sí).

Existen las siguientes integraciones para incrustaciones de texto.

Recursos adicionales


Soy Samu Sarmiento, embajador de thirdweb y desarrollador de software. Mi experiencia incluye trabajar con TypeScript y frameworks populares como React, Next.js y Node.js, así como construir aplicaciones Web 3.0 usando thirdweb.

A Junio de 2023, llevo aproximadamente tres meses investigando el mundo de la inteligencia artificial, machine learning, deep learning, modelos de lenguaje, agentes autónomos.... Y de ahí nacen estas guías/tutoriales ;)

En los próximos días y semanas estaré trayendoles en mi Newsletter más notícias, actualizaciones, nuevos agentes o frameworks. Nuevos casos de uso. Y sobretodo muchos tutoriales y guías prácticas para que no pierdas mucho tiempo investigando y puedas poner en marcha tus ideas rápidamente.

Espero que les guste y la disfruten. Todo feedback es más que bienvenido, contacta conmigo en Twitter directamente ( @SamuSarmiento_ ).


¡Y eso es todo por hoy! Espero que hayas adquirido una comprensión superficial de las capacidades de LangChain. Si quieres seguir leyendo guías y tutoriales como este o el anterior, estar al día sobre AI, AGI, LLMs y productos potenciados por IA:

  1. Sígueme en Twitter

  2. Suscríbete a mi Newsletter para no perderte las últimas noticias sobre Agentes autónomos, LLMs y productos potenciados por IA.

  3. ⭐ el repo de Github mientras tanto para recibir actualizaciones.