已合并
Add test for _EmptyStateDictLoadPlanner on NPU #42765
Add test for _EmptyStateDictLoadPlanner on NPU #42765
已合并
文诺tan创建于 26 天前
文诺tan
文诺tan
26 天前

【合入来源】

关联任务issue: https://gitcode.com/Ascend/pytorch/issues/3146

【修改方案】

torch.distributed.checkpoint.default_planner._EmptyStateDictLoadPlanner
PyTorch 官方社区在 test/distributed/composable/test_composability/test_pp_composability.py 中有间接测试,但未针对该 API 编写直接独立测试,因此自行编写用例并提交到 test 目录。
该 API 为纯 Python 元数据操作,不涉及 NPU 适配,不需要代码修改。
新增 test/distributed/checkpoint/test_empty_state_dict_load_planner.py,验证 EmptyStateDictLoadPlanner 的加载功能及异常处理

【资料变更】

涉及。上游 PyTorch 在 test/distributed/composable/test_composability/test_pp_composability.py 中有相关测试,但仅作为 PP+DCP 集成测试的工具使用,未针对 EmptyStateDictLoadPlanner 公开 API 编写独立测试。本次提交补充了 15个测试方法,覆盖 keys 参数传参与不传参、异常场景的核心行为,测试文件位于 test/distributed/checkpoint/test_empty_state_dict_load_planner.py。

【接口变更】

不涉及

【功能介绍】

torch.distributed.checkpoint.default_planner._EmptyStateDictLoadPlanner 是 PyTorch 分布式检查点系统的内部工具类,继承自 DefaultLoadPlanner。用于从空 state_dict 加载 DCP 检查点,通过读取元数据重建 state_dict 结构,适用于未初始化模型时加载检查点的场景(如 DCP checkpoint 转 Torch save 文件)。

【功能验证】

test_empty_state_dict_load_planner.py (_EmptyStateDictLoadPlanner)

  • test_init_without_keys — 不传 keys 构造 planner, keys 为 None
  • test_init_with_keys — 传入 keys=["model"] ,确认被保存
  • test_set_up_planner_with_non_empty_state_dict — state_dict 非空时 set_up_planner 抛 AssertionError
  • test_set_up_planner_without_metadata — metadata=None 时抛 AssertionError
  • test_set_up_planner_success — 空 state_dict + 合法 metadata,重建出正确 shape/dtype 的张量并保存 metadata
  • test_set_up_planner_with_is_coordinator — 接受并保存 is_coordinator 标志
  • test_keys_none_loads_all — keys=None 时加载 metadata 中全部 key
  • test_keys_filter_loads_subset — keys={"x","z"} 只加载指定子集
  • test_keys_filter_loads_nothing_when_no_match — keys 无匹配时 state_dict 保持为空
  • test_keys_filter_with_planner_data — 通过 planner_data 嵌套路径( model.layer.weight )匹配并构建嵌套 dict
  • test_create_local_plan_after_setup — setup 后 create_local_plan 返回含 TENSOR ReadItem 的 LoadPlan
  • test_create_local_plan_empty_when_keys_filter_all — key 全被过滤时 local plan 为空
  • test_create_global_plan — 单个 rank 时返回 1 个 LoadPlan
  • test_create_global_plan_multiple_ranks — 多 rank 返回对应数量 plan
  • test_finish_plan_passthrough — finish_plan 恒等返回原 plan

运行命令:
python -m pytest /workspace/user_data/pytorch-v2.12.0/test/distributed/checkpoint/test_empty_state_dict_load_planner.py -x
运行结果:

=============================================== test session starts ================================================
platform linux -- Python 3.12.13, pytest-9.1.1, pluggy-1.6.0
rootdir: /workspace/user_data/pytorch-v2.12.0
configfile: pyproject.toml
plugins: hypothesis-6.156.6
collected 15 items                                                                                                 

user_data/pytorch-v2.12.0/test/distributed/checkpoint/test_empty_state_dict_load_planner.py ...............  [100%]

================================================ 15 passed in 4.13s ================================================

【CheckList】

PR提交人对以下CheckList自检项进行全量自检,自检通过或不涉及,均修改 [ ] 为 [x]

