Inteligencia Artificial (IA) local

Antes de que andes preguntando a tu dios; sí, veras como ejecutar tu IA en local, sin internet.

La inteligencia artificial (IA) es una evolución de los buscadores y algoritmos. La IA trata de simular el mismo funcionamiento que nuestro cerebro; a una entrada de información, la red neuronal se reconfigura internamente para producir la salida correcta (por ejemplo; si recibe como entrada una foto de un perro, la salida tiene que ser identificar a ese ser vivo como un perro, o más características).

La finalidad es que luego de haber entrenado a la IA con datos específicos (llamado; ‘dataset’), su red neuronal producirá una salida específica y que luego cuando entra información nueva, y desconocida, pueda identificar patrones para detectar relaciones para hacer asociaciones nuevas (tal y como hace nuestro cerebro). Por ejemplo; si hemos entrenado a la IA para detectar perros, y luego de forma más especializada razas concretas, cuando le demos una foto de un lobo podrá detectar las similitudes y decirnos que un perro (a pesar de que no es tan así, pero sí están emperentados biológicamente).

La IA se puede entrenar para cualquier información que se pueda pasar como digital; y hoy en día es cualquier cosa.

Para entender y detectar relaciones tenemos dos búsquedas principales;

  1. La búsqueda vertical es la más simple e intuitiva de todas; insertas una palabra y se busca todo lo que la tenga dentro de unas bases de datos. Mientras que la búsqueda horizontal, hace lo mismo que la vertical pero incluyendo la información de búsquedas anteriores, luego corre algoritmos que las analizan y hacen predicciones.

  2. La búsqueda horizontal es lo que permite que la IA pueda recordar el contexto de una conversación; si estás hablando sobre la bacteria Vibrio Cholerae (que produce la cólera) analizando los síntomas y su medio de actuación, y luego preguntas algo sobre perros o gatos, la IA tommará eso en cuenta para realizar una nueva búsqueda que se aproxime a ese contexto ya dado anteriormente.

NOTA IMPORTANTE
La mayoria de los frameworks que ejecutan IAs, modelos o entrenamientos en GPU lo hacen necesitando CUDA (que es exclusivo de GPUs NVIDIA) y algunos pocos tienen soporte para ROCm (que es exclusivo de GPUs AMD)

Neuronas

Las neuronas son funciones matemáticas que a una entrada le aplican una multiplicación por el conjunto pesos (parámetros) y le suma un sesgo (bias) y pasar ese nuevo resultado a la siguiente neurona.

Como tal, cada peso y sesgo deben guardar su valor en un lugar, en los lenguajes de programación es en las variables. Y como tal pueden ser mutables o inmutables al momento de ser liberado el modelo al público, generalmente suelen ser inmutables para que la gente no los modifique.

Las variables tienen valores máximos que pueden almacenar según cuantos bits se estén usando para almacenar en memoria el dato. Por eso mismo, generalmente para que los modelos de IA tengan una muy buena precisión se usan variables F32 (float 32 bits) y es por ese motivo que cuando las mismas son muy pesadas para ser ejecutadas en una computadora sin mucha potencia, se puede realizar el proceso de ‘quantización’ el cual baja el tipo de dato de la variable a uno más liviano (como INT8 o INT4, véase entero de 8 o 4 bits) pero a costa de perder precisión en las respuestas y asociaciones. Existen procesos para quantificar; bitsandbytes, EETQ, etc. Mayormente todos necesitan obligatoriamente una GPU para hacer el proceso.

A F32 le decimos “full precision”, a F16 “half precision” y a INT8 “integer representation”. Mayormente todos los procesos de quantificación solo llegan hasta INT8, salvo algunos como “bitsandbytes” que logra llegar hasta INT4.

Existen las llamadas ‘bitnets’ las cuales son redes neuronales en donde las variables tienen solamente 1 bit de almacenamiento (-1, 0 ó 1). Desde 2022 (cuando empecé a escribir este libro), hasta el momento en que estoy escribiendo estas líneas (enero 2025), no paro de ver cada unos pocos meses algún avance nuevo en bitnets con una eficiencia tan alta que pueden ejecutarse en un CPU Intel Pentium 2 con 128mb de RAM y pesando solamente 1,5 GB, u otras con un rendimiento tal alto que sobrepasan a otras con variables FLOAT32.

A nivel de quantización tenemos que considerar el siguiente punto;

  • BF16 y FP16

    Aunque tanto BF16 como FP16 requieren 2 bytes por parámetro, los requisitos de memoria del entrenamiento con BF16 son realmente menores que los del entrenamiento con FP16. Debido a la baja precisión de BF16, los gradientes en el entrenamiento BF16 se almacenan directamente en FP32 y, en consecuencia, no requieren una copia extra.

    BF16 no requiere escalado de pérdidas a diferencia de FP16 y puede conducir a una mayor precisión. Además dado que BF16 es básicamente los 2 primeros bytes del número FP32, convertir entre BF16 y FP32 es tan fácil como descartar los 2 últimos bytes del número FP32 y copiar el número BF16 en los 2 primeros bytes de la posición de almacenamiento del número FP32.

    En cambio, la conversión entre FP16 y FP32 requiere más lógica debido al diferente tamaño de la mantisa.

    Además, en el entrenamiento de precisión mixta FP16, los gradientes se construyen en FP16, y luego se convierten a FP32 para la actualización de los parámetros. Este paso no es necesario en el entrenamiento BF16 porque los gradientes se almacenan directamente en FP32.

    Por último, el número de operaciones por iteración se reduce un poco porque ya no es necesario escalar gradientes/pérdidas.

Tipos de redes neuronales

Al tipo de red neuronal se le llama; modelo y hay varios tipos:

  1. Artificial Neural Network (ANN)

    Una red neuronal artificial es lo que estamos viendo, una representación informática de un cerebro biolóǵico.

  2. Convolutional Neural Network (CNN)

    Una red neuronal artificial convolucional o CNN (Convolutional Neural Network) es un tipo de red neuronal especialmente diseñada para procesar y analizar datos con estructura de grilla, como imágenes. Las CNN son populares en tareas de visión por computadora, como la clasificación de imágenes, el reconocimiento de objetos, la detección de rostros y el procesamiento de texto y voz.

    Las CNN se inspiran en cómo el cerebro humano procesa la información visual, simulando la forma en que las neuronas responden a estímulos en la corteza visual. En una CNN, se utilizan capas de convolución para reducir la complejidad y la dimensión de los datos, manteniendo al mismo tiempo las características más importantes. Esto permite que el modelo reconozca patrones visuales complejos sin procesar cada píxel individual.

    Una CNN recibe una imagen como entrada y pasa esa imagen a través de una serie de capas convolucionales, cada una con sus propios filtros que capturan características visuales progresivamente más abstractas. Al inicio, las primeras capas tienden a identificar bordes o patrones simples, mientras que las capas más profundas capturan estructuras más complejas, como partes de objetos o caras completas. Finalmente, la capa completamente conectada (o capas) interpreta estas características y produce la salida final, que suele ser la predicción de la red.

  3. Modelado predictivo

    Este tipo de modelos se basan en la estadistica de su entrenamiento para identificar patrones y predecir las siguientes acciones o valores. Es muy parecido a lo que hace el cerebro humano para aprender de la experiencia y predecir que tan probable es que pase algo en el futuro.

    Hay dos formas de aplicar este modelo; parámetricamente (asumen que los datos siguen una distribución específica y, por lo tanto, solo necesitan ajustar un número fijo de parámetros para realizar predicciones) y los no paramétricos (no asumen una distribución fija para los datos y, en cambio, permiten que la estructura del modelo se adapte libremente a los datos sin restricciones de parámetros fijos).

    Los árboles de decisión son modelos de aprendizaje predictivos.

  4. Modelo de regresión

    La regresión es una técnica de modelado estadístico y de machine learning utilizada para predecir o estimar un valor continuo basándose en la relación entre una variable dependiente (eje ‘y’, la que se quiere predecir) y una o más variables independientes (eje ‘x’, las que se usan para hacer la predicción).

    En el contexto de machine learning y estadística, el objetivo de un modelo de regresión es encontrar la relación matemática que mejor explique cómo cambia la variable dependiente en función de las independientes, de manera que se puedan hacer predicciones en nuevos datos.

    El objetivo principal de la regresión es ajustar una función o modelo que describa la relación entre las variables y minimice el error en las predicciones. Esto se logra a través de técnicas de optimización que ajustan los parámetros del modelo para minimizar la función de pérdida.

    El más común de este tipo de modelos es el lineal;

    Pero también hay otras de mayor complejidad como la polinomial;

  5. Modelo de máquina con soporte de vectores

    Estos modelos se crean mediante el entrenamiento supervisado. Usando algoritmos de clasificación y regresión (y un dataset marcado con las categorías a las que cae cada ejemplo) crea internamente categorías y sus datos clasificatorios para luego determinar a un nuevo ejemplo que características comparte con las que tiene cada categoría, y luego determina a cual debe pertenecer ese modelo.

  6. Modelo Beyesian

    Es un modelo, mayormente representativo, en donde se relaciona a un objeto con otros. Al ser objetos representan tanto adjetivos como sustantivos.

    Es muy común para hacer relaciones, se usa mucho en el ámbito medicinal para detectar enfermedades según diferentes objetos presentes.

    También se llaman; diagramas de influencia.

  7. Modelo de regresión gaussiano

    Es un enfoque probabilístico no paramétrico para realizar regresión. Este modelo se basa en la suposición de que cualquier conjunto de puntos de datos puede describirse mediante una distribución conjunta gaussiana, y en lugar de estimar directamente una función específica, estima una distribución de funciones que podría explicar los datos observados. Esto permite que el modelo no solo prediga valores, sino también proporcione una estimación de incertidumbre en sus predicciones, lo que es valioso en contextos donde la confianza en los resultados es crítica.

    Un GP (Gaussian Process) es un conjunto de variables aleatorias, cada una de las cuales sigue una distribución normal, y cualquier subconjunto de ellas está también distribuido normalmente.

    El GPR (Gaussian Process Regression) no solo da una predicción, sino también una medida de incertidumbre en cada punto de predicción, lo cual es muy útil en aplicaciones donde la confianza en la predicción es relevante.

    El modelo no necesita definir explícitamente la forma de la función subyacente, por lo que puede modelar relaciones complejas en los datos.

    Los GPs son muy efectivos en contextos de datos pequeños o medianos, donde los modelos no paramétricos pueden superar a los modelos de regresión tradicionales.

    La principal desventaja de los GPs es su costo computacional, ya que requiere invertir mucho tiempo y memoria debido a la inversión de matrices, que se vuelve computacionalmente prohibitiva con datos grandes.

    El rendimiento del GPR depende en gran medida de la elección del kernel. La selección y ajuste de este kernel puede ser compleja, especialmente en problemas donde no se conoce mucho sobre los datos.

  • Red estocástica

    Son redes neuronales que tienen la particularidad de que se les agrega cambios aleatorios a los pesos de las neuronas.

    Son algo cercano a como evoluciona un ser vivo en la naturaleza; por mera aleatoridad se da una mejor optimización a un problema y esa logra sobrevivir.

