Intermedio 13 minMac

MLX vs llama.cpp en Mac con chips de la serie M: quién gana en 2026 ?

En los Mac de la serie M, tienes dos opciones para ejecutar un LLM en local: MLX, el framework oficial de Apple, o llama.cpp con su backend Metal. Ambos aprovechan la GPU integrada y la memoria unificada, pero con filosofías muy diferentes. Esta comparativa de MLX y llama.cpp en Mac enfrenta ambos en tokens/segundo, compatibilidad con modelos, cuantización y comodidad de uso en Python, con un veredicto claro según tu perfil.

Por Marie L.·Actualización 2026-08-27·Probado en macOS 14+

#Los dos bandos en 2026

MLX se lanzó al final de 2023, desarrollado por el equipo de ML de Apple. Es un framework Python que parece una fusión de NumPy y PyTorch, diseñado desde el principio para la memoria unificada y Metal. Su objetivo es amplio: LLM, visión, audio, fine-tuning. El paquete mlx-lm se encarga específicamente de la inferencia y el entrenamiento de modelos de lenguaje.

llama.cpp es un proyecto en C++ nacido en 2023, que se ha convertido en el estándar de hecho para la inferencia local de LLM en todas las plataformas. En Mac, su backend Metal genera shaders de cómputo para aprovechar la GPU de Apple Silicon. Es lo que hace funcionar Ollama, LM Studio y la mayoría de las herramientas para el público general. Formato de modelo: GGUF.

i
¿Por qué existen juntos?
MLX es nativo de Apple, llama.cpp es portátil. El primero está optimizado hasta la última instrucción de Metal; el segundo exporta el mismo código para CUDA, Vulkan y ROCm. En Mac, compiten directamente. En otras plataformas, no hay debate.

#1. Instalación

El kit Mac

La IA local en tu Mac, a fondo: memoria unificada, MLX vs GGUF, el modelo adecuado para tu chip, Ollama y LM Studio configurados para Apple Silicon.

  • Espacio en línea de por vida
  • PDF + archivos
  • Actualizaciones de por vida

En MLX, todo pasa por pip. El runtime mlx-lm gestiona la descarga desde Hugging Face, la conversión, la cuantización y la inferencia.

MLX
pip install mlx-lm

# Premier test : Qwen 3.5 4B 4-bit en une commande
mlx_lm.generate --model mlx-community/Qwen3.5-4B-Instruct-4bit \
  --prompt "Explique la mémoire unifiée Apple en 3 phrases."

Con llama.cpp, tienes tres opciones: compilar a partir del código fuente con Metal activado, usar Homebrew o emplear un wrapper como Ollama o LM Studio. Para comparar de forma honesta, se utiliza el binario compilado.

llama.cpp
brew install llama.cpp

# Inférence sur un modèle GGUF déjà téléchargé
llama-cli -m ./Qwen3.5-4B-Instruct-Q4_K_M.gguf \
  -p "Explique la mémoire unifiée Apple en 3 phrases." \
  -n 256 -ngl 99
→
ngl 99 = todo en GPU
En Mac, configura siempre la opción -ngl (número de capas en la GPU) en 99 o más. Todas las capas se ejecutan en la GPU integrada mediante Metal, y la memoria unificada hace que esto no tenga coste en ancho de banda.

#2. Tokens/segundo en M3 Max y M4 Pro

Aquí tienes órdenes de magnitud representativos en dos máquinas habituales en 2026: un MacBook Pro M3 Max de 64 GB (ancho de banda de 400 GB/s) y un Mac mini M4 Pro de 48 GB (273 GB/s). Los modelos se comparan con una cuantización equivalente —MLX de 4 bits frente a GGUF Q4_K_M—, con un prompt de 200 tokens y 256 tokens generados.

Qwen 3.5 4B — M3 Max
MLX de 4 bits: 150 tok/s · llama.cpp Q4_K_M: 135 tok/s. MLX lleva una ventaja de ~11 %.
Qwen 3.5 9B — M3 Max
MLX 4-bit: 72 tok/s · llama.cpp Q4_K_M: 66 tok/s. Diferencia ~9% a favor de MLX.
Gemma 4 12B — M3 Max
MLX 4-bit: 48 tok/s · llama.cpp Q4_K_M: 44 tok/s. MLX +9%.
Mistral Small 24B — M3 Max
MLX 4 bits: 24 tok/s · llama.cpp Q4_K_M: 22 tok/s. MLX +9%.
Qwen 3.8 27B — M3 Max
MLX 4 bits: 21 tok/s · llama.cpp Q4_K_M: 19 tok/s. MLX +10%.
Qwen 3.5 9B — M4 Pro
MLX 4 bits: 50 tok/s · llama.cpp Q4_K_M: 46 tok/s. MLX +9%.

El patrón es claro y reproducible: MLX gana entre un 8 % y un 15 % en la generación pura. La diferencia se debe a que los kernels Metal de MLX están escritos y optimizados directamente por Apple, con un conocimiento detallado del planificador de la GPU y de las cachés L1/L2. llama.cpp también utiliza kernels Metal, pero más genéricos.

