{"id":243,"date":"2026-05-16T20:42:28","date_gmt":"2026-05-16T20:42:28","guid":{"rendered":"https:\/\/pulki.es\/blog\/?p=243"},"modified":"2026-05-16T20:42:28","modified_gmt":"2026-05-16T20:42:28","slug":"large-language-model-llm-from-scratch-transformers","status":"publish","type":"post","link":"https:\/\/pulki.es\/blog\/index.php\/2026\/05\/16\/large-language-model-llm-from-scratch-transformers\/","title":{"rendered":"Large Language Model (LLM) from scratch. Transformers."},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">En la publicaci\u00f3n pasada entendimos la estructura general de un <strong>LLM<\/strong>.  Este paso es vital, puesto que nos da una visi\u00f3n panor\u00e1mica sobre la morfolog\u00eda de estos modelos. Con esto en mente, ahora podemos estudiar la arquitectura de aquellos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Existen m\u00faltiples arquitecturas para dise\u00f1ar un <strong>LLM<\/strong>, no obstante, en esta entrada vamos a estudiar <em>transformers,<\/em> puesto que es la que emplean los <strong>LLM<\/strong> m\u00e1s famosos, tales como GPT, BERT, T5, LLaMa, etc. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Al igual que en la entrada anterior, usaremos como referencia a <strong><a href=\"https:\/\/web.stanford.edu\/~jurafsky\/slp3\/\">Jurafsky y Martin (2026)<\/a><\/strong>, como es usual. Cualquier error es mi responsabilidad.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Atenci\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En el contexto espec\u00edfico de <strong>transformers<\/strong>, el concepto de <strong>atenci\u00f3n<\/strong> fue introducido por <strong><a href=\"https:\/\/arxiv.org\/abs\/1706.03762\">Vaswani et al. (2017)<\/a><\/strong>. Este art\u00edculo, y concepto, son importantes por varias razones, no obstante, en este momento se me ocurren dos muy obvias: la atenci\u00f3n est\u00e1 presente en los LLMs m\u00e1s famosos, tales como GPT, BERT, etc., y adem\u00e1s, el art\u00edculo tiene m\u00e1s de <a href=\"https:\/\/scholar.google.com\/citations?user=oR9sCGYAAAAJ&amp;hl=en\">250 mil citas<\/a> (a mayo de 2026). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En t\u00e9rminos formales, la atenci\u00f3n es un mecanismo que permite construir una nueva representaci\u00f3n contextual de un token combinando informaci\u00f3n de otros tokens de la secuencia. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pero, \u00bfPor qu\u00e9 necesitamos una nueva representaci\u00f3n contextual?. Primero que todo, recordemos algunos conceptos expuestos en la entrada sobre <a href=\"https:\/\/pulki.es\/blog\/index.php\/2026\/03\/18\/large-language-model-llm-from-scratch-embeddings\/\">embeddings<\/a>. En esta publicaci\u00f3n, represent\u00e1bamos el significado de una palabra de forma vectorial y est\u00e1tica, es decir, los valores de los componentes del vector de la palabra no dependen del contexto en el que se encuentre. Esto es problem\u00e1tico porque muchas veces la idoneidad de la palabra es definida por el contexto. Por ejemplo:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">El coche no sigui\u00f3 avanzando por el camino porque <strong>este<\/strong> estaba mojado.<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">El coche no sigui\u00f3 avanzando por el camino porque <strong>este<\/strong> estaba averiado.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">En este caso, en la primera oraci\u00f3n, el coche no avanz\u00f3 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 <strong>\u00abeste\u00bb<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Entonces, respondiendo a la pregunta, sobre si una nueva representaci\u00f3n conceptual es necesaria, si, es absolutamente necesaria, puesto que ayuda al modelo a distinguir este tipo de sutilidades.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ahora que sabemos por qu\u00e9 una representaci\u00f3n contextual es necesaria, estamos en condiciones de explicar el concepto de atenci\u00f3n. Formalmente, se podr\u00eda definir como el mecanismo mediante el cual el <em>transformer<\/em> toma <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_i<\/annotation><\/semantics><\/math>, es decir, la representaci\u00f3n vectorial del token que est\u00e1 en la posici\u00f3n <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>i<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">i<\/annotation><\/semantics><\/math> de la secuencia, y produce <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>a<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">a_i<\/annotation><\/semantics><\/math>, una nueva representaci\u00f3n del mismo <em>token<\/em>, pero enriquecida con informaci\u00f3n de los tokens anteriores. En un modelo causal, como GPT, esta informaci\u00f3n s\u00f3lo puede venir del propio <em>token<\/em> y de los tokens que aparecen antes de \u00e9l, no de los tokens futuros.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para entender esta idea, usaremos una versi\u00f3n simplificada de lo que realmente ocurre, tal y como lo muestra <strong><a href=\"https:\/\/web.stanford.edu\/~jurafsky\/slp3\/\">Jurafsky y Martin (2026)<\/a><\/strong>. Para esto, asumiremos la siguiente estructura:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"a_{i} = \\sum_{j\\leq i}\\alpha_{ij}x_{j}\"><semantics><mrow><msub><mi>a<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><msub><mo movablelimits=\"false\">\u2211<\/mo><mrow><mi>j<\/mi><mo>\u2264<\/mo><mi>i<\/mi><\/mrow><\/msub><msub><mi>\u03b1<\/mi><mrow><mi>i<\/mi><mi>j<\/mi><\/mrow><\/msub><msub><mi>x<\/mi><mi>j<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">a_{i} = \\sum_{j\\leq i}\\alpha_{ij}x_{j}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Es decir, en la posici\u00f3n <math data-latex=\"i\"><semantics><mi>i<\/mi><annotation encoding=\"application\/x-tex\">i<\/annotation><\/semantics><\/math> de la secuencia, tomamos la representaci\u00f3n vectorial de los tokens anteriores (incluyendo <math data-latex=\"i\"><semantics><mi>i<\/mi><annotation encoding=\"application\/x-tex\">i<\/annotation><\/semantics><\/math>), y los ponderamos por <math data-latex=\"\\alpha_{ij}\"><semantics><msub><mi>\u03b1<\/mi><mrow><mi>i<\/mi><mi>j<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">\\alpha_{ij}<\/annotation><\/semantics><\/math>. Luego, para obtener este \u00faltimo, calculamos el <em>score<\/em>, y lo pasamos por la <em>softmax<\/em>:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"score(x_{i},x_{j}) = x_{i} \\cdot x_{j}\"><semantics><mrow><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><mi>e<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo>\u22c5<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">score(x_{i},x_{j}) = x_{i} \\cdot x_{j}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"\\alpha_{ij} = softmax(score(x_{i},x_{j}) ), \\forall j\\leq i\"><semantics><mrow><msub><mi>\u03b1<\/mi><mrow><mi>i<\/mi><mi>j<\/mi><\/mrow><\/msub><mo>=<\/mo><mi>s<\/mi><mi>o<\/mi><mi>f<\/mi><mi>t<\/mi><mi>m<\/mi><mi>a<\/mi><mi>x<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><mi>e<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo separator=\"true\">,<\/mo><mi>\u2200<\/mi><mi>j<\/mi><mo>\u2264<\/mo><mi>i<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\alpha_{ij} = softmax(score(x_{i},x_{j}) ), \\forall j\\leq i<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfPor qu\u00e9 calculamos el <em>producto punto<\/em>? Recordemos que este se puede interpretar como una medida de similitud entre dos vectores, entonces, si el vector de un token previo <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mi>j<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_j<\/annotation><\/semantics><\/math>\u200b es parecido al vector del token actual <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_i<\/annotation><\/semantics><\/math>, entonces probablemente contiene informaci\u00f3n \u00fatil para interpretar o representar mejor a <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_i<\/annotation><\/semantics><\/math>. En t\u00e9rminos pr\u00e1cticos, supongamos el siguiente ejemplo:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">El gato es buena mascota. Este felino\u2026<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Supongamos que en esta frase estamos analizando <math data-latex=\"x_{felino}\"><semantics><msub><mi>x<\/mi><mrow><mi>f<\/mi><mi>e<\/mi><mi>l<\/mi><mi>i<\/mi><mi>n<\/mi><mi>o<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">x_{felino}<\/annotation><\/semantics><\/math>. Es de esperar, que la similitud entre <math data-latex=\"x_{felino}\"><semantics><msub><mi>x<\/mi><mrow><mi>f<\/mi><mi>e<\/mi><mi>l<\/mi><mi>i<\/mi><mi>n<\/mi><mi>o<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">x_{felino}<\/annotation><\/semantics><\/math> y <math data-latex=\"x_{gato}\"><semantics><msub><mi>x<\/mi><mrow><mi>g<\/mi><mi>a<\/mi><mi>t<\/mi><mi>o<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">x_{gato}<\/annotation><\/semantics><\/math>, sea mayor a la similitud entre <math data-latex=\"x_{felino}\"><semantics><msub><mi>x<\/mi><mrow><mi>f<\/mi><mi>e<\/mi><mi>l<\/mi><mi>i<\/mi><mi>n<\/mi><mi>o<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">x_{felino}<\/annotation><\/semantics><\/math>y <math data-latex=\"x_{buena}\"><semantics><msub><mi>x<\/mi><mrow><mi>b<\/mi><mi>u<\/mi><mi>e<\/mi><mi>n<\/mi><mi>a<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">x_{buena}<\/annotation><\/semantics><\/math>. Lo anterior implica que <math data-latex=\"\\alpha_{felino,gato}  &gt;\\alpha_{felino,buena}\"><semantics><mrow><msub><mi>\u03b1<\/mi><mrow><mi>f<\/mi><mi>e<\/mi><mi>l<\/mi><mi>i<\/mi><mi>n<\/mi><mi>o<\/mi><mo separator=\"true\">,<\/mo><mi>g<\/mi><mi>a<\/mi><mi>t<\/mi><mi>o<\/mi><\/mrow><\/msub><mo>&gt;<\/mo><msub><mi>\u03b1<\/mi><mrow><mi>f<\/mi><mi>e<\/mi><mi>l<\/mi><mi>i<\/mi><mi>n<\/mi><mi>o<\/mi><mo separator=\"true\">,<\/mo><mi>b<\/mi><mi>u<\/mi><mi>e<\/mi><mi>n<\/mi><mi>a<\/mi><\/mrow><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">\\alpha_{felino,gato} &gt;\\alpha_{felino,buena}<\/annotation><\/semantics><\/math>. Por tanto, el vector contextualizado del <em>token<\/em> felino, <math data-latex=\"a_{felino}\"><semantics><msub><mi>a<\/mi><mrow><mi>f<\/mi><mi>e<\/mi><mi>l<\/mi><mi>i<\/mi><mi>n<\/mi><mi>o<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">a_{felino}<\/annotation><\/semantics><\/math>, contendr\u00e1 m\u00e1s informaci\u00f3n de gato que del token buena.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Esta metodolog\u00eda fue desarrollada por <strong><a href=\"https:\/\/web.stanford.edu\/~jurafsky\/slp3\/\">Jurafsky y Martin (2026)<\/a><\/strong> con fines pedag\u00f3gicos, no obstante, el funcionamiento de la atenci\u00f3n es m\u00e1s compleja. Esta, tiene conceptos adicionales como <em>attention head<\/em>, <em>query,<\/em> <em>key<\/em> y <em>value<\/em>. A continuaci\u00f3n veremos cada uno, y c\u00f3mo se relacionan.<\/p>\n\n\n\n<p class=\"is-style-text-subtitle is-style-text-subtitle--1 wp-block-paragraph\">Attention head, query y value<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una <strong>attention head<\/strong> es un componente de atenci\u00f3n que toma las representaciones vectoriales de los <em>tokens<\/em> y las proyecta en tres espacios distintos: <strong>queries<\/strong>, <strong>keys<\/strong> y <strong>values<\/strong>. La <strong>query<\/strong> corresponde a la representaci\u00f3n del <em>token<\/em> actual en su rol de b\u00fasqueda; las <strong>keys<\/strong> corresponden a las representaciones de los <em>tokens<\/em> del contexto en su rol de comparaci\u00f3n; y los <strong>values<\/strong> corresponden a la informaci\u00f3n que finalmente ser\u00e1 ponderada y sumada. De esta forma, la cabeza de atenci\u00f3n compara la <em>query<\/em> del <em>token<\/em> actual con las<em> keys<\/em> de los <em>tokens <\/em>disponibles en el contexto \u2014en un transformer causal, el propio <em>token<\/em> y los <em>tokens<\/em> anteriores\u2014, transforma esas comparaciones en pesos de atenci\u00f3n y usa esos pesos para combinar los <em>values<\/em>. El resultado es una nueva representaci\u00f3n del token actual, enriquecida con informaci\u00f3n contextual. En la siguiente imagen, podemos ver con m\u00e1s claridad qu\u00e9 ocurre:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"769\" src=\"https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/foto_mejorada-1024x769.png\" alt=\"\" class=\"wp-image-277\" srcset=\"https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/foto_mejorada-1024x769.png 1024w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/foto_mejorada-300x225.png 300w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/foto_mejorada-768x577.png 768w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/foto_mejorada.png 1447w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">En el ejemplo de la ilustraci\u00f3n, tenemos tres tokens de entrada que vienen en forma de embeddings: <math data-latex=\"x_{1}\"><semantics><msub><mi>x<\/mi><mn>1<\/mn><\/msub><annotation encoding=\"application\/x-tex\">x_{1}<\/annotation><\/semantics><\/math>, <math data-latex=\"x_{2}\"><semantics><msub><mi>x<\/mi><mn>2<\/mn><\/msub><annotation encoding=\"application\/x-tex\">x_{2}<\/annotation><\/semantics><\/math>y <math data-latex=\"x_{3}\"><semantics><msub><mi>x<\/mi><mn>3<\/mn><\/msub><annotation encoding=\"application\/x-tex\">x_{3}<\/annotation><\/semantics><\/math>, siendo este \u00faltimo, el token que estamos analizando. Nuestro objetivo es calcular <math data-latex=\"a_{3}\"><semantics><msub><mi>a<\/mi><mn>3<\/mn><\/msub><annotation encoding=\"application\/x-tex\">a_{3}<\/annotation><\/semantics><\/math>, es decir, una nueva representaci\u00f3n contextualizada de ese <em>token<\/em>. Para ello, primero proyectamos cada vector de entrada en tres representaciones distintas: <strong>key<\/strong>, <strong>query<\/strong> y <strong>value<\/strong>. Estas proyecciones se obtienen mediante tres matrices aprendidas por el modelo:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"q_{i} = x_{i}W^{Q}\"><semantics><mrow><msub><mi>q<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><msup><mi>W<\/mi><mi>Q<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">q_{i} = x_{i}W^{Q}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"k_{i} = x_{i}W^{K}\"><semantics><mrow><msub><mi>k<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><msup><mi>W<\/mi><mi>K<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">k_{i} = x_{i}W^{K}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"v_{i} = x_{i}W^{V}\"><semantics><mrow><msub><mi>v<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><msup><mi>W<\/mi><mi>V<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">v_{i} = x_{i}W^{V}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">donde <math data-latex=\"q_{i}\"><semantics><msub><mi>q<\/mi><mi>i<\/mi><\/msub><annotation encoding=\"application\/x-tex\">q_{i}<\/annotation><\/semantics><\/math> es la query, <math data-latex=\"k_{i}\"><semantics><msub><mi>k<\/mi><mi>i<\/mi><\/msub><annotation encoding=\"application\/x-tex\">k_{i}<\/annotation><\/semantics><\/math>es la key y <math data-latex=\"v_{i}\"><semantics><msub><mi>v<\/mi><mi>i<\/mi><\/msub><annotation encoding=\"application\/x-tex\">v_{i}<\/annotation><\/semantics><\/math>es el value correspondiente al token en la posici\u00f3n <math data-latex=\"i\"><semantics><mi>i<\/mi><annotation encoding=\"application\/x-tex\">i<\/annotation><\/semantics><\/math>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Como queremos calcular la salida de atenci\u00f3n para <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_3<\/annotation><\/semantics><\/math>, usamos la query de <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_3<\/annotation><\/semantics><\/math>, es decir, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>q<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">q_3<\/annotation><\/semantics><\/math>, y la comparamos con las keys de los tokens disponibles en el contexto. Puesto que estamos en un modelo causal, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_3<\/annotation><\/semantics><\/math> puede atender a <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>1<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_1<\/annotation><\/semantics><\/math>, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>2<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_2<\/annotation><\/semantics><\/math> y a s\u00ed mismo, pero no a tokens futuros. Por lo tanto, calculamos los siguientes scores:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"x_{3} \\text{contra } x_{1} :  score(x_{3},x_{1}) =  \\frac{q_{3}\\cdot k_{1}}{\\sqrt{d_{k}}}\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mtext>contra&nbsp;<\/mtext><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><mi>e<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mfrac><mrow><msub><mi>q<\/mi><mn>3<\/mn><\/msub><mo>\u22c5<\/mo><msub><mi>k<\/mi><mn>1<\/mn><\/msub><\/mrow><msqrt><msub><mi>d<\/mi><mi>k<\/mi><\/msub><\/msqrt><\/mfrac><\/mrow><annotation encoding=\"application\/x-tex\">x_{3} \\text{contra } x_{1} :  score(x_{3},x_{1}) =  \\frac{q_{3}\\cdot k_{1}}{\\sqrt{d_{k}}}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"x_{3} \\text{contra } x_{2} :  score(x_{3},x_{2}) =  \\frac{q_{3}\\cdot k_{2}}{\\sqrt{d_{k}}}\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mtext>contra&nbsp;<\/mtext><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><mi>e<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mfrac><mrow><msub><mi>q<\/mi><mn>3<\/mn><\/msub><mo>\u22c5<\/mo><msub><mi>k<\/mi><mn>2<\/mn><\/msub><\/mrow><msqrt><msub><mi>d<\/mi><mi>k<\/mi><\/msub><\/msqrt><\/mfrac><\/mrow><annotation encoding=\"application\/x-tex\">x_{3} \\text{contra } x_{2} :  score(x_{3},x_{2}) =  \\frac{q_{3}\\cdot k_{2}}{\\sqrt{d_{k}}}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"x_{3} \\text{contra } x_{1} :  score(x_{3},x_{3}) =  \\frac{q_{3}\\cdot k_{3}}{\\sqrt{d_{k}}}\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mtext>contra&nbsp;<\/mtext><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo lspace=\"0.2222em\" rspace=\"0.2222em\">:<\/mo><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><mi>e<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>3<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mfrac><mrow><msub><mi>q<\/mi><mn>3<\/mn><\/msub><mo>\u22c5<\/mo><msub><mi>k<\/mi><mn>3<\/mn><\/msub><\/mrow><msqrt><msub><mi>d<\/mi><mi>k<\/mi><\/msub><\/msqrt><\/mfrac><\/mrow><annotation encoding=\"application\/x-tex\">x_{3} \\text{contra } x_{1} :  score(x_{3},x_{3}) =  \\frac{q_{3}\\cdot k_{3}}{\\sqrt{d_{k}}}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El producto punto <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>q<\/mi><mn>3<\/mn><\/msub><mo>\u22c5<\/mo><msub><mi>k<\/mi><mi>j<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">q_3 \\cdot k_j<\/annotation><\/semantics><\/math> mide la compatibilidad entre la query del token actual y la key de cada token del contexto. Luego, dividimos por <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msqrt><msub><mi>d<\/mi><mi>k<\/mi><\/msub><\/msqrt><\/mrow><annotation encoding=\"application\/x-tex\">\\sqrt{d_k}<\/annotation><\/semantics><\/math> para evitar que los scores crezcan demasiado cuando la dimensi\u00f3n de las queries y keys es alta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Posteriormente, pasamos estos scores por una <em>softmax<\/em>. Esto nos permite convertir los scores en pesos de atenci\u00f3n:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"\\alpha_{31}, \\alpha_{32}, \\alpha_{33}\"><semantics><mrow><msub><mi>\u03b1<\/mi><mn>31<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>\u03b1<\/mi><mn>32<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>\u03b1<\/mi><mn>33<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">\\alpha_{31}, \\alpha_{32}, \\alpha_{33}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Formalmente:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"\\alpha_{3j} = \\frac{e^{score(x_{3},x_{j})}}{\\sum_{m\\leq3}e^{score(x_{3},x_{m})}}\"><semantics><mrow><msub><mi>\u03b1<\/mi><mrow><mn>3<\/mn><mi>j<\/mi><\/mrow><\/msub><mo>=<\/mo><mfrac><msup><mi>e<\/mi><mrow><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><mi>e<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn scriptlevel=\"2\">3<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi scriptlevel=\"2\">j<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><\/msup><mrow><msub><mo movablelimits=\"false\">\u2211<\/mo><mrow><mi>m<\/mi><mo>\u2264<\/mo><mn>3<\/mn><\/mrow><\/msub><msup><mi>e<\/mi><mrow><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><mi>e<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn scriptlevel=\"2\">3<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi scriptlevel=\"2\">m<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\" lspace=\"0em\" rspace=\"0em\">)<\/mo><\/mrow><\/msup><\/mrow><\/mfrac><\/mrow><annotation encoding=\"application\/x-tex\">\\alpha_{3j} = \\frac{e^{score(x_{3},x_{j})}}{\\sum_{m\\leq3}e^{score(x_{3},x_{m})}}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">para  <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>j<\/mi><mo>\u2208<\/mo><mo stretchy=\"false\">{<\/mo><mn>1<\/mn><mo separator=\"true\">,<\/mo><mn>2<\/mn><mo separator=\"true\">,<\/mo><mn>3<\/mn><mo stretchy=\"false\">}<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">j \\in \\{1,2,3\\}<\/annotation><\/semantics><\/math>. De esta forma, los pesos de atenci\u00f3n son n\u00fameros positivos que suman 1:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"\\alpha_{31} + \\alpha_{32} + \\alpha_{33} =1\"><semantics><mrow><msub><mi>\u03b1<\/mi><mn>31<\/mn><\/msub><mo>+<\/mo><msub><mi>\u03b1<\/mi><mn>32<\/mn><\/msub><mo>+<\/mo><msub><mi>\u03b1<\/mi><mn>33<\/mn><\/msub><mo>=<\/mo><mn>1<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">\\alpha_{31} + \\alpha_{32} + \\alpha_{33} =1<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cada <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>\u03b1<\/mi><mrow><mn>3<\/mn><mi>j<\/mi><\/mrow><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">\\alpha_{3j}<\/annotation><\/semantics><\/math>\u200b indica cu\u00e1nta informaci\u00f3n del token <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mi>j<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_j<\/annotation><\/semantics><\/math> ser\u00e1 incorporada en la nueva representaci\u00f3n de <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_3<\/annotation><\/semantics><\/math>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una vez obtenidos los pesos de atenci\u00f3n, podemos calcular la salida de la cabeza de atenci\u00f3n para el token <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_3<\/annotation><\/semantics><\/math>. Para ello, hacemos una suma ponderada de los <strong>value vectors<\/strong>:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"head_{3} = \\alpha_{31}v_{1} + \\alpha_{32}v_{2} + \\alpha_{33}v_{3}\"><semantics><mrow><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msub><mi>d<\/mi><mn>3<\/mn><\/msub><mo>=<\/mo><msub><mi>\u03b1<\/mi><mn>31<\/mn><\/msub><msub><mi>v<\/mi><mn>1<\/mn><\/msub><mo>+<\/mo><msub><mi>\u03b1<\/mi><mn>32<\/mn><\/msub><msub><mi>v<\/mi><mn>2<\/mn><\/msub><mo>+<\/mo><msub><mi>\u03b1<\/mi><mn>33<\/mn><\/msub><msub><mi>v<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">head_{3} = \\alpha_{31}v_{1} + \\alpha_{32}v_{2} + \\alpha_{33}v_{3}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El vector <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msub><mi>d<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">head_3<\/annotation><\/semantics><\/math>\u200b tiene dimensi\u00f3n:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"1\\times d_{v}\"><semantics><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mi>v<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">1\\times d_{v}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sin embargo, la arquitectura del <em>transformer<\/em> necesita que la salida de la atenci\u00f3n tenga la misma dimensi\u00f3n que la representaci\u00f3n original del token, es decir:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"1\\times d_{model}\"><semantics><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">1\\times d_{model}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por esta raz\u00f3n, multiplicamos <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msub><mi>d<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">head_3<\/annotation><\/semantics><\/math> por una matriz de salida <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msup><mi>W<\/mi><mi>O<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W^O<\/annotation><\/semantics><\/math>:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"a_{3} = head_{3}W^{o} \"><semantics><mrow><msub><mi>a<\/mi><mn>3<\/mn><\/msub><mo>=<\/mo><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msub><mi>d<\/mi><mn>3<\/mn><\/msub><msup><mi>W<\/mi><mi>o<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">a_{3} = head_{3}W^{o} <\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">donde:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"W^{O} \\in \\mathbb{R}^{d_{v}\\times d_{model}}\"><semantics><mrow><msup><mi>W<\/mi><mi>O<\/mi><\/msup><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><msub><mi>d<\/mi><mi>v<\/mi><\/msub><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W^{O} \\in \\mathbb{R}^{d_{v}\\times d_{model}}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As\u00ed, la operaci\u00f3n tiene la siguiente forma:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"[1\\times d_{v}]\\cdot [d_{v}\\times d_{model}] = [1\\times d_{model}]\"><semantics><mrow><mo form=\"prefix\" stretchy=\"false\">[<\/mo><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mi>v<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">]<\/mo><mo>\u22c5<\/mo><mo form=\"prefix\" stretchy=\"false\">[<\/mo><msub><mi>d<\/mi><mi>v<\/mi><\/msub><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">]<\/mo><mo>=<\/mo><mo form=\"prefix\" stretchy=\"false\">[<\/mo><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">]<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">[1\\times d_{v}]\\cdot [d_{v}\\times d_{model}] = [1\\times d_{model}]<\/annotation><\/semantics><\/math> <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El resultado final es:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"a_{3} \\in \\mathbb{R}^{1\\times d_{model}}\"><semantics><mrow><msub><mi>a<\/mi><mn>3<\/mn><\/msub><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">a_{3} \\in \\mathbb{R}^{1\\times d_{model}}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Es decir, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>a<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">a_3<\/annotation><\/semantics><\/math> es una nueva representaci\u00f3n del token <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_3<\/annotation><\/semantics><\/math>\u200b, enriquecida con informaci\u00f3n de <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>1<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_1<\/annotation><\/semantics><\/math>, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>2<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_2<\/annotation><\/semantics><\/math> y del propio <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_3<\/annotation><\/semantics><\/math>\u200b. Esta representaci\u00f3n mantiene la misma dimensionalidad que la entrada, lo que permite integrarla al flujo residual del <em>transformer<\/em> y pasarla a las siguientes capas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para verlo con un ejemplo peque\u00f1o, supongamos que:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"d_{v} = 3 \\ \\ \\ \\text{y} \\ \\ \\ d_{model}=2\"><semantics><mrow><msub><mi>d<\/mi><mi>v<\/mi><\/msub><mo>=<\/mo><mn>3<\/mn><mtext>&nbsp;<\/mtext><mtext>&nbsp;<\/mtext><mtext>&nbsp;<\/mtext><mtext>y<\/mtext><mtext>&nbsp;<\/mtext><mtext>&nbsp;<\/mtext><mtext>&nbsp;<\/mtext><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mo>=<\/mo><mn>2<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">d_{v} = 3 \\ \\ \\ \\text{y} \\ \\ \\ d_{model}=2<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Entonces <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msub><mi>d<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">head_3<\/annotation><\/semantics><\/math> podr\u00eda ser un vector de tres dimensiones:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"head_{i} = [h_{1} \\  h_{2} \\ h_{3}]\"><semantics><mrow><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msub><mi>d<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><mo form=\"prefix\" stretchy=\"false\">[<\/mo><msub><mi>h<\/mi><mn>1<\/mn><\/msub><mtext>&nbsp;<\/mtext><msub><mi>h<\/mi><mn>2<\/mn><\/msub><mtext>&nbsp;<\/mtext><msub><mi>h<\/mi><mn>3<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">]<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">head_{i} = [h_{1} \\  h_{2} \\ h_{3}]<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">y <math data-latex=\"W^{O} \"><semantics><msup><mi>W<\/mi><mi>O<\/mi><\/msup><annotation encoding=\"application\/x-tex\">W^{O} <\/annotation><\/semantics><\/math>tendr\u00eda dimensi\u00f3n <math data-latex=\"3\\times 2\"><semantics><mrow><mn>3<\/mn><mo>\u00d7<\/mo><mn>2<\/mn><\/mrow><annotation encoding=\"application\/x-tex\">3\\times 2<\/annotation><\/semantics><\/math>:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"W^{O} = \\begin{bmatrix} w_{11} &amp; w_{12} \\\\ w_{21} &amp; w_{22} \\\\ w_{31} &amp; w_{32} \\end{bmatrix} \"><semantics><mrow><msup><mi>W<\/mi><mi>O<\/mi><\/msup><mo>=<\/mo><mrow><mo fence=\"true\" form=\"prefix\">[<\/mo><mtable columnalign=\"center center\"><mtr><mtd style=\"padding-left:0em;\"><msub><mi>w<\/mi><mn>11<\/mn><\/msub><\/mtd><mtd style=\"padding-right:0em;\"><msub><mi>w<\/mi><mn>12<\/mn><\/msub><\/mtd><\/mtr><mtr><mtd style=\"padding-left:0em;\"><msub><mi>w<\/mi><mn>21<\/mn><\/msub><\/mtd><mtd style=\"padding-right:0em;\"><msub><mi>w<\/mi><mn>22<\/mn><\/msub><\/mtd><\/mtr><mtr><mtd style=\"padding-left:0em;\"><msub><mi>w<\/mi><mn>31<\/mn><\/msub><\/mtd><mtd style=\"padding-right:0em;\"><msub><mi>w<\/mi><mn>32<\/mn><\/msub><\/mtd><\/mtr><\/mtable><mo fence=\"true\" form=\"postfix\">]<\/mo><\/mrow><\/mrow><annotation encoding=\"application\/x-tex\">W^{O} = \\begin{bmatrix} w_{11} &amp; w_{12} \\\\ w_{21} &amp; w_{22} \\\\ w_{31} &amp; w_{32} \\end{bmatrix} <\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La multiplicaci\u00f3n ser\u00eda:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"a_{3} = \\begin{bmatrix} h_{1} &amp; h_{2} &amp; h_{3} \\end{bmatrix} \\cdot \\begin{bmatrix} w_{11} &amp; w_{12} \\\\ w_{21} &amp; w_{22} \\\\ w_{31} &amp; w_{32} \\end{bmatrix} \"><semantics><mrow><msub><mi>a<\/mi><mn>3<\/mn><\/msub><mo>=<\/mo><mrow><mo fence=\"true\" form=\"prefix\">[<\/mo><mtable columnalign=\"center center center\"><mtr><mtd style=\"padding-left:0em;\"><msub><mi>h<\/mi><mn>1<\/mn><\/msub><\/mtd><mtd><msub><mi>h<\/mi><mn>2<\/mn><\/msub><\/mtd><mtd style=\"padding-right:0em;\"><msub><mi>h<\/mi><mn>3<\/mn><\/msub><\/mtd><\/mtr><\/mtable><mo fence=\"true\" form=\"postfix\">]<\/mo><\/mrow><mo>\u22c5<\/mo><mrow><mo fence=\"true\" form=\"prefix\">[<\/mo><mtable columnalign=\"center center\"><mtr><mtd style=\"padding-left:0em;\"><msub><mi>w<\/mi><mn>11<\/mn><\/msub><\/mtd><mtd style=\"padding-right:0em;\"><msub><mi>w<\/mi><mn>12<\/mn><\/msub><\/mtd><\/mtr><mtr><mtd style=\"padding-left:0em;\"><msub><mi>w<\/mi><mn>21<\/mn><\/msub><\/mtd><mtd style=\"padding-right:0em;\"><msub><mi>w<\/mi><mn>22<\/mn><\/msub><\/mtd><\/mtr><mtr><mtd style=\"padding-left:0em;\"><msub><mi>w<\/mi><mn>31<\/mn><\/msub><\/mtd><mtd style=\"padding-right:0em;\"><msub><mi>w<\/mi><mn>32<\/mn><\/msub><\/mtd><\/mtr><\/mtable><mo fence=\"true\" form=\"postfix\">]<\/mo><\/mrow><\/mrow><annotation encoding=\"application\/x-tex\">a_{3} = \\begin{bmatrix} h_{1} &amp; h_{2} &amp; h_{3} \\end{bmatrix} \\cdot \\begin{bmatrix} w_{11} &amp; w_{12} \\\\ w_{21} &amp; w_{22} \\\\ w_{31} &amp; w_{32} \\end{bmatrix} <\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por lo tanto:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"a_{3} = \\begin{bmatrix} h_{1}w_{11} + h_{2}w_{21} + h_{3}w_{31} &amp; h_{1}w_{12} + h_{2}w_{22} + h_{3}w_{32} \\end{bmatrix} \"><semantics><mrow><msub><mi>a<\/mi><mn>3<\/mn><\/msub><mo>=<\/mo><mrow><mo fence=\"true\" form=\"prefix\">[<\/mo><mtable columnalign=\"center center\"><mtr><mtd style=\"padding-left:0em;\"><mrow><msub><mi>h<\/mi><mn>1<\/mn><\/msub><msub><mi>w<\/mi><mn>11<\/mn><\/msub><mo>+<\/mo><msub><mi>h<\/mi><mn>2<\/mn><\/msub><msub><mi>w<\/mi><mn>21<\/mn><\/msub><mo>+<\/mo><msub><mi>h<\/mi><mn>3<\/mn><\/msub><msub><mi>w<\/mi><mn>31<\/mn><\/msub><\/mrow><\/mtd><mtd style=\"padding-right:0em;\"><mrow><msub><mi>h<\/mi><mn>1<\/mn><\/msub><msub><mi>w<\/mi><mn>12<\/mn><\/msub><mo>+<\/mo><msub><mi>h<\/mi><mn>2<\/mn><\/msub><msub><mi>w<\/mi><mn>22<\/mn><\/msub><mo>+<\/mo><msub><mi>h<\/mi><mn>3<\/mn><\/msub><msub><mi>w<\/mi><mn>32<\/mn><\/msub><\/mrow><\/mtd><\/mtr><\/mtable><mo fence=\"true\" form=\"postfix\">]<\/mo><\/mrow><\/mrow><annotation encoding=\"application\/x-tex\">a_{3} = \\begin{bmatrix} h_{1}w_{11} + h_{2}w_{21} + h_{3}w_{31} &amp; h_{1}w_{12} + h_{2}w_{22} + h_{3}w_{32} \\end{bmatrix} <\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As\u00ed, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msup><mi>W<\/mi><mi>O<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W^O<\/annotation><\/semantics><\/math> aprende c\u00f3mo transformar y mezclar la informaci\u00f3n contenida en <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msub><mi>d<\/mi><mn>3<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">head_3<\/annotation><\/semantics><\/math> para devolverla al espacio general del modelo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dicho esto, en t\u00e9rminos formales, el conjunto de ecuaciones para obtener <math data-latex=\"a_{i}\"><semantics><msub><mi>a<\/mi><mi>i<\/mi><\/msub><annotation encoding=\"application\/x-tex\">a_{i}<\/annotation><\/semantics><\/math>vendr\u00eda dado por:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"q_{i} = x_{i}W^{Q} \\ \\ ; \\ \\  k_{j} = x_{j}W^{K} \\ \\ ; \\ \\ v_{j} = x_{j}W^{V}\"><semantics><mrow><msub><mi>q<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><msup><mi>W<\/mi><mi>Q<\/mi><\/msup><mtext>&nbsp;<\/mtext><mtext>&nbsp;<\/mtext><mo separator=\"true\">;<\/mo><mtext>&nbsp;<\/mtext><mtext>&nbsp;<\/mtext><msub><mi>k<\/mi><mi>j<\/mi><\/msub><mo>=<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><msup><mi>W<\/mi><mi>K<\/mi><\/msup><mtext>&nbsp;<\/mtext><mtext>&nbsp;<\/mtext><mo separator=\"true\">;<\/mo><mtext>&nbsp;<\/mtext><mtext>&nbsp;<\/mtext><msub><mi>v<\/mi><mi>j<\/mi><\/msub><mo>=<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><msup><mi>W<\/mi><mi>V<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">q_{i} = x_{i}W^{Q} \\ \\ ; \\ \\  k_{j} = x_{j}W^{K} \\ \\ ; \\ \\ v_{j} = x_{j}W^{V}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"score(x_{i},x_{j}) = \\frac{q_{i}k_{j}}{\\sqrt{d_{k}}}\"><semantics><mrow><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><mi>e<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mfrac><mrow><msub><mi>q<\/mi><mi>i<\/mi><\/msub><msub><mi>k<\/mi><mi>j<\/mi><\/msub><\/mrow><msqrt><msub><mi>d<\/mi><mi>k<\/mi><\/msub><\/msqrt><\/mfrac><\/mrow><annotation encoding=\"application\/x-tex\">score(x_{i},x_{j}) = \\frac{q_{i}k_{j}}{\\sqrt{d_{k}}}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"\\alpha_{ij} = softmax(score(x_{i},x_{j})) \\ \\ \\forall j \\leq i\"><semantics><mrow><msub><mi>\u03b1<\/mi><mrow><mi>i<\/mi><mi>j<\/mi><\/mrow><\/msub><mo>=<\/mo><mi>s<\/mi><mi>o<\/mi><mi>f<\/mi><mi>t<\/mi><mi>m<\/mi><mi>a<\/mi><mi>x<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><mi>e<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mtext>&nbsp;<\/mtext><mtext>&nbsp;<\/mtext><mi>\u2200<\/mi><mi>j<\/mi><mo>\u2264<\/mo><mi>i<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\alpha_{ij} = softmax(score(x_{i},x_{j})) \\ \\ \\forall j \\leq i<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"> <math data-latex=\"head_{i} = \\sum_{j\\leq i} \\alpha_{ij}v_{j}\"><semantics><mrow><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msub><mi>d<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><msub><mo movablelimits=\"false\">\u2211<\/mo><mrow><mi>j<\/mi><mo>\u2264<\/mo><mi>i<\/mi><\/mrow><\/msub><msub><mi>\u03b1<\/mi><mrow><mi>i<\/mi><mi>j<\/mi><\/mrow><\/msub><msub><mi>v<\/mi><mi>j<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">head_{i} = \\sum_{j\\leq i} \\alpha_{ij}v_{j}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"a_{i} = head_{i}W^{o}\"><semantics><mrow><msub><mi>a<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msub><mi>d<\/mi><mi>i<\/mi><\/msub><msup><mi>W<\/mi><mi>o<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">a_{i} = head_{i}W^{o}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"is-style-text-subtitle is-style-text-subtitle--2 wp-block-paragraph\">M\u00faltiples attention heads<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En la secci\u00f3n anterior mostramos el funcionamiento de una sola <strong>attention head<\/strong>. Sin embargo, los <em>transformers <\/em>no suelen usar una \u00fanica cabeza de atenci\u00f3n, 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\u00eda especializarse en ciertas relaciones gramaticales, otra en relaciones sem\u00e1nticas, otra en repeticiones o dependencias de largo alcance. En este sentido, <strong>multi-head attention<\/strong> permite que el modelo construya varias representaciones contextuales complementarias a partir de los mismos tokens de entrada.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Siguiendo la notaci\u00f3n de <strong><a href=\"https:\/\/web.stanford.edu\/~jurafsky\/slp3\/\">Jurafsky y Martin (2026)<\/a><\/strong>, si tenemos <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>A<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">A<\/annotation><\/semantics><\/math> cabezas de atenci\u00f3n, cada cabeza <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>c<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">c<\/annotation><\/semantics><\/math> tiene su propio conjunto de matrices aprendidas:<math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><msup><mi>W<\/mi><msub><mi>Q<\/mi><mi>c<\/mi><\/msub><\/msup><mo separator=\"true\">,<\/mo><mspace width=\"1em\"><\/mspace><msup><mi>W<\/mi><msub><mi>K<\/mi><mi>c<\/mi><\/msub><\/msup><mo separator=\"true\">,<\/mo><mspace width=\"1em\"><\/mspace><msup><mi>W<\/mi><msub><mi>V<\/mi><mi>c<\/mi><\/msub><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W^{Q_c}, \\quad W^{K_c}, \\quad W^{V_c}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Estas matrices proyectan los vectores de entrada en queries, keys y values espec\u00edficos para cada cabeza:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><msubsup><mi>q<\/mi><mi>i<\/mi><mi>c<\/mi><\/msubsup><mo>=<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><msup><mi>W<\/mi><msub><mi>Q<\/mi><mi>c<\/mi><\/msub><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">q_i^c = x_i W^{Q_c}<\/annotation><\/semantics><\/math><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><msubsup><mi>k<\/mi><mi>j<\/mi><mi>c<\/mi><\/msubsup><mo>=<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><msup><mi>W<\/mi><msub><mi>K<\/mi><mi>c<\/mi><\/msub><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">k_j^c = x_j W^{K_c}<\/annotation><\/semantics><\/math><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><msubsup><mi>v<\/mi><mi>j<\/mi><mi>c<\/mi><\/msubsup><mo>=<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><msup><mi>W<\/mi><msub><mi>V<\/mi><mi>c<\/mi><\/msub><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">v_j^c = x_j W^{V_c}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">para cada cabeza <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>c<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">c<\/annotation><\/semantics><\/math>, con <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mn>1<\/mn><mo>\u2264<\/mo><mi>c<\/mi><mo>\u2264<\/mo><mi>A<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">1 \\leq c \\leq A<\/annotation><\/semantics><\/math>. Luego, para calcular la atenci\u00f3n del token en posici\u00f3n <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>i<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">i<\/annotation><\/semantics><\/math>, la cabeza <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>c<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">c<\/annotation><\/semantics><\/math> compara la query <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>q<\/mi><mi>i<\/mi><mi>c<\/mi><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">q_i^c<\/annotation><\/semantics><\/math>\u200b con las keys <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>k<\/mi><mi>j<\/mi><mi>c<\/mi><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">k_j^c<\/annotation><\/semantics><\/math>\u200b de los tokens disponibles en el contexto:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><msup><mi>e<\/mi><mi>c<\/mi><\/msup><mo stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><mo stretchy=\"false\">)<\/mo><mo>=<\/mo><mfrac><mrow><msubsup><mi>q<\/mi><mi>i<\/mi><mi>c<\/mi><\/msubsup><mo>\u22c5<\/mo><msubsup><mi>k<\/mi><mi>j<\/mi><mi>c<\/mi><\/msubsup><\/mrow><msqrt><msub><mi>d<\/mi><mi>k<\/mi><\/msub><\/msqrt><\/mfrac><\/mrow><annotation encoding=\"application\/x-tex\">score^c(x_i,x_j) = \\frac{q_i^c \\cdot k_j^c}{\\sqrt{d_k}}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Estos scores se normalizan mediante una softmax, produciendo los pesos de atenci\u00f3n:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><msubsup><mi>\u03b1<\/mi><mrow><mi>i<\/mi><mi>j<\/mi><\/mrow><mi>c<\/mi><\/msubsup><mo>=<\/mo><mtext>softmax<\/mtext><mo stretchy=\"false\">(<\/mo><mi>s<\/mi><mi>c<\/mi><mi>o<\/mi><mi>r<\/mi><msup><mi>e<\/mi><mi>c<\/mi><\/msup><mo stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>j<\/mi><\/msub><mo stretchy=\"false\">)<\/mo><mo stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">\\alpha_{ij}^c = \\text{softmax}(score^c(x_i,x_j))<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A partir de estos pesos, cada cabeza calcula su propia suma ponderada de los value vectors:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msubsup><mi>d<\/mi><mi>i<\/mi><mi>c<\/mi><\/msubsup><mo>=<\/mo><munder><mo>\u2211<\/mo><mrow><mi>j<\/mi><mo>\u2264<\/mo><mi>i<\/mi><\/mrow><\/munder><msubsup><mi>\u03b1<\/mi><mrow><mi>i<\/mi><mi>j<\/mi><\/mrow><mi>c<\/mi><\/msubsup><msubsup><mi>v<\/mi><mi>j<\/mi><mi>c<\/mi><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">head_i^c = \\sum_{j \\leq i} \\alpha_{ij}^c v_j^c<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Finalmente, las salidas de todas las cabezas se concatenan y se proyectan mediante una matriz <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msup><mi>W<\/mi><mi>O<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W^O<\/annotation><\/semantics><\/math>:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><msub><mi>a<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><mo stretchy=\"false\">(<\/mo><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msubsup><mi>d<\/mi><mi>i<\/mi><mn>1<\/mn><\/msubsup><mo>\u2295<\/mo><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msubsup><mi>d<\/mi><mi>i<\/mi><mn>2<\/mn><\/msubsup><mo>\u2295<\/mo><mo>\u22ef<\/mo><mo>\u2295<\/mo><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msubsup><mi>d<\/mi><mi>i<\/mi><mi>A<\/mi><\/msubsup><mo stretchy=\"false\">)<\/mo><msup><mi>W<\/mi><mi>O<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">a_i = (head_i^1 \\oplus head_i^2 \\oplus \\dots \\oplus head_i^A)W^O<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As\u00ed, la funci\u00f3n de multi-head attention puede expresarse como:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mi>M<\/mi><mi>u<\/mi><mi>l<\/mi><mi>t<\/mi><mi>i<\/mi><mi>H<\/mi><mi>e<\/mi><mi>a<\/mi><mi>d<\/mi><mi>A<\/mi><mi>t<\/mi><mi>t<\/mi><mi>e<\/mi><mi>n<\/mi><mi>t<\/mi><mi>i<\/mi><mi>o<\/mi><mi>n<\/mi><mo stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo separator=\"true\">,<\/mo><mo stretchy=\"false\">[<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><mo>\u2026<\/mo><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo stretchy=\"false\">]<\/mo><mo stretchy=\"false\">)<\/mo><mo>=<\/mo><msub><mi>a<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">MultiHeadAttention(x_i, [x_1, \\dots, x_i]) = a_i<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vale la pena destacar que la salida de cada cabeza <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>h<\/mi><mi>e<\/mi><mi>a<\/mi><msubsup><mi>d<\/mi><mi>i<\/mi><mi>c<\/mi><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">head_i^c<\/annotation><\/semantics><\/math> tiene dimensi\u00f3n:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mo stretchy=\"false\">[<\/mo><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mi>v<\/mi><\/msub><mo stretchy=\"false\">]<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">[1 \\times d_v]<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por lo tanto, si tenemos <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>A<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">A<\/annotation><\/semantics><\/math> cabezas, la concatenaci\u00f3n de todas ellas produce un vector de dimensi\u00f3n:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\" display=\"block\"><semantics><mrow><mo stretchy=\"false\">[<\/mo><mn>1<\/mn><mo>\u00d7<\/mo><mi>A<\/mi><msub><mi>d<\/mi><mi>v<\/mi><\/msub><mo stretchy=\"false\">]<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">[1 \\times A d_v]<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Luego, la matriz <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msup><mi>W<\/mi><mi>O<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W^O<\/annotation><\/semantics><\/math> proyecta esta concatenaci\u00f3n de vuelta al espacio del modelo:<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msup><mi>W<\/mi><mi>O<\/mi><\/msup><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mi>A<\/mi><msub><mi>d<\/mi><mi>v<\/mi><\/msub><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W^{O} \\in \\mathbb{R}^{Ad_{v}\\times d_{model}}<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">De esta forma, la salida final de <em>multi-head attention<\/em> conserva la dimensi\u00f3n esperada:<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><msub><mi>a<\/mi><mi>i<\/mi><\/msub><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">a_{i} \\in \\mathbb{R}^{1\\times d_{model}}<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Esto es importante porque permite que la salida de la atenci\u00f3n pueda integrarse al flujo residual del transformer y pasar a las siguientes capas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Transformer Blocks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Multi-head attention<\/strong> es uno de los subcomponentes de un <strong>transformer block<\/strong>. Lo hemos explicado en un apartado especial porque es, probablemente, el componente m\u00e1s caracter\u00edstico y complejo de la arquitectura. Sin embargo, un transformer block moderno incluye tambi\u00e9n otros elementos importantes, como <strong>LayerNorm<\/strong>, <strong>conexiones residuales<\/strong> y una <strong>feedforward network<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El objetivo de esta secci\u00f3n es entender c\u00f3mo interact\u00faan estos subcomponentes dentro del bloque. Para ello, resulta \u00fatil introducir la idea de <strong>residual stream<\/strong>. En un transformer moderno, la representaci\u00f3n de cada token no se reemplaza por completo cada vez que pasa por un subcomponente. M\u00e1s bien, existe un flujo principal de informaci\u00f3n \u2014el residual stream\u2014 que transporta la representaci\u00f3n del token a trav\u00e9s del bloque. Los distintos m\u00f3dulos leen desde ese flujo, calculan nueva informaci\u00f3n y luego suman su resultado de vuelta mediante conexiones residuales. En particular, la <strong>multi-head attention<\/strong> incorpora informaci\u00f3n contextual proveniente de otros tokens, mientras que la <strong>feedforward network<\/strong> transforma la representaci\u00f3n de cada token de forma independiente. Este principio se ilustra en la siguiente figura:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-1-1024x768.png\" alt=\"\" class=\"wp-image-257\" srcset=\"https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-1-1024x768.png 1024w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-1-300x225.png 300w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-1-768x576.png 768w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-1.png 1448w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Como se puede ver, cada token tiene su propio flujo vertical de informaci\u00f3n. En la figura, el token principal es <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_i<\/annotation><\/semantics><\/math>. Ese vector sube por el bloque, mientras algunos m\u00f3dulos leen desde \u00e9l, calculan nueva informaci\u00f3n y la suman de vuelta al flujo principal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En la secci\u00f3n pasada explicamos el m\u00f3dulo de <em>multi-head attention<\/em>, sin embargo, nos falta explicar <em>feedforward<\/em>, y <em>layernorm<\/em>.<\/p>\n\n\n\n<p class=\"is-style-text-subtitle is-style-text-subtitle--3 wp-block-paragraph\">Capa feedforward<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La capa <em>feedforward<\/em>  de esta arquitectura-cuyo concepto fue explicado en esta <a href=\"https:\/\/pulki.es\/blog\/index.php\/2026\/04\/11\/large-language-model-llm-from-scratch-neural-networks\/\">entrada<\/a>&#8211; es una red neuronal completamente conectada de dos capas, cuya capa oculta (<math data-latex=\"d_{ff}\"><semantics><msub><mi>d<\/mi><mrow><mi>f<\/mi><mi>f<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">d_{ff}<\/annotation><\/semantics><\/math>) suele tener una dimensi\u00f3n m\u00e1s grande que la del modelo (<math data-latex=\"d_{model}\"><semantics><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">d_{model}<\/annotation><\/semantics><\/math>). Conceptualmente, la red hace algo similar a esto:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"[1\\times d_{model}] \\to [1\\times d_{ff}] \\to [1\\times d_{model}] \"><semantics><mrow><mo form=\"prefix\" stretchy=\"false\">[<\/mo><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">]<\/mo><mo>\u2192<\/mo><mo form=\"prefix\" stretchy=\"false\">[<\/mo><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>f<\/mi><mi>f<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">]<\/mo><mo>\u2192<\/mo><mo form=\"prefix\" stretchy=\"false\">[<\/mo><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mo form=\"postfix\" stretchy=\"false\">]<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">[1\\times d_{model}] \\to [1\\times d_{ff}] \\to [1\\times d_{model}] <\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En este caso, llevamos al vector de entrada a un espacio m\u00e1s grande (de  <math data-latex=\"d_{model}\"><semantics><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">d_{model}<\/annotation><\/semantics><\/math> a  <math data-latex=\"d_{ff}\"><semantics><msub><mi>d<\/mi><mrow><mi>f<\/mi><mi>f<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">d_{ff}<\/annotation><\/semantics><\/math>), porque as\u00ed la red tiene m\u00e1s \u201clugar\u201d para representar combinaciones, patrones y transformaciones no lineales. Despu\u00e9s, comprime esa informaci\u00f3n de vuelta a la dimensi\u00f3n del modelo (<math data-latex=\"d_{model}\"><semantics><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">d_{model}<\/annotation><\/semantics><\/math>). Esta compresi\u00f3n es necesaria para que sigamos trabajando con el vector en el flujo residual, de otra forma, dejar\u00edamos el vector de salida en una dimensi\u00f3n que no es la que espera el subcomponente siguiente. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dicho esto, en t\u00e9rminos matem\u00e1ticos, este paso se puede expresar de la siguiente forma:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"FFN(x_{i}) = ReLU(x_{i}W_{1} + b_{1} ) W_{2} + b_{2}\"><semantics><mrow><mi>F<\/mi><mi>F<\/mi><mi>N<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mi>R<\/mi><mi>e<\/mi><mi>L<\/mi><mi>U<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><msub><mi>W<\/mi><mn>1<\/mn><\/msub><mo>+<\/mo><msub><mi>b<\/mi><mn>1<\/mn><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><msub><mi>W<\/mi><mn>2<\/mn><\/msub><mo>+<\/mo><msub><mi>b<\/mi><mn>2<\/mn><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">FFN(x_{i}) = ReLU(x_{i}W_{1} + b_{1} ) W_{2} + b_{2}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">donde <math data-latex=\"x_{i} \\in \\mathbb{R}^{1\\times d_{model}}\"><semantics><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">x_{i} \\in \\mathbb{R}^{1\\times d_{model}}<\/annotation><\/semantics><\/math>, <math data-latex=\"W_{1} \\in \\mathbb{R}^{d_{model}\\times d_{ff}}\"><semantics><mrow><msub><mi>W<\/mi><mn>1<\/mn><\/msub><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>f<\/mi><mi>f<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W_{1} \\in \\mathbb{R}^{d_{model}\\times d_{ff}}<\/annotation><\/semantics><\/math> y <math data-latex=\"W_{2} \\in \\mathbb{R}^{d_{ff}\\times d_{model}}\"><semantics><mrow><msub><mi>W<\/mi><mn>2<\/mn><\/msub><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><msub><mi>d<\/mi><mrow><mi>f<\/mi><mi>f<\/mi><\/mrow><\/msub><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">W_{2} \\in \\mathbb{R}^{d_{ff}\\times d_{model}}<\/annotation><\/semantics><\/math> (Tarea: chequea que <math data-latex=\"FFN(x_{i}) \\in \\mathbb{R}^{1\\times d_{model}}\"><semantics><mrow><mi>F<\/mi><mi>F<\/mi><mi>N<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">FFN(x_{i}) \\in \\mathbb{R}^{1\\times d_{model}}<\/annotation><\/semantics><\/math>). <\/p>\n\n\n\n<p class=\"is-style-text-subtitle is-style-text-subtitle--4 wp-block-paragraph\">Capa LayerNorm<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Layer norm<\/em> (de Layer Normalization) normaliza el vector de representaci\u00f3n de cada token para que sus valores no crezcan, se desplacen o se vuelvan demasiado extremos a medida que pasan por muchas capas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si pensamos en <math data-latex=\"x_{i} \\in \\mathbb{R}^{1\\times d_{model}}\"><semantics><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">x_{i} \\in \\mathbb{R}^{1\\times d_{model}}<\/annotation><\/semantics><\/math>, <em>layer norm<\/em> toma ese vector y calcula la media y la desviaci\u00f3n est\u00e1ndar <strong>de sus propias dimensiones internas<\/strong>. Es decir, no normaliza toda la capa completa ni todos los tokens juntos, sino el vector individual de un token. En t\u00e9rminos matem\u00e1ticos, primero hace<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"\\mu = \\frac{1}{d_{model}}\\sum_{r=1}^{d_{model}}x_{i}^{r}\"><semantics><mrow><mi>\u03bc<\/mi><mo>=<\/mo><mfrac><mn>1<\/mn><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mfrac><msubsup><mo movablelimits=\"false\">\u2211<\/mo><mrow><mi>r<\/mi><mo>=<\/mo><mn>1<\/mn><\/mrow><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/msubsup><msubsup><mi>x<\/mi><mi>i<\/mi><mi>r<\/mi><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">\\mu = \\frac{1}{d_{model}}\\sum_{r=1}^{d_{model}}x_{i}^{r}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"\\sigma = \\sqrt{\\frac{1}{d_{model}}\\sum_{r=1}^{d_{model}}(x_{i}^{r}-\\mu)^{2}}\"><semantics><mrow><mi>\u03c3<\/mi><mo>=<\/mo><msqrt><mrow><mfrac><mn>1<\/mn><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mfrac><msubsup><mo movablelimits=\"false\">\u2211<\/mo><mrow><mi>r<\/mi><mo>=<\/mo><mn>1<\/mn><\/mrow><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/msubsup><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msubsup><mi>x<\/mi><mi>i<\/mi><mi>r<\/mi><\/msubsup><mo>\u2212<\/mo><mi>\u03bc<\/mi><msup><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mn>2<\/mn><\/msup><\/mrow><\/msqrt><\/mrow><annotation encoding=\"application\/x-tex\">\\sigma = \\sqrt{\\frac{1}{d_{model}}\\sum_{r=1}^{d_{model}}(x_{i}^{r}-\\mu)^{2}}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Luego, normaliza:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"\\hat{x}_{i} = \\frac{x_{i}-\\mu}{\\sigma}\"><semantics><mrow><msub><mover><mi>x<\/mi><mo stretchy=\"false\" class=\"tml-xshift\" style=\"math-style:normal;math-depth:0;\">^<\/mo><\/mover><mi>i<\/mi><\/msub><mo>=<\/mo><mfrac><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo>\u2212<\/mo><mi>\u03bc<\/mi><\/mrow><mi>\u03c3<\/mi><\/mfrac><\/mrow><annotation encoding=\"application\/x-tex\">\\hat{x}_{i} = \\frac{x_{i}-\\mu}{\\sigma}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">y finalmente, aplica dos par\u00e1metros aprendibles (<math data-latex=\"\\alpha \"><semantics><mi>\u03b1<\/mi><annotation encoding=\"application\/x-tex\">\\alpha <\/annotation><\/semantics><\/math> y <math data-latex=\"\\beta\"><semantics><mi>\u03b2<\/mi><annotation encoding=\"application\/x-tex\">\\beta<\/annotation><\/semantics><\/math>):<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"\\text{LayerNorm}(\\hat{x}_{i}) = \\alpha \\hat{x_{i}} + \\beta\"><semantics><mrow><mtext>LayerNorm<\/mtext><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mover><mi>x<\/mi><mo stretchy=\"false\" class=\"tml-xshift\" style=\"math-style:normal;math-depth:0;\">^<\/mo><\/mover><mi>i<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>=<\/mo><mi>\u03b1<\/mi><mover><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo stretchy=\"false\" style=\"math-style:normal;math-depth:0;\">^<\/mo><\/mover><mo>+<\/mo><mi>\u03b2<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\text{LayerNorm}(\\hat{x}_{i}) = \\alpha \\hat{x_{i}} + \\beta<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"is-style-text-subtitle is-style-text-subtitle--5 wp-block-paragraph\">Bloque completo<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Empleando la notaci\u00f3n de <strong><a href=\"https:\/\/web.stanford.edu\/~jurafsky\/slp3\/\">Jurafsky y Martin (2026)<\/a><\/strong>, podemos expresar los c\u00e1lculos que hace un <em>transformer block<\/em> en el siguiente conjunto de ecauciones:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math data-latex=\"t_{i}^{1} = \\text{LayerNorm}(x_{i})\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>1<\/mn><\/msubsup><mo>=<\/mo><mtext>LayerNorm<\/mtext><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">t_{i}^{1} = \\text{LayerNorm}(x_{i})<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math data-latex=\"t_{i}^{2} = \\text{MultiheadAttention}(t_{i}^{1}, [t_{1}^{1},...t_{N}^{1}])\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>2<\/mn><\/msubsup><mo>=<\/mo><mtext>MultiheadAttention<\/mtext><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msubsup><mi>t<\/mi><mi>i<\/mi><mn>1<\/mn><\/msubsup><mo separator=\"true\">,<\/mo><mo form=\"prefix\" stretchy=\"false\">[<\/mo><msubsup><mi>t<\/mi><mn>1<\/mn><mn>1<\/mn><\/msubsup><mo separator=\"true\">,<\/mo><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><msubsup><mi>t<\/mi><mi>N<\/mi><mn>1<\/mn><\/msubsup><mo form=\"postfix\" stretchy=\"false\">]<\/mo><mo form=\"postfix\" stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">t_{i}^{2} = \\text{MultiheadAttention}(t_{i}^{1}, [t_{1}^{1},&#8230;t_{N}^{1}])<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math data-latex=\"t^{3}_{i} = t_{i}^{2} + x_{i}\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>3<\/mn><\/msubsup><mo>=<\/mo><msubsup><mi>t<\/mi><mi>i<\/mi><mn>2<\/mn><\/msubsup><mo>+<\/mo><msub><mi>x<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">t^{3}_{i} = t_{i}^{2} + x_{i}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math data-latex=\"t_{i}^{4} = \\text{LayerNorm}(t_{i}^{3})\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>4<\/mn><\/msubsup><mo>=<\/mo><mtext>LayerNorm<\/mtext><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msubsup><mi>t<\/mi><mi>i<\/mi><mn>3<\/mn><\/msubsup><mo form=\"postfix\" stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">t_{i}^{4} = \\text{LayerNorm}(t_{i}^{3})<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math data-latex=\"t_{i}^{5} = \\text{FFN}(t_{i}^{4})\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>5<\/mn><\/msubsup><mo>=<\/mo><mtext>FFN<\/mtext><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msubsup><mi>t<\/mi><mi>i<\/mi><mn>4<\/mn><\/msubsup><mo form=\"postfix\" stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">t_{i}^{5} = \\text{FFN}(t_{i}^{4})<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><math data-latex=\"h_{i} = t_{i}^{5} + t_{i}^{3}\"><semantics><mrow><msub><mi>h<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><msubsup><mi>t<\/mi><mi>i<\/mi><mn>5<\/mn><\/msubsup><mo>+<\/mo><msubsup><mi>t<\/mi><mi>i<\/mi><mn>3<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">h_{i} = t_{i}^{5} + t_{i}^{3}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Primero, en <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>1<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">t_i^1<\/annotation><\/semantics><\/math>, se normaliza la representaci\u00f3n de entrada del token <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_i<\/annotation><\/semantics><\/math>. Luego, en <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>2<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">t_i^2<\/annotation><\/semantics><\/math>\u200b, esa representaci\u00f3n normalizada entra al m\u00f3dulo de <strong>multi-head attention<\/strong>, que calcula una contribuci\u00f3n contextual para el token <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>i<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">i<\/annotation><\/semantics><\/math>, usando informaci\u00f3n del propio token y de los tokens disponibles en el contexto. Despu\u00e9s, en <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>3<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">t_i^3<\/annotation><\/semantics><\/math>, la salida de attention se suma al vector original <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_i<\/annotation><\/semantics><\/math>, formando la primera conexi\u00f3n residual.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A continuaci\u00f3n, en <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>4<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">t_i^4<\/annotation><\/semantics><\/math>\u200b, se normaliza esta representaci\u00f3n actualizada <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>3<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">t_i^3<\/annotation><\/semantics><\/math>\u200b. Luego, en <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>5<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">t_i^5<\/annotation><\/semantics><\/math>, la representaci\u00f3n normalizada pasa por la red <strong>feedforward<\/strong>, que transforma el vector del <em>token<\/em> de forma independiente respecto de los dem\u00e1s <em>tokens.<\/em> Finalmente, la salida de la <strong>feedforward<\/strong> se suma nuevamente a <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>t<\/mi><mi>i<\/mi><mn>3<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">t_i^3<\/annotation><\/semantics><\/math>, produciendo <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>h<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">h_i<\/annotation><\/semantics><\/math>, la salida final del transformer block para el token en la posici\u00f3n <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>i<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">i<\/annotation><\/semantics><\/math>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sobre la entrada <math data-latex=\"x_{i}\"><semantics><msub><mi>x<\/mi><mi>i<\/mi><\/msub><annotation encoding=\"application\/x-tex\">x_{i}<\/annotation><\/semantics><\/math><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Hasta este punto, hemos discutido lo que hacemos con el vector <math data-latex=\"x_{i} \\in \\mathbb{R}^{1\\times d_{model}}\"><semantics><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">x_{i} \\in \\mathbb{R}^{1\\times d_{model}}<\/annotation><\/semantics><\/math> , no obstante, no hemos dicho mucho sobre \u00e9l. En esta secci\u00f3n veremos que no s\u00f3lo es necesario el <em>embedding<\/em>, si no tambi\u00e9n, la posici\u00f3n de dicho vector en la secuencia.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Supongamos que tenemos una secuencia de <strong>N<\/strong> tokens, donde<strong> N <\/strong>es el largo del contexto. El <em>input<\/em> del <em>transformer<\/em> se podr\u00eda escribir como <math data-latex=\"X \\in \\mathbb{R}^{N\\times d_{model}}\"><semantics><mrow><mi>X<\/mi><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mi>N<\/mi><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">X \\in \\mathbb{R}^{N\\times d_{model}}<\/annotation><\/semantics><\/math> , donde <math data-latex=\"d_{model}\"><semantics><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><annotation encoding=\"application\/x-tex\">d_{model}<\/annotation><\/semantics><\/math> es el largo del <em>embedding<\/em>. Para ilustrar esta matriz, a modo de ejemplo, asumiremos que cada <em>token<\/em> es una palabra, y que nuestro contexto viene dado por la siguiente frase (N=7):<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Esto me an buelto myos enemigos malos<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Dicha secuencia deber\u00e1 tener 7 <em>embeddings<\/em>, que vienen dados por:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Esto = [<math data-latex=\"x_{1}^{1},...,x_{d_{model}}^{1}\"><semantics><mrow><msubsup><mi>x<\/mi><mn>1<\/mn><mn>1<\/mn><\/msubsup><mo separator=\"true\">,<\/mo><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><mo separator=\"true\">,<\/mo><msubsup><mi>x<\/mi><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mn>1<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">x_{1}^{1},&#8230;,x_{d_{model}}^{1}<\/annotation><\/semantics><\/math>]<\/li>\n\n\n\n<li>me = [<math data-latex=\"x_{1}^{2},...,x_{d_{model}}^{2}\"><semantics><mrow><msubsup><mi>x<\/mi><mn>1<\/mn><mn>2<\/mn><\/msubsup><mo separator=\"true\">,<\/mo><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><mo separator=\"true\">,<\/mo><msubsup><mi>x<\/mi><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mn>2<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">x_{1}^{2},&#8230;,x_{d_{model}}^{2}<\/annotation><\/semantics><\/math>]<\/li>\n\n\n\n<li>an = [<math data-latex=\"x_{1}^{3},...,x_{d_{model}}^{3}\"><semantics><mrow><msubsup><mi>x<\/mi><mn>1<\/mn><mn>3<\/mn><\/msubsup><mo separator=\"true\">,<\/mo><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><mo separator=\"true\">,<\/mo><msubsup><mi>x<\/mi><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mn>3<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">x_{1}^{3},&#8230;,x_{d_{model}}^{3}<\/annotation><\/semantics><\/math>]<\/li>\n\n\n\n<li>&#8230;<\/li>\n\n\n\n<li>malos = [<math data-latex=\"x_{1}^{7},...,x_{d_{model}}^{7}\"><semantics><mrow><msubsup><mi>x<\/mi><mn>1<\/mn><mn>7<\/mn><\/msubsup><mo separator=\"true\">,<\/mo><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><mo separator=\"true\">,<\/mo><msubsup><mi>x<\/mi><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mn>7<\/mn><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">x_{1}^{7},&#8230;,x_{d_{model}}^{7}<\/annotation><\/semantics><\/math>]<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Por lo que la matriz <strong>X<\/strong> vendr\u00eda dada por:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"X = \\begin{bmatrix} x_{1}^{1} &amp; ... &amp; x_{d_{model}}^{1} \\\\ ... &amp; ... &amp; ... \\\\ x_{1}^{7} &amp; ... &amp; x_{d_{model}}^{7} \\end{bmatrix} \"><semantics><mrow><mi>X<\/mi><mo>=<\/mo><mrow><mo fence=\"true\" form=\"prefix\">[<\/mo><mtable columnalign=\"center center center\"><mtr><mtd style=\"padding-left:0em;\"><msubsup><mi>x<\/mi><mn>1<\/mn><mn>1<\/mn><\/msubsup><\/mtd><mtd><mrow><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><\/mrow><\/mtd><mtd style=\"padding-right:0em;\"><msubsup><mi>x<\/mi><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mn>1<\/mn><\/msubsup><\/mtd><\/mtr><mtr><mtd style=\"padding-left:0em;\"><mrow><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><\/mrow><\/mtd><mtd><mrow><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><\/mrow><\/mtd><mtd style=\"padding-right:0em;\"><mrow><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><\/mrow><\/mtd><\/mtr><mtr><mtd style=\"padding-left:0em;\"><msubsup><mi>x<\/mi><mn>1<\/mn><mn>7<\/mn><\/msubsup><\/mtd><mtd><mrow><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><\/mrow><\/mtd><mtd style=\"padding-right:0em;\"><msubsup><mi>x<\/mi><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><mn>7<\/mn><\/msubsup><\/mtd><\/mtr><\/mtable><mo fence=\"true\" form=\"postfix\">]<\/mo><\/mrow><\/mrow><annotation encoding=\"application\/x-tex\">X = \\begin{bmatrix} x_{1}^{1} &amp; &#8230; &amp; x_{d_{model}}^{1} \\\\ &#8230; &amp; &#8230; &amp; &#8230; \\\\ x_{1}^{7} &amp; &#8230; &amp; x_{d_{model}}^{7} \\end{bmatrix} <\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En este punto, es importante entender que los <em>embeddings <\/em>obtenidos no registran ning\u00fan tipo de posici\u00f3n en el texto -en <a href=\"https:\/\/pulki.es\/blog\/index.php\/2026\/03\/18\/large-language-model-llm-from-scratch-embeddings\/\">esta entrada<\/a> podr\u00e1s entender por qu\u00e9-. No obstante, como podr\u00e1s intuir despu\u00e9s de leer el apartado de atenci\u00f3n, la posici\u00f3n importa. En la siguiente imagen ilustramos por qu\u00e9 importa:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-2-1024x768.png\" alt=\"\" class=\"wp-image-264\" srcset=\"https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-2-1024x768.png 1024w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-2-300x225.png 300w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-2-768x576.png 768w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-2.png 1448w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">En este caso, podemos ver que el significado de la oraci\u00f3n cambia levemente al intercambiar el orden de las palabras. Entonces, para que el <em>transformer<\/em> enriquezca los vectores seg\u00fan el contexto de forma correcta, es necesario que reciba el <em>token<\/em> bajo an\u00e1lisis, m\u00e1s los <em>tokens<\/em> que lo preceden en el orden original en que aparecieron en la secuencia.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para llevar a cabo esta tarea, el modelo usa <strong>positional embeddings<\/strong>. Estos <em>embeddings<\/em> son vectores asociados a las posiciones de la secuencia. Por ejemplo, si tenemos una secuencia de <strong><em>N<\/em><\/strong>  <em>tokens<\/em>, tendr\u00edamos <strong><em>N<\/em><\/strong> vectores:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><math data-latex=\"P_{1} \\in \\mathbb{R}^{1\\times d_{model}}\"><semantics><mrow><msub><mi>P<\/mi><mn>1<\/mn><\/msub><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">P_{1} \\in \\mathbb{R}^{1\\times d_{model}}<\/annotation><\/semantics><\/math><\/li>\n\n\n\n<li><math data-latex=\"P_{2} \\in \\mathbb{R}^{1\\times d_{model}}\"><semantics><mrow><msub><mi>P<\/mi><mn>2<\/mn><\/msub><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">P_{2} \\in \\mathbb{R}^{1\\times d_{model}}<\/annotation><\/semantics><\/math><\/li>\n\n\n\n<li>&#8230;<\/li>\n\n\n\n<li><math data-latex=\"P_{N} \\in \\mathbb{R}^{1\\times d_{model}}\"><semantics><mrow><msub><mi>P<\/mi><mi>N<\/mi><\/msub><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">P_{N} \\in \\mathbb{R}^{1\\times d_{model}}<\/annotation><\/semantics><\/math><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Luego, para construir la representaci\u00f3n final de la entrada del <em>token<\/em> en la posici\u00f3n <math data-latex=\"i\"><semantics><mi>i<\/mi><annotation encoding=\"application\/x-tex\">i<\/annotation><\/semantics><\/math>, llevamos a cabo la siguiente suma:<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><math data-latex=\"x_{i} = E[token_{i}] + P_{i}\"><semantics><mrow><msub><mi>x<\/mi><mi>i<\/mi><\/msub><mo>=<\/mo><mi>E<\/mi><mo form=\"prefix\" stretchy=\"false\">[<\/mo><mi>t<\/mi><mi>o<\/mi><mi>k<\/mi><mi>e<\/mi><msub><mi>n<\/mi><mi>i<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">]<\/mo><mo>+<\/mo><msub><mi>P<\/mi><mi>i<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">x_{i} = E[token_{i}] + P_{i}<\/annotation><\/semantics><\/math><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">donde <math data-latex=\"E \\in \\mathbb{R}^{|V|\\times d_{model}}\"><semantics><mrow><mi>E<\/mi><mo>\u2208<\/mo><msup><mi>\u211d<\/mi><mrow><mi>|<\/mi><mi>V<\/mi><mi>|<\/mi><mo>\u00d7<\/mo><msub><mi>d<\/mi><mrow><mi>m<\/mi><mi>o<\/mi><mi>d<\/mi><mi>e<\/mi><mi>l<\/mi><\/mrow><\/msub><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">E \\in \\mathbb{R}^{|V|\\times d_{model}}<\/annotation><\/semantics><\/math>, es el vector de <em>embeddings<\/em>, y <math data-latex=\"|V|\"><semantics><mrow><mi>|<\/mi><mi>V<\/mi><mi>|<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">|V|<\/annotation><\/semantics><\/math> es el tama\u00f1o del vocabulario.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfC\u00f3mo se aprende el modelo <math data-latex=\"P_{i}\"><semantics><msub><mi>P<\/mi><mi>i<\/mi><\/msub><annotation encoding=\"application\/x-tex\">P_{i}<\/annotation><\/semantics><\/math>? Al inicio del entrenamiento, los vectores <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>P<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><mo>\u2026<\/mo><mo separator=\"true\">,<\/mo><msub><mi>P<\/mi><mi>N<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">P_1,\\dots,P_N<\/annotation><\/semantics><\/math>\u200b suelen estar inicializados con valores aleatorios. Durante el entrenamiento, el modelo intenta predecir correctamente los siguientes tokens. Si la informaci\u00f3n de posici\u00f3n ayuda a reducir el error, los gradientes van ajustando esos vectores posicionales. Con muchas frases, el modelo aprende patrones como: qu\u00e9 suele pasar al comienzo de una oraci\u00f3n, qu\u00e9 roles suelen tener ciertas posiciones, c\u00f3mo afecta el orden a la interpretaci\u00f3n, etc.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Language Modeling Head<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Hasta este punto ya sabemos lo que hace la capa del <em>transformer.<\/em> En t\u00e9rminos coloquiales, en dicha capa entra un bloque completo de <em>tokens<\/em> como una matriz, y el <em>transformer<\/em> procesa todas las posiciones en paralelo. Gracias a la <strong>m\u00e1scara causal<\/strong>, cada posici\u00f3n s\u00f3lo puede usar informaci\u00f3n de los tokens anteriores y de s\u00ed misma. En t\u00e9rminos matem\u00e1ticos, una capa de <em>transformer<\/em> mapea una ventana completa de vectores de entrada (<strong>x)<\/strong> en vectores de salida contextualizados <strong>(h)<\/strong>, es decir,<\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>x<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mn>2<\/mn><\/msub><mo separator=\"true\">,<\/mo><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><mo separator=\"true\">,<\/mo><msub><mi>x<\/mi><mi>N<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mo>\u2192<\/mo><mo form=\"prefix\" stretchy=\"false\">(<\/mo><msub><mi>h<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>h<\/mi><mn>2<\/mn><\/msub><mo separator=\"true\">,<\/mo><mi>.<\/mi><mi>.<\/mi><mi>.<\/mi><mo separator=\"true\">,<\/mo><msub><mi>h<\/mi><mi>N<\/mi><\/msub><mo form=\"postfix\" stretchy=\"false\">)<\/mo><\/mrow><annotation encoding=\"application\/x-tex\">(x_{1},x_{2},&#8230;,x_{N}) \\to (h_{1},h_{2},&#8230;,h_{N})<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">La siguiente ilustraci\u00f3n resume parte de lo que hemos explicado si entrase la secuencia \u00abA diestro dexan a Sant Esteuan, mas cae aluen.\u00bb<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-3-1024x768.png\" alt=\"\" class=\"wp-image-269\" srcset=\"https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-3-1024x768.png 1024w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-3-300x225.png 300w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-3-768x576.png 768w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-3.png 1448w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Con estos vectores ya enriquecidos, estamos en condiciones de predecir la siguiente palabra (como lo hicimos en esta <a href=\"https:\/\/pulki.es\/blog\/index.php\/2026\/02\/21\/large-language-model-llm-from-scratch-n-gram-language-models\/\">entrada<\/a>). Este proceso es la funci\u00f3n principal de un <strong>language modeling head<\/strong>. La siguiente imagen explica esta funci\u00f3n en detalle:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-4-1024x576.png\" alt=\"\" class=\"wp-image-270\" srcset=\"https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-4-1024x576.png 1024w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-4-300x169.png 300w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-4-768x432.png 768w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-4-1536x864.png 1536w, https:\/\/pulki.es\/blog\/wp-content\/uploads\/2026\/05\/image-4.png 1672w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">La figura muestra el flujo final de un transformer usado como modelo de lenguaje. Primero, una secuencia de tokens de entrada <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msub><mi>w<\/mi><mn>1<\/mn><\/msub><mo separator=\"true\">,<\/mo><msub><mi>w<\/mi><mn>2<\/mn><\/msub><mo separator=\"true\">,<\/mo><mo>\u2026<\/mo><mo separator=\"true\">,<\/mo><msub><mi>w<\/mi><mi>N<\/mi><\/msub><\/mrow><annotation encoding=\"application\/x-tex\">w_1, w_2, \\dots, w_N<\/annotation><\/semantics><\/math>\u200b atraviesa el \u00faltimo bloque <em>transformer<\/em>, produciendo una representaci\u00f3n contextualizada para cada posici\u00f3n: <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>h<\/mi><mn>1<\/mn><mi>L<\/mi><\/msubsup><mo separator=\"true\">,<\/mo><msubsup><mi>h<\/mi><mn>2<\/mn><mi>L<\/mi><\/msubsup><mo separator=\"true\">,<\/mo><mo>\u2026<\/mo><mo separator=\"true\">,<\/mo><msubsup><mi>h<\/mi><mi>N<\/mi><mi>L<\/mi><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">h_1^L, h_2^L, \\dots, h_N^L<\/annotation><\/semantics><\/math>\u200b. Durante la generaci\u00f3n, normalmente nos interesa el \u00faltimo vector contextualizado, <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>h<\/mi><mi>N<\/mi><mi>L<\/mi><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">h_N^L<\/annotation><\/semantics><\/math>\u200b, porque contiene informaci\u00f3n del contexto disponible hasta el token <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>N<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">N<\/annotation><\/semantics><\/math>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Luego, el vector <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><msubsup><mi>h<\/mi><mi>N<\/mi><mi>L<\/mi><\/msubsup><\/mrow><annotation encoding=\"application\/x-tex\">h_N^L<\/annotation><\/semantics><\/math> entra en la <strong>language modeling head<\/strong>. En esta etapa, se proyecta desde el espacio interno del modelo hacia el espacio del vocabulario mediante una capa de <strong>unembedding<\/strong>, usualmente representada como <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>U<\/mi><mo>=<\/mo><msup><mi>E<\/mi><mi>T<\/mi><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">U = E^T<\/annotation><\/semantics><\/math>, donde <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>U<\/mi><mo>\u2208<\/mo><msup><mi mathvariant=\"double-struck\">R<\/mi><mrow><mi>d<\/mi><mo>\u00d7<\/mo><mi mathvariant=\"normal\">\u2223<\/mi><mi>V<\/mi><mi mathvariant=\"normal\">\u2223<\/mi><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">U \\in \\mathbb{R}^{d \\times |V|}<\/annotation><\/semantics><\/math>. Matem\u00e1ticamente, esta operaci\u00f3n se expresa como <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>u<\/mi><mo>=<\/mo><msubsup><mi>h<\/mi><mi>N<\/mi><mi>L<\/mi><\/msubsup><mi>U<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">u = h_N^L U<\/annotation><\/semantics><\/math>, con <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>u<\/mi><mo>\u2208<\/mo><msup><mi mathvariant=\"double-struck\">R<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><mi mathvariant=\"normal\">\u2223<\/mi><mi>V<\/mi><mi mathvariant=\"normal\">\u2223<\/mi><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">u \\in \\mathbb{R}^{1 \\times |V|}<\/annotation><\/semantics><\/math>. El vector resultante <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>u<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">u<\/annotation><\/semantics><\/math> contiene los <strong>logits<\/strong>, es decir, un puntaje no normalizado para cada token posible del vocabulario. Finalmente, una funci\u00f3n <strong>softmax<\/strong> transforma esos logits en una distribuci\u00f3n de probabilidad <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>y<\/mi><mo>\u2208<\/mo><msup><mi mathvariant=\"double-struck\">R<\/mi><mrow><mn>1<\/mn><mo>\u00d7<\/mo><mi mathvariant=\"normal\">\u2223<\/mi><mi>V<\/mi><mi mathvariant=\"normal\">\u2223<\/mi><\/mrow><\/msup><\/mrow><annotation encoding=\"application\/x-tex\">y \\in \\mathbb{R}^{1 \\times |V|}<\/annotation><\/semantics><\/math>. Cada componente de <math xmlns=\"http:\/\/www.w3.org\/1998\/Math\/MathML\"><semantics><mrow><mi>y<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">y<\/annotation><\/semantics><\/math> indica la probabilidad que el modelo asigna a un posible siguiente token.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fase de entrenamiento<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">En el entrenamiento de un transformer causal, el modelo aprende a predecir el siguiente token en cada posici\u00f3n de una secuencia, es decir, <\/p>\n\n\n\n<div class=\"wp-block-math\"><math display=\"block\"><semantics><mrow><mi>\u2119<\/mi><mo form=\"prefix\" stretchy=\"false\">(<\/mo><mtext>aluen.<\/mtext><mi>|<\/mi><mtext>A&nbsp;diestro&nbsp;dexan&nbsp;a&nbsp;Sant&nbsp;Esteuan,&nbsp;mas&nbsp;cae&nbsp;aluen<\/mtext><mo form=\"postfix\" stretchy=\"false\">)<\/mo><mi>.<\/mi><\/mrow><annotation encoding=\"application\/x-tex\">\\mathbb{P}(\\text{aluen.} | \\text{A diestro dexan a Sant Esteuan, mas cae aluen}).<\/annotation><\/semantics><\/math><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Para ello, produce una distribuci\u00f3n de probabilidad sobre el vocabulario y se compara esa distribuci\u00f3n con el token correcto. La p\u00e9rdida usada es la <strong>cross-entropy loss<\/strong>, que penaliza al modelo cuando asigna baja probabilidad al <em>token<\/em> real siguiente (si has seguido esta serie de publicaciones, esto te resultar\u00eda familiar, en caso contrario, visita <a href=\"https:\/\/pulki.es\/blog\/index.php\/2026\/03\/09\/large-language-model-llm-from-scratch-clasificacion\/\">esta<\/a> entrada). Luego, mediante <strong>gradient descent<\/strong>, los pesos del modelo se ajustan para reducir esa p\u00e9rdida promedio. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Es importante precisar que, durante el entrenamiento, el modelo no procesa todo el corpus completo de una sola vez. En la pr\u00e1ctica, se define una <strong>ventana de contexto<\/strong> \u2014por ejemplo, de algunos miles de tokens\u2014 y el corpus se organiza en segmentos o <em>chunks<\/em> que caben dentro de esa ventana. Si un documento es m\u00e1s corto que la ventana, pueden empaquetarse varios documentos en un mismo <em>chunk<\/em>, normalmente separados por un token especial. Cada <em>chunk<\/em> se procesa como una secuencia de entrenamiento: el modelo recibe sus tokens y aprende a predecir el siguiente token en cada posici\u00f3n, respetando la m\u00e1scara causal. De esta manera, puede entrenarse sobre corpus muy grandes, pero siempre mediante fragmentos de tama\u00f1o limitado por su ventana de contexto.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>Notas finales, y pr\u00f3xima entrada\u2026<\/em><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En esta entrada vimos el concepto de <em>transformers <\/em>con mayor profundidad. Esta idea ha sido fundamental en la construcci\u00f3n de los LLM&#8217;s m\u00e1s famosos, por tanto, su lectura es obligatoria.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En la pr\u00f3xima publicaci\u00f3n veremos pr\u00e1cticas asociadas al post-entrenamiento, tales como <em>instuction tuning<\/em> y <em>alignment<\/em>. Stay tuned!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Jos\u00e9 Miguel Mu\u00f1oz Urra \u2013&nbsp;<a href=\"mailto:jmunozu@pulki.es\">jmunozu@pulki.es<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la publicaci\u00f3n pasada entendimos la estructura general de un LLM. Este paso es vital, puesto que nos da una visi\u00f3n panor\u00e1mica sobre la morfolog\u00eda de estos modelos. Con esto en mente, ahora podemos estudiar la arquitectura de aquellos. Existen m\u00faltiples arquitecturas para dise\u00f1ar un LLM, no obstante, en esta entrada vamos a estudiar transformers, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-243","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/pulki.es\/blog\/index.php\/wp-json\/wp\/v2\/posts\/243","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pulki.es\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pulki.es\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pulki.es\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pulki.es\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=243"}],"version-history":[{"count":30,"href":"https:\/\/pulki.es\/blog\/index.php\/wp-json\/wp\/v2\/posts\/243\/revisions"}],"predecessor-version":[{"id":280,"href":"https:\/\/pulki.es\/blog\/index.php\/wp-json\/wp\/v2\/posts\/243\/revisions\/280"}],"wp:attachment":[{"href":"https:\/\/pulki.es\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pulki.es\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pulki.es\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}