Belajar ML Engineer - Serving at Scale
Episode 22 of 28

Belajar ML Engineer - Serving at Scale

Menyajikan model ke skala produksi: deployment di Kubernetes dengan resource limits yang benar, autoscaling berbasis metrik inference, serta multi-tenant serving untuk melayani banyak model dan banyak pelanggan dengan isolasi dan biaya yang terkontrol

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 21 kita melatih model dengan banyak GPU, sekarang giliran sisi lain dari skala: serving. Model yang dilatih sebesar apa pun tidak ada artinya jika saat dipanggil ribuan pengguna ia ambruk. Di episode 9 kita serving di satu mesin; kini kita naik ke skala produksi: Kubernetes, autoscaling, dan multi-tenant serving.

Serving at scale punya tantangan unik yang berbeda dari serving aplikasi biasa: model butuh GPU (mahal), beban inference bersifat bursty (melonjak mendadak), dan satu mesin biasanya melayani satu keluarga model saja. Episode ini membangun fondasi: deploy di Kubernetes dengan resource yang benar, autoscaling berbasis metrik yang tepat, dan pola multi-tenant untuk mengendalikan biaya.

Kubernetes sebagai Basis Serving

Kubernetes memberi tiga hal yang dibutuhkan serving skala: elastisitas (menambah/mengurangi pod otomatis), resilience (restart saat gagal), dan declarative config (semua terdokumentasi di git).

Deployment serving sederhana
apiVersion: apps/v1
kind: Deployment
metadata:
  name: churn-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: churn-api
  template:
    metadata:
      labels:
        app: churn-api
    spec:
      containers:
        - name: churn-api
          image: registry.example/churn-api:1.4.2
          ports:
            - containerPort: 8000
          resources:
            requests:
              cpu: 500m
              memory: 1Gi
            limits:
              cpu: "2"
              memory: 2Gi
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8000

Dua hal yang wajib kalian pahami sejak awal:

  • resources requests vs limits: requests = jaminan yang direservasi (dipakai scheduler), limits = batas maksimum (penyebab throttling). Untuk serving ML, set keduanya berdasarkan profil latensi.
  • readinessProbe: pod hanya menerima trafik saat /healthz sehat — mencegah request dikirim ke model yang belum siap (model loading bisa butuh menit untuk model besar).

Autoscaling Inference: Metrik yang Tepat

Autoscaler standar HPA mengukur CPU — yang untuk serving ML sering menyesatkan: GPU bisa 100% sementara CPU menganggur. Solusinya, scale berdasarkan metrik inference (RPS, request per pod) atau queue depth:

HPA berbasis custom metric (ilustrasi)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: churn-api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: churn-api
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: External
      external:
        metric:
          name: inference_rps_per_pod
        target:
          type: AverageValue
          averageValue: 50

Prinsip autoscaling serving:

  • Skala lambat naik, cepat turun? Tidak — untuk inference, naik cepat, turun pelan (menghindari thundering herd saat trafik turun drastis).
  • Cooldown mencegah flapping.
  • GPU pod mahal — pasang maximum yang sesuai biaya; lebih baik antre daripada over-provisioning abadi.

Untuk LLM, GPU utilization bukan satu-satunya: KV cache (episode 15) menentukan berapa request konkuren yang muat. Autoscaling LLM sering dihitung dari estimated concurrent requests vs max_num_seqs.

Pola Multi-Tenant Serving

Saat melayani banyak model (tim internal, banyak pelanggan, banyak versi), muncul pilihan arsitektur:

PolaCaraCocokTrade-off
Satu model per serviceTiap model punya deployment sendiriIsolasi kuatBoros resource, banyak service
Multi-model per serviceSatu deployment memuat beberapa model (Triton/Seldon)Hemat GPU, model kecilBlast radius lebih besar
Model mesh / gatewayGateway routing ke kumpulan servingSkala banyak modelKompleksitas infrastruktur

Multi-model serving dengan Triton adalah cara paling efisien: satu proses GPU melayani beberapa model, memanfaatkan idle satu model dengan model lain. Pengaturan per-model (resource, GPU quota, concurrency) penting untuk mencegah satu penyewa rakus menghabiskan resource bersama.

Isolasi dan Quota untuk Banyak Penyewa

Konsep yang wajib ada di sistem multi-tenant:

  • Quota: batas concurrency/throughput per tenant — satu pelanggan tidak boleh melumpuhkan yang lain.
  • Isolasi kegagalan: model satu tenant crash tidak boleh mengganggu tenant lain.
  • Metrik per tenant: latency dan error rate dilacak per tenant (untuk SLO dan penagihan).

Serving LLM di Kubernetes: Kasus Khusus

LLM serving (episode 15) di K8s punya tambahan:

  • GPU node pool terpisah untuk pod LLM (node dengan GPU, taint/toleration).
  • vLLM dengan multi-GPU: --tensor-parallel-size + resource nvidia.com/gpu: 2.
  • Stateful consideration: model harus di-load ulang saat pod restart — memakai prefetch/anticipatory scaling (scale sebelum beban datang) karena loading model lama.
Pod LLM dengan GPU
          resources:
            limits:
              nvidia.com/gpu: 1
              memory: 48Gi
            requests:
              nvidia.com/gpu: 1
              memory: 40Gi

Mengendalikan Biaya Serving

Biaya adalah metrik serving yang paling sering diabaikan. Empat lever utama:

LeverCara
Pilih ukuran model yang tepatTerkecil yang cukup (episode 15)
Autoscale agresif saat idleTurun ke 0-2 pod di luar jam sibuk
Multi-model di satu GPUManfaatkan idle (Triton)
Batch inferenceGabungkan request untuk model batch

Important

Menghitung biaya serving hanya dari "harga GPU per jam" itu salah. Biaya sesungguhnya adalah harga per 1.000 prediksi — yang menggabungkan pemilihan model, efisiensi batching, dan pemakaian resource. Ukur metrik ini dari awal; kalian akan terkejut betapa besarnya perbedaan antar pilihan arsitektur.

Common Pitfalls

PitfallDampakPencegahan
HPA berbasis CPU untuk serving MLSalah trigger saat GPU yang penuhMetrik inference (RPS/concurrency)
Tanpa readinessProbeTrafik masuk sebelum model siapProbe /healthz
GPU request di lupakan di yamlPod dijadwalkan di node tanpa GPUnvidia.com/gpu requests
Satu tenant rakus resourceTenant lain melambatQuota + metrik per tenant
Over-provisioning abadiBiaya GPU meledakAutoscale + scale-to-zero saat idle

Penutup

Pada episode 22 ini, kalian telah membangun serving skala produksi:

  • Kubernetes: deployment dengan resources & readiness probe yang benar.
  • Autoscaling berbasis metrik inference (bukan CPU), naik cepat turun pelan.
  • Multi-tenant serving: multi-model (Triton), quota, isolasi, metrik per tenant.
  • Kasus LLM: GPU node pool, tensor parallel, dan anticipatory scaling.
  • Biaya: ukur harga per 1.000 prediksi, bukan per jam.

Di episode 23 selanjutnya kita akan membahas Model Optimization — kuantisasi INT8/FP8, distillation, dan pruning: cara membuat model lebih kecil, lebih cepat, dan lebih hemat biaya tanpa mengorbankan kualitas secara signifikan. Sampai jumpa di episode 23!

Belajar ML Engineer - Serving at Scale | Belajar ML Engineer