Organización - Arquitectura

Capas de una red
Copyright: sciencelearn.org.nz

Una red neuronal es un modelo computacional que imita el funcionamiento del cerebro humano a través de un conjunto de neuronas artificiales (funciones matemáticas). Cada neurona (en color verde) recibe una entrada, desde la interfaz (en color azul), la multiplica por un conjunto de pesos (parámetros), le suma un sesgo (bias) y envia el resultado a la siguiente capa. Finalmente aplica una función de activación para producir una salida (en color amarillo).

Las neuronas están organizadas en capas, y las conexiones entre capas (conocidas como sinapsis) están definidas por estos parámetros (pesos y sesgos). Cada capa de neuronas recibe la salida de la capa anterior y la envía a la siguiente, permitiendo que la red aprenda representaciones complejas a medida que avanza.

Pero puede pasar que en el medio de su procesamiento, haga relaciones entre conceptos que no son correctos, en los humanos diriamos que se ‘confundió’ mientras que en este contexto lo llamamos ‘alucinación’. La diferencia radica en que la IA / modelo no se dará cuenta de eso hasta que termine de procesar todo y dé una salida claramente errónea.

La forma en que se relacionan las capas ente si y con cada neurona de entrada-salida de las mismas es mediante matrices matemáticas representadas en forma de software.

Algo a considerar; las arquitecturas entre modelos suelen variar enormemente. No es la misma estructura ni arquitectura que tiene Gemma (de Google), Llama (de Meta) y Mixtral (de Mistral), por poner unos pocos ejemplos. Por lo que funciona para un modelo, puede no funcionar (o hacerlo pobremente) para otros.

Expertos - Mixture of Experts

Los “expertos” son partes de la red neuronal que están entrenadas específicamente para un determinado tema, eso permite que un modelo sea “modular”. Dejando de esta manera ciertas partes a entender, por ejemplo, temas de cocina y luego otras partes a programación en Python, Rust, etc.

Esto se complementa con un mecanismo complementario, denominado ‘Auxiliary-Loss-Free Load Balancing’, que permite al modelo organizar de forma automática y eficiente el trabajo de cada ‘experto’, asegurándose de que todas contribuyan en su justa medida, sin necesidad de procesos extras.

Machine Learning (ML)

Es un subcampo dentro de la IA. Busca la creación, optimmización y depuración de algoritmos estadísticos que le permitan a la red neuronal entender las relaciones entre los diferentes datos de entrenamiento (‘dataset’). Esto con el fin de que al entrar un dato nuevo, el algoritmo pueda detectar tales relaciones y similitudes y dar una salida apropiada.

Algo que voy a repetir de diferentes formas a lo largo de este capítulo, la IA no solamente es para texto, puede usarse para cualquier cosa que se pueda usar como dato de entrada y codificado.

Deep Learning

Es un subcampo dentro del ML. Es el eslabón más profundo dentro de la ejecución de una red neuronal, ya que se enfoca en las neuronas y como aprenden mediante; clasificaciones, regresiones y representaciones de la información introducida.

‘Deep’ viene de las varias capas creadas en la red neuronal.

Tenemos varios métodos de entrenamiento de la red, aunque debemos tener en cuenta que no son las únicas formas;

  1. Supervisada (SL: Supervised Learning)

    • Conjunto de datos etiquetado

      En el entrenamiento supervisado, se utiliza un dataset que contiene ejemplos de entrada y sus correspondientes etiquetas o salidas esperadas. Cada entrada tiene un resultado correcto asociado, que el modelo debe aprender a predecir.

    • Proceso de entrenamiento

      La red neuronal recibe las entradas del dataset, pasa los datos a través de sus capas, y produce una salida (predicción). Esta salida se compara con la salida esperada (la etiqueta) mediante una función de pérdida (o función de error), que mide qué tan lejos está la predicción del modelo del resultado correcto.

    • Retropropagación y ajuste automático

      Si la predicción es incorrecta, el modelo utiliza un proceso llamado retropropagación (backpropagation) para ajustar automáticamente los pesos y sesgos de la red. Esto se realiza mediante un algoritmo de optimización, como descenso por gradiente. Este proceso iterativo busca minimizar el error al ajustar los parámetros para que las futuras predicciones sean más precisas.

  2. Semisupervisado (WS: Weak supervision)

    En este enfoque, el modelo se entrena con una combinación de datos etiquetados y datos no etiquetados, lo que lo hace muy útil cuando es costoso o difícil obtener un dataset completamente etiquetado.

    Características:

    • Datos etiquetados y no etiquetados

      El modelo recibe una pequeña porción de datos etiquetados (es decir, datos que tienen una salida o etiqueta conocida) y una gran cantidad de datos no etiquetados (sin salida conocida). Dado que etiquetar datos puede ser costoso, esta técnica permite aprovechar los datos no etiquetados para mejorar el entrenamiento.

    • Proceso de entrenamiento

      El modelo comienza aprendiendo de los datos etiquetados de manera supervisada, utilizando las etiquetas conocidas para ajustar los parámetros.

      Luego, se usa una técnica para tratar de estimar o inferir las etiquetas de los datos no etiquetados, de modo que el modelo pueda mejorar su capacidad para generalizar y aprender de toda la información disponible.

    • Aprovechamiento de grandes volúmenes de datos

      En muchos casos, es fácil recopilar grandes cantidades de datos no etiquetados (por ejemplo, imágenes, texto, etc.), pero el etiquetado manual puede ser costoso. El aprendizaje semi-supervisado permite utilizar ambos tipos de datos.

    • Mejora en la generalización

      El uso de datos no etiquetados ayuda a que el modelo no dependa únicamente de los pocos datos etiquetados, mejorando así su capacidad para generalizar a datos nuevos o desconocidos.

  3. No supervisado

    A diferencia del aprendizaje supervisado, en el que el objetivo es predecir etiquetas a partir de ejemplos ya etiquetados, en el aprendizaje no supervisado el objetivo principal es descubrir patrones ocultos o estructura subyacente en los datos.

    El objetivo del aprendizaje no supervisado es encontrar patrones, agrupamientos o estructuras dentro del conjunto de datos. No se espera que el modelo genere predicciones exactas como en el caso del aprendizaje supervisado.

    Catacterísticas:

    • Sin etiquetas

      En el aprendizaje no supervisado, los datos no tienen etiquetas ni salidas esperadas. El modelo trabaja con las entradas brutas y debe identificar por sí mismo las relaciones o agrupaciones dentro de los datos.

    Tareas comunes:

    • Clustering (agrupamiento)

      El modelo agrupa los datos en clústeres o grupos de objetos similares basándose en sus características. Un ejemplo común es el algoritmo K-means, que agrupa datos en un número fijo de clústeres, donde los puntos dentro de un mismo clúster son más similares entre sí que a los puntos en otros clústeres.

    • Reducción de dimensionalidad

      Técnicas como Análisis de Componentes Principales (PCA) se utilizan para reducir el número de variables en un conjunto de datos, manteniendo la mayor cantidad de información posible. Esto es útil para visualizar datos o para mejorar el rendimiento de otros algoritmos.

    • Detección de anomalías

      Se utiliza para identificar datos que no siguen los patrones generales, como identificar transacciones fraudulentas en datos financieros.

  4. Aprendizaje reforzado

    En este contexto, se deja a la IA en un ambiente dinámico con un motor que detecta el ambiente y las decisiones de la IA. Si la IA hace las cosas bien le emite una señal de recompensa, la red neuronal entiende eso y sigue, pero si lo hace mal se emite una señal acorde y la IA repite hasta hacerlo bien.

    Cuando tiene varias señales de haber hecho bien las cosas, la IA busca relaciones y patrones en común para aprender y seguir haciendo cosas.

    Por eso es un constante prueba y error (a veces miles de miles de esos) hasta que empieza a hacerlo bien y ahi empieza aprender.

  5. Auto aprendizaje

    Desde 1982 existe un algoritmo, relativamente simple, que es parecido al aprendizaje no supervisado: se basa en que a una entrada determinada, el algoritmo analice la entrada y actualice una matriz de memoria en donde; una situación ‘s’ dispara una acción ‘a’, luego se recibe como respuesta una situación deribada (s’) donde luego se actualiza la matriz de memoria.

    Este tipo de aprendizaje no tiene señales de recompensa y sin manipulación de datos, pesos o bias.

  6. Aprendizaje futuro o representacional

    A mi me gusta llamarlo ‘general’.

    El aprendizaje futuro o aprendizaje representacional es un enfoque que intenta capturar y aprender representaciones más generales y transferibles de los datos, en lugar de memorizar o aprender directamente patrones específicos de cada tarea. Este tipo de aprendizaje se centra en identificar patrones de alto nivel, estructuras y características en los datos que se pueden reutilizar o transferir a tareas similares o incluso distintas. En inteligencia artificial y machine learning, el aprendizaje representacional tiene como objetivo que los modelos comprendan mejor los conceptos subyacentes, facilitando que puedan adaptarse a nuevas situaciones con menos ajustes.

    Los modelos, en especial los de deep learning, aprenden representaciones a distintos niveles, desde características más simples (como bordes en imágenes) hasta conceptos complejos (como el reconocimiento de caras). Esta jerarquía ayuda a crear una representación del conocimiento cada vez más abstracta y reutilizable.

    En muchos casos, el aprendizaje representacional se basa en la creación de embeddings, o representaciones numéricas de alta dimensión que capturan relaciones entre entidades. En NLP (Procesamiento del Lenguaje Natural), por ejemplo, los embeddings de palabras permiten que el modelo relacione palabras similares (como “rey” y “reina”) en un espacio semántico que representa significados y contextos.

    Se aplican técnicas como el aprendizaje contrastivo, en el cual el modelo aprende a distinguir entre representaciones similares y distintas. Esto ayuda a que el modelo refine sus representaciones de manera más robusta y distintiva.

  7. Aprendizaje continuo

    Generalmente cuando se termina el entrenamiento del modelo, se bloquean sus variables internas para hacerlas inmutables y que de esa manera la misma no cambie (si sigue entrenando) conforme pasa el tiempo. Pero si la misma no se bloquea se puede seguir entrenándola con cada uso para que mejore según necesitemos.

  8. Decisión por árbol

    Se usa una estructura de árbol para partir de una observación inicial y variar de acuerdo a las características que se consideren (las ramificaciones) para llegar las conclusiones.

