已关闭
[Bug]: npugraph_ex控核报错 Dynamo does not know how to trace builtin operator `str` with argument types ['int'] #602
chenyuqi创建于  7月21日关闭于  7月23日
chenyuqi
chenyuqi
7月21日 创建

在提交问题之前,请通过搜索现有和历史问题确保该问题尚未被提出并解决。

您的环境信息

-- CANN 版本 (e.g., 5.x.x, 8.x.x):  9.1.0
-- Pytorch/Torch_npu 版本 (e.g., v2.6.0, v2.9.0):2.7.1
-- Python 版本 (e.g., Python3.9.x, Python3.11.x):py39
-- 操作系统版本 (e.g., Ubuntu 18.04, EulerOs 2.0):2.7.1.post5.dev20260721

🐛 请描述bug

npugraph_ex控核报错:
File "/usr/local/python3.9/lib/python3.9/site-packages/torch/nn/modules/module.py", line 1751, in _wrapped_call_impl
return self._call_impl(*args, **kwargs)
File "/usr/local/python3.9/lib/python3.9/site-packages/torch/nn/modules/module.py", line 1762, in _call_impl
return forward_call(*args, **kwargs)
File "/usr/local/python3.9/lib/python3.9/site-packages/torch/_dynamo/eval_frame.py", line 659, in _fn
raise e.with_traceback(None) from None
torch._dynamo.exc.Unsupported: Failed to trace builtin operator
Explanation: Dynamo does not know how to trace builtin operator str with argument types ['int'] (has_kwargs False)
Hint: Avoid calling builtin str with argument types ['int']. Consider using an equivalent alternative function/method to str.
Hint: If you are attempting to call a logging function (e.g. print), you can try adding it to torch._dynamo.config.reorderable_logging_functions.
Hint: Please report an issue to PyTorch.

Developer debug context: builtin str [<class 'torch._dynamo.variables.tensor.SymNodeVariable'>] False

代码如下:

import os
os.environ["TORCH_COMPILE_DEBUG"] = "1"
os.environ['HCCL_OP_EXPANSION_MODE'] = "AIV"
import torch
import torch_npu
import torch.distributed as dist
from torch.distributed.distributed_c10d import _get_default_group
import dataclasses

@dataclasses.dataclass
class InputMeta:
    data: torch.Tensor
    is_prompt: bool

def cache_npu(rank, world_size, aic_num, aiv_num):

    class Network(torch.nn.Module):
        def __init__(self, group1, group2):
            super().__init__()
            self.group1 = group1
            self.group2 = group2
            self.relu = torch.nn.ReLU()
            self.cached_model = torch.npu.npugraph_ex.inference.cache_compile(self._forward, dynamic=True, options={"deadlock_check": True})

        def forward(self, data1, data2, aic_num, aiv_num):
            return self.cached_model(data1, data2, aic_num, aiv_num)

        def _forward(self, data1, data2, aic_num, aiv_num):
            stream1 = torch.npu.Stream()
            stream2 = torch.npu.Stream()
            with torch.npu.stream(stream1):
                with torch.npu.npugraph_ex.scope.limit_core_num(aic_num, aiv_num):
                    zeros_like_01 = torch.zeros_like(data1)
                    # 使用第一个通信域
                    torch.distributed.all_to_all_single(zeros_like_01, data2, group=self.group1)
                    relu1 = self.relu(zeros_like_01)

            with torch.npu.stream(stream2):
                with torch.npu.npugraph_ex.scope.limit_core_num(aic_num, aiv_num):
                    zeros_like_02 = torch.zeros_like(data1)
                    # 使用第二个通信域(新创建的)
                    torch.distributed.all_to_all_single(zeros_like_02, data2, group=self.group2)
                    relu2 = self.relu(zeros_like_02)
            return relu1,relu2

    torch_npu.npu.set_device("npu:" + str(rank))
    device = torch.device('npu', rank)
    dist.init_process_group("hccl", rank=rank, world_size=world_size)
    default_pg = dist.group.WORLD
    # 创建一个全新的 HCCL 通信句柄
    new_pg = dist.new_group(ranks=list(range(world_size)))

    input0 = torch.empty(16384).to('npu')
    input1 = torch.randn(16384, dtype=torch.float32).to('npu')
    npu_mode = Network(default_pg, new_pg).to(device)
    npu_out0 = npu_mode(input0, input1, aic_num, aiv_num)
    return npu_out0

def run_cache(aic_num, aiv_num):
    os.environ["MASTER_ADDR"] = "localhost"
    os.environ["MASTER_PORT"] = "29505"
    world_size = 8
    with torch.multiprocessing.Manager() as mg:

        # npu 执行
        torch.multiprocessing.spawn(cache_npu,
                                    args=(world_size, aic_num, aiv_num),
                                    nprocs=world_size, join=True)

