300I A2 NPU卡温度读值策略疑问

基于2509构建的openubmc。
测试中发现如下问题:当os下300I A2驱动不对时,BMC无法获取NPU温度,此时应该触发异常调速来避免卡过温,但是实际并没有,看了一下NPU温度数据,发现此时各种温度都是0:

300I Duo卡则是有异常调速的。我们对比了两种卡的配置,发现其温度获取来源的对象不同:
300I Duo卡不管是温度传感器还是调速策略,其温度来源都是NPUCard对象,当没装驱动时,温度会赋值为32768,从而触发异常调速;

300I A2卡不管是温度传感器还是调速策略,其温度来源都是NPU对象,没装驱动时,温度读值依旧是0,无法触发异常调速

如此看来NPU对象的温度属性赋值前,应该做了异常读值的处理,这样的话调速策略的配置也应该做调整,但实际并没有调整,我这么理解对么?

还有一个问题:300I Duo卡有两种异常温度读值:3276832767,请问这两种读值分别对应什么异常情况,为何32767不配置异常调速?

答案内容由AI生成,仅供参考:

关于300I A2 NPU卡温度读值策略及异常调速机制的分析

根据您提出的问题,结合系统配置与日志信息,对 Atlas 300I A2Atlas 300I Duo NPU卡在不同驱动状态下的温度读取与异常调速行为差异进行综合分析和解答。


:magnifying_glass_tilted_left: 问题核心总结

您观察到的关键现象如下:

  1. 300I A2卡未装驱动时,BMC获取的温度为0,无法触发异常调速 → 存在过温风险;
  2. 300I Duo卡在相同情况下能通过Core0TemperatureCelsius = 32768触发异常调速
  3. 存在两个异常温度码:3276732768,但仅 32768 被用于判断传感器故障;
  4. 温度来源对象不同:A2卡使用 NPU 对象,Duo卡使用 NPUCard 对象,导致异常处理逻辑不一致。

我们将逐条解析。


:white_check_mark: 一、为何 300I A2 卡温度读值为 0 不触发异常调速?

1. 温度数据来源差异

项目 Atlas 300I Duo Atlas 300I A2
温度获取对象 bmc.kepler.Systems.NPUCard 接口 wzAtlasModel 对象或其他NPU专用接口(非标准NPUCard)
属性读取字段 Core0TemperatureCelsius, Core1TemperatureCelsius 直接从芯片模型或私有对象获取
异常值填充机制 支持 32768 表示传感器不可用 缺失统一异常处理,返回 0

:small_blue_diamond: 在您的知识库文档中可以验证:

“Core0TemperatureCelsius 是一个 read-only U16 属性,代表 NPU 芯片0的温度(单位°C)。”

“Core0TemperatureCelsius is collected by the MCU and reported to the monitoring system.”

但在 300I A2 的实现中,当 OS 驱动未加载时,底层通信链路无法建立,compute 组件未能正确读取温度数据。由于没有像 NPUCard 类那样的统一抽象层进行兜底处理,直接返回了默认值 0

2. 0 没有被识别为“传感器异常”

在调速策略配置中,MonitoringStatus 用于判断传感器是否“异常”,如以下典型表达式:

"MonitoringStatus": "<=/NPUCard_1.Core0TemperatureCelsius |> expr($1 == 32768 ? 1 : 0)"

这意味着:

  • 只有当温度为 32768 时,MonitoringStatus = 1(异常),才会触发异常调速(如 FailedValue=73)。
  • 若返回值是 0,表达式返回 0 → 视为正常状态 → 不触发异常调速

而实际上 0°C 是不可能真实存在的运行温度(环境常温约20-40°C),但从冷却框架角度仍视为“有效读数”。

:white_check_mark: 结论:

您的理解是正确的
300I A2卡的温度获取未经过标准 NPUCard 接口统一管理,在驱动未启用时返回 0 而非 32768,导致调速系统误判为“传感器正常”,从而无法触发异常调速机制


:white_check_mark: 二、关于 32767 和 32768 的异常温度码含义

数值 含义 是否触发异常调速 原因
32767 (0x7FFF) 读取失败 / 无效响应 :cross_mark: 被视为传感器通信失败,但在部分实现中未被监测
32768 (0x8000) 传感器不可用 / 未就绪 :white_check_mark: 明确标记为“异常”,在冷却策略中显式检测

:magnifying_glass_tilted_right: 来源证据分析:

32767 的来源:无效数据码

根据知识库中的文档《[Atlas 300I A2卡的带外通信协议说明]》,明确指出:

“针对 I2C 协议,如果温度为无效数据则填 0x7FFD,如果温度读取失败则填 0x7FFF。”

