miércoles, 21 de enero de 2026

Grietas en el determinismo de los modelos generativos: limitaciones, errores e imprevistos

Ya he hablado en algunos post recientes sobre el carácter probabilista o determinista de los modelos generativos, en especial de los grandes modelos de lenguaje, LLM ('Large Language Models').

Mi conclusión hasta ahora, es que, aunque de comportamiento externamente probabilista, internamente tienen un funcionamiento plenamente determinista. Incluso, como veíamos en el último post de la serie hasta ahora, esa aleatoriedad externa se puede exacerbar y, lo que es más importante, eliminar, o congelar, usando parámetros de configuración.

Y esta conclusión momentánea, excluye, en mi opinión,  la posibilidad de un libre albedrío de las máquinas.

Sin embargo, hay experiencias prácticas y estudios científicos que desafían ese determinismo subyacente, y que muestran que, aunque los modelos 'se congelen' (es decir, se elimine el carácter probabilista mediante el ajuste de parámetros), se siguen produciendo resultados no deterministas.

¿Cómo es eso posible?

Según vamos a ver, creo que podemos considerar que esos efectos no deterministas se producen por limitaciones en el hardware y errores en el diseño o implementación de los modelos o, si preferimos no ser muy duros, por la aparición de fenómenos imprevistos, muy difíciles de haber anticipado a priori.

En este post, probablemente el más técnico de la serie, vamos a revisar algunos de esas limitaciones, errores o imprevistos que desafían el determinismo de los modelos.

Y para ello me baso en el muy interesante, pero también complejo, artículo 'Defeating Nondeterminism in LLM Inference' publicado por  Thinking Machines la startup de Mira Murati, quien fuera CTO ('Chief Technology Officer') de OpenAI.


Los números reales y la coma flotante


El primero de los problemas que se describe en el artículo, pero que ha sido tratado anteriormente por otros autores, aborda problemáticas derivadas del trabajo con números reales representados en el formato denominado 'coma flotante'.

Recordemos brevemente qué es eso de 'coma flotante'. Se trata de una estrategia de representación en formato digital (unos y ceros) de números reales (por entendernos, los que tienen decimales).

