¿Qué es un embedding?
- Un "embedding" consiste en convertir contenido en un "arreglo de números de punto flotante"
- La clave de este arreglo es que, sin importar la "longitud del contenido", el "tamaño del arreglo" siempre es el mismo
- El tamaño del arreglo lo determina el modelo de embeddings que se use: 300, 1000, 1536, etc.
- La mejor forma de pensar en este arreglo es imaginarlo como las "coordenadas en un espacio multidimensional muy extraño"
- ¿Por qué colocar contenido en un espacio multidimensional? Porque puedes aprender cosas interesantes sobre ese contenido a partir de su posición, en especial del otro contenido que está cerca
- La posición en ese espacio representa el "significado semántico (Semantic Meaning)" del contenido, según la "extraña y en su mayor parte incomprensible comprensión del mundo" que tenga el modelo de embeddings
- El contenido embebido puede capturar color, forma, conceptos u otras clases de características
- Nadie entiende por completo qué significa cada uno de esos números individuales, pero sí sabemos que su posición puede usarse para encontrar información útil sobre el contenido
Encontrar contenido relacionado usando embeddings
- El primer problema que resolví con embeddings fue crear una función de "Related Content" para mi blog TIL
- Usé el modelo
text-embedding-ada-002 de OpenAI. Se puede usar vía API
- Ahora mismo mi sitio tiene 472 artículos, y para cada uno calculé un vector de embedding de 1536 dimensiones (un arreglo de números de punto flotante), y almacené ese vector en la base de datos SQLite de mi sitio
- Ahora, para encontrar artículos relacionados con uno específico, basta con calcular la similitud coseno (Cosine Similarity) entre el vector de embedding de ese artículo y los demás artículos en la base de datos, y luego devolver las 10 coincidencias más cercanas por distancia
- El código Python que usé para la similitud coseno es este
def cosine_similarity(a, b):
dot_product = sum(x * y for x, y in zip(a, b))
magnitude_a = sum(x * x for x in a) ** 0.5
magnitude_b = sum(x * x for x in b) ** 0.5
return dot_product / (magnitude_a * magnitude_b)
- La API de embeddings de OpenAI es muy barata y fácil de usar
- Embebí alrededor de 400 mil tokens de mi sitio web TIL, y a $0.0001 por cada mil tokens, todo costó apenas $0.04
- Solo haces un
POST con el texto junto con tu API key, y te devuelve un JSON Array de números de punto flotante
- Pero este es un modelo propietario, y hace unos meses OpenAI incluso retiró algunos de sus modelos de embeddings
- Eso significa que si almacenaste una gran cantidad de embeddings de ese modelo, tendrás que recalcularlos para el modelo nuevo
- OpenAI dijo que compensaría el costo de re-embebido para migrar al nuevo modelo, pero hay que tener cuidado con los modelos propietarios
- Esto puede evitarse usando modelos con licencias abiertas y potentes
Entender cómo funciona esto en los modelos Word2Vec
- Hace 10 años, Google Research publicó un influyente paper que describía un modelo temprano de embeddings llamado Word2Vec
- Se publicó en 2013 con el título "Efficient Estimation of Word Representations in Vector Space" y despertó el interés por los embeddings
- Word2Vec es un modelo que toma una sola palabra y la convierte en una lista de 300 números. Esa lista captura información sobre el significado de palabras relacionadas
- Si buscas una palabra, puedes encontrar palabras similares según la distancia coseno con la representación Word2Vec de esa palabra
- Si buscas "france", puedes obtener valores como "french: 0.70007~", "belgium: 0.69331~", "paris: 0.63349~", "germany: 0.62707~"
- Es una mezcla de lo francés y de la geografía europea
- Lo realmente interesante que puedes hacer aquí es realizar operaciones aritméticas con esos vectores
- Si al vector de "germany" le sumas "paris" y le restas "france", el vector resultante queda más cerca de "berlin"
- Este modelo capturó ideas sobre nacionalidad y geografía, de modo que se pueden explorar hechos adicionales del mundo usando aritmética sobre ciertas cosas
- Word2Vec fue entrenado con contenido de 1.6 mil millones de palabras, y los modelos de embeddings que usamos hoy se entrenan con conjuntos de datos muchísimo mayores, capturando una comprensión mucho más rica de las relaciones subyacentes
Calcular embeddings y buscar con mis herramientas
- Estoy creando una CLI y librería de Python llamada LLM
- Se puede usar como una CLI para interactuar con LLMs, y también permite integración con OpenAPI
- Hace unos meses también añadí a esa herramienta, mediante plugins, la capacidad de ejecutar modelos de embeddings (se puede usar la librería SentenceTransformers)
- Puedes elegir una colección de embeddings y hacer búsquedas semánticas "Vibes-based" para encontrar cosas similares
- También estoy creando una herramienta llamada Symbex para encontrar símbolos en un codebase de Python. Con ella es posible calcular embeddings de funciones del código y construir un motor de búsqueda de código
- (Se omiten los detalles de implementación)
Embebiendo texto e imágenes juntos con CLIP
- Mi modelo de embeddings favorito en este momento es CLIP
- Es un modelo lanzado por OpenAI en enero de 2021 que puede embedir tanto "texto como imágenes", y ambos quedan en el mismo espacio vectorial
- Si insertas "dog", obtienes una posición en un espacio de 512 dimensiones (depende de la configuración de CLIP)
- Si embebes una foto de un perro, obtienes una posición en ese mismo espacio, y estará cerca en distancia de la posición de la cadena "dog"
- Es decir, puedes buscar imágenes relacionadas usando texto, o buscar texto relacionado usando imágenes
- Si metes una foto de una playa, puedes obtener puntajes de similitud como "beach: 26.946%", "city: 19.839%", "sunshine: 24.146%"
Encontrar grifos con CLIP
- Drew Breunig construyó un motor de búsqueda de grifos con el plugin
llm-clip
- Tomó 20 mil fotos de grifos y ejecutó CLIP sobre ellas
- Luego pudo encontrar grifos parecidos a otros grifos, y entre ellos localizar opciones similares pero más baratas
Responder preguntas con RAG
- La última pregunta de todos los que han probado ChatGPT es siempre la misma
"¿Cómo hago para que responda sobre mis notas o los documentos de nuestra empresa?"
- La gente asume que eso significa entrenar un modelo personalizado con ese contenido, a un costo enorme, pero
- En realidad no hace falta. Se puede hacer con LLM y RAG (Retrieval Augmented Generation)
- La idea central es que "el usuario hace una pregunta"
- Luego buscas en tus documentos personales lo que sea relevante para esa pregunta
- Tomas extractos de ese contenido y los metes en el LLM junto con la pregunta original
- Entonces el LLM puede responder la pregunta basándose en el contenido adicional que le proporcionaste
- Este truco barato funciona sorprendentemente bien
- Pero no es tan fácil lograr que funcione bien incluso la versión básica de este enfoque
- Tienes que hacer que funcione lo mejor posible considerando el conjunto infinito de preguntas que los usuarios podrían hacer
- El principal problema de RAG es determinar cuáles son los mejores extractos de contenido para incluir en el prompt que se enviará al LLM
- La búsqueda semántica "Vibes-based" impulsada por embeddings es la capacidad necesaria para reunir contenido muy relevante que pueda ayudar a responder la pregunta del usuario
- Construí y publiqué una versión para "el contenido de mi blog"
- Como resultado, fue posible hacer RAG con un script de Bash de una sola línea
5 comentarios
Vi este artículo y lo probé el fin de semana. Intenté usar un modelo en coreano, pero como no fue fácil configurar el entorno, usé ada v2 y en total gasté 0.03 dólares. Si eres un usuario nuevo que no ha usado chatgpt, con los 5 dólares de crédito gratis te alcanza de sobra para probarlo jaja.
También calculé y comparé la similitud coseno, y los resultados me parecieron razonables. Gracias por compartir el artículo.
Creo que voy a intentar seguirlo este fin de semana.
¡Gracias~
Creo que ya lo entiendo, aunque sea un poco.
Gracias.
Aprendí mucho sobre aspectos que normalmente me daban curiosidad pero que no entendía bien. Muchas gracias, como siempre, por el excelente contenido.