Skip to main content
BlogAI/ML

vLLM Bi-Directional KV Transfer untuk Agen Multi-Turn

Agen multi-turn mengirim ulang seluruh riwayatnya, dan prefill node yang di-disaggregate menghitung ulang apa yang sudah dipegang decode node. Pembacaan teliti bi-directional KV transfer di vLLM: enam langkah, pengaturan TTL dan threshold, angkanya, dan apa yang bisa rusak.

Matthews Wong

Software Engineer

Oktober 202612 menit baca
vLLM Bi-Directional KV Transfer untuk Agen Multi-Turn

Ringkasan Utama

Bi-directional KV transfer di vLLM membuat prefill node menarik KV cache yang disimpan decode node dari giliran sebelumnya, sehingga agen multi-turn hanya melakukan prefill untuk suffix yang baru. Tim vLLM melaporkan time to first token turun hingga 1,6x pada Qwen3-32B dan 3,3x pada GLM-5-FP8 di setup satu prefill dan satu decode dengan EFA, dengan prefix caching dimatikan di prefill.

Setiap agent loop yang saya baca berakhir sama: giliran demi giliran, client mengirim ulang seluruh percakapan, termasuk tool call dan hasilnya, dan server melakukan prefill untuk semuanya sebelum mengeluarkan satu token pun. Pada 12 Oktober 2026 tim vLLM menerbitkan tulisan tentang cara mengambil kembali pekerjaan berulang itu, dan detail yang membuat saya membacanya dua kali adalah lokasi cache-nya. Decode node sudah menyimpan KV block untuk giliran sebelumnya, termasuk token yang ia hasilkan sendiri. Prefill node, yang mengerjakan bagian paling mahal, tidak bisa melihatnya.

Ini adalah hasil membaca sumber primer, bukan benchmark yang saya jalankan sendiri. Saya membaca tulisan vLLM, halaman NixlConnector dan disaggregated prefill di dokumentasi vLLM, pull request yang sudah di-merge beserta RFC di baliknya, pull request yang masih terbuka yang menjadi dependensi reproduksi di tulisan itu, dan dokumentasi EFA dari AWS. Setiap angka di bawah milik tim vLLM atau kontributornya dan ditulis dengan atribusi. Apa pun yang tidak saya temukan di sumber, saya buang.

Mengapa giliran agen kesepuluh membayar sembilan giliran pertama lagi

Pada agen multi-turn, giliran N mengirim ulang giliran 1 sampai N-1 ditambah apa pun yang baru. Pada satu node dengan prefix caching ini murah, karena riwayatnya sudah ada. Pada disaggregation prefill-decode sering tidak demikian: tulisan itu menjelaskan prefill node menghitung ulang konteks setiap kali ia miss pada cache-nya sendiri, dan biayanya tumbuh seiring percakapan. Baseline di tulisan itu menunjukkannya. Dengan fitur mati, time to first token (TTFT) Qwen3-32B naik dari 158 ms pada prompt sekitar 2k token menjadi 778 ms pada sekitar 24k, dan GLM-5-FP8 naik dari 500 ms pada sekitar 2k menjadi 2.334 ms pada sekitar 20k.

Bagi angka ujung itu dan polanya jelas. Prompt tumbuh sekitar 12 kali untuk Qwen3-32B dan 10 kali untuk GLM-5-FP8, sedangkan TTFT tumbuh sekitar 4,9 dan 4,7 kali. Itu hitungan saya atas angka ujung di tulisan tersebut, bukan angka yang dinyatakan tulisannya, dan campuran antara recompute dan overhead tetap, jadi bukan hukum yang bersih. Poinnya lebih sempit: agen di giliran keempat puluh membayar pajak latensi yang terlihat di setiap giliran untuk teks yang sudah pernah dihitung oleh cluster.

Disaggregation saja tidak menyelesaikan ini. Dokumentasi vLLM menyebut disaggregated prefill ada untuk menyetel TTFT dan inter-token latency secara terpisah, dengan memberi tiap instance pengaturan parallel sendiri, dan menyatakan bahwa fitur itu tidak meningkatkan throughput. Halaman itu juga menandai fiturnya sebagai experimental. Jadi pertanyaan pertama bukan cara mengaktifkan bi-directional transfer, melainkan apakah traffic Anda cukup multi-turn dan berat di prefill sehingga prefix yang berulang itulah yang Anda bayar.

