MLIR与IREE(中间表示执行引擎)的集成
一个让我熬夜到凌晨三点的bug
去年秋天,我在调试一个边缘设备上的模型推理管线。模型在x86上跑得飞快,一交叉编译到ARM Cortex-A系列,推理结果就开始随机飘。更诡异的是,同样的MLIR编译流程,换一个算子就正常。我盯着IREE的HAL(硬件抽象层)调度日志看了整整两天,最后发现是MLIR的linalg方言到IREE的flow方言转换时,一个tensor.collapse_shape的维度信息被错误地折叠了——IREE的运行时调度器根据这个折叠后的形状分配了错误的workgroup大小,导致部分线程读取了未初始化的共享内存。
这个坑让我意识到,MLIR与IREE的集成远不是“把IR丢进去就能跑”那么简单。今天这篇笔记,就从这个血泪教训开始,聊聊两者之间那些容易翻车的细节。
集成架构:不是简单的“前端-后端”
很多人把IREE理解为MLIR的一个后端,这其实是个误解。IREE本身就是一个完整的编译执行框架,MLIR只是它的“前端语言层”。实际集成路径是这样的:
MLIR (各种方言) → IREE的flow方言 → IREE的hal方言 → IREE的vm (虚拟机) → 目标后端 (Vulkan/Metal/CPU)关键点在于:MLIR的方言需要先“下沉”到IREE的flow方言。这个下沉过程不是自动的,需要手动编写转换pass。我见过