Pero también tenemos una complementación a todos los tipos anteriores muy interesante:

  1. Reducción dimensional

    La reducción dimensional se basa en realizar un análisis de la información que va entrar y se va a procesar para identificar información que no sea útil para el modelo. Con el fin de simplificarla y mejorar el nivel de precisión resultante.

    Técnicamente se dice que es reducir la dimensión de la información (3D) a una más pequeña (2D). Como ejemplo; si una IA tiene que evaluar si por el color de una estrella es una enana blanca o una super nova, no necesita (en principio, de forma más esencial) la información sobre la profundidad de campo.

    La información adicional pero no requerida para la tarea puede hacer ‘alucionar’ al modelo.

Debemos entender algunos conceptos adicionales que aplican a todos los tipos de entrenamiento anteriormente listados:

  • Función de pérdida / costo (“loss rate”)

    Es una función que compara la salida que deseamos que tenga la red neuronal (‘salida real / deseada’) con la que dió la red al hacer una propagación hacia adelante (véase; una ejecución normal de la red). Luego se comparan los valores de ambas salidas y se calcula el ratio de diferencia (obviamente a mayor diferencia entre la salida esperada y la obtenida menor es la precisión del modelo).

    Un ejemplo de esto es MSE (Medium Square Error).

    Tanto en el aprendizaje como en el fine tuning, no siempre un valor de cero absoluto es lo mejor. A un valor mayor, significa que la red neuronal todavia está aprendiendo, mientra que a un valor cercano a cero significa que ya aprendió y se está sobre ajustando (lo cual tampoco es bueno). Lo ideal es que el ratio de pérdida oscile entre 0.399 y 0.799.

    Si el valor final del loss rate es mayor a 1.000, significa que necesita un learning rate (ver abajo) más bajo y varios epoch (ver abajo). Si el valor queda a menor de 0.399 significa que el modelo puede dar respuestas perfectas en el dataset de entrenamiento, pero fallar en datos nuevos (poca capacidad de generalización).

    Loss RateInterpretación
    > 1.0Modelo está aprendiendo, pero todavía es muy inexacto.
    0.6 - 1.0Sigue ajustando parámetros, pero hay espacio para mejora.
    0.3 - 0.5Buen balance entre aprendizaje y generalización.
    0.1 - 0.3Posible ajuste fino, pero riesgo de sobreajuste.
    < 0.1Modelo puede estar sobreajustando el dataset.
    ~0.0004Modelo está completamente sobreajustado.
  • Tasa de aprendizaje (“Learning Rate”)

    La tasa de aprendizaje es el tamaño de los pasos correctivos que aplica el modelo en entrenamiento para mejorar la precisión de los datos aprendidos. Obviamente, a menor tasa más lento es el proceso pero más (y mejor) eficiente es el modelo y mejor sus respuestas (véase; los datos de salida).

    Hay algoritmos, de funciones recursivas, como ‘Quickprop’ para determinar el mínimo de pérdida de precisión en la red neuronal.

    Dependiendo de si la red neuronal tiene, o no, varias capas grandes de neuronas puede pasar que si se tiene una baja tasa de aprendizaje entonces la red quede en un bucle buscando constantemente la neurona y ruta con el camino más corto y eficiente. Entonces se suele usar una tasa variable adaptativa para ajustar según se requiera.

    Un valor cercano a cero (0) enfatiza aprender las diferencias (el gradiente) y relaciones entre todos los datos (en cada una de las capas), mientras que un valor cercano a uno (1) enfatiza el último cambio (sin considerar todo lo anterior a ese cambio). De ahí que un valor más bajo aumenta la precisión del aprendizaje, y es más lento.

    Un valor bastante común y equilibrado es; “ 1.866666666666667e-05 “. Prestá atención al número y verás que no es un entero, si no que el tener “e” indica que es un decimal, por lo tanto “ 1.866666666666667e-05 “ es equivalente a “ 0.00001866666 “.

  • “Propagación hacia atrás de los errores” o retropropagación (‘backpropagation’)

    Si durante el aprendizaje se detectaron errores en la propia red neuronal usando una función de pérdida/costo (por ejemplo; si queremos que identifique el idioma y en vez de español nos dice que es hebreo, o si le pasamos la foto de un gato y dice que es un lince), la misma se re ajusta para corregir esos errores, debe hacerlo tanto en la capa donde detectó el error como hacia atrás y adelante (para que toda la red se perfeccione en conjunto).

    Técnicamente este proceso (llamado ‘backprop’ muchas veces) se ejecuta una vez obtenido el valor de la función de pérdia / costo, luego se calcula cuanto contribuyó el peso de cada neurona (y su relación con el resto de la red) al error final y se procede ajustar.

    Obviamente el error puede estar en un lugar en concreto o en unas determinadas capas de la red, por lo que para saber si se está en el lugar correcto o no, se calcula el gradiente (la derivada matemática) y su valor indica si es hacia atrás, hacia adelante o si es en ese lugar.

    Una vez calculado el gradiente, se utilizan optimizaciones (como el ‘gradient descent’) para actualizar los pesos en la red. El descenso de gradiente actualiza los pesos en la dirección contraria a la indicación del gradiente, a fin de contrarrestar el error.

    Obviamente, si entendiste bien hasta ahora, te darás cuenta que el backprop es uno de los procesos que se realizan en la tasa de aprendizaje.

  • Época (“epoch”)

    Una época es una iteración completa sobre el conjunto de datos (‘dataset’). A varias épocas y una menor tasa de aprendizaje, mejor precisión.

Retrieval-Augmented Generation (RAG)

Los modelos lingüísticos se limitan a proporcionar respuestas basadas en sus datos de entrenamiento. Esto se debe a que no han sido entrenados con datos específicos de su organización. Además, los datos de entrenamiento de estos modelos tienen una fecha de corte, lo que limita su capacidad para proporcionar respuestas actualizadas.

