179062a5d4
Primera tool del agente. No depende del modelo, así que se puede usar y
verificar de punta a punta antes de que exista el modelo propio.
Sobre el endpoint: la API oficial de DuckDuckGo ("Instant Answer") no sirve
para esto — responde definiciones y fichas de entidades, y para una consulta
normal devuelve 200 con el cuerpo vacío. Los resultados web reales solo están
en el endpoint lite, que no es una API con contrato: el HTML puede cambiar y
hay límite de tasa. Por eso el backend está detrás de una interfaz y queda
implementado también SearxNG autoalojado, que es un cambio de una línea de
config cuando haga falta.
Decisiones:
- Presupuesto de contexto explícito: con seq_len 2048 los resultados compiten
con la memoria recuperada y el turno del usuario, así que se devuelven cinco
recortados en vez de diez completos.
- Las redirecciones /l/?uddg= se desenvuelven al destino real: guardarlas
ensuciaría la memoria episódica, donde dos búsquedas a la misma página
parecerían páginas distintas.
- Caché con TTL, que es de comportamiento y no de rendimiento: en una casa las
mismas preguntas se repiten muchas veces por día.
- Sin resultados devuelve "Sin resultados." en vez de vacío, para que el modelo
pueda decir que no encontró nada en lugar de inventar.
Se quitan Brave y Tavily de .env.example: ya no hay credenciales que gestionar
ni un tercero al que informarle qué busca la familia.
23 tests nuevos (71 en total), contra una respuesta real guardada como fixture:
el parser es lo que se rompe cuando cambia el markup, y tiene que fallar en la
suite y no en producción. Ningún test sale a internet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
103 lines
3.6 KiB
Markdown
103 lines
3.6 KiB
Markdown
# ENLACE
|
||
|
||
Modelo de lenguaje propio, entrenado desde cero, para asistencia general y
|
||
familiar en español. No es fine-tuning de un modelo existente: tokenizer, datos
|
||
y pesos son propios.
|
||
|
||
El plan completo — etapas, presupuestos de cómputo, arquitectura de datos y
|
||
criterios de verificación — está en `docs/PLAN.md`.
|
||
|
||
## Estado
|
||
|
||
Etapa 0 (entorno y validación del stack) implementada y verificada:
|
||
|
||
- Capa de configuración validada, con composición por capas y perfiles de hardware.
|
||
- Arquitectura del modelo: RMSNorm, SwiGLU, RoPE, GQA, QK-norm, z-loss.
|
||
- Entrenador con WSD, precisión mixta, acumulación de gradiente y **reanudación exacta**.
|
||
- Cargadores de datos: bytes (smoke test) y shards `uint16` (corpus real).
|
||
|
||
Primera tool del agente (Etapa 4), que no depende del modelo y ya funciona:
|
||
|
||
- Búsqueda web con DuckDuckGo, **sin API key ni cuenta en ningún servicio**.
|
||
|
||
```bash
|
||
.venv/bin/python -m enlace.agent.tools.search "que es home assistant"
|
||
```
|
||
|
||
71 tests, incluido el de reanudación exacta.
|
||
|
||
Pendiente: Etapa 1 en adelante (corpus, tokenizer, pretraining, post-training,
|
||
agente, bases del sistema, memoria, snapshots).
|
||
|
||
## Puesta en marcha
|
||
|
||
```bash
|
||
python3 -m venv .venv
|
||
.venv/bin/pip install -e ".[dev]"
|
||
|
||
scripts/prepare_smoke_data.sh # texto en español de dominio público
|
||
.venv/bin/python -m enlace.train.train configs/runs/smoke-cpu.yaml
|
||
scripts/test.sh
|
||
```
|
||
|
||
En el servidor con GPU, por SSH (ver `.env.example`):
|
||
|
||
```bash
|
||
scripts/remote.sh sync
|
||
scripts/remote.sh run configs/runs/smoke-2060.yaml # smoke test, ~10 min
|
||
scripts/remote.sh run configs/runs/pretrain-2060.yaml # pretraining, 1-2 días
|
||
scripts/remote.sh logs
|
||
```
|
||
|
||
Toda corrida larga arranca bajo `tmux`: cortar el SSH no mata el entrenamiento.
|
||
|
||
## Configuración
|
||
|
||
Ningún hiperparámetro vive en el código. Las configs se componen por capas:
|
||
|
||
```yaml
|
||
# configs/runs/pretrain-2060.yaml
|
||
include:
|
||
hardware: hardware/turing-2060.yaml # dtype, backend de atención, batch
|
||
model: model/tiny-50m.yaml # capas, dimensiones, contexto
|
||
train: train/pretrain.yaml # LR, schedule, intervalos
|
||
data: data/corpus.yaml # de dónde salen los tokens
|
||
```
|
||
|
||
Overrides puntuales desde la línea de comandos, para probar variantes sin editar
|
||
archivos:
|
||
|
||
```bash
|
||
.venv/bin/python -m enlace.train.train configs/runs/smoke-cpu.yaml train.seed=99
|
||
```
|
||
|
||
Una config inválida falla al arrancar con un mensaje concreto, no a las tres
|
||
horas de entrenamiento.
|
||
|
||
## Hardware
|
||
|
||
El perfil de hardware es la única capa que cambia al migrar de placa.
|
||
|
||
| Perfil | Placa | dtype | Atención | Notas |
|
||
|---|---|---|---|---|
|
||
| `turing-2060` | RTX 2060 12 GB (sm_75) | float16 + GradScaler | mem_efficient | Turing no soporta bfloat16 ni FlashAttention-2 |
|
||
| `blackwell-5090` | RTX 5090 32 GB (sm_120) | bfloat16 | flash | Requiere PyTorch ≥ 2.7 con CUDA 12.8 |
|
||
| `cpu` | — | float32 | math | Solo desarrollo y tests |
|
||
|
||
`enlace/train/backends.py` es el único archivo del entrenamiento que conoce
|
||
diferencias entre placas, y valida el perfil contra la GPU real antes de
|
||
empezar: pedir bfloat16 en Turing falla de inmediato en vez de degradarse en
|
||
silencio.
|
||
|
||
## Estructura
|
||
|
||
```
|
||
enlace/config/ Esquemas pydantic y composición de YAML
|
||
enlace/model/ Transformer decoder-only y selección de backend de atención
|
||
enlace/train/ Bucle, schedules, checkpointing, detección de hardware
|
||
enlace/data/ Cargadores con reanudación exacta
|
||
configs/ hardware × model × train × data, compuestos en configs/runs/
|
||
scripts/ Utilidades: remote.sh, test.sh, prepare_smoke_data.sh
|
||
tests/ Suite completa; test_resume.py es el crítico
|
||
```
|