CreaRack-SL

Plataforma IA self-hosted · roadmap futuro (gestión multi-modelo en pve-epyc-02)

Plataforma IA self-hosted · roadmap futuro

Estado: planificación documentada, NO implementación. Bloqueado por dos pre-requisitos no negociables (sección 2). Diseñado el 01-05-2026 (sesión 45).


1. Visión general

Hoy pve-epyc-02 corre llama-server con un modelo único (Gemma 4 26B-A4B Q4_K_M) sirviendo Auto-Plan en CreaRack PROD vía OpenAI-compat. La plataforma futura amplía esto a:

  • Múltiples modelos coexistiendo en disco (Gemma 4 variantes, Qwen 3.6, otros) con switch operativo entre ellos.
  • UI de gestión estilo ChatGPT con conversaciones persistentes, multi-usuario, RAG, y selector de modelo.
  • API keys propias para que otros proyectos (no solo CreaRack PROD) puedan consumir el llama vía endpoint controlado, con auth y rate limiting.
  • Dependencia cero de APIs comerciales (Gemini, OpenRouter, Anthropic) en el día a día CreaRack — todo sirviendo desde nuestro hardware.

Es la culminación natural del trabajo iniciado en sesión 41 (cuando se valoró self-host como respuesta a OpenRouter limitando calidad de visión Auto-Plan).


2. Pre-requisitos NO negociables

Esta plataforma NO se implementa hasta que ambos hitos estén cubiertos:

Pre-req 1 · Auto-Plan al 100 % con Gemma 4 self-hosted

Hoy estamos en ~70 % calidad / ~91 % recall plano 70 racks. Falta el último tramo. Vías exploradas pero no exhaustadas:

  • Probar Q6_K (21 GB) y Q8_0 (25 GB) del 26B-A4B en lugar de Q4_K_M (16 GB). Cabe en LXC 100 sin problema. Esperado: 70→80 %.
  • mmproj-F32 en lugar de F16 para vision encoder más preciso.
  • Pivotar a otro modelo: Gemma 4 31B denso, Qwen3.6-27B, Qwen3.6-35B-A3B, MiniCPM-V 2.6, InternVL.
  • Ajustes de prompting / sampling específicos para visión densa.

Sin Auto-Plan al 100 % en self-host, expandir a otros sites IA es prematuro.

Pre-req 2 · Resto de sites IA CreaRack migrados a self-host

Sites IA actuales en CreaRack-Pro (Regla 8 CLAUDE.md, 8 sites + 3 workspace):

  • blueprints/services/autoplan.py (visión, Gemma 4 OpenRouter — futuro pve-epyc-02)
  • monitoring/services/ai_providers/openrouter.py (CNS Insight)
  • monitoring/services/tutor_service.py (síntesis tutor async)
  • network/services/mib_assistant.py (JSON crítico SNMP)
  • core/services/ai_operations.py (ops generales)
  • core/services/ai_providers/router.py (router default)
  • core/management/commands/finops_report.py (informe finops)
  • core/management/commands/perf_review.py (review performance)
  • Workspace: archivo-core.ts (Help Widget bib_ask), translate.ts (traducción ES→EN), translate-wiki.mjs (batch pre-build)

Todos apuntan hoy a google/gemma-4-26b-a4b-it vía OpenRouter (Cloudflare/Parasail upstream). Para migrar a self-host:

  • Cada site cambia provider de OpenRouter a OLLAMA_BASE_URL interno (ya tenemos el adapter Python — driver “ollama” apuntando a nuestro :8080).
  • Validar latencia + calidad en cada uno (algunos son crons largos = OK lentos; otros son UX = necesitan rapidez).
  • Algunos sites son síncronos en request HTTP (Help Widget, tutor en chat) — comprobar que latencia self-host es aceptable.

Una vez TODOS los sites usan pve-epyc-02 + el server soporta el caudal sin saturarse, la plataforma de gestión tiene sentido.


3. Arquitectura objetivo (alto nivel)