Supongamos que queremos representar números reales usando 4 bytes (es decir, 32 bits y, por lo tanto, la posibilidad, a priori, de representar 232 números diferentes). Si ahora queremos representar números decimales, podríamos decidir dedicar tres bytes a representar la parte entera del número y uno a representar la parte decimal. Con esto, tendríamos lo siguiente:


  • Un bit para indicar el signo (positivo o negativo)

  • 23 bits para indicar la parte entera, con lo cual, podríamos representar hasta el 223, es decir, hasta 8.388.608

  • 8 bits para la parte decimal, lo cual nos daría una precisión (incremento más pequeño, por decirlo de alguna manera, de 2-8, es decir 0,00390625


Esto es fácil de entender y gestionar, pero tiene dos problemas: un rango limitado (cantidad de números que puede representar) y una precisión limitada. Aparte de la opción de incrementar el numero de bits, la que se suele adoptar es usar el denominado formato de coma flotante, que es lo que estamos acostumbrados a visualizar como 'notación científica'.

En este caso, representamos un número real 'x', que 'pensamos' como


x = ± m×2e


donde m es lo que se denomina mantisa y que está constituido por las cifras significativas (aquellas que aportan información real sobre su valor, excluyendo, en esencia, los ceros que sirven solo como relleno de posición) y 'e' es el exponente (que puede ser positivo o negativo)

En el caso del formato se simple precisión IEEE 754, los bits se utilizarían de la siguiente forma:

  • un bit para el signo

  • 8 bits para el exponente, que es quien controla, en el fondo, la posición de 'la coma' en la representación binaria

  • 23 bits para la mantisa

No quiero, 'liarlo' ya mucho más, pero sí decir que los bits que utilizamos en la mantisa nos dan la precisión, que en esta caso son 24 bits (23 bits de la mantisa más uno).

Esta forma de representar los números reales, habituales en cálculos científicos y, desde luego, en machine learning, tiene ventajas de cubrir rangos muy amplios pero viene con alguna limitación o desventaja. Por un lado, necesita de un hardware y software más complejo y, sobre todo, y lo que nos interesa en este momento es que, no sólo no puede representar de manera exacta muchos números (por falta de precisión) y, lo más importante de todo: comete errores de redondeo.


Asociatividad y condiciones de carrera


Cuando usamos la representación en coma flotante cada representación concreta de un número tiene la misma precisión pero puede tener 'la coma' en un sitio diferente.

En el artículo se nos muestra con un ejemplo sencillo cómo si sumamos dos números en coma flotante con diferente posición de 'la coma', es decir, con diferente exponente, puede suceder que el numero resultante (la suma) necesite de una precisión superior a aquella de la que disponemos (digamos porque uno es muy grande y el otro muy pequeño). Representar correctamente el número resultante, un número 'muy grande' pero 'con muchos decimales',  implicaría disponer de más bits en la mantisa de los que tenemos.

Por tanto, en la operación es preciso hacer un redondeo que nos permita encajar el resultado en la precisión disponible. Y, en ese redondeo, perdemos información, generamos un cierto error.

En el artículo se nos explica que, en ese caso, el orden en que realizamos las operaciones entre números (los mismos números) impacta en el resultado. En concreto, nos muestra cómo la propiedad asociativa 


a + (b + c) = (a + b) + c


no se mantiene, realmente. Para, admitiendo que se puede producir un error de redondeo pero que, al menos, eso no llevase a resultados diferentes en ejecuciones diferentes, habría que garantizar que las operaciones se realizan exactamente en el mismo orden

Pero eso, ese mantenimiento del mismo orden, no sucede, y la explicación de por qué no sucede nos lleva al mundo del hardware, de los famosos GPU ('Grahical Processing Unit') y procesadores similares


El hardware y condiciones de carrera no deterministas


Los modernos procesadores, como los GPUs, están compuestos de muchos núcleos o 'cores' que pueden procesar en paralelo diferentes operaciones, siendo las operaciones que se paralelizan en una GPU para tratar muchos datos, lo que se conoce como 'kernels' (que, lamentablemente, en castellano se suele traducir también como núcleo). Estos 'cores' funcionan de manera concurrente y sin sincronización entre ellos.

Una hipótesis formulada en otros trabajos para explicar el no determinismo, supone que el problema del no determinismo nace de que los propios 'cores' funcionan de manera no determinista. Esto quiere decir que un algoritmo hace que se lancen concurrentemente varios cálculos cuyos resultados luego, digamos, que se van a ir por ejemplo sumando (acumulando) a medida que acaben. Pero no es determinista cuándo finaliza cada 'core su cálculo y, por tanto, no es podemos saber en qué orden se va a a sumar o acumular cada resultado parcial.

Como, por lo que hemos visto más arriba, en operaciones en coma flotante  se producen errores de redondeo diferentes según el orden de las operaciones, esto lleva a que el resultado final del algoritmo sea no determinista.

Sin embargo, aunque los autores del artículo explican esta hipótesis, afirman que en la práctica, los problemas reales y las implementaciones reales de las típicas librerías python involucradas, hacen que este problema no aparezca nunca o casi nunca.


Peticiones en paralelo


Los autores, sin embargo, aportan otro escenario.

Indican que los LLMs cuando se utilizan en inferencia ('forward pass') son, en efecto, deterministas. Ante una misma petición del usuario, responderán lo mismo (asumo que hemos eliminado el paso final de selección probabilista de token que expliqué en el post anterior).

El problema, según indican, es la concurrencia de diferentes peticiones  y la creación, por ello, de diferentes 'batches'. Es decir, mantienen que si, el 'forward pass' considerado individualmente es determinista, pero el sistema en su conjunto, no.

Antes de seguir, comentar que los 'batches' son las entradas que, efectivamente, se envían a un LLM. Por eficiencia de implementación, los batches que se envían pueden, en realidad, incluir textos de entradas de usuario diferentes. Aunque, en teoría, el tamaño de los batches y las entradas que combinan no debería afectar al resultado, los autores muestran que no es así, que sí que afectan

Y eso porque no existe en los 'kernels' la denominada 'batch-invariance', es decir, el procesamiento de las peticiones de un usuario no es completamente independiente de los batches que procesa y, por tanto, del procesamiento de las peticiones de otro usuario. 

Para explicarlo los autores se centran en las operaciones de multiplicación de matrices (que se utilizan profusamente en machine learning y deep learning y, por tanto, también en la inferencia de los LLMs).

Parece que, esas operaciones deben ser deterministas (y en teoría lo son) y que, además, no les debería afectar otras operaciones en paralelo. Bueno, pues esto último, no es del todo cierto.

¿Por qué?

.Pues porque la carga computacional a que se ve sometido un LLM (y, sobre todo, el hardware que lo soporta) se ve afectado por la cantidad y naturaleza de las peticiones a que se ve sometido. Es decir, el tamaño de los  'batches' que se van enviando al LLM se pueden modificar según la carga, o dicho de otra forma, la carga computacional determina el tamaño de batch. Y como los 'kernels' no son invariantes respecto al batch (no son 'batch-invariant') el resultado puede modificarse según sean las peticiones en paralelo.


En busca de la invariancia


Todo lo que he explicado hasta el momento, apenas ocupa la mitad, aproximadamente, del artículo en que me baso. En lo que resta, los autores, se centran en indicar (de forma muy técnica) cómo conseguir que los 'kernels' sean realmente 'batch-invariant'. Para ello, asumen que las operaciones más básicas son invariantes y entienden que basta con conseguir la invariancia en tres operaciones complejas y muy importantes, a saber:


  • La aplicación de la RMSNorm ('Root Mean Square Normalization'), operación de normalización (ajuste de los valores a un rango concreto)  usada en entrenamiento e inferencia

  • Multiplicación de matrices

  • Mecanismo de atención: elemento fundamental de las arquitecturas transformes y que aporta el nivel de importancia que se asigna cada elemento de la entrada


Los autores, además, afirman disponer de una implementación de esas soluciones y aportan datos de los experimentos realizados


Vuelta al determinismo


En sus conclusiones, los autores se posicionan a favor del determinismo de los algoritmos en el sentido de que, no debemos aceptar los errores que se han observado (y que hemos descrito) y que llevan a que los LLMs no sean completamente deterministas.

Dicen que, con un poco de trabajo, se pueden entender las causas raíces de ese determinismo y resolverlas. Y abogan por ello, claro.


Implicaciones de cara al libre albedrío de las máquinas


Si aplicamos las recetas de estos autores, está claro que volvemos a la situación que yo siempre había afirmado (y que aquí hemos visto algunas grietas) volveríamos a estar en el caso de algoritmos plenamente deterministas, al menos en su comportamiento interno, aunque así no en su manifestación externa. 

Y, en ese sentido, no habría lugar, al menos eso entiendo yo, para pensar en un libre albedrío ni voluntad propia de las máquinas, al menos las actuales.

Pero ¿Y qué pasa si no resolvemos eso? ¿Qué pasa si se siguen produciendo errores de redondeo y, sobre todo, si esos errores, ante condiciones de carrera o peticiones en paralelo de usuarios y unos 'kernels' no invariantes en batches, nos llevan a resultados no deterministas? 

¿Abre eso realmente la puerta a un libre albedrío de las máquinas?

Creo que esa reflexión la reservo para un siguiente post, algo menos técnico y más especulativo y filosófico y con el que, creo, cerraré de momento este pequeño grupo de artículos dedicados al determinismo de los modelos generativos.


Conclusiones


Aunque externamente los modelos generativos, y en concreto los LLMs, se manifiestan como probabilistas, en su funcionamiento interno siguen algoritmos muy claros (aunque complejos) y en que el comportamiento probabilista está también perfectamente delimitado mediante parámetros de configuración por lo que, internamente, y sobre todo para razonar sobre libres albedríos, podemos considerarlos, en principio, deterministas.

Sin embargo, según hemos visto en este artículo, hay algunas grietas no buscadas en ese determinismo, pequeñas dosis de aleatoriedad no controlada y achacables, podríamos decir, a errores de diseño o implementación debidos, seguramente, a imprevistos.

En el propio artículo hemos visto que hay alguna propuesta para 'devolver al redil' a esos LLMs y que vuelvan a ser, internamente, plenamente deterministas.

Lo que queda por razonar es si esas brechas en el determinismo, realmente abren alguna posibilidad al libre albedrío de las máquinas o no.

Pero eso queda ya para otro post.


Artículos de este blog relacionados

No hay comentarios:

Publicar un comentario