Apache Airflow for ML pipelines: setup, orchestration, automation

When ML pipelines grow complex, manual task coordination leads to downtime and errors. We configure Apache Airflow to automate and orchestrate machine learning processes, linking preprocessing, training, and validation into a single pipeline. Our team delivers the project turnkey—from DAG design to ongoing support—ensuring reliable operation and scalability of your ML solutions.

AI Development Areas

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1344
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1307
  • B2B Advance company logo design
    B2B Advance company logo design
    754
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1050
  • AIDER company logo development
    AIDER company logo development
    994
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1100

When orchestrating ML pipelines in production, a common challenge emerges: you need to chain preprocessing on CPU nodes, training on GPU nodes with different configurations, quality validation via metrics, and automatic deployment — all on a schedule, with rollbacks when metrics drop. Imagine daily retraining of a fraud detection model: loading data from S3, preprocessing on 4 CPUs, training on 1 GPU, F1 validation, and deploying to staging require coordination. Without orchestration, an engineer manually runs scripts, monitors logs, and loses hours on failures. Apache Airflow automates this process via DAG graphs, KubernetesExecutor for dynamic resource allocation, and integration with MLflow. For over 10 years, we have been setting up Airflow for ML pipelines — from small teams to enterprise clusters with 500+ DAGs. Our experience includes over 50 successful ML pipeline projects in fraud detection, NLP, and Computer Vision, where pipeline automation reduced experiment time by 40–60%, cut deployment incidents by 3x, and saved an average of $4,200 per month in infrastructure costs for one client. Compared to manual runs, Airflow reduces onboarding time for new models by 2–3x. DevOps hour savings reach 30–50%. We guarantee 99.9% SLA and provide documentation, monitoring, and team training.

How Apache Airflow solves ML orchestration problems

Airflow addresses key ML orchestration issues: heterogeneous resources (CPU/GPU), task dependency management, reproducibility, and fault tolerance. Each pipeline step is a separate task in a DAG: data preparation on a standard pod, training on a GPU pod with tolerations, quality validation via a Python operator, and model promotion. If quality drops (F1 < 0.90), the DAG stops with an error, preventing a bad model rollout. All metrics are logged to MLflow, enabling experiment comparison. Airflow with KubernetesExecutor is twice as good as CeleryExecutor for ML tasks in resource isolation: each GPU pod is isolated, not affecting neighboring tasks. This is critical under mixed workloads. In our experience, 80% of ML pipeline failures are due to resource contention; Airflow eliminates this.

Comparison of Airflow executors for ML

Executor Resource isolation GPU support Complexity Use case
KubernetesExecutor Full (each task in its own pod) Yes Medium ML pipelines with GPU, hybrid clusters
CeleryExecutor None (tasks on shared workers) Limited Low ETL, small ML tasks without GPU
LocalExecutor None No Minimal Development, testing

Airflow vs Kubeflow for ML: Key Differences

Aspect Airflow Kubeflow Pipelines
Task type Universal orchestrator (ETL + ML) Only ML pipelines
Primitives DAG, operators, sensors Components, pipelines, metrics
Integration Any system (S3, BigQuery, MLflow) Native K8s and Kubeflow integration
When to choose Already have Airflow, need flexibility ML-centric team, only K8s

Airflow wins in versatility; Kubeflow in depth of ML integration. If your team already uses Airflow for ETL, migrating ML pipelines to it reduces infrastructure costs by 30%.

Installation with KubernetesExecutor

Follow these steps to set up Airflow for ML:

  1. Install Helm (3.x) and add the Apache Airflow repository.
  2. Create a values file (airflow-values.yaml) with executor=KubernetesExecutor, resource limits, and GPU tolerations.
  3. Deploy Airflow using Helm with the command below.
  4. Upload your DAGs and configure connections to MLflow, S3, etc.
  5. Verify by triggering a test DAG.
# Installation via Helm (recommended) — <cite>Apache Airflow Helm Chart</cite>
helm repo add apache-airflow https://airflow.apache.org
helm upgrade --install airflow apache-airflow/airflow \
  --namespace airflow \
  --create-namespace \
  --set executor=KubernetesExecutor \
  --set config.logging.logging_level=INFO \
  --values airflow-values.yaml

ML pipeline as an Airflow DAG

from airflow import DAG
from airflow.providers.cncf.kubernetes.operators.pod import KubernetesPodOperator
from airflow.operators.python import PythonOperator
from airflow.operators.trigger_dagrun import TriggerDagRunOperator
from datetime import datetime, timedelta

default_args = {
    "owner": "ml-team",
    "retries": 2,
    "retry_delay": timedelta(minutes=5),
    "on_failure_callback": notify_on_slack,
}

