Por qué un servidor MLflow
Ejecutado en local, MLflow escribe sus resultados en una carpeta mlruns de tu equipo: nadie más los ve, y desaparecen con la máquina. Un servidor de seguimiento lo cambia todo. Cada notebook, cada script de entrenamiento y cada miembro del equipo envía sus ejecuciones al mismo sitio, y la interfaz las compara lado a lado.
El mismo servidor aloja el registro de modelos — la lista de modelos validados y versionados, con un alias para el que está en producción — y, para la IA generativa, las trazas de tus llamadas a los modelos de lenguaje.
Lo que aporta MLflow
- Seguimiento de experimentos — parámetros, métricas y artefactos de cada ejecución, filtrados y comparados en la interfaz.
- Registro de modelos — versiones, alias e historial, para saber exactamente qué funciona en producción.
- Trazas LLM — entradas, salidas, latencia y pasos de cada petición de tus aplicaciones de IA generativa.
- Artefactos servidos por el servidor — archivos, gráficos y modelos subidos por HTTPS, sin almacenamiento S3 que configurar.
- Registro automático —
autolog()para scikit-learn, PyTorch, Transformers, XGBoost, OpenAI o LangChain. - Cuentas y permisos — una cuenta por persona, permisos concedidos experimento por experimento.
MLflow frente al seguimiento a mano
Desplace la tabla
| Servidor MLflow | Notebooks y hoja de cálculo | |
|---|---|---|
| Historial de pruebas | Cada ejecución registrada automáticamente | Lo que alguien se acordó de anotar |
| Comparar dos modelos | Una pantalla, métricas lado a lado | Copiar cifras |
| Archivos generados | Guardados con la ejecución que los creó | Dispersos en los portátiles |
| Modelo en producción | Una versión y un alias en el registro | Un archivo llamado «final_v3» |
| Trabajo en equipo | Un servidor compartido, cuentas | Envíos de archivos |
Requisitos previos
Un VPS Ubuntu 24.04 con 2 GB de RAM basta para empezar; prevé 4 GB y más disco si guardas muchos modelos, porque son los artefactos los que ocupan espacio. Necesitas Docker con el plugin Compose y un nombre de dominio que apunte al VPS, con nginx y un certificado HTTPS: tus scripts y tu equipo se conectarán a él.
Instalar MLflow con Docker Compose
Preparar el directorio y los secretos
Crea el directorio de la aplicación y un archivo
.envcon la contraseña de la cuentaadmin, la clave de sesión y tu dominio.mkdir -p /opt/mlflow && cd /opt/mlflow cat > .env <<EOF ADMIN_PASSWORD=$(openssl rand -hex 16) SECRET_KEY=$(openssl rand -hex 24) DOMAIN=mlflow.example.ma EOF chmod 600 .envEscribir el docker-compose.yml
La imagen
-fulles la variante oficial que incluye el módulo de autenticación. Al arrancar, el comando escribe el archivobasic_auth.inique declara la cuentaadmin;--allowed-hostssolo acepta tu dominio y la interfaz local. El puerto solo se publica en la interfaz local: solo nginx accede a él.MLFLOW_SERVER_ENABLE_JOB_EXECUTION=falsedesactiva el ejecutor de tareas en segundo plano, que consume mucha memoria y no hace falta para el seguimiento.services: mlflow: image: ghcr.io/mlflow/mlflow:v3.18.0-full restart: unless-stopped ports: - "127.0.0.1:5000:5000" environment: ADMIN_PASSWORD: ${ADMIN_PASSWORD} DOMAIN: ${DOMAIN} MLFLOW_FLASK_SERVER_SECRET_KEY: ${SECRET_KEY} MLFLOW_AUTH_CONFIG_PATH: /mlflow/basic_auth.ini MLFLOW_SERVER_ENABLE_JOB_EXECUTION: "false" entrypoint: ["/bin/sh", "-c"] command: - >- mkdir -p /mlflow/artifacts && printf '[mlflow]\ndefault_permission = NO_PERMISSIONS\ndatabase_uri = sqlite:////mlflow/basic_auth.db\nadmin_username = admin\nadmin_password = %s\nauthorization_function = mlflow.server.auth:authenticate_request_basic_auth\n' "$$ADMIN_PASSWORD" > /mlflow/basic_auth.ini && exec mlflow server --app-name basic-auth --host 0.0.0.0 --port 5000 --workers 2 --backend-store-uri sqlite:////mlflow/mlflow.db --artifacts-destination /mlflow/artifacts --allowed-hosts "$$DOMAIN,localhost:*,127.0.0.1:*" volumes: - mlflow-data:/mlflow volumes: mlflow-data: {}Arrancar y comprobar
El arranque tarda unos quince segundos.
/healthresponde sin autenticación; la API, en cambio, devuelve 401 sin credenciales.docker compose up -d curl -fsS http://127.0.0.1:5000/health curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:5000/api/2.0/mlflow/experiments/searchPublicar por HTTPS con nginx
En el vhost de tu dominio (certificado obtenido con certbot), redirige al puerto local transmitiendo la cabecera
Host. Aumentaclient_max_body_size: un modelo subido como artefacto supera enseguida el límite por defecto.location / { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; client_max_body_size 512m; }
Sin --app-name basic-auth, el servidor está abierto
Por defecto, mlflow server no tiene autenticación: cualquiera que llegue a la dirección puede leer tus experimentos, descargar tus modelos y borrarlo todo. Mantén --app-name basic-auth, no publiques nunca el puerto 5000 en la IP pública y deja --allowed-hosts con tu dominio únicamente: es la protección de MLflow contra el DNS rebinding.
Enviar tus experimentos desde Python
Instala el cliente (pip install mlflow) en la máquina de entrenamiento y apúntalo a tu servidor. Las credenciales se pasan por variables de entorno:
import os
import mlflow
os.environ["MLFLOW_TRACKING_USERNAME"] = "admin"
os.environ["MLFLOW_TRACKING_PASSWORD"] = "TU_CONTRASEÑA"
mlflow.set_tracking_uri("https://mlflow.example.ma")
mlflow.set_experiment("churn-model")
with mlflow.start_run():
mlflow.log_param("learning_rate", 0.01)
mlflow.log_metric("accuracy", 0.93)
mlflow.log_artifact("confusion_matrix.png")La ejecución aparece al instante en la interfaz, con sus parámetros, sus métricas y el archivo subido. mlflow.sklearn.autolog() o mlflow.pytorch.autolog() registran todo eso sin una línea más.
Trazar una aplicación LLM
Para un asistente o un agente, las trazas registran cada petición con sus llamadas al modelo, sus pasos y su duración. Activa el registro automático de tu biblioteca o decora tus propias funciones:
import mlflow
mlflow.set_experiment("support-assistant")
mlflow.openai.autolog() # cada llamada al cliente de OpenAI se convierte en una traza
@mlflow.trace
def answer(question: str) -> str:
...Las trazas aparecen en la pestaña del experimento: ves qué llamada fue lenta, qué contexto se envió y qué respondió el modelo.
El registro de modelos
Cuando validas una prueba, registra su modelo: recibe un número de versión y puedes darle un alias como production.
mlflow.register_model(f"runs:/{run_id}/model", "churn-model")Tu servicio de inferencia carga entonces models:/churn-model@production: cambiar de modelo consiste en mover el alias, sin tocar el código.
Cuentas y permisos
La cuenta admin crea las demás cuentas a través de la API:
curl -u admin:TU_CONTRASEÑA -X POST https://mlflow.example.ma/api/2.0/mlflow/users/create \
-H 'Content-Type: application/json' \
-d '{"username": "sara", "password": "UNA_CONTRASEÑA_LARGA"}'Una cuenta nueva no ve ningún experimento hasta que se le comparte uno: los permisos (lectura, edición, gestión) se conceden experimento por experimento y modelo por modelo. Cambia la contraseña de admin con la API users/update-password (indicando la anterior en current_password); la nueva se conserva tras los reinicios.
Copias de seguridad y actualizaciones
Todo el estado de MLflow está en el volumen mlflow-data: la base de los experimentos, la de las cuentas y la carpeta de artefactos. Haz la copia con el contenedor detenido y luego copia el archivo fuera del VPS:
cd /opt/mlflow
docker compose stop
docker run --rm -v mlflow_mlflow-data:/data -v "$PWD":/backup alpine \
tar czf /backup/mlflow-$(date +%F).tar.gz -C /data .
docker compose startPara actualizar, lee primero las notas de la versión — una actualización puede migrar el esquema de la base —, cambia la etiqueta de la imagen en docker-compose.yml y luego:
cd /opt/mlflow
docker compose pull && docker compose up -d
docker compose logs --tail 20Instalación en 1 clic con ServOrbit
Las Aplicaciones en 1 clic de ServOrbit instalan MLflow en tu VPS sin línea de comandos: despliega el contenedor oficial, genera la contraseña de la cuenta admin y la clave de sesión, activa la autenticación en la interfaz y la API, limita los nombres de host aceptados a tu dirección y publica el servidor por HTTPS en un subdominio de tu dominio o en el subdominio gratuito del VPS (mlflow.{dns_slug}.servorbit-dns.com). La contraseña aparece en tu área de cliente; solo queda conectar tus notebooks.