# ClearML

{% hint style="info" %}
**ClearML** (anteriormente Trains) es una plataforma MLOps de código abierto para seguimiento de experimentos, versionado de datos, gestión de modelos, orquestación de pipelines y gestión de recursos de cómputo — todo en una suite unificada.
{% endhint %}

## Resumen

ClearML es una plataforma integral de gestión del ciclo de vida de ML de Allegro AI. Captura automáticamente parámetros de experimentos, métricas, artefactos y código con cambios mínimos en el código. ClearML soporta el flujo de trabajo completo de ML: desde la gestión de datos y el seguimiento de experimentos hasta el registro de modelos, pipelines automatizados y ejecución distribuida de tareas en clusters GPU.

| Propiedad         | Valor                                                     |
| ----------------- | --------------------------------------------------------- |
| **Categoría**     | MLOps / Seguimiento de experimentos                       |
| **Desarrollador** | Allegro AI                                                |
| **Licencia**      | Apache 2.0                                                |
| **GitHub**        | [allegroai/clearml](https://github.com/allegroai/clearml) |
| **Estrellas**     | 5.5K+                                                     |
| **Docker Hub**    | `allegroai/clearml`                                       |
| **Puertos**       | 22 (SSH), 8008 (API Server), 8081 (Interfaz Web)          |

***

## Arquitectura

ClearML consta de cuatro componentes principales:

| Componente         | Puerto | Descripción                            |
| ------------------ | ------ | -------------------------------------- |
| **ClearML Server** | —      | Coordinador backend                    |
| **Interfaz Web**   | 8081   | Panel basado en navegador              |
| **API Server**     | 8008   | API REST para SDK y agentes            |
| **File Server**    | 8081   | Almacenamiento de artefactos y modelos |
| **ClearML Agent**  | —      | Trabajador que ejecuta tareas de ML    |

***

## Características clave

* **Seguimiento de experimentos sin código** — añade 2 líneas de código para capturar todo automáticamente
* **Registro automático** — métricas, parámetros, modelos, salida de consola, gráficos, imágenes
* **Integración con Git** — captura automática del commit, diff y cambios no comiteados
* **Gestión de datos** — conjuntos de datos versionados con seguimiento de linaje
* **Registro de modelos** — almacenar, versionar y servir modelos de ML
* **Orquestación de pipelines** — construir y ejecutar pipelines ML de múltiples pasos
* **Ejecución remota** — encolar experimentos y ejecutarlos en trabajadores GPU remotos (ClearML Agent)
* **Optimización de hiperparámetros** — HPO automatizado con entrenamiento basado en población
* **Monitoreo de recursos** — monitoreo GPU/CPU/RAM por experimento
* **Autohospedado o en la nube** — ejecuta tu propio servidor o utiliza la plataforma hospedada de ClearML

***

## Configuración en Clore.ai

### Opción 1 — Servidor totalmente autohospedado

Ejecuta el servidor ClearML en Clore.ai para control total.

### Paso 1 — Elige un servidor

| Caso de uso                       | Recomendado    | VRAM  | RAM    |
| --------------------------------- | -------------- | ----- | ------ |
| Solo servidor (sin entrenamiento) | Instancia CPU  | —     | 8 GB+  |
| Servidor + entrenamiento          | RTX 3080       | 10 GB | 16 GB  |
| Cluster MLOps completo            | Múltiples GPUs | —     | 32 GB+ |

### Paso 2 — Alquila un servidor en Clore.ai

1. Ir a [clore.ai](https://clore.ai) → **Marketplace**
2. Para el **componente servidor:** las instancias CPU funcionan bien
3. Para **trabajadores de entrenamiento**: instancias GPU (RTX 3090, 4090, A100)
4. Abrir puertos: **22**, **8008**, **8081**
5. Asegúrate **≥ 50 GB de disco** para artefactos de experimentos

### Paso 3 — Desplegar con Docker Compose

Crear `docker-compose.yml`:

```yaml
versión: "3.6"

servicios:
  apiserver:
    imagen: allegroai/clearml:latest
    reinicio: unless-stopped
    volúmenes:
      - /opt/clearml/logs:/var/log/clearml
      - /opt/clearml/config:/opt/clearml/config
      - /opt/clearml/data/fileserver:/mnt/fileserver
    entorno:
      CLEARML_MONGODB_SERVICE_HOST: mongo
      CLEARML_MONGODB_SERVICE_PORT: 27017
      CLEARML_ELASTICSEARCH_SERVICE_HOST: elasticsearch
      CLEARML_ELASTICSEARCH_SERVICE_PORT: 9200
      CLEARML_REDIS_SERVICE_HOST: redis
      CLEARML_REDIS_SERVICE_PORT: 6379
    puertos:
      - "8008:8008"
    depends_on:
      - mongo
      - elasticsearch
      - redis

  webserver:
    imagen: allegroai/clearml-webserver:latest
    reinicio: unless-stopped
    puertos:
      - "8081:80"
    entorno:
      CLEARML_API_HOST: http://localhost:8008

  fileserver:
    imagen: allegroai/clearml-fileserver:latest
    reinicio: unless-stopped
    volúmenes:
      - /opt/clearml/data/fileserver:/mnt/fileserver
    puertos:
      - "8081:8081"

  mongo:
    imagen: mongo:4.4
    reinicio: unless-stopped
    volúmenes:
      - /opt/clearml/data/mongo:/data/db
    comando: --setParameter internalQueryMaxBlockingSortMemoryUsageBytes=196100200

  elasticsearch:
    imagen: docker.elastic.co/elasticsearch/elasticsearch:7.17.6
    reinicio: unless-stopped
    entorno:
      ES_JAVA_OPTS: "-Xms512m -Xmx2048m"
      bootstrap.memory_lock: "true"
      cluster.name: "clearml"
      discovery.type: "single-node"
      http.publish_host: "$CLEARML_HOST_IP"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volúmenes:
      - /opt/clearml/data/elastic:/usr/share/elasticsearch/data

  redis:
    imagen: redis:6
    reinicio: unless-stopped
    volúmenes:
      - /opt/clearml/data/redis:/data

networks:
  default:
    name: clearml_network
```

Iniciar la pila:

```bash
mkdir -p /opt/clearml/{logs,config,data/{fileserver,mongo,elastic,redis}}

# Establece la IP pública de tu servidor
export CLEARML_HOST_IP=<tu-ip-servidor>

docker-compose up -d
```

{% hint style="warning" %}
ClearML Server requiere \~4 GB de RAM para la pila completa (MongoDB + Elasticsearch + Redis + API server + WebUI). Asegúrate de que tu instancia en Clore.ai tenga suficiente RAM.
{% endhint %}

### Opción 2 — Usar ClearML hospedado (Gratis)

Para seguimiento de experimentos sin ejecutar un servidor, utiliza el plan hospedado gratuito:

```bash
# Instalar SDK
pip install clearml

# Configurar con servidor hospedado
clearml-init
# Introduce: https://api.clear.ml cuando se te solicite el host de la API
# Obtén credenciales en: https://app.clear.ml/settings/workspace-configuration
```

***

## Accediendo a la interfaz

### Panel web

```
http://<server-ip>:8081
```

Credenciales por defecto: crea tu cuenta en el primer inicio de sesión.

### API Server

```
http://<server-ip>:8008
```

### Vía SSH

```bash
ssh root@<server-ip> -p 22
```

***

## Integración del SDK

### Instalación

```bash
pip install clearml
```

### Configuración inicial

```bash
clearml-init
```

Introduce la URL de tu servidor (`http://<server-ip>:8008`) y las credenciales API desde el panel.

O configura programáticamente:

```python
from clearml import Task

Task.set_credentials(
    api_host="http://<server-ip>:8008",
    web_host="http://<server-ip>:8081",
    files_host="http://<server-ip>:8081",
    key="YOUR_ACCESS_KEY",
    secret="YOUR_SECRET_KEY"
)
```

***

## Seguimiento de experimentos

### Integración mínima (2 líneas)

```python
from clearml import Task

# Inicializa la tarea — esto captura TODO automáticamente
task = Task.init(project_name="MyProject", task_name="experiment-001")

# Tu código de entrenamiento existente — no se necesitan cambios
import torch
import torch.nn as nn

model = nn.Linear(10, 1)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

for epoch in range(10):
    loss = torch.tensor(1.0 / (epoch + 1))
    # ClearML detecta y registra la pérdida automáticamente si usas frameworks estándar
    print(f"Epoch {epoch}, Loss: {loss.item():.4f}")

task.close()
```

### Registro manual de métricas

```python
from clearml import Task, Logger

task = Task.init(project_name="MyProject", task_name="manual-logging-demo")
logger = task.get_logger()

for epoch in range(50):
    train_loss = 1.0 / (epoch + 1)
    val_accuracy = 0.95 - 0.5 / (epoch + 1)

    # Registrar escalares
    logger.report_scalar("Loss", "train", value=train_loss, iteration=epoch)
    logger.report_scalar("Accuracy", "validation", value=val_accuracy, iteration=epoch)

    # Registrar tasa de aprendizaje
    logger.report_scalar("Learning Rate", "lr", value=0.001 * 0.9**epoch, iteration=epoch)

print("¡Entrenamiento completado!")
task.close()
```

### Seguimiento de hiperparámetros

```python
from clearml import Task

task = Task.init(project_name="HPO-Demo", task_name="run-001")

# Conectar hiperparámetros — se registran automáticamente y se pueden sobrescribir de forma remota
params = {
    "learning_rate": 0.001,
    "batch_size": 32,
    "num_layers": 4,
    "dropout": 0.3,
    "optimizer": "adam",
    "epochs": 100,
}
params = task.connect(params)  # Ahora sobrescribible por ClearML HPO

print(f"Entrenando con lr={params['learning_rate']}, batch={params['batch_size']}")
```

***

## Gestión de datos

```python
from clearml import Dataset

# Crear un dataset versionado
dataset = Dataset.create(
    dataset_name="my-training-data",
    dataset_project="MyProject",
    dataset_version="1.0",
)

# Añadir archivos
dataset.add_files(path="/data/images/", recursive=True)
dataset.add_files(path="/data/labels.csv")

# Subir al servidor ClearML
dataset.upload()
dataset.finalize()
print(f"ID del dataset: {dataset.id}")

# Más tarde: usar el dataset en experimentos
dataset = Dataset.get(dataset_name="my-training-data", dataset_version="1.0")
local_path = dataset.get_local_copy()
print(f"Dataset en: {local_path}")
```

***

## Registro de modelos

```python
from clearml import Task, OutputModel, InputModel
import torch

task = Task.init(project_name="ModelRegistry", task_name="training-run")

# Después del entrenamiento, registra el modelo
model = torch.nn.Linear(100, 10)
torch.save(model.state_dict(), "my_model.pt")

# Registrar modelo de salida
output_model = OutputModel(task=task, name="MyModel-v1")
output_model.update_weights("my_model.pt")
output_model.publish()  # Marcar como listo para usar

print(f"Modelo registrado: {output_model.id}")

# En despliegue: cargar modelo por nombre
input_model = InputModel(model_id="<model-id-from-dashboard>")
local_model_path = input_model.get_local_copy()
state_dict = torch.load(local_model_path)
```

***

## Orquestación de pipelines

```python
from clearml.automation import PipelineController

def step_preprocess(dataset_id: str) -> str:
    """Paso de preprocesamiento de datos."""
    from clearml import Task, Dataset
    task = Task.init(task_name="step-preprocess")
    # ... lógica de preprocesamiento
    return "processed_data_id"

def step_train(data_id: str, lr: float = 0.001) -> str:
    """Paso de entrenamiento del modelo."""
    from clearml import Task
    task = Task.init(task_name="step-train")
    # ... lógica de entrenamiento
    return "model_id"

def step_evaluate(model_id: str) -> float:
    """Paso de evaluación del modelo."""
    from clearml import Task
    task = Task.init(task_name="step-evaluate")
    # ... lógica de evaluación
    return 0.95

# Construir pipeline
pipe = PipelineController(
    name="ML-Training-Pipeline",
    project="MyPipelines",
    version="1.0"
)

pipe.add_function_step(
    name="preprocess",
    function=step_preprocess,
    function_kwargs={"dataset_id": "raw-data-id"},
    function_return=["processed_id"],
)

pipe.add_function_step(
    name="train",
    parents=["preprocess"],
    function=step_train,
    function_kwargs={"data_id": "${preprocess.processed_id}"},
    function_return=["model_id"],
    execution_queue="gpu-queue",  # Ejecutar en trabajador con GPU
)

pipe.add_function_step(
    name="evaluate",
    parents=["train"],
    function=step_evaluate,
    function_kwargs={"model_id": "${train.model_id}"},
    function_return=["accuracy"],
)

pipe.start()
pipe.wait()
print("¡Pipeline completado!")
```

***

## ClearML Agent (Trabajador)

Ejecuta un ClearML Agent en un servidor GPU para ejecutar experimentos encolados:

```bash
# Instalar agent
pip install clearml-agent

# Configurar (usa las mismas credenciales que el SDK)
clearml-agent init

# Iniciar trabajador en GPU
clearml-agent daemon --queue "gpu-queue" --gpus 0,1

# Iniciar trabajador con aislamiento Docker (recomendado)
clearml-agent daemon \
    --queue "gpu-queue" \
    --docker pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime \
    --gpus all
```

En Clore.ai, lanza múltiples nodos GPU como agentes ClearML para crear un clúster de cómputo distribuido.

***

## Optimización de hiperparámetros

```python
from clearml.automation import (
    HyperParameterOptimizer,
    UniformParameterRange,
    DiscreteParameterValues,
    GridSearch,
)

optimizer = HyperParameterOptimizer(
    base_task_id="<task-id-to-optimize>",
    hyper_parameters=[
        UniformParameterRange("General/learning_rate", min_value=1e-5, max_value=1e-2, step_size=1e-5),
        DiscreteParameterValues("General/batch_size", values=[16, 32, 64, 128]),
        DiscreteParameterValues("General/optimizer", values=["adam", "sgd", "adamw"]),
    ],
    objective_metric_title="Accuracy",
    objective_metric_series="validation",
    objective_metric_sign="max",  # Maximizar la precisión de validación
    max_number_of_concurrent_tasks=4,
    optimizer_class=GridSearch,
    execution_queue="gpu-queue",
    total_max_jobs=50,
)

optimizer.start()
top_exps = optimizer.get_top_experiments(top_k=3)
print("Mejores experimentos:", top_exps)
```

***

## Monitoreo y alertas

```python
from clearml import Task

task = Task.init(project_name="Production", task_name="monitoring")

# Establecer etiquetas de tarea para facilitar el filtrado
task.add_tags(["production", "v2.1", "gpu"])

# Registrar métricas del sistema automáticamente — solo inicializa la tarea
# ClearML captura: utilización de CPU, RAM, GPU, VRAM de GPU automáticamente

# Añadir monitoreo de escalares personalizados
logger = task.get_logger()
import time
for i in range(100):
    gpu_util = 85 + (i % 10)
    logger.report_scalar("GPU", "utilization_%", value=gpu_util, iteration=i)
    time.sleep(1)
```

***

## Solución de problemas

{% hint style="warning" %}
**Elasticsearch no inicia** — Establece `vm.max_map_count=262144` en el host: `sysctl -w vm.max_map_count=262144`. Añadir a `/etc/sysctl.conf` para persistencia.
{% endhint %}

{% hint style="warning" %}
**No se puede conectar al servidor** — Verifica que los puertos 8008 y 8081 estén abiertos en la configuración de puertos de Clore.ai. Revisa `docker ps` para asegurar que todos los contenedores estén en ejecución.
{% endhint %}

{% hint style="info" %}
**Los experimentos no aparecen en la interfaz** — Comprueba que `CLEARML_API_HOST` en la configuración del SDK apunte a `http://<server-ip>:8008`, no a localhost.
{% endhint %}

{% hint style="info" %}
**Espacio en disco insuficiente** — ClearML almacena todos los artefactos localmente. Configura almacenamiento S3/GCS o aumenta la asignación de disco en Clore.ai.
{% endhint %}

| Problema                     | Solución                                                                         |
| ---------------------------- | -------------------------------------------------------------------------------- |
| Conexión a MongoDB rechazada | Comprueba el contenedor mongo: `docker logs clearml_mongo_1`                     |
| Tarea atascada en la cola    | Asegúrate de que ClearML Agent esté en ejecución y conectado a la cola           |
| Interfaz lenta               | Elasticsearch necesita tiempo para indexar — espera 2–3 min después del arranque |
| API 401 Unauthorized         | Regenera las credenciales API en el panel web de ClearML                         |

***

## Casos de uso para investigadores con GPU

* **Rastrear ejecuciones de entrenamiento** — nunca pierdas hiperparámetros o resultados nuevamente
* **Comparar experimentos** — comparación lado a lado de métricas en la interfaz
* **Reproducir resultados** — ClearML captura commit de git + diff de código automáticamente
* **Compartir resultados** — los colaboradores ven todos los experimentos en el panel compartido
* **Trabajos GPU remotos** — encola trabajos de entrenamiento desde el portátil y ejecútalos en nodos GPU de Clore.ai
* **HPO automatizado** — ejecutar búsqueda de hiperparámetros en múltiples nodos GPU en paralelo

***

## Herramientas relacionadas

* [MLflow](/guides/guides_v2-es/mlops-y-despliegue/mlflow.md) — alternativa para seguimiento de experimentos
* [Weights & Biases](https://wandb.ai/) — seguimiento de experimentos ML hospedado
* [Ray](https://www.ray.io/) — entrenamiento ML distribuido y HPO

***

*ClearML en Clore.ai combina el seguimiento de experimentos con la gestión de cómputo GPU — brindando a tu equipo de ML capacidades MLOps completas sin quedar atado a un proveedor de nube.*

***

## Recomendaciones de GPU para Clore.ai

| Caso de uso                 | GPU recomendada | Costo estimado en Clore.ai |
| --------------------------- | --------------- | -------------------------- |
| Desarrollo/Pruebas          | RTX 3090 (24GB) | \~$0.12/gpu/hr             |
| Entrenamiento de producción | RTX 4090 (24GB) | \~$0.70/gpu/hr             |
| Experimentos a gran escala  | A100 80GB       | \~$1.20/gpu/hr             |

> 💡 Todos los ejemplos en esta guía pueden desplegarse en [Clore.ai](https://clore.ai/marketplace) servidores GPU. Explora las GPUs disponibles y alquila por hora: sin compromisos, con acceso root completo.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-es/mlops-y-despliegue/clearml.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
