所有调用点都在这一个文件里(ascend/conn.py 是另一个后端,逻辑相同)。梳理如下:
_transfer_data 调用全景
_transfer_data 是底层 RDMA 传输的统一入口,上层按传输的数据种类分成 4 类调用:
1. KV Cache 正常传输(_send_kvcache_generic,行 669 / 676)
触发路径: send_kvcache → _send_kvcache_generic(标准 MHA/MLA)
send_kvcache_hisparse → _send_kvcache_generic(HiSparse token 粒度)
maybe_send_extra 里 SWA/NSA state → _send_kvcache_generic
两条代码路径:
| 路径 | 行号 | 条件 | 行为 |
|---|---|---|---|
process_layer | 669 | enable_custom_mem_pool=True | 每层独立提交线程池,并发调 _transfer_data |
process_layers | 676 | 默认路径 | 把所有层的 transfer_blocks 合并成一个大 batch,单次调 _transfer_data |
传的内容: prefill KV pool → decode KV pool,以 page 为粒度做地址映射(prefill_kv_indices → dst_kv_indices)。
2. Staging Bulk 传输(send_kvcache_staged,行 557)
触发路径: _do_staging_transfer → staging_strategy.transfer → send_kvcache_staged
条件: prefill/decode TP size 不同 + staging buffer 启用时。
传的内容: prefill 先把多层 KV gather 到本地 CPU staging buffer,再用单次 bulk RDMA 把整个 staging buffer 打过去(staging_buffer.get_ptr() → dst_staging_ptr + rank_offset,大小 per_rank_bytes)。是所有调用里 block 数最少(只有 1 个)但单块最大的。
3. Auxiliary Data 传输(send_aux,行 907)
触发路径: transfer_worker 在 is_last_chunk=True 时 → send_aux(RDMA 路径,NVLINK 时走 TCP fallback)
传的内容: prefill aux pool(如 attention metadata、decode 需要的 attention output)→ decode aux pool,每个 buffer 各传一条 transfer_block。每次请求只在最后一个 chunk 触发一次。
4. Mamba State 传输(_send_mamba_state 行 1064 / _send_mamba_state_slice 行 1150)
触发路径: maybe_send_extra(state_type == “mamba”)→ 两者之一
| 方法 | 行号 | 条件 | 行为 |
|---|---|---|---|
_send_mamba_state | 1064 | prefill/decode TP size 相同 | 整段 state 直传,每个 tensor 一个 block |
_send_mamba_state_slice | 1150 | prefill/decode TP size 不同 | 按第 3 维(conv_dim/tp 或 num_heads/tp)切片,只传本 rank 负责的部分 |
传的内容: Mamba 的 conv_state 和 temporal_state,只有单个 state index(assert 了 len==1)。
总结
_transfer_data
├── KV Cache 主体 send_kvcache / send_kvcache_hisparse / SWA·NSA state
│ ├── per-layer 并发(custom_mem_pool) process_layer ×N 层
│ └── all-layer 合批(默认) process_layers ×1
├── Staging Bulk send_kvcache_staged ×1 超大块(gather 后整段打)
├── Aux Data send_aux(RDMA 路径) ×每个 aux buffer 一块
└── Mamba State _send_mamba_state ×每个 state tensor 一块
_send_mamba_state_slice ×每个 tensor 的 TP 切片
send_kvcache_slice 是个例外——它绕开了 _transfer_data,直接调 engine.batch_transfer_sync,因为它要做 per-token、per-head 的细粒度切片,不走统一封装。