ClearML Tutorial: Open-Source MLOps Platform for Experiment Tracking and Pipeline Automation

# Tutorial ClearML: Platform MLOps Open-Source untuk Experiment Tracking dan Pipeline Automation ClearML adalah platform MLOps open-source yang menyediakan solusi lengkap untuk experiment tracking, d...

By Ruby Abdullah · · tutorial
ClearMLMLOpsExperiment TrackingPipelinePython

ClearML Tutorial: Open-Source MLOps Platform for Experiment Tracking and Pipeline Automation

ClearML is an open-source MLOps platform that provides a comprehensive solution for experiment tracking, data management, orchestration, and machine learning model deployment. With ClearML, data science teams can manage the entire ML project lifecycle from initial experimentation to production deployment within a single integrated platform.

In this tutorial, we will learn how to use ClearML from installation, basic experiment tracking, dataset management, to pipeline automation. All code examples can be directly practiced in your local environment.

Why ClearML?

Before diving into implementation, here are several reasons why ClearML deserves consideration for your MLOps workflow:

  • Fully Open-Source: ClearML Server can be self-deployed at no licensing cost, with a hosted solution option for teams that prefer not to manage infrastructure.
  • Minimal Code Changes: Just add 2 lines of code to start tracking experiments, without needing to change your existing project structure.
  • Auto-Logging: ClearML automatically captures metrics, hyperparameters, artifacts, and even console output from popular frameworks like PyTorch, TensorFlow, scikit-learn, and XGBoost.
  • Pipeline Orchestration: Ability to create and run reproducible ML pipelines with automatic dependency management.
  • Data Management: Dataset versioning features that enable efficient data change tracking.
  • Installation

    Installing ClearML SDK

    Install the ClearML Python SDK using pip:

    pip install clearml
    

    For additional features, you can install with extras:

    pip install clearml[s3]
    

    pip install clearml[gs]

    pip install clearml[azure]

    Setting Up ClearML Server

    There are two options for ClearML Server:

    Option 1: ClearML Hosted (Free for individuals)

    Register a free account at app.clear.ml, then run:

    clearml-init
    

    Enter the credentials (API key, secret, and host) that can be obtained from Settings > Workspace in the ClearML dashboard.

    Option 2: Self-Hosted with Docker
    mkdir -p /opt/clearml && cd /opt/clearml
    
    

    curl -o docker-compose.yml https://raw.githubusercontent.com/allegroai/clearml-server/master/docker/docker-compose.yml

    docker-compose up -d

    After the server is running, access the dashboard at http://localhost:8080 and create new credentials.

    Configuration

    After running clearml-init, the configuration file will be saved at ~/clearml.conf:

    api {
    

    webserver: https://app.clear.ml

    apiserver: https://api.clear.ml

    filesserver: https://files.clear.ml

    credentials {

    "accesskey" = "YOURACCESSKEY"

    "secretkey" = "YOURSECRETKEY"

    }

    }

    Basic Usage: Experiment Tracking

    Your First Experiment Tracking

    The simplest way to get started with ClearML is by adding two lines of code to your training script:

    from clearml import Task
    
    

    task = Task.init(projectname="ClearML Tutorial", taskname="First Experiment")

    import numpy as np

    from sklearn.ensemble import RandomForestClassifier

    from sklearn.datasets import makeclassification

    from sklearn.modelselection import traintestsplit

    from sklearn.metrics import accuracyscore, f1score

    X, y = makeclassification(

    nsamples=1000,

    nfeatures=20,

    ninformative=10,

    nclasses=2,

    randomstate=42

    )

    Xtrain, Xtest, ytrain, ytest = traintestsplit(X, y, testsize=0.2, randomstate=42)

    params = {

    "nestimators": 100,

    "maxdepth": 10,

    "minsamplessplit": 5,

    "randomstate": 42

    }

    task.connect(params)

    model = RandomForestClassifier(*params)

    model.fit(Xtrain, ytrain)

    ypred = model.predict(Xtest)

    accuracy = accuracyscore(ytest, ypred)

    f1 = f1score(ytest, ypred)

    logger = task.getlogger()

    logger.reportscalar("metrics", "accuracy", value=accuracy, iteration=1)

    logger.reportscalar("metrics", "f1score", value=f1, iteration=1)

    print(f"Accuracy: {accuracy:.4f}")

    print(f"F1 Score: {f1:.4f}")

    When this script is executed, ClearML will automatically:

    • Record all hyperparameters
    • Capture console output
    • Store reported metrics
    • Log environment details (packages, OS, GPU)
    • Track source code and uncommitted changes

    Logging Metrics Iteratively

    For training loops that require per-epoch logging:

    from clearml import Task
    

    import numpy as np

    task = Task.init(projectname="ClearML Tutorial", taskname="Training Loop Metrics")

    logger = task.getlogger()

    nepochs = 50

    for epoch in range(nepochs):

    trainloss = 1.0 / (epoch + 1) + np.random.normal(0, 0.05)

    valloss = 1.2 / (epoch + 1) + np.random.normal(0, 0.08)

    learningrate = 0.001 (0.95 epoch)

    logger.reportscalar("loss", "train", value=trainloss, iteration=epoch)

    logger.reportscalar("loss", "validation", value=valloss, iteration=epoch)

    logger.reportscalar("learningrate", "lr", value=learningrate, iteration=epoch)

    print("Training complete!")

    Logging Visualizations

    ClearML supports various visualization types:

    from clearml import Task
    

    import numpy as np

    import matplotlib.pyplot as plt

    from sklearn.metrics import confusionmatrix, ConfusionMatrixDisplay

    task = Task.init(projectname="ClearML Tutorial", taskname="Visualizations")

    logger = task.getlogger()

    cm = np.array([[45, 5], [8, 42]])

    fig, ax = plt.subplots(figsize=(8, 6))

    disp = ConfusionMatrixDisplay(confusionmatrix=cm, displaylabels=["Negative", "Positive"])

    disp.plot(ax=ax)

    plt.title("Confusion Matrix")

    logger.reportmatplotlibfigure("Confusion Matrix", "results", figure=fig)

    categories = ["Precision", "Recall", "F1-Score", "Accuracy"]

    values = [0.89, 0.84, 0.86, 0.87]

    fig2, ax2 = plt.subplots(figsize=(8, 5))

    ax2.bar(categories, values, color=["#2196F3", "#4CAF50", "#FF9800", "#9C27B0"])

    ax2.setylim(0, 1.0)

    ax2.settitle("Model Performance Metrics")

    logger.reportmatplotlibfigure("Performance", "barchart", figure=fig2)

    data = np.random.randn(1000)

    logger.reporthistogram("Distribution", "predictions", values=data, xaxis="Value", yaxis="Frequency")

    Framework Integrations

    PyTorch Integration

    ClearML automatically captures metrics from PyTorch:

    from clearml import Task
    

    import torch

    import torch.nn as nn

    import torch.optim as optim

    from torch.utils.data import DataLoader, TensorDataset

    import numpy as np

    task = Task.init(projectname="ClearML Tutorial", taskname="PyTorch Training")

    logger = task.getlogger()

    params = {

    "batchsize": 32,

    "learningrate": 0.001,

    "epochs": 20,

    "hiddensize": 64

    }

    task.connect(params)

    class SimpleNet(nn.Module):

    def init(self, inputsize, hiddensize, numclasses):

    super().init()

    self.fc1 = nn.Linear(inputsize, hiddensize)

    self.relu = nn.ReLU()

    self.dropout = nn.Dropout(0.3)

    self.fc2 = nn.Linear(hiddensize, hiddensize // 2)

    self.fc3 = nn.Linear(hiddensize // 2, numclasses)

    def forward(self, x):

    x = self.dropout(self.relu(self.fc1(x)))

    x = self.relu(self.fc2(x))

    return self.fc3(x)

    X = np.random.randn(1000, 20).astype(np.float32)

    y = (X[:, 0] + X[:, 1] > 0).astype(np.int64)

    dataset = TensorDataset(torch.fromnumpy(X), torch.fromnumpy(y))

    trainloader = DataLoader(dataset, batchsize=params["batchsize"], shuffle=True)

    model = SimpleNet(20, params["hiddensize"], 2)

    criterion = nn.CrossEntropyLoss()

    optimizer = optim.Adam(model.parameters(), lr=params["learningrate"])

    for epoch in range(params["epochs"]):

    model.train()

    totalloss = 0

    correct = 0

    total = 0

    for batchX, batchy in trainloader:

    optimizer.zerograd()

    outputs = model(batchX)

    loss = criterion(outputs, batchy)

    loss.backward()

    optimizer.step()

    totalloss += loss.item()

    , predicted = torch.max(outputs, 1)

    total += batchy.size(0)

    correct += (predicted == batchy).sum().item()

    avgloss = totalloss / len(trainloader)

    accuracy = correct / total

    logger.reportscalar("training", "loss", value=avgloss, iteration=epoch)

    logger.reportscalar("training", "accuracy", value=accuracy, iteration=epoch)

    torch.save(model.statedict(), "model.pth")

    task.uploadartifact("modelweights", artifactobject="model.pth")

    print("PyTorch training complete!")

    Hugging Face Transformers Integration

    from clearml import Task
    
    

    task = Task.init(projectname="ClearML Tutorial", taskname="HuggingFace Fine-tuning")

    from transformers import (

    AutoTokenizer,

    AutoModelForSequenceClassification,

    TrainingArguments,

    Trainer

    )

    from datasets import loaddataset

    import numpy as np

    from sklearn.metrics import accuracyscore

    dataset = loaddataset("imdb", split={"train": "train[:1000]", "test": "test[:200]"})

    tokenizer = AutoTokenizer.frompretrained("distilbert-base-uncased")

    def tokenizefunction(examples):

    return tokenizer(examples["text"], padding="maxlength", truncation=True, maxlength=256)

    tokenized = dataset.map(tokenizefunction, batched=True)

    model = AutoModelForSequenceClassification.frompretrained(

    "distilbert-base-uncased", numlabels=2

    )

    def computemetrics(evalpred):

    logits, labels = evalpred

    predictions = np.argmax(logits, axis=-1)

    return {"accuracy": accuracyscore(labels, predictions)}

    trainingargs = TrainingArguments(

    outputdir="./results",

    numtrainepochs=3,

    perdevicetrainbatchsize=16,

    perdeviceevalbatchsize=16,

    evaluationstrategy="epoch",

    savestrategy="epoch",

    loggingsteps=10,

    loadbestmodelatend=True,

    )

    trainer = Trainer(

    model=model,

    args=trainingargs,

    traindataset=tokenized["train"],

    evaldataset=tokenized["test"],

    computemetrics=computemetrics,

    )

    trainer.train()

    ClearML will automatically capture all metrics from the Hugging Face Trainer without any additional code.

    Dataset Management

    ClearML Dataset enables efficient dataset versioning and sharing:

    Creating a Dataset

    from clearml import Dataset
    
    

    dataset = Dataset.create(

    datasetname="Customer Churn Dataset",

    datasetproject="ClearML Tutorial/Datasets"

    )

    dataset.addfiles(path="./data/customerchurn.csv")

    dataset.addfiles(path="./data/features/")

    dataset.getlogger().reporttable(

    "Dataset Info",

    "summary",

    tableplot=[

    ["Total Records", "10,000"],

    ["Features", "15"],

    ["Target", "churn (binary)"],

    ["Missing Values", "2.3%"]

    ]

    )

    dataset.upload()

    dataset.finalize()

    print(f"Dataset ID: {dataset.id}")

    Using a Dataset

    from clearml import Dataset
    
    

    datasetpath = Dataset.get(

    datasetname="Customer Churn Dataset",

    datasetproject="ClearML Tutorial/Datasets"

    ).getlocalcopy()

    import pandas as pd

    df = pd.readcsv(f"{datasetpath}/customerchurn.csv")

    print(f"Dataset loaded: {df.shape}")

    Dataset Versioning

    from clearml import Dataset
    
    

    childdataset = Dataset.create(

    datasetname="Customer Churn Dataset",

    datasetproject="ClearML Tutorial/Datasets",

    parentdatasets=[parentdatasetid]

    )

    childdataset.addfiles(path="./data/newrecords.csv")

    childdataset.removefiles(match="outdatedrecords.csv")

    childdataset.upload()

    childdataset.finalize()

    Advanced Usage: Pipeline Automation

    Building Pipelines with PipelineDecorator

    ClearML provides PipelineDecorator for creating modular and reproducible ML pipelines:

    from clearml import PipelineDecorator
    
    

    @PipelineDecorator.component(

    returnvalues=["Xtrain", "Xtest", "ytrain", "ytest"],

    cache=True

    )

    def stepdatapreparation(datasetname, testsize=0.2):

    import pandas as pd

    from sklearn.modelselection import traintestsplit

    from clearml import Dataset

    datasetpath = Dataset.get(datasetname=datasetname).getlocalcopy()

    df = pd.readcsv(f"{datasetpath}/customerchurn.csv")

    X = df.drop("churn", axis=1)

    y = df["churn"]

    Xtrain, Xtest, ytrain, ytest = traintestsplit(

    X, y, testsize=testsize, randomstate=42, stratify=y

    )

    print(f"Train size: {len(Xtrain)}, Test size: {len(Xtest)}")

    return Xtrain, Xtest, ytrain, ytest

    @PipelineDecorator.component(

    returnvalues=["Xtrainscaled", "Xtestscaled", "scaler"],

    cache=True

    )

    def stepfeatureengineering(Xtrain, Xtest):

    from sklearn.preprocessing import StandardScaler

    import numpy as np

    scaler = StandardScaler()

    Xtrainscaled = scaler.fittransform(Xtrain)

    Xtestscaled = scaler.transform(Xtest)

    print(f"Features scaled. Mean: {np.mean(Xtrainscaled):.4f}")

    return Xtrainscaled, Xtestscaled, scaler

    @PipelineDecorator.component(

    returnvalues=["model", "metrics"],

    cache=False

    )

    def stepmodeltraining(Xtrain, ytrain, Xtest, ytest, modelparams):

    from sklearn.ensemble import GradientBoostingClassifier

    from sklearn.metrics import accuracyscore, precisionscore, recallscore, f1score

    model = GradientBoostingClassifier(modelparams)

    model.fit(Xtrain, ytrain)

    ypred = model.predict(Xtest)

    metrics = {

    "accuracy": accuracyscore(ytest, ypred),

    "precision": precisionscore(ytest, ypred),

    "recall": recallscore(ytest, ypred),

    "f1score": f1score(ytest, ypred)

    }

    print(f"Model trained. Accuracy: {metrics['accuracy']:.4f}")

    return model, metrics

    @PipelineDecorator.component(returnvalues=["modelpath"])

    def stepmodelexport(model, scaler, metrics):

    import joblib

    from clearml import Task

    modelpath = "modelproduction.joblib"

    joblib.dump({"model": model, "scaler": scaler, "metrics": metrics}, modelpath)

    task = Task.currenttask()

    task.uploadartifact("productionmodel", artifactobject=modelpath)

    print(f"Model exported to {modelpath}")

    return modelpath

    @PipelineDecorator.pipeline(

    name="Customer Churn Pipeline",

    project="ClearML Tutorial/Pipelines",

    version="1.0"

    )

    def churnpredictionpipeline(datasetname, modelparams):

    Xtrain, Xtest, ytrain, ytest = stepdatapreparation(

    datasetname=datasetname

    )

    Xtrainscaled, Xtestscaled, scaler = stepfeatureengineering(

    Xtrain=Xtrain, Xtest=Xtest

    )

    model, metrics = stepmodeltraining(

    Xtrain=Xtrainscaled,

    ytrain=ytrain,

    Xtest=Xtestscaled,

    ytest=ytest,

    modelparams=modelparams

    )

    modelpath = stepmodelexport(

    model=model, scaler=scaler, metrics=metrics

    )

    print(f"Pipeline complete! Metrics: {metrics}")

    return modelpath

    if name == "main":

    PipelineDecorator.runlocally()

    modelparams = {

    "nestimators": 200,

    "maxdepth": 5,

    "learningrate": 0.1,

    "subsample": 0.8

    }

    churnpredictionpipeline(

    datasetname="Customer Churn Dataset",

    modelparams=modelparams

    )

    Running Pipelines Remotely

    To run the pipeline on a remote agent:

    if name == "main":
    

    churnpredictionpipeline(

    datasetname="Customer Churn Dataset",

    modelparams=modelparams

    )

    Scheduling Pipelines

    from clearml.automation import TriggerScheduler
    
    

    scheduler = TriggerScheduler()

    scheduler.addtask(

    schedulefunction=lambda: churnpredictionpipeline(

    datasetname="Customer Churn Dataset",

    modelparams={"nestimators": 200, "maxdepth": 5}

    ),

    name="Daily Churn Pipeline",

    minute=0,

    hour=6

    )

    scheduler.start()

    ClearML Agent: Remote Execution

    ClearML Agent enables task execution on remote machines:

    Installing the Agent

    pip install clearml-agent
    

    clearml-agent init

    Running the Agent

    clearml-agent daemon --queue default --foreground
    

    Sending Tasks to a Queue

    from clearml import Task
    
    

    task = Task.init(projectname="ClearML Tutorial", taskname="Remote Training")

    params = {"epochs": 50, "batchsize": 64, "learningrate": 0.001}

    task.connect(params)

    Task.enqueue(task, queuename="default")

    print(f"Task {task.id} sent to queue 'default'")

    Cloning and Re-running Experiments

    from clearml import Task
    
    

    originaltask = Task.gettask(taskid="abc123")

    clonedtask = Task.clone(sourcetask=originaltask, name="Cloned Experiment")

    clonedparams = clonedtask.getparameters()

    clonedparams["General/learningrate"] = 0.0005

    clonedtask.setparameters(clonedparams)

    Task.enqueue(clonedtask, queuename="gpu-queue")

    Hyperparameter Optimization

    ClearML provides built-in HPO (Hyperparameter Optimization):

    from clearml import Task
    

    from clearml.automation import (

    UniformParameterRange,

    UniformIntegerParameterRange,

    DiscreteParameterRange,

    HyperParameterOptimizer,

    RandomSearch

    )

    task = Task.init(

    projectname="ClearML Tutorial",

    taskname="HPO Controller",

    tasktype=Task.TaskTypes.optimizer

    )

    optimizer = HyperParameterOptimizer(

    basetaskid="BASETASKID",

    hyperparameters=[

    UniformParameterRange("General/learningrate", minvalue=0.0001, maxvalue=0.01),

    UniformIntegerParameterRange("General/batchsize", minvalue=16, maxvalue=128),

    UniformIntegerParameterRange("General/epochs", minvalue=10, maxvalue=100),

    DiscreteParameterRange("General/optimizer", values=["adam", "sgd", "adamw"]),

    ],

    objectivemetrictitle="metrics",

    objectivemetricseries="accuracy",

    objectivemetricsign="max",

    optimizerclass=RandomSearch,

    maxnumberofconcurrenttasks=4,

    totalmaxjobs=20,

    miniterationperjob=0,

    maxiterationperjob=150,

    )

    optimizer.setreportperiod(1)

    optimizer.start()

    optimizer.wait()

    best = optimizer.gettopexperiments(topk=3)

    print(f"Best experiment: {best[0].id}")

    print(f"Best accuracy: {best[0].getlastscalarmetrics()}")

    optimizer.stop()

    Model Registry

    ClearML provides a model registry for managing model artifacts:

    from clearml import OutputModel, InputModel, Task
    
    

    task = Task.init(projectname="ClearML Tutorial", taskname="Model Registry")

    outputmodel = OutputModel(

    task=task,

    name="Churn Prediction Model v1",

    tags=["production", "churn", "gradient-boosting"],

    framework="scikit-learn"

    )

    outputmodel.updateweights(weightsfilename="modelproduction.joblib")

    outputmodel.setmetadata({

    "accuracy": "0.92",

    "f1score": "0.89",

    "trainingdataversion": "v2.1",

    "featurecount": "15"

    })

    model = InputModel(modelid="MODELID")

    localpath = model.getweights()

    print(f"Model downloaded to: {localpath}")

    Best Practices

    1. Project Organization

    Use a consistent project structure:

    Company/
    

    ├── Team-A/

    │ ├── Experiments/

    │ ├── Pipelines/

    │ └── Datasets/

    ├── Team-B/

    │ ├── Experiments/

    │ └── Pipelines/

    └── Production/

    ├── Models/

    └── Monitoring/

    2. Tagging and Naming Conventions

    task = Task.init(
    

    projectname="Fraud Detection/Experiments",

    taskname="XGBoost v2 - balanced sampling",

    tags=["xgboost", "balanced", "v2", "candidate"]

    )

    3. Environment Reproducibility

    ClearML automatically captures requirements, but you can add packages explicitly:

    task.setpackages(["torch==2.0.1", "transformers==4.30.0"])
    

    4. Use Caching in Pipelines

    Enable cache=True on deterministic pipeline components to save time:

    @PipelineDecorator.component(cache=True)
    

    def expensivepreprocessing(data):

    ...

    5. Monitoring and Alerting

    from clearml.automation import TaskScheduler
    
    

    scheduler = TaskScheduler()

    scheduler.addtask(

    taskid="monitoringtaskid",

    queue="monitoring",

    minute=0,

    hour="*/4"

    )

    6. Use Artifacts for Large Files

    Don't log large files as metrics. Use artifacts instead:

    task.uploadartifact("largedataset", artifactobject=dataframe)
    

    task.uploadartifact("modelcheckpoint", artifactobject="checkpoint.pt")

    Conclusion

    ClearML is an MLOps platform that offers a comprehensive solution for managing the machine learning lifecycle. Key advantages of ClearML include:

    • Easy Adoption: Only 2 lines of code needed to start tracking experiments, without changing your existing workflow.
    • Feature-Complete: From experiment tracking, dataset versioning, pipeline automation, to model serving, everything is available in one platform.
    • Open-Source: ClearML Server can be self-deployed, giving full control over data and infrastructure.
    • Scalable: Supports small teams to enterprise with collaboration features and role-based access control.

    By mastering ClearML, you can build MLOps workflows that are reproducible, scalable, and easy to maintain. Start with simple experiment tracking, then gradually adopt dataset management, pipeline automation, and remote execution features as your team's needs grow.

    Recommended next steps:

    • Explore ClearML Serving for model deployment
    • Learn ClearML Sessions for remote development
    • Integrate ClearML with CI/CD pipelines using GitHub Actions or GitLab CI

    Related Articles

    Complete Comet ML Tutorial: MLOps Platform for Experiment Tracking and Model Management

    Tutorial Lengkap Comet ML: Platform MLOps untuk Experiment Tracking dan Model Management Dalam dunia machine learning mo...

    Metaflow Tutorial: Netflix's MLOps Framework for Data Science

    Tutorial Metaflow: Framework MLOps dari Netflix untuk Data Science Metaflow adalah framework open-source yang dikembangk...

    Kedro Tutorial: Reproducible and Maintainable Data Science Pipelines

    Kedro: Pipeline Data Science yang Reproducible dan Mudah Dirawat Sebagian besar proyek data science dimulai dari satu no...

    ZenML: Modular and Cloud-Agnostic MLOps Pipeline Framework

    ZenML: Framework Pipeline MLOps yang Modular dan Cloud-Agnostic Pendahuluan Membangun model machine learning yang akurat...