Menyebarkan model ke produksi: serving dengan TorchServe, vLLM untuk LLM, dan Triton Inference Server dalam container Docker, plus monitoring drift, latency, throughput, dan observability dengan OpenTelemetry.

Model yang akurat di notebook tidak bernilai sampai ia bisa melayani pengguna. Episode ini menjembatani dunia riset dan dunia operasional: bagaimana menyajikan model sebagai service yang siap produksi — dengan throughput tinggi, latency stabil, dan kesehatan yang terpantau.
Di 2026, serving bukan lagi "letakkan model di Flask". Ada tool khusus: TorchServe untuk model PyTorch umum, vLLM yang mendominasi serving LLM, dan Triton Inference Server sebagai pilihan enterprise. Plus container Docker sebagai standar distribusi. Dan setelah deploy, pekerjaan belum selesai: model harus dipantau. Mari kita mulai.
Semua strategi serving berjalan di dalam container — lingkungan yang terisolasi dan reproducible. Model, runtime, dan dependensi dibungkus jadi satu image:
FROM nvidia/cuda:12.4-runtime-ubuntu22.04
RUN apt-get update && apt-get install -y python3-pip
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY model/ ./model/
COPY app.py .
CMD ["python", "app.py"]Prinsip: image kecil (runtime saja, bukan build), dependensi dikunci (pin versi), dan model di-bake atau di-mount dari volume terpisah tergantung ukuran. Untuk model besar, pisahkan weight dari image agar update model tidak me-rebuild image.
TorchServe adalah server inference resmi PyTorch — mendukung batching, scaling, dan endpoint REST/gRPC:
torch-model-archiver --model-name cifar_cnn \
--version 1.0 --model-file model.py --serialized-file cifar_cnn.pt \
--handler image_classifier --export-path model_store
torchserve --start --ncs --model-store model_store \
--models cifar_cnn=cifar_cnn.marHandler menentukan preprocessing (resize, normalisasi) dan postprocessing. Konsistensi preprocessing antara training dan serving adalah sumber bug paling umum — jadikan handler satu-satunya tempat preprocessing di produksi.
Untuk LLM, vLLM adalah standar de facto 2026. Kunci kecepatannya: PagedAttention — memori KV-cache dikelola seperti halaman memori sistem operasi, menghilangkan fragmentasi sehingga bisa melayani banyak request paralel:
from vllm import LLM, SamplingParams
llm = LLM(model="Qwen/Qwen2.5-7B-Instruct", tensor_parallel_size=1, max_model_len=8192)
params = SamplingParams(temperature=0.7, top_p=0.9, max_tokens=512)
outputs = llm.generate(["Ceritakan tentang deep learning"], params)
print(outputs[0].outputs[0].text)vLLM juga punya server OpenAI-compatible:
vllm serve Qwen/Qwen2.5-7B-Instruct --port 8000curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"Qwen/Qwen2.5-7B-Instruct","messages":[{"role":"user","content":"Halo"}]}'Keuntungan langsung: aplikasi bisa berganti model/backend tanpa mengganti kode — cukup ubah base URL.
Tip
max_model_len adalah pengatur besar pemakaian memori vLLM: semakin panjang konteks yang diizinkan, semakin besar KV-cache yang dialokasikan. Atur sesuai kebutuhan nyata aplikasi kalian, bukan maksimum model — ini bisa melipatgandakan jumlah request yang bisa dilayani sekaligus.
Triton dari NVIDIA melayani banyak model dan framework (PyTorch, TF, ONNX) sekaligus dalam satu server, dengan batching dinamis, model ensemble, dan dynamic model loading tanpa downtime. Pilihan untuk organisasi yang menjalankan puluhan model. Konsep-konsepnya (model repository, batching, concurrency) lebih berat dipelajari, tetapi untuk skala enterprise sering sepadan.
Deploy bukan akhir. Model yang sama bisa memburuk seiring waktu — data nyata berubah. Tiga hal wajib dipantau:
Pendekatan praktis: bandingkan distribusi fitur input waktu nyata vs distribusi training (statistik sederhana seperti mean/std, atau PSI), dan pantau metrik bisnis (akurasi pada sampel terlabel ulang, jumlah keluhan) sebagai sinyal drift.
OpenTelemetry menyatukan metrik, trace, dan log dengan satu API. Untuk LLM serving, tracing tiap request (prompt → model → output) sangat berharga:
from opentelemetry import trace
tracer = trace.get_tracer("serving")
def predict(request):
with tracer.start_as_current_span("llm.generate") as span:
span.set_attribute("prompt_tokens", n_prompt)
span.set_attribute("model", model_name)
output = llm.generate(request)
span.set_attribute("latency_ms", latency)
return outputDengan tracing, kalian bisa menemukan di mana waktu hilang — preprocessing, queue, atau generasi — dan melacak root cause saat output aneh.
Warning
Latency LLM tidak konstan: lebih banyak token output = lebih lama. Metrik latency yang jujur untuk LLM adalah token pertama (TTFT) dan token per detik, bukan total request time. Laporkan keduanya — total time saja menyesatkan.
/health yang benar-benar menguji model, bukan sekadar "proses hidup".Pada episode 20 ini, kalian telah menguasai deployment.
Inti yang harus dibawa pulang:
Di episode 21 selanjutnya kita akan menggabungkan semuanya: multimodal & foundation models — CLIP, vision-language models (VLM), audio dengan Whisper, plus pipeline image+text VQA dan fine-tune multimodal ringan. Sampai jumpa di episode 21!