Membawa model dari artifact menjadi layanan: mengemas model ke Docker image yang minimal & aman, memilih framework serving (BentoML, Triton, Seldon), serta menyajikan prediksi lewat REST dan gRPC dengan latensi, throughput, dan graceful degradation yang terukur

Setelah di episode 8 proyek ML kalian reproducible (kode + data + model ter-versioning), saatnya langkah yang mendefinisikan peran MLE: mengubah artifact model menjadi layanan yang benar-benar berjalan. Di sinilah model "hidup" — dipanggil aplikasi, menjawab request dalam milidetik, dan bertahan di bawah beban.
Serving adalah persimpangan antara data science dan software engineering. Kalian harus memikirkan: protokol apa (REST atau gRPC), framework serving mana, bagaimana image Docker dibuat agar kecil dan aman, dan bagaimana service berperilaku saat model lambat atau gagal. Episode ini membangun fondasi containerization + serving yang akan kita perbesar di episode 22.
Container mengemas model, kode, dan dependensi menjadi satu unit yang berjalan sama di mana saja. Dua prinsip image serving yang baik:
FROM python:3.12-slim
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends libgomp1 && rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY src/ ./src/
COPY model/ ./model/
EXPOSE 8000
CMD ["uvicorn", "src.serve:app", "--host", "0.0.0.0", "--port", "8000"]docker build -t churn-api:1.4.2 .
docker run -d --rm -p 8000:8000 churn-api:1.4.2Untuk image yang benar-benar ramping, pisahkan build dan runtime:
FROM python:3.12-slim AS builder
WORKDIR /build
COPY requirements.txt .
RUN pip wheel --no-cache-dir -w /wheels -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /wheels /wheels
RUN pip install --no-cache-dir --no-index --find-links=/wheels -r requirements.txt
COPY src/ ./src/
COPY model/ ./model/
CMD ["uvicorn", "src.serve:app", "--host", "0.0.0.0", "--port", "8000"]Tiga opsi populer dengan fokus berbeda:
| Framework | Kekuatan | Cocok untuk |
|---|---|---|
| BentoML | Simple, Pythonic, bento package, model store | Serving cepat dari artifact sklearn/torch/HF |
| NVIDIA Triton | Multi-model, multi-framework, GPU optimal, dynamic batching | Inference GPU skala besar, multi-model |
| Seldon Core | Integrasi Kubernetes, canary/rollout, explainer | Platform serving di atas K8s |
import bentoml
import numpy as np
from bentoml.io import JSON, NumpyNdarray
model = bentoml.sklearn.get("churn-predictor:latest")
runner = model.to_runner()
svc = bentoml.Service("churn-service", runners=[runner])
@svc.api(input=NumpyNdarray(), output=JSON())
def predict(input_data: np.ndarray):
result = runner.predict.run(input_data)
return {"prediction": result.tolist()}bentoml serve src.serve:svc --port 3000
bentoml containerize churn-service:latest| Aspek | REST (JSON over HTTP) | gRPC (Protobuf over HTTP/2) |
|---|---|---|
| Kemudahan debugging | Tinggi, terbaca manusia | Rendah, butuh tooling |
| Serialization overhead | Besar (JSON) | Kecil (binary) |
| Throughput | Sedang | Tinggi |
| Fitur streaming/batching | Manual | Bawaan (bidirectional streaming) |
Aturan praktis: mulai dengan REST untuk kesederhanaan; beralih ke gRPC saat throughput menjadi masalah. Triton dan framework besar mendukung keduanya.
Serving produksi bukan hanya "menerima request". Kalian wajib memikirkan:
from fastapi import FastAPI
from src.serve import predict_fast, predict_fallback
app = FastAPI()
@app.post("/predict")
def predict(payload: dict):
try:
return predict_fast(payload)
except TimeoutError:
return predict_fallback(payload)Tip
Sebelum mengejar framework canggih, ukur dulu kebutuhan: berapa latensi p95 yang dibutuhkan? berapa QPS? Model 200MB di server 2GB jelas butuh strategi (kuantisasi, episode 23) sebelum sampai pada masalah framework. Prinsip: optimize berdasarkan data, bukan dugaan.
Sebelum deployment, lakukan smoke test: kirim request valid, request invalid (shape salah), dan request ke endpoint yang tidak ada. Pastikan error handling mengembalikan HTTP status yang benar, bukan crash diam-diam.
curl -s -X POST http://localhost:8000/predict \
-H "Content-Type: application/json" \
-d '{"age": 34, "event_count": 12, "tier": "gold"}'| Pitfall | Dampak | Pencegahan |
|---|---|---|
| Image gemuk (dev + runtime) | Build lambat, permukaan serangan besar | Multi-stage build |
| Tanpa timeout | Request menggantung, resource habis | Set timeout + fallback |
| Protokol salah pilih | Throughput kurang untuk beban | Ukur kebutuhan, REST dulu |
| Model & kode dicampur tanpa versi | Update model = deploy ulang aplikasi | Pisah, image per versi model |
| Tanpa health check | Orchestrator tidak tahu service sehat | Endpoint /healthz |
Pada episode 9 ini, kalian telah membawa model ke dunia layanan:
Di episode 10 selanjutnya kita akan membahas CI/CD untuk ML — otomasi build, test, dan deployment dengan GitHub Actions, gerbang validasi model (validasi data, evaluasi, drift check), serta pipeline deployment yang aman dan bisa di-rollback. Sampai jumpa di episode 10!