Apa yang ditinggalkan disaggregation prefill-decode satu arah

Pada alur standar, KV bergerak satu arah. Prefill node menghitung KV dari prompt dan mengirimnya ke decode node, yang menghasilkan jawaban. Karena itu decode node akhirnya memegang KV untuk prompt dan untuk setiap token yang ia hasilkan. Pada giliran berikutnya client mengirim ulang semuanya sebagai input, dan prefill node, yang tidak pernah melihat token hasil generate, tidak punya apa pun untuk dicocokkan. RFC di balik fitur ini menyebut dua kasus yang timbul: percakapan multi-turn, di mana respons model sebelumnya hanya ada di decode, dan prefill cache yang tergusur (evicted), di mana state sesi ada di decode sementara prefill miss pada cache-nya sendiri.

Hal yang dibandingkanSatu arah P ke DBi-directional
Arah transfer KVHanya prefill ke decodeDua arah; decode mengembalikan block yang disimpan ke prefill pada giliran berikutnya, memakai NIXL READ di kedua arah
KV dari token hasil generateHanya di decode; prefill tidak bisa memakainya lagiDisimpan di decode selama TTL; prefill bisa menariknya
Prefix yang berulangPrefill menghitung ulang apa pun yang miss di cache-nya sendiriPrefill menarik block-nya dan hanya menghitung suffix yang tersisa
Komponen tambahanProxy yang merutekan requestRouter stateful yang sadar KV cache, dikunci dengan conversation_id, hanya menyimpan metadata
Saat state cache sudah basiTidak berlaku; prefill selalu menghitung ulangPembacaan block yang kedaluwarsa ditolak dan giliran itu kembali ke prefill normal

Penulis RFC mempertimbangkan alternatif yang jelas, yaitu incremental prefill di decode node, dan menolaknya karena itu menggagalkan tujuan disaggregation dengan membuat decode node menjalankan kedua jalur. Menarik block kembali menjaga pembagian peran dan hanya mengubah apa yang berpindah lewat jaringan.

Enam langkah penarikan dari decode ke prefill

Tulisan vLLM menjelaskan alurnya dalam enam langkah. Jika dibaca bersama RFC, keputusan desain yang penting adalah tidak ada yang melakukan query ke decode node di jalur utama.

  1. Decode menyimpan KV untuk prompt dan untuk responsnya sendiri setelah request selesai.
  2. Decode mengembalikan metadata block pada chunk terakhir dari streaming response.
  3. Router menyimpan metadata itu di cache dengan kunci conversation_id.
  4. Pada giliran berikutnya, prefill melakukan lookup prefix cache lokal seperti biasa, lalu memeriksa apakah reuse dari remote memungkinkan.
  5. Jika jumlah yang bisa dipakai ulang mencapai threshold, ia mengantrekan receive yang asynchronous.
  6. Ia memuat KV dengan NIXL READ dari decode ke prefill dan hanya menghitung suffix yang tersisa secara lokal.

RFC menjelaskan mengapa metadata dibawa di response stream. Penulisnya awalnya mengusulkan query API terpisah untuk menanyakan parameter KV ke decode, mem-benchmark-nya, dan menemukan round trip tambahan menambah latensi, sehingga kini decode mengembalikan kv_transfer_params di streaming response-nya. Query API hanya tersisa untuk pairing node awal. Router menyimpan lokasi block, tidak pernah tensor KV.

# My sketch of the router-side state the post describes. NOT vLLM's code.
import time

DECODER_TTL_S = 480   # decoder_kv_blocks_ttl on the decode node
ROUTER_TTL_S = 450    # shorter on purpose: stop asking before decode drops blocks

_cache: dict[str, tuple[dict, float]] = {}  # conversation_id -> (kv_params, stored_at)

def remember(conversation_id: str, kv_params: dict) -> None:
    # kv_params comes from the terminal chunk of decode's streaming response.
    # Block LOCATIONS only. The router never touches KV tensors.
    _cache[conversation_id] = (kv_params, time.monotonic())

def lookup(conversation_id: str) -> dict | None:
    hit = _cache.get(conversation_id)
    if hit is None:
        return None                      # first turn, or router restarted: full prefill
    kv_params, stored_at = hit
    if time.monotonic() - stored_at > ROUTER_TTL_S:
        del _cache[conversation_id]
        return None                      # decode may have dropped them: full prefill
    return kv_params                     # handed to prefill, which pulls via NIXL READ