La generación mejorada por recuperación es un proceso en el que grandes modelos lingüísticos como GPT-4o adquieren integraciones del contexto utilizando fuentes de datos externas. Es una combinación de un recuperador y un generador. El recuperador obtiene datos de Internet o de una base de datos vectorial (publica o privada) y se los proporciona al generador junto con la consulta original del usuario. El generador utiliza el contexto adicional para generar una respuesta muy precisa y pertinente.

El proceso consta de estos pasos simplificados;

  1. El usuario indica lo que quiere o necesita
  2. El RAG interpreta la introducción del usuario/a
  3. Con la información interpretada, se conecta a internet o la base de datos para buscar información en distintos lugares sobre esos conceptos.
  4. Con la información adicional obtenida de distintas fuentes, se inserta en conjunto con lo que solicitó el usuario/a y se pasa al modelo.
  5. El modelo interpreta toda la información y devuelve una salida.

En algunos sistemas RAG se usa un modelo de embeddings para encontrar los documentos más relevantes. Pero en todos los casos el uso del RAG reduce las alucinaciones (respuestas inventadas).

Fine tuning

El fine tuning es un proceso por el que; a un modelo ya creado y dado, le hacemos un nuevo entrenamiento, modificando los valores de los pesos y bias de sus neuronas para hacer que “aprenda” nueva información. De esta forma podemos actualizar un modelo sin tener que entrenarlo desde cero, y podemos cambiar la información que contiene dentro (pudiendo crear o eliminar limitaciones sobre hablar o dar determinado tipo de conocimiento).

Nota legal
Dependiendo del país done estes, puede ser que sea ilegal que tengas un dataset determinado (datos médicos, financieros, etc) mientras que tengas un modelo entrenado con tales puede ser que no. Asesórate legalmente.

Hay muchas formas de realizar una personalización fina (nota; sigamos con la denominación en inglés) entre los que se incluyen (pero estos no son todos los que hay);

  1. Feature extraction (repurposing)

    Cuando tenemos un modelo open source como Llama, Gemma, etc, estamos obteniendo un modelo extremadamente entrenado en un abanico gigante de temas (por eso tienen una cantidad de parámetros que no bajan de los dos mil millones). Pero al adaptarlo con este proceso a nuestras necesidades, lo que se realiza es; utilizando las últimas capas / campos del modelo, se las modifica para adaptarse a los datos nuevos.

    Es un primer acercamiento interesante pero el menos eficiente de todos, ya que solamente estas actualizando la última parte del modelo.

  • Full

    En esta metodología, el proceso analiza la red neuronal entera y va modificando los valores para adaptarse a la nueva información.

    Como te podras imaginar, modificiar millones de parámetros (ya previamente entrenados) con información nueva es muy costoso computacionalmente hablando. Este modelo de fine tuning, permite tener un modelo actualizado con una mejor precisión en los resultados pero el tiempo es mucho mayor ya que se modifica la red neuronal entera.

  • Low-Rank Adaptation (LoRA)

    Introducido por el equipo de investigación de Microsoft en el 2021.

    LoRA es una metodología que aprovecha las funciones matemáticas esenciales del modelo para añadir capas nuevas que actualicen las neuronas con pesos y bias nuevos acorde a la información que proviene del dataset. Cada una de esas nuevas capas que crea LoRA no se insertan al final del modelo, si no que van encima de las ya existentes (pero sin modificarlas) y se llaman “adaptadores”.

    Cada adaptador modifica una o varias neuronas de capas determinadas para crear “parches” con valores nuevos, para que funcionen con el nuevo entrenamiento dado. Algo que debemos considerar y no olvidar, es que LoRA no modifica el modelo base (a nivel de archivo, llamado “PeftModel” debido a que se segmenta en partes que LoRA puede entender y saber cuales deben llevar o no estos “parches”), si no que crea en archivos separados (archivos “.pt” y “.pth”) esos adaptadores para que cuando el modelo se carga en RAM se apliquen como parches.

    A medida que el entrenamiento avanza, se crean cantidades más grandes de adaptadores y la cantidad de RAM o VRAM empieza a aumentar. Recorda que es por que no solamente estas ejecutando el modelo base (el PeftModel), si no que además estas ejecutando cada adaptador / capa nueva que modifica los valores. Pero sigue siendo mucho más eficiente, más liviano y rápido que usar “full”.

    Hasta la fecha de escritura del presente documento, esta es la forma más eficiente de hacer un fine-tuning.

    Al final del proceso de entrenamiento tenes dos opciones; o cargas el nuevo modelo usando la base y cada una de las capas, ó unificas las capas LoRA con el modelo base.

    “QLoRA”; es el proceso LoRA normal pero introduciendo quantificación en esas variables.

    Por si te lo estas preguntando; podes unir varios adaptadores en uno solo. Se llama “weighter_adapter”.

  • Ajuste fino eficiente de parámetros (PEFT)

    El ajuste fino eficiente de parámetros (PEFT por sus siglas en inglés) es una técnica utilizada para mejorar el rendimiento de los LLM preentrenados en tareas posteriores específicas minimizando el número de parámetros entrenables. Ofrece un enfoque más eficiente al actualizar sólo una pequeña fracción de los parámetros del modelo durante el ajuste fino.

    PEFT modifica selectivamente sólo un pequeño subconjunto de los parámetros del LLM, normalmente añadiendo nuevas capas o modificando las existentes de forma específica para cada tarea. Este enfoque reduce significativamente los requisitos de cálculo y almacenamiento, al tiempo que mantiene un rendimiento comparable al del ajuste fino completo.

En el proceso de fine tuning, y básicamente en todo proceso de entrenamiento, debemos controlar varios parámetros dependiendo nuestras necesidades y de las capacidades computacionales;

  • “Batch size”

    Es el tamaño que va a tener cada paquete que se va a usar en cada etapa (etapa, no epoch) de entrenamiento. A mayor tamaño / peso; mayor cantidad de datos de entrenamiento, mayor velocidad de entrenamiento, mayor uso de VRAM (GPU) / RAM (CPU) y más diferencia entre cada etapa (esto hace que cada adaptador de LoRA pese más).

  • El tamaño del dataset

    A mayor tamaño del dataset más probable que aparezcan inconsistencias entre diferentes “outputs”.

    Es preferible tener datasets lo más chicos y precisos posibles.

  • LoRA Config

    Creo que es evidente que el mejor proceso de fine tuning viene con LoRA. Por lo que cuando hagas esto vas a tener que indicar una serie de valores e instrucciones;

    1. Las partes / capas concretas del modelo que LoRA debe re entrenar durante el fine tuning.
    2. Que matrices matemáticas deben actualizarse dentro de las capas.

    LoraConfig permite controlar cómo se aplica LoRA al modelo base a través de los siguientes parámetros:

    • r: el rango de las matrices de actualización, expresado en int. Un rango menor resulta en matrices de actualización más pequeñas con menos parámetros entrenables.
    • target_modules: Los módulos (por ejemplo, bloques de atención) a los que aplicar las matrices de actualización LoRA.
    • lora_alpha: Factor de escala LoRA.
    • bias: Especifica si se deben entrenar los parámetros de bias. Puede ser ‘none’, ‘all’ o ‘lora_only’.
    • use_rslora: Cuando se establece en True, utiliza Rank-Stabilized LoRA que establece el factor de escala del adaptador en lora_alpha/math.sqrt(r), ya que se ha demostrado que funciona mejor. En caso contrario, utilizará el valor original por defecto de lora_alpha/r.
    • modules_to_save: Lista de módulos aparte de las capas LoRA que deben establecerse como entrenables y guardarse en el punto de control final. Normalmente incluyen el cabezal personalizado del modelo que se inicializa aleatoriamente para la tarea de ajuste.
    • layers_to_transform: Lista de capas a transformar por LoRA. Si no se especifica, se transforman todas las capas de target_modules.
    • patrón_capas: Patrón para hacer coincidir los nombres de las capas en target_modules, si se especifica layers_to_transform. Por defecto PeftModel buscará el patrón de capas común (layers, h, blocks, etc.), lo usará para modelos exóticos y personalizados.
    • rank_pattern: El mapeo desde nombres de capas o expresión regexp a rangos que son diferentes del rango por defecto especificado por r.
    • alpha_pattern: El mapeo de nombres de capa o expresión regexp a alfas que son diferentes del alfa por defecto especificado por lora_alpha.

Dataset

En el contexto de inteligencia artificial (IA) y machine learning (aprendizaje automático), un dataset (o conjunto de datos) es una colección estructurada de datos que se utiliza para entrenar, validar y probar un modelo de IA o de aprendizaje automático. Los datasets son esenciales para que los algoritmos de machine learning puedan aprender patrones, hacer predicciones y realizar tareas específicas.

