El intérprete está en la sala de reuniones y traduce cada palabra. Pero de repente se da cuenta de que puede mejorar su traducción si aprende de sus errores. Empieza a anotar qué frases causaron malentendidos y las corrige. Al cabo de una hora, su traducción es más precisa y la reunión avanza más rápido. Pues aquí ocurre lo mismo: un intérprete de Scheme, compilado una sola vez, puede ejecutar cualquier programa que se le pase como datos y, además, calcular gradientes para mejorar esos programas.
Antes, cada modelo científico había que reescribirlo manualmente en forma diferenciable para poder aplicar optimización por gradientes. Es como si para cada texto nuevo hubiera que contratar a un intérprete nuevo. Ahora, el propio intérprete se vuelve entrenable: no solo traduce, sino que también entiende cómo modificar el texto para mejorarlo. Los autores han creado un compilador que traduce el código fuente en Scheme a una representación intermedia llamada ComputeGraph, y de ahí a módulos de PyTorch o JAX. La característica clave es que lo que se vuelve diferenciable es el propio intérprete, no los programas individuales.
Dentro del intérprete, todos los valores se representan como vectores de 14 dimensiones: una etiqueta de tipo one-hot de 10 dimensiones y una carga útil de 4 dimensiones. El montón se implementa como un diccionario de escritura única, lo que preserva la corrección de los gradientes. Para las llamadas en posición final se usa un trampolín, es decir, un bucle que sustituye a la recursión profunda y evita que la pila crezca. Gracias a esto, los gradientes calculados a través del intérprete compilado coinciden con la compilación directa con una precisión de hasta 7×10⁻⁷ en la función de pérdida en 171 pares (programa, valor inicial).
En datos reales de degradación de baterías, la búsqueda conjunta de estructura y parámetros recuperó la estructura de codo en la degradación a partir de una aproximación inicial suave y mejoró la extrapolación en datos reservados. En el problema de modelado inverso de El Niño, el intérprete diferenciable permitió optimizar la función de verosimilitud del filtro de Kalman con 611 parámetros, donde la búsqueda sin gradientes no funcionó. El procesamiento por lotes proporcionó una aceleración de hasta 875 veces en rendimiento.
Ahora el intérprete no solo traduce, sino que aprende de cada palabra. Puede calibrar automáticamente los parámetros de modelos generados por modelos de lenguaje en tareas científicas y de ingeniería. Es como si el intérprete, al recibir un borrador del escritor, lo puliera él mismo hasta dejarlo perfecto, sin necesidad de reescribirlo desde cero. Volviendo al principio: un intérprete que aprende de cada palabra convierte una hora de reunión en minutos, y hace que la ciencia sea más rápida y precisa.
El intérprete de Scheme, escrito en el propio Scheme, ocupa solo 288 líneas de código. Y soporta cierres, recursión, listas y llamadas en posición final, lo suficiente para ser autoaplicable.
La idea de un programa que puede modificarse y mejorarse a sí mismo mediante gradientes resuena con el concepto de máquinas de Gödel de Jürgen Schmidhuber, descrito en sus trabajos sobre automejora universal.