4. 排查环境准备

旭日算子兼容性问题的排查,本质上是在一个多层软硬件栈中定位“哪一层与预期不一致”。如果环境本身没有准备清楚,后续所有结论都不可信。因此,排查的第一步不是急着跑算子,而是把硬件、驱动、框架、工具链和日志采集环境完整固定下来,形成一份可复现的“环境基线”。

环境准备的核心目标只有一句话:让每一次排查都能回答“在什么硬件、什么驱动、什么框架、什么工具链下,出现了什么现象,并留下了什么日志”。

一、核心原理:兼容性排查依赖“环境基线”

旭日(Sunrise)算子通常运行在异构计算环境中,涉及 CPU、加速卡、驱动、运行时库、深度学习框架以及算子编译工具链。兼容性问题往往不是单一版本错误,而是多个组件版本之间的约束关系被破坏。例如:框架版本要求某个运行时 ABI,而驱动版本只支持旧 ABI;或者算子编译工具链生成的指令集与当前硬件代际不匹配。

因此,环境准备要围绕“可复现”和“可观测”两个原则展开。可复现要求所有版本号、路径、环境变量、设备编号都被记录;可观测要求日志、指标、错误码能够被完整采集,而不是只看到框架层抛出的模糊异常。

二、硬件环境:先确认设备与拓扑

硬件环境包括加速卡型号、数量、PCIe 拓扑、NUMA 节点、内存容量以及设备健康状态。排查前应确认设备是否被系统正确识别,避免把“设备未识别”误判为算子兼容性问题。

# 查看加速卡设备
lspci | grep -i sunrise

# 查看设备节点
ls -l /dev/sunrise*

# 查看 NUMA 与 PCIe 拓扑
lscpu | grep NUMA
numactl --hardware

# 查看设备健康状态(示例工具)
sunrise-smi -q

如果设备数量与预期不符,或某个设备处于降速、掉卡状态,应先处理硬件与驱动问题,再进入算子排查。否则后续日志中会出现大量无关错误,干扰判断。

三、软件依赖与驱动版本:锁定约束关系

软件依赖包括操作系统版本、内核版本、驱动版本、运行时库版本、Python 版本及关键依赖包。驱动版本与运行时库通常存在严格的匹配矩阵,不能只看“能装上”。建议用清单方式记录,并与官方兼容性矩阵逐项核对。

层级 检查项 记录方式 常见风险
硬件 加速卡型号、数量、拓扑 lspci / sunrise-smi 设备未识别、降速
驱动 驱动版本、内核模块 modinfo / dmesg 版本不匹配、加载失败
运行时 运行时库、ABI 版本 ldd / 版本查询命令 符号缺失、ABI 冲突
框架 框架版本、算子后端 pip show / 框架自检 算子未注册、后端回退
工具链 编译器、算子编译工具 版本命令、编译日志 指令集不匹配、编译失败
日志 日志级别、采集路径 环境变量、日志目录 日志缺失、级别过低

四、框架版本与工具链:确保算子可被正确加载

框架版本决定了算子注册方式、后端调度逻辑和 ABI 约束。排查时应确认框架版本与旭日后端插件版本匹配,并检查算子是否真正走到了加速设备,而不是被静默回退到 CPU。

# 查看框架与后端版本
python -c "import sunrise_framework as sf; print(sf.__version__)"
python -c "import sunrise_backend; print(sunrise_backend.__version__)"

# 查看算子注册与设备分配
python -c "from sunrise_framework import ops; print(ops.list_registered())"

# 工具链版本
sunrise-cc --version
sunrise-opt --version

工具链方面,要特别关注算子编译时使用的目标架构参数。如果编译目标与当前硬件代际不一致,可能出现“编译通过但运行报非法指令”的现象。此时应保留编译命令、编译日志和生成的中间文件,便于回溯。

五、日志采集环境搭建:让问题留下证据

日志采集环境是排查的“黑匣子”。建议在复现问题前就设置好日志级别、日志路径和采集脚本,避免问题出现后再临时开启导致现场丢失。

# 设置日志级别与路径
export SUNRISE_LOG_LEVEL=DEBUG
export SUNRISE_LOG_DIR=/var/log/sunrise
export FRAMEWORK_LOG_LEVEL=INFO

# 采集驱动与内核日志
dmesg -T > /var/log/sunrise/dmesg.log
sunrise-smi -q > /var/log/sunrise/smi.log

# 采集框架与算子日志
python run_operator_test.py 2>&1 | tee /var/log/sunrise/operator_test.log
建议在日志目录中同时保存一份“环境快照”:uname -a、pip freeze、驱动版本、设备列表、环境变量。这样即使问题在他人机器上复现,也能快速比对差异。

六、案例与场景:一次典型的“环境不一致”排查

某团队反馈旭日算子在某节点上精度异常,但在另一节点正常。初步怀疑算子实现问题。按照环境基线方法排查后发现:两个节点的驱动版本一致,但框架后端插件版本不同,异常节点使用了旧版插件,导致部分算子走了回退路径,精度与预期不符。更新插件并重新采集日志后,问题消失。

这个案例说明:兼容性排查不能只看“算子本身”,而要先确认环境基线是否一致。环境准备做得越完整,后续定位越快。

七、误区与复盘

  • 误区一:只记录框架版本,忽略驱动与运行时。 兼容性问题常发生在驱动与运行时之间,必须逐层记录。
  • 误区二:日志级别默认过低。 默认 INFO 可能看不到算子注册、设备分配和回退信息,排查前应临时提升到 DEBUG。
  • 误区三:不保存环境快照。 问题复现后环境可能被改动,缺少快照会导致无法回溯。
  • 误区四:把硬件未识别当成算子问题。 先确认设备与驱动正常,再进入算子层排查。
环境准备不是“一次性动作”,而是每次排查前都要执行的固定流程。建议将上述检查项脚本化,形成一键采集环境基线的工具,减少人为遗漏。
旭日算子兼容性排查 · 环境准备分层基线 自下而上逐层确认,任何一层不一致都会导致算子行为异常 ① 硬件环境 加速卡型号 / 数量 / PCIe 拓扑 / NUMA / 设备健康状态 lspci | grep sunrise sunrise-smi -q ② 驱动与运行时 驱动版本 / 内核模块 / 运行时库 / ABI 约束 / 符号完整性 modinfo sunrise_drv ldd libsunrise_rt.so ③ 框架与后端插件 框架版本 / 后端插件版本 / 算子注册 / 设备分配与回退路径 pip show sunrise-fw ops.list_registered() ④ 算子工具链 编译器版本 / 目标架构参数 / 编译日志 / 中间产物保留 sunrise-cc --version sunrise-opt --version ⑤ 日志采集环境 日志级别 / 日志路径 / 驱动日志 / 框架日志 / 环境快照 SUNRISE_LOG_LEVEL dmesg -T > dmesg.log 逐层确认

完成以上五层环境准备后,再开始运行算子测试用例,才能保证排查结论建立在可靠基线上。环境基线越清晰,兼容性问题的定位路径就越短。