Un dataset generalmente incluye varias instancias o ejemplos, y cada instancia contiene un conjunto de características o atributos que describen esa instancia. Dependiendo del tipo de tarea, los datasets pueden variar en estructura y contenido:

  1. Datasets para tareas de clasificación

    Aquí, cada instancia está etiquetada con una clase o categoría. Por ejemplo, en un dataset de imágenes de animales, cada imagen podría estar etiquetada como “gato”, “perro”, etc.

  2. Datasets para tareas de regresión

    En este caso, cada instancia está asociada a un valor numérico continuo. Por ejemplo, en un dataset que predice precios de casas, cada entrada incluiría características de una casa (como tamaño, ubicación) y el precio de venta.

  3. Datasets de entrenamiento, validación y prueba

    Para entrenar y evaluar correctamente un modelo, los datasets generalmente se dividen en tres partes:

    • Dataset de entrenamiento: Utilizado para enseñar al modelo a identificar patrones.
    • Dataset de validación: Sirve para ajustar los hiperparámetros del modelo y evitar el sobreajuste (overfitting).
    • Dataset de prueba: Se usa para evaluar el rendimiento del modelo final, en datos no vistos previamente.

En machine learning, la calidad y cantidad del dataset son cruciales. Un dataset representativo, diverso y correctamente etiquetado es clave para el éxito del modelo de IA.

Formato de un dataset

No podes crear un dataset simplemente con texto plano y esperar que la IA lo entienda y haga las relaciones. Debe tener un formato.

Hay un dataset muy conocido, pero con ciertos errores, que lleva el mismo nombre que el modelo final “Alpaca”. Y tiene una estructura muy interesante y lógica usando el formato JSON (nota; luego de cada grupo antes de uno nuevo va una ‘coma’, salvo el último que no lleva);

[
	{
		"instruction": "XXXXXXXXXXXXXXXXXXXXXXX"
		"input": "YYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
		"output": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	},
	{
		"instruction": "XXXXXXXXXXXXXXXXXXXXXXX"
		"input": "YYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
		"output": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
	}
]

Empecemos por partes;

  • “instruction”

    Esta seccion indica que debe analizar (técnicamente hablando) el modelo.

    Por ejemplo;

    “Con la información que te proveo, analiza cual es el siguiente paso que se debe realizar para completar la tarea”

  • “input”

    Es lo que nosotros le damos en forma de archivo o texto de entrada.

    Por ejemplo;

    “Hola [modelo]. Necesito que me indiques como puedo reparar una canilla de bronce que se rompio y que necesito remplazarla por un modelo diferente.”

  • “output”

    Es lo que debe devolver la IA cuando detecta que lo que se le solicitó tiene realción con el “input” anterior.

Ahora debemos hacer unas aclaraciones importantes; si recordas las primeras líneas de este capítulo entenderás que lo que hace el modelo es analyzar la entrada que le dió el usuario/a (usando los “input” e “instruction” del dataset) y detectar las posibles combinaciones que se deben realizar (usando los “outputs” del dataset) para cumplir esa relación y dar la salida apropiada. Esto es lo que permite que puedas preguntar o pedir asociaciones diversas en temática pero que la salida tenga “más o menos” una coherencia de salida.

Por eso mismo, si cuando interactuas con ChatGPT, Gemini, DeepSeek, Llama, etc especificas (primero) la instrucción y luego el pedido con la información, el resultado es mucho mejor. Ya que le permite al modelo realizar mejores y más precisas relaciones entre los datos. Aca un ejemplo con mi cuenta de ChatGPT Plus;

Yo;

Hola ChatGPT
Analiza la relación entre los datos que te voy a pasar y dame una explicación 
plausible de por que los datos pueden estar, o no, relacionados.

1. Aumento de la calidad de vida y nivel económico de los países nórdicos 
al encontrar petroleo en el mar del norte

2. Aumento del poder blando de Noruega e Inglaterra en el mundo a través 
de la influencia en distintos estratos de la sociedad al rededor del mundo

=================================================================================
ChatGPT;

La relación entre los dos puntos que mencionas puede explicarse a través de una 
serie de 
efectos económicos, políticos y estratégicos derivados 
del descubrimiento y explotación del petróleo en el Mar del Norte.

### **1. Aumento de la calidad de vida y nivel económico en los países nórdicos 
tras el hallazgo de petróleo**

Cuando Noruega descubrió petróleo en el Mar del Norte en los años 60 y 70, 
el país implementó políticas económicas que permitieron la creación del 
**Fondo de Pensiones del Gobierno de Noruega**, el cual invierte en mercados 
internacionales y actúa como un colchón financiero para el país. Esto generó:

   - **Mayor inversión en infraestructura y bienestar social**, con educación y 
   salud gratuitas o de bajo costo.
   
   - **Alta calidad de vida** debido a políticas redistributivas y sostenibles.
   
   - **Diversificación económica**, ya que Noruega ha tratado de no depender 
   solo del petróleo, sino también de energías renovables y tecnologías avanzadas.

Reino Unido también explotó petróleo en el Mar del Norte, pero su modelo de 
gestión fue más privatizado, por lo que los efectos en calidad de vida fueron 
menos evidentes en comparación con Noruega. Sin embargo, sí tuvo un impacto 
positivo en la economía británica, especialmente en los años 80 y 90.

### **2. Aumento del poder blando de Noruega e Inglaterra en el mundo**
El poder blando (soft power) se refiere a la capacidad de un país para influir 
en otros a través de la cultura, la diplomacia, la ayuda internacional y otros
medios no coercitivos. La riqueza petrolera permitió a Noruega e Inglaterra 
incrementar su influencia global de varias formas:

- **Noruega como mediador internacional**

Gracias a sus ingresos petroleros, Noruega ha financiado esfuerzos de paz y 
desarrollo en varias partes del mundo (como el Proceso de Paz en Colombia, 
Sudán y Medio Oriente), lo que ha reforzado su reputación internacional.

- **Inversión en cultura y educación**: Noruega y Reino Unido han impulsado 
becas, universidades y proyectos culturales que refuerzan su presencia en la 
educación y en la formación de elites extranjeras.

- **Inglaterra como centro financiero y cultural**: Londres ya era un centro 
financiero global, pero la estabilidad económica proveniente del petróleo 
ayudó a fortalecer esta posición, atrayendo inversión extranjera y 
manteniendo la influencia británica en negocios y política global.

### **Conclusión: ¿Están relacionados?**
Sí, ambos fenómenos están relacionados, aunque no de manera directa 
y exclusiva. La riqueza generada por el petróleo brindó a Noruega y a 
Reino Unido **herramientas económicas y estratégicas** que les 
permitieron fortalecer su presencia en el mundo mediante inversión en 
diplomacia, educación, cultura y ayuda internacional. En el caso de 
Noruega, el modelo de administración de los recursos petroleros 
fue clave para que pudiera desarrollar un fuerte poder blando a 
nivel global.

Ahora algo a recordar, y que lo pondré con mayúsculas en negrita para que no se te olvide, por que es realmente muy importante;

EL 80% DE LA CALIDAD FINAL DE UNA IA DEPENDE DE LA CALIDAD DEL DATASET UTILIZADO.

Obviamente otras cosas como; el learning rate, el nivel de quantización, el loss rate, etc afectan a la calidad final pero es en gran medida el dataset utilizado el que determina que tan útil son las respuestas que da el modelo.

Mi recomendación es la siguiente; si elegis crear el dataset desde cero vas a tener mucho trabajo (cientos de horas), por lo que te recomiendo que uses ChatGPT Plus, Gemini Advance, etc para que subas el archivo JSON y le pidas al modelo que te cree un nuevo archivo con información sobre determinadas cosas en las que quieras entrenar tu modelo personalizado. Esta recomiendación viene por el hecho de que puedas asistirte y de que te evites el limite de lineas de las interfaces WebGUI.

Luego, una vez que tengas tu archivo de dataset, no es cuestión de usarlo y ya, tenes que refinarlo y depurarlo.

Recorda; el modelo analiza el “input” y separa los elementos claves para detectar su relación. Por lo tanto, tenes que “limpiar” de tu dataset el ruido en la variable “input” que tengas. El ruido que tenes que eliminar son elementos innecesarios de la oración que no ayudan a mejorar su entiendimiento si no que son redundantes.

Supongamos que tenemos esto en el dataset (reduje el “output” por que esto es un ejemplo);

input="Hola ChatGPT, te quiero hacer una pregunta, qué relación hay entre un lobo y un perro domestico como un fox terrier?"
output="La relación que existe entre un perro doméstico y un lobo incluye muchos aspectos psicológicos como físicos entre los que se incluyen ........"

Esa sentencia de lo que se espera que introduzca el usuario/a es muy grande, hay muchas palabras que deben estar correctamente introducidas para tener sentido unas con otras. Podemos reducir la sentencia para dejar la misma información a solicitar y reducir el ruido;

input="Qué relación hay entre un lobo y un perro domestico?"
output="La relación que existe entre un perro doméstico y un lobo incluye muchos aspectos psicológicos como físicos entre los que se incluyen ........"

De esta manera, reducimos los tokens (que hablaremos más adelante de que esto) de 43 en el primer ejemplo a 19 en el segundo ejemplo. Hicimos una reducción dimensional bastante grande.

Que tantos datos le pongamos para ser aprendidos esta determinado por el “batch” (a mayor batch mayor cantidad de datos procesados a la vez pero mayor peso en la VRAM).

