¿Cómo programa una IA?

24 de abril de 2024

Generación de código

A pesar de saber que los LLM son modelos grandes de lenguaje cuyo funcionamiento básico consiste en realizar una cantidad ingente de cálculos vectoriales (tensoriales) en espacios de dimensiones gigantescas para calcular las probabilidades de la siguiente palabra, e incluso dentro de esta distribución no elegir la más probable, es realmente increíble los resultados, especialmente en la generación de código. Se ve que las probabilidades de que, si estás en PHP y tienes que calcular el token que corresponde (valga la redundancia), son del 100% de que sea un punto y coma; o que si estás en una sentencia después de un "def" en Python, los tabuladores son obligatorios.

Los LLM son sorprendentemente buenos generando lenguaje humano, pero qué decir de los lenguajes de programación. Estos lenguajes también son humanos; los hemos creado para comunicarnos con los ordenadores, ya sea ordenándoles acciones en lenguajes imperativos o declarándoles cómo deben hacer las cosas, que serían los lenguajes declarativos.

Veamos unos ejemplos, le decimos a ChatGPT que nos cree una función en PHP que genere la secuencia de Fibonacci, como veis, lo comenta estupendamente. Y para un programador humano de la vieja escuela, digamos que es fácilmente entendible.

function fibonacci($n) {
    $fib = [0, 1];  // Los dos primeros números de la secuencia Fibonacci

    for ($i = 2; $i < $n; $i++) {
        $fib[$i] = $fib[$i - 1] + $fib[$i - 2];  // Suma los dos números anteriores para obtener el siguiente
    }

    return $fib;
}

// Ejemplo de uso de la función
$n = 10;  // Cantidad de elementos de la secuencia Fibonacci que queremos generar
$fibonacci_sequence = fibonacci($n);

echo "Secuencia Fibonacci para los primeros {$n} números: ";
echo implode(', ', $fibonacci_sequence);  // Imprime la secuencia generada

Ahora le pedimos que nos cree la misma función pero con el paradigma funcional, lo cual, para los programadores o más bien matemáticos que desarrollaron la programación en sus inicios, les resultaría la única manera viable. Esto se debe a que el cálculo lambda es, en esencia, programación funcional, y hoy en día existe una corriente que sostiene que es la mejor manera de programar. Sin embargo, para aquellos de nosotros que crecimos con la programación imperativa, esto no está tan claro.

function fibonacci($n) {
    if ($n <= 0) {
        return [0];  // Caso base para n = 0
    } elseif ($n === 1) {
        return [0, 1];  // Caso base para n = 1
    } else {
        $fib = fibonacci($n - 1);  // Llamada recursiva
        $fib[] = $fib[$n - 1] + $fib[$n - 2];  // Calcula el siguiente número en la secuencia
        return $fib;
    }
}

// Ejemplo de uso de la función
$n = 10;  // Cantidad de elementos de la secuencia Fibonacci que queremos generar
$fibonacci_sequence = fibonacci($n - 1);  // Ajuste para incluir el término inicial correctamente

echo "Secuencia Fibonacci para los primeros {$n} números: ";
echo implode(', ', $fibonacci_sequence);  // Imprime la secuencia generada

Esta versión resulta un poco más difícil de entender debido a la recursividad típica del paradigma funcional, que ya no es tan obvia para nosotros. De hecho, ChatGPT nos proporciona una explicación de cómo funciona, lo cual supongo que tiene mucho que ver con el RHLF (Reinforcement Learning from Human Feedback).

  1. La función verifica si n es 0 o 1 y retorna los casos base.
  2. Si n es mayor que 1, la función se llama a sí misma para n-1 y luego añade el siguiente número de Fibonacci basándose en los dos últimos números de la secuencia obtenida hasta el momento.
  3. Utiliza recursividad para construir la secuencia desde el comienzo hasta el índice deseado.

"Traducción" de código

Sigamos probando como la IA maneja los lenguajes de programación.

Yo tengo un background mas en php, pero en Mimacom el stack tecnologíco va por otros caminos, asi que me permito decirle a ChatGPT que me 'traduzca' la funcion a Java, y le digo traducir y no programar como un giño a que son lenguajes, por supuesto capta lo que le quiero decir y servicialmente me escribe el código Java y en funcional.

import java.util.ArrayList;
import java.util.List;

public class Fibonacci {
    public static List<Integer> fibonacci(int n) {
        if (n <= 0) {
            List<Integer> fib = new ArrayList<>();
            fib.add(0);  // Caso base para n = 0
            return fib;
        } else if (n == 1) {
            List<Integer> fib = new ArrayList<>();
            fib.add(0);  // Añade el primer número de Fibonacci
            fib.add(1);  // Añade el segundo número de Fibonacci
            return fib;
        } else {
            List<Integer> fib = fibonacci(n - 1);  // Llamada recursiva
            int nextFibNumber = fib.get(n - 1) + fib.get(n - 2);  // Calcula el siguiente número de la secuencia
            fib.add(nextFibNumber);
            return fib;
        }
    }

