perf(maru_vllm): eliminate direct connector bottlenecks#66
Open
youngrok-XCENA wants to merge 7 commits into
Open
perf(maru_vllm): eliminate direct connector bottlenecks#66youngrok-XCENA wants to merge 7 commits into
youngrok-XCENA wants to merge 7 commits into
Conversation
youngrok-XCENA
marked this pull request as ready for review
July 21, 2026 08:35
jooho-XCENA
reviewed
Jul 21, 2026
Deferred (parked) loads previously executed synchronously inside start_load_kv on the packed path: the Maru retrieve RPC blocked the model-runner thread and _load_packed synchronized the stream, so a parked request's load still stalled every co-scheduled request's decode. Submit the whole load (batch_retrieve + H2D on a dedicated high-priority stream) to a single background loader thread and report completion through get_finished_loading via a CUDA event — the in-process analog of the MP server's separate-process retrieve, without the IPC hop. Failures report the request's blocks so vLLM recomputes. All _deferred_* state is now lock-guarded (loader thread and engine thread both touch it).
The deferred job ran multi_layer_kv_transfer directly on the host slab (UVA reads from CXL), occupying SMs for the whole transfer and stalling concurrent decode exactly like the inline path it replaced — measured TPOT stayed at the inline level while the MP server's media-invariant TPOT (CXL == host DRAM) shows its bulk bytes ride the copy engine. Stage each chunk's slab with an async H2D DMA (the CXL mapping is cudaHostRegister'ed) and scatter the device-resident slab with one brief kernel instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤔 Background & Motivation (Why)
MaruKVConnector의 control/data path에는 long-context에서 증폭되는 구조적 병목이 있었습니다.(layer × chunk)단위로 단건 RPC와 작은 GPU 전송을 반복했습니다. 64k prompt에서는 요청당 key가 약 8,000개까지 늘어났습니다.이 PR은 해당 병목과 정합성 문제를 제거하고, single-instance 및 P2P direct connector 검증 예제를 함께 제공합니다.
위 재설계로 캐시 히트 지표는 LMCache 경유(non-MP)와 동등해졌지만, 로드·저장이 여전히 엔진 안의 동기 호출이라 한 요청의 KV 전송이 같은 배치의 다른 요청 decode를 세우는 병목이 남아 있었습니다. 같은 조건에서 로드·저장을 별도 프로세스로 빼는 LMCache MP 모드는 동시 8요청 캐시 히트 TTFT가 29% 낮고 처리량이 19% 높았습니다. 후속 커밋 4개는 이 갭을 in-process에서 해소합니다 — 벌크 전송을 GPU copy engine으로 빼고, 전송 시점을 첫 토큰의 임계 경로 밖으로 옮깁니다.
🏗️ Design Changes
flowchart LR subgraph before["Before"] S1[Scheduler] -->|key별 exists RPC| M1[MaruServer] W1[Worker] -->|layer × chunk별 retrieve/store| M1 W1 -->|첫 요청에서 CXL mapping| C1[CXL] end subgraph after["After"] S2[Scheduler] -->|batch exists and linear key hashing| M2[MaruServer] W2[Worker] -->|chunk-packed batch retrieve/store| M2 W2 -->|multi-layer coalesced transfer| C2[CXL] I2[Engine startup] -->|eager worker connect| W2 end before ~~~ afterregister_kv_caches()에서 수행해 요청 critical path에서 제거합니다.후속 커밋(비동기화)의 구조 변화:
flowchart LR subgraph sync_path["Before — 엔진 안 동기 로드/저장"] direction TB A1["cache-hit/populate 전송이<br/>엔진 스레드에서 동기 실행 (SM 점유)"] --> A2["같은 배치의 다른 요청<br/>decode 정지"] end subgraph async_path["After — 비동기화 + 요청 내 겹침 (opt-in)"] direction TB B1["로드: 요청 파킹 후 로더 스레드가<br/>copy engine DMA로 수행"] --> B2["저장: prompt 완료 뒤<br/>write-behind로 발행"] --> B3["단독 hit 요청:<br/>layer k 연산 ∥ layer k+1 로드"] end sync_path ~~~ async_path성능 개선 결과 (Llama-3.1-8B, lveval 16k, 문서 20개, CXL-DRAM)
📝 Implementation Details
batch_retrieve/batch_store와 payload-bounded retrieve batchingexamples/vllm/single/자동 cold→warm 검증과examples/vllm/p2p_sharing/예제 정리lmcache.c_ops가 설치된 경우 multi-layer CUDA kernel을 선택적으로 재사용하지만 LMCache connector/service를 실행하지는 않습니다. 해당 extension이 없으면 호환 가능한 per-layer fallback을 사용합니다.후속 커밋(비동기화):
maru_enable_deferred_loading) — scheduler가 hit 요청을WAITING_FOR_REMOTE_KVS로 파킹, 단일 로더 스레드가batch_retrieve후 registered CXL mmap → GPU stagingcudaMemcpyAsync(copy engine DMA) +multi_layer_kv_transfer산포, 전용 stream의 CUDA event를get_finished()가 폴링. 로드 실패 블록은 재계산으로 보고maru_enable_write_behind) — save hook은 마지막 layer에서 metadata만 기록하고 prompt-완료 step의get_finished()에서 발행. pending key와 shared-prefix waiter를 lock 아래 추적해 중복 저장 방지, 완료 전 끝난 요청은 connector가 GPU block ownership을 보류 후finished_sending으로 해제, preemption은 store stream drain 후 진행maru_enable_layerwise_overlap, deferred 전제) — live deferred-hit 요청이 정확히 1건일 때만 packed layout을 유지한 pitchedcudaMemcpy2DAsync+ layer별 CUDA event를 발행하고 attention은 자기 layer event만 대기. 2건 이상이면 whole-request DMA 경로 유지. step-local 판정은 full grid에서 고동시성 TPOT 회귀(+16~18%)를 일으켜 live-request 추적으로 교체✅ Tests
801 passed, 1 skipped(후속 커밋 반영; connector 단독99 passed. suite 순서에서만 나타나는 기존 CUDA host-memory 재등록 이슈 1건은 단독 실행 시 pass)180/180성공, external hit66%(만점), 신규 store/load/CUDA 실패 020/20byte-for-byte (동기 경로 기준; 후속 기능은 기본 off)bash -n장비 검증 결과 warm cache-hit TTFT/TPOT/TPS의 기존 병목이 제거됐고, populate TTFT도 if1
916 ms, if83,035 ms로 안정화됐습니다.후속 커밋(모두 opt-in) 활성 시, 같은 grid에서 warm cache-hit TTFT는 동시 8에서
580→462 ms(−20%), 처리량192→229 tok/s(+19%), populate TTFT는 동시 8에서3,049→2,549 ms(−16.4%)입니다. 같은 조건의 LMCache MP 모드와 처리량/TPOT가 동등하고 동시 1/4 TTFT는 앞섭니다.🔗 Related Issues (optional)
🌿 Related PRs (optional)
🌿 Related Branches (optional)
📦 Release Note (for auto-generation / write in English)
NEW
CHANGED
FIXED
IMPORTANT NOTES