second-brain-twitter: observar el funcionamiento de los transformers

Fecha: 2026-09-09 · Rama: experiment/attention-is-all-you-need

Nota rectora

El objetivo NO es producir algo útil con la base de datos, sino entender cómo funcionan los transformers. La idea de “dotar de ideas a un personaje que tuitea con base en los likes” y el “teclado predictivo” son posibles aplicaciones, pero se descartan como fin: son distractores del propósito didáctico.

Decisiones

  1. Entrenar un mini-Transformer a mano (numpy, backprop propio) únicamente para que los pesos dejen de ser aleatorios y la atención sea interesante de observar. El entrenamiento es un medio, no el producto.
  2. Corpus: likes (~124k usables). Volumen adecuado para estadística de lenguaje real. No se usan los tweets (ni el “año”) porque la tarea ya no es por año.
  3. Tokenización word-level, vocab top-10k + <unk>/<bos>/<eos>/<pad>, truncado ~40 tokens.
  4. Dedup por documento ANTES de partir train/test — fuga en este corpus (muchos cortes/truncamientos parecidos) daría análisis falso.
  5. Split por documento, 80/10/10 train/val/test, seed fija (7). Nunca partir por token. Checks: disyunción train∩test y casi-duplicados.
  6. NO hay teclado predictivo jugable ni personaje. La interfaz es un visor didáctico (HTML local) para observar:
    • mapas de atención por capa y por head,
    • comparación multi-head (¿cada head aprende un patrón distinto?),
    • distribución de softmax / perplejidad por token,
    • análisis de gradientes por capa/head,
    • probing/intervención (opcional, el más profundo).
  7. El informe del paso 0 (pesos aleatorios) sirve como “antes de aprender”; este nuevo análisis es el “después”. El contraste es la mejor lección.

Nota honesta

Con un modelo diminuto entrenado a mano, los mapas de atención aprendidos serán más interpretables que el paso 0 aleatorio, pero no necesariamente “lingüísticamente profundos” (eso exige escala). El valor está en ver emerger estructura (heads distintos, perplejidad no-uniforme) y poder razonar sobre ella paso a paso.

Entregables previstos

  • scripts/train_attention.py — dataset + split + entrenamiento + checkpoints.
  • scripts/analyze_attention.py — mapas por head, perplejidad token, gradientes, probing.
  • scripts/attention_viewer.py — servidor local HTML (visor didáctico).
  • tests/ — forward/backward + gradient check, disyunción split, dedup, pérdida decrece.
  • README.md + reports/attention-analysis.md.

D1 Import (commits f0638f3, 7fe2e4d)

Import completo — D1 populated with all real Twitter data.

  • Database: second-brain-search (ID: 1617523a-ce4e-4782-be20-67d1a6d9c298)
  • Tables: tweets (5,911 rows), likes (130,626 distinct rows)
  • FTS5 virtual tables: tweets_fts (5,911), likes_fts (130,626)
  • Schema: worker/schema_fts.sql — FTS5 indexes for full-text search
  • Import mechanism: worker/import_d1.sh executes SQL batches via wrangler d1 execute
  • Two waves to respect free-tier 100k writes/day limit (reset at 00:00 UTC)
  • Wave 1: schema + tweets + likes 0000-0187
  • Wave 2: likes 0188-0261

Progreso (commits c0f7df9 → f0638f3)

Backprop verificado correcto. Se corrigieron dos bugs y se hizo el gradient check.

  • Bug 1 (raíz): _layer_backward pasaba los valores ya normalizados (ln_x) como entrada a _ln_backward, pero esta necesita el input original. Cambiado a h_res1/h_res2. Con esto el gradiente dejó de colapsar a cero en wq/wk.
  • Bug 2: _ln_backward reescrito con la fórmula estándar (factor 1/d en el término de varianza), verificado por diferencias finitas aislado (rel ≈ 3e-10).
  • Métrica del gradient-check: ahora relativo robusto (normalizar por norma total del gradiente de diferencia finita; omitir params con gradiente real ~0, ej. wq/wk en init aleatorio, donde |g-f| es ruido de cancelación ~1e-10).
  • Estado: 9/9 pruebas pasan (python3 -m unittest discover -s tests -v).
  • Diagnóstico clave aprendido: los gradientes de wq/wk en un modelo recién inicializado son genuinamente diminutos (~1e-10), no un bug; la señal real está en wv/wo/ffn/emb (~1e-3..1e-1).

Siguiente

  1. scripts/train_attention.py — corpus likes (130,626 filas en D1), dedup, tokeniz top-10k, split 80/10/10 seed 7, entrenamiento con TinyTransformer verificado, checkpoints.
  2. scripts/analyze_attention.py — mapas por head, perplejidad token, gradientes, probing.
  3. scripts/attention_viewer.py — visor HTML local para observar atención.
  4. Tests para split/dedup; actualizar README.md + reports/attention-analysis.md; commit.