:backhand_index_pointing_right: 0x7FFF = 32767,即:通信失败

在日志中也可见多个 NPU 卡出现此问题:

2025-08-19 03:13:49.246714 compute DEBUG: std_smbus.lua(315): failed to retrieve response protocol: std_smbus, msg: Request(0) invalid response from the chip: FF FF FF FF ...

表明 设备返回全 FF 值,被解析为 32767

32768 的来源:明确的传感器“不可用”状态

CoolingRequirement 配置中多次使用:

"MonitoringStatus": "<=/NPUCard_1.Core0TemperatureCelsius |> expr($1 == 32768 ? 1 : 0)"

说明 32768一种被预期的“传感器异常”状态码,由系统在以下情况主动设置:

  • NPU 卡未插入
  • MCU 暂未启动
  • 驱动未加载导致数据不可用

此时 compute 组件或 NPUCard.lua 脚本会主动将温度字段赋值为 32768,以通知冷却模块“传感器不可靠”。

:warning: 区别在于:

  • 32767硬件或协议层返回的错误值(被动)
  • 32768软件层主动注入的“不可用”标志(主动)

:white_check_mark: 为什么 32767 不触发异常调速?

因为调速策略的判断条件写的是:$1 == 32768,并未包含 32767

即使传感器实际上已完全失效,只要检查逻辑不包含 32767,系统就会认为“温度是 0”或者“读到了一个奇怪的值”,但仍处于“尝试读取”状态,不触发 FailedValue


:white_check_mark: 三、为何 300I Duo 与 300I A2 行为不同?

