CI/CDパイプラインにAI品質ゲートを組み込む方法

GitHub ActionsによるMLモデルの自動品質チェック。精度劣化の検知からデプロイ承認まで、AIシステムのCI/CDパイプライン設計を解説します。

約2分で読めます
#CI/CD #GitHub Actions #MLOps #モデル評価 #自動化

「モデルの精度が先週より落ちているけど、誰も気づいていなかった」——よくある話だ。AIシステムは一度デプロイすると「動いているから大丈夫」と思われがちだが、データの変化やモデルの更新によって静かに品質が劣化する。CI/CDパイプラインにAI品質ゲートを組み込むことで、この問題を自動検知できる。

AI品質ゲートとは何か

ソフトウェア開発におけるCI/CDは、コードが正しく動くかをテストし、合格したものだけをデプロイする仕組みだ。AI品質ゲートは、この考え方をモデルに適用したものだ。

  • 新しいモデルの精度が、現行モデルより低下していないか
  • テストデータに対して、設定した閾値を超えているか
  • 推論レイテンシが許容範囲内に収まっているか
  • 特定のエッジケースで破綻していないか

これらをPRマージやデプロイのたびに自動チェックし、基準を満たさないものは本番に出さない——それがAI品質ゲートの役割だ。

GitHub Actions によるパイプライン構成

全体構成

┌─────────────────────────────────────────┐
│  PR作成 / main pushをトリガー            │
└──────────────┬──────────────────────────┘

    ┌──────────▼──────────┐
    │  1. コード品質チェック  │  (lint, type check)
    └──────────┬──────────┘

    ┌──────────▼──────────┐
    │  2. ユニットテスト     │  (前処理・特徴量関数)
    └──────────┬──────────┘

    ┌──────────▼──────────┐
    │  3. モデル評価         │  (精度・性能テスト)
    └──────────┬──────────┘

    ┌──────────▼──────────┐
    │  4. 品質ゲート判定     │  (閾値チェック)
    └──────────┬──────────┘
               │ 合格のみ通過
    ┌──────────▼──────────┐
    │  5. ステージングデプロイ │
    └─────────────────────┘

Step 1-2: コード品質・ユニットテスト

# .github/workflows/ml-ci.yml
name: ML CI/CD Pipeline

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  code-quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
          cache: 'pip'
      - run: pip install -r requirements.txt
      - name: Lint
        run: |
          ruff check src/
          mypy src/ --ignore-missing-imports
      - name: Unit tests
        run: pytest tests/unit/ -v --tb=short

Step 3: モデル評価

  model-evaluation:
    needs: code-quality
    runs-on: ubuntu-latest
    outputs:
      accuracy: ${{ steps.evaluate.outputs.accuracy }}
      f1_score: ${{ steps.evaluate.outputs.f1_score }}
      latency_p95: ${{ steps.evaluate.outputs.latency_p95 }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
          cache: 'pip'
      - run: pip install -r requirements.txt

      - name: Download test dataset
        run: |
          aws s3 cp s3://your-bucket/test-data/golden_set.csv data/
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: Run model evaluation
        id: evaluate
        run: |
          python scripts/evaluate_model.py \
            --model-path models/candidate/ \
            --test-data data/golden_set.csv \
            --output results.json
          
          ACCURACY=$(jq -r '.accuracy' results.json)
          F1=$(jq -r '.f1_score' results.json)
          LATENCY=$(jq -r '.latency_p95' results.json)
          
          echo "accuracy=$ACCURACY" >> $GITHUB_OUTPUT
          echo "f1_score=$F1" >> $GITHUB_OUTPUT
          echo "latency_p95=$LATENCY" >> $GITHUB_OUTPUT

Step 4: 品質ゲート判定

  quality-gate:
    needs: model-evaluation
    runs-on: ubuntu-latest
    steps:
      - name: Check quality thresholds
        run: |
          ACCURACY=${{ needs.model-evaluation.outputs.accuracy }}
          F1=${{ needs.model-evaluation.outputs.f1_score }}
          LATENCY=${{ needs.model-evaluation.outputs.latency_p95 }}
          
          FAILED=0
          
          # 精度チェック (閾値: 90%)
          if (( $(echo "$ACCURACY < 0.90" | bc -l) )); then
            echo "❌ Accuracy $ACCURACY is below threshold 0.90"
            FAILED=1
          else
            echo "✅ Accuracy $ACCURACY passed"
          fi
          
          # F1スコアチェック (閾値: 0.85)
          if (( $(echo "$F1 < 0.85" | bc -l) )); then
            echo "❌ F1 score $F1 is below threshold 0.85"
            FAILED=1
          else
            echo "✅ F1 score $F1 passed"
          fi
          
          # レイテンシチェック (閾値: 500ms)
          if (( $(echo "$LATENCY > 500" | bc -l) )); then
            echo "❌ P95 latency ${LATENCY}ms exceeds 500ms"
            FAILED=1
          else
            echo "✅ P95 latency ${LATENCY}ms passed"
          fi
          
          if [ "$FAILED" -eq 1 ]; then
            echo "Quality gate failed. Deployment blocked."
            exit 1
          fi
          
          echo "All quality checks passed. Proceeding to deployment."

モデルのリグレッションテスト

精度の絶対値チェックだけでなく、現行モデルとの比較(リグレッションテスト)も重要だ。

# scripts/regression_test.py
import json
import sys
from pathlib import Path

def compare_models(candidate_results: dict, baseline_results: dict,
                   tolerance: float = 0.02) -> bool:
    """
    候補モデルが現行モデルより2%以上悪化していたら失敗とする
    """
    metrics = ['accuracy', 'f1_score', 'precision', 'recall']
    passed = True

    for metric in metrics:
        candidate = candidate_results[metric]
        baseline = baseline_results[metric]
        diff = candidate - baseline

        if diff < -tolerance:
            print(f"REGRESSION: {metric} dropped by {abs(diff):.3f} "
                  f"({baseline:.3f}{candidate:.3f})")
            passed = False
        else:
            print(f"OK: {metric} {baseline:.3f}{candidate:.3f} "
                  f"(diff: {diff:+.3f})")

    return passed

PR コメントへの結果出力

品質チェックの結果をPRのコメントとして自動投稿することで、レビュアーが確認しやすくなる。

      - name: Post results to PR
        uses: actions/github-script@v7
        if: github.event_name == 'pull_request'
        with:
          script: |
            const accuracy = '${{ needs.model-evaluation.outputs.accuracy }}';
            const f1 = '${{ needs.model-evaluation.outputs.f1_score }}';
            const latency = '${{ needs.model-evaluation.outputs.latency_p95 }}';
            
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## 🤖 モデル品質レポート\n\n| 指標 | 値 | 閾値 | 判定 |\n|---|---|---|---|\n| Accuracy | ${accuracy} | 0.90 | ${accuracy >= 0.90 ? '✅' : '❌'} |\n| F1 Score | ${f1} | 0.85 | ${f1 >= 0.85 ? '✅' : '❌'} |\n| P95 Latency | ${latency}ms | 500ms | ${latency <= 500 ? '✅' : '❌'} |`
            });

CI/CDパイプラインにAI品質ゲートを組み込むことで、「誰かが気づいたときには手遅れ」という状況を防げる。品質の劣化をシステムが自動検知し、人間は判断に集中できる——それがMLOpsの目指す姿だ。

シェアする: X でシェア LinkedIn でシェア

AI導入のご相談はこちら

クラウド基盤設計からデータ基盤・AI品質保証まで、 運用まで見据えた伴走型でサポートします。

無料相談を予約する

関連する記事