Informe técnico · GPT-2 · Flujo de inferencia

Informe Técnico: Análisis del Flujo de Inferencia en el Modelo Transformer GPT-2

Desglose paso a paso del recorrido de los tokens a través del modelo, desde la entrada en texto hasta la generación del siguiente token.

1. Introducción al Proceso de Inferencia

En el contexto de los grandes modelos de lenguaje (LLM) como GPT-2, el término inferencia se refiere al proceso de utilizar un modelo ya entrenado para generar una predicción o respuesta a partir de una entrada de datos. Para los arquitectos de software, comprender este flujo es de importancia estratégica, ya que define cómo una aplicación interactuará con el modelo para producir resultados en tiempo real.

Para los arquitectos, este proceso secuencial y dependiente del estado tiene implicaciones directas en el diseño de sistemas, influyendo en las decisiones sobre estrategias de procesamiento por lotes (batching), la optimización de la latencia para aplicaciones en tiempo real y la gestión de los recursos computacionales necesarios para cada paso de la generación token por token.

Este proceso es fundamentalmente distinto al entrenamiento, que es la fase de aprendizaje computacionalmente intensiva donde el modelo ajusta sus parámetros internos a partir de un vasto corpus de datos. A diferencia de las redes neuronales clásicas, donde las entradas pueden procesarse en paralelo de forma independiente, el procesamiento en un Transformer es inherentemente secuencial y contextual: el significado de cada elemento depende de su relación con todos los demás elementos de la secuencia.

Este informe desglosará cada etapa del flujo de inferencia, comenzando por la preparación de la entrada para su procesamiento por el modelo.

2. Etapa 1: Preparación de la Entrada y Creación de Embeddings

Antes de que un modelo Transformer pueda procesar texto, el lenguaje humano debe ser traducido a una representación matemática estructurada. Esta fase de preparación de la entrada es fundamental, ya que convierte una secuencia de caracteres en un formato numérico de alta dimensión que encapsula tanto el significado semántico de las palabras como su orden dentro de la secuencia.

Este proceso se divide en dos pasos principales: la tokenización y la construcción de un embedding inicial.

2.1. Tokenización: De Texto a Identificadores Numéricos

El primer paso es la tokenización, donde el texto de entrada se descompone en unidades más pequeñas llamadas tokens. A cada token único en el vocabulario del modelo se le asigna un identificador numérico (ID de token). Este proceso convierte una cadena de texto en una secuencia de números enteros que el modelo puede interpretar.

Por ejemplo, al procesar el siguiente texto:

Hola mundo

Esta es una prueba de tokenizacion real.

El tokenizador lo convierte en un tensor de identificadores numéricos, como se muestra a continuación:

Esto indica que el texto original ha sido descompuesto en una secuencia de 20 tokens, cada uno representado por un ID único.

2.2. Construcción del Embedding Inicial

Cada ID de token debe ser convertido en un vector denso y significativo. Este embedding inicial se construye sumando dos componentes vectoriales distintos, ambos con una dimensionalidad de 768 en el caso de GPT-2.

2.2.1. Embedding de Token

Cada ID de token se utiliza como un índice para consultar una gran tabla de embeddings pre-entrenada. Esta tabla asigna a cada token un vector fijo de 768 dimensiones que representa su significado semántico. Este vector fue aprendido durante la fase de entrenamiento del modelo y permanece inalterado durante la inferencia. Por ejemplo, el token para "Hola" siempre corresponderá al mismo vector de 768 valores.

2.2.2. Embedding de Posición

Para que el modelo comprenda el orden de las palabras, se genera un segundo vector de 768 dimensiones. Este vector se obtiene de una tabla de embeddings de posición separada. A diferencia del embedding de token, este vector no depende del contenido de la palabra, sino únicamente de su posición en la secuencia de entrada (por ejemplo, la primera palabra, la segunda, y así sucesivamente).

2.3. Embedding Combinado Inicial

Los dos vectores —el embedding de token y el embedding de posición— se suman elemento a elemento para crear el embedding inicial de cada token. La lógica subyacente es que tanto el significado de una palabra (qué es) como su ubicación en la frase (dónde está) son cruciales para determinar el contexto completo.

