Mostrando entradas con la etiqueta BBDD. Mostrar todas las entradas
Mostrando entradas con la etiqueta BBDD. Mostrar todas las entradas

miércoles, mayo 22, 2024

El amo de los datos

Ayer tuve una jornada interesante de transformación digital en Londres. Hablando de datos, ML, GenAI, arquitecturas RAG, y normalización de datos. Cosas habituales hoy en día en cualquier empresa. En uno de esos momentos en los que estaba escuchando, sobre casos de uso que que se iban a crear usando ML, el debate acabó una vez en los datos. El Catálogo, el Data-Fabric, el Data WharehouseData Curation, la validación de la ingesta, los Data Streams, etcétera. Cosas habituales en la vida de la digitalización de empresas.

Figura 1: El amo de los datos

Para mí, eso fue el día a día cuando en al año 2016 tuve la responsabilidad de ser el Chief Data Officer de Telefónica y tuve que tomar muchas, muchas, muchas decisiones sobre estos temas que, a día de hoy que soy el Chief Digital Officer, siguen perdurando en nuestro trabajo diario. 

Estando en ese debate, mi cabeza viajo temporalmente a mis inicios con los datos. Cuando bajaba la calle Barcelona de Móstoles, pasaba por delante del Eco Móstoles, y me metía en un pequeño parque a medio terminar que se encontraba y se encuentra a espaldas de calle Libertad de Móstoles. Allí estaba uno de los locales de la Academia RUS de la que os he hablado muchas veces. Tendría yo 14 o 15 años e iba a mi clase de Informática diaria. A seguir aprendiendo a programar.

En aquellos años ya había dejado el BASIC y el Logo atrás, y estaba con con COBOL, SQL y MS/DOS. También tocaría aprender DBASE, C y Pascal, pero antes de ellos, mi paso era hacer códigos con la IDENTIFICATION DIVISION y la PROCEDURE DIVISON. Había que aprender a identar el código, usar muchas mayúsculas, y ser muy disciplinado en la forma de hacer programas con este lenguaje llamado COBOL.

Las clases a las que asistía de informática se multiplicaban en mi agenda, normalmente hacía tres cursos a la semana diferente, haciendo clases los lunes y miércoles, y los martes y jueves, y repitiendo algunas de 17:30 a 18:30 y de 18:30 a 19:30, y luego había algunos cursos que se daban los viernes y sábados. De los 12 a los 16 años fueron años en los que mi afición era programar, así que no me importaba pasarme dos horas cada día en la academia, e incluso quedarme los viernes y sábado. ¿Qué podría haber más divertido que eso? Además, de vez en cuando daba yo la clase, y me llevaba de maravilla con Bea, mi profesora muchos de esos años.

Nada de lo que aprendí en aquellos años fue en vano. Todo ese aprendizaje sigue en mí, cambiado, adaptado, y mejorado, pero como base sobre la que construí mucho de mi conocimiento futuro. Y ayer me acordé de la época de COBOL y el acceso a Datos para hacer cosas. En aquellos momentos, cuando pasé de BASIC a COBOL, entré en el mundo de las reglas de estilo y la programación estructurada con técnicas de diseño de software muy metódicas. Formas de hacer las cosas de manera industrial. El trabajo de programador como factoría de software. Dados unos requisitos, escribir código como si fueras una máquina tú.

Los programas de gestión, hechos con COBOL y datos almacenados en bases de datos o ficheros tenían siempre las mismas estructuras. Y todos mis primeros Menús eran siempre ALTAS, BAJAS, MODIFICACIONES y CONSULTAS. Tendía que definir las fuentes de datos, los tipos de datos que iba a utilizar, si eran ficheros, los accesos que serían Secuenciales (si eran en cinta), acceso aleatorio (si eran en cintas modernas con aceleración de rebobinado y avanzado) o de acceso directo (si el almacenamiento era en disco). O los tipos de datos que se iban a leer de las bases de datos, en forma de registros que había que procesar,  pintar por pantalla en listados, etcétera.

La programación era una ingeniería. Las cosas tenía una forma de hacerse. Había metodologías de desarrollo de software. Hablábamos de los modelos de solucionar cada uno de los problemas. Y teníamos guías de estilo de programación, nombres de variables, llamadas a procedimientos, factorización del software, etcétera, para hacerlo mantenible, aduitable, y permitir que cualquier código fuera tocado por cualquier programador de COBOL. Me encantaba saber que era una pieza de parte de una industria de desarrollo de software. Podría ser programador o mi sueño entonces, ser "Analista", para poder asignar las tareas a los programadores siguiendo las guías de desarrollo del software de una empresa. 

