1. 程式人生 > >學習筆記TF062:TensorFlow線性代數編譯框架XLA

學習筆記TF062:TensorFlow線性代數編譯框架XLA

per acc tmp form 緩沖區 適合 correct raw prot

XLA(Accelerated Linear Algebra),線性代數領域專用編譯器(demain-specific compiler),優化TensorFlow計算。即時(just-in-time,JIT)編譯或提前(ahead-of-time,AOT)編譯實現XLA,有助於硬件加速。XLA還在試驗階段。https://www.tensorflow.org/versions/master/experimental/xla/ 。

XLA優勢。線性代數領域專用編譯器,優化TensorFlow計算的執行速度(編譯子圖減少生命周期較短操作執行時間,融合管道化操作減少內存占用)、內存使用(分析、規劃內存使用需求,消除許多中間結果緩存)、自定義操作依賴(提高自動化融合底層操作low-level op性能,達到手動融合自定義操作custom op效果)、移動端內存占用(提前AOT編譯子圖減少TensorFlow執行時間,共享頭文件對被其他程序直接鏈接)、可移植性方面(為新硬件開發新後端,TensorFlow不需要更改很多代碼用在新硬件設備上)。

XLA工作原理。LLVM編譯器框架系統,C++編寫,優化任意編程語言縮寫程序編譯時間(compile time)、鏈接時間(link time)、運行時間(run time)、空閑時間(idle time)。前端解析、驗證、論斷輸入代碼錯誤,解析代碼轉換LLVM中間表示(intermdediate representation,IR)。IR分析、優化改進代碼,發送到代碼生成器,產生本地機器代碼。三相設計LLVM實現。最重要,LLVM IR。編譯器IR表示代碼。C->Clang C/C++/ObjC前端、Fortran->llvm-gcc前端、Haskell->GHC前端 LLVM IR-> LLVM 優化器 ->LLVM IR LLVM X86後端->X86、LLVM PowerPC後端->PowerPC、LLVM ARM後端->ARM。http://www.aosabook.org/en/llvm.html 。
XLA輸入語言HLO IR,XLA HLO定義圖形,編譯成各種體系結構機器指令。編譯過程。XLA HLO->目標無關優化分析->XLA HLO->XLA後端->目標相關優化分析->目標特定代碼生成。XLA首先進行目標無關優化分析(公共子表達式消除common subexpression elimination CSE,目標無關操作融合,運行時內存緩沖區分析)。XLA將HLO計算發送到後端。後端執行進一步HLO級目標不相關優化分析。XLA GPU後端執行對GPU編程模型有益操作融合,確定計算劃分成流。生成目標特定代碼。XLA CPU、GPU後端用LLVM中間表示、優化、代碼生成。後端用LLVM IR表示XLA HLO計算。XLA 支持x86-64?NVIDIA GPU JIT編譯,x86-64?ARM AOT編譯。AOT更適合移動、嵌入式深度學習應用。

JIT編譯方式。XLA編譯、運行TensorFlow計算圖一部分。XLA 將多個操作(內核)融合到少量編譯內核,融合操作符減少存儲器帶寬提高性能。XLA 運行TensorFlow計算方法。一,打開CPU、GPU設備JIT編譯。二,操作符放在XLA_CPU、XLA_GPU設備。
打開JIT編譯。在會話打開。把所有可能操作符編程成XLA計算。

config = tf.ConfigProto()
config.graph_options.optimizer_options.global_jit_level = tf.OptimizerOptions.ON_1
sess = tf.Session(config=config)
為一個或多個操作符手動打開JIT編譯。屬性_XlaCompile = true標記編譯操作符。

jit_scope = tf.contrib.compiler.jit.experimental_jit_scope
x = tf.placeholder(np.float32)
with jit_scope():
y = tf.add(x, x)
操作符放在XLA設備。有效設備XLA_CPU、XLA_GPU:

with tf.device("/job:localhost/replica:0/task:0/device:XLA_GPU:0"):
output = tf.add(input1, input2)

JIT編譯MNIST實現。https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist_softmax_xla.py 。
不使用XLA運行。

python mnist_softmax_xla.py --xla=false
運行完成生成時間線文件timeline.ctf.json,用Chrome跟蹤事件分析器 chrome://tracing,打開時間線文件,呈現時間線。左側列出GPU,可以看操作符時間消耗情況。
用XLA訓練模型。

TF_XLA_FLAGS=--xla_generate_hlo_graph=.* python mnist_softmax_xla.py
XLA框架處於試驗階段,AOT主要應用場景內存較小嵌入式設備、手機、樹莓派。

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import sys
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
from tensorflow.python.client import timeline
FLAGS = None
def main(_):
  # Import data
  mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
  # Create the model
  x = tf.placeholder(tf.float32, [None, 784])
  w = tf.Variable(tf.zeros([784, 10]))
  b = tf.Variable(tf.zeros([10]))
  y = tf.matmul(x, w) + b
  # Define loss and optimizer
  y_ = tf.placeholder(tf.float32, [None, 10])
  # The raw formulation of cross-entropy,
  #
  #   tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(tf.nn.softmax(y)),
  #                                 reduction_indices=[1]))
  #
  # can be numerically unstable.
  #
  # So here we use tf.nn.softmax_cross_entropy_with_logits on the raw
  # outputs of ‘y‘, and then average across the batch.
  cross_entropy = tf.reduce_mean(
      tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))
  train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
  config = tf.ConfigProto()
  jit_level = 0
  if FLAGS.xla:
    # Turns on XLA JIT compilation.
    # 開啟XLA JIT編譯
    jit_level = tf.OptimizerOptions.ON_1
  config.graph_options.optimizer_options.global_jit_level = jit_level
  run_metadata = tf.RunMetadata()
  sess = tf.Session(config=config)
  tf.global_variables_initializer().run(session=sess)
  # Train
  # 訓練
  train_loops = 1000
  for i in range(train_loops):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    # Create a timeline for the last loop and export to json to view with
    # chrome://tracing/.
    # 在最後一次循環創建時間線文件,用chrome://tracing/打開分析
    if i == train_loops - 1:
      sess.run(train_step,
               feed_dict={x: batch_xs,
                          y_: batch_ys},
               options=tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE),
               run_metadata=run_metadata)
      trace = timeline.Timeline(step_stats=run_metadata.step_stats)
      with open(timeline.ctf.json, w) as trace_file:
        trace_file.write(trace.generate_chrome_trace_format())
    else:
      sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
  # Test trained model
  correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
  accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
  print(sess.run(accuracy,
                 feed_dict={x: mnist.test.images,
                            y_: mnist.test.labels}))
  sess.close()
if __name__ == __main__:
  parser = argparse.ArgumentParser()
  parser.add_argument(
      --data_dir,
      type=str,
      default=/tmp/tensorflow/mnist/input_data,
      help=Directory for storing input data)
  parser.add_argument(
      --xla, type=bool, default=True, help=Turn xla via JIT on)
  FLAGS, unparsed = parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)

參考資料:
《TensorFlow技術解析與實戰》

歡迎推薦上海機器學習工作機會,我的微信:qingxingfengzi

學習筆記TF062:TensorFlow線性代數編譯框架XLA