Este vector combinado, que integra información semántica y posicional, sirve como la entrada inicial para el proceso de contextualización que ocurre dentro de los bloques Transformer.

El resultado de esta operación es un tensor final con la siguiente forma:

Esto representa un lote (1), con 20 tokens, donde cada token es ahora un vector de 768 dimensiones. Un ejemplo del primer embedding de la secuencia podría verse así (mostrando solo los primeros 10 de 768 valores):

tensor([-0.2077, -0.1556, -0.1638, 0.0468, -0.0956, -0.3012,
        0.1546,  0.1558, -0.3139, -0.0316, ...])

Estos embeddings iniciales, que ya contienen información semántica y posicional, están ahora listos para ser procesados por el núcleo del modelo: los bloques Transformer.

3. Etapa 2: El Bloque Transformer y el Procesamiento Contextual

El bloque Transformer es la unidad de procesamiento fundamental y repetitiva del modelo. Su propósito es refinar iterativamente los embeddings de entrada. Dentro de cada bloque, cada token puede "mirar" a todos los demás tokens de la secuencia para reinterpretar y enriquecer su propia representación vectorial con información contextual completa.

Cada bloque se compone de dos subcapas principales: un mecanismo de auto-atención y una red de proyección feed-forward.

3.1. Subcapa 1: Mecanismo de Auto-Atención Multi-Cabeza

La auto-atención es el mecanismo que permite al modelo ponderar dinámicamente la importancia de las diferentes palabras en la secuencia de entrada al procesar una palabra específica. Este proceso permite que la información fluya entre los tokens, contextualizándolos.

3.1.1. Proyección a Query (Q), Key (K) y Value (V)

El embedding de entrada de cada token se proyecta en tres vectores distintos: Query, Key y Value. Esto se logra multiplicando el vector de embedding por tres matrices de pesos (W_Q, W_K, W_V) que fueron aprendidas durante el entrenamiento.

Elemento Descripción Origen
X Embedding inicial (token + posición) para cada token. Calculado en la etapa de preparación.
W_Q Matriz de pesos para generar el vector Query. Aprendida en entrenamiento (valor fijo).
W_K Matriz de pesos para generar el vector Key. Aprendida en entrenamiento (valor fijo).
W_V Matriz de pesos para generar el vector Value. Aprendida en entrenamiento (valor fijo).

Conceptualmente, estos vectores representan:

3.1.2. Cálculo de los Pesos de Atención

A continuación, el modelo calcula una puntuación de atención entre cada par de tokens usando sus vectores Query y Key. Esta puntuación determina cuánto "interés" debe prestar un token a otro. La fórmula es la siguiente:

attention_scores = softmax(Q · Kᵀ / √dₖ)

El resultado es una matriz de puntuaciones (de 20 × 20 en nuestro ejemplo), donde cada fila representa un token observador y cada columna representa el token al que se le presta atención. Es importante notar que el vector V (Value) no se utiliza en este cálculo; esta fase solo determina los pesos de la atención.

3.1.3. Creación del Embedding Contextualizado

Finalmente, la matriz de pesos de atención se aplica a los vectores de Valor (V). Para cada token, se calcula un nuevo embedding mediante una suma ponderada de los vectores V de todos los tokens de la secuencia, donde los pesos son las puntuaciones de atención calculadas.

nuevo_embedding[i] = Σ_j ( attention_scores[i, j] × V[j] )

Ejemplo ilustrativo: Consideremos la frase "Hoy martes llueve" y calculemos el nuevo embedding para el token "hoy".

  1. Vectores V simplificados (4 dimensiones):

    • V["hoy"] = [0.3, 0.2, 0.1, 0.5]
    • V["martes"] = [-0.4, 0.6, 0.3, -0.2]
    • V["llueve"] = [0.7, -0.1, 0.0, 0.2]
  2. Pesos de atención calculados para "hoy":

    • Atención a "hoy": 0.2
    • Atención a "martes": 0.7
    • Atención a "llueve": 0.1
  3. Cálculo del nuevo embedding contextualizado:

    • 0.2 × V["hoy"] = [ 0.06, 0.04, 0.02, 0.10]
    • 0.7 × V["martes"] = [-0.28, 0.42, 0.21, -0.14]
    • 0.1 × V["llueve"] = [ 0.07, -0.01, 0.00, 0.02]
    • Suma total (nuevo embedding de "hoy"): [-0.15, 0.45, 0.23, -0.02]

