03 · Capacidades reales en M4 Pro 24 GB¶
Performance medible, memoria, cuellos de botella y framework selection para Apple M4 Pro.
Hardware de referencia¶
- Chip: Apple M4 Pro (12-core CPU, 16-core GPU)
- Memoria unificada: 24 GB
- Bandwidth de memoria: 273 GB/s (vs M3 Pro: +75%, vs M4 Max 32-core: 410 GB/s, vs M4 Max 40-core: 546 GB/s)
- Neural Engine: 16-core
- OS: macOS Darwin 24.6+
Disponible para modelos: 24 GB − ~5 GB (macOS + apps) = ~19 GB efectivos.
Performance verificada (mayo 2026)¶
Benchmark independiente Anass Kartit (MacBook M4 Pro, 24 GB, kartit.net):
| Modelo | Ollama | MLX-LM | Notas |
|---|---|---|---|
| Gemma 4 E2B | 95 tok/s | 81 tok/s | Audio falla en algunos casos |
| Gemma 4 E4B | 57 tok/s | 49 tok/s | Ganador práctico: audio ASR en 3 idiomas, imagen, código full-stack |
| Gemma 4 26B-A4B | ~2 tok/s | — | Carga pero OOM bajo carga sostenida |
| Gemma 4 31B Dense | — | — | No entra en 24 GB |
| Gemma 3 4B | ~70-90 tok/s | ~80-100 tok/s | Multimodal sólido |
| Gemma 3 12B (Q4_K_M) | ~25-35 tok/s | ~28-40 tok/s | Margen ajustado en context largo |
| Gemma 3 27B (Q4_K_M) | ~10-15 tok/s | — | Solo viable con prompts cortos |
Referencia: velocidad lectura humana ≈ 4-5 tok/s. >10 tok/s "tiempo real". Para producción interactiva, apunta a >25 tok/s.
Aviso: los números son con prompts cortos (≤512 tokens). En uso real con contexto de 8-32K tokens, espera 30-50% menos. Mide tu caso.
El cuello de botella real: bandwidth, no cores¶
- M4 Pro 273 GB/s → maneja Gemma 4 E4B a 57 tok/s.
- M4 Max 40-core 546 GB/s → ~2× más rápido en el mismo modelo.
- M3 Ultra (2× chips) → ~4× más rápido, puede correr 31B Dense con holgura.
Implicación: invertir en M4 Max 64 GB o Mac Studio M5 Ultra es viable solo si tu producto requiere correr el 26B o 31B localmente y de forma sostenida.
Cuantización: Q4_K_M es el sweet spot¶
| Cuantización | Memoria E4B | Velocidad | Calidad | Recomendación |
|---|---|---|---|---|
| Q2_K | ~3 GB | 70 tok/s | ↓↓ degradado | Solo edge extremo |
| Q4_K_M | ~5.5 GB | 57 tok/s | ≈ FP16 (99%) | ✅ Default |
| Q5_K_M | ~6.5 GB | 50 tok/s | ≈ FP16 | Si Q4 falla en eval |
| Q6_K | ~7.5 GB | 45 tok/s | ≈ FP16 | Marginal |
| Q8_0 | ~9.5 GB | 35 tok/s | ≈ FP16 | Solo si necesitas certificación |
| FP16 | ~11 GB | 25 tok/s | Referencia | Investigación, no producción |
Razón: M4 Pro es bandwidth-bound; Q4_K_M minimiza datos a mover por inferencia.
KV cache y contexto largo¶
- Gemma 4 E4B: KV cache añade ~2-4 GB en 32K tokens.
- Reduce
--num-ctx 8192por defecto si no necesitas más. - Flash Attention (en Ollama 0.22+ y llama.cpp) reduce KV cache en 30-50%.
- KV cache cuantizado a Q8 (solo llama.cpp): reduce otro 50%.
# Ollama con KV cache cuantizado y flash attention
OLLAMA_FLASH_ATTENTION=1 OLLAMA_KV_CACHE_TYPE=q8_0 ollama serve
Frameworks: cuándo usar cada uno¶
| Framework | Pros | Contras | Cuándo usarlo |
|---|---|---|---|
| Ollama 0.22+ | Setup en 1 comando, runner MLX integrado, API OpenAI-compatible, modelos pre-empaquetados (ollama run gemma4:e4b) |
Menor control de cuantización exacta | Día a día, prototipado, API local |
| llama.cpp | Máximo control (flags, KV cache cuantizado a Q8, flash attention), GGUF universal | Más setup; en agentic tooling Ollama tiene bugs con Gemma 4 (issue #15368) | Producción con tooling agentic complejo, prompts >500 tokens, exportación |
| MLX-LM | Nativo Apple Silicon, 10-30% más rápido teórico, soporta VLM (mlx-vlm 0.4.3) | Ecosistema más joven, menos modelos pre-cuantizados | Cuando quieres exprimir cada token/s, vision multimodal nativa |
| vLLM | Mejor throughput en servidor (continuous batching) | No usar localmente en Mac; sí para deploy en cloud | Cuando migres a GPU servidor |
| LiteRT-LM | Optimizado para edge (iOS/Android/Raspberry Pi 5 con NPU) | Solo edge | Apps móviles que embeben Gemma 4 E2B/E4B |
| Transformers (HF) | Estándar, fine-tuning fácil | Lento para inferencia en Mac | Solo para fine-tuning/training |
Recomendación práctica¶
- Empieza con Ollama, expón vía OpenAI-compatible API a tu backend.
- Escala a llama.cpp con flash attention solo si tu producto necesita tool-calling agentic.
- Pasa a MLX nativo únicamente si vendes una desktop app (Swift) y necesitas integración profunda con macOS.
Bugs conocidos en M4 Pro + Gemma 4 (mayo 2026)¶
Github issue ollama/ollama#15368 documenta:
- Flash Attention hang con prompts >500 tokens en el 31B Dense (Ollama 0.20.x). Mitigación: usa 0.22+ o
OLLAMA_FLASH_ATTENTION=0. - /v1 OpenAI endpoint envía contenido al campo
reasoningen vez decontent. Mitigación: parsea ambos campos, concaténalos. - MLX runner aún no soportado para
Gemma4ForConditionalGenerationen algunas builds. Mitigación: backend Metal (default) funciona.
Para agentic/tool-calling en Mac: usa llama.cpp directamente hasta que estos bugs cierren.
Plan de escalado por hardware¶
| Etapa | Hardware | Capacidad | Costo |
|---|---|---|---|
| 0-50 clientes | M4 Pro 24 GB (este) | ~500K tokens/día sostenidos | $0 marginal |
| 50-500 clientes | Mac Mini M4 Pro 48 GB headless | ~2M tokens/día | ~$1.8K one-time + $50/mes |
| 500-5K clientes | 2× Mac Studio M5 Ultra 256 GB en cluster | ~10M tokens/día | ~$16K one-time + $150/mes |
| 5K-50K clientes | Cloud Run NIM con L4/L40S/RTX 6000 | Auto-scale | Pay-per-use |
| 50K+ clientes | Vertex AI Model Garden / on-prem H100 | Ilimitado | $5K-50K/mes |
Break-even self-hosting vs API (según VentureBeat TCO 2026): ~22.2M palabras/día (≈ 30M tokens/día) para justificar 2× H100 colocation.
Comandos útiles para benchmarking¶
# Tokens por segundo en interactive
ollama run gemma4:e4b --verbose "Escribe un párrafo sobre IA."
# Latencia de primer token
time echo "hola" | ollama run gemma4:e4b
# Memoria residente
ps aux | grep ollama
# o más preciso:
sudo powermetrics --samplers gpu_power -n 1 -i 1000
# Stress test (script proporcionado en scripts/bench.sh)
./scripts/bench.sh gemma4:e4b 100 # 100 queries
Ver benchmarks/m4-pro-24gb.md para resultados reproducibles.