Relay IR表示

Relay IR简介
本节介绍了 Relay IR——第二代 NNVM。期待两种背景的读者——具有编程语言背景的读者和熟悉计算图表示的,深度学习框架开发人员。
简要总结了设计目标,讨论要点。
• 支持传统的数据流式编程和转换。
• 支持函数式作用域,let-binding,成为功能齐全的可微分语言。
• 能够允许用户混合两种编程风格。
使用 Relay 构建计算图
传统的深度学习框架,使用计算图作为中间表示。计算图(或数据流图)是表示计算的有向无环图 (DAG)。由于缺乏控制流,数据流图表达的计算受限制,容易实现自动微分,异构执行环境编译(例如,专用硬件上执行图)。
可以使用 Relay 构建计算(数据流)图。如何构造一个简单的二节点图。示例语法与 NNVMv1 等现有计算图 IR,唯一区别:
• 现有框架通常使用图和子图
• Relay 使用函数 eg – 表示图形fn (%x)
每个数据流节点,都是 Relay 中的一个 CallNode。Relay Python DSL快速构建数据流图。构造Add节点,两个输入点都指向%1。深度学习框架评估时,按照拓扑顺序计算节点, %1只会计算一次。实现访问者,打印结果,嵌套的 Call,变成log(%x) + log(%x)。
DAG 中存在共享节点时,对语义的不同解释造成的。在普通的函数式编程 IR 中,嵌套表达式视为表达式树,不考虑%1在%2中,实际重用了两次。
Relay IR 到了这种差异。通常,深度学习框架用户,用这种方式构建计算图,经常发生 DAG 节点重用。用文本格式打印 Relay时,每行打印一个 CallNode,将每个 CallNode分配一个临时 id (%1, %2),可以引用每个公共节点。
模块:支持多种功能(图形)
介绍了如何将数据流图构建为函数。能不能支持多种功能,可以互相调用?Relay将多个功能组合在一个模块中;下面的代码显示,一个函数调用另一个函数的示例。
def @muladd(%x, %y, %z) {
%1 = mul(%x, %y)
%2 = add(%1, %z)
%2
}
def @myfunc(%x) {
%1 = @muladd(%x, 1, 2)
%2 = @muladd(%1, 2, 3)
%2
}
该模块可以被视为一个Map<GlobalVar, Function>,这里 GlobalVar 只是一个 id,表示模块中的功能。@muladd与@myfunc是上面例子中的 GlobalVars。当CallNode调用另一个函数时,对应的 GlobalVar 存储在 CallNode 的 op 字段中。包含一个间接级别——使用相应的 GlobalVar,查找调用函数的主体。可以直接将函数的引用,存储为 CallNode 中的 op。为什么需要引入 GlobalVar 呢? GlobalVar 解耦了定义/声明,启用了函数的递归和延迟声明。
def @myfunc(%x) {
%1 = equal(%x, 1)
if (%1) {
%x
} else {
%2 = sub(%x, 1)
%3 = @myfunc(%2)
%4 = add(%3, %3)
%4
}
}
在上面的例子中,@myfunc递归地调用。使用 GlobalVar@myfunc,表示函数避免了数据结构中的循环依赖。Relay 相对于 NNVMv1,有以下改进:
• 简洁的文本格式,可简化写入passes的调试。
• 在联合模块中,对子图函数的一流支持,使得联合优化会成为可能,如内联和调用约定规范。
• 简单的前端语言互操作,所有数据结构,可以在 Python 中访问,允许在 Python 中,快速构建优化原型,与 C++ 代码混合。
让绑定和作用域
深度学习框架中,使用的旧方法构建计算图。将讨论 Relay 引入新结构——let 绑定。
每一种高级编程语言,使用 let 绑定。在 Relay 中,Let(var, value, body)表示三个字段的数据结构。评估let表达式,先评估 value 部分,分配给 var,在 body 表达式中,返回评估结果。
可以使用一系列 let 绑定,构造逻辑上等效数据流程序。
嵌套的 let 绑定称为 A 范式,通常用作函数式编程语言中的 IR,仔细看看 AST 结构。虽然这两个程序在语义上相同(除了 A 范式,有 let 前缀),但AST 结构不同。
程序优化采用这些 AST 数据结构,进行转换,两种不同的结构,将影响要编写的编译器代码。例如,如果检测一个模式:add(log(x),y)。
• 在data-flow形式中,先访问add节点,直接查看第一个参数,是不是日志
• 在 A 范式中,不能直接检查,要添加的第一个输入是%v1–需要保留从变量到绑定值的映射查找, %v1是一个日志。
不同的数据结构,影响编写转换的方式。为什么需要 let 绑定?PL 是一个相当成熟的领域。
为什么可能需要绑定
let 绑定的一个关键用法,指定计算范围。下面的例子,没有使用 let 绑定。
试图决定应该在哪里评估 node 时,问题就出现了%1。特别是,虽然文本格式似乎建议应该%1,在if 范围之外评估节点,但 AST(如图所示)不建议这样做。实际上,数据流图从未定义评估范围。这在语义中,引入了一些歧义。
有闭包时,这种歧义变得更加有趣。考虑以下程序,返回一个闭包。不知道应该在哪里计算%1;可以在闭包内部或外部。
fn (%x) {
%1 = log(%x)
%2 = fn(%y) {
add(%y, %1)
}
%2
}
let 绑定解决了这个问题,值的计算发生在 let 节点。在这两个程序中,如果%1 = log(%x)更改成let %v1 = log(%x),明确指定计算位置,在 if 范围和闭包外。let-binding 提供了更精确的计算站点规范,生成后端代码时,可能很有用(此类规范在 IR 中)。
另一方面,不指定计算范围的数据流形式,确实有优势——在生成代码时,无需担心将 let 放在哪里。数据流表单为后面的passes,决定将评估点放在哪里。在优化的初始阶段,当发现方便时,使用程序的数据流形式,可能不是一个坏主意。Relay 中的许多优化,都是为了优化数据流程序编写的。
将 IR 降低到实际运行时程序时,需要精确计算的范围。使用子函数和闭包时,希望明确指定计算范围,应该发生在哪里。Let-binding 可用于后期执行特定优化,解决问题。
对 IR 转换的影响
大多数函数式编程语言,用 A 范式分析,不需要表达式DAG。
Relay同时支持数据流形式和 let 绑定。让框架开发人员熟悉的表示。如何编写 pass,有一些影响:
• 如果来自数据流背景,要处理 let,将 var 映射到表达式,遇到 var 时,执行查找。需要一个从表达式到转换表达式的映射。有效地删除程序中的所有lets。
• 如果来自 PL 背景,喜欢 A 范式,将提供 A 范式pass的数据流。
• 对于 PL 人员,当实现某些东西(例如,数据流到 ANF 的转换)时,表达式可以是 DAG,应该使用 Map<Expr, Result> 访问表达式,计算一次转换后的结果,结果表达式保持公共结构。
有一些额外的高级概念,例如符号形状推理,未涵盖的多态函数。

