En la publicación pasada entendimos la estructura general de un LLM. Este paso es vital, puesto que nos da una visión panorámica sobre la morfología de estos modelos. Con esto en mente, ahora podemos estudiar la arquitectura de aquellos.
Existen múltiples arquitecturas para diseñar un LLM, no obstante, en esta entrada vamos a estudiar transformers, puesto que es la que emplean los LLM más famosos, tales como GPT, BERT, T5, LLaMa, etc.
Al igual que en la entrada anterior, usaremos como referencia a Jurafsky y Martin (2026), como es usual. Cualquier error es mi responsabilidad.
Atención
En el contexto específico de transformers, el concepto de atención fue introducido por Vaswani et al. (2017). Este artículo, y concepto, son importantes por varias razones, no obstante, en este momento se me ocurren dos muy obvias: la atención está presente en los LLMs más famosos, tales como GPT, BERT, etc., y además, el artículo tiene más de 250 mil citas (a mayo de 2026).
En términos formales, la atención es un mecanismo que permite construir una nueva representación contextual de un token combinando información de otros tokens de la secuencia.
Pero, ¿Por qué necesitamos una nueva representación contextual?. Primero que todo, recordemos algunos conceptos expuestos en la entrada sobre embeddings. En esta publicación, representábamos el significado de una palabra de forma vectorial y estática, es decir, los valores de los componentes del vector de la palabra no dependen del contexto en el que se encuentre. Esto es problemático porque muchas veces la idoneidad de la palabra es definida por el contexto. Por ejemplo:
El coche no siguió avanzando por el camino porque este estaba mojado.
El coche no siguió avanzando por el camino porque este estaba averiado.
En este caso, en la primera oración, el coche no avanzó porque el camino estaba mojado, y en la segunda, porque el coche estaba averiado. Como podemos ver, el contexto determina el significado de la palabra «este».
Entonces, respondiendo a la pregunta, sobre si una nueva representación conceptual es necesaria, si, es absolutamente necesaria, puesto que ayuda al modelo a distinguir este tipo de sutilidades.
Ahora que sabemos por qué una representación contextual es necesaria, estamos en condiciones de explicar el concepto de atención. Formalmente, se podría definir como el mecanismo mediante el cual el transformer toma , es decir, la representación vectorial del token que está en la posición de la secuencia, y produce , una nueva representación del mismo token, pero enriquecida con información de los tokens anteriores. En un modelo causal, como GPT, esta información sólo puede venir del propio token y de los tokens que aparecen antes de él, no de los tokens futuros.
Para entender esta idea, usaremos una versión simplificada de lo que realmente ocurre, tal y como lo muestra Jurafsky y Martin (2026). Para esto, asumiremos la siguiente estructura:
Es decir, en la posición de la secuencia, tomamos la representación vectorial de los tokens anteriores (incluyendo ), y los ponderamos por . Luego, para obtener este último, calculamos el score, y lo pasamos por la softmax:
¿Por qué calculamos el producto punto? Recordemos que este se puede interpretar como una medida de similitud entre dos vectores, entonces, si el vector de un token previo es parecido al vector del token actual , entonces probablemente contiene información útil para interpretar o representar mejor a . En términos prácticos, supongamos el siguiente ejemplo:
El gato es buena mascota. Este felino…
Supongamos que en esta frase estamos analizando . Es de esperar, que la similitud entre y , sea mayor a la similitud entre y . Lo anterior implica que . Por tanto, el vector contextualizado del token felino, , contendrá más información de gato que del token buena.
Esta metodología fue desarrollada por Jurafsky y Martin (2026) con fines pedagógicos, no obstante, el funcionamiento de la atención es más compleja. Esta, tiene conceptos adicionales como attention head, query, key y value. A continuación veremos cada uno, y cómo se relacionan.
Attention head, query y value
Una attention head es un componente de atención que toma las representaciones vectoriales de los tokens y las proyecta en tres espacios distintos: queries, keys y values. La query corresponde a la representación del token actual en su rol de búsqueda; las keys corresponden a las representaciones de los tokens del contexto en su rol de comparación; y los values corresponden a la información que finalmente será ponderada y sumada. De esta forma, la cabeza de atención compara la query del token actual con las keys de los tokens disponibles en el contexto —en un transformer causal, el propio token y los tokens anteriores—, transforma esas comparaciones en pesos de atención y usa esos pesos para combinar los values. El resultado es una nueva representación del token actual, enriquecida con información contextual. En la siguiente imagen, podemos ver con más claridad qué ocurre:

