图算融合优化示例
圖算融合優化示例
概述
圖算融合是MindSpore特有的網絡性能優化技術。它可以通過自動分析和優化現有網絡計算圖邏輯,并結合目標硬件能力,對計算圖進行計算化簡和替代、算子拆分和融合、算子特例化編譯等優化,以提升設備計算資源利用率,實現對網絡性能的整體優化。相比傳統優化技術,圖算融合具有多算子跨邊界聯合優化、與算子編譯跨層協同、基于Polyhedral的算子即時編譯等獨特優勢。另外,圖算融合只需要用戶打開對應配置后,整個優化過程即可自動完成,不需要網絡開發人員進行其它額外感知,使得用戶可以聚焦網絡算法實現。
圖算融合的適用場景包括:
? 對網絡執行時間具有較高性能要求的場景;
? 通過拼接基本算子實現自定義組合算子,并希望對這些基本算子進行自動融合,以提升自定義組合算子性能的場景。
使用方法
當前圖算融合優化默認關閉狀態,我們只需在訓練腳本中為context指定參數enable_graph_kernel=True即可啟用圖算融合:
from mindspore import context
context.set_context(enable_graph_kernel=True)
圖算融合優化只支持Graph模式。
樣例腳本
為了說明圖算融合優化場景,我們構造了一個簡單網絡MyNet, 包含一個乘法和加法計算。在打開圖算融合進行優化之后,這兩個計算便會自動合成一個融合算子:
import numpy as np
import mindspore.context as context
from mindspore import Tensor
from mindspore.nn import Cell
import mindspore.ops as ops
context.set_context(mode=context.GRAPH_MODE, device_target=“GPU”)
save graph ir to view fusion detail.
context.set_context(save_graphs=True)
enable graph kernel optimization.
context.set_context(enable_graph_kernel=True)
class MyNet(Cell):
def init(self):
super(MyNet, self).init()
self.add = ops.Add()
self.mul = ops.Mul()
def construct(self, x):a = self.mul(x, 2.0)res = self.add(a, 1.0)return res
x = np.ones((4, 4)).astype(np.float32) * 0.5
net = MyNet()
result = net(Tensor(x))
print(“result: {}”.format(result))
輸出結果:
result: [[2. 2. 2. 2.]
[2. 2. 2. 2.]
[2. 2. 2. 2.]
[2. 2. 2. 2.]]
該計算圖的融合結果如圖1所示,其中左圖為未使能圖算融合時的對應計算圖,右圖為使能圖算融合后的對應計算圖。可以看到該網絡中的加法和乘法被融合成一個算子。該融合過程可以通過查看中間IR,或者通過Profiling等工具跟蹤算子執行過程進行驗證。
圖1:圖算融合優化計算圖
自定義組合算子
基于圖算融合技術,用戶可以很方便地實現高性能的自定義組合算子。其主要流程為:
- 在腳本中用基本算子組合的方式實現自定義算子定義和使用;
- 打開圖算融合配置;
- 圖算融合對自定義組合算子中的基本算子自動進行算子融合,并生成高性能融合算子。
相比其它自定義算子方式,這種方式具有對框架無侵入、簡單易用等優點。
樣例腳本
我們構造一個簡單網絡MyNet,并在其中使用了自定義算子MyOp。代碼樣例如下:
import numpy as np
import mindspore.context as context
from mindspore import Tensor
from mindspore.nn import Cell
import mindspore.ops.operations as P
context.set_context(mode=context.GRAPH_MODE, device_target=“GPU”)
enable graph kernel optimization.
context.set_context(enable_graph_kernel=True)
class MyOp(Cell):
“”" my first custom OP composited by basic OPs “”"
def init(self):
super(MyOp, self).init()
self.sub = P.Sub()
self.mul = P.Mul()
def construct(self, x, y):a = self.sub(x, y)return self.mul(a, x)
class MyNet(Cell):
def init(self):
super(MyNet, self).init()
self.mul = P.Mul()
self.pow = P.Pow()
self.my_op = MyOp()
def construct(self, x, y):a = self.mul(x, 2.0)b = self.pow(a, 3.0)res = self.my_op(b, y)return res
x = np.ones((4, 4)).astype(np.float32) * 0.2
y = np.ones((4, 4)).astype(np.float32) * 0.3
net = MyNet()
result = net(Tensor(x), Tensor(y))
print(“result: {}”.format(result))
輸出結果:
result: [[-0.015104 -0.015104 -0.015104 -0.015104]
[-0.015104 -0.015104 -0.015104 -0.015104]
[-0.015104 -0.015104 -0.015104 -0.015104]
[-0.015104 -0.015104 -0.015104 -0.015104]]
該計算圖的融合結果如圖2所示,其中左圖為未使能圖算融合時的對應計算圖,右圖為使能圖算融合后的對應計算圖。可以看到不僅自定義算子MyOp中的基本算子進行了融合,并且與主圖中的其他算子也進行了更大范圍融合。該融合過程可以通過查看中間IR,或者通過Profiling等工具跟蹤算子執行過程進行驗證。
圖2:自定義組合算子優化計算圖
總結
- 上一篇: 单精度和半精度混合训练
- 下一篇: 自动驾驶开发云平台业务分析