Sketsa itu buatan saya dan sengaja dibuat naif. Implementasi sebenarnya adalah disagg_proxy_multiturn.py di repositori vLLM, yang belum saya baca baris demi baris. Dokumentasi menambahkan satu detail penting: conversation_id adalah ekstensi proxy dan tidak diteruskan ke vLLM sendiri, jadi gateway Anda harus membuatnya dan membawanya di setiap giliran, dan pull request yang menambahkan kv_transfer_params ke streaming response adalah dependensi wajib.

Dua pengaturan yang menentukan apakah penarikan terjadi: TTL dan threshold

Dua pengaturan menentukan apakah penarikan terjadi dan apakah itu sepadan. Keduanya ada di kv_connector_extra_config, dan tulisan serta dokumentasinya memberi nilai default berikut.

SettingDefaultFungsinyaYang bisa salah
bidirectional_kv_xferTidak disebutkan; set true di kedua instanceMengaktifkan transfer dari decode ke prefillHanya di satu sisi, atau false di decode, dan proxy terus mencatat cache MISS
decoder_kv_blocks_ttl480 detikBerapa lama decode menyimpan block untuk dipakai ulang; tetap, dan tidak diperpanjang oleh heartbeatGiliran yang datang lebih lambat mencatat Declining expired remote read dan kembali ke prefill normal
kv_recompute_threshold64 tokenJumlah minimum token remote yang bisa dipakai ulang sebelum prefill menarik, bukan menghitung ulangTerlalu rendah membuang transfer untuk prefix yang lebih murah dihitung ulang; terlalu tinggi melepas reuse yang nyata
kv_lease_duration30 detikBerapa lama prefiller menahan block untuk decoder pada alur P ke D biasa; heartbeat memperpanjangnyaBukan TTL bidirectional; mengubahnya tidak membuat block di decode bertahan lebih lama

Jebakan penamaan: contoh config di pull request yang sudah di-merge menyebut threshold itu remote_pull_threshold, sedangkan dokumentasi terbaru dan tulisan Oktober menyebutnya kv_recompute_threshold. Periksa nama key terhadap versi yang Anda jalankan. Saya tidak bisa memastikan dari sumber apakah key yang tidak dikenal menimbulkan error atau diabaikan, jadi uji sendiri, jangan berasumsi.

Diskusi pull request menyebut retensi block di decode mengikuti timeout yang sama dengan transfer biasa, VLLM_NIXL_ABORT_REQUEST_TIMEOUT sebesar 480 detik, dan proxy contohnya mengadaluarsakan entry-nya sendiri pada 450 detik agar berhenti meminta block sebelum decode membuangnya. Saat PR itu ditulis, connector belum bisa menolak pembacaan block yang kedaluwarsa, jadi tiru kebiasaannya: jaga TTL router lebih pendek dari decoder_kv_blocks_ttl.

Membaca angkanya: 1,6x dan 3,3x, dan di kondisi apa diukur

Berikut angka-angka seperti yang diberikan tulisan itu. Ia mencetak angka ujung dalam prosa, bukan tabel per panjang prompt, jadi saya hanya menyalin apa yang dinyatakan.

ModelTTFT, fitur matiTTFT, fitur hidupTambahan waktu transfer KVPengurangan maksimum yang dilaporkan
Qwen3-32B (TP 8)158 ms pada sekitar 2k sampai 778 ms pada sekitar 24k122 ms sampai 460 msSekitar 30 sampai 130 msSekitar 1,6x
GLM-5-FP8500 ms pada sekitar 2k sampai 2.334 ms pada sekitar 20k358 ms sampai 702 msSekitar 29 sampai 110 msHingga 3,3x

Baca kondisinya sebelum rasionya. Satu prefill node dan satu decode node, masing-masing p5en.48xlarge dengan delapan GPU H200, di availability zone yang sama, lewat EFA, dengan prefix caching sengaja dimatikan di prefill node untuk meniru node yang sudah mengevict cache lokalnya. Benchmark client, jumlah percakapan, dan concurrency tidak disebutkan. Membagi angka ujung Qwen3-32B memberi sekitar 1,7x, bukan 1,6x seperti headline, jadi anggap headline sudah dibulatkan. Tulisan itu mengaitkan gain GLM-5-FP8 yang lebih besar dengan biaya recompute per token yang lebih tinggi; waktu transfer berada di rentang puluhan milidetik yang sama untuk kedua model, sehingga model yang lebih lambat dihitung ulang mendapat gain lebih besar. Tulisan itu sendiri menyatakan hasil bergantung pada workload dan konfigurasi deployment.

