Belajar ML Engineer - Serving LLMs (vLLM/TGI)
Episode 15 of 28

Belajar ML Engineer - Serving LLMs (vLLM/TGI)

Menyajikan model bahasa besar secara efisien: PagedAttention yang menghemat memori KV cache, continuous batching yang memaksimalkan throughput, serta praktik menjalankan server vLLM dengan API kompatibel OpenAI untuk integrasi aplikasi yang mulus

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

Pendahuluan

Setelah di episode 14 kalian menghasilkan adapter LoRA berkualitas, tibalah pertanyaan yang sering membuat tim tersendat: bagaimana menyajikan LLM ke aplikasi secara efisien? Serving LLM berbeda total dari serving model klasik. Setiap request yang menghasilkan teks memakai memori yang tumbuh seiring panjang output (KV cache), dan throughput naive — satu request per satu waktu — membuat GPU menganggur sebagian besar waktu.

Pada 2026, dua server paling umum adalah vLLM dan Hugging Face TGI (Text Generation Inference). Episode ini membedah teknik inti yang membuat keduanya cepat — PagedAttention dan continuous batching — lalu mempraktikkan menjalankan vLLM dengan API kompatibel OpenAI yang bisa langsung dipakai aplikasi apa pun.

Kenapa Serving LLM Itu Sulit

Perbedaan mendasar dengan serving model klasik: request LLM bersifat generatif dan autoregressive. Menghasilkan 500 token = 500 langkah forward; tiap langkah butuh KV cache — hasil attention token sebelumnya — yang tumbuh per request. Beban juga tidak merata: request pendek dan panjang bercampur.

Imbasnya dua masalah klasik:

  1. Fragmentasi memori KV cache: menyimpan cache dalam blok besar menyisakan banyak memori tak terpakai.
  2. Throughput rendah: memproses satu request sekaligus membuat GPU idle menunggu generation lambat.

PagedAttention: Memori KV yang Efisien

vLLM memperkenalkan PagedAttention — mengadaptasi ide paging dari sistem operasi ke memori GPU. KV cache tidak lagi dialokasikan kontigu (satu blok raksasa), melainkan dalam blok-blok kecil (pages) yang bisa menyebar di memori dan hanya dialokasikan saat dibutuhkan.

text
Tanpa paging:  [#### request A (cache) ######____fragmentasi____]
Dengan paging: [#### A ####] [#### B ####] [#### A ####] [#### A ####]
                 blok-blok kecil, bisa menyebar, tanpa celah boros

Manfaatnya: fragmentasi turun drastis, memori terpakai lebih penuh, dan beam search bisa berbagi blok antar kandidat jawaban. Efek praktis: model yang lebih besar atau batch yang lebih besar bisa muat di VRAM yang sama.

Continuous Batching: GPU Selalu Sibuk

Batching klasik menunggu semua request dalam batch selesai sebelum batch berikutnya — request pendek jadi "terjebak" menunggu yang panjang. Continuous batching (juga disebut in-flight batching) memasukkan request baru ke batch begitu request lain selesai:

100%

Hasilnya, throughput meningkat signifikan — seringkali beberapa kali lipat dibanding naive serving — karena GPU tidak pernah menganggur menunggu batch penuh. Inilah alasan vLLM/TGI menjadi standar untuk inference LLM produksi.

Menjalankan vLLM: Praktik

Jalankan server vLLM
pip install vllm
 
vllm serve Qwen/Qwen2.5-7B-Instruct \
  --tensor-parallel-size 1 \
  --gpu-memory-utilization 0.9 \
  --max-model-len 8192

Parameter penting yang harus dipahami:

ParameterArtiCatatan
--tensor-parallel-sizeSplit model ke beberapa GPU1 untuk satu GPU; n untuk n GPU (episode 21)
--gpu-memory-utilizationPorsi VRAM untuk model+cacheNaikkan untuk throughput, sisakan untuk lainnya
--max-model-lenPanjang konteks maksimumSemakin besar, semakin boros memori
--quantizationfp8/awq/gptqHemat memori, cek kualitasnya

API Kompatibel OpenAI

Kekuatan vLLM: server-nya mengekspos API yang sama persis dengan OpenAI, sehingga aplikasi yang memakai openai SDK langsung bisa menukar endpoint:

Klien OpenAI ke vLLM
from openai import OpenAI
 
client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed",   # vLLM tidak butuh key
)
 
resp = client.chat.completions.create(
    model="Qwen/Qwen2.5-7B-Instruct",
    messages=[{"role": "user", "content": "Jelaskan PagedAttention singkat!"}],
    max_tokens=256,
    temperature=0.3,
)
print(resp.choices[0].message.content)

Ini killer feature: semua tooling yang menarget OpenAI (framework agent, evaluasi, dll) otomatis bekerja dengan model lokal kalian tanpa perubahan kode.

Streaming dan Metrik

Untuk UX chat yang responsif, gunakan streaming — token muncul bertahap:

Streaming response
stream = client.chat.completions.create(
    model="Qwen/Qwen2.5-7B-Instruct",
    messages=[{"role": "user", "content": "Ceritakan sejarah vLLM."}],
    stream=True,
)
for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)