参考链接:
https://tvm.apache.org/docs/dev/relay_intro.html

Relay IR表示相关推荐

  1. TVM学习笔记二.relay IR介绍

    relay是一种功能多样的编程语言,用于机器学习系统表达的中间表示.relay支持代数数据类型,闭包,控制流和递归,从而可以直接表示比基于计算图的IR更复杂的模型.relay还包括一种使用类型关系的依 ...

  2. TVM,Relay,Pass

    TVM,Relay,Pass Relay介绍 主要结合TVM的文档(https://tvm.apache.org/docs/dev/relay_intro.html),介绍一下NNVM的第二代Rela ...

  3. TVM/Relay 的 PartitionGraph()(mod) 函数讨论整理

    TVM/Relay 的 PartitionGraph()(mod) 函数讨论整理 TVM/Relay 的图形分区功能.以下简单示例,错误信息. PartitionGraph() 函数指定图形是用带有 ...

  4. 向Relay添加算子

    向Relay添加算子 为了在Relay IR中使用TVM算子,需要在Relay中注册算子,以确保将其集成到Relay的类型系统中. 注册算子需要三个步骤: • 使用RELAY_REGISTER_OPC ...

  5. AI System 人工智能系统 TVM深度学习编译器 DSL IR优化 计算图 编译 优化 内存内核调度优化 DAG 图优化 DFS TaiChi 函数注册机 Registry

    DSL 领域专用语言 TVM深度学习编译器 AI System 人工智能系统 参考项目 TaiChi 三维动画渲染物理仿真引擎DSL TVM 深度学习DSL 密集计算DSL LLVM 模块化编译器 编 ...

  6. TVM Relay与Pass

    TVM Relay与Pass 本文介绍TVM的Relay,如何基于Relay构建一个Conv+BN+ReLU的小网络, TVM中的Pass的工作机制,并较为详细的介绍了RemoveUnusedFunc ...

  7. pass基础架构分析

    pass基础架构分析 Relay 和 TVM IR,包含一系列优化passes,可提高模型的性能指标,如平均推理,内存占用,或特定设备的功耗.有一套标准优化,及特定机器学习的优化,包括常量折叠,死代码 ...

  8. AI中pass架构设计优化

    AI中pass架构设计优化 Relay 和 TVM IR,包含一系列优化passes,可提高模型的性能指标,例如平均推理,内存占用,或特定设备的功耗.有一套标准优化,及特定机器学习的优化,包括常量折叠 ...

  9. 传统编译器与神经网络编译器

    传统编译器与神经网络编译器 传统编译器 以LLVM(low level virtual machine)为例,输入是高级编程语言源码,输出是机器码,由一系列模块化的编译器组件和工具链组成. LLVM通 ...

最新文章

  1. 强大自己,从学习开始!2020年最有内容的订阅号,每一个都是万里挑一!
  2. 15岁成杀人犯,监狱里学编程,37岁获释后年薪70万
  3. eltable 无数据文案修改_有哪些适合十二月发的文艺文案?记录文案用这款图片便签...
  4. 正则表达式基本语法元字符
  5. 【Linux 内核】编译 Linux 内核 ⑤ ( 查看 .config 编译配置文件 | 正式编译内核 )
  6. 登 GitHub 趋势榜首德国疫情追踪 App 号称可保疫情隐私数据无忧,你信吗?
  7. Linux的工作队列work queue和延时工作队列
  8. Samba通过ad域进行认证并限制空间大小
  9. fill函数 神奇的迭代器
  10. 标准化的EPLAN电气绘图
  11. Day2:数据类型介绍及相关使用方法
  12. 华三H3C路由器配置FTP服务并使用电脑连接ftp传输文件
  13. perl编译器下载linux64,perl 在linux 下的安装
  14. 4种公众号文章编辑器亲测对比
  15. 加密算法详解AES/HmacSHA1/DES
  16. JavaScript 中的数字在计算机内存中占多少个Byte?
  17. 极客领航 C/C++|MCU|软件|物联网|嵌入式|Linux|辅助设计|飞行器
  18. 如何在Linux系统中整理磁盘碎片 节省空间
  19. ubuntu22.04系统cp2102驱动USB端口占用问题解决
  20. C语言+windows API仿写类酷狗播放器(1)

热门文章

  1. 2021-2027年中国室内定位市场研究及前瞻分析报告
  2. 利用c语言找出输入文本最长的一行
  3. 手撸一个JdbcTemplate,带你了解其原理
  4. line_profile逐行代码分析
  5. Python xrange() 函数
  6. LeetCode简单题之差的绝对值为 K 的数对数目
  7. 如何在TVM上集成Codegen(上)
  8. 在OpenShift平台上验证NVIDIA DGX系统的分布式多节点自动驾驶AI训练
  9. 2021年大数据环境命令(一):常用命令汇总
  10. Kazoo安装和使用