Pull request lebih terus terang soal kasus yang dialami sebagian besar cluster produksi. Dengan prefix caching aktif di prefill, penulisnya melaporkan median TTFT turun dari 307,86 ms menjadi 219,61 ms, sekitar 29 persen, pada Llama-3.3-70B di p5en. Itu hasil yang bagus dan sangat berbeda dari 3,3x. Rasio besar menggambarkan prefill node yang miss pada cache-nya sendiri; jika milik Anda jarang miss, harapkan angka yang lebih kecil.

Memasangnya: config yang dicetak tulisan vLLM, dan yang tidak dicetaknya

Tulisan itu mencetak sisi prefill secara lengkap. Ini adalah command dan config tersebut apa adanya, dengan komentar saya tentang fungsi tiap bagian.

# Prefill node, as printed in the vLLM post (Qwen3-32B, 8x H200, EFA).
# The post prints bidirectional_kv_xfer as false for the OFF leg; true is the ON leg.
export FI_PROVIDER=efa                      # EFA via libfabric; without it NIXL may use TCP
export VLLM_NIXL_SIDE_CHANNEL_HOST=<P_IP> VLLM_NIXL_SIDE_CHANNEL_PORT=5600

# --no-enable-prefix-caching goes on the PREFILL node only. It emulates a prefill
# node that has evicted its cache, which is the post's best case. Decode keeps it on.
vllm serve Qwen/Qwen3-32B --served-model-name Qwen --dtype bfloat16 \
  --tensor-parallel-size 8 --max-model-len 32768 --max-num-seqs 8 \
  --no-enable-prefix-caching --port 8100 \
  --kv-transfer-config '{"kv_connector":"NixlConnector","kv_buffer_device":"cuda",
    "kv_role":"kv_producer","engine_id":"prefill-engine-001","kv_rank":0,
    "kv_parallel_size":2,"kv_connector_extra_config":{"backends":["LIBFABRIC"],
    "kv_recompute_threshold":64,"decoder_kv_blocks_ttl":480,
    "bidirectional_kv_xfer":true}}'

Sisi decode tidak dicetak. Tulisan itu meminta menjalankan serve_pd_multiturn.sh dengan ROLE=decode dan menjaga BIDIR sama di kedua node. Dokumentasi memberi perannya: prefill adalah kv_producer, decode adalah kv_consumer, dan kv_both yang lama sudah deprecated untuk NixlConnector. Salin nilai decode dari repro script, bukan dari tebakan saya.

# Wrong: flag set on one side only. Nothing errors, the proxy logs "cache MISS"
# on every turn, and the run looks healthy while showing no speed-up.
#   prefill: "bidirectional_kv_xfer": true
#   decode:  "bidirectional_kv_xfer": false

# Right: identical on both nodes (the post's scripts take BIDIR=true on each),
# and restart the proxy between the OFF and ON legs: its cache is in-process.

# The multi-turn proxy takes hosts and ports, not URLs.
python3 $VLLM_SRC/examples/disaggregated/disaggregated_serving/disagg_proxy_multiturn.py \
  --port 8000 --prefiller-host <P_IP> --prefiller-ports 8100 \
  --decoder-hosts <D_IP> --decoder-ports 8200

# Before reading a single TTFT number, prove the transport on BOTH nodes:
fi_info -p efa | head -n 5        # empty output = no EFA provider = invalid run

# Then watch for the two log lines that explain most bad runs:
#   "Declining expired remote read"   -> TTL lapsed before the next turn
#   "KV Transfer metrics:"            -> transfer timings (prefill node log)

Transport adalah bagian dari hasil. AWS mendokumentasikan bahwa EFA terintegrasi dengan libfabric dan mendukung NIXL, bahwa NIXL membutuhkan libfabric 1.21.0 atau lebih baru, bahwa RDMA read didukung pada instance dengan Nitro versi 4 ke atas, dan bahwa traffic EFA tidak bisa melintasi availability zone atau VPC. Batas terakhir itulah alasan dua node di tulisan tersebut berada di zone yang sama. Tanpa EFA, tulisan itu memperingatkan, NIXL gagal atau jatuh ke TCP socket dan angka transfernya tidak valid. Dokumentasi vLLM menambahkan bahwa backend NIXL default adalah UCX, dan mode bi-directional saat ini hanya untuk CUDA dengan KV cache di device buffer.

