Seguridad

Bases de datos vectoriales potenciando la Inteligencia Artificial

En Ideas Locas desarrollamos para el Equinox de marzo un prototipo de búsqueda semántica, Summify.ai, en donde teníamos almacenadas las transcripciones de diferentes programas de «La Resistencia» del gran David Broncano, y mediante Inteligencia Artificial, con un modelo de lenguaje, podíamos hacer una pregunta sobre algo relacionado con uno de los programas y esta IA se “leía” la transcripción y nos generaba la respuesta deseada. ¿Pero cómo sabía el modelo de lenguaje qué programa de La Resistencia tenía que leerse para poder generar una respuesta acorde a la pregunta realizada?
Figura 1: Bases de datos vectoriales potenciando la Inteligencia Artificial

En realidad, no almacenábamos únicamente las transcripciones de estos programas, sino también sus embeddings, una codificación del conocimiento de manera numérica. De esta manera, cuando hacíamos una query, computábamos el embedding de esta query y lo comparábamos con los embeddings almacenados, los correspondientes a las transcripciones de cada programa. Aquella comparación que diese mayor valor significaba que habíamos encontrado un programa de La Resistencia que estaba muy relacionado con la pregunta que hicimos.



Figura 2: Para veas qué es un Equinox tienes el de Autumn 2015

Lo que desarrollamos fue un prototipo y no teníamos almacenados demasiados embeddings, pero si se hiciera algo parecido donde se tuviese que comparar el embedding de nuestra query con miles o millones de embeddings, el proceso de búsqueda sería lento. Es por esto por lo que existen las llamadas bases de datos vectoriales, que indexan y almacenan estos embeddings para poder realizar este tipo de búsqueda más rápido. Un mercado que está en auge, donde recientemente varias soluciones dedicadas a esto han levantado millones de dólares, como Weaviate, Pinecone, o Chroma.

En este artículo vamos a ver en primer lugar en qué consisten los embeddings, sin los cuales nada de esto podría ser posible, para posteriormente ver diferentes técnicas de indexación que existen para recuperar información más rápido.

La magia de los embeddings


Cuando entrenas una red neuronal, esta necesita ser alimentada con datos para comprender todo lo que está viendo y saber realizar la tarea que le pidamos. Por ejemplo, si queremos entrenar una red para detectar deepfakes en imágenes, necesitamos enseñarle a estas imágenes tanto de personas reales como de personas generadas con algunas técnicas de Inteligencia Artificial. O si queremos crear ChatGPT, se necesita enseñarle una cantidad muy extensa de textos para que pueda aprender la estructura del lenguaje (qué significa cada palabra, cómo utilizarlas para crear frases estructuralmente correctas…).

Cuando la red ha terminado su aprendizaje, se podría decir que “almacena” una especie de diccionario interno, y es capaz de traducir o codificar lo que sea que reciba en una lista de números. Por hacer una analogía, es como si actuara como el diccionario de la RAE, donde explicara lo que significa cada palabra, solo que, en vez de expresar su significado en texto, lo que hace es codificarlo en una lista de números.

   
Esta lista de números es lo que se conoce como embedding. En concreto, es una lista o vector de un número determinado de dimensiones, y en cada dimensión hay un número decimal. La clave es que cada una de estas dimensiones quiere significar algo. Por ejemplo, una de ellas podría significar algo “humano”, entonces las palabras “rey” y “reina” tendrían un número similar en esa dimensión, ya que ambas representan algo humano. Y si otras de las dimensiones fuese la representación de “género”, entonces estas dos palabras mencionadas tendrían ya un valor distinto al no tener el mismo género. En la realidad, puede haber hasta miles de dimensiones que se encargan de codificar los significados de las palabras y las relaciones entre ellas.


Búsqueda semántica


Como he dicho al principio, una red neuronal se puede entrenar para diversas tareas, ya sea por ejemplo trabajando con texto como ChatGPT, o por ejemplo trabajando con imágenes como un detector de deepfakes, que es un buen ejemplo de cómo aplicar IA/ML a Ciberseguridad. Como siempre que se entrena una red esta aprende esta especie de diccionario interno que he comentado al principio, esto significa que será capaz de crear embeddings para cualquier tipo de datos que reciba, siempre y cuando haya sido entrenada con este.


Figura 4: Libro de Machine Learning aplicado a Ciberseguridad de
Carmen TorranoFran Ramírez, Paloma Recuero, José Torres y Santiago Hernández.

Esto quiere decir que podemos expresar, entre otras cosas, textos (palabras, frases, párrafos…), imágenes, vídeos, documentos (como por ejemplo PDF, en realidad codificando el contenido textual de este) o audios en vectores de números (embeddings), pero con significado. Es decir, por ejemplo, si obtenemos los embeddings de una gran cantidad de imágenes, aquellas que contengan animales tendrán vector de números más similar que si las comparamos con imágenes de edificios, ya que se trata de otro concepto.

Y como podemos ver, todos los tipos de datos que he comentado son datos no estructurados. De esta manera, ahora tenemos una manera mucho más inteligente de generar y almacenar conocimiento sobre este tipo de datos, donde sin el uso de embeddings se necesitaría de algún etiquetado manual para intentar generar algo de conocimiento en ellos que nos sirvieran posteriormente para recuperar información cuando fuese necesario.

Como he comentado al principio del artículo, cuando en Ideas Locas desarrollamos Summify.ai para el Equinox, no almacenábamos solamente las transcripciones como tal, sino también los embeddings de estas. De esta manera, cuando en la aplicación queríamos obtener la respuesta a la consulta “¿Qué le gusta a Jhay Cortez?”, esta misma consulta se transformaba en embedding, y se comparaba con los embeddings que teníamos almacenados en base de datos, correspondientes a cada programa de La Resistencia que habíamos guardado.

