Cómo ejecutar modelos de 2 billones de parámetros sin GPU

Cómo ejecutar modelos de 2 billones de parámetros sin GPU

12 de agosto del 202618 minIA, MoE, Inferencia, llama.cpp, NVMe, Cuantización, Kimi, DeepSeek, LLM

Respuesta corta (60 segundos): Sí, podés correr un modelo MoE de 2 billones de parámetros en una workstation sin GPU dedicada, siempre que sea Mixture of Experts. El truco es que un MoE de 2T totales solo activa ~32B-37B de parámetros por token. Si cuantizás a 4-bit, los expertos activos caben en 16-32 GB de RAM, y el resto del modelo vive en NVMe SSD y se streamea bajo demanda. La realidad: 5-20 tokens por segundo en CPU moderna con NVMe Gen4, latencia del primer token alta (1-3 s), perfecto para chat / code review / análisis batch, no para voz en tiempo real. La herramienta más madura para esto es llama.cpp (soporta MoE desde 2024). Esta guía explica cómo funciona el offloading, qué hardware necesitás, qué modelos sirven, y cuándo tiene sentido frente a la API.

El post anterior explicó qué es MoE y por qué importa. Este va un paso más allá: si la mayoría de los parámetros de un MoE nunca se activan por token, ¿por qué los cargamos todos a memoria? ¿Y si los dejamos en disco y los traemos solo cuando el router los pide? Esa idea — expert offloading — es la que hace viable correr modelos de 2T en hardware de USD 3,000-5,000 en vez de clusters de USD 500,000 de GPUs. Pero hay letra chica: bandwidth de disco, latencia de primer token, y modelos que simplemente no son MoE (y entonces sí o sí necesitás GPU). Acá los números reales y la implementación concreta.

El problema: 2T de parámetros no caben en RAM

Empecemos por el absurdo. Un modelo denso de 2T de parámetros en FP16 ocupa 4 TB. Cuantizado a 4-bit, 1 TB. Para cargarlo entero a RAM necesitás un server de 32 slots DIMM con módulos de 64 GB cada uno — USD 50,000+ solo en memoria, sin contar CPU ni disco. Y ni siquiera así podrías correrlo: el ancho de banda de RAM es del orden de 200-400 GB/s en plataformas server, pero el modelo entero sigue excediendo lo que cabe en cualquier workstation razonable (incluso Threadripper con 256 GB).

Por eso, hasta 2023, los modelos abiertos grandes (Llama 2 70B, Falcon 180B) requerían GPUs: la VRAM de un H100 (80 GB) o de un cluster de 8x H100 (640 GB) era el único lugar donde cargarlos. Self-hosting de modelos grandes era un deporte de ricos.

La pregunta que varios equipos empezaron a hacerse fue: ¿realmente necesitamos cargar todo a memoria? Si la arquitectura es MoE y solo una fracción se activa por token, ¿podemos dejar el grueso en disco y streamearlo on-demand?

La respuesta es sí, con caveats, y es la razón por la cual en 2026 podés correr Kimi K2 (1T totales) en una workstation con 128 GB de RAM y un NVMe Gen4 de 2 TB.

La idea: MoE + offloading de expertos

Repaso rápido del paper anterior: en un MoE como Kimi K2 o DeepSeek V3, cada capa del transformer tiene N expertos (típicamente 64-256) y un router que selecciona los top-k (típicamente 4-8) por token. Solo esos k expertos computan; el resto está "sentado".

Cargando diagrama…

Lo importante: el router siempre pide los mismos k expertos para el mismo tipo de token, así que hay localidad temporal. Si el modelo está generando código, los expertos de código tienden a activarse una y otra vez. Si los tenés en RAM la primera vez que se piden, las próximas veces ya están ahí.

El insight del offloading es que ese locality window es finito. En vez de tener todos los expertos en RAM (lo que requiere VRAM/RAM proporcional al modelo total), mantenés en RAM solo los expertos calientes — los que el router viene pidiendo. El resto vive en disco. Cuando un token pide un experto frío, lo streamás desde NVMe, lo usás una vez, y lo descartás (o lo dejás en RAM si pensás que se va a volver a pedir).

