TensorFlow
計算グラフ最適化処理
@第1回 TensorFlow内部構造 勉強会
2019/3/4
nuka
自己紹介
❖ Nuka(@nuka_137)
➢ TensorFlowの内部構造記事書いてます
https://qiita.com/nuka/items/028780aab338d9b1a7c2
➢ TensorFlowなにもわからない(TensorFlow歴1年)
❖ 仕事
➢ HPC向け分散ファイルシステム(1年前くらいまで)
➢ 深層学習フレームワーク、周辺ツール(今)
(TF、PyTorch、TVM、ONNX、nGraph、Glowあたりを中心に)
最近調べていた、計算グラフの最適化周りについて話します
この資料は、
TensorFlowのソースコードから
計算グラフの最適化処理を
調べてまとめたものです
https://github.com/tensorflow/tensorflow
Commit ID: a8e5c41c5bbe684a88b9285e07bd9838c089e83b
(Tag: v1.13.0-rc0) 変化が激しいため、
バージョン注意
TensorFlowの基本
エッジ:テンソルの流れConst Sqrt
Conv
Add ReLU
ノード:演算
❖ ユーザが計算グラフを定義して、Session.runで実行
  計算グラフが評価されて、ユーザに結果が返る
Session.runすると・・・
内部では主に4つのことを行う
デバイス割り当て
❖ 計算グラフの各ノードに、実行デバイスを割り当て
Const
Add
Sqrt
Conv
Const
Add
Sqrt
Conv
CPU CPU
CPU
GPU
デバイス割り当て前 デバイス割り当て後
ノードにデバイスを
割り当てる
最適化
Const
Add
Sqrt
Conv
CPU CPU
CPU
GPU
❖ 演算を効率的に行えるように、計算グラフを変形
最適化前
Add
Const
Conv
CPU
CPU
GPU
演算効率の良い
計算グラフへ変形
最適化後
分割
デバイス間転送
Add
Const
Conv
CPU
CPU
GPU
Const
Conv
CPU
CPU
_Send
CPU
_Send
CPU
Add
GPU
_Recv
GPU
_Recv
GPU
❖ 割り当てたデバイスごとに、計算グラフを分割
分割前 分割後
Executor(GPU)
実行
Const
Conv
CPU
CPU
_Send
CPU
_Send
CPU
Add
GPU
_Recv
GPU
_Recv
GPU
❖ 分割した計算グラフを実行
Executor(CPU)
入力が整った
ノードから実行
実行単位
今日は最適化処理の
一部を話します
でも、その前に・・・
import tensorflow as tf
from tensorflow.python.framework.function import Defun
@Defun(tf.float32, tf.float32)
def fn(x, y):
return x + y
a = tf.constant(1.5)
b = tf.constant(2.7)
c = a * b
d = a + b
e = fn(c, d)
f = tf.constant(-7.8)
out = e + f
tf.Session().run(out)
計算グラフの最適化を確認しよう
❖ 最適化を狙った計算グラフを作ってみる
TensorBoard
サブグラフ
全入力が
Constの演算
最適化後の計算グラフを見るために
❖ RunMetadata
➢ Session.runの実行情報を取得可能
メモリ使用量/確保時間、演算毎の実行時間・・・
❖ RunOptionsの設定で、最適化後の計算グラフも取得可能
run_opts = tf.RunOptions()
run_opts.output_partition_graphs = True
run_md = tf.RunMetadata()
ops = ...
with tf.Session() as sess:
sess.run(ops, run_metadata=run_md, options=run_opts)
print(run_md.partition_graphs)
最適化後の計算グラフを
出力する設定
最適化後の計算グラフが
保存されている
Session.runに
RunMetadataとRunOptionsを渡す
最適化後の計算グラフ
実際の演算は
Const(値=0.4499998)
❖ 定数値を割り当て、その値を返すだけの計算グラフに変化
Session.runの先で、最適化処理が動作している
実際の演算は
NoOp(No Operation)
※TensorBoardは演算名ではなく、ノード名を表示する
計算グラフの
最適化処理をみてみよう
計算グラフ最適化処理
❖ Grappler
➢ グラフ分割前の最適化
❖ GraphOptimizer
➢ グラフ分割後の最適化
❖ GraphOptimizationPass
➢ 4フェーズで追加可能な最適化
グラフ構築
デバイス割り当て
Grappler
グラフ分割
GraphOptimizer
GraphOptimizationPass
Grappler
❖ Model Pruner
❖ Function Optimizer†1
❖ Constant Folding†1
❖ Shape Optimizer
❖ Remapper
❖ Layout Optimizer
❖ Memory Optimizer
❖ Arithmetic Optimizer
❖ Auto Parallel
❖ Loop Optimizer
❖ Dependency Optimizer
❖ Debug Stripper
❖ Scoped Allocator Optimizer
❖ Pin to Host Optimizer
tensorflow/core/grappler/optimizers/meta_optimizer.cc
†1 p11の計算グラフで実際に実行された最適化処理
Model Pruner
tensorflow/core/grappler/optimizers/model_pruner.cc
❖ 実行不要なノードを削除
Grappler
Fetch Fetch
演算結果に影響がない
ノードを削除
Function Optimizer
❖ サブグラフをインライン展開
tensorflow/core/grappler/optimizers/function_optimizer.cc
サブグラフ
サブグラフをメイングラフに
インライン展開することで、
呼び出しコスト削減
Grappler
サブグラフを呼び出す
処理が発生
❖ ノードの全入力が定数値の場合、定数ノードに置換
Constant Folding
Const
(4.0)
Add
Sqrt
Const
(3.5)
Add
Const
Const
(3.5)
(2.0)
Const
(5.5)
全ての入力が定数値のものは、
演算してConstノードに変換
計算グラフが変化しなく
なるまで、続ける
tensorflow/core/grappler/optimizers/constant_folding.cc
Grappler
❖ テンソルの形状に関する演算を最適化
Shape Optimizer
Grappler
tensorflow/core/grappler/optimizers/shape_optimizer.cc
Shape Prod Size
単純にテンソルの要素数
(tensor.size)を返せばよい
tensor.shape: [32, 3, 64, 64]
↓
32 * 3 * 64 * 64 = テンソルの要素数
❖ ノードを結合/分解し、演算呼び出しコストを削減
Remapper
tensorflow/core/grappler/optimizers/remapper.cc
Grappler
Conv
2D
Add
_Fused
Conv2D
❖ GPUに最適なテンソルフォーマット(NCHW)へ変換
Layout Optimizer
tensorflow/core/grappler/optimizers/layout_optimizer.cc
Grappler
CPU GPU
NHWC NHWC
CPU
Trans
pose
NHWC NHWC
↓
NCHW
GPU
NHWC
テンソルフォーマットを変換
❖ GPUのメモリをCPUへ退避し、ピークメモリ使用量削減
Memory Optimizer①
tensorflow/core/grappler/optimizers/memory_optimizer.cc
Grappler
ピークメモリ使用量が高い
GPU
↓
CPU
CPU
↓
GPU
一時的にCPUへ
メモリを退避
❖ 勾配計算に必要なデータを再計算
Memory Optimizer②
tensorflow/core/grappler/optimizers/memory_optimizer.cc
Grappler
Op1 Op2
Op
Grad
Op1 Op2
Op1
Grad
Op1
再計算
❖ 計算の中間結果を保持することで、メモリ使用量削減
Memory Optimizer③
tensorflow/core/grappler/optimizers/memory_optimizer.cc
Grappler
AddN AddN
中間結果を保持
❖ 算術演算を簡易化
Arithmetic Optimizer
tensorflow/core/grappler/optimizers/arithmetic_optimizer.cc
Grappler
Add
Add
AddN
例:Add(Add(x, y), z) ⇒ AddN(x, y, z)
❖ 計算グラフを複製し、各GPUで並列実行
Auto Parallel
tensorflow/core/grappler/optimizers/auto_parallel.cc
Grappler
GPU #1 GPU #2
❖ 実行されない分岐先のノードを削除
Loop Optimizer①
tensorflow/core/grappler/optimizers/loop_optimizer.cc
Grappler
Switch
True
Op
False
Op
Merge
True
Op
必ずTrueOpが
実行される場合
❖ ループ内不変ノードをループ外へ移動
Loop Optimizer②
tensorflow/core/grappler/optimizers/loop_optimizer.cc
Grappler
While While
ループ内不変 ループ外へ移動
❖ Control Edge(データ移動がないエッジ)の最適化
Dependency Optimizer
tensorflow/core/grappler/optimizers/dependency_optimizer.cc
Grappler
Identity
1
3
2
1
3
2
Control Edge
4 4
1の出力テンソルを
そのまま4に流す
1~3実行後に実行
1~3実行後に実行
❖ デバッグ用途のノードをNoOp(何もしない)に置換
Debug Stripper
tensorflow/core/grappler/optimizers/debug_stripper.cc
Grappler
Print NoOp
Scoped Allocator Optimizer
tensorflow/core/grappler/optimizers/scoped_allocator_optimizer.cc
Grappler
❖ メモリをプーリングし、メモリ確保&解放時間短縮
2
1
1 2
3
Memory Pool
プールした
メモリから確保
3
❖ 演算効率が良くなるように、CPUでの演算に変更
Pin to Host Optimizer
tensorflow/core/grappler/optimizers/pin_to_host_optimizer.cc
Grappler
Op
Const
Const
GPU
GPU
入力は
CPUメモリを期待
Op
Const
Const
CPU
CPU
デバイス割り当てを
CPUに変更
GraphOptimizer
❖ Common Subexpression Elimination(CSE)
❖ Constant Folding
➢ tensorflow/core/common_runtime/constant_folding.cc
➢ GrapplerのConstant Foldingと同じ
❖ Function Inlining
➢ tensorflow/core/common_runtime/function.cc
➢ GrapplerのFunction Optimizerと同じ
tensorflow/core/common_runtime/graph_optimizer.cc
❖ 演算結果が同じになる演算を共通化
Common SubExpression Elimination
tensorflow/core/graph/optimizer_cse.cc
GraphOptimizer
Add
Add
Add
GraphOptimizationPass
❖ PRE_PLACEMENT
➢ XLA†1
向けのグラフ変形
➢ If/While Lowering
➢ Parallel Concat Optimizer
➢ AccumulateN Optimizer
❖ POST_PLACEMENT
➢ NCCL Replace
❖ POST_REWRITE_FOR_EXEC
➢ XLA向けのグラフ変形
❖ POST_PARTITIONING
➢ Intel MKL向けの最適化
グラフ構築
デバイス割り当て
Grappler
グラフ分割
GraphOptimizer
†1 グラフコンパイラ
❖ PrimitiveなControl Flow Opsから、If/Whileへの変換
➢ 「If/While Lowering」の逆変換
➢ 後発となるXLAは、If/Whileの方が扱いやすいため
❖ TensorFlowのグラフから、XLAのグラフへ変換
XLA
GraphOptimizationPass
tensorflow/compiler/tf2xla/functionalize_control_flow_pass_registration.cc
tensorflow/compiler/jit/jit_compilation_pass_registration.cc
❖ If/Whileを、PrimitiveなControl Flow Opsに変換
➢ If ⇒ Switch, Merge
➢ While ⇒ Switch, Merge, Enter, Exit, NextIteration, LoopCond
❖ TensorFlowの内部処理に合わせるための変形処理
If/While Lowering
tensorflow/core/common_runtime/lower_if_while.cc
GraphOptimizationPass
❖ ParallelConcat演算を実現するための計算グラフ変形
➢ ParallelConcat:並列版のConcat処理
Parallel Concat Optimizer
tensorflow/core/common_runtime/parallel_concat_optimizer.cc
GraphOptimizationPass
A
B
Parallel
Concat
A
B
_Parallel
Concat
Update
_Parallel
Concat
Update
_Parallel
Concat
Start
部分ごとに
Concatを
並列実行
Identity
❖ AccumulateN演算を実現するための計算グラフ変形
➢ AccumulateN:AddNと同じ演算だが、入力が揃ったところから演算
AccumulateN Optimizer
tensorflow/core/common_runtime/accumulate_n_optimizer.cc
GraphOptimizationPass
A
B
Accumu
lateN
V2
A
B
Assign
Add
Assign
Add
Assign
Const
(0)
入力が揃った
ところから
実行可能
❖ ncclによるGPU間集合通信を実現するための計算グラフ変形
➢ nccl:NVIDIAが提供する、GPU向けの集合通信用ライブラリ
Nccl Replace
tensorflow/core/nccl/nccl_rewrite.cc
GraphOptimizationPass
Nccl
Reduce
_Nccl
Broadcast
Send
_Nccl
Broadcast
Send
_Nccl
Broadcast
Recv
❖ ノードを結合し、Intel MKLで得意な演算に変更
MKL①
tensorflow/core/graph/mkl_layout_pass.cc
GraphOptimizationPass
Conv
2D
Bias
Add
_Mkl
Conv2D
WithBias
ノードを結合して、
Intel MKLに最適な演算に変更
❖ テンソルフォーマット変換(Intel MKL ⇒ TensorFlow)
MKL②
tensorflow/core/graph/mkl_tfconversion_pass.cc
GraphOptimizationPass
MKL
Op
Op1
Tensor
Flow
Intel
MKL
↓
Tenosor
Flow
Intel
MKL
MKL
Op
MklTo
TF
Intel
MKL
Op1
Tensor
Flow
Intel MKLの
テンソルフォーマットから戻す
最適化の有効/無効を制御する
❖ ConfigProtoを使って、最適化の有効/無効を制御可能
➢ Grappler: ConfigProto.graph_options.rewrite_options
➢ GraphOptimizer: ConfigProto.graph_options.optimizer_options
import tensorflow as tf
from tensorflow.core.protobuf import config_pb2
from tensorflow.core.protobuf import rewriter_config_pb2
cfg = config_pb2.ConfigProto()
cfg.graph_options.rewrite_options.constant_folding =
rewriter_config_pb2.RewriterConfig.OFF
cfg.graph_options.optimizer_options.opt_level =
config_pb2.OptimizerOptions.L0
with tf.Session(config=cfg) as sess:
sess.run(...)
GraphOptimizer「Constant Folding」
無効化
Grappler「Constant Folding」
無効化
tf.SessionにConfigProtoを渡す
❖ Constant Folding:無効
❖ Function Optimizer:有効
最適化の無効化を確認する
サブグラフ
呼び出し処理
サブグラフ呼び出し処理は
消えている
最適化前
(p11で紹介した計算グラフ) 最適化後
全入力がConstの
演算はそのまま
全入力が
Constの演算
TensorFlow 2.0では
どうなる?
Eager ModeとGraph Mode
❖ TensorFlow 2.0では、Eager Modeがデフォルト化
➢ Eager Modeでは、最適化処理が適用されない
❖ tf.functionを利用することで、Graph Modeで動作可能
➢ Graph Modeでは、従来の最適化処理が適用される
import tensorflow as tf
@tf.function
def graph_mode():
a = tf.constant(1.5)
b = tf.constant(2.7)
c = a * b
d = a + b
return c + d
out = graph_mode()
GraphModeで動作するため、
最適化処理も適用される
❖ Design Documentに変更方針が記載されている
➢ TensorFlow Design Document(tensorflow/community)
https://github.com/tensorflow/community
➢ Design Documentから見たTensorFlow 2.0の変更点
https://qiita.com/nuka/items/6966efeddceb96012819
TensorFlow 2.0の内部構造
❖ 最適化後の計算グラフは、RunMetadataを使って
確認できる
まとめ
❖ 計算グラフの最適化を行う仕組みは、3つある
➢ 計算グラフ分割前の最適化「Grappler」
➢ 計算グラフ分割後の最適化「GraphOptimizer」
➢ 各計算グラフ変形の前後に行う最適化「GraphOptimizationPass」
❖ TensorFlow 2.0でtf.functionを利用することにより、
最適化処理を活用できる
参考資料
❖ QiitaにもTensorFlowの最適化処理をまとめています
➢ TensorFlow内部構造解析 (4.4) 計算グラフ最適化処理1 Grappler
https://qiita.com/nuka/items/f1b0fe9c820e4d5f80cc
➢ TensorFlow内部構造解析 (4.6) 計算グラフ最適化処理2
GraphOptimizationPass
https://qiita.com/nuka/items/808fbec073f97be8b872
➢ TensorFlow内部構造解析 (4.7) 計算グラフ最適化処理3 GraphOptimizer
https://qiita.com/nuka/items/1936ad509cd4e68d2fad
宣伝
❖ 技術書典6にて、TechBoosterから頒布予定の技術書に、
「TensorFlowの計算グラフ最適化処理」を寄稿します
➢ https://techbookfest.org/event/tbf06
➢ 日程:2019/4/14(日)11:00-17:00
➢ 場所:池袋サンシャインシティ2F 展示ホールD(文化会館ビル2F)
➢ 主催:TechBooster/達人出版会
おわり