En el ejemplo de la ilustración, tenemos tres tokens de entrada que vienen en forma de embeddings: , y , siendo este último, el token que estamos analizando. Nuestro objetivo es calcular , es decir, una nueva representación contextualizada de ese token. Para ello, primero proyectamos cada vector de entrada en tres representaciones distintas: key, query y value. Estas proyecciones se obtienen mediante tres matrices aprendidas por el modelo:
donde es la query, es la key y es el value correspondiente al token en la posición .
Como queremos calcular la salida de atención para , usamos la query de , es decir, , y la comparamos con las keys de los tokens disponibles en el contexto. Puesto que estamos en un modelo causal, puede atender a , y a sí mismo, pero no a tokens futuros. Por lo tanto, calculamos los siguientes scores:
El producto punto mide la compatibilidad entre la query del token actual y la key de cada token del contexto. Luego, dividimos por para evitar que los scores crezcan demasiado cuando la dimensión de las queries y keys es alta.
Posteriormente, pasamos estos scores por una softmax. Esto nos permite convertir los scores en pesos de atención:
Formalmente:
para . De esta forma, los pesos de atención son números positivos que suman 1:
Cada indica cuánta información del token será incorporada en la nueva representación de .
Una vez obtenidos los pesos de atención, podemos calcular la salida de la cabeza de atención para el token . Para ello, hacemos una suma ponderada de los value vectors:
El vector tiene dimensión:
Sin embargo, la arquitectura del transformer necesita que la salida de la atención tenga la misma dimensión que la representación original del token, es decir:
Por esta razón, multiplicamos por una matriz de salida :
donde:
Así, la operación tiene la siguiente forma:
El resultado final es:
Es decir, es una nueva representación del token , enriquecida con información de , y del propio . Esta representación mantiene la misma dimensionalidad que la entrada, lo que permite integrarla al flujo residual del transformer y pasarla a las siguientes capas.
Para verlo con un ejemplo pequeño, supongamos que:
Entonces podría ser un vector de tres dimensiones:
y tendría dimensión :
La multiplicación sería:
Por lo tanto:
Así, aprende cómo transformar y mezclar la información contenida en para devolverla al espacio general del modelo.
Dicho esto, en términos formales, el conjunto de ecuaciones para obtener vendría dado por:
Múltiples attention heads
En la sección anterior mostramos el funcionamiento de una sola attention head. Sin embargo, los transformers no suelen usar una única cabeza de atención, sino varias trabajando en paralelo. La idea es que cada cabeza pueda aprender una forma distinta de mirar el mismo contexto. Por ejemplo, una cabeza podría especializarse en ciertas relaciones gramaticales, otra en relaciones semánticas, otra en repeticiones o dependencias de largo alcance. En este sentido, multi-head attention permite que el modelo construya varias representaciones contextuales complementarias a partir de los mismos tokens de entrada.
Siguiendo la notación de Jurafsky y Martin (2026), si tenemos cabezas de atención, cada cabeza tiene su propio conjunto de matrices aprendidas:
Estas matrices proyectan los vectores de entrada en queries, keys y values específicos para cada cabeza:
para cada cabeza , con . Luego, para calcular la atención del token en posición , la cabeza compara la query con las keys de los tokens disponibles en el contexto:
Estos scores se normalizan mediante una softmax, produciendo los pesos de atención:
A partir de estos pesos, cada cabeza calcula su propia suma ponderada de los value vectors:
Finalmente, las salidas de todas las cabezas se concatenan y se proyectan mediante una matriz :
Así, la función de multi-head attention puede expresarse como:
Vale la pena destacar que la salida de cada cabeza tiene dimensión:
Por lo tanto, si tenemos cabezas, la concatenación de todas ellas produce un vector de dimensión:
Luego, la matriz proyecta esta concatenación de vuelta al espacio del modelo:
De esta forma, la salida final de multi-head attention conserva la dimensión esperada:
Esto es importante porque permite que la salida de la atención pueda integrarse al flujo residual del transformer y pasar a las siguientes capas.
Transformer Blocks
Multi-head attention es uno de los subcomponentes de un transformer block. Lo hemos explicado en un apartado especial porque es, probablemente, el componente más característico y complejo de la arquitectura. Sin embargo, un transformer block moderno incluye también otros elementos importantes, como LayerNorm, conexiones residuales y una feedforward network.
El objetivo de esta sección es entender cómo interactúan estos subcomponentes dentro del bloque. Para ello, resulta útil introducir la idea de residual stream. En un transformer moderno, la representación de cada token no se reemplaza por completo cada vez que pasa por un subcomponente. Más bien, existe un flujo principal de información —el residual stream— que transporta la representación del token a través del bloque. Los distintos módulos leen desde ese flujo, calculan nueva información y luego suman su resultado de vuelta mediante conexiones residuales. En particular, la multi-head attention incorpora información contextual proveniente de otros tokens, mientras que la feedforward network transforma la representación de cada token de forma independiente. Este principio se ilustra en la siguiente figura:

