Prhub

#43871 [CI] Nixl+SimpleCPUOffloadingConnector unit tests

原始 PR 作者 NickLucche 合并时间 2026-05-29 17:40 文件变更 1 提交数 2 评论 0 代码增减 +325 / -0

执行摘要

为 Nixl+SimpleCPUOffload 多连接器添加单元测试

初始的测试套件未覆盖 NixlConnector 与 SimpleCPUOffloadConnector 组合使用这一重要场景。本 PR 补充基础单元测试,确保基本功能可被跟踪,降低回归风险。

建议开发者查阅本测试了解 MultiConnector 的模拟验证方式,对涉及 Nixl 与 CPU Offload 的贡献者尤其有参考价值。

讨论亮点

无 review 讨论。

实现拆解

  1. 创建 FakeNixlWrapper mock 类(位于测试文件顶部),提供 get_reg_descsregister_memoryprep_xfer_dlist 等核心接口的简化实现,避免对真实 NIXL 硬件和 Ray 的依赖。
  2. 编写辅助函数 _make_kv_cache_config,构造包含非空 kv_cache_tensorsKVCacheConfig,以触发 SimpleCPUOffloadConnector._derive_cpu_config 的执行。
  3. 使用 @patch 装饰器将 NixlWrapper 替换为 FakeNixlWrapper,实例化 MultiConnector 并注入两个子连接器( NixlConnector 和 SimpleCPUOffloadConnector )。
  4. 实施 4 个核心测试用例:
    • HMA 支持检测:验证 supports_hma 在任一子连接器返回 True 时整体为 True 。
    • Load 委托( first-wins ):检查 load 操作仅传递给第一个子连接器,避免重复写入。
    • Store-to-all:确认 store 操作广播至所有子连接器。
    • 元数据聚合:测试 get_metadata 合并两个子连接器的 metadata 字典。
  5. 测试配置文件不涉及改动,所有新增代码集中在单个测试文件中。
文件 模块 状态 重要度
tests/v1/kv_connector/unit/test_nixl_simple_cpu_offload.py KV 卸载测试 added 7.48

关键符号

FakeNixlWrapper.__init__ FakeNixlWrapper.get_reg_descs FakeNixlWrapper.register_memory FakeNixlWrapper.deregister_memory FakeNixlWrapper.get_xfer_descs FakeNixlWrapper.prep_xfer_dlist FakeNixlWrapper.get_agent_metadata FakeNixlWrapper.check_xfer_state _make_kv_cache_config

关键源码片段

tests/v1/kv_connector/unit/test_nixl_simple_cpu_offload.py test-coverage

唯一变更文件,完整覆盖了 MultiConnector 的 Nixl+CPU Offload 组合场景的单元测试,包含 FakeNixlWrapper mock 类和多个核心测试用例。

# SPDX-License-Identifier: Apache-2.0class FakeNixlWrapper:
    """Minimal mock of NixlWrapper for testing without NIXL hardware.    Duplicated from test_nixl_connector.py to avoid importing that module
    (which has heavy dependencies like ray).
    """
​
    AGENT_METADATA = b"fake_agent_metadata"
    REMOTE_AGENT_NAME = "remote_agent"
​
    def __init__(self, agent_name: str, *args, **kwargs):
        # `_cycles_before_xfer_done` 控制传输何时完成,便于测试异步状态
        self._cycles_before_xfer_done = 0
        self._check_xfer_state_cycles: defaultdict[int, int] = defaultdict(lambda: 0)
​
    def get_reg_descs(self, caches_data, memory_type: str) -> list:
        # 为每个缓存块生成唯一描述符,模拟 NIXL 注册
        return [str(uuid.uuid4()) for _ in caches_data]
​
    def register_memory(self, descs, backends) -> None:
        pass # 实际注册由真实驱动完成,mock 中免去
​
    def deregister_memory(self, descs) -> None:
        pass
​
    def get_xfer_descs(self, blocks_data, memory_type: str) -> list:
        return [str(uuid.uuid4()) for _ in blocks_data]
​
    def prep_xfer_dlist(self, agent_name: str, descs: list) -> int:
        return uuid.uuid4().int
​
    def get_agent_metadata(self) -> bytes:
        return self.AGENT_METADATA
​
    def add_remote_agent(self, agent_metadata: bytes) -> str:
        return self.REMOTE_AGENT_NAME
​
    def get_new_notifs(self) -> dict[str, list[bytes]]:
        return {}
​
    def check_xfer_state(self, handle: int) -> str:
        # 模拟传输状态:经过指定 cycles 后返回 "DONE"
        if self._check_xfer_state_cycles[handle] >= self._cycles_before_xfer_done:
            return "DONE"
        self._check_xfer_state_cycles[handle] += 1
        return "PROC"
​
    def release_xfer_handle(self, handle: int) -> None:
        pass
​
    def release_dlist_handle(self, handle: int) -> None:
        pass
​
    def remove_remote_agent(self, agent: str) -> None:
        pass
​
    def send_notif(self, agent_name: str, notif_msg: bytes) -> None:
        pass
​
    def make_prepped_xfer(self, *args, **kwargs) -> int:
        return uuid.uuid4().int
​
    def transfer(self, handle: int) -> str:
        return "PROC"
​
    def get_xfer_telemetry(self, handle: int) -> dict:
        return {}
​
    def set_cycles_before_xfer_done(self, cycles: int):
        pass

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

测试全部基于 mock ( FakeNixlWrapper ),无法验证真实 NIXL 硬件路径的交互行为;同时未集成 e2e 测试,可能遗漏调度层与底层传输之间的集成问题。

直接提升 v1 KV connector 组合场景的测试覆盖度,有助于捕获后续重构或功能添加时的回归。改动仅涉及测试模块,不影响生成或推理路径。

测试依赖 mock 缺少 e2e 测试

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论