
MLIR的Constant Propagation與Folding:一次踩坑后的深度復(fù)盤上個(gè)月調(diào)試一個(gè)AI推理引擎的中間表示優(yōu)化流程,遇到一個(gè)詭異現(xiàn)象:模型在x86上跑得好好的,交叉編譯到RISC-V后,某些層的計(jì)算結(jié)果開始出現(xiàn)微小偏差。追了兩天,發(fā)現(xiàn)是MLIR的constant folding階段把一些本該保留的浮點(diǎn)常量折疊成了不同的精度表示。這個(gè)坑讓我重新審視了MLIR中看似簡(jiǎn)單的常量傳播與折疊機(jī)制——它遠(yuǎn)不止“把常量算出來”這么簡(jiǎn)單。從一次“過度優(yōu)化”說起問題出在某個(gè)量化感知訓(xùn)練后的模型,圖中存在大量形如%c = arith.addf %a, %b的節(jié)點(diǎn),其中%a和%b都是通過arith.constant定義的浮點(diǎn)常量。MLIR的 canonicalization pass 默認(rèn)會(huì)嘗試將這些常量運(yùn)算折疊成新的常量。但問題在于,當(dāng)%a和%b的精度不同(比如一個(gè)f32一個(gè)f16),或者它們來自不同的dialect(比如tosa.const與arith.constant混用)時(shí),折疊行為會(huì)觸發(fā)隱式的類型提升,導(dǎo)致最終結(jié)果與原始語義不一致。更隱蔽的是,MLIR的fold()接口默認(rèn)返回OptionalValue,如果返回nullopt表示無法折疊。但很多自定義op的fold實(shí)現(xiàn)會(huì)“偷懶”——直