** Una consideración muy importante del dataset; a mayor cantidad de información en cada archivo (JSON o el que sea el formato), mayor cantidad de memoria RAM que se va a usar. Puede parecer algo lógico y obvio, pero para que te des una idea; un dataset JSON de 25M ha llegado a consumirme 35 GB de RAM, por como tiene que manejar y crear los tokens. Es preferible crear datasets chicos (aproximadamente 100 kb) en donde luego el proceso de fine tuning lo cargue desde el almacenamiento en RAM, lo tokenice, entrene el modelo, lo descargue de la memoria RAM y luego siga con el siguiente.**

Otra consideracion es que si tenemos varios inputs iguales con distintos outputs (por ejemplo; “que programas tienen esta carpeta?”) la IA no va a ser capaz de devolver varios valores, por que aprendió por el dataset que le diste que es; 1 input -> 1 salida. En este caso tenes que modificar el dataset para que el formato sea;

[
	{
		"instruction": "XXXXXXXXXXXXXXXXXXXXXXX"
		"input": "YYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
		"output": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
		          "ZZZZZZZZZZZZZZZZZZZZZZ222222"
	}
]

Destilación

Preparate por que esto es muy importante; El 20 de Enero de 2025, una empresa de origen chino llamada DeepSeek lanzó su modelo DeepkSeek-R1, el cual presenta muchas optimizaciones muy precisas para lograr sortear las sanciones tecnológicas impuestas por EEUU a China en entrenamiento de inteligencias artificiales.

Como te dije anteriormente, una enorme parte de la calidad final del modelo depende de la calidad del dataset con el que se lo entrene. Entonces, y si entrenamos a una IA utilizando otra IA más avanzada?. Simplemente dejamos que conversen entre ellas durante varias horas, que serán millones de datos al ser máquinas, y luego dejamos que el modelo “aprendiz” aprenda de las respuestas que le da el modelo “maestro”.

Por supuesto que esto es un tipo de aprendizaje no supervisado, por lo que la calidad de este entrenamiento dependerá que tan bien haga las preguntas, y que tan bien se las responda el modelo “maestro”.

Bueno, esto mismo hizo DeepSeek para entrenar su modelo R1; utilizó las APIs de OpenAI ChatGPT y de Google Gemini para poner a conversar su modelo con el de ellos y que le enseñaran sobre datos en general. Abaratando mucho el costo humano de generar un dataset de calidad.

Data mining

El data mining (o minería de datos) es el proceso de explorar grandes volúmenes de datos para descubrir patrones, tendencias y relaciones significativas que no son obvias a simple vista. En el contexto de machine learning y aprendizaje automático, el data mining es una fase crucial, ya que ayuda a identificar la información útil que puede alimentar modelos predictivos y analíticos, apoyando la toma de decisiones.

Objetivo del Data Mining:

El objetivo principal del data mining es extraer conocimiento de datos grandes y complejos, lo cual ayuda a:

  • Identificar patrones recurrentes que se pueden utilizar para hacer predicciones o entender mejor un fenómeno.
  • Detectar anomalías o casos atípicos en los datos (útil en detección de fraudes, por ejemplo).
  • Clasificar y segmentar los datos en grupos o categorías, lo que facilita la personalización en marketing, las recomendaciones, y otros tipos de análisis.

Técnicas comunes de Data Mining:

  1. Clustering / Agrupación

    Agrupamiento de datos similares en categorías o clústeres. Se usa en segmentación de clientes, agrupación de documentos, etc.

  2. Clasificación

    Asignación de etiquetas o categorías a datos nuevos, basándose en ejemplos etiquetados previamente. Ejemplo: Clasificar correos como “spam” o “no spam”.

  3. Reglas de asociación

    Identificación de relaciones entre variables en conjuntos grandes. Un ejemplo clásico es la “análisis de cesta de mercado,” donde se identifican productos que tienden a comprarse juntos.

  4. Reducción de dimensionalidad

    Técnicas como PCA que simplifican los datos al reducir su complejidad, facilitando la visualización y el procesamiento.

  5. Detección de anomalías

    Identificación de datos inusuales o atípicos que no siguen el patrón general, útil para aplicaciones de seguridad o salud.

Proceso de Data Mining:

  1. Preparación de datos

    Involucra limpiar, transformar y seleccionar los datos que serán procesados. Esto incluye manejo de valores faltantes y corrección de inconsistencias.

  2. Elección del modelo y técnica de análisis

    Seleccionar el algoritmo o enfoque adecuado para extraer los patrones según el tipo de datos y el objetivo. Aquí puede incluirse aprendizaje supervisado, no supervisado o técnicas estadísticas.

  3. Evaluación e interpretación de resultados

    Evaluar los patrones descubiertos para asegurarse de que son válidos y útiles. En este paso se pueden ajustar los parámetros o técnicas si es necesario.

  4. Implementación y monitoreo

    Una vez que los patrones son validados, se implementan para generar valor, ya sea como modelos predictivos en producción o como información para la toma de decisiones.

Relación con Machine Learning:

El data mining y el machine learning están estrechamente relacionados, pero no son lo mismo. El data mining se enfoca en explorar y encontrar patrones en los datos, mientras que el machine learning se centra en entrenar modelos predictivos que puedan tomar decisiones o hacer predicciones basadas en esos datos. Sin embargo, el data mining proporciona las bases para entrenar modelos de machine learning al identificar los datos más relevantes y transformarlos en el formato adecuado para los algoritmos.

El machine learning usa principalmente modelos aritméticos de deep learning.

Token

Un token es una unidad mínima de texto que se utiliza para representar palabras, subpalabras o caracteres, y sirve como entrada a modelos de procesamiento del lenguaje natural para su análisis o aprendizaje.

En procesamiento del lenguaje natural (NLP)

Un token es la unidad básica de texto que un modelo utiliza para procesar lenguaje. Los tokens suelen ser palabras, pero también pueden ser fragmentos de palabras, caracteres individuales o secuencias que tengan un significado. Los procesos de tokenización dividen un texto en estas unidades más pequeñas.

Por ejemplo, la frase “El gato negro” podría ser tokenizada de diferentes maneras:

  • Palabras como tokens: [“El”, “gato”, “negro”]
  • Subpalabras o morfemas como tokens: [“El”, “gat”, “o”, “negr”, “o”]
  • Caracteres como tokens: [“E”, “l”, “ “, “g”, “a”, “t”, “o”, “ “, “n”, “e”, “g”, “r”, “o”]

Aquí, un token no “genera asociaciones con otras palabras”, sino que es una representación mínima sobre la cual los modelos trabajan para procesar texto.

En otros contextos de IA o machine learning

Un token también puede hacer referencia a una unidad numérica en la representación de datos, como cuando se codifican palabras o secuencias en vectores (embeddings) para que los modelos puedan manejarlas matemáticamente.

Ventana de contexto

La ventana de contexto es el número total de tokens que el modelo de lenguaje podrá procesar en un momento determinado.

Si el número de tokens de “input” supera a la ventana de contexto, la IA no podrá generar una salida. Es el error que ocurre cuando en ChatGPT querés indicar una entrada muy extensa y obtenes el error “El texto introducido es demasiado largo”.

Y es por ese motivo que no es posible indicarle a cualquier IA que haga un resumen de todo un libro entero, si no que debemos ir capítulo por capítulo.

Ampliar las ventanas de contexto son especialmente costosas: cada token requiere contar con un almacén de combinaciones clave/valor.

DeepSeek R1, OpenRAI O3 Mini, Mixtral y otras usan una técnica conocida como “FP8 Mixed Precision Training)” que permite representar una gran cantidad de información en un espacio mucho más pequeño. Lo logra usando números más pequeños (de 8 bits) para hacer la mayoría de los cálculos, pero pasando selectivamente a otros más grandes (de 16/32 bits) en los pasos donde se necesita más precisión. De esta forma, se ahorra memoria y tiempo de cálculo sin perder mucha exactitud.

Esta compresión de la cantidad de datos que necesita almacenar, reduce el costo y tiempo necesarios para generar resultados. Además, esta optimización no compromete la calidad de las predicciones y permite a esos modelos operar modelos grandes en hardware más asequible.

Transformers

Esta es una inovación muy importante dentro del área. El modelo de transformador se ha implementado en frameworks de aprendizaje profundo estándar como TensorFlow y PyTorch.

Transformers es una biblioteca creada por Hugging Face que proporciona arquitecturas basadas en transformadores y modelos preentrenados.

Texto procedente de la Wikipedia (ya que lo explica muy bien);

Un transformador es una arquitectura de aprendizaje profundo desarrollada por investigadores de Google y basada en el mecanismo de atención multicabezal propuesto en el artículo de 2017 «Attention Is All You Need». El texto se convierte en representaciones numéricas denominadas tokens, y cada token se convierte en un vector mediante la búsqueda en una tabla de incrustación de palabras. En cada capa, cada token se contextualiza dentro del ámbito de la ventana de contexto con otros tokens (desenmascarados) mediante un mecanismo paralelo de atención multicabezal, lo que permite amplificar la señal de los tokens clave y disminuir la de los tokens menos importantes.

