Belajar MLOps - Model Packaging & Serving
Episode 9 of 28

Belajar MLOps - Model Packaging & Serving

Mengubah model yang sudah dilatih menjadi API produksi: FastAPI untuk endpoint custom, BentoML untuk packaging terotomasi, TorchServe & Triton untuk model berat, plus skema request-response dan praktik serving yang benar.

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

Pendahuluan

Setelah di episode 8 CI/CD meloloskan model, tibalah momen yang dinanti: model kalian melayani prediksi nyata. Sampai di sini, model masih berupa artifact di MLflow. Episode ini mengubahnya menjadi layanan yang bisa dipanggil aplikasi lain — melalui HTTP API.

Mengapa model serving adalah titik paling krusial? Karena di sinilah model menghadapi dunia nyata yang tidak ramah: request malformed, latensi yang tidak bisa ditoleransi, dan traffic yang melonjak. Cara model di-package dan di-serve menentukan apakah ia bisa bertahan — bukan hanya di demo, tapi di produksi. Episode ini memperkenalkan empat pendekatan: FastAPI, BentoML, TorchServe, dan Triton.

FastAPI: Endpoint Custom Paling Fleksibel

FastAPI adalah cara paling langsung untuk menyajikan model yang sudah dilatih dengan scikit-learn/PyTorch. Ia memberi kontrol penuh dan performa tinggi (berbasis ASGI), plus validasi input otomatis lewat Pydantic.

app.py — API inference FastAPI
import joblib
import numpy as np
from fastapi import FastAPI
from pydantic import BaseModel
 
app = FastAPI(title="Churn Predictor")
model = joblib.load("models/churn.joblib")
 
class PredictionInput(BaseModel):
    age: int
    monthly_charges: float
    tenure_months: int
    contract_type: str
 
class PredictionOutput(BaseModel):
    churn_probability: float
    will_churn: bool
 
@app.get("/health")
def health():
    return {"status": "ok"}
 
@app.post("/predict", response_model=PredictionOutput)
def predict(inp: PredictionInput):
    features = np.array([[
        inp.age,
        inp.monthly_charges,
        inp.tenure_months,
        1 if inp.contract_type == "monthly" else 0,
    ]])
    prob = float(model.predict_proba(features)[0, 1])
    return PredictionOutput(
        churn_probability=round(prob, 4),
        will_churn=prob >= 0.5,
    )

Perhatikan tiga hal penting:

  • Schema dengan Pydantic — request yang salah bentuk ditolak otomatis (episode 3 membayar di sini).
  • Endpoint /health — dibutuhkan untuk readiness probe saat dideploy di Kubernetes (episode 17).
  • Preprocessing inline — encoding fitur ada di endpoint; nanti kita pindahkan ke preprocessor yang disimpan bersama model (episode 14 membahas anti-skew).

Jalankan dan uji:

Run dan uji API
uvicorn app:app --host 0.0.0.0 --port 8000
Panggil endpoint prediksi
curl -X POST http://localhost:8000/predict \
  -H "Content-Type: application/json" \
  -d '{"age": 45, "monthly_charges": 89.9, "tenure_months": 3, "contract_type": "monthly"}'
Response prediksi
{
  "churn_probability": 0.873,
  "will_churn": true
}

BentoML: Packaging Otomatis

BentoML mengambil pendekatan yang lebih "selesai": kalian mendefinisikan service dengan sedikit kode, dan BentoML menangani packaging, image Docker, dan deployment ke berbagai target (Kubernetes, serverless, cloud).

BentoML service
import bentoml
import joblib
 
model = joblib.load("models/churn.joblib")
 
@bentoml.service
class ChurnService:
    @bentoml.api
    def predict(self, age: int, monthly_charges: float, tenure: int) -> float:
        prob = model.predict_proba([[age, monthly_charges, tenure]])[0, 1]
        return float(prob)
Build image BentoML
bentoml build
bentoml containerize churn_service:latest -t churn-serve:0.1.0
docker run -p 3000:3000 churn-serve:0.1.0

Keunggulan BentoML: adaptive batching dan dukungan GPU built-in, plus UI untuk mencoba endpoint. Cocok jika ingin serving siap produksi tanpa menulis banyak kode infrastruktur.

TorchServe & Triton untuk Model Berat

Untuk model deep learning yang butuh performa maksimal:

  • TorchServe — serving resmi PyTorch. Format artifact .mar, mendukung batching, GPU, dan versioning model. Cocok jika model kalian PyTorch native.
  • NVIDIA Triton — inference server untuk semua framework (PyTorch, TensorFlow, ONNX). Performa tertinggi, cocok untuk deployment GPU skala besar, mendukung ensemble dan dynamic batching.
Serve model dengan Triton
docker run --gpus all --rm -p 8000:8000 \
  -v /models:/models \
  nvcr.io/nvidia/tritonserver:24.12-py3 \
  tritonserver --model-repository=/models

Triton dan TorchServe lebih berat untuk dioperasikan — keuntungannya muncul saat performa dan skala benar-benar dibutuhkan (episode 22-23 akan kembali ke performa inference).

Memilih Pendekatan Serving

PendekatanTerbaik untukKompleksitas
FastAPIModel tabular, kontrol penuh, integrasi customRendah
BentoMLServing cepat tanpa banyak kode infraRendah-sedang
TorchServeModel PyTorch, fitur server lengkapSedang
TritonSkala besar, multi-framework, GPUTinggi

Tip

Mulai dari FastAPI untuk model pertama — ia paling mudah dipahami dan di-debug. Upgrade ke BentoML/Triton hanya ketika kalian menemukan kebutuhan nyata: batching besar, multi-framework, atau GPU utilization tinggi. Jangan menambah kompleksitas sebelum ada masalah yang menuntutnya.

Praktik Baik Serving

  • Health check endpoint/health wajib untuk readiness/liveness probe.
  • Preprocessor dibundel dengan model — jangan mengandalkan kode eksternal yang bisa berubah (anti training-serving skew).
  • Batas request & timeout — tetapkan max_request_size dan timeout agar server tidak digantung request raksasa.
  • Logging terstruktur — catat versi model dan request ID per prediksi untuk audit (episode 15).
  • Jangan menyimpan request body di log — data pribadi pengguna berpotensi sensitif (episode 19).

Common Pitfalls

  • Model di-load setiap request → lambat; load sekali di startup (seperti contoh kita).
  • Tanpa schema validation → request rusak masuk sampai ke model dan menghasilkan error aneh; Pydantic menyaringnya.
  • Preprocessing tidak konsisten dengan training → hasil produksi berbeda dari ekspektasi; bundel preprocessor.
  • Endpoint tanpa health check → orchestrator tidak tahu kapan service siap; deploy di K8s akan kacau.

Penutup

Pada episode 9 ini, kalian telah mengubah model menjadi API produksi.

Inti yang harus dibawa pulang:

  • FastAPI untuk endpoint custom dengan validasi Pydantic dan kontrol penuh.
  • BentoML untuk packaging terotomasi + batching built-in.
  • TorchServe/Triton untuk model berat dan skala GPU.
  • Praktik baik: health check, preprocessor bundel, batas request, dan logging terstruktur.

Di episode 10 selanjutnya kita akan membahas model deployment patterns — perbedaan online (REST/gRPC), batch, dan streaming, plus strategi blue-green dan canary khusus untuk model agar deploy tidak lagi berarti downtime. Sampai jumpa di episode 10!

Belajar MLOps - Model Packaging & Serving | Belajar MLOps