ML Community Day คือวันที่ 9 พฤศจิกายน! ร่วมกับเราสำหรับการปรับปรุงจาก TensorFlow, JAX และอื่น ๆ เรียนรู้เพิ่มเติม

การเพิ่มประสิทธิภาพกราฟ TensorFlow ด้วย Grappler

ดูบน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดโน๊ตบุ๊ค

ภาพรวม

TensorFlow ใช้ทั้งกราฟและการดำเนินการที่กระตือรือร้นเพื่อดำเนินการคำนวณ tf.Graph มีชุดของ tf.Operation วัตถุ (OPS) ซึ่งเป็นตัวแทนของหน่วยของการคำนวณและ tf.Tensor วัตถุซึ่งเป็นตัวแทนของหน่วยของข้อมูลที่ไหลระหว่างปฏิบัติการ

Grappler คือระบบการเพิ่มประสิทธิภาพกราฟเริ่มต้นในรันไทม์ TensorFlow Grappler ใช้เพิ่มประสิทธิภาพในโหมดกราฟ (ภายใน tf.function ) เพื่อปรับปรุงประสิทธิภาพของการคำนวณ TensorFlow ของคุณผ่าน simplifications กราฟและการเพิ่มประสิทธิภาพระดับสูงอื่น ๆ เช่นอินไลน์ร่างกายของฟังก์ชั่นเพื่อเปิดใช้งานการเพิ่มประสิทธิภาพระหว่างขั้นตอน การเพิ่มประสิทธิภาพ tf.Graph ยังช่วยลดการใช้หน่วยความจำสูงสุดอุปกรณ์และปรับปรุงการใช้ฮาร์ดแวร์โดยการเพิ่มประสิทธิภาพการทำแผนที่ของโหนดกราฟทรัพยากรการคำนวณ

ใช้ tf.config.optimizer.set_experimental_options() สำหรับการควบคุมปลีกย่อยมากกว่าคุณ tf.Graph การเพิ่มประสิทธิภาพ

เครื่องมือเพิ่มประสิทธิภาพกราฟที่มีอยู่