Como se puede ver, cada token tiene su propio flujo vertical de información. En la figura, el token principal es . Ese vector sube por el bloque, mientras algunos módulos leen desde él, calculan nueva información y la suman de vuelta al flujo principal.
En la sección pasada explicamos el módulo de multi-head attention, sin embargo, nos falta explicar feedforward, y layernorm.
Capa feedforward
La capa feedforward de esta arquitectura-cuyo concepto fue explicado en esta entrada– es una red neuronal completamente conectada de dos capas, cuya capa oculta () suele tener una dimensión más grande que la del modelo (). Conceptualmente, la red hace algo similar a esto:
En este caso, llevamos al vector de entrada a un espacio más grande (de a ), porque así la red tiene más “lugar” para representar combinaciones, patrones y transformaciones no lineales. Después, comprime esa información de vuelta a la dimensión del modelo (). Esta compresión es necesaria para que sigamos trabajando con el vector en el flujo residual, de otra forma, dejaríamos el vector de salida en una dimensión que no es la que espera el subcomponente siguiente.
Dicho esto, en términos matemáticos, este paso se puede expresar de la siguiente forma:
donde , y (Tarea: chequea que ).
Capa LayerNorm
Layer norm (de Layer Normalization) normaliza el vector de representación de cada token para que sus valores no crezcan, se desplacen o se vuelvan demasiado extremos a medida que pasan por muchas capas.
Si pensamos en , layer norm toma ese vector y calcula la media y la desviación estándar de sus propias dimensiones internas. Es decir, no normaliza toda la capa completa ni todos los tokens juntos, sino el vector individual de un token. En términos matemáticos, primero hace
Luego, normaliza:
y finalmente, aplica dos parámetros aprendibles ( y ):
Bloque completo
Empleando la notación de Jurafsky y Martin (2026), podemos expresar los cálculos que hace un transformer block en el siguiente conjunto de ecauciones:
Primero, en , se normaliza la representación de entrada del token . Luego, en , esa representación normalizada entra al módulo de multi-head attention, que calcula una contribución contextual para el token , usando información del propio token y de los tokens disponibles en el contexto. Después, en , la salida de attention se suma al vector original , formando la primera conexión residual.
A continuación, en , se normaliza esta representación actualizada . Luego, en , la representación normalizada pasa por la red feedforward, que transforma el vector del token de forma independiente respecto de los demás tokens. Finalmente, la salida de la feedforward se suma nuevamente a , produciendo , la salida final del transformer block para el token en la posición .
Sobre la entrada
Hasta este punto, hemos discutido lo que hacemos con el vector , no obstante, no hemos dicho mucho sobre él. En esta sección veremos que no sólo es necesario el embedding, si no también, la posición de dicho vector en la secuencia.
Supongamos que tenemos una secuencia de N tokens, donde N es el largo del contexto. El input del transformer se podría escribir como , donde es el largo del embedding. Para ilustrar esta matriz, a modo de ejemplo, asumiremos que cada token es una palabra, y que nuestro contexto viene dado por la siguiente frase (N=7):
Esto me an buelto myos enemigos malos
Dicha secuencia deberá tener 7 embeddings, que vienen dados por:
- Esto = []
- me = []
- an = []
- …
- malos = []
Por lo que la matriz X vendría dada por:
En este punto, es importante entender que los embeddings obtenidos no registran ningún tipo de posición en el texto -en esta entrada podrás entender por qué-. No obstante, como podrás intuir después de leer el apartado de atención, la posición importa. En la siguiente imagen ilustramos por qué importa:

