| Qué es | Cuándo se fija | ¿Cambia dentro del run? | |
|---|---|---|---|
| Parámetro | Una entrada: la configuración que elegiste | Antes de ejecutar | No. Se escribe una vez |
| Métrica | Una salida: el resultado de medir | Después de ejecutar | Sí: tiene serie temporal (step) |
| Artefacto | Un fichero: modelo, gráfica, CSV, config | En cualquier momento | Se añaden, no se sobrescriben |
| Tag | Un metadato para organizar y buscar | En cualquier momento | Sí, es mutable |
mlflow.log_param("n_estimators", 100) # entrada
mlflow.log_metric("f1", 0.87) # salida
mlflow.log_artifact("matriz_confusion.png") # fichero
mlflow.set_tag("responsable", "nico") # metadato
La pregunta que resuelve casi todas las dudas: ¿lo elegí yo o lo midió el código? Lo que elegiste es parámetro; lo que salió es métrica. Cualquier cosa que sea un fichero es artefacto, y lo que sirve para encontrar la ejecución meses después es tag.
Inmutable dentro del run. Escribirlo dos veces con valores distintos es un error, porque una entrada no cambia a mitad de una ejecución. Se guarda como cadena de texto.
Cada log_metric añade un punto a una serie. Por eso llamarlo
dentro de un bucle con step=i produce una curva. Se guarda como número.
La consecuencia es práctica y llega tarde: si registras la accuracy final como parámetro, has perdido la posibilidad de ordenar y filtrar por ella, porque el filtro comparará textos. Y al revés: un learning rate que va cambiando durante el entrenamiento está bien registrado como métrica, aunque suene a configuración.
// la duda «¿esto es param o metric?» se resuelve mirando quién decidió el valorSin configurar nada, MLflow escribe en una carpeta mlruns/ relativa al directorio
de trabajo. Ese detalle explica el fallo más habitual de la primera sesión: lanzas
mlflow ui desde otra carpeta y la interfaz sale vacía. No se ha perdido nada — estás
mirando otro almacén.
| Pieza | Para qué |
|---|---|
mlflow.set_experiment(nombre) | Agrupa runs. Sin él, todo cae en Default |
with mlflow.start_run(): | Abre y cierra el run |
mlflow ui | Lee mlruns/ del directorio actual |
El with no es cuestión de estilo. Si el run no se cierra, la siguiente llamada a
start_run() falla con Run ... is already active — el error que aparece al
reejecutar una celda de notebook y que desconcierta porque el código «no ha cambiado».
El primer ejemplo del módulo registra esto como métrica:
accuracy = (alpha * 0.5) + (l1_ratio * 0.2) + random.uniform(0, 0.1)
Eso no es una accuracy: es una función lineal de los hiperparámetros más ruido. El «mejor»
modelo será siempre el de alpha más alto, por construcción, y nada acota el
resultado a [0, 1]. Además alpha y l1_ratio son parámetros
de ElasticNet, un modelo que no aparece en ninguna otra parte del módulo.
Como demostración de la API funciona perfectamente. La pregunta es otra: el ejercicio te pide después abrir la UI y comparar las dos ejecuciones. Si nadie te dice que la métrica está inventada, ¿qué habrías concluido de esa comparación? ¿Y cómo distinguirías, en una tabla real, una métrica que mide algo de una que solo repite tus propias entradas?
Dentro de un mismo run, llama dos veces a log_param("k", 1) y
log_param("k", 2). Después dos veces a log_metric("m", 1) y
log_metric("m", 2). Mira qué hace cada caso y qué enseña la UI.
Uno de los dos protesta y el otro no. Esa asimetría no es una rareza de implementación: es la diferencia entre una entrada y una salida, y una vez que la has visto ya no vuelves a dudar dónde va cada cosa.