ดำเนินการ Grappler กราฟการเพิ่มประสิทธิภาพผ่านโปรแกรมควบคุมระดับบนสุดที่เรียกว่า MetaOptimizer เครื่องมือเพิ่มประสิทธิภาพกราฟต่อไปนี้ใช้ได้กับ TensorFlow:

  • เพิ่มประสิทธิภาพการพับอย่างต่อเนื่อง - Statically อนุมานค่าของเทนเซอร์เมื่อเป็นไปได้โดยการพับโหนดคงที่ในกราฟและ materializes ผลโดยใช้ค่าคงที่
  • เพิ่มประสิทธิภาพเลขคณิต - ง่ายดำเนินการทางคณิตศาสตร์โดยการกำจัด subexpressions ร่วมกันและลดความซับซ้อนของงบเลขคณิต
  • รูปแบบการเพิ่มประสิทธิภาพ - เพิ่มประสิทธิภาพเมตริกซ์รูปแบบในการดำเนินการรูปแบบข้อมูลการดำเนินงานขึ้นเช่น convolutions มีประสิทธิภาพมากขึ้น
  • เพิ่มประสิทธิภาพ Remapper - subgraphs remaps เข้าสู่การใช้งานมีประสิทธิภาพมากขึ้นโดยการเปลี่ยนทั่วไปที่เกิดขึ้นกับ subgraphs Optimized ผสมเมล็ดเสาหิน
  • เพิ่มประสิทธิภาพหน่วยความจำ - การวิเคราะห์กราฟในการตรวจสอบการใช้งานหน่วยความจำสูงสุดสำหรับแต่ละการดำเนินงานและแทรก CPU-GPU ดำเนินการคัดลอกหน่วยความจำสำหรับการแลกเปลี่ยนหน่วยความจำ GPU ซีพียูเพื่อลดการใช้หน่วยความจำสูงสุด
  • เพิ่มประสิทธิภาพการพึ่งพา - ลบหรือจัดเรียงควบคุมการอ้างอิงเพื่อตัดเส้นทางที่สำคัญสำหรับขั้นตอนรูปแบบหรือช่วยเพิ่มประสิทธิภาพอื่น ๆ ยังลบโหนดที่ไม่มีประสิทธิภาพเช่น Identity
  • การตัดแต่งกิ่งเพิ่มประสิทธิภาพ - โหนดลูกพรุนที่ไม่มีผลกระทบต่อการส่งออกจากกราฟ โดยปกติจะดำเนินการก่อนเพื่อลดขนาดของกราฟและเร่งการประมวลผลใน Grappler pass อื่นๆ
  • เพิ่มประสิทธิภาพฟังก์ชั่น - เพิ่มประสิทธิภาพการทำงานของห้องสมุดโปรแกรม TensorFlow และ inlines ทำงานร่างกายเพื่อเปิดใช้งานการเพิ่มประสิทธิภาพระหว่างขั้นตอนอื่น ๆ
  • เพิ่มประสิทธิภาพรูปร่าง - ปรับการ subgraphs ที่ทำงานในรูปทรงและรูปร่างข้อมูลที่เกี่ยวข้อง
  • Autoparallel เพิ่มประสิทธิภาพ - parallelizes กราฟโดยแยกตามมิติชุดโดยอัตโนมัติ เครื่องมือเพิ่มประสิทธิภาพนี้ถูกปิดโดยค่าเริ่มต้น
  • เพิ่มประสิทธิภาพ Loop - เพิ่มประสิทธิภาพการควบคุมการไหลของกราฟโดยชู subgraphs ห่วงคงออกจากลูปและการดำเนินงานโดยการเอาสแต็คซ้ำซ้อนในลูป ยังปรับลูปให้เหมาะสมด้วยจำนวนการเดินทางที่ทราบแบบสถิตและลบกิ่งที่หยุดทำงานที่ทราบแบบสถิตในเงื่อนไข
  • เพิ่มประสิทธิภาพการจัดสรรขอบเขต - เปิดตัวกำหนดขอบเขต allocators เพื่อลดการเคลื่อนไหวของข้อมูลและการที่จะรวมการดำเนินการบางอย่าง
  • ขาเพื่อเพิ่มประสิทธิภาพโฮสต์ - แลกเปลี่ยนการดำเนินงานเล็ก ๆ บนซีพียู เครื่องมือเพิ่มประสิทธิภาพนี้ถูกปิดโดยค่าเริ่มต้น
  • รถยนต์เพิ่มประสิทธิภาพความแม่นยำผสม - แปลงชนิดข้อมูลที่จะ float16 ที่ใช้บังคับกับการปรับปรุงประสิทธิภาพการทำงาน ปัจจุบันใช้ได้กับ GPU เท่านั้น
  • เต้นระบำเปลื้องผ้า Debug - โหนดแถบเกี่ยวข้องกับการดำเนินการแก้จุดบกพร่องเช่น tf.debugging.Assert , tf.debugging.check_numerics และ tf.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.0018392090000816097 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.0006749789999958011 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)
2021-09-22 20:34:55.871238: E tensorflow/core/kernels/check_numerics_op.cc:292] abnormal_detected_host @0x7f4878e00100 = {0, 1} Bad!
Traceback (most recent call last):
  File "/tmp/ipykernel_22954/3616845043.py", line 4, in <module>
    test_func(p1)
  File "/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 885, in __call__
    result = self._call(*args, **kwds)
tensorflow.python.framework.errors_impl.InvalidArgumentError:  Bad! : Tensor had Inf values
     [[node CheckNumerics (defined at tmp/ipykernel_22954/2241890286.py:5) ]] [Op:__inference_simple_func_131]

Errors may have originated from an input operation.
Input Source operations connected to node CheckNumerics:
 input_arg (defined at tmp/ipykernel_22954/3616845043.py:4)

Function call stack:
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 กราฟการเพิ่มประสิทธิภาพ