Ringkasan Utama
vLLM 0.31.0, rilis 5 Oktober 2026, menambahkan vllm preload, yaitu weight-cache daemon per GPU yang menyimpan weight hasil quantization di memori GPU sehingga restart engine tidak perlu loading dari disk. Model Runner V2 sudah menjadi default sejak 0.29. Sebelum upgrade, grep flag yang dihapus, batasi multimodal kwargs, dan buktikan cached start tidak diam-diam kembali ke disk.
Saya membaca halaman release vLLM v0.29.0, v0.30.0 dan v0.31.0 untuk mencari satu jawaban: apa yang berubah bagi orang yang me-restart server vLLM di production. Jawabannya tersebar di tiga release dalam empat minggu. Daemon muncul di 0.30, menjadi command resmi di 0.31, dan runner di bawahnya berganti default di 0.29. Kalau hanya membaca halaman terbaru, dua pertiga ceritanya terlewat.
Sumber saya adalah tiga halaman release GitHub, docs preload dan CLI v0.31.0, docs initialized snapshots, satu checklist upgrade dari pihak ketiga, dan tulisan LMSYS tentang ide yang sama di SGLang. Saya tidak menjalankan apa pun di GPU, jadi tidak ada angka di bawah ini yang hasil ukur saya. Setiap flag, default dan batasan dikutip dari halaman yang saya baca, dan bila sumbernya sekunder atau docs-nya tidak terkunci ke 0.31, saya sebutkan.
Tiga release dalam empat minggu, dan cerita restart menyebar di semuanya
Mulai dari timeline, karena breaking change menumpuk sepanjang itu. Catatan 0.30 menjelaskan weight-cache daemon per GPU yang melayani restart lewat --load-format ipc_cache. Catatan 0.31 menaikkannya menjadi CLI vllm preload dan menambah data parallelism, model draft MTP, endpoint /health dan readiness wait. Kalau Anda upgrade dari sebelum 0.29, Anda mewarisi semua penghapusan di tabel di bawah, bukan hanya daftar di halaman terbaru.
| Release | Tanggal | Ukuran | Perubahan restart dan runner |
|---|---|---|---|
| v0.29.0 | 9 Sep 2026 | 594 commit, 277 contributor | Model Runner V2 menjadi default untuk semua model; V1 deprecated, penghapusan ditargetkan di v0.32 |
| v0.30.0 | 22 Sep 2026 | 762 commit, 315 contributor | Weight-cache daemon per GPU lewat --load-format ipc_cache; endpoint scale-out menjadi opt-in |
| v0.31.0 | 5 Okt 2026 | 717 commit, 307 contributor | CLI vllm preload dengan data parallelism, draft MTP, /health dan readiness wait; snapshot CRIU eksperimental |
Halaman release menghitung sendiri commit dan contributor, dan saya menyalin angkanya apa adanya. Ini pengingat bahwa ritmenya bukan patch kecil: tiap release berisi ratusan commit, dan tiap release menghapus atau mengganti nama sesuatu yang mungkin ada di systemd unit Anda. Satu batasan jujur: halaman v0.29 tidak mencetak tahun, jadi tahunnya saya simpulkan dari tanggal release di sekitarnya.
Model Runner V2 sudah default, dan V1 kini punya tanggal penghapusan
Catatan 0.29 menyatakan Model Runner V2 kini default untuk semua model. Catatan itu juga menyebut Model Runner V1 deprecated, dengan penghapusan ditargetkan di v0.32, dan proyek tidak akan menerima optimisasi khusus V1 lagi. Saat itu V2 masih belum punya sequence parallelism, dual-batch overlap, elastic expert parallelism, custom logits processor dan beberapa metode speculative decoding, dan vLLM kembali ke V1 bila Anda mengonfigurasi salah satunya.
Celahnya menutup sesuai jadwal. Highlight 0.31 mencantumkan draft-model speculative decoding dan custom logits processor yang kini jalan di Model Runner V2, dan 0.31 juga menolak Model Runner V1 dengan pipeline parallelism di atas 1, async scheduling dan structured output saat startup. Di 0.30, cache mode all untuk Mamba di-deprecate dan jatuh kembali ke V1. Artinya: config yang diam-diam jalan di V1 pada 0.29 kini punya tenggat, dan satu kombinasi tertentu langsung gagal alih-alih tersendat.
Jangan campur dengan biaya startup. Catatan 0.30 menyebut gc freezing di Model Runner V2 memangkas init engine dari 28,9 s menjadi 8,2 s di H200, angka milik proyek untuk setup mereka sendiri. Itu inisialisasi, bukan weight loading, dan merupakan bagian restart yang berbeda dari yang disasar preload. Saya tidak menemukan flag di catatan itu yang melaporkan runner mana yang terpilih, jadi periksa log startup Anda, jangan berasumsi.
Cara kerja weight-cache daemon, dan apa yang dijaganya tetap hidup
vllm preload menjalankan satu daemon per GPU. Setiap daemon memuat shard-nya, menjalankan post-processing quantization, lalu mengekspor tiap parameter dan buffer sebagai CUDA IPC handle lewat Unix domain socket. Engine yang dijalankan dengan --load-format ipc_cache membangun model di meta device, meminta tensor ke daemon di GPU-nya dan memetakannya tanpa copy, sehingga engine yang di-restart tidak pernah membaca checkpoint dari disk. Hanya jalan di CUDA dan ROCm.
# Step 1: one daemon per GPU. It loads each shard from disk ONCE, runs the
# quantization post-processing, and exports every tensor as a CUDA IPC handle.
# The command reports ready only when every rank is serving; if a rank dies at
# startup the others are terminated and the exit code is that rank's.
vllm preload --model meta-llama/Llama-3.1-8B-Instruct --tensor-parallel-size 4
# Step 2: engines map the daemon's tensors instead of reading the checkpoint.
# TP size, dtype, quantization, revision and the vLLM version must match the
# daemon's, or the engine quietly loads from disk (fallback defaults to true).
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--tensor-parallel-size 4 \
--load-format ipc_cache
# Stop the daemon with SIGINT or SIGTERM: it removes its sockets and frees GPU
# memory. In the default zero_copy mode the engines must be gone first.Sebelum melayani, engine dan daemon membandingkan fingerprint yang mencakup isi checkpoint (di-hash dari metadata safetensors), arsitektur, ukuran dan rank TP serta DP, dtype, quantization, model revision dan versi vLLM. Engine juga memeriksa bahwa GPU UUID milik daemon sama dengan device-nya, sehingga socket usang tidak bisa menyerahkan GPU yang salah. Bila daemon tidak ada atau salah satu fingerprint berbeda, engine memuat dari disk, dan itu perilaku default.
Idenya bukan baru di vLLM. LMSYS menerbitkan desain yang sama untuk SGLang pada Agustus 2026: satu daemon per GPU yang mengekspor CUDA IPC handle. Pada Ling-2.6-1T FP8 di delapan GPU H20-3e mereka melaporkan weight loading turun dari sekitar 495 s menjadi sekitar 0,63 s, dan menyebut loading dari disk memakan 93,2 persen waktu startup. Tulisan mereka sendiri tidak konsisten soal angka disk dan menyebut nilai lain di bagian lain, jadi baca sebagai orde besaran. Itu engine dan model yang berbeda, bukan hasil ukur vLLM, dan tulisan itu mencatat start pertama daemon tetap membaca dari disk.
Endpoint /health milik daemon mati kecuali Anda memberi --weight-cache-health-port, dan --weight-cache-health-host default-nya 0.0.0.0. Kalau diaktifkan, set host ke 127.0.0.1 sendiri kecuali probe eksternal benar-benar butuh. Endpoint itu hanya menyatakan parent daemon hidup; ia tidak menjalankan inference.
Config loader: dua mode, satu fallback, dan timeout-nya
Loader diatur lewat --model-loader-extra-config di engine. Mode menentukan siapa yang memegang weight: di zero_copy engine memetakan alokasi milik daemon dan daemon harus hidup lebih lama darinya, dengan satu salinan per GPU; di copy engine mengkloning tiap tensor ke memorinya sendiri dan daemon melepas cache-nya, yang membebaskan memori GPU tetapi memakan satu salinan penuh tiap restart. Di zero_copy, sleep mode weight offloading tidak boleh dipakai bersama loader ini.
| Key | Default | Fungsinya |
|---|---|---|
| mode | zero_copy | zero_copy memetakan alokasi CUDA daemon; copy mengkloning ke memori engine dan membiarkan daemon melepas cache-nya |
| fallback | true | Muat dari disk bila daemon tidak tersedia atau fingerprint tidak cocok; platform yang tidak didukung tetap memunculkan error |
| socket_dir | Direktori privat per user di bawah temp dir | Direktori yang berisi socket daemon per GPU |
| connect_timeout_s | 5.0 | Timeout koneksi socket dalam detik |
| state_timeout_s | 300.0 | Timeout untuk request transfer weight dalam detik |
Scale-out mengikuti node. IPC handle bersifat lokal per node, jadi tensor parallelism multi-node butuh satu launcher per node, masing-masing hanya melayani GPU lokalnya, dengan --weight-cache-master-port dipatok dan berbeda dari --master-port milik engine. Dengan data parallelism, GPU lokal i melayani DP rank start_rank ditambah hasil bagi bulat i dengan tp_size, dan TP rank i modulo tp_size. Untuk MTP, EAGLE dan EAGLE3, grup draft daemon terpisah menyimpan model draft dengan nama socket dan rendezvous port sendiri.
# Strict engine config for rollout tests: fail instead of falling back to disk.
# connect_timeout_s and state_timeout_s are shown at their documented defaults.
vllm serve meta-llama/Llama-3.1-8B-Instruct --tensor-parallel-size 4 \
--load-format ipc_cache \
--model-loader-extra-config '{"mode": "zero_copy", "fallback": false, "connect_timeout_s": 5.0, "state_timeout_s": 300.0}'
# Multi-node TP: one launcher per node, each serving only its local GPUs.
# The daemon's rendezvous port must differ from the engine's --master-port
# and match across nodes.
vllm preload --model /path/to/model --tensor-parallel-size 16 \
--nnodes 2 --node-rank 0 --master-addr 10.0.0.1 \
--weight-cache-master-port 29600
# node 1: the same command with --node-rank 1Preload, snapshot, sleep mode: alat restart mana yang cocok
0.31 memberi dua cara baru menghindari cold start, dan keduanya tidak bisa saling menggantikan. vllm snapshot create dan vllm snapshot restore memakai CRIU untuk memulihkan engine TP1 yang sudah terinisialisasi penuh, sehingga menyasar inisialisasi engine, walau docs menyebut restore tetap memuat ulang file model dan KV cache sebelum mengikat HTTP. Harganya kotak yang jauh lebih sempit: Linux x86-64, satu GPU NVIDIA, root atau sudo tanpa password, io_uring dinonaktifkan, model revision 40 karakter yang dipatok, dan server HTTP plaintext tanpa autentikasi. Saya membaca halaman snapshot di URL latest, karena URL versi 0.31.0 mengembalikan 404, jadi anggap batasannya docs terkini, bukan terkunci ke 0.31.
| Opsi | Yang bertahan saat restart | Syarat keras | Cakupan tervalidasi menurut docs |
|---|---|---|---|
| Start biasa (--load-format auto) | Tidak ada: weight dibaca dari disk dan diproses ulang | Instalasi biasa | Semua yang didukung vLLM |
| Preload daemon (zero_copy) | Weight hasil quantization di memori GPU, satu daemon per GPU | CUDA atau ROCm; node, user dan versi vLLM yang sama; tanpa pipeline parallelism | TP, EP dan DP; metode quantization harus mendukung weight pra-proses |
| Snapshot terinisialisasi (CRIU) | Engine yang sudah terinisialisasi penuh, dipulihkan dengan CRIU | Linux x86-64, satu GPU NVIDIA, root atau sudo, io_uring nonaktif, revision dipatok | Hanya dense float16 TP1; berlabel eksperimental |
| Sleep mode | Proses yang tetap hidup | Tidak bisa digabung dengan loader preload zero_copy | Docs menyebutnya alternatif yang lebih sederhana dibanding snapshot, dengan biaya resource berbeda |
Aturan praktis saya dari tabel, dan ini penilaian, bukan rekomendasi resmi docs: coba preload dulu, karena syaratnya lingkungan yang sudah dipenuhi kebanyakan host GPU dan ia mencakup tensor, expert dan data parallelism. Snapshot cocok untuk layanan satu GPU satu model di mana waktu init mendominasi dan Anda bisa menerima root, container privileged, dan listener plaintext di dalam batas yang tepercaya. Restore gagal alih-alih kembali ke start normal, jadi ia butuh jalur recovery sendiri.
Breaking change, dalam urutan yang akan menabrak deploy Anda
Kebanyakan gagal dengan suara keras, yang merupakan kasus baik. Yang perlu dibaca dua kali adalah gerbang multimodal kwargs, perubahan keamanan yang tampil sebagai flag, serta baris GPTQ dan YaRN yang mengubah perilaku alih-alih menolak start.
| Perubahan | Sejak | Kata catatan release | Yang perlu dicek |
|---|---|---|---|
| mm_processor_kwargs dan media_io_kwargs per request | 0.31 | Mengembalikan error kecuali server dijalankan dengan --trust-request-mm-kwargs; setelan tingkat server dan LLM offline tidak berubah | Cari client yang mengirimnya per request; aktifkan flag hanya untuk client yang Anda percaya |
| tokenizer_mode slow | 0.31 | Dihapus; sebelumnya sudah berperilaku seperti hf di Transformers v5 | Ganti dengan hf |
| quantization fp8 | 0.31 | Dialihkan ke shorthand fp8_per_tensor | Tulis fp8_per_tensor secara eksplisit agar config menyatakan apa yang dilakukannya |
| --enable-mamba-fine-grained-prefix-cache | 0.31 | Diganti nama menjadi --enable-mamba-shared-prefix-checkpoint | Perbarui launch script |
| Bentuk koma pada --collect-detailed-traces | 0.31 | Dihapus, diganti sintaks list | Tulis ulang nilainya sebagai list |
| Model Runner V1 dengan pipeline parallelism di atas 1, async scheduling dan structured output | 0.31 | Ditolak saat startup | Lepas salah satu dari ketiganya sebelum upgrade |
| Endpoint scale-out | 0.30 | Tidak lagi didaftarkan di vllm serve biasa kecuali --enable-scale-out diberikan; VLLM_ENABLE_SCALE_OUT_ENDPOINTS dihapus | Tambahkan flag di mana pun Anda memanggil endpoint itu |
| Urutan aktivasi g_idx pada GPTQ | 0.30 | Dihapus; g_idx diabaikan | Catatan tidak menyebut dampaknya ke kualitas output, jadi evaluasi ulang model GPTQ |
| Alias YaRN vendor | 0.30 | Tidak lagi me-rescale max_model_len; TeleChat3-36B-Thinking turun dari 131072 ke 32768 | Catat max_model_len efektif setelah upgrade |
| python -m vllm.entrypoints.openai.api_server | 0.29 | Deprecated, diganti vllm serve | Ganti entrypoint di service unit |
Script di bawah meng-grep repository deploy untuk string-string itu, ditambah tiga env var yang dihapus catatan release (VLLM_PREFIX_CACHE_RETENTION_INTERVAL, VLLM_MM_HASHER_ALGORITHM dan VLLM_PLE_CPU_OFFLOAD). Dua knob baru perlu diketahui sekalian: --max-num-active-seqs membatasi admisi RUNNING terpisah dari max_num_seqs (0.31), dan --max-num-queued-reqs serta --max-num-queued-tokens menambah admission control pada waiting queue (0.29).
# Run from the repo that holds your launch scripts, unit files and compose files.
# Each pattern is something the 0.29 to 0.31 notes removed, renamed or gated.
# A hit is a place to read, not proof of a bug: the quantization pattern also
# matches a deliberately spelled fp8 that now redirects to fp8_per_tensor.
grep -rnE \
-e 'tokenizer[_-]mode[= ]+"?slow' \
-e 'quantization[= ]+"?fp8"?( |$)' \
-e 'enable-mamba-fine-grained-prefix-cache' \
-e 'collect-detailed-traces[= ][^ ]*,' \
-e 'VLLM_ENABLE_SCALE_OUT_ENDPOINTS' \
-e 'VLLM_PREFIX_CACHE_RETENTION_INTERVAL' \
-e 'VLLM_MM_HASHER_ALGORITHM' \
-e 'VLLM_PLE_CPU_OFFLOAD' \
-e 'vllm\.entrypoints\.openai\.api_server' \
-e 'mm_processor_kwargs|media_io_kwargs' \
--include='*.sh' --include='*.service' --include='*.yml' \
--include='*.yaml' --include='*.py' .Di mana ia bisa salah: start yang berhasil bukan berarti cache hit
Kegagalan yang perlu dinamai adalah fallback senyap. fallback default-nya true, jadi daemon yang hilang, di socket yang salah, atau punya fingerprint untuk versi vLLM berbeda menghasilkan engine yang start, lulus health check dan memuat dari disk dengan kecepatan lama. Checklist upgrade pihak ketiga menyatakannya lugas: start yang berhasil saja tidak membuktikan cache hit. Tidak ada yang saya baca yang menyediakan metrik hit versus fallback, jadi buktinya adalah menjalankan engine sekali dengan fallback false dan melihat ia bisa start.
Trade-off kedua adalah versi termasuk dalam fingerprint. Docs menyatakan daemon dan engine harus memakai versi vLLM yang sama, dan checklist menyebut daemon 0.30 bukan warm cache untuk engine 0.31. Kesimpulan saya, bukan prosedur resmi: upgrade tetap cold start, karena daemon baru harus membaca checkpoint dari disk sekali sebelum restart menjadi cepat. Preload mempercepat restart build yang sama, bukan upgrade.
Protokol daemon memakai pickle, dan docs membatasinya untuk proses lokal tepercaya milik user yang sama. Socket berada di direktori 0700 dan daemon memeriksa UID peer dengan SO_PEERCRED, tetapi jangan arahkan socket_dir ke path bersama, dan ingat artifact snapshot berisi memori proses dan state CUDA, jadi perlakukan sebagai data sensitif.
Batasan lain lebih sederhana. Di mode zero_copy daemon harus hidup selama engine hidup, dan menghentikannya dengan SIGINT atau SIGTERM menghapus socket dan membebaskan memori GPU. Metode quantization yang tidak bisa menyediakan weight pra-proses memunculkan error, pipeline parallelism ditolak saat launch, dan aturan node sama dan user sama berarti batas pod Kubernetes bisa memisahkan daemon dari engine-nya. Versi SGLang dari LMSYS membatasi diri pada unquantized dan FP8 block-wise, jadi cocokkan metode quantization Anda dengan docs vLLM, jangan menganggap sama.
Yang dikerjakan hari Senin
Perlakukan upgrade dan cached restart sebagai dua perubahan terpisah, dan rilis satu per satu. Urutan yang akan saya pakai:
- Jalankan grep audit di atas pada setiap repository yang meluncurkan vLLM, dan perbaiki tiap temuan di versi lama selama ejaan barunya sudah berfungsi.
- Upgrade tanpa preload dan periksa log startup untuk runner yang terpilih; jika config jatuh ke Model Runner V1, jadwalkan pekerjaannya sebelum v0.32.
- Audit client multimodal untuk mm_processor_kwargs dan media_io_kwargs per request sebelum memutuskan apakah --trust-request-mm-kwargs memang dibutuhkan.
- Jalankan preload daemon di satu canary host dan nyalakan engine dengan fallback false, agar ketidakcocokan gagal dengan keras.
- Ukur cold start, restart lewat daemon, dan ketidakcocokan yang disengaja pada model dan GPU Anda sendiri. Catat angkanya sendiri; tidak ada sumber yang saya baca yang memberi angka Anda.
- Baru setelah itu kembalikan fallback ke true untuk production, dan simpan image container serta launch config sebelumnya untuk rollback.
#!/usr/bin/env bash
# Canary rollout of the weight-cache daemon. Defaults for socket locations on purpose.
set -euo pipefail
MODEL=meta-llama/Llama-3.1-8B-Instruct
TP=4
# Daemon first. /health is off unless a port is given; bind it to loopback.
vllm preload --model "$MODEL" --tensor-parallel-size "$TP" \
--weight-cache-health-port 8100 --weight-cache-health-host 127.0.0.1 &
# The parent answers once the daemon is up. It does not prove the engine will
# hit the cache, and it runs no inference.
until curl -fs http://127.0.0.1:8100/health > /dev/null; do sleep 2; done
# Wrong: a plain engine start. It succeeds on a cache miss too, so a version
# or dtype mismatch is invisible.
# vllm serve "$MODEL" --tensor-parallel-size "$TP" --load-format ipc_cache
# Right for the canary: fallback false turns a mismatch into a startup failure.
vllm serve "$MODEL" --tensor-parallel-size "$TP" \
--load-format ipc_cache \
--model-loader-extra-config '{"fallback": false}'Script rollout di atas sengaja memakai default lokasi socket. Docs menurunkan direktori privat per user dan nama socket per GPU, dan menimpanya adalah keputusan terpisah yang hanya perlu Anda ambil bila launcher dan engine memang berjalan di path yang berbeda.
Aturan yang akan saya bawa dari tiga release ini: restart yang lebih cepat adalah fitur sekaligus mode kegagalan baru, karena jalur cepat dan jalur lambat sama-sama berakhir di server yang berjalan. Buat jalur cepat membuktikan dirinya dengan fallback mati, cek flag yang dihapus sebelum kode, dan ukur di hardware Anda sendiri, karena satu-satunya angka vLLM di halaman release adalah milik orang lain.
Sumber dan bacaan lanjutan
- vLLM GitHub: catatan release v0.31.0 (5 Oktober 2026), sumber item preload, snapshot, scheduling dan breaking change
- vLLM GitHub: catatan release v0.30.0, sumber daemon ipc_cache, opt-in scale-out dan penghapusan g_idx GPTQ
- vLLM GitHub: catatan release v0.29.0, sumber Model Runner V2 sebagai default dan deprecation V1
- Docs vLLM v0.31.0: halaman fitur Preload (cara kerja, cache mode, batasan, keamanan)
- Docs vLLM v0.31.0: referensi engine arguments, sumber flag weight-cache dan defaultnya
- Docs vLLM (latest): initialized snapshots, sumber syarat dan batasan CRIU
- Rohit AI: vLLM 0.31 preload, snapshot dan pengecekan upgrade multimodal (checklist pihak ketiga, bukan resmi)
- LMSYS: Fast Engine Recovery untuk SGLang lewat weight cache daemon (engine berbeda, dipakai untuk desain dan caveat-nya)

