====== Modul 5: Containerisering och orkestrering av ML-applikationer ====== ===== Översikt ===== I denna modul fokuserar vi på hur containerteknologier och orkestreringsplattformar kan användas för att paketera, driftsätta och skala ML-modeller i produktionsmiljöer. Vi utforskar hur man kan bygga portabla, reproducerbara och skalbara ML-applikationer med hjälp av Docker och Kubernetes. Modulen behandlar även hur man kan hantera resursbehov, skalning och lastbalansering för prediktions-API:er och batchprocessering. ===== Lärandemål ===== Efter denna modul kommer du att: * Förstå fördelarna med containerisering för ML-system * Kunna bygga optimerade Docker-images för ML-modeller * Behärska driftsättning av ML-modeller i Kubernetes * Implementera skalningsstrategier för varierande belastning * Hantera GPU-resurser i containeriserade miljöer * Designa lösningar för både realtidsprediktioner och batchinferens ===== 5.1 Introduktion till containerisering för ML ===== ==== Varför containerisering för ML? ==== * **Miljöisolering**: Löser "fungerar på min maskin"-problem * **Reproduktion**: Säkerställer att modeller körs i identiska miljöer * **Portabilitet**: Enkel förflyttning mellan utveckling, test och produktion * **Skalbarhet**: Enkel skalning upp och ner baserat på belastning * **Versionering**: Tydlig spårning av miljö och modellversioner * **Resurseffektivitet**: Bättre resursutnyttjande än virtuella maskiner ==== Containerteknologier för ML ==== * **Docker**: De facto-standard för containerisering * **Singularity**: Populärt för HPC (High-Performance Computing) och GPU-arbetslaster * **Containerd**: Lättviktig container runtime * **Podman**: Daemonless containerhantering ==== Grundläggande Docker-koncept för ML ==== * **Images**: Paketerad miljö för ML-modeller * **Containers**: Körande instanser av images * **Dockerfile**: Definition av en Docker-image * **Registry**: Lagring och distribution av images (Docker Hub, ECR, etc.) * **Nätverk**: Kommunikation mellan containers * **Volymer**: Persistent datalagring ===== 5.2 Containerisering av ML-modeller med Docker ===== ==== Optimala Dockerfile-strategier för ML ==== * **Base images**: Val av lämpliga bas-images (TensorFlow, PyTorch, etc.) * **Multi-stage builds**: Separera träning från inferens * **Layer-optimering**: Minimera antalet lager och storleken * **Dependency management**: Hantering av biblioteksberoenden * **Caching**: Effektiv caching för snabbare byggen ==== Exempel på Dockerfile för ML-modell ==== # Multi-stage build för en ML-modell # Byggfas - använd officiell TensorFlow-image med GPU-stöd FROM tensorflow/tensorflow:2.9.0-gpu AS builder # Installera byggberoenden RUN apt-get update && apt-get install -y --no-install-recommends \ git \ && rm -rf /var/lib/apt/lists/* # Sätt arbetskatalog WORKDIR /build # Kopiera requirements först för bättre caching COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Kopiera källkod COPY src/ ./src/ COPY models/ ./models/ COPY config.yaml . # Pakagera modellen för optimerad inferens RUN python src/optimize_model.py --model models/model.h5 --output models/optimized_model # Inferensfas - använd lightweight image för runtime FROM tensorflow/tensorflow:2.9.0 AS runtime # Installera produktionsberoenden COPY --from=builder /build/requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Kopiera optimerad modell och kod WORKDIR /app COPY --from=builder /build/models/optimized_model ./models/ COPY --from=builder /build/src/inference.py ./ COPY --from=builder /build/config.yaml ./ # Exponera port för API EXPOSE 8501 # Definiera standardkommando CMD ["python", "inference.py", "--port", "8501"] ==== Optimering av Docker-images för ML ==== * **Image-storlek**: Minimera storleken genom att ta bort utvecklingsverktyg * **Startid**: Optimera för snabb startup av containers * **Caching**: Strukturera Dockerfile för optimal caching * **Lagerstruktur**: Gruppera relaterade kommandon för att minimera antal lager * **Alpine-baserade images**: För minimala produktionsimages ==== Best practices för containerisering av ML-modeller ==== * **Separering av träning och inferens**: Olika containers för olika ändamål * **Externalisera konfiguration**: Använd environment-variabler eller config-filer * **Preload-modeller**: Ladda modeller vid container-uppstart för att minimera kallstarttid * **Health checks**: Implementera hälsokontroller för containerövervakning * **Lämplig loggning**: Konfigurera loggning för effektiv felsökning * **Säkerhetsoptimering**: Kör som non-root-användare, scanna för sårbarheter ===== 5.3 Orkestrering med Kubernetes för ML-arbetsbelastningar ===== ==== Introduktion till Kubernetes för ML ==== * **Kubernetes-komponenter**: Noder, Pods, Services, Deployments * **Kubernetes-arkitektur**: Control plane och worker nodes * **Namespace-organisering**: Logisk separation av miljöer och team * **ML-specifika överväganden**: Resursbehov, specialiserad hårdvara ==== Kubernetes-resurser för ML-driftsättning ==== * **Deployments**: För stateless prediktions-API:er * **StatefulSets**: För tillståndsbaserade ML-system * **Services**: Exponera ML-endpoints * **ConfigMaps och Secrets**: Hantera konfiguration och hemligheter * **Jobs och CronJobs**: För batchträning och -inferens * **HPA (Horizontal Pod Autoscaler)**: Automatisk skalning baserat på belastning ==== Exempel på Kubernetes-manifest för ML-modellserving ==== # deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: ml-model-service labels: app: ml-model-service spec: replicas: 3 selector: matchLabels: app: ml-model-service template: metadata: labels: app: ml-model-service spec: containers: - name: model-server image: my-registry/ml-model:latest ports: - containerPort: 8501 resources: limits: cpu: "2" memory: "4Gi" nvidia.com/gpu: 1 requests: cpu: "1" memory: "2Gi" readinessProbe: httpGet: path: /health port: 8501 initialDelaySeconds: 10 periodSeconds: 5 livenessProbe: httpGet: path: /health port: 8501 initialDelaySeconds: 30 periodSeconds: 15 env: - name: MODEL_PATH value: "/app/models/optimized_model" - name: PREDICTION_TIMEOUT value: "5" volumeMounts: - name: model-storage mountPath: /app/models volumes: - name: model-storage persistentVolumeClaim: claimName: model-pvc --- # service.yaml apiVersion: v1 kind: Service metadata: name: ml-model-service spec: selector: app: ml-model-service ports: - port: 80 targetPort: 8501 type: ClusterIP --- # autoscaler.yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: ml-model-service-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: ml-model-service minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 ==== Kubernetes-operatörer för ML ==== * **KubeFlow Operator**: Hantering av ML-arbetsflöden * **Seldon Core**: Driftsättning av ML-modeller med komplex routning * **Feast Operator**: Feature Store-hantering * **NVIDIA GPU Operator**: GPU-resurshantering ===== 5.4 Hantering av GPU-resurser i containeriserade miljöer ===== ==== GPU-runtime för containers ==== * **NVIDIA Docker**: Docker med GPU-stöd * **Kubernetes Device Plugins**: GPU-allokering i Kubernetes * **Multi-GPU-konfigurationer**: Parallellisering över flera GPUs ==== GPU-specifika optimeringar ==== * **Memory management**: Optimalt utnyttjande av GPU-minne * **Batch sizing**: Anpassade batchstorlekar för GPU * **Mixed precision**: Användning av FP16 för snabbare inferens * **Kernel tuning**: Optimering av CUDA-kernels * **GPU-delning**: Dela en GPU mellan flera containers ==== Exempel på GPU-konfiguration i Kubernetes ==== # nvidia-device-plugin.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: nvidia-device-plugin-daemonset namespace: kube-system spec: selector: matchLabels: name: nvidia-device-plugin-ds template: metadata: labels: name: nvidia-device-plugin-ds spec: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule containers: - name: nvidia-device-plugin-ctr image: nvidia/k8s-device-plugin:v0.12.2 securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] volumeMounts: - name: device-plugin mountPath: /var/lib/kubelet/device-plugins volumes: - name: device-plugin hostPath: path: /var/lib/kubelet/device-plugins ===== 5.5 Skalning och lastbalansering av ML-modeller ===== ==== Skalningsstrategier för ML-tjänster ==== * **Horisontell skalning**: Öka antalet poddar baserat på belastning * **Vertikal skalning**: Öka resurser per podd * **Autoskalning**: Automatisk anpassning baserat på metrics * **Prediktiv skalning**: Förutsägbara skalning baserat på historiska mönster ==== Lastbalanseringsmetoder ==== * **Round-robin**: Jämn fördelning av förfrågningar * **Sessionsstickyness**: Håll användare till samma instans * **Modellshard**: Dela upp modellen över flera instanser * **Specialisering**: Olika modeller för olika typer av förfrågningar ==== Implementering av optimal inferens i en distribuerad miljö ==== * **Modellparallellism**: Dela upp stora modeller över flera GPUs/noder * **Batchprediktioner**: Gruppera förfrågningar för bättre genomströmning * **Dataparallelism**: Samma modell på flera noder för bättre genomströmning * **Adaptive batching**: Dynamisk batchstorlek baserat på belastning * **Caching**: Cacha vanliga förfrågningar för snabbare respons ==== Exempel på adaptive batching med TensorFlow Serving ==== import tensorflow as tf from tensorflow_serving.apis import predict_pb2 from tensorflow_serving.apis import prediction_service_pb2_grpc import grpc import numpy as np import time from concurrent import futures # Konfigurera gRPC-klient channel = grpc.insecure_channel('localhost:8500') stub = prediction_service_pb2_grpc.PredictionServiceStub(channel) # Batchsamlare class BatchCollector: def __init__(self, max_batch_size=32, timeout=0.1): self.max_batch_size = max_batch_size self.timeout = timeout self.batch = [] self.executor = futures.ThreadPoolExecutor(max_workers=1) self.future = None def add_request(self, image): # Skapa ett Future-object för resultatet result_future = futures.Future() # Lägg till request i batch self.batch.append((image, result_future)) # Starta batch-process om det är den första i batchen if len(self.batch) == 1: self.future = self.executor.submit(self._process_batch) # Processa omedelbart om batch är full if len(self.batch) >= self.max_batch_size: self.future.result() return result_future def _process_batch(self): # Vänta tills timeout eller maximal batchstorlek start_time = time.time() while len(self.batch) < self.max_batch_size and time.time() - start_time < self.timeout: time.sleep(0.001) # Skapa batch-request batch_size = len(self.batch) images = np.zeros((batch_size, 224, 224, 3), dtype=np.float32) futures = [] # Samla in data och futures for i, (image, future) in enumerate(self.batch): images[i] = image futures.append(future) # Töm batchen self.batch = [] # Skapa TF Serving-request request = predict_pb2.PredictRequest() request.model_spec.name = 'image_classifier' request.model_spec.signature_name = 'serving_default' request.inputs['input'].CopyFrom( tf.make_tensor_proto(images) ) # Gör prediktionen try: result = stub.Predict(request, timeout=5.0) predictions = tf.make_ndarray(result.outputs['output']) # Sätt resultat för varje future for i, future in enumerate(futures): future.set_result(predictions[i]) except Exception as e: # Sätt undantag för alla futures for future in futures: future.set_exception(e) ===== 5.6 Design av ML-tjänster för olika användningsfall ===== ==== Realtidsprediktioner ==== * **API-design**: RESTful eller gRPC-API för snabb inferens * **Latensoptimering**: Minimera svarstid för realtidsapplikationer * **Stateless design**: Stateless design för enkel skalning * **Caching-strategier**: Cacha vanliga förfrågningar * **Felhantering**: Robusta strategier för hantering av fel och timeout ==== Batchprediktioner ==== * **Arbetsköer**: Använd köer för att hantera stora batchjobb * **Schemaläggning**: Schemalägg batchjobb under låg belastning * **Checkpointing**: Spara tillstånd för att återuppta vid fel * **Parallellisering**: Dela upp stora jobb i parallella arbetare * **Dataflödesoptimering**: Optimera dataflöde för hög genomströmning ==== Online learning ==== * **Inkrementell träning**: Uppdatera modeller med nya data i realtid * **A/B-testmiljö**: Testa modelluppdateringar i produktion * **Shadow deployment**: Validera nya modeller utan att påverka användare * **Feedback loops**: Samla in feedback för kontinuerlig förbättring ==== Exempel på ML-tjänstarkitektur för realtid- och batchprediktioner ==== # Real-time API service apiVersion: apps/v1 kind: Deployment metadata: name: realtime-prediction-api spec: replicas: 5 selector: matchLabels: app: realtime-prediction-api template: metadata: labels: app: realtime-prediction-api spec: containers: - name: api-server image: my-registry/ml-api:latest ports: - containerPort: 8000 resources: limits: nvidia.com/gpu: 1 --- # Batch prediction job apiVersion: batch/v1 kind: CronJob metadata: name: batch-prediction-job spec: schedule: "0 2 * * *" # Kör kl 02:00 varje dag jobTemplate: spec: parallelism: 5 # 5 parallella pods completions: 1 template: spec: containers: - name: batch-processor image: my-registry/ml-batch:latest resources: limits: nvidia.com/gpu: 1 volumeMounts: - name: data-volume mountPath: /data - name: output-volume mountPath: /output volumes: - name: data-volume persistentVolumeClaim: claimName: input-data-pvc - name: output-volume persistentVolumeClaim: claimName: output-data-pvc restartPolicy: Never ===== Praktiska övningar ===== 1. **Docker containerisering**: Bygg en Docker-container för en tränad ML-modell 2. **Kubernetes-driftsättning**: Driftsätt en ML-modell på Kubernetes-kluster 3. **Autoskalningskonfiguration**: Implementera automatisk skalning baserat på trafikbelastning 4. **GPU-optimering**: Optimera en GPU-baserad inferensmiljö för maximal prestanda ===== Verktygsintroduktion ===== * **Docker**: Byggande och hantering av containers * **Kubernetes**: Orkestrering av containers * **KubeFlow**: ML-specifika tjänster för Kubernetes * **Seldon Core**: Driftsättningsplattform för ML på Kubernetes * **TensorRT**: NVIDIA SDK för optimerad inferens ===== Läsresurser ===== * "Containerization of Machine Learning Models" - NVIDIA Developer Blog * "Kubernetes Patterns for ML Services" - Kubeflow Documentation * "Optimizing GPU Usage for Deep Learning Inference" - AWS ML Blog * "Distributed TensorFlow on Kubernetes" - Google Cloud Documentation * "High-Performance Inference with TensorRT" - NVIDIA Documentation ===== Nyckelinsikter ===== * Containerisering möjliggör portabel, reproducerbar ML-utveckling och -driftsättning * Multi-stage Docker-byggen separerar utveckling från produktion för optimal effektivitet * Kubernetes ger en robust plattform för att orkestreras ML-tjänster med komplex skalning * GPU-hantering i containeriserade miljöer kräver speciella överväganden för optimal prestanda * Skalnings- och lastbalanseringsstrategierna bör anpassas efter specifika ML-användningsfall * Realtids- vs. batchprediktioner kräver olika arkitekturella mönster ===== Nästa steg ===== I nästa modul kommer vi att fokusera på modellövervakning och underhåll, där vi kommer att lära oss hur man övervakar modellprestanda i produktion, detekterar drift och implementerar automatiska omträningsstrategier.