┌────────────────────────────────────────────────────────────────────┐
│ HOST: pve-epyc-02 (Proxmox VE 9.1)                                  │
│ EPYC 7502P · 256 GB DDR4-2933 · 4× NVMe                             │
├────────────────────────────────────────────────────────────────────┤
│                                                                    │
│ LXC 100 · crearack-llama-epyc-02 (PROD - actual)                   │
│ ├─ llama-server :8080 (modelo PROD fijo, gemma 26B Q?_K_M)         │
│ ├─ Auto-Plan + CNS + Help + tutor + MIB + ops apuntan AQUÍ         │
│ └─ NUNCA se interrumpe                                              │
│                                                                    │
│ LXC 102 · crearack-llama-playground (NUEVO)                         │
│ ├─ llama-server :8081 (modelo intercambiable)                      │
│ ├─ Switch modelo via UI o CLI sin afectar PROD                     │
│ └─ Multi-instancia opcional :8082, :8083 para tener varios warm    │
│                                                                    │
│ LXC 101 · crearack-openwebui (NUEVO)                                │
│ ├─ Docker container Open WebUI :3000                               │
│ ├─ Auth multi-usuario, BD conversaciones persistente               │
│ ├─ API keys nativas + RAG sobre documentos                         │
│ ├─ Endpoint OpenAI-compat agregando ambos LXC 100 + 102            │
│ └─ Posible LiteLLM proxy delante para tenant management            │
│                                                                    │
│ Pool ZFS llamacpp (888 GB)                                          │
│ ├─ Modelos GGUF (compartidos vía bind-mounts)                      │
│ │   ├─ gemma-4-26B-A4B-it-Q?_K_M.gguf  (PROD)                      │
│ │   ├─ gemma-4-31B-it-Q?_K_M.gguf                                  │
│ │   ├─ gemma-4-E4B-it-Q?_K_M.gguf                                  │
│ │   ├─ Qwen3.6-27B-Q?_K_M.gguf                                     │
│ │   ├─ Qwen3.6-35B-A3B-Q?_K_M.gguf                                 │
│ │   └─ ...                                                          │
│ └─ Registry JSON con metadatos                                     │
│                                                                    │
│ Pool ZFS backup (888 GB)                                            │
│ └─ vzdump nightly de los 3 LXC                                      │
└────────────────────────────────────────────────────────────────────┘
                                │
                                │ Tailscale (CreaRackSL@)
                                │
        ┌───────────────────────┼───────────────────────────┐
        │                       │                           │
   CreaRack PROD           Edu / Dani devices         Otros proyectos
   (Auto-Plan,             (UI ChatGPT-like           (futuras apps con
    CNS, etc.)              en navegador)              API keys propias)

4. Fases del plan

Fase A · Modelos en disco + CLI gestión (estimación ~3 h)

Objetivo: tener varios modelos descargados + scripts CLI para gestión sin UI.

Implementación:

  • Scripts en /usr/local/bin/ del LXC playground (no del PROD):

    • model-download <repo> [pattern] — wget desde HuggingFace al directorio modelos. Si HF tiene varios files matching pattern, lista para elegir.
    • model-list — lista GGUFs en /var/lib/llamacpp/models/, marca cuál está activo, muestra tamaños y last_used.
    • model-rm <file> — borra GGUF (con confirmación interactiva o --force).
    • model-switch <file> — cambia --model en systemd unit + restart. Verifica que existe + valida arquitectura compatible.
    • model-info <file> — gguf_info rápido (architecture, quant, context size, vision/no, tokenizer).
    • model-bench <file> [<prompt>] — benchmark rápido sobre el modelo (prompt eval + decode tps).
  • Registry simple en /var/lib/llamacpp/registry.json:

    {
      "models": [
        {
          "file": "gemma-4-26B-A4B-it-UD-Q4_K_M.gguf",
          "repo": "unsloth/gemma-4-26B-A4B-it-GGUF",
          "size_bytes": 16868240704,
          "downloaded_at": "2026-05-01T10:35:00Z",
          "last_used_at": "2026-05-01T11:20:00Z",
          "vision": true,
          "mmproj": "mmproj-F16.gguf",
          "context_max": 16384,
          "is_locked_for_prod": true
        }
      ]
    }
  • Integration HF: usar API pública https://huggingface.co/api/models/<repo> para listar files + descargas con wget al CDN cdn-lfs.huggingface.co. Sin token (modelos públicos).

Modelos a descargar inicialmente: los 5 que pidió Edu en s45 (verificados existen):

  • unsloth/gemma-4-E4B-it-GGUF
  • unsloth/gemma-4-26B-A4B-it-GGUF (ya parcialmente descargado)
  • unsloth/gemma-4-31B-it-GGUF
  • unsloth/Qwen3.6-27B-GGUF
  • unsloth/Qwen3.6-35B-A3B-GGUF

Total estimado en Q4_K_M: ~77 GB. Cabe ×10 en pool de 888 GB.