En este caso, podemos ver que el significado de la oración cambia levemente al intercambiar el orden de las palabras. Entonces, para que el transformer enriquezca los vectores según el contexto de forma correcta, es necesario que reciba el token bajo análisis, más los tokens que lo preceden en el orden original en que aparecieron en la secuencia.
Para llevar a cabo esta tarea, el modelo usa positional embeddings. Estos embeddings son vectores asociados a las posiciones de la secuencia. Por ejemplo, si tenemos una secuencia de N tokens, tendríamos N vectores:
- …
Luego, para construir la representación final de la entrada del token en la posición , llevamos a cabo la siguiente suma:
donde , es el vector de embeddings, y es el tamaño del vocabulario.
¿Cómo se aprende el modelo ? Al inicio del entrenamiento, los vectores suelen estar inicializados con valores aleatorios. Durante el entrenamiento, el modelo intenta predecir correctamente los siguientes tokens. Si la información de posición ayuda a reducir el error, los gradientes van ajustando esos vectores posicionales. Con muchas frases, el modelo aprende patrones como: qué suele pasar al comienzo de una oración, qué roles suelen tener ciertas posiciones, cómo afecta el orden a la interpretación, etc.
The Language Modeling Head
Hasta este punto ya sabemos lo que hace la capa del transformer. En términos coloquiales, en dicha capa entra un bloque completo de tokens como una matriz, y el transformer procesa todas las posiciones en paralelo. Gracias a la máscara causal, cada posición sólo puede usar información de los tokens anteriores y de sí misma. En términos matemáticos, una capa de transformer mapea una ventana completa de vectores de entrada (x) en vectores de salida contextualizados (h), es decir,
La siguiente ilustración resume parte de lo que hemos explicado si entrase la secuencia «A diestro dexan a Sant Esteuan, mas cae aluen.»

Con estos vectores ya enriquecidos, estamos en condiciones de predecir la siguiente palabra (como lo hicimos en esta entrada). Este proceso es la función principal de un language modeling head. La siguiente imagen explica esta función en detalle:

La figura muestra el flujo final de un transformer usado como modelo de lenguaje. Primero, una secuencia de tokens de entrada atraviesa el último bloque transformer, produciendo una representación contextualizada para cada posición: . Durante la generación, normalmente nos interesa el último vector contextualizado, , porque contiene información del contexto disponible hasta el token .
Luego, el vector entra en la language modeling head. En esta etapa, se proyecta desde el espacio interno del modelo hacia el espacio del vocabulario mediante una capa de unembedding, usualmente representada como , donde . Matemáticamente, esta operación se expresa como , con . El vector resultante contiene los logits, es decir, un puntaje no normalizado para cada token posible del vocabulario. Finalmente, una función softmax transforma esos logits en una distribución de probabilidad . Cada componente de indica la probabilidad que el modelo asigna a un posible siguiente token.
Fase de entrenamiento
En el entrenamiento de un transformer causal, el modelo aprende a predecir el siguiente token en cada posición de una secuencia, es decir,
Para ello, produce una distribución de probabilidad sobre el vocabulario y se compara esa distribución con el token correcto. La pérdida usada es la cross-entropy loss, que penaliza al modelo cuando asigna baja probabilidad al token real siguiente (si has seguido esta serie de publicaciones, esto te resultaría familiar, en caso contrario, visita esta entrada). Luego, mediante gradient descent, los pesos del modelo se ajustan para reducir esa pérdida promedio.
Es importante precisar que, durante el entrenamiento, el modelo no procesa todo el corpus completo de una sola vez. En la práctica, se define una ventana de contexto —por ejemplo, de algunos miles de tokens— y el corpus se organiza en segmentos o chunks que caben dentro de esa ventana. Si un documento es más corto que la ventana, pueden empaquetarse varios documentos en un mismo chunk, normalmente separados por un token especial. Cada chunk se procesa como una secuencia de entrenamiento: el modelo recibe sus tokens y aprende a predecir el siguiente token en cada posición, respetando la máscara causal. De esta manera, puede entrenarse sobre corpus muy grandes, pero siempre mediante fragmentos de tamaño limitado por su ventana de contexto.
Notas finales, y próxima entrada…
En esta entrada vimos el concepto de transformers con mayor profundidad. Esta idea ha sido fundamental en la construcción de los LLM’s más famosos, por tanto, su lectura es obligatoria.
En la próxima publicación veremos prácticas asociadas al post-entrenamiento, tales como instuction tuning y alignment. Stay tuned!
José Miguel Muñoz Urra – jmunozu@pulki.es