Prhub

#19541 [NPU] fix some npu error with OffloaderV2

原始 PR 作者 Hide-on-bushsh 合并时间 2026-04-30 20:05 文件变更 4 提交数 3 评论 15 代码增减 +116 / -2

执行摘要

修复 NPU OffloaderV2 的 meta 和 sharded_gpu 模式兼容问题

在NPU上使用OffloaderV2的meta或sharded_gpu offload模式时,服务器无法正常工作。PR body指出'when set --offload-mode=meta or sharded_gpu in feature offloaderV2, it doesn't work with npu',因此需要修复兼容性问题。

该PR虽是bugfix但涉及offloader核心路径和NPU后端的关键操作,值得相关维护者精读。'_move_param_to_meta' 中的weight_loader补全和NPU格式转换的meta跳过是两个值得注意的设计决策,体现了对框架参数迁移和异构设备支持的深入理解。

讨论亮点

该PR的review过程较为简单,提交后由 ping1jing2 批准。主要讨论集中在CI重跑(多次 /rerun-failed-ci 命令)以通过测试,未出现设计或实现层面的技术争议。

实现拆解

  1. python/sglang/srt/utils/offloader.py_move_param_to_meta 函数中,当参数类型为 torch.nn.Parameter 时,补全 weight_loader 属性:若原参数有 weight_loader 则赋值给新参数,否则设为一个空操作函数。

  2. python/sglang/srt/hardware_backend/npu/utils.pynpu_format_cast 函数开头,增加 if tensor.device.type == 'meta': return tensor 的提前返回,避免对 meta 张量执行 NPU 格式转换导致错误。

  3. python/sglang/srt/layers/quantization/unquant.pyprocess_weights_after_loading 中,重构 NPU 分支:先对转置后的权重调用 contiguous() 创建连续副本,再通过 untyped_storage().resize_(0) 释放原张量存储,最后用 npu_format_cast 对新副本进行格式转换,解决 OffloaderV1 下 MoE 模型的精度错误。

  4. 新增测试文件 test_npu_offload_modes.py,通过启动真实服务器并验证输出包含 'Paris' 来测试 cpu 和 sharded_gpu 两种 offload 模式,确保基本功能正常。

文件 模块 状态 重要度
test/registered/ascend/basic_function/offloading/test_npu_offload_modes.py NPU 测试 added 7.18
python/sglang/srt/utils/offloader.py Offloader modified 5.63
python/sglang/srt/layers/quantization/unquant.py 量化层 modified 5.19
python/sglang/srt/hardware_backend/npu/utils.py NPU 后端 modified 5.07

关键符号

_move_param_to_meta process_weights_after_loading npu_format_cast run_a_test test_offload_mode_cpu test_offload_mode_sharded_gpu

关键源码片段

python/sglang/srt/utils/offloader.py core-logic

修复 _move_param_to_meta 中为 nn.Parameter 补全 weight_loader 属性,避免后续权重加载失败。

def _move_param_to_meta(module, param_name):
    old_param = getattr(module, param_name)
    old_param_type = type(old_param)
    new_data = old_param.data.to('meta')
​
    if old_param_type == ModelWeightParameter:
        new_param = ModelWeightParameter(
            data=new_data,
            **{k: getattr(old_param, k) for k in ['input_dim', 'output_dim', 'weight_loader']},
        )
    elif old_param_type == torch.nn.Parameter:
        new_param = torch.nn.Parameter(data=new_data, requires_grad=False)
        # 补全 weight_loader 属性,避免后续加载失败
        if hasattr(old_param, 'weight_loader'):
            new_param.weight_loader = old_param.weight_loader
        else:
            new_param.weight_loader = lambda *args, **kwargs: None
    else:
        raise ValueError(f'Unknown {old_param_type=} {old_param=}')
​
    setattr(module, param_name, new_param)
python/sglang/srt/layers/quantization/unquant.py core-logic

重构 NPU 权重后处理:转置后先 contiguous() 再格式转换,并释放原存储,解决 OffloaderV1 下 MoE 精度错误。

if _is_npu:
    for weight_name in ['w13_weight', 'w2_weight']:
        weight = getattr(layer, weight_name)
        origin_weight = weight.data.transpose(1, 2)
        new_weight = origin_weight.contiguous() # 创建连续副本
        origin_weight.untyped_storage().resize_(0) # 释放原存储
        weight.data = npu_format_cast(new_weight) # 格式转换
python/sglang/srt/hardware_backend/npu/utils.py core-logic

在 npu_format_cast 中提前返回 meta 张量,避免对 meta 设备张量执行 NPU 格式转换。

def npu_format_cast(tensor, acl_format=NPUACLFormat.ACL_FORMAT_ND):
    # ... 已有检查 ...
    if tensor.device.type == 'meta':
        # 跳过 meta 张量的格式转换,offloader 中需要
        return tensor
    return torch.ops.npu.npu_format_cast(tensor, acl_format.value)

评论区精华

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

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

风险与影响

主要风险在于:1)_move_param_to_meta 的修改影响所有offload模式的参数转移到meta的过程,若weight_loader属性赋值不当可能导致加载异常;2)跳过meta张量的格式转换可能使某些场景下无法捕获到非meta但需要格式转换的张量,但逻辑上安全;3)unquant.py 中的改动改变了NPU上权重的连续性与格式转换顺序,可能影响量化或格式对齐;4)测试仅覆盖了基础功能(输出包含'Paris'),未验证精度、性能退化或边界条件。由于更改集中在offloader和NPU后端,影响范围相对隔离。

对用户:NPU用户现在可以使用 --offload-mode=meta 和 sharded_gpu,扩展了部署灵活性;同时修复了MoE模型在OffloaderV1下的精度错误。对系统:offloader和NPU格式转换逻辑调整,但保持向后兼容。对团队:新增的测试提供了一定回归保障,但需关注后续offloader重构时的兼容性。

核心路径变更 缺少测试覆盖 NPU 专用代码

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论