Ajusta la inferencia local en tu tarjeta NVIDIA: AITune para modelos PyTorch y los tres ajustes que importan en los LLM
Al terminar este artículo habrás medido tus propios tokens por segundo, habrás cambiado los tres ajustes que más mueven ese número y sabrás si el kit AITune de NVIDIA tiene sitio en tu equipo. El punto de partida más barato es cualquier tarjeta NVIDIA con capacidad de cómputo 5.0 o superior, que llega hasta la serie GTX 900, o una Jetson Orin Nano Super de unos 250 EUR.
Primero, una corrección. La versión anterior de este artículo era una reescritura automática de una nota de prensa. Esto es lo que hemos verificado esta semana. AITune existe: NVIDIA lo publicó el 10 de abril de 2026 con licencia Apache 2.0 en github.com/ai-dynamo/aitune, y MarkTechPost cubrió el lanzamiento. Compara varios motores de inferencia sobre tu modelo PyTorch y tu GPU, comprueba que las salidas siguen coincidiendo y se queda con el más rápido. Lo que no es: un servidor de modelos de lenguaje. El propio README de NVIDIA dice que, si un framework de servicio dedicado soporta tu modelo, uses TensorRT-LLM, vLLM o SGLang. Es decir: AITune para visión, voz, embeddings y difusión escritos en PyTorch; Ollama, vLLM o TensorRT-LLM para los LLM. Este artículo cubre las dos mitades.
Qué necesitas
- Una GPU NVIDIA con capacidad de cómputo 5.0 o superior y driver 550 o más reciente, que es el requisito que publica Ollama. Una RTX 3060 de 12 GB de segunda mano, una RTX 4060 de portátil con 8 GB o una Jetson Orin Nano Super valen.
- Ollama instalado desde ollama.com/download y un modelo descargado, por ejemplo
ollama pull qwen2.5-coder:7b(4,7 GB) oollama pull qwen2.5:3b(1,9 GB) en la Jetson. - Solo para AITune: Linux (Ubuntu 22.04 o superior), Python 3.10+, PyTorch 2.8+ y TensorRT 10.3+ si quieres ese motor. Son los requisitos del README; no menciona Jetson, así que comprueba la versión de TensorRT de tu JetPack antes de probar ese motor allí.
- Treinta minutos. Sin cuenta y sin clave de API.
Paso 1: mide antes de tocar nada
La API de Ollama devuelve el número de tokens y el tiempo de generación con cada respuesta. Esa es tu herramienta de medida.
curl -s localhost:11434/api/generate -d '{
"model": "qwen2.5-coder:7b",
"prompt": "Escribe una función en Python que valide un NIF español.",
"stream": false
}' | python3 -c "import json,sys; d=json.load(sys.stdin); \
print(d['eval_count'], 'tokens en', round(d['eval_duration']/1e9,2), 's =', \
round(d['eval_count']/(d['eval_duration']/1e9),1), 'tok/s; carga', round(d['load_duration']/1e9,2), 's')"
En nuestra estación de trabajo (NVIDIA GB10, 128 GB de memoria unificada, 9 de septiembre de 2026) esto imprimió 231 tokens en 6,92 s = 33,4 tok/s; carga 10,7 s. La segunda llamada mostró carga 0,2 s: el modelo ya estaba residente. Si ollama ps muestra 100% CPU en la columna Processor, la GPU no se ha detectado. Revisa nvidia-smi y la versión del driver antes de seguir.
Paso 2: los tres ajustes de Ollama
| Ajuste | Dónde | Por defecto | Qué hace |
|---|---|---|---|
num_ctx / OLLAMA_CONTEXT_LENGTH | por petición o variable del servidor | 4096 tokens | Tamaño de la ventana de contexto. La memoria crece con ella. |
OLLAMA_KV_CACHE_TYPE | variable del servidor | f16 | q8_0 usa aproximadamente la mitad de memoria de caché; q4_0, un cuarto. |
OLLAMA_FLASH_ATTENTION | variable del servidor | automático | Reduce el uso de memoria al crecer el contexto; 1 lo fuerza. |
num_gpu | por petición o Modelfile | todas las capas | Capas descargadas en la GPU. 0 fuerza la CPU. |
keep_alive | por petición | 5 minutos | Cuánto tiempo sigue cargado el modelo. -1 lo mantiene siempre. |
OLLAMA_NUM_PARALLEL | variable del servidor | 1 | Peticiones atendidas a la vez por modelo. |
Valores y defectos según las preguntas frecuentes de Ollama.
1. El contexto es el ajuste de memoria. Cargamos el mismo qwen2.5-coder:7b dos veces y leímos ollama ps: 4,7 GB residentes con num_ctx 4096 y 6,6 GB con 32768. Fija el contexto que necesita la tarea, no el máximo que soporta el modelo. Por petición:
curl -s localhost:11434/api/generate -d '{"model":"qwen2.5-coder:7b","prompt":"...","stream":false,"options":{"num_ctx":8192}}'
2. Cuantiza la caché cuando la memoria aprieta. En una instalación con systemd, ejecuta systemctl edit ollama.service y añade bajo [Service]:
Environment="OLLAMA_KV_CACHE_TYPE=q8_0"
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_CONTEXT_LENGTH=8192"
Después, systemctl daemon-reload && systemctl restart ollama. En una tarjeta de 8 GB, esto suele ser la diferencia entre que un modelo de 7B quepa entero en la GPU o se desborde a la CPU.
3. Nunca aceptes un reparto CPU/GPU. Forzamos "num_gpu": 0 con el mismo prompt y obtuvimos 5,2 tok/s de nuestra CPU ARM de 20 núcleos frente a 33 tok/s en la GPU. Si ollama ps muestra un reparto tipo 40%/60% CPU/GPU, elige una cuantización menor o un modelo más pequeño en lugar de convivir con el reparto. Nuestra guía de cuantización explica el intercambio.
Paso 3: cuando varias personas comparten el modelo, los flags de vLLM
Ollama es el primer servidor correcto. Cuando un equipo lo usa a la vez, el batching continuo de vLLM se gana su sitio. Instalación y arranque, según el inicio rápido de vLLM:
uv pip install vllm --torch-backend=auto
vllm serve Qwen/Qwen2.5-7B-Instruct \
--max-model-len 8192 \
--gpu-memory-utilization 0.85 \
--enable-prefix-caching
Los flags que importan, según la referencia de argumentos del motor: --max-model-len limita el contexto para que la caché KV se planifique para lo que usas; --gpu-memory-utilization (0,92 por defecto) debe bajar cuando la tarjeta se comparte con cualquier otra cosa; --enable-prefix-caching reutiliza el cálculo de los prompts de sistema repetidos; --kv-cache-dtype permite cuantizar la caché; --max-num-seqs acota las secuencias simultáneas. Nosotros servimos Qwen2.5-7B-Instruct así en el puerto 8200, junto a Ollama en el 11434, y enrutamos entre ambos con LiteLLM.
Paso 4: AITune para un modelo PyTorch
Si ejecutas un detector, un modelo de transcripción, un modelo de embeddings o una pipeline de difusión en tu propio código PyTorch, aquí es donde encaja AITune.
pip install --extra-index-url https://pypi.nvidia.com aitune
import aitune.torch as ait
modules_info = ait.inspect(model, dataset) # localiza los módulos ajustables
modules = modules_info.get_modules()
model = ait.wrap(model, modules)
ait.tune(model, dataset) # prueba cada motor y se queda con el más rápido
ait.save(model, "tuned.ait") # reutilízalo en el siguiente arranque, sin calentamiento
# después: ait.load(model, "tuned.ait")
Para una primera prueba sin tocar código, define AUTOWRAPT_BOOTSTRAP=aitune_enable_jit_tuning en el entorno y ejecuta tu script; AITune ajusta los módulos en su primera llamada. Los motores que prueba son TensorRT, Torch-TensorRT (JIT y AOT), TorchAO, Torch Inductor (JIT y AOT) y ONNX Runtime, según la documentación de motores. Tú aportas un conjunto de datos pequeño para que compruebe que las salidas ajustadas coinciden con las originales. No hemos medido AITune en una Jetson, así que no afirmamos ninguna velocidad allí.
Paso 5: TensorRT-LLM cuando un modelo sirve a muchos usuarios
TensorRT-LLM se instala con pip install tensorrt-llm y se sirve con trtllm-serve. Su README lista Blackwell, H100, H200 y L4 como soportadas; la Jetson AGX Orin tiene una rama dedicada v0.12.0-jetson sobre JetPack 6.1. En una Orin Nano, quédate con Ollama. El coste es una compilación de motor por modelo y por GPU, que compensa cuando el modelo es fijo y el tráfico es alto.
Qué medimos
| Máquina | Modelo | Ajuste | Resultado | Fecha |
|---|---|---|---|---|
| Estación GB10 | qwen2.5-coder:7b | GPU, num_ctx 4096 | 33,4 tok/s, 4,7 GB residentes | 09-09-2026 |
| Estación GB10 | qwen2.5-coder:7b | GPU, num_ctx 32768 | 6,6 GB residentes | 09-09-2026 |
| Estación GB10 | qwen2.5-coder:7b | num_gpu 0 (solo CPU) | 5,2 tok/s | 09-09-2026 |
| Estación GB10 | llama3.1:8b | GPU, valores por defecto | 37,8 tok/s | 08-09-2026 |
| Jetson Orin Nano Super (terceros) | modelos de 3B | GPU | 12 a 18 tok/s (Edge AI Vision) | 01-2026 |
Una nota honesta: nuestra GPU está compartida con unos cincuenta servicios más. Durante una ráfaga de otro trabajo, el mismo modelo de 7B midió entre 12 y 25 tok/s. Mide en una máquina tranquila y fija OLLAMA_MAX_LOADED_MODELS para que un segundo modelo no pueda expulsar al que estás cronometrando.
Dónde encaja esto, y los límites
Estos ajustes no hacen más listo a un modelo de 7B; hacen que quepa y responda más rápido en el hardware que ya tienes. Para un negocio de dos personas, el paso 2 es todo el trabajo. Para un equipo, añade el paso 3. Usa AITune solo si tienes código PyTorch propio que ejecutar. La nube sigue siendo la opción correcta para las tareas que necesitan un modelo de primera línea; el cálculo del punto de equilibrio te dice qué parte es esa.
Siguientes pasos
- Elige la máquina: Mejores dispositivos para IA local en 2026.
- Mete un modelo más grande en menos memoria: La cuantización explicada.
- Pon el servidor ajustado a trabajar: Cómo implementar IA en una empresa española.
Trabaja con nosotros
Ajustamos la inferencia en nuestras propias máquinas cada semana y dejamos a los clientes los números medidos, no estimaciones. Si quieres que midamos y configuremos tu tarjeta, escríbenos o mira cómo trabajamos en consultoría.