تحسين الرسم البياني TensorFlow مع Grappler

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

ملخص

يستخدم TensorFlow كلاً من الرسم البياني وعمليات التنفيذ الحثيثة لتنفيذ العمليات الحسابية. A tf.Graph يحتوي على مجموعة من tf.Operation الكائنات (التقاط) التي تمثل وحدة الحساب و tf.Tensor الأشياء التي تمثل وحدة من البيانات التي تتدفق بين مكتب خدمات المشاريع.

Grappler هو نظام تحسين الرسم البياني الافتراضي في وقت تشغيل TensorFlow. الطارح ينطبق تحسينات في وضع الرسم البياني (في tf.function ) لتحسين أداء العمليات الحسابية TensorFlow من خلال تبسيط الرسم البياني وغيرها من التحسينات على مستوى عال مثل رمز مصدر الهيئات وظيفة لتمكين أمثل بين الإجرائية. الاستفادة المثلى من tf.Graph أيضا يقلل من استخدام الذاكرة الذروة الجهاز ويحسن استخدام الأجهزة عن طريق تحسين الخرائط من العقد الرسم البياني للموارد حساب.

استخدام tf.config.optimizer.set_experimental_options() للسيطرة الدقيقة على الخاص tf.Graph أمثل.

أدوات تحسين الرسم البياني المتاحة

ينفذ الطارح الرسم البياني أمثل من خلال برنامج تشغيل مستوى أعلى يسمى MetaOptimizer . تتوفر أدوات تحسين الرسم البياني التالية مع TensorFlow:

  • ثابت محسن للطي - ثابت يستنتج قيمة التنسورات عندما يكون ذلك ممكنا من قبل للطي العقد ثابت في الرسم البياني ويتحقق نتيجة استخدام الثوابت.
  • محسن الحسابي - يبسط العمليات الحسابية من خلال القضاء على subexpressions المشتركة وتبسيط البيانات الحسابية.
  • تخطيط محسن - المثلى موتر تخطيطات لتنفيذ عمليات تعتمد تنسيق البيانات مثل تلافيف أكثر كفاءة.
  • Remapper محسن - Remaps subgraphs على تطبيقات أكثر كفاءة عن طريق استبدال subgraphs شيوعا التي تحدث مع الأمثل حبات متجانسة تنصهر.
  • محسن الذاكرة - يحلل الرسم البياني للتفتيش على استخدام الذاكرة الذروة لكل عملية وإدراج عمليات النسخ الذاكرة CPU-GPU لضخ ذاكرة GPU إلى وحدة المعالجة المركزية للحد من استخدام الذاكرة الذروة.
  • محسن التبعية - يزيل أو تعيد ترتيب تسيطر تبعيات لتقصير المسار الحرج لخطوة نموذج أو تمكن تحسينات أخرى. يزيل أيضًا العقد التي لا تعمل بشكل فعال مثل Identity.
  • تشذيب محسن - البرقوق العقد التي ليس لها أي تأثير على الانتاج من الرسم البياني. عادةً ما يتم تشغيله أولاً لتقليل حجم الرسم البياني وتسريع المعالجة في تمريرات Grappler الأخرى.
  • وظيفة محسن - يحسن مكتبة وظيفة من برنامج TensorFlow وinlines تعمل الهيئات لتمكين تحسينات أخرى بين الإجرائية.
  • محسن شكل - المثلى subgraphs التي تعمل على شكل وشكل المعلومات ذات الصلة.
  • Autoparallel محسن - parallelizes تلقائيا الرسوم البيانية من خلال تقسيم طول البعد دفعة واحدة. يتم إيقاف تشغيل هذا المحسن افتراضيًا.
  • حلقة محسن - يحسن التحكم في التدفق الرسم البياني من خلال رفع subgraphs حلقة ثابتة من الحلقات وعن طريق إزالة عمليات كومة زائدة في الحلقات. يعمل أيضًا على تحسين الحلقات ذات عدد الرحلات المعروفة ثابتًا ويزيل الفروع الميتة المعروفة بشكل ثابت في الحالات الشرطية.
  • راقب مخصص محسن - راقب يدخل موزعي للحد من حركة البيانات وتعزيز بعض العمليات.
  • دبوس إلى محسن المضيفة - عمليات المقايضة صغيرة على وحدة المعالجة المركزية. يتم إيقاف تشغيل هذا المحسن افتراضيًا.
  • السيارات مختلطة الدقة محسن - أنواع البيانات تحويل إلى float16 عند الاقتضاء لتحسين الأداء. ينطبق حاليًا على وحدات معالجة الرسومات فقط.
  • متجرد التصحيح - شرائط العقد المتعلقة بعمليات التصحيح مثل 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.0018649740000000747 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.0004272599999808335 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-08-28 01:24:41.080416: E tensorflow/core/kernels/check_numerics_op.cc:292] abnormal_detected_host @0x7fc850e00100 = {0, 1} Bad!
Traceback (most recent call last):
  File "/tmp/ipykernel_26762/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_26762/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_26762/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 لتمكين أو تعطيل مختلف أبتيميزر الرسم البياني.

لمزيد من المعلومات حول الطارح، انظر TensorFlow الرسم البياني أمثل .