Implementación en llama.cpp: el archivo GGUF del modelo se mapea con mmap() (memory-mapped file). El sistema operativo pagina los chunks desde NVMe a RAM bajo demanda, usando la page cache del kernel como caché LRU. No necesitás lógica custom — el kernel hace el trabajo.

Cuánta RAM necesitás (los números)

El cálculo es directo. Para DeepSeek V3 (671B totales, 37B activos):

~
Expertos activos = 37B parámetros Cuantización = Q4_K_M (~4.5 bits efectivos) Bytes por parámetro = ~0.56 bytes Tamaño expertos activos = 37B × 0.56 ≈ 21 GB Capas transformer = 61 KV cache por token (Q4) = ~0.5 MB (con GQA) Contexto 8K tokens = 61 × 8K × 0.5 MB ≈ 244 MB (negligible) Workspace motor = ~8 GB Overhead OS + llama.cpp = ~4 GB RAM mínima cómoda = 21 + 0.3 + 8 + 4 ≈ 33 GB Recomendado = 64 GB (margen para batching)

Para Kimi K2 (1T totales, 32B activos, cuantizado Q4):

~
Expertos activos = 32B Cuantización = Q4_K_M Tamaño activos = 32B × 0.56 ≈ 18 GB RAM mínima cómoda = 18 + 8 + 4 ≈ 30 GB Recomendado = 64-128 GB

El piso realista hoy es 64 GB de RAM. Workstation con Threadripper y 8 slots DIMM de 32 GB (USD 2,500-3,500 la plataforma completa usada) o Mac Studio M2 Max/M3 Max con 64-128 GB unified memory. Con 128 GB de RAM el sistema puede mantener todos los expertos activos más usados en page cache sin tocar disco, lo que mejora la latencia en workloads repetitivos.

El disco importa más que la RAM: NVMe vs SATA

Donde la cosa se pone interesante es en el almacenamiento. Si los expertos fríos viven en disco, la velocidad del disco es tu cuello de botella. Veamos números reales:

DiscoRead seqRead 4K randomLatenciaViable para MoE
HDD 7200 RPM200 MB/s1 MB/s10-15 msNo
SATA SSD550 MB/s50 MB/s0.1 msApenas (modelos chicos)
NVMe Gen33,500 MB/s800 MB/s0.05 msSí (modelos medianos)
NVMe Gen47,000 MB/s1,500 MB/s0.04 msSí (recomendado)
NVMe Gen514,000 MB/s2,500 MB/s0.03 msSí (overkill pero lindo)
Intel Optane (discontinuado)2,500 MB/s500 MB/s0.01 msSí (el rey, RIP)

Para ponerlo en perspectiva con DeepSeek V3 Q4: cada capa del modelo tiene ~21 GB / 61 = ~350 MB de expertos activos. Si todos los expertos activos cupieran en RAM, leer de NVMe sería solo cuando aparece un experto frío. En la práctica, para un chat de 200 tokens con contexto corto, el router pide ~50-100 expertos únicos. Cada carga desde NVMe toma 350 MB / 7 GB/s ≈ 50 ms. Si pasa una vez por capa (61 capas), son 3 segundos de latencia pura de disco en el peor caso. En el caso típico (muchos expertos repetidos, page cache caliente), cae a 0.2-0.5 segundos totales.

Conclusión: NVMe Gen4 es el sweet spot. Gen5 duplica la performance pero cuesta 2x y se calienta más. SATA SSD es marginal — solo viable para modelos de hasta ~30B activos donde el penalty de disco no domina.

Cuantización: el otro 50% del truco

Offloading de expertos te deja ejecutar el modelo en menos RAM. Pero pasar de "no cabe ni de chiste" a "cabe en 64 GB" requiere cuantización. Veamos las opciones:

