La promesa de ejecutar Inteligencia Artificial de forma local y 100% privada es sumamente atractiva. Sin embargo, cuando no contamos con una GPU dedicada de última generación, la realidad del rendimiento puede ser frustrante. En esta bitácora documento mi experiencia explorando Jan AI y Ollama, los desafíos de rendimiento que enfrenté en mi hardware de consumo y cómo logré una integración fluida con mi entorno de desarrollo utilizando un VPS con Ubuntu.
1. El punto de partida y el hardware disponible
Mi objetivo inicial era probar Jan AI, una alternativa open-source a ChatGPT que se ejecuta completamente offline. Jan AI utiliza llama.cpp como motor de inferencia y expone una API compatible con OpenAI en https://localhost:1337. Por defecto, organiza sus datos de la siguiente manera:
- Modelos:
/models/ - Historial de chats:
/threads/ - Logs del sistema:
/logs/ - Configuraciones de asistentes:
/assistants/
Sin embargo, mi hardware local es bastante limitado para tareas de IA:
- CPU: Intel i5-12400 (6 núcleos, 12 hilos, 2.5 GHz)
- RAM: 16 GB DDR4
- Almacenamiento: 500 GB SSD NVMe
- GPU: Sin GPU dedicada (solo los gráficos integrados del procesador)
Ante la falta de potencia gráfica, me planteé la posibilidad de usar clústeres para distribuir la carga de Jan AI. Tras investigar, descubrí que aunque llama.cpp puede compilarse para sistemas distribuidos (usando MPI o DeepSpeed), Jan AI como aplicación de escritorio no soporta clustering de forma nativa. Para un entorno de desarrollo personal, la complejidad técnica de montar un clúster no compensa el esfuerzo.
2. El choque con la realidad: Jan AI vs. Ollama
Para decidir qué herramienta se adaptaba mejor a mis necesidades de integración (especialmente con IDEs), comparé Jan AI con Ollama. Aquí un resumen de mis conclusiones:
- Jan AI: Excelente interfaz gráfica para principiantes, ideal para chatear de forma offline, pero con integraciones limitadas y mayor consumo de recursos en CPU.
- Ollama: Funciona sin interfaz gráfica por defecto (CLI/API), es extremadamente eficiente en el uso de memoria RAM, es más rápido en CPU y es el estándar para integrarse con herramientas externas como VSCode.
3. El error de escala: Ejecutando un modelo de 20B en CPU
En mi primera prueba local con Ollama, cometí el error de descargar el modelo gpt-oss:20b. Al ejecutar un prompt básico, la respuesta tardó 60.7 segundos en generarse.
Para solucionar esto, eliminé el modelo pesado utilizando la terminal:
ollama rm gpt-oss
4. Migrando la infraestructura a un VPS con Ubuntu
Para mejorar el rendimiento y centralizar el servicio, decidí probar Ollama en un VPS con Ubuntu que tenía disponible. Sus características eran:
- CPU: Intel Core (Broadwell, sin TSX, IBRS) de 8 núcleos
- RAM: 23.5 GB disponibles
- Disco: 1.15 TB SSD
Al intentar instalar Ollama con el script oficial, la descarga del binario de Linux (el "Linux amd64 bundle", que pesa entre 50 y 120 MB) se detuvo en el 0.5% durante varios segundos:
curl -fsSL https://ollama.com/install.sh | sh
>>> Installing ollama to /usr/local
>>> Downloading Linux amd64 bundle
0.5%^C
Para descartar que mi VPS tuviera una conexión de red deficiente, realicé dos pruebas rápidas de descarga y latencia:
root@web:~# curl -I https://ollama.com
HTTP/2 200
...
root@web:~# curl -LO https://ash-speed.hetzner.com/100MB.bin
100 100M 100 100M 0 0 6999k 0 0:00:14 0:00:14 --:--:-- 7340k
La descarga de prueba de Hetzner bajó 100 MB en solo 14 segundos (~7 MB/s). Esto demostró que el VPS tenía una conexión excelente y que el cuello de botella era una congestión temporal de red o ruteo hacia la CDN de Ollama (Cloudflare).
Poco después, reintenté la instalación y se completó correctamente sin problemas:
root@web:~# curl -fsSL https://ollama.com/install.sh | sh
>>> Downloading Linux amd64 bundle
######################################################################## 100.0%
>>> Creating ollama systemd service...
>>> Enabling and starting ollama service...
WARNING: No NVIDIA/AMD GPU detected. Ollama will run in CPU-only mode.
5. Pruebas de rendimiento y optimización en el VPS
Con Ollama listo, decidí probar el modelo Phi-2 (2.7B), que ofrece un gran balance entre calidad y ligereza para entornos basados únicamente en CPU. Realicé una petición POST directa a la API local de Ollama para medir el tiempo de respuesta:
root@web:~# time curl -s -X POST http://127.0.0.1:11434/api/generate \
-d \'{
"model": "phi",
"prompt": "¿Qué es el aprendizaje automático?"
}\' > /dev/null
real 0m14.448s
user 0m0.005s
sys 0m0.025s
Un tiempo de 14.4 segundos para una respuesta completa en CPU es aceptable, pero se puede optimizar significativamente aplicando las siguientes técnicas:
A. Limitar la cantidad de tokens generados
Por defecto, el modelo puede extenderse demasiado. Podemos limitar la respuesta agregando el parámetro num_predict en las opciones de la petición:
time curl -s -X POST http://127.0.0.1:11434/api/generate \
-d \'{
"model": "phi",
"prompt": "¿Qué es el aprendizaje automático?",
"options": {
"temperature": 0.7,
"num_predict": 64
}
}\' > /dev/null
Esto limita la salida a unos 64 tokens (~45 palabras), reduciendo el tiempo de espera a un rango de entre 4 y 8 segundos.
B. Desactivar el Streaming
Si no necesitamos ver el texto palabra por palabra en tiempo real, desactivar el streaming ("stream": false) permite que Ollama entregue la respuesta completa de golpe, lo que a veces agiliza el proceso en conexiones remotas.
C. Automatizar las pruebas de rendimiento
Para comparar de manera científica el rendimiento de diferentes modelos en el VPS, escribí este script en Bash que mide los tiempos de respuesta y los exporta a un archivo CSV:
#!/bin/bash
MODELS=("phi" "tinyllama")
PROMPT="¿Qué es el aprendizaje automático?"
OUTFILE="resultados.csv"
echo "Modelo,Tiempo (s)" > $OUTFILE
for MODEL in "${MODELS[@]}"; do
echo "Probando modelo: $MODEL"
START=$(date +%s.%N)
curl -s -X POST http://127.0.0.1:11434/api/generate \
-d "{\"model\": \"$MODEL\", \"prompt\": \"$PROMPT\", \"options\": {\"num_predict\": 64}}" > /dev/null
END=$(date +%s.%N)
TIME=$(echo "$END - $START" | bc)
echo "$MODEL,$TIME" >> $OUTFILE
done
echo "Resultados guardados en $OUTFILE"
6. Integración con el IDE (VSCode + Continue)
El verdadero valor de tener Ollama corriendo en el VPS es poder usarlo como asistente de código local (un reemplazo gratuito y privado de GitHub Copilot). Para lograrlo:
- Instalé la extensión Continue en VSCode.
- En la configuración de Continue (
config.json), definí el proveedor comoollamay apunté al endpoint de mi VPS:
{
"models": [
{
"title": "Ollama Phi-2",
"provider": "ollama",
"model": "phi",
"apiBase": "http://[IP_DEL_VPS]:11434"
}
]
}
La historia detrás de la nota
Ejecutar modelos de lenguaje locales en CPU es un ejercicio de paciencia y optimización. Al final, entendí que no se trata de usar el modelo más grande, sino el más adecuado para el hardware que tienes a mano.