Apache Airflow for ML pipelines: setup, orchestration, automation

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

AI Development Areas

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1285
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1241
  • image_logo-advance_0.webp
    B2B Advance company logo design
    696
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    983
  • image_logo-aider_0.webp
    AIDER company logo development
    919
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1033

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 free consultation — we will analyze your project and propose the optimal architecture. Order Airflow implementation and get a stable ML pipeline in weeks, not months.