El vector resultante para "hoy" es una nueva representación sintetizada. Si bien el alto peso de atención (0.7) hace que el vector de "martes" sea el contribuyente dominante, el embedding final es una mezcla compuesta, sutilmente influenciada por todos los tokens en proporción a su relevancia calculada. Este es el fundamento matemático de la comprensión contextual en los Transformers.

3.2. Subcapa 1: Conexión Residual y Normalización de Capa

Después del mecanismo de atención, se aplican dos operaciones cruciales para la estabilidad numérica y la eficacia del modelo.

3.2.1. Conexión Residual (Add)

El embedding original (X) se suma elemento a elemento al nuevo embedding contextualizado (Embedding_Score) generado por la atención:

Embedding_Residual = X + Embedding_Score

Esta operación, conocida como conexión residual o skip connection, es estratégicamente vital. Asegura que la información original del token no se pierda durante la transformación, preservando su significado base mientras se le añade el nuevo contexto.

3.2.2. Normalización de Capa (LayerNorm)

El vector resultante de la suma residual se normaliza. La normalización de capa (LayerNorm) reescala las activaciones para que tengan una media cercana a 0 y una varianza cercana a 1.

Fórmula general:

LayerNorm(x) = (x - media) / sqrt(varianza + ε)

Ejemplo de cálculo para un vector x = [2.0, 0.5, 1.5, 3.0]:

  1. Media: (2.0 + 0.5 + 1.5 + 3.0) / 4 = 1.75
  2. Varianza: ((2.0-1.75)² + (0.5-1.75)² + (1.5-1.75)² + (3.0-1.75)²) / 4 = 0.8125
  3. Denominador: sqrt(0.8125 + 1e-5) ≈ 0.90139
  4. Vector normalizado: ≈ [ 0.277, -1.386, -0.277, 1.386 ]

Esta operación estabiliza el flujo de datos a través de la red, evitando que los valores de las activaciones crezcan o disminuyan descontroladamente en capas sucesivas.

3.3. Subcapa 2: Red de Proyección Feed-Forward (FFN)

La segunda subcapa principal del bloque Transformer es una red feed-forward (FFN). A diferencia del mecanismo de atención, que procesa las relaciones entre tokens, la FFN procesa cada embedding de token de forma aislada a través de una transformación no lineal.

3.3.1. Transformación No Lineal

La expansión hacia un espacio de mayor dimensionalidad puede entenderse como la creación de un "espacio de trabajo computacional". En este espacio expandido, el modelo tiene más libertad expresiva para desenredar y aislar características complejas y abstractas del vector de entrada, características que podrían no ser linealmente separables en la dimensión original.

La activación ReLU actúa entonces como un filtro, preservando solo las características más destacadas antes de que la capa de contracción proyecte esta representación refinada de nuevo al espacio original de 768 dimensiones. Este proceso se ejecuta en tres pasos:

  1. Expansión: El vector de entrada se proyecta a una dimensión mayor mediante una transformación lineal:
    h1 = x_norm · W1 + b1
    Ejemplo: [ 0.277, -1.386, ...] (4D) → [ -0.2881, -0.7484, ...] (6D)
  2. Función de activación ReLU: Se aplica la función:
    ReLU(x) = max(0, x)
    que reemplaza todos los valores negativos por cero. Esto introduce no linealidad en el modelo, una propiedad esencial para aprender funciones complejas.
    Ejemplo: [ -0.2881, -0.7484, 1.4197, -0.3218, 0.5491, -0.9423 ] → [ 0, 0, 1.4197, 0, 0.5491, 0 ]
  3. Contracción: El vector resultante se proyecta de nuevo a la dimensión original mediante una segunda transformación lineal:
    output_ffn = h1_relu · W2 + b2
    Ejemplo: [ 0, 0, 1.4197, ...] (6D) → [ 1.01164, 0.2867, ...] (4D)

3.4. Subcapa 2: Conexión Residual y Normalización Final

De manera análoga a la subcapa de atención, la salida de la FFN también pasa por una conexión residual y una capa de normalización final. Este proceso consolida la transformación del embedding dentro de un bloque Transformer completo.