!
El procesamiento del prompt puede invertir el veredicto
En el procesamiento del prompt inicial (prefill), llama.cpp con Flash Attention activado (-fa) suele igualar a MLX e incluso superarlo con contextos largos. Si introduces 16 k tokens en un sistema RAG, mide las dos fases por separado antes de decidir.

#3. Soporte para modelos Hugging Face

Es uno de los puntos en los que los dos ecosistemas se diferencian en la práctica. MLX tiene su propio formato de pesos (.safetensors con configuración MLX), llama.cpp utiliza GGUF.

MLX — disponibilidad
El grupo mlx-community en Hugging Face publica la mayoría de los modelos populares (Qwen 3.5/3.8, Gemma 4, Mistral, Granite 4.2) en versiones de 4 bits y 8 bits, a menudo durante la semana de lanzamiento.
MLX — modelos poco comunes
Para un fine-tune poco habitual o un modelo poco conocido, tendrás que convertirlo tú mismo con mlx_lm.convert. Conversión típica: de 2 a 10 minutos según el tamaño.
llama.cpp — disponibilidad
Los GGUF están por todas partes. Bartowski, TheBloke (archivos), Unsloth y los editores oficiales publican muchos modelos en formato GGUF antes incluso que en MLX.
llama.cpp — modelos muy recientes
Cuando se lanza una nueva arquitectura (p. ej., una MoE inédita o un mecanismo de atención exótico), llama.cpp debe implementarla en C++. Plazo típico: de unos días a 2 semanas. MLX, al estar basado en Python + Metal, a veces incorpora el soporte más rápido cuando Apple ya la ha preparado.
Convertir un modelo HF a MLX de 4 bits
mlx_lm.convert \
  --hf-path Qwen/Qwen3.5-9B-Instruct \
  --mlx-path ./qwen3.5-9b-mlx-4bit \
  -q --q-bits 4 --q-group-size 64

#4. Cuantizaciones disponibles

Es probablemente el tema en el que llama.cpp domina sin duda. GGUF ofrece una docena de variantes de cuantización (Q2_K, Q3_K_S/M/L, Q4_K_S/M, Q5_K_M, Q6_K, Q8_0, más los I-quants IQ2_XXS a IQ4_NL) que permiten ajustar finamente el equilibrio entre tamaño y calidad.

MLX
Cuantización de 4 bits, 6 bits y 8 bits. Parámetro principal: group-size (32, 64, 128). No hay equivalente directo de los K-quants mixtos (Q4_K_M conserva más precisión en ciertas capas).
llama.cpp
GGUF Q4_K_M (recomendado), Q5_K_M, Q6_K, Q8_0, FP16, más los I-quants para ir aún más bajo. Calibración posible mediante imatrix.
Calidad observada
A igual tamaño, GGUF Q4_K_M y MLX 4-bit ofrecen una perplejidad muy similar (diferencia < 1 %). Para que un modelo grande quepa en una RAM limitada (Qwen 3.8 27B en 16 GB), los I-quants de llama.cpp siguen ofreciendo un ajuste más fino.
i
Q4_K_M sigue siendo la referencia
Para la mayoría de los casos de uso, Q4_K_M en llama.cpp y la cuantización a 4 bits con un tamaño de grupo de 64 en MLX dan el mismo resultado en la práctica. La diferencia solo es visible si haces pruebas precisas con MMLU o mediciones precisas de perplejidad.

#5. Memoria unificada: ¿quién la aprovecha mejor?

En los Mac de la serie M, la CPU y la GPU comparten la misma RAM. No hay copias ni transferencias por PCIe, solo una misma reserva de memoria. Es la ventaja estructural de los chips de Apple para la inferencia de LLM, y ambos frameworks se benefician de ella, aunque de distinta manera.

MLX
Diseñado desde el principio para la memoria unificada. Los tensores se alojan en un espacio de memoria direccionable tanto por la CPU como por la GPU, sin distinción. Conversión sin copia entre NumPy y MLX. Este es el principal argumento arquitectónico de Apple.
llama.cpp Metal
Asigna objetos MTLBuffer compartidos. Funciona, pero añade una capa de abstracción. Para modelos que superan la VRAM asignada por defecto, a veces es necesario ajustar manualmente el límite mediante sudo sysctl iogpu.wired_limit_mb.
Grandes modelos con 64 GB
En 2026, incluso el modelo generalista líder Qwen 3.8 27B pesa solo ~18 GB en 4 bits: 64 GB de RAM unificada dejan ample espacio para un gran MoE como Qwen 3.6 35B-A3B (~23 GB) o para la misma versión en Q8 para calidad máxima. En 128 GB (M3 Max de especificaciones máximas o M2 Ultra), puedes cargar varios modelos simultáneamente sin comprometerlos.
→
Aumentar el límite de VRAM en macOS
Por defecto, macOS reserva aproximadamente el 75 % de la RAM para la GPU. En una máquina de 64 GB, eso equivale a unos 48 GB utilizables. Para aumentar el límite a 56 GB: sudo sysctl iogpu.wired_limit_mb=57344 — útil para cargar un MoE grande de 35B con una cuantización de mayor precisión (Q5_K_M o MLX de 6 bits) o varios modelos al mismo tiempo.