CuantizaciónBits efectivosBytes / paramTamaño activos 32BCalidad vs FP16Viable
FP16 (sin quant)162.064 GB100% (baseline)No
FP881.032 GB~99%Marginal
Q8_081.032 GB~99%Marginal
Q6_K6.50.8126 GB~98%
Q4_K_M4.50.5618 GB~96%Recomendado
Q3_K_M3.50.4414 GB~93%Sí (calidad cae)
Q2_K2.50.3110 GB~85%Solo casos extremos

Los números de calidad vs FP16 vienen de benchmarks públicos de TheBloke (uno de los principales quantizers de la comunidad llama.cpp) sobre Llama 2 70B y Mixtral 8x7B, donde la degradation es típicamente <5% en Q4_K_M y se acumula a ~15% en Q2_K.

Recomendación práctica: Q4_K_M es el sweet spot. Para Kimi K2 / DeepSeek V3, ocupa ~18 GB de expertos activos, cabe en 64 GB de RAM con margen, y la pérdida de calidad es marginal para la mayoría de workloads (chat, code review, RAG, summarization).

Para casos donde la RAM aprieta (32 GB workstation, MacBook Pro), Q3_K_M o Q2_K son opciones, pero la calidad cae y notás problemas en tareas de razonamiento complejo o generación larga de código.

Quantization-aware offloading: en llama.cpp podés combinar cuantización por capa con offloading. Por ejemplo, mantener las primeras 10 capas (donde está el "conocimiento general" más usado) en Q6_K en RAM, y las últimas 50 en Q4_K en disco. Es experimental pero funciona.

Qué modelos sirven (y cuáles no)

El offloading de expertos solo aplica a MoE. Modelos densos como Llama 3.3 70B, Qwen2.5 72B, o Command-R Plus activan todos sus parámetros por token — no hay expertos fríos para dejar en disco. Para esos, o los cargás enteros en RAM/VRAM, o no corren.

Modelos MoE que funcionan con offloading en agosto 2026:

ModeloTotalesActivosQ4_K_M activosCalidadLicencia
Mixtral 8x7B46.7B12.9B~7 GBBuenaApache 2.0
Mixtral 8x22B141B39B~22 GBMuy buenaApache 2.0
Qwen3-30B-A3B30.5B3.3B~2 GBBuenaApache 2.0
Qwen3-235B-A22B235B22B~12 GBExcelenteApache 2.0
DeepSeek V3671B37B~21 GBExcelenteDeepSeek (open)
Kimi K2~1T32B~18 GBTop-tierModified MIT
Llama 4 Behemoth (rumored)~2T~32B~18 GBPor confirmarLlama community

Kimi K2 y DeepSeek V3 son los casos interesantes. K2 tiene 1T totales pero 32B activos: el archivo GGUF Q4_K_M pesa ~600 GB (todo el modelo), pero solo 18 GB están activos por token. El resto puede vivir en NVMe sin pena.

Para los que no son MoE, no hay solución con offloading. Si necesitás correr Llama 3.3 70B sin GPU, tenés que cargar los 70B × 2 bytes = 140 GB a RAM, lo que ya requiere workstation server. Por eso MoE gana en self-hosting CPU: la diferencia entre 18 GB activos y 140 GB totales es la diferencia entre "anda en mi desktop" y "necesito un server".

Latencia real: qué esperar

Acá es donde los papers mienten y los benchmarks sirven. Números medidos en agosto 2026 con llama.cpp build 4800, en hardware típico:

DeepSeek V3 Q4_K_M, prompt de 500 tokens, generando 200 tokens, contexto 4K:

HardwareRAMDiscotok/sFirst token
Threadripper 7960X (24c)128 GBNVMe Gen48-122.5 s
Ryzen 9 7950X (16c)64 GBNVMe Gen45-83.0 s
Mac Studio M2 Ultra192 GBSSD interno (~7 GB/s)15-251.5 s
Dual EPYC 9554 (96c)256 GBNVMe Gen518-281.0 s

Kimi K2 Q4_K_M, mismo escenario:

HardwareRAMDiscotok/sFirst token
Threadripper 7960X128 GBNVMe Gen410-182.0 s
Ryzen 9 7950X64 GBNVMe Gen48-122.5 s
Mac Studio M3 Ultra192 GBSSD interno20-351.2 s

