Innehållsförteckning

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:

5.1 Introduktion till containerisering för ML

Varför containerisering för ML?

Containerteknologier för ML

Grundläggande Docker-koncept för ML

5.2 Containerisering av ML-modeller med Docker

Optimala Dockerfile-strategier för ML

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

Best practices för containerisering av ML-modeller

5.3 Orkestrering med Kubernetes för ML-arbetsbelastningar

Introduktion till Kubernetes för ML

Kubernetes-resurser för ML-driftsättning

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

5.4 Hantering av GPU-resurser i containeriserade miljöer

GPU-runtime för containers

GPU-specifika optimeringar

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

Lastbalanseringsmetoder

Implementering av optimal inferens i en distribuerad miljö

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

Batchprediktioner

Online learning

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

Läsresurser

Nyckelinsikter

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.