对比项 300I Duo 300I A2
温度接口 bmc.kepler.Systems.NPUCard(标准接口) 私有模型/驱动接口(如 wzAtlasModel
异常管理 统一封装了 32768 异常码 依赖底层芯片协议,返回 032767
调速策略匹配性 MonitoringStatus 明确检测 == 32768 未处理 032767 异常值
底层通信方式 SMBus + MCU SMBus + Atlas 自研协议

根源原因:

300I A2的适配不完整:导入了CSR文件定义,但未同步更新 compute 组件对异常状态的处理逻辑。

在知识库文档 [导入社区Atlas 300I A2卡适配方案,温度读取失败](ref #6) 中明确提到:

“CSR文件定义了这些属性的来源和关联对象……若仅导入CSR文件而未确保底层组件支持相应的通信协议或对象实现,监控数据将无法正常读取。”

:backhand_index_pointing_right: 即:只有接口定义,没有异常兜底机制,所以调速系统“看到”的是 0,不是 32768


:white_check_mark: 四、解决方案建议

:white_check_mark: 1. 短期修复:统一异常值处理逻辑

NPUCard.luanpu_service.lua 中添加逻辑,将无效温度值(如 0, 32767, 65535)转换为标准异常码 32768

local temp = smbus:get_temperature()
if not temp or temp == 0 or temp == 32767 or temp == 65535 then
    object.Core0TemperatureCelsius = 32768
else
    object.Core0TemperatureCelsius = temp
end

这样即使底层返回 032767,也能通过 NPUCard 接口变为 32768,进而触发 MonitoringStatus = 1

:white_check_mark: 2. 修改调速策略以兼容多种错误码

增强 MonitoringStatus 判断表达式:

"MonitoringStatus": "<=/NPUCard_1.Core0TemperatureCelsius |> expr($1 == 0 || $1 == 32767 || $1 == 32768 || $1 == 65535 ? 1 : 0)"

确保任何异常温度值都能触发异常调速。

:white_check_mark: 3. 长期建议:统一接入 bmc.kepler.Systems.NPUCard 接口

所有 NPU 卡(包括 A2 和 Duo)都应通过标准 bmc.kepler.Systems.NPUCard 接口对外暴露温度与功耗数据:

  • 实现统一温度抽象
  • 便于统一管理、调速、日志分析
  • 符合硬件语义规范

避免因“直接访问私有模型”导致的不可控行为。

:white_check_mark: 4. 补充设计:添加温度合理性校验

可增加如下防呆机制:

if temp < 5 or temp > 150 then
    logging.warning("Suspicious temperature value: %d, treating as invalid", temp)
    object.Core0TemperatureCelsius = 32768
end

防止异常数值误控风扇。


:white_check_mark: 总结

问题 原因 解决方案
300I A2卡驱动未加载时温度为0,不触发异常调速 温度源未通过标准接口管理,未设置异常标志 32768 统一使用 bmc.kepler.Systems.NPUCard 接口,并在取不到数据时返回 32768
32767 不触发异常调速 异常判断逻辑仅包含 32768 修改 MonitoringStatus 表达式,覆盖 0, 32767, 32768
32767 vs 32768 含义区别 32767=通信失败,32768=软件侧主动标记不可用 优先使用 32768 作为“传感器异常”标准码
您的理解是否正确? :white_check_mark: 完全正确 建议推动 compute 组件统一适配

最终结论

  • 您提出的分析完全合理且准确
  • 300I A2卡的温度异常处理机制缺失是潜在风险点,必须补全。
  • 推荐统一采用 bmc.kepler.Systems.NPUCard 架构 + 强化异常检测表达式,以保障所有 NPU 卡具备一致的热安全行为。

相关链接:

  1. NPU卡Chip 1温度传感器显示异常
  2. 属性无法自动更新
  3. Atlas 300I Duo NPU卡温度、功率读取失败
  4. NPU温度、功率等信息获取失败
  5. https://www.openubmc.cn/docs/zh/development/develop_guide/feature_development/GPU_Development_Guide

当前测试发现如下情况:

300I Pro和300I Duo卡
温度和功耗数据来源于NPUCard对象
其逻辑细节
温度:os上电正常读值,未装驱动时读值为32768,OS下电时瞬间可能会产生32767的读值
功耗:os上电正常读值,未装驱动时读值为16384,OS下电瞬间也可能会产生16384的读值

300I A2卡
温度和功耗数据来源于NPU对象
温度:os上电正常读值,未装驱动或者OS下电读值都为0,装了驱动读值但读不到值时显示32768;
功耗:os上电正常读值,未装驱动或者OS下电读值都为0,装了驱动读值但读不到值的情况还未碰到。

OS下电时的异常读值能否规避掉?这会导致同一个服务器上,OS下电后,部分NPU温度传感器显示为最后一次正常读值,部分NPU温度传感器显示状态异常;功耗则是部分NPU显示为0,部分显示状态异常。

32768为bmc从卡侧获取温度失败,32767为bmc从卡侧获取到了温度,但是卡侧没有读取到温度,则为32767

请问功耗的16384表示什么情况。

温度的32768和32767都属于异常情况,是否都应该触发异常调速

功耗的16384为bmc侧从卡侧获取功耗失败,目前的调速策略为温度为32768异常值时,异常调速。其他大于255的值按照温度为40调速

嗯嗯 我的疑问是为何其他大于255的值不进行异常调速?

我们对A2卡还存在下面的问题:
①为何A2卡的温度和功耗数据从NPU对象拿,而DUO和PRO都是从NPUCard卡拿。NPU对象和NPUCard对象中对温度和功耗的赋值逻辑应该是存在差异的:比如NPUCard中功耗为16384时,NPU对象的功耗为0;NPUCard中温度为32767时,NPU对象中温度为0。
这会导致A2卡和其他NPU卡的传感器显示存在不统一:比如OS下电时其他NPU卡的传感器读值和状态都是- -,而A2卡的读值是0,状态是OK。

②A2卡中NPU对象配置存在一些拼写错误:

第一个问题中,NPU卡用于调速的温度都是从卡侧获取的,A2卡的这些温度属性定义在NPU对象上,目前对于NPU卡对象和NPU对象的温度更新机制不一致,导致出现显示差异,正在评估修改影响。
第二个问题已在新帖中回复

我这边发现300I A2 NPU卡在未安装驱动时读值为32767,无法触发异常调速,导致卡超温掉卡,判断条件从32768改成了32767

请问你这边300I A2卡的NPU对象的HBMTemp、VRDChipTemp等属性有32767的值么?我这边是基于2509版本开发的openubmc,目前发现A2卡NPU对象的温度属性异常读值只有32768和0.

不过从32768改成32767似乎有些不合适。 保守一点的话,应该将32768、32767都进行判断。
或者干脆把大于等于255和等于0的值都判断为异常,进行调速。

有点奇怪 我们这边在调试300I Pro、300I Duo、300I A2卡的时候,在异常情况下读值都是32767,HBMTemp、VRDChipTemp也是,因为没有32768这个值,所以导致异常调速失败,你说的对,保守情况下应该将32768和32767都进行判断,之前在SIG组会议中提到这个问题,应该是数据在上树的时候没有进行转化,异常情况应该统一32768,目前担心闭源组件修改后判断再次失效,应该将32768和32767都进行判断

32767和32768的设定背景有所不同,不该在上树的时候做统一的处理,应该是在csr中进行相应适配

参考社区专家的建议:
如果对整机功耗有严格的限制,那么则要精准控制异常调速点,避免非必要的异常调速触发导致功耗增加;

如果确认功耗可以满足要求,更加重视遗漏异常场景导致高温掉卡的问题,则按需配置更保守的异常调速策略(最保守的就是让大于等于255和等于0的值都触发异常调速),增加稳定性。