#6. Integración en Python

Si desarrollas un agente, un pipeline RAG, o instrumentas tu LLM con LangChain / LlamaIndex / tu propio código, la experiencia de uso en Python cuenta tanto como los tokens/segundo.

MLX — inferencia en flujo
from mlx_lm import load, stream_generate

model, tokenizer = load("mlx-community/Qwen3.5-9B-Instruct-4bit")

prompt = tokenizer.apply_chat_template(
    [{"role": "user", "content": "Résume MLX en 3 phrases."}],
    tokenize=False, add_generation_prompt=True,
)

for chunk in stream_generate(model, tokenizer, prompt, max_tokens=256):
    print(chunk.text, end="", flush=True)

En llama.cpp, la integración con Python se realiza a través de llama-cpp-python (bindings oficiales). La API es más verbosa, más cercana a C++, pero es compatible con OpenAI una vez que el servidor está en marcha.

llama-cpp-python
from llama_cpp import Llama

llm = Llama(
    model_path="./Qwen3.5-9B-Instruct-Q4_K_M.gguf",
    n_gpu_layers=-1,   # tout sur Metal
    n_ctx=8192,
    flash_attn=True,
)

for chunk in llm.create_chat_completion(
    messages=[{"role": "user", "content": "Résume llama.cpp en 3 phrases."}],
    stream=True,
):
    delta = chunk["choices"][0]["delta"].get("content", "")
    print(delta, end="", flush=True)
MLX — comodidad
API muy limpia, sintaxis similar a NumPy, integración nativa con HF Hub. Para un científico de datos, empezar a usarla resulta inmediato.
MLX — limitaciones
Aún no hay un endpoint oficial integrado compatible con OpenAI. Para servir un modelo a varios clientes, debes construir tu propio wrapper con FastAPI.
llama.cpp — comodidad
La API de Python es aceptable, pero el uso real en producción pasa por llama-server (binario), que expone de forma nativa el endpoint /v1/chat/completions compatible con OpenAI.
llama.cpp — límites
El paquete wheel de llama-cpp-python debe recompilarse con la opción correcta para Metal (CMAKE_ARGS="-DGGML_METAL=on" pip install llama-cpp-python --force-reinstall --no-cache-dir). Esto complica la instalación.

#7. Ecosistema y herramientas

Más allá del motor de ejecución en sí, es el ecosistema el que determina lo que podrás hacer en la práctica.

Ollama
Basado en llama.cpp. La forma más sencilla de tener un LLM que funcione en Mac con una API compatible con OpenAI en localhost:11434.
LM Studio
Soporta los dos motores desde 2025: llama.cpp por defecto, MLX como opción para modelos compatibles. Cambio en un clic.
Fine-tuning LoRA
MLX incluye mlx_lm.lora de forma nativa, con una implementación muy cuidada que funciona en la GPU integrada sin ajustes complicados. llama.cpp no permite hacer fine-tuning: hay que recurrir a Unsloth o MLX.
Servir un modelo
llama.cpp gana sin discusión con llama-server: soporte para múltiples clientes, procesamiento por lotes, slots y compatibilidad con OAI. En cuanto a MLX, mlx_lm.server existe desde 2025, pero sigue siendo básico.
Visión y audio
MLX tiene extensiones (mlx-vlm, mlx-whisper) bien mantenidas. llama.cpp cubre la visión mediante los modelos LLaVA / Qwen-VL con soporte que depende del build.

#Veredicto por caso de uso

Quieres el máximo de tokens por segundo en chat local
MLX. Un 10 % más gratis, y la diferencia se amplía con los modelos grandes. Sobre todo en 4 bits.
Quieres servir un endpoint a varios clientes (equipo, aplicación)
llama.cpp (llama-server o Ollama). Con múltiples slots, procesamiento por lotes y compatibilidad con OpenAI; estable desde hace mucho tiempo.
Estás probando una decena de modelos diferentes por semana
llama.cpp. El ecosistema GGUF es imbatible por la variedad y la actualidad de sus cuantizaciones.
Desarrollas un proyecto en Python (agente, RAG, pipeline)
MLX si todo es local y solo para Mac. llama-cpp-python o un cliente Ollama si quieres código portátil para Linux/Mac.
Quieres hacer fine-tuning de un modelo de 7-13B en tu Mac
MLX. mlx_lm.lora funciona muy bien en M3 Max / M4 Pro con 32 GB+.
Estás empezando y solo quieres un LLM que funcione
Ollama (por tanto llama.cpp). Un comando, ya está hecho.
i
La verdadera respuesta: usa ambos
En un Mac, nada impide tener Ollama ejecutándose como demonio para el uso diario (Open WebUI, Continue.dev, API local) y MLX en un entorno virtual de Python para tareas de investigación o benchmarks. No interfieren entre sí y cada uno destaca en su campo.

#Para ir más allá

Algunas lecturas relacionadas para profundizar en el tema:

¿Esta guía te ha ayudado?

¿Un comentario, un error, una precisión? Avísanos, eso mejora la guía para todos.