iT邦幫忙

2025 iThome 鐵人賽

DAY 9
0
DevOps

新創視角下的 DevOps × AI 探索系列 第 28

Day 28: LLM 推理的自動伸縮策略:讓模型服務在高流量下保持高效穩定

  • 分享至 

  • xImage
  •  

一、前言:為什麼 LLM 推理需要自動伸縮?

LLM 推理的挑戰:

  • 每次推理需要大量 GPU 計算資源,尤其是多 Token 的生成。
  • 流量波動明顯(例如白天使用高峰、夜間低谷)。

固定部署的問題:

  • 浪費 GPU 資源,造成高成本。
  • 或者在突發流量下導致請求延遲、Timeout。

自動伸縮(Auto Scaling)的目標:

  • 根據實際負載自動調整 Pod 數量。
  • 讓系統兼顧「性能」與「成本」。

二、自動伸縮的三種典型模式

  1. 基於資源使用率的水平自動伸縮(HPA)
    核心概念: 根據 CPU/GPU 使用率自動調整副本數。
    LLM 特殊挑戰:
  • GPU 使用率不易直接透過內建指標取得。
  • 需要自定義 Metrics(Custom Metrics)上報至 Prometheus。
User → Inference Service (Pods) → Metrics Exporter → Prometheus Adapter → HPA
  1. 基於事件的自動伸縮(KEDA)
    KEDA(Kubernetes Event-Driven Autoscaling):
    能根據「事件」觸發伸縮,例如:
  • Message Queue 長度(如 Kafka、RabbitMQ)
  • Redis Queue
  • HTTP 請求速率(透過 Prometheus Adapter)
  • 特別適合 LLM API 在高峰期被突發流量打爆的情境。
    範例場景:
  • 前端請求量突增 → Queue 累積 → KEDA Scale Out Pods。
  1. 批次推理(Batch Inference)的 Job 自動調度
    不需要常駐的 GPU Pod,而是根據任務動態建立 Job。
    適用情境:
  • LLM Embedding、批量生成摘要、週期性報告。
    可結合:
  • KEDA + CronJob(自動啟動批次任務)
  • Ray on K8s / Kubeflow Pipelines(大規模分佈式推理)

三、監控與告警:量化推理服務的健康狀態

  1. 推理延遲與吞吐量監控
    透過 Prometheus + Grafana 建立以下 Metrics:
  • inference_latency_seconds
  • tokens_generated_per_second
  • gpu_utilization
    實例 Dashboard:
  • 每個模型版本的平均推理延遲。
  • 每台 GPU 的實時利用率。
  • 各版本的成功率(5xx 錯誤佔比)。
  1. 告警策略
    設定 AlertManager:
  • 延遲 > 3 秒持續 1 分鐘 → 通知 Slack。
  • GPU 使用率 < 20% → 降低副本數。
  • 請求速率突增 → 提前預熱 Pod。

四、實作範例:KServe + KEDA + Prometheus + GPU Metrics Exporter

範例目標:建立一個能根據 GPU 使用率與請求量動態伸縮的 LLM 推理服務。

  1. 部署 GPU Metrics Exporter
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: dcgm-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: dcgm-exporter
  template:
    metadata:
      labels:
        app: dcgm-exporter
    spec:
      containers:
      - name: dcgm-exporter
        image: nvidia/dcgm-exporter:3.1.8-2.6.10
        ports:
        - containerPort: 9400
  1. 自定義 Metrics Adapter
apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-metrics-config
  namespace: monitoring
data:
  config.yaml: |
    rules:
    - seriesQuery: 'DCGM_FI_DEV_GPU_UTIL'
      resources:
        overrides:
          namespace: {resource: "namespace"}
          pod: {resource: "pod"}
      name:
        matches: "DCGM_FI_DEV_GPU_UTIL"
        as: "gpu_utilization"
      metricsQuery: avg(DCGM_FI_DEV_GPU_UTIL) by (pod)
  1. HPA 基於 GPU 使用率伸縮
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: llm-inference-hpa
  namespace: llm
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: llm-inference
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Pods
    pods:
      metric:
        name: gpu_utilization
      target:
        type: AverageValue
        averageValue: 80
  1. KEDA 事件驅動自動伸縮
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: llm-inference-keda
  namespace: llm
spec:
  scaleTargetRef:
    kind: Deployment
    name: llm-inference
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus.monitoring.svc.cluster.local:9090
      metricName: http_requests_per_second
      threshold: "10"

當 HTTP 請求速率超過 10 req/s 時自動擴容。

  1. 結合 Batch Job 推理
apiVersion: batch/v1
kind: CronJob
metadata:
  name: llm-batch-inference
spec:
  schedule: "*/30 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: llm-batch
            image: myrepo/llm-batch:latest
            command: ["python", "batch_infer.py"]
          restartPolicy: OnFailure

每 30 分鐘自動啟動一次批次推理任務。

五、延伸:冷啟動優化與預熱策略

問題:GPU Pod 啟動時間通常在 30–90 秒。
解法:

  • 在高峰期前預熱 Pod。
  • 使用 KServe 的 Predictor warmup。
  • 或透過 Sidecar 模擬預熱請求(Dummy Request)。

六、結語:從「自動伸縮」到「自我調節」

自動伸縮只是第一步,最終目標是:

  • 讓 LLM 系統具備「自我調節能力」。
  • 結合 MLOps + AIOps,實現智能化運維。
    預告下一篇:
  • 分散式訓練與模型微調 —— 帶你從推理回到訓練,打造可持續優化的模型生命週期。

上一篇
Day 27:LLM 模型服務部署與版本管理
下一篇
Day 29: 分散式訓練與模型微調
系列文
新創視角下的 DevOps × AI 探索30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言