if __name__ == '__main__':
    aic_num = 16
    aiv_num = 32

    # 第一次运行
    run_cache(aic_num, aiv_num)

    # 第二次运行
    run_cache(aic_num, aiv_num)
likedislike
chenyuqichenyuqi
7月21日 添加了label:bug
wj1e
wj1e成员
7月21日 评论:

/assign @dingdairong

likedislike
ascend-robotascend-robot成员
7月21日 将 dingdairong 设为负责人
dingdairong成员
7月22日 评论:

请问,你这是什么时间的torch_npu,及cann包?

likedislike
chenyuqi
chenyuqi
7月22日 评论:

请问,你这是什么时间的torch_npu,及cann包?

@dingdairong

都是7月21号的

likedislike
dingdairong成员
7月23日 评论:

torch 2.7.1

likedislike
dingdairong成员
7月23日 评论:

torch_npu/dynamo/npugraph_ex/scope/init.py对动态int入参调用str(), dynamo无法trace str(SymNodeVariable).规避方式:不要把aic_num/aiv_num作为cached_model的动态入参,改为模块属性/常量。

likedislike
dingdairong成员
7月23日 评论:

我把你的脚步修改为单卡,改造入参后,可以跑过,请参考修改试试。脚本如下:
import os
os.environ["TORCH_COMPILE_DEBUG"] = "1"
os.environ['HCCL_OP_EXPANSION_MODE'] = "AIV"
import torch
import torch_npu
import torch.distributed as dist
from torch.distributed.distributed_c10d import _get_default_group
import dataclasses

@dataclasses.dataclass
class InputMeta:
data: torch.Tensor
is_prompt: bool

def cache_npu(rank, world_size, aic_num, aiv_num):

class Network(torch.nn.Module):
    def __init__(self, group1, group2, aic_num, aiv_num):
        super().__init__()
        self.group1 = group1
        self.group2 = group2
        self.aic_num = aic_num
        self.aiv_num = aiv_num
        self.relu = torch.nn.ReLU()
        self.cached_model = torch.npu.npugraph_ex.inference.cache_compile(self._forward, dynamic=True, options={"deadlock_check": True})

    def forward(self, data1, data2):
        return self.cached_model(data1, data2)

    def _forward(self, data1, data2):
        stream1 = torch.npu.Stream()
        stream2 = torch.npu.Stream()
        with torch.npu.stream(stream1):
            with torch.npu.npugraph_ex.scope.limit_core_num(self.aic_num, self.aiv_num):
                zeros_like_01 = torch.zeros_like(data1)
                # 使用第一个通信域
                torch.distributed.all_to_all_single(zeros_like_01, data2, group=self.group1)
                relu1 = self.relu(zeros_like_01)

        with torch.npu.stream(stream2):
            with torch.npu.npugraph_ex.scope.limit_core_num(self.aic_num, self.aiv_num):
                zeros_like_02 = torch.zeros_like(data1)
                # 使用第二个通信域(新创建的)
                torch.distributed.all_to_all_single(zeros_like_02, data2, group=self.group2)
                relu2 = self.relu(zeros_like_02)
        return relu1,relu2

torch_npu.npu.set_device("npu:" + str(rank))
device = torch.device('npu', rank)
if not dist.is_initialized():
    dist.init_process_group("hccl", rank=rank, world_size=world_size)
default_pg = dist.group.WORLD
# 创建一个全新的 HCCL 通信句柄
new_pg = dist.new_group(ranks=list(range(world_size)))

input0 = torch.empty(16384).to('npu')
input1 = torch.randn(16384, dtype=torch.float32).to('npu')
npu_mode = Network(default_pg, new_pg, aic_num, aiv_num).to(device)
npu_out0 = npu_mode(input0, input1)
return npu_out0

def run_cache(aic_num, aiv_num):
os.environ["MASTER_ADDR"] = "localhost"
os.environ["MASTER_PORT"] = "29505"
world_size = 1
# 单卡执行
cache_npu(0, world_size, aic_num, aiv_num)

if name == 'main':
aic_num = 16
aiv_num = 32

# 第一次运行
run_cache(aic_num, aiv_num)

# 第二次运行
run_cache(aic_num, aiv_num)
likedislike
chenyuqi
chenyuqi
7月23日 评论:

问题已解决

likedislike
Ddingdairong成员
7月23日 issue状态由 TODO 改变为 DONE
Ddingdairong成员
7月23日 关闭了 issue
ascend-robotascend-robot成员
7月23日 添加了label:resolved