本頁面由 Cloud Translation API 翻譯而成。
Switch to English

使用Grappler優化TensorFlow圖

在TensorFlow.org上查看 在Google Colab中運行 在GitHub上查看源代碼 下載筆記本

總覽

TensorFlow同時使用圖形執行和急切執行來執行計算。一個tf.Graph包含一組代表計算單位的tf.Operation對象(ops)和一tf.Tensor代表在ops之間流動的數據單位的tf.Tensor對象。

Grappler是TensorFlow運行時中的默認圖形優化系統。 Grappler在圖模式下( tf.function內)應用優化,以通過圖簡化和其他高級優化(例如內聯函數體以啟用過程間優化)來提高TensorFlow計算的性能。通過優化圖節點到計算資源的映射,優化tf.Graph還可以減少設備峰值內存使用量並提高硬件利用率。

使用tf.config.optimizer.set_experimental_options()可以更好地控制tf.Graph優化。

可用的圖形優化器

Grappler通過稱為MetaOptimizer的頂級驅動程序執行圖形優化。以下圖表優化器可用於TensorFlow:

  • 常量折疊優化器-盡可能通過折疊圖中的常量節點來靜態推斷張量的值,並使用常量實現結果。
  • 算術優化器-通過消除常見的子表達式並簡化算術語句來簡化算術運算。
  • 佈局優化器-優化張量佈局以更有效地執行數據格式相關的操作,例如卷積。
  • 重新映射優化器-通過將常見的子圖替換為優化的融合單片內核,將子圖重新映射到更有效的實現上。
  • 內存優化器-分析該圖以檢查每個操作的峰值內存使用情況,並插入CPU-GPU內存複製操作以將GPU內存交換到CPU,以減少峰值內存使用情況。
  • 依賴優化器-刪除或重新排列控件依賴關係,以縮短模型步驟的關鍵路徑或啟用其他優化。還刪除實際上是無操作的節點,例如身份。
  • 修剪優化器-修剪對圖形輸出沒有影響的節點。通常首先運行它以減小圖形的大小並加快其他Grappler通道中的處理速度。
  • 函數優化器-優化TensorFlow程序的函數庫,並內聯函數主體以啟用其他過程間優化。
  • 形狀優化器-優化對形狀和形狀相關信息進行操作的子圖。
  • 自動並行優化器-通過沿批處理維度拆分來自動並行化圖形。默認情況下,此優化器處於關閉狀態。
  • 循環優化器-通過將循環不變的子圖提升到循環外並通過刪除循環中的冗餘堆棧操作來優化圖形控制流程。還使用靜態已知的跳閘計數優化循環,並刪除條件中的靜態已知的無效分支。
  • 範圍分配器優化器-引入範圍分配器以減少數據移動並合併某些操作。
  • 固定到主機優化器-將小的操作交換到CPU上。默認情況下,此優化器處於關閉狀態。
  • 自動混合精度優化器-在適用的情況下將數據類型轉換為float16以提高性能。目前僅適用於GPU。
  • 調試剝離器-從圖中剝離與調試操作有關的節點,例如tf.debugging.Asserttf.debugging.check_numericstf.print 。默認情況下,此優化器處於關閉狀態。

建立

 import numpy as np
import timeit
import traceback
import contextlib


import tensorflow as tf
 

創建上下文管理器以輕鬆切換優化器狀態。

 @contextlib.contextmanager
def options(options):
  old_opts = tf.config.optimizer.get_experimental_options()
  tf.config.optimizer.set_experimental_options(options)
  try:
    yield
  finally:
    tf.config.optimizer.set_experimental_options(old_opts)
 

比較使用和不使用Grappler的執行性能

TensorFlow 2及更高版本默認情況下會急切執行。使用tf.function將默認執行切換為圖形模式。 Grappler在後台自動運行,以應用上述圖形優化並提高執行性能。

恆定折疊優化器