More Related Content

PPTX
[DL輪読会]Pay Attention to MLPs (gMLP)
PDF
Deeplearning輪読会
PPTX
backbone としての timm 入門
PDF
【メタサーベイ】数式ドリブン教師あり学習
PPTX
[DL輪読会]Revisiting Deep Learning Models for Tabular Data (NeurIPS 2021) 表形式デー...
PPTX
【論文紹介】How Powerful are Graph Neural Networks?
PDF
全力解説!Transformer
PDF
三次元点群を取り扱うニューラルネットワークのサーベイ
[DL輪読会]Pay Attention to MLPs (gMLP)
Deeplearning輪読会
backbone としての timm 入門
【メタサーベイ】数式ドリブン教師あり学習
[DL輪読会]Revisiting Deep Learning Models for Tabular Data (NeurIPS 2021) 表形式デー...
【論文紹介】How Powerful are Graph Neural Networks?
全力解説!Transformer
三次元点群を取り扱うニューラルネットワークのサーベイ

What's hot (20)

PDF
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで
PDF
最近のDeep Learning (NLP) 界隈におけるAttention事情
PDF
最適輸送の解き方
PDF
方策勾配型強化学習の基礎と応用
PPTX
分散深層学習 @ NIPS'17
PDF
4 データ間の距離と類似度
PDF
BlackBox モデルの説明性・解釈性技術の実装
PDF
PCAの最終形態GPLVMの解説
PPTX
畳み込みニューラルネットワークの高精度化と高速化
PDF
SSII2022 [TS1] Transformerの最前線〜 畳込みニューラルネットワークの先へ 〜
PDF
Kaggleのテクニック
PDF
[DL輪読会]Understanding Black-box Predictions via Influence Functions
PPTX
モデルアーキテクチャ観点からの高速化2019
PDF
一般化線形モデル (GLM) & 一般化加法モデル(GAM)
PPTX
モデル高速化百選
PPTX
近年のHierarchical Vision Transformer
PDF
Semantic segmentation
PDF
グラフニューラルネットワーク入門
PDF
深層生成モデルと世界モデル(2020/11/20版)
PDF
強化学習その1
深層学習による自然言語処理入門: word2vecからBERT, GPT-3まで
最近のDeep Learning (NLP) 界隈におけるAttention事情
最適輸送の解き方
方策勾配型強化学習の基礎と応用
分散深層学習 @ NIPS'17
4 データ間の距離と類似度
BlackBox モデルの説明性・解釈性技術の実装
PCAの最終形態GPLVMの解説
畳み込みニューラルネットワークの高精度化と高速化
SSII2022 [TS1] Transformerの最前線〜 畳込みニューラルネットワークの先へ 〜
Kaggleのテクニック
[DL輪読会]Understanding Black-box Predictions via Influence Functions
モデルアーキテクチャ観点からの高速化2019
一般化線形モデル (GLM) & 一般化加法モデル(GAM)
モデル高速化百選
近年のHierarchical Vision Transformer
Semantic segmentation
グラフニューラルネットワーク入門
深層生成モデルと世界モデル(2020/11/20版)
強化学習その1
Ad

