想象一间充满活力的国际出版社——“IREE出版社”。世界各地的作者用不同的语言写书:有人用“PyTorch语”写,有人用“TensorFlow语”写,还有人用“ONNX语”写。出版社的使命是:不管作者用什么语言写、写的是什么题材,最终都要变成全球不同国家的书店里能够上架销售的成品——英文版、中文版、电子书版,一应俱全。这个“接稿、翻译、编辑、排版、印刷、发行”的全过程,就是 IREE 端到端编译。 IREE(Intermediate Representation Execution Environment,中间表示执行环境)是一个基于 MLIR 的端到端编译器。它把 PyTorch、TensorFlow 等框架训练出来的模型,经过一层层“翻译与加工”,最终编译成可以在 Vulkan、CUDA、ROCm 等多种硬件后端上直接运行的部署产物。模型在哪个“语言环境”里长大并不重要,重要的是它到任何“市场”(硬件平台)都能交付。这正是框架集成时代,AI 从业者最需要的“全球发行网络”。
掌握 IREE 端到端编译,是打通“训练到部署”全链路的关键技能,能让你把模型高效交付到手机、汽车、云端等异构硬件平台。
可视化演示
演示IREE端到端编译器,展示分层Lowering、多后端部署与端到端编译关键流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
IREE端到端编译 分层Lowering、多后端部署与端到端编译,实现跨平台模型高效部署 Model→Compile→Run MLIR多后端编译核心
框架集成
出版社的收稿台前,作者们排着队递上五花八门的书稿:用 PyTorch 语写的手稿、用 TensorFlow 语写的剧本、用 ONNX 语写的诗集。IREE 出版社从不挑剔语言,因为它有一套专门的“前台”,负责把每种语言的书稿接进来,登记编号、统一格式。这个前台,就是 IREE 的框架集成层。
在技术上,框架集成由一系列前端转换器完成。常用的工具链是 Torch-MLIR(接收 PyTorch 导出的模型)和 TensorFlow 前端(接收 SavedModel 格式)。它们把训练框架产出的模型文件解析成一棵计算图,再映射到 MLIR 体系中的高层方言表示。这一阶段只做“接入与初译”,不深入改动模型语义。
这个阶段的产物通常称为顶层 IR,例如 MHLO 方言。它仍然保留模型的高层语义——卷积、矩阵乘、激活函数这些“大块头”算子都还是完整的一整块,并未拆散成细碎指令。保留完整算子的好处是,后续的高层优化(如算子融合)可以在“语义完整”的粒度上进行,不丢失任何结构信息。
正如收稿台只负责登记和初步整理、不评判书稿内容好坏,框架集成层也只做“接入与初译”。接下来,这份电子稿将被送入编辑系统,开启真正意义上的多轮加工。
- Model_{框架}表示某个训练框架产出的模型工件,例如 PyTorch 的 ScriptModule、TensorFlow 的 SavedModel。它是整个翻译流水线的“原稿”,携带网络结构与权重参数。
- Frontend_{框架}IREE 为该框架定制的前端转换器,如 Torch-MLIR、TensorFlow 前端。它负责读入原稿、解析计算图,并完成框架语义到 MLIR 方言的映射。
- IR_{front}转换后得到的高层中间表示(如 MHLO 方言),是后续所有编译阶段的统一入口,相当于出版社编辑系统里的“标准电子稿”。
MLIR基础
编辑系统里最重要的资产,是一套“统一编辑标注语言”规范。无论原稿是英文还是德文,编辑都会先把章节标题、段落、插图位置翻译成统一的标注符号。这套规范在编译器世界里就是 MLIR——Multi-Level Intermediate Representation,多级中间表示。
MLIR 不是一个单一的 IR,它更像一套“编译器乐高套装”,提供基础积木和拼装规则。核心机制是 Dialect(方言)。每个 Dialect 定义一组算子、类型和语法,对应一个抽象层级。IREE 的编译流水线,本质上就是在这个乐高套装中,把积木从“高层方言”逐步改装成“低层方言”的过程。
常见的方言层级包括:高层的 MHLO 方言(保留卷积、归一化等整体算子)、中层的 TOSA 方言(面向张量运算的可移植规范)、中低层的 Linalg 方言(以线性代数运算表达)、以及低层的 LLVM 方言(贴近机器指令)。一个 MLIR 模块中可以同时混用多种方言,编译器通过 Pass 把算子从一种方言转换为另一种方言。
有了这套统一编辑语言,出版社不用为一本书专门建一套系统——所有书稿共用同一套标注规则,只是不同阶段挂上不同的标注。这正是 MLIR 被称作“编译器基石”的原因。
- Dialect_{i}第 i 个方言,定义一组算子、类型、属性以及它们之间的合法组合规则,相当于一套编辑标注符号集。
- \bigcup(并集)表示整个程序表示可以同时容纳多个方言的操作。例如一开始只有 MHLO 算子,随后逐步加入 TOSA、Linalg 算子,它们共存于同一个模块。
- IR_{total}整个编译单元的完整中间表示。它不是一成不变的,而是随编译过程不断演化,一个阶段一个样子。
编译流水线
书稿进入编辑流程后,要依次经过收稿登记、初审拆解、格式翻译、排版输出、印刷打包几个环节。IREE 的编译过程同样是流水线:每个工位接收上一环节的产物,加工后交给下一环节。一环扣一环,顺序不能乱。
完整的 IREE 编译流水线可以概括为四大阶段。前端导入阶段把框架模型变成顶层 IR;方言转换与优化阶段在 MLIR 内完成多轮“编辑加工”;后端代码生成阶段把低层 IR 变成目标硬件的代码;打包阶段把代码、元数据、调用约定封装成部署模块文件(.vmfb)。
流水线设计带来两个关键好处。一是“中间产物可复用”:只要接入一个新的前端,就能复用后续所有优化与后端;二是每个阶段的 Pass 职责单一,便于调试和扩展。IREE 沿着这条流水线,把“训练模型”一步一步变成“可执行模块”。
流水线让每本书的出版流程高度标准化。作者只需关心写书,剩下的翻译、编辑、印刷、发行全部交给流水线上的工位完成。这就是 IREE 作为“端到端编译器”的含义。
- Model_{train}训练产出的模型,是流水线的最初输入,相当于作者交来的原稿。
- \mathrm{Import}前端导入,把框架模型转换为 MLIR 顶层方言表示,也就是收稿登记与初译。
- \mathrm{Optimize}以一系列 Pass 完成方言转换与优化,让中间表示更精简、更适合硬件执行,相当于编辑的反复修改与润色。
- \mathrm{CodeGen}后端代码生成,把低层 IR 编译为目标指令(如 Vulkan shader、CUDA kernel),相当于把定稿排版成印刷文件。
- \mathrm{Package}打包生成部署模块,附带元数据与调用入口,最终产出可交付的产物,相当于把印好的书装订打包。
分层降级
把一本德语书译成中文,编辑不会一步到位,而是先写出全书梗概,再把每一章翻译成中文初稿,最后按中文表达习惯润色。编译器也是类似的——它不会把 MHLO 层面的“卷积”直接变成硬件指令,而是逐层翻译。这个过程就是 Lowering(降级)。
Lowering 的本质是“语义等价、表示降级”。每一步把一个高抽象层级的算子拆解为多个低抽象层级算子的组合。例如一个高层卷积算子,可能先变成张量操作集合,再变成循环加内存访问序列,最终变成线程调度指令。任何一步,输入与输出的计算结果必须完全一致——就像翻译不能改变原意。
分层设计让优化各司其职。硬件无关的优化(常量折叠、公共子表达式消除、算子融合)尽量在高、中层完成,因为它们不依赖具体硬件;而硬件相关的调整(向量宽度、内存布局、并行度)放到低层基于目标信息完成。这样,同一份高层代码可以被多个后端复用,每个后端又能做针对性调优。
就像台阶的每一级都承上启下,分层降级的每一层都让程序离硬件更近一步,同时保证语义不走样。IREE 正是凭借这条逐级台阶,让同一模型在完全不同的硬件上都能“落地”。
- IR_{k}第 k 层的中间表示,例如 k=0 时是 MHLO 高层方言,k=n 时是接近机器的低层表示。
- \mathrm{Transform}_{k}第 k 步转换,对应编译器中的一个或一组 Pass,负责把当前层表示改写为更低层表示,同时保持语义等价。
- k = 0,1,\dots,n 的递推整个 Lowering 是一连串递推过程,每一步的输出成为下一步的输入,直到得到适合后端生成的低层表示。
多后端支持
书稿定稿后,出版社要发行多个语言版本:英文版给美国书店,中文版给中国书店,日文版给日本书店。IREE 也一样,同一份低层 IR 要面向不同的“硬件市场”发行。这些市场对应的就是各类执行后端:Vulkan、CUDA、ROCm。
Vulkan 是一套跨厂商的图形与计算接口,适合在不同品牌的 GPU、甚至移动端 GPU 上运行;CUDA 是 NVIDIA 的并行计算平台,在英伟达 GPU 上性能与生态最成熟;ROCm 是 AMD 的开放计算平台,服务于 AMD GPU 与加速卡。IREE 的编译器针对每个后端都有独立的代码生成组件。
为了不让“一份 IR 适配 N 个后端”变成 N 份重复工作,IREE 设计了后端抽象层。后端无关的任务(内存规划、模块管理、调用约定)在框架层面统一完成;后端相关的任务(指令选择、资源分配、shader/kernel 生成)由各后端实现。编译时通过 target 参数指定目标后端,编译器把低层 IR 分发给对应后端完成生成。
多后端如同出版社的多语种发行网络,每种语言版本都针对当地市场做了本地化,但书的内容始终是同一本。这让 IREE 成为真正意义上的“一次编译、多处部署”平台。
- IR_{low}经过完整降级后的低层中间表示,例如 Linalg 或 LLVM 方言,相当于已经定稿、准备发行的“母版”。
- \mathrm{Backend}_{target}目标后端编译组件,如 IREE 的 Vulkan 后端、CUDA 后端、ROCm 后端,负责把低层 IR 翻译成目标执行代码。
- Exec_{target}最终面向目标平台的可执行模块,例如一个包含 Vulkan shader 或 CUDA kernel 的 .vmfb 文件。
IREE运行时
印刷好的书摆在书店里,读者买回家还需要一个“阅读体验”——翻开、扫读、理解。同样,编译产物 .vmfb 只是“印好的书”,真正运行起来还需要 IREE 运行时(Runtime)负责加载与执行。IREE 的运行时采用虚拟机(VM)架构。
为什么编译成可执行模块后还需要一个 VM?因为 IREE 的编译产物是“半成品”:它包含多个硬件后端生成的代码片段,以及把这些片段组织起来的字节码。VM 负责加载模块、解析调用约定、把输入数据调度到正确的后端函数上执行。就像书印好了,但不同章节可能需要不同的阅读工具配合——插图需要看图、习题需要演算纸——VM 就是帮忙切换工具的人。
IREE 运行时的核心职责包括:模块加载(解析 .vmfb 和内置元数据)、函数调度(按调用约定把输入送入对应后端 Kernel)、内存管理(复用缓冲、规划生命周期)、以及异步流水执行(把多个计算阶段重叠起来,提高硬件利用率)。这些职责与编译器分离,保证了编译产物在多种宿主环境中都能被一致地执行。
如果说编译器是出版社的生产线,那运行时就是全球书店的“阅读服务体系”——它让每一位读者拿到书就能读,不必关心印刷用了什么机器。IREE 对编译器与运行时的清晰分工,恰恰是端到端方案高效、可移植的保障。
- M_{load}运行时加载的编译产物模块(.vmfb 文件),相当于摆在书架上的成品书。
- X模型输入数据,例如一张图片的张量表示,相当于读者开始读书时带入的“问题”。
- \mathrm{VM}( \cdot )IREE 虚拟机中的执行入口,负责按调用约定完成数据搬运、kernel 调度与结果回收。
部署应用
流水线的终点是“送达读者”。手机上的推荐模型、自动驾驶汽车里的感知模型、云端 GPU 上托管的推理服务——它们都是 IREE 编译产物的落地场景。部署环节检验整个链条的成色:产物体积、启动时间、峰值内存、推理延迟,每一项都决定产品的用户体验。
在 AI 编译与部署生态中,IREE 并不是孤军奋战。XLA 主要深耕 TensorFlow/JAX 生态,TVM 以“自动调优 + 算子库生成”见长,IREE 则强调“以 MLIR 为底座的多后端端到端流水线”。三者理念互补、各有侧重,实践中常根据硬件与框架的组合来选择。理解各自的定位,才能在真实项目中做对技术选型。
性能层面,IREE 的收益来自多层优化叠加:高层算子融合减少内存往返,中层并行化提升多核利用,后端特化(如向量化、共享内存优化)贴合硬件特性。衡量收益的常用指标是加速比:以基线方案耗时为分母,以 IREE 部署耗时为分子,大于 1 即表示更快。
从收稿到送达,IREE 把“一本书”的全球之旅压缩成一条自动化流水线。对 AI 工程师来说,理解这趟旅程的每个站点,才能在真实项目中选对工具、调好参数,让模型真正从论文走进产品。
- T_{baseline}基线方案的执行耗时,例如直接用原框架进行推理的时间。
- T_{IREE}同样模型经 IREE 编译部署后的执行耗时。
- \mathrm{Speedup}加速比,衡量 IREE 部署相对基线方案的性能增益,是部署优化中最直观的量化指标。
AI 应用场景
移动端端侧推理部署
阶段:模型部署与推理阶段
解决的问题:移动端芯片品牌繁杂,NVIDIA CUDA 在手机上行不通。传统做法是为每种 GPU 手写 shader 或算子,工作量爆炸且难以维护。借助 IREE 的 Vulkan 后端,PyTorch/TensorFlow 模型可编译成 .vmfb 直接在手机 GPU 上运行,运行时轻量,适合端侧嵌入。
具体案例:某图像识别 App 原方案在部分安卓手机 GPU 上无法调用加速算子。引入 IREE 后用 Vulkan 后端编译轻量模型并做真机验证——一份编译产物覆盖多品牌 GPU,启动时间与功耗明显改善。
云厂商异构 GPU 推理服务
阶段:云端推理服务构建
解决的问题:云上 GPU 既有 NVIDIA 也有 AMD,客户模型又来自不同训练框架,统一推理引擎需要同时对接 CUDA 与 ROCm。IREE 的多后端支持让同一套编译流水线分别产出 CUDA/ROCm 模块,再配合运行时统一调度。
具体案例:某 MLOps 平台为其推理服务引入 IREE,用户提交 PyTorch 模型后,平台根据用户云主机的 GPU 品牌,用对应后端编译出可执行模块并部署到容器中。跨品牌 GPU 的部署周期从“按周计”缩短到“按分钟计”。
自动驾驶多域控制器部署
阶段:车规级编译部署
解决的问题:智驾系统在感知、规控等多个域控制器上运行,硬件形态各异,传统手写算子难以适应车型快速迭代。IREE 以 MLIR 分层降级和可插拔后端,让同一套模型面向不同芯片生成优化代码。
具体案例:某自动驾驶团队将感知模型分别编译到车规级 GPU(Vulkan)与车载计算平台(自定义后端),IREE 流水线使模型版本与硬件版本解耦,新车型的适配周期大幅缩短。
Python 演示
"""mini_iree.py: 迷你 IREE, 模拟端到端编译的逐层 Lowering.""" class Op: """一个算子节点, 包含名字与参数列表.""" def __init__(self, name, *args): self.name = name self.args = list(args) def __repr__(self): return self.name def to_mhlo(ops): """第 1 站: 框架原生算子 -> 高层方言 MHLO.""" return [Op('mhlo.' + o.name, *o.args) for o in ops] def to_tosa(ops): """第 2 站: 高层方言 MHLO -> 中高层方言 TOSA.""" out = [] for o in ops: if o.name == 'mhlo.relu': out.append(Op('tosa.maximum', o.args[0], 0)) else: out.append(Op(o.name.replace('mhlo.', 'tosa.'), *o.args)) return out def to_linalg(ops): """第 3 站: 中高层方言 TOSA -> 线性代数方言 Linalg.""" out = [] for o in ops: if o.name == 'tosa.matmul': out.append(Op('linalg.matmul', *o.args)) else: out.append(Op(o.name.replace('tosa.', 'linalg.'), *o.args)) return out def to_llvm(ops): """第 4 站: 线性代数方言 Linalg -> 类 LLVM 指令.""" return [Op(o.name.replace('linalg.', 'llvm.'), *o.args) for o in ops] def compile_pipeline(model): """完整流水线: 导入 -> 方言转换 -> 中层降级 -> 后端生成.""" print('== IREE 端到端编译流水线 (迷你版) ==') stages = [ ('前端导入(框架->MHLO)', to_mhlo), ('方言转换(MHLO->TOSA)', to_tosa), ('中层降级(TOSA->Linalg)', to_linalg), ('后端生成(Linalg->LLVM)', to_llvm), ] ir = model for name, fn in stages: ir = fn(ir) print('[{0}] 产物: {1}'.format(name, [o.name for o in ir])) return ir if __name__ == '__main__': model = [ Op('conv2d', 'input', 'weight'), Op('relu', 'conv_out'), Op('matmul', 'relu_out', 'fc_w'), ] final_ir = compile_pipeline(model) print('最终生成底层指令数:', len(final_ir))
class Op:定义算子节点,name表示算子名,args保存参数;它对应编译系统中的一个操作原语。def to_mhlo(ops):模拟前端导入,给每个算子冠上mhlo.前缀,表示进入了高层方言世界。if o.name == 'mhlo.relu':模拟方言转换中的语义改写:ReLU 被改写成maximum(x, 0)张量运算,这正是 TOSA 方言的表达方式。out.append(Op('tosa.maximum', o.args[0], 0))把高层激活算子降级为更通用的张量运算,体现“表示层级逐层降低”。o.name.replace('mhlo.', 'tosa.')同一类算子在方言间“平移命名”,强调它是表示层级的迁移,而不是语义改变。stages = [...]明确编译流水线的顺序:导入、方言转换、中层降级、后端生成,四个工位缺一不可。ir = fn(ir)每一站的输出成为下一站的输入,对应公式IR_{k+1} = Transform_k(IR_k)。if __name__ == '__main__':程序入口,构造一个包含卷积、ReLU、矩阵乘的迷你模型,跑通全流程。
常见误区
误区我以为 IREE 跟 ONNX Runtime 一样,是个拿来加载模型的推理引擎。把模型文件丢给它就能跑,不需要什么“编译”过程。
正解IREE 包含编译器与运行时两大组成部分。编译器负责把框架模型逐步降低成目标硬件的可执行模块(.vmfb),运行时只负责加载和执行这个编译产物。类比出版社:编译是“把书稿变成印刷版”,运行时是“读者翻开书阅读”。没有编译环节,运行时无书可读。
为何常见:IREE 的部署形态是“编译器离线完成、运行时在线使用”,很多使用者只接触过运行时接口,就误以为它是全部。
误区我以为编译就是把高层代码丢给一个“翻译器”,一次性输出机器码,跟点一下编译按钮一样简单。
正解IREE 的 Lowering 是多次逐步降级:MHLO→TOSA→Linalg→LLVM→后端指令,每一步都保持语义等价。这像翻译一本书要经过概译、精译、润色多个环节,而不是一段脚本搞定。多步设计是为了在合适的层级做合适的优化,比如算子融合放在高层、向量化放在低层。
为何常见:传统编译器把整个编译过程封装成一条命令,人们习惯把编译当成“瞬间完成的黑盒”。
误区我以为 MLIR 和 LLVM IR 一样,是大家统一写的一种固定 IR 语法,各编译器都输出它就行。
正解MLIR 是一套可扩展的编译器基础设施,核心是 Dialect 机制。它不规定单一表示,而是允许在同一模块内共存多个方言,并通过 Pass 在方言间转换。LLVM IR 只是 MLIR 生态中的众多方言之一(LLVM 方言)。MLIR 更像是出版社的“统一编辑标注系统”,而非某一种固定语言。
为何常见:MLIR 名字里带"IR"两个字,且大量资料拿它与 LLVM IR 对比,容易让人望文生义。
误区我以为只要把模型用 IREE 编译部署,推理速度就一定比原框架快,甚至不需要调任何参数。
正解IREE 提供的是“可优化的编译流水线与多后端支持”,最终性能取决于算子组合、后端选择、运行时配置以及是否启用异步流水线。加速比公式 Speedup = T_baseline / T_IREE 说明,IREE 方案耗时才是关键变量。有些场景(如小型算子、I/O 瓶颈)收益有限,需要针对性地做后端选择与调优。
为何常见:宣传材料总是强调“高性能、跨平台”,读者容易忽略编译器不是魔法,而是需要正确配置与调优的一整套工具链。
面试题
Q1. IREE的核心定位是?
- A.分布式文件系统
- B.模型压缩工具箱
- C.端到端编译部署← 正确答案
- D.数据监控预警平台
答案:C。IREE 是基于 MLIR 的端到端编译器,负责把 PyTorch/TensorFlow 模型编译成可在多种后端运行的可执行模块。它解决的是“训练到部署”的问题,而不是存储、压缩或监控问题。
Q2. IREE后端中不包含下面哪一项?
- A.Vulkan图形计算接口
- B.CUDA并行计算平台
- C.ROCm开放计算生态
- D.SQL数据库查询接口← 正确答案
答案:D。IREE 支持 Vulkan、CUDA、ROCm 等硬件计算后端,分别面向跨厂商 GPU、NVIDIA GPU 与 AMD GPU。SQL 是数据库查询语言,与硬件执行后端无关。
Q3. 将PyTorch模型导入IREE通常使用的工具是?
- A.TorchMLIR模型转换← 正确答案
- B.LabelImg图像标注
- C.NumPy数值计算库
- D.Git分布式版本管理
答案:A。Torch-MLIR 负责把 PyTorch 模型解析并转换为 MLIR 高层方言(如 MHLO),是 IREE 框架集成层的关键前端。LabelImg 做标注、NumPy 做数值计算、Git 做版本管理,都不承担模型导入职责。
Q4. 关于分层Lowering的说法正确的是?
- A.一步到位直接生成汇编
- B.逐层降低抽象表示层级← 正确答案
- C.跳过中间优化直接执行
- D.只保留低层硬件指令集
答案:B。Lowering 是逐步把高层 IR(如 MHLO)降级为更低层表示(如 TOSA、Linalg、LLVM),每一步做语义等价的转换并执行对应优化,类似翻译书稿的多轮流程,而非一步到位。
Q5. MLIR中用于描述不同抽象层次的机制是?
- A.Dialect方言扩展体系← 正确答案
- B.Python脚本解释器
- C.JSON配置文件存储
- D.SQL数据库索引引擎
答案:A。MLIR 的核心机制是 Dialect。每个 Dialect 定义一组算子、类型与语法,对应一个抽象层级,编译器通过 Pass 在方言间转换。脚本、JSON、SQL 都不属于 MLIR 的层级描述机制。
Q6. 下面属于IREE支持的执行后端的有?
- A.Vulkan图形计算接口← 正确答案
- B.CUDA并行计算平台← 正确答案
- C.ROCm开放计算生态← 正确答案
- D.SCSI存储设备接口
答案:ABC。IREE 覆盖 Vulkan(跨厂商 GPU)、CUDA(NVIDIA GPU)、ROCm(AMD GPU)等计算后端。SCSI 是存储设备接口规范,与模型执行后端无关。
Q7. IREE运行时(VM)的核心职责是?
- A.训练模型更新梯度
- B.加载调度执行编译产物← 正确答案
- C.设计深度神经网络结构
- D.采集并标注图像数据
答案:B。IREE 运行时(VM)负责加载 .vmfb 编译产物、解析调用约定、调度后端函数执行并管理内存。训练、网络设计、数据采集都发生在编译之前,不归运行时管。
Q8. 为什么IREE要采用分层Lowering而不是直接映射到硬件指令?
- A.逐层降级可复用各层优化降低适配成本← 正确答案
- B.MLIR编译器自身缺少低层算子表达能力
- C.模型结构简单根本无需任何编译优化
- D.IREE各后端硬件架构完全一致无需分层
答案:A。分层降级让硬件无关优化在高层完成、硬件相关优化在低层完成,同一份高层 IR 可复用到多个后端,这正是 IREE 跨平台能力的根本支撑。B、C、D 都不符合实际情况。
Q9. IREE端到端编译流水线的构成阶段包括?
- A.前端导入训练模型计算图← 正确答案
- B.方言转换完成中间优化← 正确答案
- C.后端生成目标可执行代码← 正确答案
- D.训练阶段更新网络权重
答案:ABC。流水线的四大阶段为前端导入、方言转换与优化、后端代码生成、打包部署。训练是模型的生产过程,发生在编译流水线之前,不属于编译阶段。
Q10. 与各框架直接部署相比,IREE跨平台部署的优势有哪些?
- A.一次编译产物可面向多个后端复用← 正确答案
- B.统一中间表示降低跨硬件部署成本← 正确答案
- C.运行时轻量适合端侧设备嵌入使用← 正确答案
- D.编译全程无需任何中间表示参与
答案:ABC。IREE 以 MLIR 多级 IR 为底座,编译器与运行时分离,编译产物可由轻量 VM 加载执行,适合端侧嵌入,且多后端让一份编译流程适配多种硬件。D 与事实相反——MLIR 中间表示正是其核心所在。