作為一個初步的示例,考慮一個對常量執行運算並返回輸出的函數。

 def test_function_1():
  @tf.function
  def simple_function(input_arg):
    print('Tracing!')
    a = tf.constant(np.random.randn(2000,2000), dtype = tf.float32)
    c = a
    for n in range(50):
      c = c@a
    return tf.reduce_mean(c+input_arg)

  return simple_function
 

關閉常量折疊優化器並執行以下功能:

 with options({'constant_folding': False}):
  print(tf.config.optimizer.get_experimental_options())
  simple_function = test_function_1()
  # Trace once
  x = tf.constant(2.2)
  simple_function(x)
  print("Vanilla execution:", timeit.timeit(lambda: simple_function(x), number = 1), "s")
 
{'constant_folding': False, 'disable_model_pruning': False, 'disable_meta_optimizer': False}
Tracing!
Vanilla execution: 0.004905937999865273 s

啟用恆定折疊優化器,然後再次執行功能以觀察功能執行的加速。

 with options({'constant_folding': True}):
  print(tf.config.optimizer.get_experimental_options())
  simple_function = test_function_1()
  # Trace once
  x = tf.constant(2.2)
  simple_function(x)
  print("Constant folded execution:", timeit.timeit(lambda: simple_function(x), number = 1), "s")
 
{'constant_folding': True, 'disable_model_pruning': False, 'disable_meta_optimizer': False}
Tracing!
Constant folded execution: 0.0005699149999145448 s

調試剝離器優化器

考慮一個簡單的函數,該函數檢查其輸入參數的數值並返回它。

 def test_function_2():
  @tf.function
  def simple_func(input_arg):
    output = input_arg
    tf.debugging.check_numerics(output, "Bad!")
    return output
  return simple_func
 

首先,在關閉調試剝離器優化器的情況下執行該功能。

 test_func = test_function_2()
p1 = tf.constant(float('inf'))
try:
  test_func(p1)
except tf.errors.InvalidArgumentError as e:
  traceback.print_exc(limit=2)
 
Traceback (most recent call last):
  File "<ipython-input-8-1ac473fdfbab>", line 4, in <module>
    test_func(p1)
  File "/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py", line 580, in __call__
    result = self._call(*args, **kwds)
tensorflow.python.framework.errors_impl.InvalidArgumentError: 2 root error(s) found.
  (0) Invalid argument:  Bad! : Tensor had Inf values
     [[node CheckNumerics (defined at <ipython-input-7-cbee1561c83e>:5) ]]
     [[Identity/_4]]
  (1) Invalid argument:  Bad! : Tensor had Inf values
     [[node CheckNumerics (defined at <ipython-input-7-cbee1561c83e>:5) ]]
0 successful operations.
0 derived errors ignored. [Op:__inference_simple_func_131]

Errors may have originated from an input operation.
Input Source operations connected to node CheckNumerics:
 input_arg (defined at <ipython-input-8-1ac473fdfbab>:4)

Input Source operations connected to node CheckNumerics:
 input_arg (defined at <ipython-input-8-1ac473fdfbab>:4)

Function call stack:
simple_func -> simple_func


tf.debugging.check_numerics提高,因為一個無效的參數錯誤Inf參數test_func

啟用調試剝離程序優化器,然後再次執行該功能。

 with options({'debug_stripper': True}):
  test_func2 = test_function_2()
  p1 = tf.constant(float('inf'))
  try:
    test_func2(p1)
  except tf.errors.InvalidArgumentError as e:
    traceback.print_exc(limit=2)
 

調試剝離器優化器從圖中剝離tf.debug.check_numerics節點並執行該函數而不會引發任何錯誤。

摘要

TensorFlow運行時在執行之前使用Grappler自動優化圖。使用tf.config.optimizer.set_experimental_options啟用或禁用各種圖形優化器。

有關Grappler的更多信息,請參見TensorFlow圖優化