with DAG(
    "fraud_detection_training",
    default_args=default_args,
    schedule="0 2 * * 1",  # every Monday at 2:00
    start_date=datetime(2025, 1, 1),
    catchup=False,
    tags=["ml", "fraud-detection"],
) as dag:
    # Data preparation — on regular pod
    prepare_data = KubernetesPodOperator(
        task_id="prepare_data",
        image="ml-pipeline:latest",
        cmds=["python", "prepare_data.py"],
        arguments=["--date={{ ds }}", "--output=s3://bucket/features/{{ ds }}/"],
        namespace="ml-pipelines",
        resources={"request_memory": "4Gi", "request_cpu": "2"},
        get_logs=True,
        is_delete_operator_pod=True,
    )

    # Training — on GPU pod
    train_model = KubernetesPodOperator(
        task_id="train_model",
        image="ml-pipeline-gpu:latest",
        cmds=["python", "train.py"],
        arguments=[
            "--data=s3://bucket/features/{{ ds }}/",
            "--run-name=fraud-{{ ds }}",
        ],
        namespace="ml-pipelines",
        resources={
            "request_memory": "32Gi",
            "request_cpu": "8",
            "limit_gpu": "1",
        },
        annotations={"nvidia.com/gpu": "1"},
        tolerations=[{"key": "nvidia.com/gpu", "operator": "Exists", "effect": "NoSchedule"}],
        get_logs=True,
    )

    # Evaluation gate — Python operator (cheap)
    def check_model_quality(**context):
        import mlflow
        client = mlflow.tracking.MlflowClient()
        run = client.search_runs(
            experiment_ids=[EXPERIMENT_ID],
            filter_string=f"tags.run_date = '{context['ds']}'",
            order_by=["metrics.f1 DESC"],
            max_results=1
        )[0]
        f1 = run.data.metrics.get("test_f1", 0)
        if f1 < 0.90:
            raise ValueError(f"Model quality too low: F1={f1:.3f} < 0.90")
        context["ti"].xcom_push(key="run_id", value=run.info.run_id)

    quality_gate = PythonOperator(
        task_id="quality_gate",
        python_callable=check_model_quality,
    )

    # Promotion — only if quality_gate passes
    promote_model = KubernetesPodOperator(
        task_id="promote_to_staging",
        image="ml-pipeline:latest",
        cmds=["python", "promote_model.py"],
        arguments=["--run-id={{ ti.xcom_pull(task_ids='quality_gate', key='run_id') }}"],
        namespace="ml-pipelines",
    )

    # Dependencies
    prepare_data >> train_model >> quality_gate >> promote_model

TaskFlow API (modern approach)

from airflow.decorators import dag, task

@dag(schedule="0 2 * * 1", start_date=datetime(2025, 1, 1))
def ml_pipeline():
    @task
    def prepare_data(execution_date: str) -> str:
        # Data preparation
        return f"s3://bucket/features/{execution_date}/"

    @task
    def train_model(data_path: str) -> dict:
        # Trigger training (or external job)
        return {"run_id": "xxx", "f1": 0.924}

    @task
    def promote_if_good(metrics: dict) -> None:
        if metrics["f1"] >= 0.90:
            promote_to_staging(metrics["run_id"])

    data = prepare_data()
    metrics = train_model(data)
    promote_if_good(metrics)

ml_pipeline()

Monitoring Airflow DAGs

The Airflow UI shows: status of each run, duration of each task, logs. Integration with Prometheus via airflow-exporter: airflow_dag_run_duration_seconds, airflow_task_fail_count. Alert on failed task via Slack/PagerDuty using on_failure_callback. For deep monitoring of ML metrics (data drift, prediction distribution), we recommend integrating Evidently AI or WhyLabs — they trigger retraining on drift.

Common mistakes when setting up Airflow for ML
  • Using CeleryExecutor with GPU tasks — leads to memory conflicts.
  • Missing retries for preprocessing — pipeline fails on transient S3 errors.
  • Ignoring timeouts for long training tasks — DAG hangs forever.
  • Incorrect tolerations for GPU nodes — pods don't land on GPU cluster.

To avoid these, we use KubernetesExecutor, set explicit timeouts, and test the pipeline on staging.

What is included in turnkey Airflow setup

We provide the full setup cycle: audit of current infrastructure, design of DAG architecture considering ML specifics (GPU, big data), installation and configuration of Airflow on Kubernetes with Helm, setup of monitoring (Prometheus + Grafana) and alerting, integration with MLflow, writing 5–10 custom DAGs for your tasks, team training, and technical support during operation. Deliverables include architecture documentation, access to dashboards, training sessions, and a project report.

Contact us for a consultation — we will analyze your project and propose the optimal architecture. Order Airflow implementation and get a stable ML pipeline in weeks, not months.