Los transformadores tienen la ventaja de no tener unidades recurrentes, por lo que requieren menos tiempo de entrenamiento que las arquitecturas neuronales recurrentes (RNN) anteriores, como la memoria a largo plazo (LSTM). Las variaciones posteriores se han adoptado ampliamente para el entrenamiento de grandes modelos lingüísticos (LLM) en grandes conjuntos de datos (lingüísticos), como el corpus de Wikipedia y Common Crawl.

Los transformadores se desarrollaron por primera vez como una mejora de las arquitecturas anteriores para la traducción automática, pero desde entonces han encontrado muchas aplicaciones. Se utilizan en el procesamiento del lenguaje natural a gran escala, la visión por ordenador (transformadores de visión), el aprendizaje por refuerzo, el audio, el aprendizaje multimodal, la robótica e incluso el ajedrez. También ha dado lugar al desarrollo de sistemas preentrenados, como los transformadores generativos preentrenados (GPT) y BERT (representaciones codificadoras idireccionales de transformadores).

Métodos para estabilizar la formación

La arquitectura de transformador simple tenía dificultades para converger. En el artículo original, los autores recomendaban utilizar el calentamiento de la tasa de aprendizaje. Es decir, la tasa de aprendizaje debería escalar linealmente desde 0 hasta el valor máximo durante la primera parte del entrenamiento (normalmente se recomienda que sea el 2% del número total de pasos de entrenamiento), antes de decaer de nuevo.

Un artículo de 2020 descubrió que el uso de la normalización de capas antes (en lugar de después) de la atención multicabezal y las capas feedforward estabiliza el entrenamiento y no requiere el calentamiento de la tasa de aprendizaje.

Reentrenamiento-ajuste

Los transformadores suelen preentrenarse primero mediante aprendizaje autosupervisado en un gran conjunto de datos genéricos, seguido de un ajuste fino supervisado en un pequeño conjunto de datos de tareas específicas. El conjunto de datos de preentrenamiento suele ser un gran corpus sin etiquetar, como The Pile. Las tareas de preentrenamiento y perfeccionamiento suelen incluir:

  • modelado del lenguaje
  • predicción de la siguiente frase
  • respuesta a preguntas
  • comprensión lectora
  • análisis de sentimientos
  • parafraseo

Arquitectura

Todos los transformadores tienen los mismos componentes principales

  • Tokenizadores, que convierten el texto en tokens.
  • Capa de incrustación, que convierte los tokens y sus posiciones en representaciones vectoriales.
  • Capas transformadoras, que realizan transformaciones repetidas en las representaciones vectoriales, extrayendo cada vez más información lingüística. Están formadas por capas alternas de atención y feedforward. Hay dos tipos principales de capas transformadoras: capas codificadoras y capas decodificadoras, con otras variantes.
  • Capa de desincrustación, que convierte las representaciones vectoriales finales de nuevo en una distribución de probabilidad sobre los tokens.

La siguiente descripción sigue exactamente el transformador descrito en el artículo original. Existen variantes, que se describen en la sección siguiente.

Por convención, escribimos todos los vectores como vectores fila. Esto, por ejemplo, significa que empujar un vector a través de una capa lineal significa multiplicarlo por una matriz de pesos a la derecha, como x W {\displaystyle xW}.

Tokenización

Como la arquitectura Transformer procesa de forma nativa datos numéricos, no texto, debe haber una traducción entre texto y tokens. Un token es un número entero que representa un carácter, o un segmento corto de caracteres. En la entrada, el texto se convierte en una secuencia de tokens. Del mismo modo, en el lado de salida, los tokens de salida se vuelven a convertir en texto. El módulo que realiza la conversión entre textos y secuencias de tokens es un tokenizador.

El conjunto de todos los tokens es el vocabulario del tokenizador, y su tamaño es el vocabulario de tamaño n. Cuando nos enfrentamos a tokens fuera del vocabulario, normalmente se utiliza un token especial, escrito como «[UNK]» para «desconocido».

Algunos tokenizadores de uso común son la codificación de pares de bytes, WordPiece y SentencePiece.

Aprendizaje continuo

Todo lo que puse arriba es la teoría sin entrar en explicaciones matemáticas, pero la explicación completa involucra muchas funciones y cálculos. Por lo tanto te recomiendo que si queréss aprender verdaderamente como mejorar tus entrenamientos a los modelos, leas y aprendas este artículo;

Quantización de Transformers

Ya sabemos que la quantización es el proceso de disminuir el rango de información que puede almacenar la variable que tiene la neurona.

Pero con lo complejo que son los transformers hay un proceso que es muy eficiente; EETQ. Por lo que si vas a quantificar un modelo que usa transformers, usa el proceso EETQ y vas a tener un modelo muy eficiente y liviano.

Diseño técnico de la arquitectura del modelo

Diseñar la arquitectura para un modelo puede ser tan complejo como uno quiera, pero debemos tener en consideración siempre estos puntos:

  1. El lenguaje que vamos a usar

    Acá reina Python, pero yo uso siempre que puedo Rust con frameworks como Burst. Pero debés ponderar si podes usar el lenguaje que quieras o si tenés que cumplir con algún requisito en concreto.

    Tene en cuenta que hacer una IA desde cero es como crear un auto desde cero. Si sos como yo y no sos bueno con los cálculos matemáticos, se te va a complicar mucho por que tenés que hacer vos las modificaciones a bajo nivel, que valores tiene cada tipo, etc.

  2. La cantidad de capas

    A mayor cantidad de capas, más fácil le va a ser a la red el poder usar cada una para abstraer la salida obtenida.

    Sin embargo, debemos tener en cuenta que no siempre una mayor cantidad de capas dará un mejor resultado, a veces solamente 3 (tres) ó 4 (cuatro) sirven, si ponemos 10 (diez) entonces el resultado sería el mismo pero con mayor uso de memoria.

    Debemos evaluar que tantos datos se deben recordar y considerar en la red neuronal según la salida que necesitemos.

  3. El promedio ponderado de la tasa de aprendizaje y la función de pérdida

    Si se evalua bien el uso y la profundidad de la tasa de aprendizaje, se puede dejar un modelo robusto y sin demasiado tiempo de entrenamiento.

Por supuesto que se crearon modelos para el diseño de otros modelos (no seríamos humanos si no intentáramos automatizar absolutamente todo), se llaman “Neural architecture search” (NAS) y acá te dejo un repo de una librería.

Engines de ejecución / inferencia

El modelo de la red neuronal no es capaz de ejecutarse asi misma, necesita de un motor (‘engine’) que lo ejecute. En el momento que ese modelo se ejecuta y empezamos a interactuar con el mismo, se llama “inferencia” al proceso en que intercambiamos información en forma de peticiones u otras solicitudes.

El motor de inferencia es el que se encarga de codificar la información a formato máquina, y decodificar a formato humano.

Dependiendo del formato en que se guarde el modelo tenemos diferentes opciones;

  • Formato TensorFlow / PyTorch nativo

    Archivo en formato binario, bastante antiguo. No soporta quantización y no son portables a otros frameworks de IA.

    Extensiones; “.pb” para TensorFlow y “.pt” o “.pth” para PyTorch.

    PyTorch y TensorFlow lo usan. Generalmente solo tienen soporte para GPU, aunque se puede en CPU si se solucionan algunos errores.

  • Formato ONNX

    Formato desarrollado para superar las limitaciones de la falta de portabilidad de TensorFlow y PyTorch.

    Tiene muy poco soporte (casi nulo) de quantización.

  • Formato Safetensors / HF

    HF viene de ‘HuggingFace’, el repositorio de IAs popular.

    Archivo en formato binario, creado especialmente para modelos que usan los “transformers” para almacenar los datos de las neuronas.

    Es especialmente rápido para ejecutarse.

    Formato
    Copyright; https://www.linkedin.com/pulse/llama-3-safetensors-vs-gguf-talles-carvalho-jjcqf

    PyTorch, Llama-factory y otros engines lo usan. Generalmente tienden todos a ejecutar siempre en la GPU el modelo.

  • Formato GGUF y GGML

    Archivo en formato binario.

    GGML (GPT-Generated Model Language) es el formato viejo y ‘legacy’ (de los primeros modelos GPT), y GGUF es el nuevo formato liberado en 2023. GGUF mantiene compatiblidad con GGML pero suma nuevas funcionalidades (como; soporte para quantificación de 8 y 4 bits, los esquemas de tokenización, etc).

    GGML nació cuando se empezó a liberar los primeros modelos open-source como Llama. Tuvo por objetivo, seguir con las ventajas de ONNX pero mejorando hasta soportar totalmente la quantización, el soporte entre CPU de distintos fabricantes y otras optimizaciones.

    Una característica de este formato es que incluye todas las dependencias que necesita el modelo para funcionar, a diferencia del resto de formatos que separan los archivos de configuración y tokenización del modelo.

    Formato
    Copyright; https://medium.com/@vimalkansal/understanding-the-gguf-format-a-comprehensive-guide-67de48848256
    Formato
    Copyright; https://www.linkedin.com/pulse/llama-3-safetensors-vs-gguf-talles-carvalho-jjcqf

    Extensiones; “.gguf”.

    Ollama, llama.cpp y otros lo usan. Los que usan este formato tienden a soportar la ejecución en CPU y/o GPU.