A continuación se resume la evolución del vector a través de estas etapas (ejemplo en 4D):

  1. Entrada a FFN (Salida de LayerNorm 1):
    [ 0.277, -1.386, -0.277, 1.386 ]
    Este es el vector contextualizado por la atención y normalizado.
  2. Salida de FFN:
    [ 1.01164, 0.2867, -0.361, 0.50358 ]
    El vector ha sido ajustado por la transformación no lineal, que amplifica o reformula señales semánticas relevantes.
  3. Suma Residual:
    [ 1.28864, -1.0993, -0.638, 1.88958 ]
    Se suma la entrada a la FFN con la salida de la FFN, preservando la información original y evitando que la FFN modifique drásticamente el significado.
  4. LayerNorm Final:
    [ 0.894, -1.41, -0.97, 1.48 ]
    El vector se estabiliza de nuevo, dejándolo listo para ser la entrada del siguiente bloque Transformer.

Este bloque completo se apila múltiples veces. Cada capa refina progresivamente la comprensión del modelo sobre las complejas interacciones semánticas y sintácticas de la secuencia.

4. Etapa 3: Procesamiento Iterativo y Generación de la Salida Final

La arquitectura de GPT-2 consiste en apilar múltiples bloques Transformer, uno tras otro. Esta arquitectura apilada es análoga a una pipeline de procesamiento de señales multietapa con bucles de retroalimentación, donde la salida de cada bloque —una señal parcialmente refinada— se alimenta a la siguiente para una mayor corrección y estabilización, permitiendo el desarrollo progresivo de características semánticas complejas.

Este procesamiento iterativo permite un refinamiento profundo de la representación semántica de cada token, pasando de correlaciones simples a inferencias de alto nivel. Un modelo como GPT puede tener hasta 96 de estas capas. (verificar)

4.1. Evolución Semántica a Través de las Capas

Para ilustrar cómo evoluciona la "comprensión" del modelo a través de las capas, consideremos la frase:

Hoy martes llueve, asi que...

4.2. Generación del Siguiente Token

La función de la última capa de Transformer es diferente. Una vez que los embeddings han sido completamente refinados, el embedding final del último token de la secuencia de entrada se proyecta hacia el vocabulario completo del modelo. Esta proyección genera una distribución de probabilidad sobre todos los tokens posibles, indicando cuál es el más probable para continuar la secuencia.

Para la frase: "Hoy martes llueve, asi que...", el modelo podría generar las siguientes probabilidades:

Token Probabilidad
paraguas 0.64
llevar 0.18
sacar 0.05
abrigo 0.03
coche 0.01

El modelo selecciona el token con la probabilidad más alta, en este caso "paraguas", como la continuación más lógica y lo genera como salida.

5. Conclusión: La Naturaleza Computacional del “Entendimiento”

El proceso de inferencia de GPT-2 es una secuencia orquestada de transformaciones matemáticas: desde la tokenización inicial del texto, la creación de embeddings que capturan significado y posición, el procesamiento iterativo a través de múltiples bloques de Transformer —donde los mecanismos de atención y las redes feed-forward refinan el contexto—, hasta la proyección final que genera una distribución de probabilidad para el siguiente token.

Es crucial reflexionar sobre la naturaleza de este "entendimiento". El proceso descrito es puramente computacional. El modelo de IA no "piensa" ni posee una lógica humana abstracta. Su habilidad para generar texto coherente y contextualizado se deriva de la asociación de patrones numéricos, específicamente la similitud entre embeddings, que ha aprendido a partir de una cantidad masiva de datos durante el entrenamiento.

La relación entre "lluvia" y "paraguas" no es un concepto lógico para el modelo, sino una fuerte correlación matemática entre sus vectores. Por lo tanto, el resultado de la inferencia es siempre una predicción probabilística, no una verdad absoluta, y requiere un análisis crítico por parte del usuario.

Para el arquitecto de software, esta distinción es primordial: el sistema que se está integrando no es un motor de razonamiento, sino un sofisticado aparato de coincidencia de patrones de alta dimensionalidad. Sus resultados deben ser tratados como hipótesis probabilísticas, no como verdades definitivas, y la responsabilidad de la validación crítica recae enteramente en el sistema de implementación y sus operadores humanos.