Metrik yang wajib kalian pantau di produksi (ini bagian dari monitoring episode 11):

  • TTFT (Time To First Token): latensi token pertama — menentukan rasa responsif.
  • TPOT (Time Per Output Token): kecepatan setelah token pertama.
  • Tokens/s aggregate: throughput keseluruhan.
  • Satu batch, dua pola: max_num_seqs (ukuran batch) memengaruhi kompromi latency vs throughput.
Metrik vLLM via endpoint
curl -s http://localhost:8000/metrics | grep -E "vllm:time_to_first|vllm:e2e"

TGI vs vLLM

Hugging Face TGI adalah alternatif utama:

AspekvLLMTGI
Core teknikPagedAttentionMemori dikelola server, batching adaptif
KeunggulanThroughput tinggi, API OpenAI nativeIntegrasi ketat Hugging Face, chat template otomatis
Kapan memilihFokus throughput & API OpenAISudah ekosistem HF & butuh simplicity

Keduanya mengekspos OpenAI-compatible API; pilih berdasarkan integrasi dan benchmark di hardware kalian sendiri.

Strategi Penghematan Memori

Jika VRAM sempit, beberapa pilihan sebelum membeli GPU baru:

  • Kuantisasi model ke 4-bit/fp8 saat load (--quantization fp8 / AWQ).
  • Turunkan max-model-len jika request kalian pendek.
  • Batasi max_num_seqs agar KV cache tidak membengkak.
  • Gunakan model keluarga kecil (3B/8B) bila kualitas cukup — tren local models (episode 26).

Tip

Aturan praktis pilihan model serving: jangan deploy model terbesar yang muat; deploy model terkecil yang cukup untuk tugas kalian, dan evaluasi dengan benchmark yang sama (episode 24). Biaya serving tumbuh kuadratik dengan ukuran model — memilih tepat menghemat puluhan juta per bulan.

Common Pitfalls

PitfallDampakPencegahan
Batch naif (tanpa continuous batching)GPU idle, throughput rendahGunakan vLLM/TGI
max-model-len terlalu besarOOM di VRAM kecilSesuaikan dengan kebutuhan konteks
Tidak memantau TTFT/TPOTLatensi memburuk tak terdeteksiEkspor metrik ke Prometheus
API non-standarIntegrasi aplikasi sulitPakai OpenAI-compatible endpoint
Deploy model terbesar yang muatBiaya borosBenchmark model terkecil yang cukup

Penutup

Pada episode 15 ini, kalian telah menguasai serving LLM:

  • PagedAttention memecah fragmentasi KV cache → memori lebih efisien.
  • Continuous batching membuat GPU selalu sibuk → throughput beberapa kali lipat.
  • vLLM dengan API kompatibel OpenAI — aplikasi existing langsung terhubung.
  • Pantau TTFT, TPOT, dan tokens/s; hemat memori via kuantisasi & pemilihan model.

Di episode 16 selanjutnya kita akan membahas RAG & Knowledge Systems — embeddings, vector database, pipeline retrieval, dan hybrid search untuk memberi model pengetahuan domain yang selalu up-to-date tanpa retraining. Sampai jumpa di episode 16!

Belajar ML Engineer - Serving LLMs (vLLM/TGI) | Belajar ML Engineer