12 de noviembre de 2026 · Equipo de VRAMfarm
vLLM, Ollama o llama.cpp: con cuál ejecutar tu LLM, y los comandos
Si eres la única persona que habla con el modelo, los tres van más o menos igual de rápido y Ollama es el que menos trabajo da: un comando de instalación y un ollama run. Si un script lanza 50 peticiones en paralelo o diez compañeros usan el mismo modelo, vLLM saca de la misma tarjeta unas 5–10 veces más tokens por segundo en total, y la diferencia crece con la carga. llama.cpp, el motor del que nació Ollama, es el que debes elegir cuando quieres controlar cada byte: los archivos de cuantización exactos, los tipos de caché, qué capas se quedan en la CPU.
Los tres funcionan en un servidor alquilado con una imagen vacía de PyTorch, y los tres ofrecen una API compatible con OpenAI. Las diferencias están en el procesamiento por lotes, los formatos de archivo y cómo tratan la memoria.
La versión corta
| Ollama | llama.cpp | vLLM | |
|---|---|---|---|
| Lo mejor para | Una persona, arranque rápido, un chat privado | Control, tamaños raros, modelos más grandes que la tarjeta | Una API para apps, varios usuarios, trabajos por lotes |
| Instalación | Un script | Compilar con CUDA | pip install vllm, ajustado a la versión de CUDA |
| Formatos de modelo | GGUF, de su propia biblioteca o de Hugging Face | GGUF | BF16 original, FP8, AWQ, GPTQ, bitsandbytes, NVFP4 en Blackwell |
| Memoria | Usa lo que necesita el modelo; si falta, desborda a la CPU | Exactamente lo que fijes; descarga por capas | Reserva el 90 % de la tarjeta al arrancar |
| Peticiones en paralelo | De una a unas pocas a la vez (OLLAMA_NUM_PARALLEL) |
Slots, batching continuo | Batching continuo, de decenas a cientos |
| API compatible con OpenAI | Sí, puerto 11434, /v1 |
Sí, llama-server |
Sí, /v1 |
| Varias GPU | Reparte capas | Reparte capas o filas | Paralelismo de tensor y de pipeline |
| Arranque tras la descarga | Segundos | Segundos | 1–5 minutos |
Ollama está construido sobre la misma base GGML que llama.cpp, así que sus formatos de archivo, sus niveles de cuantización y su velocidad con un solo usuario son parecidos. Lo que añade Ollama es comodidad: una biblioteca de modelos con nombres cortos, detección automática de la GPU y modelos que se cargan cuando se piden. Lo que esconde es el control, y lo notas el día en que un modelo va lento y necesitas saber por qué.
Velocidad: una conversación frente a cincuenta
En una sola conversación, generar texto está limitado por el ancho de banda de la memoria: por cada token nuevo, la tarjeta lee el modelo entero una vez. Importa menos el motor que el tamaño del archivo. Eso lleva a un resultado que la gente no espera: vLLM sirviendo un modelo de 8B en su BF16 original (16 GB) es más lento para un usuario que Ollama con un archivo de 4 bits (5 GB), simplemente porque lee el triple de bytes por token.
El procesamiento por lotes cambia el panorama. vLLM lee los pesos una vez para todo un lote de peticiones y va metiendo peticiones nuevas en el lote en marcha a medida que terminan las antiguas, así que la salida total crece casi en línea recta con los usuarios hasta que se agotan el cálculo o la memoria de caché. Rangos para planificar con un modelo de 8B en una RTX 4090, sacados de cuentas de ancho de banda y de lo que cuenta la comunidad, no de benchmarks propios:
| Configuración | 1 usuario | 16 usuarios a la vez, total | Por usuario con 16 |
|---|---|---|---|
| Ollama, Q4_K_M | 100–150 tokens/s | 100–300 (atiende a uno o a unos pocos a la vez, el resto espera) | lento e irregular |
| llama.cpp, Q4_K_M, 16 slots | 100–150 | 300–700 | 20–45 |
| vLLM, BF16 | 45–60 | 600–1200 | 40–75 |
| vLLM, AWQ de 4 bits | 100–140 | 800–1500 | 50–90 |
La velocidad con un solo usuario sobra en todas las filas: la gente lee a 5–8 tokens por segundo. La diferencia aparece con carga: un bot de soporte, una herramienta interna para un equipo o un trabajo por lotes que clasifica 100 000 descripciones de producto durante la noche. Para eso, vLLM es el motor adecuado, y el coste por millón de tokens muestra lo que eso supone en la factura.
Hay otros dos motores que conviene conocer. SGLang es una alternativa cercana a vLLM, con formatos parecidos y un servidor compatible con OpenAI, y destaca cuando muchas peticiones comparten un prefijo largo. TensorRT-LLM exprime al máximo las tarjetas de centro de datos de NVIDIA, pero exige más configuración. Si estás eligiendo entre los tres primeros, no necesitas ninguno de los dos.
Cómo trata cada uno la memoria
La mayoría de las historias de «iba lento» y «se colgó» salen de aquí.
Ollama desborda a la CPU sin avisarte. Si el modelo y su contexto no caben, Ollama pasa algunas capas a la RAM del sistema y sigue funcionando a una fracción de la velocidad. En nuestra propia prueba, Qwen3 32B en una tarjeta de 24 GB con un contexto de 32k mandó el 18 % de sus capas a la CPU y bajó de unos 30 tokens por segundo a 2,5. Ejecuta ollama ps: la columna PROCESSOR debería decir 100% GPU. Fija el contexto con OLLAMA_CONTEXT_LENGTH, y recuerda que OLLAMA_NUM_PARALLEL multiplica la caché: cuatro slots en paralelo con 8k de contexto necesitan la caché de 32k.
llama.cpp hace exactamente lo que le dices. -ngl fija cuántas capas van a la GPU (99 significa todas), -c fija el contexto total y -np el número de slots en paralelo que lo comparten: -c 32768 -np 4 da a cuatro usuarios unos 8k a cada uno. En modelos mixture-of-experts que no caben, --n-cpu-moe deja parte de los pesos de los expertos en la RAM del sistema mientras las capas compartidas se quedan en la GPU, y así los MoE grandes funcionan en tarjetas más pequeñas a una velocidad utilizable.
vLLM reserva la memoria de entrada. Por defecto se queda con el 90 % de la tarjeta al arrancar y llena con caché KV lo que no usan los pesos. Después comprueba que cabe una petición con el contexto máximo, y si no cabe, se niega a arrancar; el error indica el contexto más grande que cabría. Fija --max-model-len en lo que de verdad necesites, y baja --gpu-memory-utilization si otra cosa tiene que compartir la tarjeta. La guía de CUDA out of memory cubre el resto.
Ollama: comandos de arranque
En un servidor PyTorch vacío, en el terminal de Jupyter o por SSH:
curl -fsSL https://ollama.com/install.sh | sh
OLLAMA_CONTEXT_LENGTH=8192 OLLAMA_FLASH_ATTENTION=1 OLLAMA_KV_CACHE_TYPE=q8_0 \
ollama serve > /workspace/ollama.log 2>&1 &
ollama run qwen3:8b
También funciona cualquier GGUF de Hugging Face: ollama run hf.co/<user>/<repo>:Q4_K_M. La API escucha en el puerto 11434:
curl http://localhost:11434/v1/chat/completions -H "Content-Type: application/json" \
-d '{"model": "qwen3:8b", "messages": [{"role": "user", "content": "Hello"}]}'
Si lo único que quieres es una ventana de chat, no necesitas nada de esto: la app ChatGPT privado lista para usar instala por sí sola Ollama, un modelo Qwen3 o MiMo y Open WebUI, como se explica en tu propio ChatGPT con Open WebUI.
llama.cpp: compila una vez y ejecuta
llama.cpp hay que compilarlo con CUDA. La imagen del servidor trae el runtime de CUDA, pero no el compilador, así que instala primero el toolkit de NVIDIA. Descarga unos pocos GB, que cuentan como tráfico, y la compilación tarda 5–15 minutos:
wget -q https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
dpkg -i cuda-keyring_1.1-1_all.deb && apt-get update -qq
apt-get install -y -qq cuda-toolkit-12-8 cmake git build-essential
export PATH=/usr/local/cuda-12.8/bin:$PATH
git clone https://github.com/ggml-org/llama.cpp /workspace/llama.cpp && cd /workspace/llama.cpp
cmake -B build -DGGML_CUDA=ON && cmake --build build --config Release -j
Después descarga un GGUF y arranca el servidor con cuatro slots en paralelo:
pip install -U huggingface_hub
hf download <user>/<repo>-GGUF <model>-Q4_K_M.gguf --local-dir /workspace/models
./build/bin/llama-server -m /workspace/models/<model>-Q4_K_M.gguf \
-ngl 99 -c 32768 -np 4 --flash-attn on --host 127.0.0.1 --port 8081
En nuestros servidores, el puerto 8080 lo ocupa Jupyter; de ahí el 8081. llama-server sirve la API al estilo de OpenAI en /v1 y una página de chat sencilla en la raíz. Si vas a volver a usar llama.cpp, conserva la carpeta compilada /workspace/llama.cpp en la carpeta guardada en vez de compilar cada vez.
vLLM: una API en dos comandos
pip install "vllm==0.11.0" "transformers>=4.56,<5" # compilado para CUDA 12.8
vllm serve Qwen/Qwen3-8B --max-model-len 16384 \
--host 0.0.0.0 --port 8000 --api-key change-me > /workspace/vllm.log 2>&1 &
Un simple pip install vllm trae la versión más reciente con su propia compilación de PyTorch, y en otoño de 2026 esa compilación apunta a una CUDA más nueva de la que admiten los drivers de muchas máquinas, así que el motor no arranca. Por eso el comando de arriba fija vLLM 0.11.0 (PyTorch 2.8, CUDA 12.8), la versión que usa nuestro servidor de vLLM; en una máquina cuya ficha del catálogo muestre CUDA 13 o posterior puedes coger una versión más reciente. Comprueba la versión de CUDA que se muestra antes de lanzar; en versión del driver de CUDA incompatible se explica cómo leer esas cifras. El servidor de vLLM listo para usar se salta este paso: vLLM viene instalado en una versión que encaja con la máquina y arranca por sí solo un modelo Qwen de 7B. Para servir otro modelo ahí, ejecuta pkill -f "vllm serve" y lanza tu propio comando en el puerto 8000.
Desde tu código, usa el cliente estándar de OpenAI con tu propia dirección:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="change-me")
r = client.chat.completions.create(model="Qwen/Qwen3-8B",
messages=[{"role": "user", "content": "Summarise this ticket: ..."}])
print(r.choices[0].message.content)
Las mismas líneas, con otra URL base, conectan un bot de Telegram, un pipeline de RAG o una app existente escrita para OpenAI.
Acceder a la API desde fuera y mantenerla en marcha
Un servidor no tiene IP pública propia; SSH, Jupyter y las apps pasan por nuestra dirección con puertos asignados a ese servidor. En el servidor de vLLM, el puerto 8000 ya está publicado, y el panel muestra la dirección de la API. En un servidor PyTorch vacío solo están publicados SSH y Jupyter, así que llega a Ollama o a llama.cpp con un túnel SSH desde tu ordenador: ssh -p <port> -L 8081:localhost:8081 root@<address> (el puerto y la dirección están en la ficha del servidor; la guía de claves SSH te ayuda a configurar la clave), y luego usa http://localhost:8081. Una imagen de Docker propia puede publicar su propio puerto. Docker dentro del servidor no está disponible, y por eso todos los comandos de aquí instalan con pip o con un script.
Todo lo que sea accesible desde fuera necesita una clave. vLLM acepta --api-key, llama.cpp también acepta --api-key, y Ollama no tiene clave propia, así que mantenlo detrás de un túnel.
Arranca los servidores que vayan a funcionar mucho rato con nohup ... & y un archivo de log, como arriba, o dentro de tmux (apt-get install -y tmux y luego tmux new -s llm), para que sigan funcionando cuando cierres el navegador o la sesión SSH. Se detienen con el servidor: la facturación termina en el mismo minuto en que pulsas Detener, y el siguiente lanzamiento empieza con un disco limpio, salvo lo que hayas conservado en la carpeta guardada.