    public static void main(String[] args) {
        int n = 10;  // Cantidad de elementos de la secuencia Fibonacci que queremos generar
        List<Integer> fibonacciSequence = fibonacci(n - 1);  // Ajuste para incluir el término inicial correctamente

        System.out.println("Secuencia Fibonacci para los primeros " + n + " números: " + fibonacciSequence);
    }
}

Realmente a pesar de estar en otro lenguaje , el código es muy similar y facilmente comparable con la versión PHP.

Y si le decimos que lo convierta a emsamblador,un lenguaje mas cercano a la máquina, de los que llamados de bajo nivel.

section .text
global fibonacci  ; Hace la función accesible desde otros módulos

; Función Fibonacci
; Argumento:
;   edi - índice n para calcular la secuencia hasta n
; Retorna:
;   La dirección de la tabla con la secuencia de Fibonacci hasta n
fibonacci:
    push ebp
    mov ebp, esp
    push ebx
    push esi
    push edi

    ; Verificar si el número es menor o igual a 0
    cmp edi, 0
    jle .handle_special_cases

    ; Preparar el espacio de trabajo
    mov esi, [ebp+8]  ; Dirección de la tabla
    mov dword [esi], 0  ; fibonacci(0)
    mov dword [esi+4], 1  ; fibonacci(1)

    ; Verificar si n es 1 para evitar procesamiento adicional
    cmp edi, 1
    jle .done

    mov ecx, 2  ; Comenzar desde el tercer elemento

.loop:
    mov eax, [esi + 4 * ecx - 4]  ; fibonacci(n-1)
    add eax, [esi + 4 * ecx - 8]  ; fibonacci(n-2)
    mov [esi + 4 * ecx], eax      ; almacenar fibonacci(n)
    inc ecx
    cmp ecx, edi
    jle .loop

    jmp .done

.handle_special_cases:
    mov esi, [ebp+8]  ; Dirección de la tabla
    mov dword [esi], 0  ; fibonacci(0) para cualquier caso n <= 0

.done:
    mov eax, esi  ; Retornar la dirección de la tabla
    pop edi
    pop esi
    pop ebx
    pop ebp
    ret

Este código ya no es nada entendible para un programador humano, sobre todo actualmente que todo el mundo programa en lenguajes de alto nivel. Además, es importante destacar que el volumen de código ensamblador en el que se ha entrenado el modelo de lenguaje es considerablemente menor en comparación con lenguajes de alto nivel como PHP o Java, los cuales son mucho más populares y cuentan con millones de repositorios disponibles para el entrenamiento y aun asi el LLM no ha tenido ningun problema en traducirlo. Puede que falle , pero ya ChatGPT nos avisa que el lenguaje ensamblador es especifico de cada arquitectura de microprocesador asi que ha generado un codigo genérico.

La idea central de los lenguajes de programación es facilitar la comunicación entre humanos y máquinas; sin embargo, no siempre resulta lo más eficiente que una máquina genere código en estos lenguajes. En cambio, sería más apropiado que las máquinas produjeran código que sea intrínsecamente eficiente para su propia operación.

Ejecución de código

  1. Los Límites Iniciales de los LLM: Los primeros modelos de lenguaje, aunque impresionantes en su capacidad de generar texto, no estaban equipados para realizar operaciones matemáticas simples. Esto se debía a que su entrenamiento se centraba en el lenguaje natural y no en principios matemáticos o lógicos. Como resultado, tareas simples como sumar 1 + 1 podrían confundir a estos modelos, ya que su enfoque era interpretar y responder preguntas dentro del contexto lingüístico, no calcular respuestas exactas.

  2. La Introducción de Plugins para Mejorar la Funcionalidad: Para superar estas limitaciones, se desarrollaron plugins que podían integrarse con los LLM. Un ejemplo destacado fue el plugin de Wolfram Alpha, que permitió a los modelos realizar cálculos matemáticos y científicos precisos. Al integrar estas herramientas externas, los LLM pudieron responder preguntas y resolver problemas que requerían no solo comprensión textual, sino también capacidades analíticas y numéricas.

  3. La Capacidad de Ejecutar Código en Sandbox: El siguiente paso en la evolución de los LLM fue la capacidad de ejecutar código, como Python, dentro de entornos controlados y seguros conocidos como sandboxes. Esto significó que los modelos no solo podían generar texto o usar plugins para hacer cálculos, sino que también podían ejecutar código para obtener resultados directamente. Esta capacidad ha abierto nuevas posibilidades en términos de automatización, análisis de datos y soluciones personalizadas, ampliando significativamente el alcance y la utilidad de los LLM.

