לשמור את התאריך! קלט / פלט של Google חוזר 18-20 במאי הירשם עכשיו
דף זה תורגם על ידי Cloud Translation API.
Switch to English

אופטימיזציה של גרפים TensorFlow עם Grappler

צפה ב- TensorFlow.org הפעל בגוגל קולאב צפה במקור ב- GitHub הורד מחברת

סקירה כללית

TensorFlow משתמש הן בגרף והן בהוצאות להוטות לביצוע חישובים. tf.Graph מכיל קבוצה של אובייקטים tf.Operation (ops) המייצגים יחידות חישוב ו- tf.Tensor אובייקטים המייצגים את יחידות הנתונים tf.Tensor בין ops.

Grappler היא מערכת ברירת המחדל לאופטימיזציה של גרפים בזמן הריצה של TensorFlow. Grappler מיישם אופטימיזציות במצב גרף (בתוך tf.function ) כדי לשפר את הביצועים של חישובי ה- TensorFlow שלך באמצעות פשטות גרפים ואופטימיזציות אחרות ברמה גבוהה, כגון הטמעת גופי פונקציות כדי לאפשר אופטימיזציות בין פרוצדורליות. מיטוב ה- tf.Graph גם מקטין את השימוש בזיכרון בשיא השיא ומשפר את ניצול החומרה על ידי אופטימיזציה של מיפוי צמתים גרפיים לחישוב משאבים.

השתמש ב- tf.config.optimizer.set_experimental_options() לשליטה טובה יותר על אופטימיזציות tf.Graph שלך.

מיטבי גרפים זמינים

גרפלר מבצע אופטימיזציה של גרפים באמצעות מנהל התקן ברמה העליונה בשם MetaOptimizer . מיטוב הגרפים הבא זמין עם TensorFlow:

  • אופטימיזציה לקיפול קבוע - מסיקה סטטיסטית את ערך הטנזורים במידת האפשר על ידי קיפול צמתים קבועים בגרף ומממש את התוצאה באמצעות קבועים.
  • ייעול חשבון - מפשט פעולות חשבון על ידי ביטול ביטויי משנה נפוצים ופישוט הצהרות חשבון.
  • מיטוב פריסות - מייעל פריסות טנסור לביצוע פעולות תלויות בפורמט נתונים כגון פיתולים בצורה יעילה יותר.
  • אופטימיזציית Remapper - ממירה מחדש תצלומי משנה ליישומים יעילים יותר על ידי החלפת תצלומי משנה נפוצים בגרעינים מונוליטיים התמזגו.
  • מיטוב זיכרון - מנתח את הגרף לבדיקת צריכת הזיכרון בשיא לכל פעולה ומכניס פעולות העתקת זיכרון CPU-GPU להחלפת זיכרון GPU למעבד כדי להפחית את השימוש בזיכרון בשיא.
  • מיטוב תלות - מסיר או מארגן מחדש תלות בקרה כדי לקצר את הנתיב הקריטי לשלב המודל או מאפשר אופטימיזציות אחרות. מסיר גם צמתים שהם למעשה ללא אופציות כגון Identity.
  • אופטימיזציה לגיזום - צמתים לגזום שאין להם השפעה על הפלט מהגרף. בדרך כלל הוא מופעל תחילה כדי להקטין את גודל הגרף ולהאיץ את העיבוד במעברי גרפלר אחרים.
  • מיטוב פונקציות - מייעל את ספריית הפונקציות של תוכנית TensorFlow ומטמיע גופי פונקציות כדי לאפשר אופטימיזציות בין פרוצדורליות אחרות.
  • אופטימיזציה של צורה - ממטבת תצלומי משנה הפועלים על מידע הקשור לצורה ולצורה.
  • ייעול מקביל אוטומטי - מקביל גרפים באופן אוטומטי על ידי פיצול לאורך מימד האצווה. אופטימיזציה זו מושבתת כברירת מחדל.
  • אופטימיזציית לולאה - מייעלת את זרימת בקרת הגרפים על ידי הרמת תצלומי לולאה בלתי משתנים מתוך לולאות ועל ידי הסרת פעולות ערימה מיותרות בלולאות. מייעל גם לולאות עם ספירות טיול ידועות ומסיר ענפים מתים ידועים סטטית במזגנים.
  • אופטימיזציה של הקצאת סקופ - מציגה מקצים מקיפים כדי להפחית את תנועת הנתונים ולאיחוד פעולות מסוימות.
  • הצמד למיטוב המארח - מחליף פעולות קטנות למעבד. אופטימיזציה זו מושבתת כברירת מחדל.
  • מיטוב אוטומטי של דיוק מעורב אוטומטי - ממיר סוגי נתונים לצוף 16 היכן שרלוונטי לשיפור הביצועים. נכון לעכשיו חל רק על GPUs.
  • חשפנית ניפוי באגים - tf.debugging.Assert צמתים הקשורים לפעולות ניפוי באגים כגון 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 כדי להחליף את ביצוע ברירת המחדל למצב Graph. 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.0801323579999007 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.0006300529998952697 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 780, 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) ]]
  (1) Invalid argument:  Bad! : Tensor had Inf values
     [[node CheckNumerics (defined at <ipython-input-7-cbee1561c83e>:5) ]]
     [[Identity/_4]]
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 .