Convertir con llama.cpp

Podemos convertir varios formatos a GGUF con el engine llama.cpp.

Primero debemos clonar el repositorio de GitHub (recorda tener instalado; git, python y python-pip);

git clone https://github.com/ggerganov/llama.cpp && cd llama.cpp

Luego instala las dependencias;

pip install --break-system-packages -r requirements.txt

Luego, dependiendo cual es el formato del modelo que necesitas vas a tener que usar uno u otro script;

convert_hf_to_gguf.py
convert_hf_to_gguf_update.py
convert_llama_ggml_to_gguf.py
convert_lora_to_gguf.py

Recorda que como el formato GGUF contiene todo lo que la IA necesita en un solo archivo, es extremadamente necesario que el HF, GGML o Lora que vayas a convertir tenga estos archivos adicionales (o si no fallara todo) en el mismo directorio;

  • config.json
  • tokenizer.json
  • tokenizer_config.json
  • generation_config.json
  • tokenizer.model

Te puedo decir por experiencia que perder 9 hs peleando con que el modelo no podia interpretar caracter alguno por que en el directorio desde donde se convirtieron los archivos le faltaba el “tokenizer.model” no es agradable.

Nota
Todos los tutoriales que veas que usan el script “convert.py” son viejos y desactualizados. Ahora hay scripts específicos como te mostré arriba

Ejecutar modelos localmente

Vamos a utilizar los siguientes componentes para estos escenarios;

  • Llama.cpp como engine para inferencia por CLI (Command Line Interface).
  • Ollama como servidor backend.
  • AnythingLLM como servidor frontend para usar el modelo desde el navegador web.

Llama.cpp

Llama.cpp fue desarrollado por Georgi Gerganov. Implementa la arquitectura LLaMa de Meta en C/C++ eficiente, y es una de las comunidades de código abierto más dinámicas en torno a la inferencia LLM, con más de 900 colaboradores, más de 69000 estrellas en el repositorio oficial de GitHub y más de 2600 versiones.

Vamos a compilar llama.cpp y a saber como usarlo para ejecutar localmente por CLI el modelo;

git clone https://github.com/ggerganov/llama.cpp && cd llama.cpp

Tenemos que instalar los requisitos / dependencias de Python y cmake (dependiendo de su distro tenes que instalarlo de una forma u otra);

pip install --break-system-packages -r requeriments.txt

Creamos el directorio “build” y compilamos dentro de ese directorio;

mkdir build/ && cmake ../

Luego con “make” compilamos el programa, si queres habilitar que use la GPU (guarda que si no tenes suficiente VRAM no vas a poder cargar el modelo) tenes que usar la variable de entorno “LLAMA_CUDA=1”, pero si queres que sea todo en CPU y RAM tiene que tener valor cero;

LLAMA_CUDA=0 make

Luego instalamos el programa para todo el sistema operativo / contenedor (tenes que tener permisos de root con sudo o ser root directamente);

make install

Una vez listo podemos ejecutar el cliente;

llama-cli

Quizás tengas un error de que una librería (por ejemplo; libllama.so) no se encuentra, ejecuta este comando (dentro del directorio de llama.cpp) y andará;

cp bin/*.so /lib/x86_64-linux-gnu/

Vamos a ejecutar este comando para ejecutar el modelo por CLI. Te recomiendo que siempre leas primero el comando y aprendas que esta haciendo antes de ejecutar;

llama-cli -t 8 -np 10 -ngl 0 -cnv -m [path_absoluto_al_modelo_gguf] -p “You are a gentile and useful assistant”

Desgranemos que hace cada argumento;

  • “-t X”

    Ejecuta X cantidad de hilos (threads) para la inferencia. A mayor cantidad de cores en tu CPU es mejor que aumentes este.

  • “-np X”

    Ejecuta X cantidad de secuencias paralelas para decodificar en el “output”. A mayor cantidad de cores en tu CPU es mejor que aumentes este.

  • “-ngl 0”

    La cantidad de capas a ser almacenadas en la VRAM. Yo lo seteo en cero para que ande todo en CPU.

  • “-cnv”

    Modo en conversación.

Si obtenes este error;

terminate called after throwing an instance of 'std::runtime_error'
  what():  this custom template is not supported
Aborted

Entonces hay que crear y especificar el chat template, en llama.cpp define cómo se formatea la entrada para modelos de conversación, asegurando que los mensajes del usuario, las respuestas del asistente y otros metadatos sean procesados adecuadamente.

El formato de la plantilla de chat debe coincidir con el estilo en el que el modelo fue entrenado. ** Cuando tuve este error era por que al convertir el modelo a GGUF me falto el tokenizer.model en la carpeta, asi que fijate si tenes los archivos esenciales que indique antes en “Convertir con llama.cpp”**

El de Gemma 2 es;

{{ bos_token }}{% if messages[0]['role'] == 'system' %}{{ raise_exception('System role not supported') }}{% endif %}{% for message in messages %}{% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %}{{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }}{% endif %}{% if (message['role'] == 'assistant') %}{% set role = 'model' %}{% else %}{% set role = message['role'] %}{% endif %}{{ '<start_of_turn>' + role + '
' + message['content'] | trim + '<end_of_turn>
' }}{% endfor %}{% if add_generation_prompt %}{{'<start_of_turn>model
'}}{% endif %}

Ollama & AnythingLLM

Ollama sirve como un servidor de modelos IAs, por lo que se puede usar en conjunto con frontends como AnythingLLM para disponibilizar los modelos.

  • Crear una IA

    Ollama usa archivos ‘Modelfile’ para especificar todos los parámetros y argumentos a la hora de ejecutar un modelo.

    Si usamos el formato GGUF (como recomiendo y voy a seguir haciendolo) simplemente en el mismo lugar donde esta ese archivo creamos un archivo ‘Modelfile’ con esto dentro;

FROM .

Luego ejecutamos;

ollama create [nombre_del_modelo]:[version_en_modo_TAG]

Cuando el proceso termine podremos verificar que esta disponible con;

ollama ls

Voy a ser sincero, como siempre; si te pones a instalar AnythingLLM, luego ollama y disponibilizar todo vas a estar un buen rato, y eso excede la finalidad de este libro. Yo ya arme un contenedor de docker/podman que tiene anythingllm y ollama funcionando.

La diferencia es que si queres usar tu modelo local en vez de descargar desde los servidores Ollama, tenes que incluir este parámetro cuando ejecutes “[docker/podman] run …”;

-v [path_al_directorio_del_modelo]:/data

Luego en el comando de “[docker/podman] exec” en vez de terminarlo con “/usr/local/bin/ollama pull llama3.1” tenes que poner;

/bin/bash

Luego vas hasta “/data” y ejecutas el comando de “ollama create”.

Por último, abri tu navegador y anda a; http://[IP_de_la_maquina]:3001

Luego selecciona Ollama, y listo. Ya podes usar el modelo sin necesidad de internet desde tu navegador. Considera que la primera vez (y cada 15 minutos si no cambias la configuración) vas a tener que cargar el modelo en RAM. En mi experiencia habiendo quantificado Gemma 2 con 2 mil millones de parámetros (el “2b”), consume unos 7 GB a 8GB en RAM, por eso ejecuto en CPU y no en GPU; no tengo una GPU con tanta memoria (la VRAM).

No te olvides de lo importante que es el formato de chat, AnythingLLM tiene un formato muy general que no va a funcionar muy bien con nuestro formato del datset de Alpaca.

Quantifición

Podes usar herramientas con WebGUI (Web Graphical User Interface) o por scripts para hacer el trabajo de quantificar; he usado programas de la primera opción como Llama-Factory pero luego me di cuenta que es mejor usar código para hacer todo el trabajo.

Te dejo un script en Python en donde ya quantifica Gemma 2 a 8 bits (esto es por que Gemma 2 tiene capas en su red neuronal muy concretas). No pude armar uno general por la propia arquitectura de este modelo, por ende; si queres usar otro usa ChatGPT, Gemini o lo que uses para modificarlo y adaptarlo al modelo que necesitas quantificar a 8 bits.

Fine tuning

Hay dos formas de hacer un fine tuning;

  1. Con una GPU con suficiente VRAM para cargar el modelo, todo el dataset, y las modificaciones con los adaptadores de LoRA.
  2. Con CPU y RAM, que seguramente tenes memoria suficiente para almacenar todo.

Usar GPU para hacer el entrenamiento es muy eficiente, pero considerá lo que dije arriba; Gemma 2 2b (el modelo más chico) quantificado (encima) a 8 bits consume para ejecutarse entre 7 y 8GB. Pocas GPUs tienen VRAM suficiente como para cargar no solamente el modelo si no todo el resto de información.

Usar CPU es mucho más lento, pero es mucho más probable que tengas la RAM suficiente para ejecutar todo.

Como mi caso es de no tener una GPU con VRAM suficiente (una 3050 TI de notebook de 4 GB en VRAM), hice un script en python que se encarga de cargar todo en CPU, una carpeta donde están los JSON para el entrenamiento y realizar el proceso.

Documentos de aprendizaje

Para que puedas consultar en general todo de forma profunda;