Fase B · LXC 102 playground separado (estimación ~1.5 h)

Objetivo: experimentar con modelos sin interrumpir Auto-Plan PROD.

Implementación:

  • pct create 102 ubuntu-24.04-standard con misma config que LXC 100 (24 cores 8-31, 64 GB RAM, bind-mount al pool ZFS llamacpp/models en modo lectura).
  • Wait — los cores 8-31 ya están asignados al LXC 100. Conflicto de cgroup. Solución: LXC 102 usa cores diferentes (ej: 32-55 si se libera del host) O los 2 LXC comparten cores via cgroup cpus=8-31 ambos con cpu.shares distintos.
  • Mejor enfoque: LXC 100 pin estricto (cgroup cpuset.cpus = 8-31), LXC 102 usa pool 0-7,32-63 (también pin estricto, los 8 cores del host + los 32 SMT siblings). Requiere validar performance (SMT siblings comparten unidades de ejecución).
  • llama-server en :8081 dentro del LXC 102.
  • Bind-mount al mismo dataset ZFS de modelos pero readonly (LXC 102 NO modifica modelos compartidos — se hace desde LXC 100 con privilegios).
  • Tailscale separado: crearack-llama-playground con su IP Tailscale propia.

Beneficio clave: cualquier model-switch en LXC 102 NO afecta a LXC 100. Auto-Plan PROD nunca pierde servicio.

Fase C · Open WebUI (LXC 101, estimación ~3 h)

Objetivo: UI ChatGPT-like para uso humano + API keys nativas.

Stack:

  • LXC 101 crearack-openwebui (4 cores, 8 GB RAM, 30 GB rootfs).
  • Docker dentro del LXC (privileged o nesting=1).
  • docker compose con:
    • open-webui container (ghcr.io/open-webui/open-webui:latest).
    • postgres container (BD persistente para usuarios + conversaciones + RAG).
    • Opcional: redis para cache.
  • Volumen Docker en pool ZFS (snapshots gratis para BD).

Configuración:

  • Open WebUI configurado con MULTIPLES OpenAI endpoints:
    • “PROD (LXC 100)” → http://100.80.142.60:8080 (modelo fijo gemma 26B)
    • “Playground (LXC 102)” → http://<TS-LXC-102>:8081 (modelo intercambiable)
  • Auth via email + password (pool inicial: Edu, Dani, Txell). API keys auto-generadas por usuario.
  • Conversaciones persistentes en BD postgres + drag-drop archivos para RAG.

Lo que Open WebUI NO da out-of-the-box:

  • Descarga de modelos GGUF directamente — esa funcionalidad está atada a Ollama (que NO usamos). Workaround: bot CLI vía nuestros scripts Fase A, o mini-página custom en Astro (workspace) que liste modelos + permita descargar de HF.
  • Switch dinámico de modelo cargado en llama-server — workaround: en Open WebUI cada modelo del playground se mapea a un endpoint distinto, y el switch real lo hace model-switch en background del LXC 102. Latencia 30-60 s aceptable para playground (no para PROD).

Fase D · LiteLLM proxy multi-tenant (opcional, estimación ~2 h)

Cuándo: si surgen apps externas a CreaRack que necesitan consumir el llama (ej: app móvil, plugin Excel, integración con Holded, etc.).

Por qué:

  • Open WebUI da API keys básicas pero su modelo es “1 user = 1 API key”. Para multi-tenant real (varios proyectos, billing por proyecto, rate limiting por team) → LiteLLM proxy delante.
  • LiteLLM expone OpenAI-compat estándar + dashboard + spending tracking + virtual keys + budgets.
  • Backend: nuestros llama-servers en LXC 100 + 102.

Setup: container Docker en LXC 101 junto a Open WebUI. Configurado con cada llama-server como “model” con virtual keys por tenant.

Fase E · Backups + DR (estimación ~1 h)

  • vzdump nightly de los 3 LXC (100, 101, 102) al pool backup.
  • Snapshots ZFS antes de cada update llama.cpp / modelo nuevo / cambio config.
  • Replicación off-site (pendiente desde s45 — diferida a soak): Storage Box Hetzner o cross-server CreaRack PROD.