Di mana ia rusak: kedaluwarsa, state router, reasoning trace

Lima mode kegagalan muncul di sumber-sumber itu, dan tidak ada yang eksotis.

  • TTL kedaluwarsa. Tulisan itu menyebut TTL tetap dan tidak diperpanjang, dan giliran yang datang lebih lambat kembali ke prefill normal. Agen yang menunggu tool lambat atau persetujuan manusia lebih dari 480 detik kehilangan cache-nya. Tulisan itu mengusulkan lease yang diperpanjang heartbeat sebagai pekerjaan berikutnya.
  • State router ada di memori. Tulisan itu mencatat conversation cache proxy ada di dalam proses, itulah sebabnya ia harus di-restart antara run off dan on. Inferensi saya, bukan tulisan itu: restart router, atau replica router kedua, mulai dengan map kosong dan setiap percakapan membayar satu kali prefill penuh.
  • Reasoning trace. Dokumentasi memperingatkan bahwa model reasoning yang membuang thinking trace di antara giliran bisa menghasilkan hasil yang salah, dan menyebut router harus mendeteksi ketidakcocokan itu.
  • Kepercayaan. Di thread RFC, seorang maintainer menandai bahwa meminta client mengembalikan kv_transfer_params pada giliran berikutnya berisiko karena client berniat jahat bisa memanfaatkannya, dan menyarankan pelacakan sesi di router atau load balancer.
  • Dependensi yang masih direview. Reproduksi di tulisan itu menerapkan pull request 40186 ke kedua node. Saat saya membaca halamannya pada 17 Oktober 2026, PR itu tampil open, dengan permintaan approval ulang setelah rebase pada 1 Oktober.

Cache yang membuat Anda lebih lambat hanya mengganggu. Cache yang membuat output salah adalah insiden. Jika Anda melayani model yang membuang reasoning di antara giliran, uji apakah output identik dengan fitur hidup dan mati sebelum melihat grafik latensi apa pun.

Soal kematangan: pull request yang di-merge masuk pada 30 April 2026, RFC ditutup sebagai selesai pada 15 Juni 2026, dokumentasi kini menjelaskan fiturnya, dan tulisan itu menyebut fitur ini awalnya dibangun dan divalidasi di AWS Trainium sebelum dikontribusikan ke vLLM. Itu jejak yang nyata, tetapi benchmark yang jadi dasarnya hanya mencakup satu workload per model dan satu transport. Saya menyebutnya masih awal.

Yang dikerjakan hari Senin

Jangan mulai dengan mengaktifkan flag. Mulailah dengan mencari tahu apakah traffic Anda memang punya masalah ini.

  1. Catat conversation_id, timestamp, dan jumlah prompt token untuk setiap request, lalu jalankan script di bawah untuk melihat berapa bagian tiap prompt yang sudah ada di giliran sebelumnya dan berapa giliran yang datang setelah TTL.
  2. Jika bagian yang berulang kecil, atau sebagian besar jeda melebihi 480 detik, berhenti. Prefix caching pada node yang menyatu adalah jawaban yang lebih sederhana, dan itu penilaian saya, bukan klaim vLLM.
  3. Jika Anda memang melakukan disaggregation, jalankan A/B dengan prefix caching aktif di prefill, karena itu kondisi produksi Anda, dan simpan run dengan caching mati sebagai skenario terbaik.
  4. Verifikasi transport sebelum membaca TTFT apa pun: fi_info -p efa harus menampilkan provider EFA di kedua node.
  5. Atur TTL router di bawah decoder_kv_blocks_ttl, dan beri alert jika tingkat cache MISS bertahan di 100 persen, yang oleh tulisan itu disebut sebagai gejala run yang salah konfigurasi.
#!/usr/bin/env python3
# usage: python3 reprefill.py < requests.jsonl
# one JSON object per line: {"conversation_id": "c1", "ts": 1760000000.0, "prompt_tokens": 18234}
import collections
import json
import sys

TTL_S = 480  # match decoder_kv_blocks_ttl

