English · Español
Lab 01 — Codificación posicional sinusoidal (sinusoidal positional encoding)¶
Objetivo: implementar PE sinusoidal; visualizarla como heatmap; plotear la propiedad de decaimiento-del-producto-escalar-con-distancia.
Tiempo estimado: 45–60 minutos.
Prerrequisito: lab 00 commiteado;
theory/01-sinusoidal.mdleído.
Lo que produces¶
Un directorio experiments/16-sinusoidal/ que contiene:
sinusoidal.py— tu implementación, ensrc/minimodel/positional/sinusoidal.py.visualize.py— script que construye PE y la plotea.pe_heatmap.png— heatmap de la matriz de PE.dot_product_decay.png— \(\text{PE}(0) \cdot \text{PE}(p)\) vs \(p\).manifest.json.README.md.
TODOs¶
Bloque A — implementación¶
- En
src/minimodel/positional/sinusoidal.py, implementasinusoidal_pe(T: int, d: int) -> np.ndarraysegún la especificación ensrc/minimodel/positional/BLUEPRINT.md. - Seis líneas de cuerpo. Vectorizado sobre T y d/2.
- Asegura
d % 2 == 0.
Bloque B — heatmap¶
- Construye
pe = sinusoidal_pe(T=64, d=32). - Plotea como heatmap: filas = posiciones, columnas = dimensiones, color = valor de PE.
- Usa
cmap='RdBu_r', rango[-1, 1]. - Anota las columnas de alta frecuencia (izquierda) y las de baja frecuencia (derecha).
- Guarda como
pe_heatmap.png.
Esperado: las columnas de la izquierda oscilan rápido (rayas visibles dentro del rango visible); las de la derecha son casi constantes sobre las 64 posiciones.
Bloque C — decaimiento del producto escalar¶
- Construye
pe = sinusoidal_pe(T=128, d=32). - Calcula
decay[p] = pe[0] @ pe[p]para \(p = 0, 1, \ldots, 127\). - Plotea
decayvs \(p\), escalas lineales. - Anota el pico en \(p = 0\) (valor = \(d/2\), más o menos), y el decaimiento oscilante.
- Guarda como
dot_product_decay.png.
Esperado: un pico alto en \(p = 0\), decaimiento oscilante hasta cerca de cero por \(p = 100\). La forma ilustra la propiedad de "posiciones cercanas se ven similares, posiciones lejanas se ven no relacionadas".
Bloque D — verifica la propiedad de cambio lineal¶
El archivo de teoría demuestra que \(\text{PE}(p + \Delta)\) es una rotación fija de \(\text{PE}(p)\). Verifícalo numéricamente:
- Construye
pe = sinusoidal_pe(T=10, d=8). - Para cada par (k = 0, 1, 2, 3) de dimensiones \((2k, 2k+1)\), calcula la matriz de rotación de PE(0) a PE(1) — llámala \(R_k\).
- Verifica que la misma \(R_k\) lleva PE(1) → PE(2), PE(2) → PE(3), etc., para todas las posiciones.
- Asegura que la diferencia máxima < 1e-5.
Bloque E — redacción¶
En README.md:
- Describe el heatmap. ¿Qué patrón ves en las columnas de alta vs baja frecuencia?
- Describe el decaimiento del producto escalar. ¿Dónde cruza el cero? ¿Dónde se estabiliza?
- Confirma la propiedad de cambio lineal. Indica la diferencia máxima del Bloque D.
Bloque F — manifest¶
{
"experiment": "16-sinusoidal",
"date": "YYYY-MM-DD",
"seed": 0,
"versions": { "python": "3.11.x", "numpy": "X.Y.Z", "matplotlib": "X.Y.Z" },
"config": {
"T_heatmap": 64,
"d_heatmap": 32,
"T_decay": 128,
"d_decay": 32
},
"results_summary": {
"linear_shift_max_diff": null,
"decay_zero_crossing_at_p": null
}
}
Restricciones¶
- Sin PyTorch.
- Vectorizado. Sin bucle
for p in range(T)en el generador de PE.
Condiciones de parada¶
Hecho cuando:
- Los seis archivos commiteados.
- La aserción de cambio lineal pasa.
- Ambos plots guardados.
README.mdcontesta a las tres preguntas del Bloque E.
Escollos¶
- Fórmula de frecuencia.
omega_k = 1 / 10000**(2*k/d)— nota que el exponente depende de \(d\) (la dimensión total del modelo), no de \(d_\text{head}\). Fácil de equivocar. - Entrelazado sin/cos.
pe[:, 0::2] = sin(...),pe[:, 1::2] = cos(...). Algunas implementaciones separanpe[:, :d/2] = sin, pe[:, d/2:] = cos— equivalente salvo una permutación de dimensiones, pero tienes que ser consistente con cómo el modelo lo consume. - Forma de
omega_k.(d/2,), broadcast con posiciones(T, 1)para obtener ángulos(T, d/2).
Cuándo consultar solutions/¶
Tras commitear los seis archivos y que la aserción de cambio lineal pase. Solución en solutions/01-sinusoidal-ref.md.
Siguiente lab: 02-rope-implementation.md.