Large Language Model (LLM) from scratch. Intro.

Un Large Language Model (LLM) es un tipo de modelo capaz de entender y generar lenguaje natural, y se entrena utilizando grandes cantidades de datos. El ejemplo más popular de este tipo de modelos es ChatGPT, conocido por la calidad de sus respuestas, que se debe al alto nivel de inteligencia que ha alcanzado.

Si bien ChatGPT —y otros modelos similares— puede resolver una lista prácticamente interminable de problemas actuales, existen razones de peso para plantearse el desarrollo de un LLM propio. A mi juicio, la más importante es el control sobre las salidas del modelo. Como comentamos, estos sistemas se entrenan con cantidades masivas de datos, en su mayoría procedentes de la web u otras fuentes cuya fiabilidad no siempre puede verificarse por completo. Esto abre la puerta a respuestas sesgadas o, en el peor de los casos, claramente inapropiadas.


Aunque OpenAI ha invertido un esfuerzo considerable en mitigar este tipo de comportamientos (con un éxito razonable), considero que, para una institución —especialmente gubernamental— el escenario ideal consiste en minimizar al máximo la probabilidad de que el modelo genere contenido que pueda dañar su reputación o credibilidad. Una forma de avanzar en esa dirección es construir y depurar un conjunto de datos cuya fiabilidad pueda ser auditada por la propia institución y utilizarlo como base para entrenar (o especializar) el modelo. Por ello, diseñar LLMs orientados a fines específicos puede resultar especialmente valioso.

Dicho lo anterior, y antes de empezar con el tutorial, hay dos puntos que aclarar. Primero: OpenAI dispone de herramientas para mitigar salidas no deseadas. Segundo: con la tecnología actual, incluso si la entrada de datos es cien por ciento fiable, la probabilidad de que el modelo genere salidas no deseadas no será cero.

Manos a la obra

En este tutorial utilizaremos como referencia el libro de Daniel Jurafsky y James H. Martin (2025). En particular, en esta entrada seguiremos de cerca el capítulo 2, que define conceptos clave que serán útiles para codear nuestro primer LLM tipo transformer.

Primero, es necesario explicar cómo funcionará el modelo. En términos simples, el modelo recibe un texto de entrada y, a partir de él, genera un nuevo texto como salida. Para poder hacerlo, necesita transformar ese texto en unidades que pueda manejar internamente. Lo habitual es definir un vocabulario de tokens (pequeñas unidades de texto) e incorporarlo al modelo, de modo que pueda mapear cada fragmento del texto de entrada a un token conocido y, con esa representación, calcular paso a paso los tokens que compondrán la respuesta.

De manera intuitiva, podría pensarse que dicho vocabulario debería estar formado por palabras completas. Sin embargo, esto plantea un problema importante: el número de palabras distintas crece a medida que aumenta la cantidad de texto. En la práctica, esto significa que, si usáramos solo palabras como unidades, el modelo se encontraría continuamente con formas que no están en su vocabulario fijo (palabras fuera de vocabulario) y no podría representarlas adecuadamente. Por este motivo, es necesario considerar unidades alternativas. A continuación presentamos otro posible candidato: los morfemas.

Morfemas…

Como sabemos, una palabra posee significado. Sin embargo, desde una perspectiva lingüística también es posible centrarse en una sola palabra y buscar unidades de significado más pequeñas en su interior. A estas unidades se les llama morfemas.

Por ejemplo, la palabra “vivía” puede analizarse en dos morfemas: el lexema “viv-”, que aporta el significado básico (vivir), y “-ía”, que es el morfema verbal flexivo que indica tiempo, modo y persona. En este sentido, podríamos definir una unidad como “viv” y otra como “ía”. Así, si nuestro vocabulario contiene las unidades “viv”, “ía” y “sab”, y en el texto de entrada aparece la palabra “sabía”, el modelo podría representarla combinando “sab” + “ía”, sin necesidad de que “sabía” esté incluida explícitamente en el vocabulario.

El problema es que, en la práctica, no siempre hay un consenso claro sobre dónde cortar el morfema. Si hilamos fino, “vivía” también puede descomponerse como “viv-” (lexema), “-í-” (vocal temática) y “-a” (desinencia de imperfecto), lo que nos daría tres unidades en vez de dos, como en el ejemplo anterior. Es decir, el número y los límites de los morfemas dependen del criterio teórico y del nivel de detalle que adoptemos.

Debido a esta dificultad para definir y segmentar morfemas de forma clara y automática (además de otros problemas técnicos que exceden esta entrada), los morfemas, por sí solos, no constituyen un buen candidato de vocabulario para el modelo.

Caracteres individuales…

Entonces, si usar palabras o morfemas como tokens no resulta adecuado, podríamos pensar que un buen vocabulario serían los caracteres individuales. Sin embargo, esta opción también tiene importantes inconvenientes: al representar cada carácter como un token, el número de tokens por texto se dispara, lo que encarece mucho el entrenamiento (las secuencias son más largas y el modelo debe procesar muchos más pasos) y hace la inferencia más lenta y menos eficiente.

Byte-pair Encoding (BPE)

Como vimos, si utilizamos palabras completas como tokens, las palabras desconocidas se convierten en un problema. También vimos que los morfemas como unidad de tokenización no son una opción práctica, y que trabajar a nivel de caracteres resulta, entre otras cosas, mucho más costoso. Una solución intermedia entre estas alternativas es el algoritmo BPE. Este algoritmo aprende un vocabulario de subpalabras que puede incluir caracteres sueltos, fragmentos de palabra cercanos a morfemas e incluso palabras completas, reduciendo de forma considerable el problema de las palabras fuera de vocabulario y mejorando la eficiencia con respecto a usar solo caracteres. En la siguiente entrada explicaremos este algoritmo con más detalle.

Notas finales, y próxima entrada…

En esta serie de publicaciones mostraremos cómo construir un LLM desde cero. Para ello, era fundamental exponer algunas ideas clave, como vocabulario, tokens y la motivación detrás de algoritmos como BPE. Ahora, con esta base en mente, en la siguiente entrada explicaremos en detalle cómo funciona dicho algoritmo.

José Miguel Muñoz Urra – jmunozu@pulki.es