পাঠ ২১ · ৩৩-এর মধ্যে · মডিউল ৩
Home / AI Courses / MLOps / CI/CD for ML

CI/CD for ML — GitHub Actions

CI/CD for ML with GitHub Actions
৮ মিনিট পড়া মধ্য · Intermediate YAML

এই পাঠে যা শিখবেন

  • ML-specific CI test types
  • GitHub Actions workflow syntax
  • Model promotion automation
  • Secrets, caching, cost optimization

১ · ML CI different কেন

Standard software CI: lint → unit test → integration test → build → deploy. ML CI extra dimensions.

  • Data validation: schema, distribution, range.
  • Model performance: baseline-এর সাথে compare.
  • Fairness gate: subgroup metrics.
  • Resource: GPU runner expensive; CPU-only-এর alternative.

২ · Complete GitHub Actions workflow

YAML · .github/workflows/ml.yml
name: ML pipeline
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 2 * * *'  # nightly retrain
  workflow_dispatch:

env:
  PYTHON_VERSION: "3.11"
  AWS_REGION: ap-south-1

jobs:
  unit-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: ${{ env.PYTHON_VERSION }} }
      - uses: actions/cache@v4
        with:
          path: ~/.cache/pip
          key: pip-${{ hashFiles('requirements.lock') }}
      - run: pip install -r requirements.lock
      - run: pytest tests/unit/ -v

  data-validation:
    runs-on: ubuntu-latest
    needs: unit-tests
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: ${{ env.PYTHON_VERSION }} }
      - run: pip install -r requirements.lock
      - name: DVC pull
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        run: dvc pull data/
      - run: python scripts/validate_data.py data/

  train-and-evaluate:
    runs-on: [self-hosted, gpu]    # ⭐ GPU runner
    needs: data-validation
    if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
    steps:
      - uses: actions/checkout@v4
      - run: pip install -r requirements.lock
      - name: DVC pull
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        run: dvc pull data/
      - name: Train
        env:
          MLFLOW_TRACKING_URI: ${{ secrets.MLFLOW_URI }}
        run: python src/train.py
      - name: Performance regression test
        run: python scripts/check_performance.py --baseline-auc 0.92
      - name: Fairness gate
        run: python scripts/fairness_check.py --max-disparity 0.05

  build-image:
    runs-on: ubuntu-latest
    needs: train-and-evaluate
    if: success()
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          registry: ${{ secrets.REGISTRY_URL }}
          username: ${{ secrets.REGISTRY_USER }}
          password: ${{ secrets.REGISTRY_PASS }}
      - uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            ${{ secrets.REGISTRY_URL }}/sentiment:${{ github.sha }}
            ${{ secrets.REGISTRY_URL }}/sentiment:latest
          cache-from: type=registry,ref=${{ secrets.REGISTRY_URL }}/sentiment:buildcache
          cache-to: type=registry,ref=${{ secrets.REGISTRY_URL }}/sentiment:buildcache,mode=max

  deploy-staging:
    runs-on: ubuntu-latest
    needs: build-image
    environment: staging   # ⭐ environment-protection
    steps:
      - uses: actions/checkout@v4
      - uses: azure/setup-kubectl@v3
      - run: |
          kubectl set image deployment/sentiment-api \
            sentiment=${{ secrets.REGISTRY_URL }}/sentiment:${{ github.sha }} \
            -n staging
          kubectl rollout status deployment/sentiment-api -n staging

    
Pattern features: matrix-aware caching, secrets, GPU self-hosted runner, conditional training (schedule/manual only), environment protection (deploy-staging requires approval).

৩ · ML-specific tests

  • Unit: preprocess function, custom transform — fast.
  • Data validation: Great Expectations / Pandera — schema, range, missing.
  • Performance regression: "AUC ≥ baseline + tolerance".
  • Fairness: "subgroup accuracy gap < threshold".
  • Schema match: training input == serving input.
  • Smoke test: sample inference end-to-end.
  • Latency benchmark: p99 < SLA.

৪ · Secrets management

  • GitHub Actions Secrets — encrypted at rest, exposed as env var.
  • For sensitive: external secret manager (AWS Secrets Manager, Vault) + GH Action fetch.
  • Never echo secret in logs.
  • Rotation periodic.

৫ · Self-hosted runners

GitHub-hosted runners CPU-only. GPU training-এর জন্য self-hosted.

  • EC2/on-prem GPU machine — runner agent install.
  • Labels: self-hosted, gpu, a100.
  • Workflow-এ runs-on: [self-hosted, gpu].
  • Security: ephemeral runner per job (containers).

৬ · Cost optimization

  • Caching: pip, Docker layer, DVC cache.
  • Conditional jobs: path filter — code change only triggers build, doc change skips.
  • Concurrent limit: avoid burst on PR open.
  • Self-hosted: 70-90% cheaper for high-utilization.
  • Spot instances: on-demand spot interrupt-tolerant.
ML CI/CD pipeline — code commit থেকে production git push PR / main Unit + lint 2 min Data validate schema, drift Train + eval GPU runner Performance gate baseline check Fairness gate Build image Deploy staging Manual approval prod Canary 5% Full prod
CI pipeline — fail-fast: each gate stop pipeline; production reach hard intentionally.
Bangladesh-এ GitHub Actions বহুল-adopted. GitLab CI alternative. On-prem GitLab self-hosted (compliance shop).