Similar to TensorFlow計算グラフ最適化処理 (20)

PDF
TensorFlowの使い方(in Japanese)
PDF
TensorFlow Operation 作ってみた
PPTX
C# 7.2 with .NET Core 2.1
PDF
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正前 typoあり)」
PDF
Mesh tensorflow
PPTX
nftables: the Next Generation Firewall in Linux
PDF
Tensorflow Liteの量子化アーキテクチャ
PDF
ゆるふわLinux-HA 〜PostgreSQL編〜
PDF
今最もアツイdistribution Gentoo Linuxについて
PDF
TensroFlow XLA : JIT編 (r1.3版)
PPTX
ヘネシー&パターソン7.4
PDF
ログ収集フレームワークの新バージョン「FlumeNG」
PDF
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
PDF
perfを使ったPostgreSQLの解析(後編)
PPTX
[DL Hacks]色々と進化しているTensorFlow - 紹介編 -
PDF
Introduction to Chainer (LL Ring Recursive)
PDF
DAシンポジウム2019招待講演「深層学習モデルの高速なTraining/InferenceのためのHW/SW技術」 金子紘也hare
PDF
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
PDF
シンプルでシステマチックな Linux 性能分析方法
PDF
Chainerの使い方と自然言語処理への応用
TensorFlowの使い方(in Japanese)
TensorFlow Operation 作ってみた
C# 7.2 with .NET Core 2.1
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正前 typoあり)」
Mesh tensorflow
nftables: the Next Generation Firewall in Linux
Tensorflow Liteの量子化アーキテクチャ
ゆるふわLinux-HA 〜PostgreSQL編〜
今最もアツイdistribution Gentoo Linuxについて
TensroFlow XLA : JIT編 (r1.3版)
ヘネシー&パターソン7.4
ログ収集フレームワークの新バージョン「FlumeNG」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
perfを使ったPostgreSQLの解析(後編)
[DL Hacks]色々と進化しているTensorFlow - 紹介編 -
Introduction to Chainer (LL Ring Recursive)
DAシンポジウム2019招待講演「深層学習モデルの高速なTraining/InferenceのためのHW/SW技術」 金子紘也hare
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
シンプルでシステマチックな Linux 性能分析方法
Chainerの使い方と自然言語処理への応用
Ad

TensorFlow計算グラフ最適化処理