llama-router — Inferencia local multi-modelo optimizada con IA
Sistema de inferencia local que sirve múltiples modelos LLM sobre una iGPU AMD Radeon 680M con 24 GB de RAM compartida. Configuración generada declarativamente, validación automática contra hardware, KV cache persistente y selección de tier según tarea. Demuestra el ajuste óptimo de un stack de inferencia completo usando herramientas IA en el ciclo de desarrollo.
Problema
La inferencia de LLMs en hardware integrado (iGPU sin VRAM dedicada, RAM compartida con el sistema) requiere decisiones de optimización muy distintas al caso cloud o GPU discreta. Quería un sistema que sirviera varios modelos a la vez, eligiera el más adecuado por tarea, y se reconfigurara sin reiniciar el contenedor.
Solución
Un servidor HTTP OpenAI-compatible con un router multi-modelo: un solo modelo en memoria a la vez (LRU swap por demanda), KV cache persistente entre swaps para que cambiar de tier no cueste re-procesar el prompt, y una capa declarativa de configuración que separa los planes de despliegue de los flags por modelo, validada contra el hardware antes de generar el archivo que consume el servidor.
Logros clave
- Múltiples modelos servidos desde un solo endpoint, con cambio transparente entre ellos
- KV cache persistente: cambiar de modelo y volver no paga el coste de re-procesar el prompt
- Configuración generada desde planes declarativos, no editada a mano
- Validación automática contra el perfil de hardware antes de cada cambio
- 27+ modelos GGUF en el pool, 2 planes de despliegue activos, tests automatizados de integridad
- Construido iterativamente con asistencia IA: cada decisión de tuning justificada y reproducible
Qué es
Un servidor de inferencia local que expone varios modelos LLM a la vez bajo una API OpenAI-compatible. Los clientes piden el modelo por nombre y el servidor se encarga de cargarlo, mantener su caché, y descargarlo cuando otro modelo lo necesita.
La diferencia con setups más típicos: un solo modelo en memoria a la vez, con la KV cache serializada a disco entre swaps. Esto permite tener docenas de modelos disponibles sin pagar el coste de tenerlos todos cargados.
Qué demuestra de capacidad técnica
Tres piezas que muestran cómo se construye un sistema de inferencia a medida con asistencia IA en el bucle:
1. Decisiones de stack justificadas para hardware atípico
Sobre una iGPU AMD sin VRAM dedicada, las opciones realistas eran CPU-only, Vulkan, o ROCm. La elección fue Vulkan, y la razón técnica es que la iGPU tiene acceso directo a la RAM compartida — no hay copia VRAM-style, y mantener el modelo en “GPU” es lo que da el throughput utilizable. Esta clase de decisión (qué backend, qué flag de offload, qué cuantización) se repite por cada modelo del pool.
2. Capa declarativa sobre un servidor con config compleja
llama.cpp tiene docenas de flags interdependientes por modelo. En vez de mantener N archivos INI editados a mano, la configuración vive en:
- planes (
plans/*.json) — qué modelo va en cada slot lógico - perfiles de modelo (
presets/*/pool/*/config.json) — flags por modelo - perfil de hardware (
hardware/profile.json) — restricciones del sistema
Un script valida la combinación contra el hardware y genera el archivo que consume el servidor. Cambiar de modelo o de flags es editar un JSON y regenerar, no buscar y reemplazar en un INI.
3. Validación antes de aplicar, no después
El flujo de cualquier cambio de configuración incluye una fase de validación contra el hardware (¿cabe en RAM? ¿el GGUF existe? ¿los flags son válidos?) y, cuando aplica, contra una baseline de rendimiento (¿se mantiene el throughput? ¿siguen pasando los tests de tool-calling?). Si la nueva config no cumple, se rechaza antes de tocar el contenedor. Si cumple, se aplica con rollback automático en caso de regresión.
El router: lo que cambia la experiencia
La pieza que justifica toda la complejidad del sistema es la gestión del modelo en memoria:
- Llega una petición para el modelo A → se carga, se procesa, su KV cache queda en RAM.
- Llega una petición para el modelo B → la KV cache de A se serializa a disco, se descarga A, se carga B.
- Vuelve una petición para A → se restaura A desde disco Y su KV cache desde el snapshot. Si el prompt encaja con la cache, no se re-procesa desde cero.
El resultado es que el sistema “se siente” como si todos los modelos estuvieran siempre cargados, sin pagar el coste de memoria de tenerlos cargados. En la práctica, cambiar entre el modelo pequeño (responde en ~0.5s) y el grande (responde en ~15s pero razona mejor) no penaliza al usuario: el siguiente intercambio con cualquiera de los dos encuentra el contexto caliente.
Optimización por tarea
Cada modelo del pool tiene un rol pensado, no se cargan “todos los modelos interesantes”:
- Un modelo pequeño y rápido para tool-calling y respuestas cortas — el “operario” del sistema.
- Un modelo más grande con capacidad de razonamiento para planificación y preguntas abiertas — el “estratega”.
- Modelos especializados reservados para casos donde los dos anteriores no bastan (revisión de código, señales de trading).
El cliente pide el modelo por nombre. La elección de cuál usar la hace el agente que consume el servicio, basándose en la fase del pipeline en la que esté (percepción, ejecución, reflexión).
Cómo se desarrolló con IA
Este proyecto es un ejemplo de uso de herramientas IA en el bucle de desarrollo de un sistema técnico:
- Exploración del espacio de flags — los flags de
llama.cppestán documentados pero sus interdependencias no. Asistir en leer código de la comunidad, issues de GitHub, y resultados de benchmarks para decidir combinaciones razonables. - Generación de la capa declarativa — el “shape adapter” que traduce entre el formato JSON interno y el INI que consume el servidor es código de plomería, no de investigación. Adecuado para generación asistida.
- Validación contra hardware — escribir las invariantes (¿cabe en RAM? ¿el GGUF está donde debería?) es más rápido con asistencia, y la verificación automática reduce regresiones.
- Tuning iterativo — cuando un cambio degrada el rendimiento, el bucle es: detectar → revertir → ajustar el flag responsable → re-validar. La IA acelera el “ajustar” y el “explicar por qué” pero el “detectar” y “revertir” lo hace el sistema de tests.
El resultado: 27+ modelos en el pool, 2 planes de despliegue, 48 tests de integridad, y la confianza de que un cambio de configuración no rompe el sistema en producción porque hay validación automática antes y rollback después.