El token "k" es el número 10. Pero la red no puede trabajar con un solo número — necesita un vector con 16 dimensiones que capture qué tiene en común "k" con otras letras.
Imagina un estadio de fútbol. Cada asiento tiene un número: del 1 al 50.000. Pero el número del asiento no dice nada sobre ese asiento: ¿tiene buena vista? ¿Está lejos de la cancha? ¿Está cubierto? ¿Cuesta caro?
Un "embedding del asiento" sería un vector de características: [vista=8.5, distancia=3.2, cubierto=1.0, precio=6.7, ...]. Eso sí captura las propiedades reales del asiento.
En microgpt, wte (weight table of tokens) es una matriz de 27 filas × 16 columnas. Cada fila es el embedding de un token: 16 números que representan ese carácter.
Cada fila es un token (a-z más [BOS]). Cada columna es una dimensión del embedding. Los colores representan el valor: cyan brillante = positivo alto, oscuro = negativo. Inicialmente aleatorio; el entrenamiento ajusta estos valores.
Tenemos el token 'k' (índice 10). Para obtener su embedding, solo indexamos la fila 10 de wte: wte[10] = [0.23, -0.15, 0.87, -0.42, 0.11, 0.65, -0.33, 0.72, -0.08, 0.45, 0.19, -0.61, 0.38, 0.04, -0.27, 0.83] 16 números. Eso es el embedding de 'k'. Para 'a' (índice 0): wte[0] = [0.44, -0.22, 0.13, ...] Para 'r' (índice 17): wte[17] = [-0.31, 0.67, 0.22, ...] Antes del entrenamiento: números aleatorios de distribución gaussiana Después del entrenamiento: números que capturan similitudes entre tokens (letras que aparecen en contextos similares tendrán embeddings parecidos)
Además del embedding del token, necesitamos saber la posición: ¿es el primer carácter del nombre, el segundo, el décimo? El significado de un carácter puede depender de dónde está.
wpe (weight table of positions) es una matriz de 16 filas × 16 columnas: una fila por cada posición posible en la secuencia (block_size=16). La posición 0 tiene su propio vector de 16 números, la posición 1 tiene otro, etc.
Procesamos el token 'k' (índice 10) en posición 0: embedding_token = wte[10] = [0.23, -0.15, 0.87, ...] ← 16 nums embedding_posicion = wpe[0] = [0.11, 0.34, -0.22, ...] ← 16 nums entrada = embedding_token + embedding_posicion = [0.23+0.11, -0.15+0.34, 0.87-0.22, ...] = [0.34, 0.19, 0.65, ...] ← 16 nums Ahora procesamos 'a' (índice 0) en posición 1: embedding_token = wte[0] = [0.44, -0.22, 0.13, ...] embedding_posicion = wpe[1] = [-0.08, 0.15, 0.41, ...] entrada = [0.36, -0.07, 0.54, ...] Este vector de 16 números es lo que entra a la primera capa de atención. El modelo puede distinguir 'k' en posición 0 de 'k' en posición 3 porque tienen embeddings de posición distintos.
Selecciona un token y una posición para ver su embedding simulado.
wte es la tabla de embeddings de tokens: 27 filas × 16 columnas. Buscar el embedding de un token es simplemente indexar la fila correspondiente.wpe es la tabla de embeddings de posición: 16 filas × 16 columnas. Una fila por posición en la secuencia.wte[token] + wpe[posición] — un vector de 16 números.