====== Modul 4: Kontinuerlig integrering och driftsättning för ML ======
===== Översikt =====
I denna modul utforskar vi tillämpningen av kontinuerlig integrering och driftsättning (CI/CD) specifikt för maskininlärningssystem. Vi kommer att lära oss hur man anpassar traditionella CI/CD-praktiker för att hantera de unika utmaningarna med ML, inklusive dataversionshantering, modellvalidering och A/B-testning. Modulen fokuserar på att bygga automatiserade arbetsflöden som säkerställer att ML-modeller kan utvecklas, testas och driftsättas på ett säkert och effektivt sätt.
===== Lärandemål =====
Efter denna modul kommer du att:
* Förstå skillnaden mellan traditionell CI/CD och ML-specifik CI/CD
* Kunna implementera CI/CD-pipelines för ML-projekt
* Behärska modellvalidering och godkännandeprocesser
* Skapa automatiserade driftsättningsstrategier för ML-modeller
* Implementera A/B-testning för modeller i produktion
* Hantera rollback och återställning av ML-system
===== 4.1 Introduktion till CI/CD för ML =====
==== Traditionell CI/CD vs. ML CI/CD ====
| **Aspekt** | **Traditionell CI/CD** | **ML CI/CD** |
| **Artefakter** | Kodbaserade binärer/containers | Modeller + kod + konfiguration |
| **Validering** | Enhetstester, integrationstester | Datakvalitetstester, modellvalideringstester |
| **Miljövariabler** | Konfiguration, endpoints | Feature stores, modellparametrar |
| **Byggsteg** | Kompilering, paketisering | Träning, validering, paketisering |
| **Tidsåtgång** | Minuter | Timmar till dagar (för träning) |
| **Driftsättning** | Vanligtvis atomär | Kan kräva gradvis utrullning |
| **Rollback** | Relativt enkel (tidigare version) | Komplex (återställ data + modell) |
==== CI/CD/CT (Continuous Training) ====
ML-system introducerar ett nytt koncept: Continuous Training (CT), som innebär automatisk omträning av modeller när:
* Nya data blir tillgängliga
* Modellprestanda sjunker under ett tröskelvärde
* Koden för modellarkitekturen uppdateras
* Feature engineering ändras
==== MLOps CI/CD-mognadsnivåer ====
* **Nivå 0**: Manuell process - ingen CI/CD
* **Nivå 1**: ML-pipeline-automatisering - CI för kod, manuell CD
* **Nivå 2**: CI/CD-pipeline-automatisering - automatiserad driftsättning
* **Nivå 3**: Fullständig CI/CD/CT - automatiserad omträning och driftsättning
===== 4.2 Implementering av CI för ML-projekt =====
==== Komponenter i ML CI-pipelines ====
* **Kodkvalitetskontroll**: Linting, formatering, statisk kodanalys
* **Enhetstestning**: Testa individuella komponenter
* **Integrationstestning**: Testa samverkan mellan komponenter
* **Datakvalitetstestning**: Validera att data uppfyller förväntningar
* **Lightweight modellträning**: Träna på mindre dataset för verifiering
* **Modellutvärdering**: Validera modellprestanda mot baselines
==== Implementering med GitHub Actions ====
# .github/workflows/mlops-ci.yml
name: MLOps CI Pipeline
on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest pytest-cov
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
- name: Test with pytest
run: |
pytest tests/ --cov=src
- name: Run data quality checks
run: |
python scripts/validate_data.py --data-path data/sample.csv
- name: Run lightweight model training
run: |
python scripts/train_model.py --small-dataset --epochs 1
- name: Validate model performance
run: |
python scripts/evaluate_model.py --model-path models/latest.h5 --threshold 0.7
==== Data-relaterade CI-kontroller ====
* **Dataintegritet**: Kontrollera att data uppfyller scheman och begränsningar
* **Datafördelning**: Validera att datafördelningen inte har förändrats avsevärt
* **Feature drift**: Kontrollera att feature-fördelningen är konsekvent
* **Referensdata**: Jämför med referensdataset för att upptäcka avvikelser
==== Användning av DVC för datapipelines i CI ====
# .github/workflows/dvc-data-ci.yml
name: DVC Data Pipeline CI
on:
push:
branches: [ main ]
paths:
- 'data/**'
- 'dvc.yaml'
- 'params.yaml'
jobs:
data_pipeline:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install dvc dvc[s3]
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- name: Pull DVC data
run: |
dvc pull
- name: Run DVC pipeline
run: |
dvc repro
- name: Run data validation
run: |
python scripts/validate_data_pipeline.py
- name: Push DVC results
run: |
dvc push
===== 4.3 Implementering av CD för ML-projekt =====
==== Komponenter i ML CD-pipelines ====
* **Modellvalidering**: Grundlig utvärdering av modellprestanda
* **Modelljämförelse**: Jämförelse med nuvarande produktionsmodell
* **Modellåtgärdsplan**: Automatisk godkännande eller manuell granskning
* **Modellpaketisering**: Förpackning av modeller för driftsättning
* **Infrastrukturförberedelse**: Skapande eller uppdatering av infrastruktur
* **Driftsättning**: Publicering av modellen i produktionsmiljö
* **Post-driftsättningsvalidering**: Kontrollera att driftsättningen lyckades
==== Implementering med GitHub Actions och AWS =====
# .github/workflows/mlops-cd.yml
name: MLOps CD Pipeline
on:
workflow_run:
workflows: ["MLOps CI Pipeline"]
branches: [main]
types: [completed]
jobs:
deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install awscli boto3
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- name: Download model from S3
run: |
aws s3 cp s3://my-model-bucket/models/latest/ ./models/latest/ --recursive
- name: Validate model
run: |
python scripts/validate_model_for_production.py --model-path models/latest/model.h5
- name: Compare with current production model
run: |
python scripts/compare_models.py --new-model models/latest/model.h5 --threshold 0.05
- name: Package model as Docker image
run: |
docker build -t my-model-service:${{ github.sha }} .
- name: Push Docker image to ECR
run: |
aws ecr get-login-password | docker login --username AWS --password-stdin ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.eu-west-1.amazonaws.com
docker tag my-model-service:${{ github.sha }} ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.eu-west-1.amazonaws.com/my-model-service:${{ github.sha }}
docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.eu-west-1.amazonaws.com/my-model-service:${{ github.sha }}
- name: Update ECS service
run: |
aws ecs update-service --cluster ml-cluster --service my-model-service --force-new-deployment
- name: Wait for deployment
run: |
aws ecs wait services-stable --cluster ml-cluster --services my-model-service
- name: Validate deployment
run: |
python scripts/validate_deployment.py --endpoint https://api.example.com/model
==== CD för gradvis utrullning av modeller ====
* **Canary releases**: Driftsättning till en liten användargrupp först
* **Blue/Green-driftsättning**: Parallella miljöer för snabb växling
* **Feature flagging**: Aktivera/inaktivera specifika modellversioner för olika användare
==== Exempel på gradvis utrullning med Kubernetes ====
# kubernetes/model-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: model-service
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: model-service
template:
metadata:
labels:
app: model-service
spec:
containers:
- name: model-service
image: my-model-registry/model-service:latest
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: "1"
memory: "2Gi"
requests:
cpu: "0.5"
memory: "1Gi"
===== 4.4 A/B-testning av ML-modeller =====
==== A/B-testning för ML ====
* **Definition**: Jämför två modellversioner i produktion för att avgöra vilken som presterar bättre
* **Användningsfall**: Validera modellförbättringar, experimentera med nya algoritmer, optimera affärsmätvärden
* **Key Performance Indicators (KPIs)**: Definiera tydliga framgångsmätvärden
==== Implementering av A/B-testning ====
* **Trafikuppdelning**: Ruttning av användare till olika modellversioner
* **Statistisk utvärdering**: Beräkning av statistisk signifikans
* **Automatisk promotion**: Främjande av den vinnande modellen
==== Exempel på A/B-testning med AWS SageMaker ====
import boto3
import json
# Skapa en SageMaker-klient
sagemaker_client = boto3.client('sagemaker')
# Konfigurera A/B-testning
response = sagemaker_client.create_endpoint_config(
EndpointConfigName='my-ab-test-config',
ProductionVariants=[
{
'VariantName': 'ModelA',
'ModelName': 'model-a',
'InitialInstanceCount': 1,
'InstanceType': 'ml.c5.large',
'InitialVariantWeight': 0.5
},
{
'VariantName': 'ModelB',
'ModelName': 'model-b',
'InitialInstanceCount': 1,
'InstanceType': 'ml.c5.large',
'InitialVariantWeight': 0.5
}
]
)
# Skapa eller uppdatera endpoint
response = sagemaker_client.create_endpoint(
EndpointName='my-ab-test-endpoint',
EndpointConfigName='my-ab-test-config'
)
# För att anropa en specifik modellvariant för testning
runtime_client = boto3.client('sagemaker-runtime')
response = runtime_client.invoke_endpoint(
EndpointName='my-ab-test-endpoint',
ContentType='application/json',
TargetVariant='ModelA', # Specifikt anropa ModelA
Body=json.dumps({"features": [1, 2, 3, 4]})
)
==== Övervakning och utvärdering av A/B-testresultat ====
* **Datainsamling**: Lagring av prediktioner och utfall för varje variant
* **Mätning**: Beräkning av KPIs för varje modellvariant
* **Visualisering**: Dashboards för att visa testresultat över tid
* **Automatiskt beslut**: Algoritmer för att avgöra när testet kan avslutas
===== 4.5 Automationsstrategier för ML-driftsättning =====
==== Triggers för automatisk driftsättning ====
* **Data-driven**: Trigga vid nya data eller dataförändring
* **Prestanda-driven**: Trigga när modellprestanda sjunker
* **Schema-driven**: Regelbunden omträning och driftsättning
* **Händelse-driven**: Trigga vid specifika händelser, t.ex. kodändringar
==== Hantering av driftsättningsfrekvens ====
* **Hög frekvens**: Kontinuerlig omträning för snabbt föränderliga data
* **Medelhög frekvens**: Daglig eller veckovis omträning
* **Låg frekvens**: Månatlig eller kvartalsvis omträning
==== Automatiserad godkännandeprocess ====
* **Automatiskt godkännande**: För mindre modellförändringar
* **Semi-automatiskt godkännande**: Automatisk validering + manuell granskning
* **Manuellt godkännande**: För större modellförändringar eller känsliga system
==== Exempel på godkännandeprocess i ML-pipeline ====
def evaluate_and_approve_model(model_path, production_model_path, metrics_threshold):
"""Utvärd och godkänn en modell baserat på tröskelvärden"""
# Ladda modellerna
new_model = load_model(model_path)
prod_model = load_model(production_model_path)
# Utvärdera på testdata
new_metrics = evaluate_model(new_model, test_data)
prod_metrics = evaluate_model(prod_model, test_data)
# Beräkna prestandaförbättring
improvement = {}
for metric_name, threshold in metrics_threshold.items():
improvement[metric_name] = new_metrics[metric_name] - prod_metrics[metric_name]
# Kontrollera om alla tröskelvärden är uppfyllda
approval_decision = True
approval_reasons = []
for metric_name, threshold in metrics_threshold.items():
if improvement[metric_name] < threshold:
approval_decision = False
approval_reasons.append(f"{metric_name} förbättring {improvement[metric_name]:.4f} under tröskelvärde {threshold}")
if approval_decision:
approval_reasons.append("Alla prestandamätvärden möter förbättringströskelvärdena")
return {
"approved": approval_decision,
"reasons": approval_reasons,
"metrics": new_metrics,
"improvement": improvement
}
===== 4.6 Rollback och återhämtningsstrategier =====
==== Utmaningar med ML-rollbacks ====
* **Komplex återställning**: Modell + infrastruktur + data
* **Data dependencies**: Modeller är beroende av historiska data
* **Dåliga prediktioner**: Felaktiga prediktioner kan propagera i system
==== Implementering av effektiva rollback-mekanismer ====
* **Modellversionering**: Tydlig spårning av alla driftsatta modeller
* **Infrastruktur som kod**: Versionerad infrastruktur för återställning
* **Observabilitet**: Tidig upptäckt av problem
* **Automatisk återställning**: Självläkande system vid upptäckt av problem
==== Exempel på automatisk rollback-logik ====
def monitor_and_rollback_if_needed(deployed_model_id, performance_threshold, window_size=1000):
"""Övervaka modellprestanda och återställ om den faller under tröskelvärdet"""
# Hämta senaste prestandamätvärden
recent_metrics = get_recent_metrics(deployed_model_id, window_size)
# Beräkna genomsnittlig prestanda
avg_performance = np.mean([m['accuracy'] for m in recent_metrics])
if avg_performance < performance_threshold:
print(f"Modellprestanda {avg_performance:.4f} under tröskelvärde {performance_threshold}")
# Hämta tidigare (stabil) modellversion
previous_stable_model = get_previous_stable_model()
# Initiera rollback
rollback_success = initiate_rollback(deployed_model_id, previous_stable_model.id)
if rollback_success:
print(f"Rollback till modell {previous_stable_model.id} lyckades")
# Skicka notifiering till team
send_alert(
subject="Automatisk modellrollback utförd",
message=f"Modell {deployed_model_id} återställd till {previous_stable_model.id} på grund av låg prestanda"
)
else:
print("Rollback misslyckades, eskalera till manuell åtgärd")
# Skicka larmnotifiering för manuell åtgärd
send_alert(
subject="AKUT: Modellrollback misslyckades",
message=f"Manuell åtgärd krävs för modell {deployed_model_id}",
priority="high"
)
else:
print(f"Modellprestanda {avg_performance:.4f} över tröskelvärde {performance_threshold}, ingen åtgärd krävs")
===== Praktiska övningar =====
1. **CI Pipeline**: Implementera en CI-pipeline för ett ML-projekt med GitHub Actions
2. **CD Pipeline**: Skapa en CD-pipeline för automatisk driftsättning av ML-modeller
3. **A/B-testning**: Implementera A/B-testning för två modellvarianter
4. **Rollback-strategi**: Designa och implementera en rollback-strategi för ML-modeller
===== Verktygsintroduktion =====
* **GitHub Actions**: Konfiguration för ML CI/CD
* **AWS SageMaker**: Driftsättning och A/B-testning
* **Kubernetes**: Gradvis utrullning av ML-modeller
* **FastAPI**: REST API för modellbetjäning
===== Läsresurser =====
* "Continuous Delivery for Machine Learning" - Continuous Delivery Foundation
* "Practical MLOps" - Noah Gift & Alfredo Deza
* "Implementing CI/CD for ML" - AWS Technical Guide
* "A/B Testing Machine Learning Models" - Microsoft Azure Documentation
===== Nyckelinsikter =====
* CI/CD för ML kräver särskild hänsyn till data och modeller utöver kod
* En robust modellvalideringsprocess är avgörande före driftsättning
* Gradvis utrullning och A/B-testning minskar risken för problem i produktion
* Automatiserade pipeline-triggers bör anpassas efter datans och modellens natur
* Effektiva rollback-strategier är avgörande för ML-systemens tillförlitlighet
===== Nästa steg =====
I nästa modul kommer vi att utforska containerisering och orkestrering av ML-applikationer, där vi kommer att lära oss hur man paketerar och driftsätter ML-modeller i containeriserade miljöer.