MindSpore IR中的CNode节点解析

举报
黄生 发表于 2025/10/04 15:43:57 2025/10/04
【摘要】 以 22_execute_0693.ir 里的19个cnodes为例,该IR文件通过MNIST数据集的推理过程产生。[mindspore@asc ir]$ grep "%[0-9]\+" 22_execute_0693.ir%0(CNode_256) = PrimFunc_Flatten(%para1_x) cnode_attrs: {checkpoint: Bool(1), is_dyna...

以 22_execute_0693.ir 里的19个cnodes为例,该IR文件通过MNIST数据集的推理过程产生。

[mindspore@asc ir]$ grep "%[0-9]\+" 22_execute_0693.ir
%0(CNode_256) = PrimFunc_Flatten(%para1_x) cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%1(ValueNode_257$input_data$logits) = Load(%para2_dense_relu_sequential.0.weight, UMonad[U]) cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%2(x) = PrimFunc_MatMul(%0, %1, Bool(0), Bool(1)) {instance name: matmul} cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%3(ValueNode_258$input_data$logits) = Load(%para3_dense_relu_sequential.0.bias, UMonad[U]) cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%4(x) = PrimFunc_BiasAdd(%2, %3, I64(0)) {instance name: bias_add} cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%5(CNode_259$input_data$logits) = PrimFunc_ReLU(%4) {instance name: relu} cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%6(ValueNode_260$input_data$logits) = Load(%para4_dense_relu_sequential.2.weight, UMonad[U]) cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%7(x) = PrimFunc_MatMul(%5, %6, Bool(0), Bool(1)) {instance name: matmul} cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%8(ValueNode_261$input_data$logits) = Load(%para5_dense_relu_sequential.2.bias, UMonad[U]) cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%9(x) = PrimFunc_BiasAdd(%7, %8, I64(0)) {instance name: bias_add} cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%10(CNode_262$input_data$logits) = PrimFunc_ReLU(%9) {instance name: relu} cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%11(ValueNode_263$input_data$logits) = Load(%para6_dense_relu_sequential.4.weight, UMonad[U]) cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%12(x) = PrimFunc_MatMul(%10, %11, Bool(0), Bool(1)) {instance name: matmul} cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%13(ValueNode_264$input_data$logits) = Load(%para7_dense_relu_sequential.4.bias, UMonad[U]) cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%14(x) = PrimFunc_BiasAdd(%12, %13, I64(0)) {instance name: bias_add} cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%15(ValueNode_265) = MakeTuple(%11, %6, %1, %3, %8, %13) cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%16(ValueNode_266) = UpdateState(UMonad[U], %15) cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
%17(CNode_267$logits) = Depend(%14, %16) primitive_attrs: {side_effect_propagate: I64(1)} cnode_attrs: {checkpoint: Bool(1), is_dynamic_len: Bool(0)}
Return(%17) primitive_attrs: {visited: Bool(1)} cnode_attrs: {checkpoint: Bool(1)}

Node(节点) 是 MindSpore 计算图中的一个基本单元。包括:

  • CNode(计算节点)
  • Parameter Node(参数节点)
  • ValueNode(常量节点)
  • Primitive Node(算子节点)

CNode(Compute Node,计算节点)实际执行计算的节点,如算子调用、函数调用等。每个 CNode 包含:

  • 输入(其他 Node)
  • 算子(Primitive)
  • 属性(attrs)

在 IR 中,CNode 通常以 CNode_xxx 或带别名的形式出现(如 %2(x))。19 个 CNode 的详细说明如下:

序号 CNode 名称 算子/操作 输入 输出形状 说明
1 %0(CNode_256) PrimFunc_Flatten %para1_x (64, 784) 将输入展平
2 %1(ValueNode_257...) Load %para2_weight + UMonad (512, 784) 加载权重1
3 %2(x) PrimFunc_MatMul %0, %1, Bool(0), Bool(1) (64, 512) 第一层矩阵乘
4 %3(ValueNode_258...) Load %para3_bias + UMonad (512) 加载偏置1
5 %4(x) PrimFunc_BiasAdd %2, %3, I64(0) (64, 512) 加偏置1
6 %5(CNode_259...) PrimFunc_ReLU %4 (64, 512) ReLU激活
7 %6(ValueNode_260...) Load %para4_weight + UMonad (512, 512) 加载权重2
8 %7(x) PrimFunc_MatMul %5, %6, Bool(0), Bool(1) (64, 512) 第二层矩阵乘
9 %8(ValueNode_261...) Load %para5_bias + UMonad (512) 加载偏置2
10 %9(x) PrimFunc_BiasAdd %7, %8, I64(0) (64, 512) 加偏置2
11 %10(CNode_262...) PrimFunc_ReLU %9 (64, 512) ReLU激活
12 %11(ValueNode_263...) Load %para6_weight + UMonad (10, 512) 加载权重3
13 %12(x) PrimFunc_MatMul %10, %11, Bool(0), Bool(1) (64, 10) 输出层矩阵乘
14 %13(ValueNode_264...) Load %para7_bias + UMonad (10) 加载偏置3
15 %14(x) PrimFunc_BiasAdd %12, %13, I64(0) (64, 10) 加偏置3
16 %15(ValueNode_265) MakeTuple %11, %6, %1, %3, %8, %13 Tuple of 6 tensors 打包所有参数
17 %16(ValueNode_266) UpdateState UMonad, %15 UMonad 更新状态
18 %17(CNode_267$logits) Depend %14, %16 (64, 10) 依赖关系处理
19 Return(%17) Return %17 - 返回最终结果

本 IR 中,总 Node 数:39 ,总 CNode 数:19,其余 20 个 Node 可能是 ValueNode、Parameter、Primitive 等非计算节点。CNode类型统计如下:

CNode类型 个数 具体节点
Load 6 %1, %3, %6, %8, %11, %13
MatMul 3 %2, %7, %12
BiasAdd 3 %4, %9, %14
ReLU 2 %5, %10
Flatten 1 %0
MakeTuple 1 %15
UpdateState 1 %16
Depend 1 %17
Return 1 Return(%17)

其中,

  • 参数操作: 6个Load
  • 核心计算: 3个MatMul + 3个BiasAdd + 2个ReLU + 1个Flatten = 9个
  • 图控制(状态管理): 1个MakeTuple + 1个UpdateState + 1个Depend + 1个Return = 4个

下面介绍最后几个依赖关系处理节点的作用:

1. %15(ValueNode_265) = MakeTuple(%11, %6, %1, %3, %8, %13)

# 把所有加载的参数打包成一个元组
参数元组 = (输出层权重, 隐藏层2权重, 隐藏层1权重, 
           隐藏层1偏置, 隐藏层2偏置, 输出层偏置)

收集所有通过Load操作加载的参数,为后续的状态更新做准备

2. %16(ValueNode_266) = UpdateState(UMonad[U], %15)

# 更新计算图的状态
新状态 = UpdateState(当前状态, 参数元组)

UMonad:是一个"状态单子",用于跟踪副作用操作(如参数加载),告诉计算图"这些加载操作已经完成了"

3. %17(CNode_267$logits) = Depend(%14, %16)

# 建立依赖关系:确保计算 %14 之前先完成 %16
最终logits = Depend(原始计算结果, 状态更新)

强制计算顺序。“在返回最终logits之前,必须确保所有参数加载操作都已完成”

这些节点确保参数加载操作在计算之前完成,避免了潜在的竞态条件,保证了计算结果的正确性。

  • 训练时:参数可能在不断更新,依赖关系很重要
  • 推理时:参数是固定的,但MindSpore保持相同的计算图结构
  • 一致性:确保训练和推理的计算逻辑一致
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。