已关闭
--cpu-affinity 在容器内绑核会给 sched_setaffinity 传空集合,子进程直接 OSError 退出 #28
崇理战队创建于 8月13日关闭于 8月20日
xiangjie10
8月13日 评论:
8月13日 评论:
👋 您好,感谢向 MindCluster-AscendNPUBurn 提交 Issue!
🎉 我们已收到您的反馈,感谢你对开源社区的支持!
📅 处理时效 维护团队将在工作日 24 小时内查看并回复您的问题。
🔍 自助排查(推荐优先查看) 在等待回复期间,您可以先查阅仓库README以及历史 Issue 中相似问题的解决方案,多数问题可快速解决。
💡 为了更快定位问题,请您确保 Issue 包含:
- 清晰的问题描述
- 可复现的操作步骤
- 相关日志、截图或环境信息
我们会尽快跟进,感谢您的理解与配合!


xiangjie10
8月13日 评论:
8月13日 评论:
/label add triaged


8月13日 添加了label:triaged
8月13日 将 yangpeng197 设为负责人
yangpeng197
8月18日 评论:
8月18日 评论:
/label add feature


8月18日 添加了label:feature
8月18日 关联了pull request:【Issue】add empty cpu_affinity check
8月20日 关闭了 issue
8月20日 添加了label:resolved
9月9日 issue状态由 TODO 改变为 DONE
在容器里带
cpu_affinity跑压测,子进程起来就挂,报的是OSError: [Errno 22] Invalid argument。追下来是拓扑探测失败之后兜底逻辑没兜住,最后给sched_setaffinity传了个空 list。链路
ascend_npu_burn/runtime/engine.py:71-78def subprocess_func(index, input_queues, result_queue, args, run_devices): setup_logger(args.log_level) try: set_cpu_flag = False if args.cpu_affinity and not set_cpu_flag: cpu_affinity = get_cpu_by_device_id(run_devices[index]) # 0表示当前进程 os.sched_setaffinity(0, cpu_affinity) # pylint: disable=E1101ascend_npu_burn/common/utils.py:209-216def get_cpu_by_device_id(device_id: int) -> List[int]: """根据设备ID获取对应的CPU列表""" numa_topology = get_npu_numa_topology() cpu_topology = get_numa_configs() for numa_id, npu_ids in numa_topology.items(): if device_id in npu_ids: return cpu_topology[numa_id] return []os.sched_setaffinity(0, [])传空集合是非法的,必抛OSError: [Errno 22] Invalid argument。这里返回[]的路径没有任何保护,直接就送进去了。什么时候会返回空
get_npu_numa_topology()靠lspci列 19e5 设备来建拓扑(utils.py:162-183)。压测工具的典型运行环境是容器,而昇腾的基础镜像里一般不装pciutils,_find_command_path('lspci')返回 None,回落到/usr/bin/lspci又不存在,Popen抛 FileNotFoundError,走到 198-204 行的兜底:except Exception as e: logger.warning(f"Could not detect NPU topology automatically: {e}") # 假设标准的 8 卡机器,前 4 张在 Node 0,后 4 张在 Node 1 numa_to_npus = defaultdict(list) # 重置 for i in range(8): node = i // 4 numa_to_npus[node].append(i)兜底把卡数写死成 8。于是:
-d指定了 8 号及以上的卡,device_id in npu_ids永远不成立 → 返回[]→ 子进程 OSError 退出;还有一个索引错配
return cpu_topology[numa_id]是拿 NUMA node 号当 list 下标用的,但get_numa_configs()返回的 list 未必是按 NUMA node 组织的:utils.py:104-119)按range(node_count)逐个 append,下标 == node 号,对得上;for s_id in range(sockets_count)按 socket 建的,长度 = socket 数。鲲鹏 920 这类每 socket 2 个 NUMA node 的机器,兜底后 list 长度是 2,而 NPU 读到的
numa_node可能是 2 或 3,cpu_topology[3]直接 IndexError;即使不越界,socket 和 NUMA node 也不是一个东西,绑出来的核是错的。影响
绑核这个功能本来是为了避免跨 NUMA 访存、让压测压出真实算力。现在的情况是:
logger.warning之后就静默降级了,报告里看不出拓扑是猜的。建议
get_cpu_by_device_id拿不到有效 CPU 列表时不要返回[]让调用方去踩,或者调用方判空后跳过绑核并打一条明确的 warning:cpu_affinity = get_cpu_by_device_id(run_devices[index]) if cpu_affinity: os.sched_setaffinity(0, cpu_affinity) else: logger.warning( f"device {run_devices[index]} 未匹配到 NUMA 拓扑,跳过绑核," f"本轮性能数据不可用于故障判定" )拓扑探测优先读
/sys/class/devdrv/(或npu-smi info -m)而不是依赖容器里未必存在的lspci;实在探测不到时,兜底不要硬编码 8 卡,按实际run_devices的最大卡号来生成,或者干脆放弃绑核。cpu_topology[numa_id]改成显式的dict映射,别用 list 下标去承载 NUMA node 号;兜底分支按 socket 建 list 的语义也和调用方的假设不一致,建议统一。顺带
engine.py:74-75的set_cpu_flag定义完就是False,if args.cpu_affinity and not set_cpu_flag里的not set_cpu_flag恒真,这个变量后面也没再赋过值。看着像是想做"只绑一次",但子进程里本来就只走一次,是不是可以直接删掉?