likedislike
Pull Request已成功合入, 合并人@ascend-robot
(感谢 文诺tan 的贡献)
文诺tan文诺tan
26 天前 创建了 pull request,commit 3b98fbbc
文诺tan文诺tan
26 天前 关联了issue:【社区任务】7月社区任务第三期-Ascend for PyTorch API 一致性开发(38)
atomgit-bot
atomgit-bot
26 天前 评论:

变更摘要

此 PR 为 torch.distributed.checkpoint.default_planner._EmptyStateDictLoadPlanner 新增了独立的 NPU 适配测试文件 test/distributed/checkpoint/test_empty_state_dict_load_planner.py。PyTorch 社区此前仅在 PP+DCP 集成测试中间接使用该类,缺乏对其公开 API 的直接验证。本次提交补充了 4 个测试方法,覆盖 keys 参数传参与不传参的加载行为以及 set_up_planner 的异常处理场景。

主要改动

  • 新增测试文件 test_empty_state_dict_load_planner.py:创建独立的测试类 TestEmptyStateDictLoadPlanner,继承自 TestCase,专门验证 _EmptyStateDictLoadPlanner 的行为。
  • 新增 test_load_keys_none 测试:在不传入 keys 参数的情况下调用 _load_state_dict,保存并加载 Linear 模型的 state_dict,验证加载后的字典包含预期的 "model" 键。
  • 新增 test_load_keys_specified 测试:传入 keys=["model"] 参数,保存包含模型和优化器状态的 state_dict,验证 _load_state_dict 仅加载指定键的数据。
  • 新增异常场景测试 test_set_up_planner_error_non_emptytest_set_up_planner_error_metadata_none:分别验证当传入非空 state_dict 或 metadata=None 时,set_up_planner 方法正确抛出 AssertionError
  • 适配 NPU 设备检测:通过 torch.accelerator.current_accelerator() 动态获取当前加速器类型,使测试可自动适配 NPU 或回退到 CPU 执行。
likedislike
atomgit-bot
atomgit-bot
26 天前 评论:

代码审查

审查总结

我对 test/distributed/checkpoint/test_empty_state_dict_load_planner.py(新增文件,+85 行)进行了逐行审查。

各优先级发现数量

  • P0: 0
  • P1: 0(原 P1 发现 #4 已撤回,见下方说明)
  • P2: 1
  • P3: 2

撤回说明

发现 #4(line 33, P1)已撤回。经重新分析,行 33 的代码:

device_type = acc.type if (acc := torch.accelerator.current_accelerator(check_available=True)) else "cpu"

在无可用加速器时,current_accelerator(check_available=True) 返回 None(falsy),三元表达式走 else "cpu" 分支,acc.type 不会被求值,因此不会发生 AttributeError。该行代码逻辑正确。

有效发现摘要

# 优先级 位置 问题
1 P2 line 71 test_load_keys_specified 缺少 assertNotIn("opt", sd),无法验证 keys=["model"] 过滤是否真正生效
2 P3 line 76 test_set_up_planner_error_non_empty 同时传入非空 state_dict 和 metadata=None,若实现先检查 metadata 则会产生假阳性
3 P3 line 46 test_load_keys_none 命名可读性(可选改进,低置信度)

总体风险评估

低风险。新增文件为纯测试代码,不涉及运行时逻辑变更。唯一的 P2 问题是测试断言不完整(缺少反向断言),可能导致 keys 过滤回归未被捕获,但不会引入生产问题。P3 项为测试设计健壮性改进,均非阻塞性问题。

已审查文件清单

  • test/distributed/checkpoint/test_empty_state_dict_load_planner.py — 已审查(发现 3 个有效问题,1 个撤回)
类型 数量
🔴 阻塞 1
🟡 建议 1

⛔ 需要修改

likedislike
此处折叠了238条消息 查看更多
ascend-robot
ascend-robot成员
7 天前 评论:

The MR can not be merged, because of CodeReview discussion not resolved

If you want to solve this problem, you can click here to do it in the FAQs.

likedislike
群青世界成员
6 天前 解决了最后一个问题
ascend-robotascend-robot成员
6 天前 合入了pull request
ascend-robot
ascend-robot成员
6 天前 评论:

Pull Request 已合并或已关闭。

If you want to solve this problem, you can click here to do it in the FAQs.

likedislike
ascend-robot
ascend-robot成员
6 天前 评论:
流水线 pytorch_gitcode_PR_multiVersion#14003 [ commitID:9cb7ac43 ] 已完成
likedislike