Ringkasan Utama
LMCache multi-process mode menjalankan KV cache sebagai server terpisah yang dipakai bersama oleh semua rank data-parallel vLLM, menggantikan delapan offload pool terisolasi per rank dengan satu host-memory pool. Pada satu tes Qwen3-235B di 8x H100 milik LMCache, mean time-to-first-token turun dari 3,98 s ke 0,29 s, sedangkan angka 10x di judul adalah angka p99.
Angka yang membuat saya membuka post ini ada di judulnya: peningkatan 10x untuk inference mixture-of-experts. Angka sebulat itu biasanya menyembunyikan pembagi yang spesifik, jadi saya membaca tulisan LMCache, dokumentasi multi-process di baliknya, dan panduan data parallel vLLM secara berdampingan sebelum punya pendapat.
Saya tidak menjalankan setup ini; node 8x H100 tidak ada di meja saya. Semua yang ada di bawah adalah pembacaan dekat atas lima sumber primer, dengan hitungan diulang dan caveat yang dihilangkan headline. Setiap angka saya kaitkan ke halaman tempat saya membacanya, dan hal yang tidak disebut halaman itu saya tandai sebagai tidak diketahui, bukan ditebak.
Kenapa DP plus EP membuat tiap rank punya KV cache sendiri
Baseline di post ini adalah vLLM dengan data parallelism untuk attention dan expert parallelism untuk expert. Panduan data parallel vLLM menjelaskan setiap DP rank sebagai proses core engine terpisah yang berbicara dengan front end lewat ZMQ socket, dan menyatakan bahwa setiap DP engine punya KV cache yang independen. Bobot attention direplikasi per rank, sedangkan expert di-shard antar rank begitu expert parallelism aktif.
Layout itu bagus untuk throughput dan buruk untuk reuse. Post LMCache menyebut setiap request di-pin ke satu DP rank, sehingga percakapan multi-turn hanya diuntungkan oleh prefix yang ter-cache jika turn berikutnya mendarat di rank yang sama dengan turn sebelumnya. Panduan vLLM menyebut load balancer internalnya memakai antrean running dan waiting tiap engine, bahwa routing yang sadar KV cache belum diimplementasikan, dan bahwa manfaat prefix caching bergantung pada pengarahan prompt yang cerdas tanpa menjelaskan caranya.
Akibatnya adalah fragmentasi. Bahkan dengan CPU offload aktif, post menyebut cache tidak dibagi antar rank, sehingga prefix yang tumpang tindih di rank berbeda dihitung ulang. Untuk chat, agent, dan RAG, tempat tiap turn memperpanjang turn sebelumnya, itu adalah kerja prefill berulang yang Anda bayar dalam time-to-first-token. Catatan: ini klaim tentang mekanisme; post tidak melaporkan cache hit rate, jadi seberapa sering hal itu terjadi di tes tidak terukur.
Baseline: in-process offload, satu pool per rank
Baseline in-process memakai offloading bawaan vLLM dengan 50 GB host memory per rank. Di delapan rank totalnya 400 GB, dan launch-nya seperti ini.
# Baseline from the LMCache post: 8-way DP, experts sharded by EP,
# and one isolated 50 GB host-memory offload pool PER RANK (8 x 50 = 400 GB).
VLLM_USE_FLASHINFER_MOE_FP8=0 VLLM_USE_DEEP_GEMM=1 \
vllm serve Qwen/Qwen3-235B-A22B-Instruct-2507-FP8 \
--data-parallel-size 8 \
--enable-expert-parallel \
--gpu-memory-utilization 0.8 \
--max-num-batched-tokens 1024 \
--kv-offloading-size 50 \
--disable-hybrid-kv-cache-manager \
--max-model-len auto
# Each rank can only reuse prefixes that rank itself has seen. A follow-up turn
# routed to a different rank than its first turn finds nothing and recomputes.Dua detail penting nanti. Pertama, post mencatat bahwa flag disable-hybrid-kv-cache-manager diperlukan untuk model hybrid-memory-allocator dengan native offloading connector. Kedua, total 400 GB sama dengan pool tunggal yang dipakai run multi-process, jadi kedua sisi mendapat host memory yang sama. Yang berbeda adalah apakah memori itu satu pool atau delapan.
Apa yang diubah multi-process mode secara arsitektur
Di multi-process mode, LMCache berhenti menjadi library di dalam tiap proses vLLM dan menjadi service mandiri. Dokumentasi menyebut engine terhubung lewat transport request ZMQ atau gRPC, dan README menggambarkannya sebagai daemon yang berjalan terpisah dari inference engine. Perbandingan di bawah disusun dari post, dokumen multi-process, dan README.
| Aspek | In-process offload | LMCache multi-process mode |
|---|---|---|
| Lokasi cache | Di dalam tiap rank vLLM, process-local dan terfragmentasi | Satu server per node, satu L1 host-memory pool bersama |
| Reuse prefix lintas rank | Tidak ada; tiap rank hanya melihat riwayatnya sendiri | Rank mana pun bisa memakai ulang yang disimpan rank lain |
| Kegagalan cache | Satu proses dengan engine, jadi senasib | Dokumen menyatakan kegagalan cache tidak menjatuhkan engine |
| Hashing dan manajemen memori | Bersaing dengan thread vLLM di proses yang sama | Berjalan di proses LMCache, di luar thread Python vLLM |
| Tier bawah | Hanya host memory offload pada baseline | L1 adalah DRAM; backend L2 seperti local storage dan remote connector |
| Jangkauan | Satu rank | Satu node saat ini; peer-to-peer lintas node masih roadmap |
Di dalam server, dokumen menjelaskan StorageManager yang mengoordinasikan L1 pool dan adapter L2 opsional, dengan controller untuk menyimpan ke L2, mengeluarkan dari L1, dan prefetch hit L2 kembali ke L1. Kebijakan eviction yang tercantum adalah LRU, ARC, IsolatedLRU, dan noop. Run di post memakai LRU. L1 secara default adalah pinned CPU DRAM, dengan Device-DAX dan NVMe slab lewat GPUDirect Storage sebagai alternatif.
Konfigurasi yang menghasilkan angkanya
Post menerbitkan kedua baris launch, dan itulah yang membuatnya bisa diperiksa. Run MP menjalankan server dengan L1 pool 400 GB dan eviction LRU, lalu meluncurkan perintah vLLM DP plus EP yang sama dengan KV connector sebagai ganti flag offload.
# Terminal 1: the LMCache server owns ONE host-memory L1 pool for the node.
# 400 GB is the pool the post used on its 8x H100 box.
lmcache server --l1-size-gb 400 --eviction-policy LRU
# Terminal 2: the same vLLM DP+EP launch, with the connector instead of
# --kv-offloading-size. The post also drops --disable-hybrid-kv-cache-manager
# and does not say why, so treat that as a second variable.
VLLM_USE_FLASHINFER_MOE_FP8=0 VLLM_USE_DEEP_GEMM=1 \
vllm serve Qwen/Qwen3-235B-A22B-Instruct-2507-FP8 \
--data-parallel-size 8 \
--enable-expert-parallel \
--gpu-memory-utilization 0.8 \
--max-num-batched-tokens 1024 \
--max-model-len auto \
--kv-transfer-config '{"kv_connector":"LMCacheMPConnector","kv_role":"kv_both"}'
# The post's load generator: multi-round chat at 2.0 QPS for 120 seconds.
lmcache bench engine --engine-url http://localhost:8000 \
--workload multi-round-chat --mrc-qps 2.0 --mrc-duration 120Baca bedanya dengan teliti. Perintah MP tidak punya kv-offloading-size dan tidak punya disable-hybrid-kv-cache-manager, dan post tidak menjelaskan kedua penghilangan itu. Jadi kedua run berbeda lebih dari sekadar connector, dan selisih yang dipublikasikan tidak bisa dikaitkan hanya ke shared memory. Jika Anda mereproduksi, ubah satu hal pada satu waktu.
Jaga A/B Anda tetap jujur: jalankan baseline dan launch MP dengan semua flag vLLM lain identik, termasuk setelan hybrid KV cache manager, dan laporkan mean serta p99 time-to-first-token dari load generator yang sama.
Membaca benchmark: 10x itu sebenarnya apa
Tes memakai Qwen3-235B-A22B-Instruct-2507-FP8 di satu server dengan delapan GPU H100 80 GB, vLLM 0.18.1 dan LMCache 0.4.3-dev, digerakkan workload multi-round chat 2,0 QPS selama 120 detik. Berikut nilai tabel post dengan rasio yang saya hitung ulang.
| Metrik | In-process | LMCache MP | Rasio |
|---|---|---|---|
| TTFT mean | 3,98 s | 0,29 s | sekitar 13,7x lebih rendah |
| TTFT p99 | 13,55 s | 1,30 s | sekitar 10,4x lebih rendah |
| Decode mean | 9,81 tok/s | 37,47 tok/s | sekitar 3,8x lebih tinggi |
| Decode p99 | 34,27 tok/s | 45,14 tok/s | sekitar 1,3x lebih tinggi |
Headline 10x cocok dengan rasio p99 time-to-first-token, bukan mean. Rasio mean lebih besar, dan bar chart di post memberi label 13,6x, dekat dengan 13,7x hitungan saya dari nilai tabel yang dibulatkan. Angka decode gain-nya lebih kecil, dan post tidak mendefinisikan apakah decode speed itu per request atau agregat, jadi saya tidak akan mengutip 3,8x tanpa caveat itu.
Post menyebut hit rate cache yang lebih tinggi, prefill redundan yang berkurang, dan fragmentasi yang berkurang, tetapi tidak menunjukkan data hit rate untuk memastikan pembagiannya. Ini satu model, satu mesin, satu workload, dan satu level QPS, tanpa pengulangan atau variansi, pada build development LMCache. Jumlah percakapan serta panjang prompt dan output tidak disebutkan. Anggap ini bukti keberadaan mekanisme yang kuat, bukan ramalan untuk cluster Anda.
Trade-off dan tempat ia bisa menggigit
Service cache bersama adalah satu bagian bergerak lagi di jalur panas setiap request. Dari dokumentasi, ini batasan yang akan saya rencanakan sebelum mengadopsinya.
- Version lockstep: dokumen menyuruh upgrade server dan worker bersamaan, karena typed inline protocol tidak kompatibel dengan versi lama.
- Sizing worker: setelan max-workers default-nya 1, dan max-gpu-workers sebaiknya minimal sebanyak instance vLLM yang berbagi server.
- Isolated IPC mode hanya bekerja dengan vLLM MP connector, butuh package cuda-python di kedua sisi, dan tidak kompatibel dengan expandable_segments:True serta vLLM sleep mode.
- Cakupan: sharing per node. Peer-to-peer sharing dan prefill-decode disaggregation untuk reuse seluruh cluster tercantum sebagai rencana, tanpa tanggal.
Benchmark memakai build development, LMCache 0.4.3-dev, dan dokumen meminta dev branch LMCache terbaru. Pin versi persis vLLM dan LMCache bersamaan, uji di release build, dan perlakukan server sebagai komponen yang kenaikan versinya dikoordinasikan dengan engine Anda.
Ada juga pertanyaan kapasitas yang tidak dijawab post. Satu pool berarti tekanan eviction dari semua rank jatuh ke memori yang sama, dan dokumen menyebut eviction dipicu di watermark 0,8 dan membebaskan 0,2 memori terisi per siklus secara default. Jika working set Anda lebih besar dari L1, pool bersama bisa membuang prefix berguna satu rank demi rank lain, perilaku yang perlu dipantau, bukan yang dilatih benchmark.
Menjalankannya: port, proses, dan bentuk Kubernetes
Halaman deployment memakai empat port. Port transport adalah yang harus disepakati connector engine, jadi ketidakcocokan antara port server dan nilai lmcache.mp.port di config connector adalah hal pertama yang dicek saat engine tidak menemukan cache.
| Port | Fungsi menurut halaman deployment |
|---|---|
| 6555 | Port transport LMCache, diatur lewat port di server dan lmcache.mp.port di connector |
| 8080 | Varian HTTP server, dengan endpoint healthcheck untuk probe |
| 9090 | Metrik Prometheus, aktif secara default |
| 8000 | API vLLM pada tes contoh di halaman itu |
# Server as the deployment page runs it (Docker, one node, 60 GB L1).
# --ipc host is what lets the engine and server share GPU memory handles;
# --isolated-ipc plus lmcache.mp.isolated_ipc on both sides removes that need.
docker run --runtime nvidia --gpus all --network host --ipc host \
lmcache/standalone:nightly \
/opt/venv/bin/lmcache server --l1-size-gb 60 --eviction-policy LRU \
--max-workers 4 --port 6555
# vLLM side: the connector must point at the same transport port.
--kv-transfer-config '{"kv_connector":"LMCacheMPConnector","kv_role":"kv_both","kv_connector_extra_config":{"lmcache.mp.port":6555}}'
# Kubernetes: the server is a DaemonSet (one per GPU node), vLLM a Deployment.
kubectl create namespace multi-process
kubectl apply -f examples/multi_process/lmcache-daemonset.yaml
kubectl apply -f examples/multi_process/vllm-deployment.yamlDi Kubernetes, halaman itu men-deploy server sebagai DaemonSet sehingga tiap node GPU menjalankan satu, dengan host networking dan transport terikat ke 127.0.0.1. DaemonSet tidak meminta GPU, pod vLLM yang memegangnya, dan pod LMCache yang terjadwal di node tanpa GPU crash dengan error inisialisasi CUDA. Halaman itu mencantumkan minimal 4 GPU per node dan NVIDIA GPU Operator sebagai syarat contohnya.
Yang dilakukan hari Senin
Jangan mulai dengan menginstalnya. Mulailah dengan mencari tahu apakah fragmentasi memang masalah Anda, lalu jalankan perbandingan terkontrol.
- Pastikan bentuknya: Anda menjalankan lebih dari satu DP rank dan traffic Anda multi-turn, agentic, atau RAG. Dengan satu rank tidak ada yang bisa dibagi.
- Catat baseline pada workload Anda sendiri: mean dan p99 time-to-first-token dari lmcache bench engine atau replay Anda sendiri, dengan flag offload yang sekarang.
- Jalankan satu server LMCache per node dengan ukuran L1 dari host memory yang tersisa setelah OS dan vLLM, lalu ganti hanya connector dan flag offload.
- Set max-gpu-workers minimal sebanyak engine di node, dan scrape port 9090 agar Anda melihat perilaku eviction dan hit, bukan menebaknya.
- Pin versi bersamaan, ulangi di lebih dari satu level QPS dengan pengulangan, baru putuskan; hasil yang dipublikasikan hanyalah satu titik.
Jika routing layer Anda sudah mengirim percakapan ke rank yang sama setiap kali, pool bersama memberi lebih sedikit dari yang disiratkan post, karena fragmentasi yang dihilangkannya adalah biaya salah routing. Dalam kasus itu, memperbaiki routing bisa jadi eksperimen pertama yang lebih murah.
Pelajaran yang saya ambil dari post ini: di serving DP plus EP, lokalitas KV cache adalah sifat topologi deployment Anda, bukan hanya kebijakan cache. Memindahkan cache dari rank ke service node-level bersama menghilangkan sumber recomputation yang nyata, dan mean 0,29 s masuk akal karena itu, tetapi headline 10x adalah angka p99 dari satu run build dev. Ukur workload Anda sendiri sebelum percaya salah satu angka.
Sumber dan bacaan lanjutan