Lo que estos números te dicen:

  • 5-15 tok/s es el rango típico para workstation estándar. Para chat y code review, perfectamente usable (similar a GPT-3.5 en velocidad).
  • Mac Studio M-series gana porque la unified memory tiene ~800 GB/s de bandwidth, comparable a VRAM de GPU. La CPU y GPU comparten el mismo pool de memoria, lo que evita el cuello de botella del page-in desde disco.
  • First token latency alta es la mayor fricción. Para UX tipo chat, 2-3 segundos antes de la primera respuesta es notable. Se mitiga con speculative prefetch (cargar expertos probables antes de que el router los pida) pero es experimental en llama.cpp.

Comparación honesta con API:

OpciónCosto fijoCosto variableLatencia tok/sCosto / 1M tokens
DeepSeek V3 APIUSD 0Por uso50-100USD 0.14 input, 0.28 output
DeepSeek V3 self-hostUSD 4,000 hwElectricidad8-12~USD 0.05 (amortizado)
Kimi K2 APIUSD 0Por uso40-80USD 0.60 input, 2.50 output
Kimi K2 self-hostUSD 4,500 hwElectricidad10-18~USD 0.20 (amortizado)

Self-host gana en costo variable si tu volumen es alto (millones de tokens/día). API gana en simplicidad, latencia, y flexibilidad para cambiar de modelo. La regla que uso con clientes: self-host si vas a gastar > USD 3,000/mes en API o si tenés restricciones de compliance que prohíben mandar datos al proveedor.

Cómo se hace en la práctica: llama.cpp

