Plan — Mover la extracción de exports al Linode (junto a nef-silo / surtido)

ANULADO (2026-09-22): el Linode [IP] está caído permanentemente. Ver 2026-09-22-linode-caido-permanentemente.md. Sustituido por 2026-09-22-plan-extraccion-hf-pro.md. Este documento se conserva solo como registro de lo medido.

Fecha: 2026-09-22. Estado: planning, sin configurar (esperar instrucciones). Origen: second-brain-twitter (extracción con Ollama de chats privados → nodos).

Objetivo

Correr scripts/extract_exports.py (111 chunks de claude-conv + pendientes) en el Linode [IP], en lugar de la GPU local del System76, sin romper la radio ni el cron de nef-silo.

Restricción dura medida (2026-09-22, sondeo read-only)

RecursoLinodeImplicación
CPU2 vCPU AMD EPYC 7713~5 tok/s para un 3B en CPU (vs 18 tok/s en la GPU local)
RAM3.8 GB (2.8 libre) + 496 MB swapqwen3.5:9b (6.6 GB) NO cabe
GPUninguna (VGA virtual 1234:1111)inferencia 100% CPU
Disco79 GB (11 usados)sobra para modelo + chunks
Ollamaya instalado; qwen2.5:3b + triage (1.9 GB c/u)punto de partida listo
Servicios vivosnginx, icecast2:8000 + liquidsoap (radio), freshrss, rsshub-silo, nef-silo cron */30contención de CPU = riesgo de dropouts de audio

Ventana libre de radio: cron apaga liquidsoap a las 05:00 y lo reinicia a las 13:00 → 8 h sin audio en vivo. Esa es la ventana natural para carga pesada.

Decisión de arquitectura (a confirmar)

El Linode no puede reproducir la corrida actual (9B, GPU). Tres caminos:

  • A. Modelo chico en el Linode (recomendado si “todo remoto” es literal). Usar qwen2.5:3b (ya está) con num_ctx bajo. Autocontenido y privado. Costo: ~10-17 min/chunk → 111 chunks ≈ 20-30 h. Riesgo de calidad < 9B.
  • B. Linode solo como orquestador (cola + cron + resume) y la inferencia en otra GPU o API. Rápido, pero rompe “todo en remoto” (necesita segundo host) o expone chats privados a un tercero (el sanitize.py corre al final, no antes).
  • C. Seguir en la GPU del System76. Contradice la instrucción.

Recomendación: A, con la ventana 05:00-13:00 y nice + límite de CPU para que nef-silo y (si acaso) liquidsoap no mueran. Decidir antes de Fase 2.

Diseño de colocación

  • Nuevo directorio /opt/extract (patrón de nef-silo/deploy.sh: rsync + venv).
  • Reutilizar scripts/extract_exports.py; parametrizar por env (hoy hardcodea localhost:11434 y qwen3.5:9b):
    • OLLAMA_HOST → http://[IP]:11434
    • MODEL → qwen2.5:3b
    • NUM_CTX → 8192 (RAM) y num_predict acotado
    • OLLAMA_KEEP_ALIVE y OLLAMA_NUM_PARALLEL=1 (-np 1)
  • Cola con flock (igual que /opt/silo/run.sh) + cron en la ventana de radio.
  • Privacidad: los chunks de claude-conv son chats privados. Generarlos local, rsync por ssh, correr, traer los reports y shred de los chunks en el Linode. Nunca dejar el export crudo en claro más allá de la corrida.
  • nice -n 19 + systemd-run --scope -p CPUQuota=150% para acotar a ~1.5 núcleos.

Fases (cada una termina en artefacto verificable)

  1. Baseline de rendimiento: correr 1 chunk con qwen2.5:3b en el Linode y medir tok/s + tiempo real. Verificar que icecast2/liquidsoap y el log de silo.log siguen sanos durante la prueba. → número de tok/s medido.
  2. Parametrizar el runner (OLLAMA_HOST/MODEL/NUM_CTX). → DRY=1 local OK.
  3. Desplegar esqueleto /opt/extract (rsync + venv), sin cron todavía. → python extract_exports.py --dry en el Linode lista los 111 chunks.
  4. 3 chunks de prueba (chatgpt 070 + 072, y 1 de claude) y comparar estilo contra los 001-069 hechos con 9B. → diff de calidad aceptable o no.
  5. Corrida completa de claude-conv (111) en la ventana 05:00-13:00 con CPU cap. → 111 extraccion-claude-conv-*.md nuevos.
  6. Traer y limpiar: rsync de reports a local, shred de chunks en Linode, correr sanitize.py reports/extraccion-*.md.
  7. Puente a second-brain: bloques “3.2 Nodos candidatos” → _enrich/<slug>.md.

Riesgos / lista de NO

  • NO intentar el 9B en el Linode (no cabe en RAM).
  • NO correr la extracción en la franja con liquidsoap activo sin CPUQuota.
  • NO dejar exports crudos sin cifrar en el Linode más allá de la corrida.
  • NO mandar datos sin sanitizar a una API de terceros (opción B/API).
  • NO duplicar el cron de nef-silo (ya usa */30; la extracción va con flock propio).

Pendientes que este plan arrastra

  • extraccion-chatgpt-conv-070.md se borró por error al apagar la cola (070 había salido bien; 071 existe y es válido). Regenerar 070 en la Fase 3.
  • Faltan chatgpt 070, 072 (y confirmar 071/072), claude-conv (111), dc-big.pretty, memories, y el sanitize.py final.
  • Opcional “con surtido”: prensa_noche.py corre en Atlantic (local) y falló por DNS el 17-18 sep (ver 2026-09-22-surtido-reportes-viejos-fix.md). Moverlo al Linode resolvería esa fragilidad; fuera de alcance de este plan.