Fase F · Observabilidad (estimación ~2 h)

  • Prometheus exporter por cada llama-server (/metrics ya expuesto).
  • Push a VictoriaMetrics de CreaRack PROD (existente) o instancia local.
  • Dashboard Grafana con: tps por modelo, latencia P50/P95/P99, requests/min, errores, RAM usage por LXC.
  • Alertas: si llama-server cae, si latencia > X, si disco pool ZFS llamacpp > 80 %.
  • Integration con sensor del workspace (workspace.crearack.com/biblioteca/pulse).

Fase G · Cost tracking interno (opcional, estimación ~3 h)

Para qué: si crece a varios proyectos consumiendo el llama, conviene saber quién usa cuánto para distribuir coste interno (aunque sea coste fijo del server, da visibilidad).

  • Logging por request: tenant + tokens prompt + tokens completion + modelo + duración.
  • Dashboard mensual: top consumidores + total tokens + utilización del server.
  • Posible cap por tenant si saturación.

5. Estimación total

FaseTiempoBloqueante para next
A · Modelos + CLI~3 hsí
B · LXC 102 playground~1.5 hsí
C · Open WebUI LXC 101~3 hparcial
D · LiteLLM (opcional)~2 hno
E · Backups + DR~1 hno
F · Observabilidad~2 hno
G · Cost tracking (opcional)~3 hno

Total mínimo viable (A+B+C+E+F): ~10 h trabajo efectivo. Total completo (A-G): ~15 h.

Distribución sugerida en 2-3 sesiones cuando llegue el momento.


6. Decisiones técnicas pendientes (cuando se aborde)

  • Cores LXC 102: ¿usar SMT siblings (cores 32-63) o partir el host en NUMA distinto? Probar ambos, medir.
  • Docker en LXC 101: ¿privileged o nesting=1 + keyctl? El segundo es más seguro pero algunos containers fallan.
  • BD Open WebUI: postgres dedicado o sqlite simple? Postgres si crecemos, sqlite suficiente para inicio.
  • TLS: Open WebUI tras Caddy con LetsEncrypt en algún subdomain de crearack.com? O queda solo Tailscale interno (sin TLS, ya cifrado por Wireguard)?
  • Sync de modelos LXC 100 ↔ LXC 102: ¿bind-mount al mismo dataset ZFS (compartir disco) o cada LXC tiene su copia? Compartir es más eficiente pero requiere coordinación si uno escribe y otro lee.
  • Naming convention: “PROD” y “Playground” claros en UI Open WebUI, o exponer cada modelo individual? Probablemente lo segundo (más explícito).

7. Riesgos identificados

  1. Saturación pve-epyc-02 al migrar todos los sites CreaRack: hoy solo Auto-Plan usa el server. CNS + Help + tutor + MIB pueden tener tráfico concurrente alto. Hay que medir caudal antes de migrar y validar que un único llama-server CPU aguanta. Si no → escalar (otro EPYC) o aceptar fallback a OpenRouter para sites menos críticos.
  2. Open WebUI lock-in: si el proyecto upstream cambia de licencia o se abandona, hay que migrar de UI. Mitigación: BD postgres exportable, conversaciones standard.
  3. Multi-instancia llama-server compite por bandwidth de RAM: aunque haya 256 GB, dos modelos cargados leyendo simultáneamente saturan los 8 canales DDR4. Probar bajo carga antes de prometer “varios modelos warm a la vez”.
  4. API keys filtradas: si una key se filtra a tercero, le da acceso ilimitado al llama. Mitigación: rate limit + rotación periódica + scope mínimo.
  5. Coste de mantenimiento creciente: 3 LXC + Docker + BD + observabilidad = más superficies que mantener. Validar que merece la pena vs simplicidad actual.

8. Trigger para ejecutar el plan

Las dos condiciones que destrabaán este plan:

✅ Auto-Plan al 100 % (calidad ≥ 95 % con modelo self-hosted, plano 70 racks ≤ 4 min) durante 2 semanas estables. ✅ Sites IA CreaRack restantes (CNS, Help, tutor, MIB, ops, finops, perf, workspace 3) migrados a OLLAMA_BASE_URL=http://100.80.142.60:8080 y operativos con calidad/latencia aceptables.

Cuando ambas se cumplan, abrir sesión dedicada para Fase A + B + C como mínimo viable. D-G según prioridades del momento.


9. Referencias


Véase también

  • [[crearack-tech—admin—llama-server-runbook]] — runbook actual del llama-server
  • [[crearack-tech—admin—proxmox-epyc-setup]] — setup host
  • [[workspace—guias—llama-acceso-uso]] — guía actual usuario
  • [[workspace—agentes-ia]] — comparativa agentes IA