ভাবনার প্রশ্ন

প্র ০১"PR-এ কী test, nightly-তে কী test?"

CI cost ও speed-এর জন্য test stratification.

Per-PR (fast, cheap):

  • Lint, unit test (Python function).
  • Schema validation.
  • Mock-based integration test.
  • Build container (cache-aware).
  • Total: 5-15 মিনিট।

Nightly (expensive):

  • Full training run.
  • Performance regression.
  • Fairness audit.
  • Latency benchmark.
  • Total: 1-3 ঘণ্টা।

Pre-merge (manual trigger):

  • Major change PR-এ explicit "/test full" comment.
  • Run nightly-suite.
  • Trade-off: PR slow, but catch issues early.

Path-based filter:

  • Doc only — skip CI.
  • Code only — skip data validation.
  • Workflow change — full test.

মূল উপলব্ধি: Cost-conscious CI = stratification + caching + filter. Per-PR fast feedback; nightly comprehensive. Big change manual trigger.

প্র ০২"Flaky model tests — কীভাবে handle?"

Statistical model — same code, same data, slightly different result possible. Flaky test painful.

Sources of flakiness:

  • Random seed not pinned.
  • Hardware non-determinism (GPU).
  • Test data sampling.
  • External dependency (Feature Store, S3).

Mitigations:

  • Seed everything (Lesson 5).
  • Tolerance-based assertion: assert abs(auc - 0.92) < 0.005 (not exact).
  • Statistical test: 10 runs avg ± std.
  • Snapshot test fixed dataset.

"Quarantine flaky" pattern:

  • Mark flaky test, don't fail PR.
  • Track separately, fix sprint-level.
  • Don't ignore; address as tech debt.

Retry policy:

  • 3-retry max, fail if all fail.
  • Random seed-different retries — better statistical confidence.

মূল উপলব্ধি: Statistical CI tests — tolerance + reproducibility + quarantine. Pretending no flakes — eventually false alarms erode trust.

প্র ০৩"GH Actions GPU runner self-host vs cloud — Bangladesh team?"

GPU CI cost — Bangladesh teams strategic decision.

Cloud GPU runner (e.g., GitHub Larger runners):

  • $0.07/min for A100 ≈ $4.20/hour.
  • 2-hour nightly = $8/run × 30 = $240/month.
  • Pros: zero ops, on-demand.
  • Cons: cost compounds, queue at busy times.

Self-hosted EC2/on-prem GPU:

  • EC2 g5.xlarge spot: $0.5/hour.
  • 2-hour run × 30 days = $30/month + ops.
  • Pros: cheap, controlled.
  • Cons: maintenance, security.

On-prem GPU (existing):

  • Cost: amortized hardware + power + cooling.
  • Bangladesh power outage — UPS, backup.
  • Idle time wasted (CI mostly nighttime).

Hybrid pattern:

  • GH-hosted CPU for normal CI.
  • Self-hosted GPU for nightly training.
  • Spot instance for cost optimization.

Security:

  • Ephemeral runners — delete after job.
  • Don't run untrusted PR on self-hosted (CI escape risk).

মূল উপলব্ধি: High-utilization → self-hosted. Low-utilization → cloud. Bangladesh hybrid common — on-prem dev runner, cloud burst for peaks.

প্র ০৪"Promotion gates — কত strict, কত flexible?"

Gates too strict — innovation slow. Too lax — bad model production-এ। Balance critical.

Strict gates (must pass):

  • Schema match — training input == serving input.
  • Smoke test — sample inference works.
  • Latency < SLA.
  • Critical fairness (legal compliance).

Flexible gates (warning, not block):

  • Slight accuracy drop (within tolerance).
  • Subgroup performance variance (within target).
  • Computational efficiency.

Override mechanism:

  • Lead-DS approval comment — bypass for specific PR.
  • Documented in PR description "why bypass".
  • Audit log of overrides.

Calibration over time:

  • Initial gates conservative.
  • Loosen as confidence builds.
  • Tighten if incidents.

BD context — fintech:

  • Bangladesh Bank compliance — strict gates non-negotiable.
  • Internal-only model — looser.

মূল উপলব্ধি: Gate strictness business risk-driven. Start strict, calibrate over time. Override mechanism essential — pure-strict eventually shipped around.

অনুশীলন

  1. Setup: উপরের workflow নিজের project-এ adapt. Secrets manage.

    Repo settings → Secrets and variables → Actions. AWS_ACCESS_KEY_ID etc. add.

  2. Performance gate: python script লিখুন যা MLflow latest run-এর AUC compare.

    mlflow.search_runs দিয়ে latest + baseline AUC. Tolerance check. sys.exit(1) on fail.

  3. চিন্তা: ৩-environment (dev/stg/prod) workflow design করুন।
    • dev: every PR auto deploy + smoke test.
    • staging: main merge → auto deploy + integration test.
    • prod: tag push → environment approval (lead-DS) → canary 5% → full.

আরও পড়ুন

পূর্ববর্তী পাঠ
পাঠ ২০ · Model optimization