convs = collections.defaultdict(list)
for line in sys.stdin:
    r = json.loads(line)
    convs[r["conversation_id"]].append((r["ts"], r["prompt_tokens"]))

prompt_total = repeated = turns = late = 0
for rows in convs.values():
    rows.sort()
    for (prev_ts, prev_tok), (ts, tok) in zip(rows, rows[1:]):
        turns += 1
        prompt_total += tok
        # Lower bound: the previous PROMPT is certainly part of this prompt.
        # The previous response is too, but we do not log it, so we ignore it.
        repeated += min(prev_tok, tok)
        if ts - prev_ts > TTL_S:
            late += 1

print(f"follow-up turns:            {turns}")
print(f"repeated prompt share (>=): {repeated / prompt_total:.1%}")
print(f"turns after the TTL:        {late / turns:.1%}")

Script itu melaporkan batas bawah, karena hanya menghitung prompt token giliran sebelumnya sebagai berulang dan mengabaikan token respons yang juga dipegang decode. Saya lebih suka meremehkan peluangnya daripada menentukan perubahan cluster berdasarkan estimasi yang optimistis.

Aturan yang saya ambil: pada serving yang di-disaggregate, cache yang Anda butuhkan mungkin ada di node lain, dan pertanyaannya adalah apakah menariknya kembali lebih baik daripada menghitung ulang. Menarik menang ketika prompt panjang, giliran datang berdekatan, dan transport-nya kelas RDMA. Angka 3,3x dari tim vLLM nyata untuk kasus yang diukurnya, sekitar 29 persen adalah angka yang diharapkan saat cache prefill sendiri sehat, dan fitur ini cukup muda sehingga Anda sebaiknya membaca pull request yang masih terbuka sebelum membangun di atasnya.

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Apa itu bi-directional KV transfer di vLLM?

Itu adalah mode NixlConnector di vLLM di mana prefill node bisa menarik KV cache block kembali dari decode node, bukan KV hanya bergerak dari prefill ke decode. Pada giliran berikutnya dalam percakapan, prefill node memuat block yang disimpan decode node dan hanya menghitung token baru. Mode ini diaktifkan dengan bidirectional_kv_xfer bernilai true di kedua instance dan butuh router stateful yang melacak conversation_id.

Mengapa agen multi-turn melakukan prefill ulang pada riwayatnya?

Client mengirim ulang seluruh percakapan di setiap giliran, dan pada disaggregation prefill-decode standar KV untuk token hasil generate hanya ada di decode node. Prefill node tidak bisa mencocokkan apa yang tidak pernah ia hitung, dan ia juga menghitung ulang apa pun yang sudah tergusur dari cache-nya sendiri. Seiring riwayat tumbuh, recompute itu menaikkan time to first token di setiap giliran.

Bagaimana cara mengaktifkan bidirectional KV transfer di vLLM?

Pakai NixlConnector dengan kv_producer di prefill dan kv_consumer di decode, set bidirectional_kv_xfer ke true di kv_connector_extra_config pada keduanya, dan jalankan router seperti contoh disagg_proxy_multiturn.py yang menyimpan kv_transfer_params berdasarkan conversation_id. Reproduksi di tulisan vLLM juga menerapkan pull request 40186, yang menambahkan kv_transfer_params ke streaming response dan masih open saat saya membacanya, jadi cek statusnya untuk versi Anda.

Apa fungsi decoder_kv_blocks_ttl dan kv_recompute_threshold?

decoder_kv_blocks_ttl adalah berapa lama decode node menyimpan block untuk dipakai ulang, 480 detik secara default, dan tidak diperpanjang, sehingga giliran yang datang terlambat kembali ke prefill normal. kv_recompute_threshold, default 64 token, adalah jumlah minimum token remote yang bisa dipakai ulang sebelum prefill menarik, bukan menghitung ulang, karena prefix pendek bisa lebih mahal ditransfer daripada dihitung ulang.

Apakah bi-directional KV transfer membutuhkan AWS EFA?

Tim vLLM mengukurnya lewat EFA dengan backend LIBFABRIC, dan memperingatkan bahwa tanpa EFA, NIXL gagal atau jatuh ke TCP socket sehingga angka transfernya tidak valid. Dokumentasi vLLM menyebut backend NIXL default adalah UCX dan mode bi-directional saat ini hanya untuk CUDA dengan KV cache di device buffer. Anggap peningkatan yang dipublikasikan spesifik untuk transport kelas RDMA.