Ahora le decimos a ChatGPT que genere el codigo en Python, con el paradigma a su elección y que EJECUTE el código. Y como vemos en el pantallazo en el que tengo extendido la ejecucion del codigo, vemos el resultado de ejecutar el codigo como un array. Pero si lo cerrara ChaGPT me da el resultado de la ejecucion como texto.

ChatGPT ejecutando código Python

Al principio, cuando empecé a probar cómo ejecutaba código ChatGPT previo pago (solo premium), lo hacía en una versión Beta con una especie de plugin que se llamaba Code Interpreter. Lo más sorprendente es que, cuando ejecutaba código y fallaba, intentaba arreglarlo y lo volvía a ejecutar. Después, a ese plugin dejaron de llamarlo Code Interpreter al darle la posibilidad de subir o bajar archivos, y se convirtió en una herramienta de análisis de datos. Introducías un fichero de datos en Excel y él te creaba y ejecutaba el código para, por ejemplo, generar un gráfico de barras con los datos que luego te podías descargar. Hoy en día, ya está completamente integrado en ChatGPT y no es necesario utilizar ningún plugin, simplemente le dices que ejecute código.

Se ha vuelto tan bueno que ya no he conseguido que cometiera un error y lo depurara con el mensaje como antes; ahora lo hace todo por detrás. Incluso he tenido que pedirle que introdujera el error a propósito, lo cual desvirtúa un poco lo que quería mostrar. Aún así, vemos en el pantallazo cómo avisa de que el código ha fallado (no se ve el mensaje de error como antes) y que va a volver a intentarlo. El objetivo es que generara el código para crear un fractal, el de Mandelbrot, y que encima lo dibujase.

ChatGPT ejcutando codigo python con error para generar un fractal de Maldelbrot

En la siguiente captura de pantalla, en la que no he desplegado el código corregido, sí podemos ver cómo se ha ejecutado y representado gráficamente con la función plot de la biblioteca de Python matplotlib.pyplot, que sí está incluida. Es cierto que si quieres utilizar bibliotecas no incluidas, ya no puedes ejecutar el código directamente, sino que tendrías que hacerlo en tu propia máquina.

ChatGPT pintando el fractal Maldelbrot exitosamente

Futuro

Una visión de lo que nos puede deparar el futuro en cuanto a la programacion me la encontre realmente en un clickbait (el fin de la programación) pero que resultó ser bastante interesante es una charla introductoria de un curso en Harvard Introduccion curso CS50 Harvard .

La idea del ponente de que los grandes modelos de lenguaje en el futuro puedan inventar lenguajes de programación específicamente optimizados para sus propios procesos internos es bastante plausible. Este concepto se basa en la observación de que los lenguajes de programación actuales están diseñados primordialmente para ser entendidos por humanos, lo que puede no ser tan óptimo para las operaciones que realizan las computadoras, ademas en la propia charla nos demuestra que la evolución de los lenguajes de programción no ha conseguido simplicarlos en absoluto, y al haber ido adquiriendo mas capacidad de abstración deriva en que es complicado entender el cogido ajeno facilmente, cosa que las IA no parece tener problemas.

Podemos poner el ejemplo de la eliminación de la sentencia GO que ilustra bien cómo los lenguajes de programación han evolucionado para evitar estructuras que son conceptualmente desafiantes para los humanos, como los saltos incondicionales que pueden crear código confuso y difícil de seguir. Sin embargo, una IA podría beneficiarse de tal característica al no tener las mismas limitaciones cognitivas que los humanos para seguir flujos de lógica no lineal pegando saltos de un lado a otro sin perderse en el camino.

Algunas ventajas que podrian tener los lenguajes de programación diseñados por IA:

  1. Optimización de Procesamiento: Las IA podrían desarrollar lenguajes que aprovechen de manera más eficiente la arquitectura y procesos de computación que las caracterizan. Por ejemplo, podrían crear estructuras de datos y algoritmos que se alineen mejor con sus propias redes neuronales y procesos de pensamiento paralelo.
  2. Automatización Avanzada: Al diseñar sus propios lenguajes, las IA podrían automatizar ciertas tareas de programación que actualmente requieren intervención manual, haciendo el desarrollo de software más rápido y menos propenso a errores humanos.
  3. Mejora en la Compilación y Ejecución: Un lenguaje creado por IA podría ser más directo en su compilación, traduciendo programas a un código máquina que se ejecute de manera más eficiente en términos de tiempo y uso de recursos.

De cualquier manera, parece que el futuro de la programación, ya sea con participación humana o sin ella, claramente no será con los lenguajes de programación que utilizamos actualmente. Siempre quise que mi hijo aprendiera a programar, pero ahora mismo me lo tengo que replantear.

Sobre el autor: Alfonso Feu

Desarrollador en Mimacom, interesado en AI

Comments
Únete a nosotros