Entonces, la comparación que devolviera el mayor valor quería decir que habíamos encontrado un programa de La Resistencia donde se hablaba sobre algo relacionado con nuestra consulta (la forma más común de computar cómo de similares son dos embeddings es haciendo uso de la similitud coseno). Siguiendo con el ejemplo, concretamente habríamos encontrado y recuperado la información del programa donde acudió Jhay Cortez como invitado, ya que en la consulta hicimos una pregunta relacionada con un tema que se trata en este programa en específico, y este conocimiento está codificado en el embedding de alguna manera.

Esta aplicación que desarrollamos era un prototipo, hecho con pocos ejemplos. Pero si se tuviera que desarrollar algo parecido, donde esta vez se almacenaran miles o millones de embeddings, sería un proceso muy lento ir calculando cómo de similar es el embedding de nuestra consulta con cada uno de los miles o millones de embeddings almacenados, por ello, lo que se está haciendo últimamente es desarrollar estrategias de búsqueda mediante indexaciones para hacer búsquedas más efectivas.

Estrategias de indexación


Hay gran investigación en este campo, y cada vez van saliendo nuevas formas de indexado para facilitar las búsquedas. Algunos algoritmos conocidos son los siguientes:

  • Inverted File Index (IVF): en este algoritmo cada embedding es asignado a su centroide más cercano. Podríamos decir que el centroide (que se calcula con algoritmos de clusterización) es como el “representante” de un determinado conjunto de embeddings, y existen varios centroides que van agrupando diferentes embeddings según sus similitudes. Entonces, cuando hacemos una query, lo que se hace primero es determinar el centroide más cercano al embedding de la query, y una vez lo sabemos ya solo tenemos que calcular la similitud con los embeddings que están representados por este centroide.
  • Cuantificación: esta técnica consiste en la reducción de la precisión de cada número decimal que conforma el embedding, reduciendo el tamaño de la base de datos y mejorando la velocidad en los cálculos de similitud entre embeddings.
  • Hierarchical Navigable Small Worlds (HNSW): en este algoritmo se crea un grafo de múltiples capas, donde en las capas superiores se tienen las llamadas conexiones largas (embeddings que guardan menos similitud entre sí), mientras que si vamos disminuyendo en capas se van teniendo conexiones más cortas, es decir, un mayor número de embeddings y con mayor similitud entre ellos.
Para el proceso de búsqueda, empezamos en la primera capa, y vamos recorriendo los vértices (embeddings) de esta mediante una greedy search, empezando desde un vértice de comienzo (entry point). Mientras estamos en un vértice, se calcula la similitud de este embedding con el de la query, y luego calculamos la similitud entre el embedding de la query y los de los vértices conectados al vértice en el que estamos. 
 
Si encontramos un vértice que presenta una similitud mayor con nuestra query que la que presenta el vértice en el que estamos, seguimos el proceso moviéndonos a ese vértice. Si ya no encontramos ningún otro vértice que tenga mayor similitud con el embedding de la query, bajamos a la siguiente capa y seguimos el mismo proceso, esta vez empezando como entry point en el vértice en el que estábamos en la capa anterior. De esta manera, cuando lleguemos a la última capa, el resultado final si seguimos este proceso será ya el embedding más similar al de nuestra query.
  • Approximate Nearest Neighbors Oh Yeah (ANNOY): este es un algoritmo popularizado por Spotify para su sistema de recomendación musical, el cual consiste en de manera iterativa ir separando el conjunto de embeddings en dos, de manera recursiva, hasta que cada conjunto tiene k elementos (normalmente unos 100 elementos).


Al final, en su esencia la indexación se comportará como un árbol binario, que tiene registrados las separaciones del espacio que se han ido haciendo, teniendo por ejemplo en las ramas “izquierda” los puntos debajo de la línea que separaba el espacio en ese momento, mientras que en las ramas “derecha” se tienen los puntos por encima. Como el proceso de separación del espacio es iterativo, el árbol tendrá una determinada profundidad, aunque cada vez cuando nos movamos a la izquierda o a la derecha habrá menos puntos representados.

El proceso de búsqueda es sencillo: dado el embedding de una query, recorremos el árbol creado y vamos cayendo por sus diferentes ramas hasta llegar a una zona del plano que tiene, siguiendo el ejemplo, 100 embeddings, y es solo con estos 100 embeddings con los que compararíamos la similitud con el embedding de nuestra query hasta determinar cuál es el más similar. En vez de computar la similitud con todos los puntos del espacio (miles o millones de embeddings), acabamos haciéndolo solo con 100 puntos, mejorando drásticamente la velocidad de la búsqueda.

Conclusiones

En este artículo hemos visto cómo la indexación de embeddings puede mejorar las búsquedas semánticas, el cual para mí es uno de los grandes usos que tienen los modelos de lenguaje. Ya lo tenemos con Microsoft Bing, y recientemente Google ya está preparando la incorporación de su modelo de lenguaje, Bard, para poder hacer este tipo de búsquedas, encontrándose en fase de experimentación.

Pero también, las bases de datos vectoriales tienen gran uso en otros casos como motores de recomendación o búsquedas por similitud (como insertar una imagen, un vídeo, un audio o un texto para recuperar contenido similar). En general, para el desarrollo de grandes aplicaciones que hagan uso de IA, sobre todo de modelos de lenguaje, las bases de datos vectoriales permitirán el desarrollo de sistemas rápidos y más eficaces.

Un saludo,
Autor: Javier del Pino Díaz, del equipo de Ideas Locas.

Powered by WPeMatico

Gustavo Genez

Informático de corazón y apasionado por la tecnología. La misión de este blog es llegar a los usuarios y profesionales con información y trucos acerca de la Seguridad Informática.