Podéis imaginaros lo que un niño de 14 o 15 años sentía cuando se veía ahí. Siento un analista de software. Metiendo líneas de código y jugando con los decimales como Richard Prior en Superman III, desde tu terminal. Identando tu código. Flipante.

Y os cuento todo esto, porque de aquella época también aprendi parte de la gestión de los datos que décadas después usé como Chief Data Officer en Telefónica. Y es que, allí, en aquellos años, me explicaron cómo la Banca creaba sus aplicaciones para preservar sus datos. Cómo los informáticos habían creado para COBOL una metodología de trabajo con datos basada en mantener el core más sagrado de la empresa, LOS DATOS, a salvo de malos programadores. Metiendo una capa de seguridad, metiendo una capa de protección. 

Y yo escuchaba atento. ¿Cuál sería el truco? ¿Cómo lo han hecho? ¿Cuál es el secreto?

No había mucha magia. O sí. Según se mire. 

Lo habían hecho otros informáticos que llegaron a interesarme tanto o más que los Analistas, se trataba de tipos más duros aún. Que tenían más poder porque protegían el activo más valioso de las empresas. De la poderosa industria bancaria. Los datos, que al final de día era dinero. Se trataba de los Administradores de Bases de Datos.

¡¡Buaahhh!

¡Qué pasada!

Resulta que había unos tipos que para que los Analista de Programación pudieran diseñar sus programas de ALTAS, BAJAS, MODIFICACIONES y CONSULTAS, con sus infinitos listados por pantalla y por impresora (no conté yo espacios ni nada para cuadrar listados en papel continuo de impresoras matriciales), estos Analistas tenían que hablar con los Administradores de Bases de Datos para que les disponibilizaran los datos que necesitaban utilizar para sus programas. Y ellos decidían cómo lo hacían.

Esto, tenía su ciencia. Porque no iban a dejar que cualquier Programador tocara cualquier dato, así que se dedicaban a crear VISTAS, VISTAS para Actualización de datos, y Tablas de solo lectura que disponibilizaban a los Analistas para que hicieran su aplicación de ABMyC sobre estas fuentes de datos. Los Analistas repartían las tareas a los Programadores, y la Factoría de Software de la empresa seguía produciendo sistemas de información para la empresa.

Si habéis leído esto, sabréis porque cuando llegué a la Universidad me centré en aprender todas las asignaturas de Bases de Datos. A aprender a hacer el diseño lógico y el diseño físico de las bases de datos. A aprender cómo funcionaban los Tablespaces, las p-codes de las consultas de bases de datos, a descubrir los detalles de las formas normales de Boyce-Codd, a aprender PL/SQL, T-SQL, hacer optimización de bases de datos y aplicaciones, etcétera. El resto, ya os lo sabéis, trabajé mucho con las bases de datos Oracle cuando salí de la Universidad, luego llegó el SQL Injection... y el resto es historia moderna, desarrollando mi perfil profesional en datos y hacking.

Pero ayer volví a ello una vez más, porque el debate nos llevaba a cómo preservar los datos y disponibilizarlos a los modelos. Hoy hablamos de Data Streams, de Gestores de Consentimientos para acceso a datos, de políticas y procedimientos de anonimización y pseudoanonimización, de consultas con algoritmos de cifrado homomórfico, de roles de seguridad, de las plantillas de cumplimiento regulativo, etcétera. 

Entonces, el Administrador de la Base de Datos era el "amo de los datos" y de todo eso. Y yo lo aprendí en una academia de barrio de Móstoles. Leyendo libros y deseando un día poder ser parte de esa Industria y la Ingeniería del Software. Flipante.  

¡Saludos Malignos!

Autor: Chema Alonso (Contactar con Chema Alonso)  


viernes, mayo 19, 2023

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.

Entrada destacada

+300 referencias a papers, posts y talks de Hacking & Security con Inteligencia Artificial

Hace un mes comencé a recuperar en un post mi interés en los últimos años, donde he publicado muchos artículos en este blog , y he dejado mu...

Entradas populares