完整调用链(一次 P→D 传输)
第一阶段:Proxy 路由 — 注入参数
| 文件 | 作用 |
|---|
| router.py | Proxy 拆分请求:给 P 注入 do_remote_decode=True,给 D 注入 do_remote_prefill=True + remote_host/port |
第二阶段:Scheduler 侧 — 3 个文件协作
| 文件 | 关键调用 |
|---|
| scheduler.py | schedule() 内依次调用 connector 的 ①get_num_new_matched_tokens ②update_state_after_alloc ③build_connector_meta ④request_finished |
mooncake_connector.py(MooncakeConnectorScheduler) | update_state_after_alloc 根据角色把请求放入 _reqs_need_recv 或 _reqs_need_send;build_connector_meta 打包成 MooncakeConnectorMetadata |
| output.py | SchedulerOutput.kv_connector_metadata 把元数据从 Scheduler 进程传到 Worker 进程 |
第三阶段:Worker 侧 — 启动传输
| 文件 | 关键调用 |
|---|
| gpu_model_runner.py | execute_model() 中进入 _get_kv_connector_output() 上下文 |
| kv_connector_model_runner_mixin.py | 编排核心: bind_connector_metadata() → start_load_kv() → yield(model forward) → get_finished() |
mooncake_connector.py(MooncakeConnectorWorker) | 实际传输逻辑 |
第四阶段:实际 RDMA 传输(核心路径)
D 端(接收方):
start_load_kv() → group_kv_pull() → asyncio submit receive_kv()
└─ receive_kv():
├─ 构建 MooncakeAgentMetadata (含本端 GPU kv_cache 基地址 + block_ids)
├─ ZMQ REQ 发给 P 端 ← "告诉 P 往哪写"
└─ await sock.recv() ← 等 P 完成 RDMA WRITE
P 端(发送方):
_mooncake_sender 线程 (ZMQ ROUTER 监听)
└─ 收到 D 的请求 → ThreadPool submit _sender_worker()
└─ send_kv_to_decode()
├─ collect SendBlockMeta, wait ready.wait() ← 等 prefill 算完
└─ _send_blocks()
├─ 计算 src/dst 指针 (base_addr + block_id × block_len)
└─ engine.batch_transfer_sync_write() ← 单边 RDMA PUT
第五阶段:完成信号回传
| 文件 | 作用 |
|---|
| outputs.py | KVConnectorOutput.finished_recving/finished_sending |
| vllm/v1/engine/__init__.py | EngineCoreOutput.kv_transfer_params — P 端回传 host/port 给 Proxy |
| output_processor.py | 透传到 CompletionOutput.kv_transfer_params → Proxy 取出后附到 D 请求上 |
