أساسيات CI/CD للتعلم الآلي
مفهوم التدريب المستمر (CT)
3 دقيقة للقراءة
CI/CD يوصل نموذجك للإنتاج. لكن ماذا يحدث عندما يتدهور هذا النموذج؟ التدريب المستمر (CT) يعيد تدريب النماذج تلقائياً عند الحاجة—مكملاً حلقة أتمتة التعلم الآلي.
ما وراء CI/CD: امتداد CT
CI/CD التقليدي:
تغيير الكود → البناء → الاختبار → النشر
ML CI/CD + CT:
تغيير الكود ─┐
تغيير البيانات─┼─→ البناء → الاختبار → النشر ─┐
الجدول ─┤ │
تنبيه الانحراف─┘ │
│
┌───────────────────────────────────────────┘
│
▼
المراقبة → اكتشاف الانحراف → محفز إعادة التدريب → خط أنابيب CI/CD
استراتيجيات محفزات CT
محفزات مختلفة تناسب سيناريوهات مختلفة:
| المحفز | متى تستخدمه | مثال |
|---|---|---|
| مجدول | أنماط بيانات متوقعة | إعادة التدريب أسبوعياً لطلب التجزئة |
| قائم على البيانات | بيانات جديدة متاحة | إعادة التدريب عند وصول 10K عينة جديدة |
| قائم على الأداء | تدهور النموذج | إعادة التدريب عند انخفاض الدقة تحت 0.80 |
| قائم على الانحراف | تغير التوزيع | إعادة التدريب عند PSI > 0.2 |
| عند الطلب | متطلب عمل | إعادة التدريب بعد إطلاق منتج كبير |
تنفيذ CT مع GitHub Actions
إعادة التدريب المجدولة
name: Scheduled Retraining
on:
schedule:
- cron: '0 2 * * 0' # كل أحد الساعة 2 صباحاً
workflow_dispatch: # السماح بالتحفيز اليدوي
jobs:
check-and-retrain:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check if retraining needed
id: check
run: |
python scripts/check_retrain_needed.py
echo "needed=$(cat retrain_needed.txt)" >> $GITHUB_OUTPUT
- name: Trigger training pipeline
if: steps.check.outputs.needed == 'true'
run: |
gh workflow run train.yml
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
المحفز القائم على الأداء
name: Performance Monitor
on:
schedule:
- cron: '0 * * * *' # كل ساعة
jobs:
monitor:
runs-on: ubuntu-latest
steps:
- name: Check model performance
run: |
python scripts/check_performance.py \
--model-name "fraud-detector" \
--min-accuracy 0.80
- name: Trigger retraining if degraded
if: failure()
run: |
gh workflow run train.yml \
--field reason="performance_degradation"
محفز انحراف البيانات
# scripts/check_drift.py
import pandas as pd
from scipy import stats
def calculate_psi(baseline, current, bins=10):
"""Calculate Population Stability Index."""
baseline_hist, edges = np.histogram(baseline, bins=bins)
current_hist, _ = np.histogram(current, bins=edges)
baseline_pct = baseline_hist / len(baseline)
current_pct = current_hist / len(current)
# تجنب القسمة على صفر
baseline_pct = np.where(baseline_pct == 0, 0.0001, baseline_pct)
current_pct = np.where(current_pct == 0, 0.0001, current_pct)
psi = np.sum((current_pct - baseline_pct) * np.log(current_pct / baseline_pct))
return psi
def check_drift(feature_name, threshold=0.2):
baseline = pd.read_parquet(f"data/baseline/{feature_name}.parquet")
current = pd.read_parquet(f"data/current/{feature_name}.parquet")
psi = calculate_psi(baseline[feature_name], current[feature_name])
if psi > threshold:
print(f"Drift detected in {feature_name}: PSI={psi:.3f}")
return True
return False
أنماط معمارية CT
النمط 1: CT مجدول بسيط
┌─────────────────────────────────────────┐
│ CT مجدول بسيط │
├─────────────────────────────────────────┤
│ │
│ Cron ──▶ سحب البيانات ──▶ تدريب ──▶ نشر│
│ (أسبوعياً) │
│ │
└─────────────────────────────────────────┘
الإيجابيات: بسيط، متوقع السلبيات: قد يعيد التدريب بدون ضرورة أو يفوت الانحراف
النمط 2: CT مراقَب
┌─────────────────────────────────────────┐
│ CT مراقَب │
├─────────────────────────────────────────┤
│ │
│ الإنتاج ──▶ المراقبة ──▶ انحراف؟ │
│ │ │ │
│ │ ▼ نعم │
│ │ إعادة التدريب │
│ │ │ │
│ └────────────────────────┘ │
│ النشر │
└─────────────────────────────────────────┘
الإيجابيات: يعيد التدريب فقط عند الحاجة السلبيات: يتطلب بنية تحتية للمراقبة
النمط 3: CT الظلي
┌─────────────────────────────────────────┐
│ CT الظلي │
├─────────────────────────────────────────┤
│ │
│ نموذج الإنتاج ──▶ خدمة حركة المرور │
│ │ │
│ ▼ │
│ إعادة التدريب المستمرة (ظل) │
│ │ │
│ ▼ │
│ الظل أفضل؟ ──نعم──▶ ترقية │
│ │
└─────────────────────────────────────────┘
الإيجابيات: دائماً لديه نموذج جاهز محدث السلبيات: تكاليف حوسبة أعلى
أفضل ممارسات CT
| الممارسة | لماذا |
|---|---|
| إصدار كل شيء | معرفة ما تغير بالضبط بين إعادات التدريب |
| أتمتة التحقق | لا تنشر أبداً نموذج متدهور |
| ضع تنبيهات، ليس فقط محفزات | البشر يجب أن يعرفوا متى يعمل CT |
| ميزانية للحوسبة | CT يزيد تكاليف التدريب |
| اختبار A/B للنماذج الجديدة | لا تفترض أن المُعاد تدريبه أفضل |
مستويات MLOps من Google وCT
Google يحدد مستويات نضج MLOps بناءً على أتمتة CT:
| المستوى | نهج CT |
|---|---|
| المستوى 0 | إعادة التدريب اليدوية |
| المستوى 1 | خط أنابيب تدريب آلي، تحفيز يدوي |
| المستوى 2 | CT آلي مع محفزات المراقبة |
المقاييس الرئيسية لقرارات CT
# مثال: منطق قرار CT
def should_retrain():
metrics = get_current_metrics()
# تدهور الأداء
if metrics['accuracy'] < ACCURACY_THRESHOLD:
return True, "accuracy_drop"
# انحراف البيانات
if metrics['psi'] > PSI_THRESHOLD:
return True, "data_drift"
# القِدم
if days_since_last_train() > MAX_MODEL_AGE:
return True, "model_staleness"
# حجم بيانات جديدة
if new_samples_count() > MIN_NEW_SAMPLES:
return True, "new_data_available"
return False, None
الرؤية الرئيسية: CT ليس عن إعادة التدريب أكثر—إنه عن إعادة التدريب في الوقت المناسب بالبيانات المناسبة.
التالي، سنستعرض مشهد الأدوات لـ ML CI/CD. :::