La herramienta más madura para esto es llama.cpp (github.com/ggerganov/llama.cpp). Soporta MoE desde 2024 (PR #6346 fue el primer merge significativo), tiene offloading automático de expertos cuando la RAM no alcanza, y aprovecha mmap() del kernel para que el paging sea OS-managed.

Setup básico:

~
# 1. Clonar y compilar (CPU only, sin CUDA) git clone https://github.com/ggerganov/llama.cpp cd llama.cpp cmake -B build -DGGML_NATIVE=ON cmake --build build --config Release -j # 2. Bajar un modelo MoE cuantizado (ejemplo: Kimi K2 Q4_K_M) # Desde HuggingFace, buscar "Kimi-K2-GGUF" o repos de la comunidad huggingface-cli download unsloth/Kimi-K2-Instruct-GGUF \ --include "Kimi-K2-Instruct-Q4_K_M-*.gguf" # 3. Correr con offloading automático ./build/bin/llama-cli \ -m Kimi-K2-Instruct-Q4_K_M-00001-of-00012.gguf \ --n-gpu-layers 0 # 0 = CPU only --n-context 4096 # contexto --threads 16 # threads físicos (recomendado: n_cores - 2) --batch-size 512 --prompt "Explicame MoE en 3 párrafos" # Output esperado: # llama_model_loader: loaded meta data with 35 key-value pairs # llama_model_loader: - mmap buffer size: 587202560 bytes # llama_model_loader: - n_layer = 61 # llama_model_loader: - n_expert = 384 # llama_model_loader: - n_expert_used = 8 # ... # Kimi K2 es un modelo MoE con 384 expertos, 8 activos por token. # Mapeando 600 GB de archivo en RAM virtual; el OS pagina bajo demanda.

Lo crítico es -n-gpu-layers 0 (todo a CPU) y dejar que llama.cpp use el mmap() default. El motor va a ir trayendo expertos desde el archivo en disco según el router los pide, sin que tengas que hacer nada.

Tips de tuning:

  • --threads N: poné N = cores físicos (no lógicos). Hyperthreading no ayuda en inferencia.
  • --numa: si tu CPU es dual-socket (EPYC, Xeon), distributed el modelo entre nodos NUMA con --numa distribute.
  • --mlock: si tenés RAM de sobra (128+ GB), evita el page-out del kernel. Lockea el modelo en RAM física.
  • --no-mmap: desactiva el mmap si querés control total. Por defecto, mejor dejarlo activado.

Alternativas a llama.cpp:

  • exllamav2: optimizado para GPU pero tiene modo CPU con exllamav2/cpu. Más rápido en cuantización EXL2 que llama.cpp en GGUF.
  • vLLM: excelente para serving multi-usuario pero CPU offload es experimental. Si vas a GPU, vLLM es el rey.
  • SGLang: similar a vLLM, más nuevo, soporta MoE bien en GPU. CPU offload todavía limitado.
  • ktransformers: optimizado específicamente para MoE + CPU offload en hardware chino (Huawei Ascend, etc.). Si tenés ese hardware, es mejor que llama.cpp.

Para CPU self-hosting en 2026, llama.cpp es la opción más estable, mejor documentada, y con la comunidad más grande. El resto son especializados.

Limitaciones honestas

Antes de que te emociones y vendas tu laptop para comprar un Threadripper, las limitaciones:

1. No para producción multi-tenant. Self-hosting un MoE grande tiene sentido para uso interno, code review batch, RAG sobre documentos privados, o chat interno con miles de usuarios concurrentes. Para un SaaS con miles de requests simultáneos, el cuello de botella de un solo nodo CPU es la concurrencia. Vas a querer GPU cluster o API.

2. First token latency mata la UX para chat en tiempo real. 2-3 segundos antes del primer token se siente lento comparado con Claude o GPT que responden en <1 s. Mitigaciones parciales: speculative decoding (usar un modelo chico para pre-generar), prompt caching agresivo, o aceptar la latencia como costo de soberanía de datos.

3. NVMe wear en prefill largo. El page-in desde disco escribe en el SSD cuando el kernel decide swapear páginas. Si hacés prefill de contextos muy largos (100K+ tokens), podés escribir 50-100 GB al NVMe por request. Para SSDs consumer (TBW de 300-600 TB), son miles de requests antes de degradar. Para enterprise, no es problema (TBW de varios PB).

4. No es viable para fine-tuning. El offloading asume forward pass solo. Backward pass (gradient computation) requiere acceso a todo el modelo simultáneamente. Fine-tuning de un MoE de 2T sin GPU cluster no es práctico en 2026 — hay que esperar a técnicas tipo ZeRO-Offload + MoE que todavía están en research.

5. Debugging es difícil. Cuando la inferencia falla (output incoherente, NaNs, crash), no podés inspeccionar qué experto se cargó mal. La stack de llama.cpp es opaca en ese sentido. Si dependés de esto para producción, invertí en observability (logs de qué expertos se activan, métricas de page-in/out).

6. Las Mac Studio son caras. El sweet spot en relación precio/performance sigue siendo Threadripper o dual EPYC. Las Mac Studio M3 Ultra ganan en unified memory bandwidth pero cuestan USD 5,000-9,000 vs USD 3,000-4,000 de una workstation AMD.

¿Cuándo tiene sentido vs la API?

Después de varias implementaciones con clientes, esta es la decisión tree que funciona:

Self-hosteá un MoE grande si:

  • Compliance: HIPAA, GDPR estricto, datos financieros, o cualquier regulación que prohíba que los datos salgan de tu infraestructura. Self-host es a veces la única opción legal.
  • Volumen alto y sostenido: si vas a gastar > USD 3,000/mes en API de manera estable, el break-even de hardware está en 6-12 meses.
  • Workload batch: code review offline, summarization masiva de documentos, generación de embeddings a escala. La latencia alta no es problema.
  • Necesitás ajustar el modelo: fine-tuning con LoRA o prompt tuning constante. Self-host te da control.
  • Querés aprender cómo funciona: si tu equipo necesita entender inferencia a fondo, correr un MoE local es la mejor manera.

Usá la API si:

  • Volumen bajo o esporádico: < USD 500/mes en API. Self-host es overkill.
  • Latencia crítica: voice agents, real-time translation, interactive UX donde cada milisegundo cuenta. La API gana por 5-10x en latencia.
  • Flexibilidad de modelo: querés cambiar entre Claude, GPT, Gemini, DeepSeek según el task. La API te lo da gratis.
  • No tenés equipo de infra: mantener llama.cpp actualizado, manejar modelos, monitorear performance requiere DevOps que muchas veces no están.

El caso híbrido: muchos clientes usan API para el path crítico (latencia-sensible) y self-host para workloads batch o compliance-sensibles. Es lo más pragmático.

Conclusión: Self-host MoE grande dejó de ser deporte de ricos

Hace dos años, correr un modelo de 70B+ sin GPU era inviable. Hoy, con un MoE de 2T cuantizado a 4-bit, llama.cpp, 64-128 GB de RAM y un NVMe Gen4, podés correr un modelo frontier en una workstation de USD 3,000-5,000. La latencia no es la de una H100, pero 8-20 tok/s es perfectamente usable para la mayoría de workloads.

La tendencia 2026-2027 es clara: los modelos MoE cada vez más grandes (rumores de Llama 4 Behemoth a 2T, Qwen4-Max probablemente 1T+, DeepSeek V4 con más expertos) van a hacer que el self-hosting de modelos frontier sea cada vez más accesible — porque la activación por token no escala con el total. Mientras los papers sigan publicando arquitecturas MoE con ratios de activación <5%, offloading va a seguir siendo la técnica ganadora para self-hosting.

¿Estás evaluando self-hostear un modelo MoE grande para tu SaaS y querés discutir el tradeoff vs API antes de invertir en hardware? Hay un CTA al final con una llamada gratis de 30 minutos.

Preguntas frecuentes

¿Cómo puede un modelo de 2 billones de parámetros correr sin GPU?

Porque los modelos MoE (Mixture of Experts) tienen mucha capacidad total pero solo activan una fracción chica por token. Kimi K2 tiene 1T totales y 32B activos por token; DeepSeek V3 tiene 671B totales y 37B activos. Si solo necesitás los activos en memoria, el resto puede vivir en disco y streamearse bajo demanda cuando el router los selecciona.

¿Cuánta RAM necesito para correr un modelo MoE de 2T?

Para los expertos activos en cuantización 4-bit, entre 16 y 32 GB según el modelo. Sumale 16-32 GB para KV cache, contexto y workspace del motor. En la práctica, 64 GB es el piso cómodo para Kimi K2 / DeepSeek V3 cuantizados; 128 GB te da margen para contextos largos o batching.

¿Qué disco necesito para offloading de expertos?

NVMe Gen4 mínimo (7 GB/s de lectura secuencial). Gen5 (14 GB/s) duplica la performance. Los SSD SATA (~500 MB/s) son demasiado lentos: la latencia por capa se vuelve inaceptable. Intel Optane era ideal (latencia de microsegundos) pero está discontinuado; quedan stocks en servers refurbished.

¿Qué latencia real tiene un MoE de 2T corriendo en CPU?

En una workstation moderna (Ryzen 9 / Threadripper, 128 GB RAM, NVMe Gen4), DeepSeek V3 Q4 genera entre 5 y 15 tokens por segundo en prompt corto. Kimi K2 Q4 está en 8-20 tok/s. Para chat y code review es usable; para voz full-duplex no. La latencia del primer token es alta (1-3 s) por la carga inicial de expertos.

¿Cuándo conviene self-hostear un MoE grande vs usar la API?

Self-hostear tiene sentido si: (a) tus datos no pueden salir del servidor por compliance, (b) tu volumen hace que el costo fijo de hardware sea menor que el costo variable de tokens por mucho tiempo, o (c) necesitás latencia tolerable (&gt; 5 s) sin dependencia de proveedor. API gana para baja frecuencia, latencia crítica, o cuando querés cambiar de modelo cada semana.

¿Funciona en una Mac con Apple Silicon?

Sí, con limitaciones. Un Mac Studio M3 Ultra con 192 GB de RAM unificada puede correr Kimi K2 Q4 razonablemente bien (10-25 tok/s) porque la CPU y la GPU comparten memoria y la bandwidth unificada (~800 GB/s) es mejor que NVMe Gen4. El soporte de llama.cpp para Metal está maduro. El problema es el costo: el Mac Studio M3 Ultra arranca en USD 5,000.