דף זה תורגם על ידי Cloud Translation API.
Switch to English

השתמש ב- GPU

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

קוד tf.keras ודגמי tf.keras יפעלו בשקיפות על GPU יחיד ללא צורך בשינויים בקוד.

הדרך הפשוטה ביותר לרוץ במספר GPUs, במכונה אחת או רבות, היא באמצעות אסטרטגיות הפצה .

מדריך זה מיועד למשתמשים שניסו את הגישות הללו ומצאו כי הם זקוקים לשליטה דקה באופן השימוש ב- TensorFlow ב- GPU. כדי ללמוד כיצד לפתור באגים בבעיות ביצועים עבור תרחישים יחידים ורב-גרפיים, עיין במדריך ביצועי ביצועי TensorFlow GPU .

להכין

ודא שהתקנת גירסת ה- GPU האחרונה של TensorFlow.

import tensorflow as tf
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
Num GPUs Available:  2

סקירה כללית

TensorFlow תומך בהפעלת חישובים על מגוון סוגי מכשירים, כולל מעבד ו- GPU. הם מיוצגים עם מזהי מחרוזות לדוגמא:

  • "/device:CPU:0" : המעבד של המחשב שלך.
  • "/GPU:0" : סימון יד קצר עבור ה- GPU הראשון של המחשב שלך הנראה ל- TensorFlow.
  • "/job:localhost/replica:0/task:0/device:GPU:1" : השם המלא לחלוטין של ה- GPU השני של המחשב שלך הגלוי ל- TensorFlow.

אם בפעולת TensorFlow יש גם יישומי מעבד וגם GPU, כברירת מחדל מכשירי ה- GPU יקבלו עדיפות כאשר הפעולה מוקצית למכשיר. לדוגמה, ל- tf.matmul יש גם tf.matmul מעבד וגם GPU. במערכת עם CPU:0 ו- GPU:0 , מכשיר GPU:0 ייבחר להפעלת tf.matmul אלא אם כן תבקש במפורש להריץ אותו במכשיר אחר.

מיקום מכשיר רישום

כדי לגלות לאילו מכשירים tf.debugging.set_log_device_placement(True) את tf.debugging.set_log_device_placement(True) , שים את tf.debugging.set_log_device_placement(True) כהצהרה הראשונה של התוכנית שלך. הפעלת רישום מיקום התקנים גורמת להדפסת הקצאות או פעולות של Tensor.

tf.debugging.set_log_device_placement(True)

# Create some tensors
a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
c = tf.matmul(a, b)

print(c)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

הקוד שלעיל ידפיס אינדיקציה שה- MatMul op בוצע ב- GPU:0 .

מיקום מכשיר ידני

אם תרצה with tf.device מסוימת תפעל במכשיר על פי בחירתך במקום מה שנבחר באופן אוטומטי עבורך, תוכל להשתמש with tf.device כדי ליצור הקשר של המכשיר, וכל הפעולות בהקשר זה יפעלו באותו מכשיר ייעודי. .

tf.debugging.set_log_device_placement(True)

# Place tensors on the CPU
with tf.device('/CPU:0'):
  a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
  b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])

# Run on the GPU
c = tf.matmul(a, b)
print(c)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

תראה שעכשיו a ו- b מוקצים CPU:0 . מכיוון שהתקן לא צוין במפורש לפעולת MatMul , זמן הריצה של TensorFlow יבחר מכשיר בהתבסס על הפעולה וההתקנים הזמינים ( GPU:0 בדוגמה זו) ועתיק אוטומטית טנזרים בין התקנים במידת הצורך.

הגבלת צמיחת זיכרון GPU

כברירת מחדל, TensorFlow ממפה כמעט את כל זיכרון ה- GPU של כל ה- GPU (בכפוף ל- CUDA_VISIBLE_DEVICES ) הגלוי לתהליך. זה נעשה כדי להשתמש ביתר יעילות במשאבי זיכרון ה- GPU היקרים יחסית במכשירים על ידי צמצום פיצול הזיכרון. כדי להגביל את TensorFlow לקבוצה ספציפית של GPUs אנו משתמשים בשיטת tf.config.experimental.set_visible_devices .

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only use the first GPU
  try:
    tf.config.experimental.set_visible_devices(gpus[0], 'GPU')
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPU")
  except RuntimeError as e:
    # Visible devices must be set before GPUs have been initialized
    print(e)
2 Physical GPUs, 1 Logical GPU

במקרים מסוימים רצוי שהתהליך יקצה רק קבוצת משנה של הזיכרון הזמין, או רק יגדיל את השימוש בזיכרון לפי הצורך בתהליך. TensorFlow מספק שתי שיטות לשלוט בזה.

האפשרות הראשונה היא להפעיל את צמיחת הזיכרון על ידי קריאה ל- tf.config.experimental.set_memory_growth , המנסה להקצות רק זיכרון GPU ככל שיידרש לצורך הקצאות זמן הריצה: מתחיל להקצות מעט מאוד זיכרון, וככל שהתוכנית מופעלת ו יש צורך בזיכרון GPU נוסף, אנו מרחיבים את אזור זיכרון ה- GPU המוקצה לתהליך TensorFlow. שים לב שאנחנו לא משחררים זיכרון, מכיוון שהוא יכול להוביל לפיצול זיכרון. כדי להפעיל צמיחת זיכרון עבור GPU ספציפי, השתמש בקוד הבא לפני הקצאת טנסורים כלשהם או ביצוע אופ.

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  try:
    # Currently, memory growth needs to be the same across GPUs
    for gpu in gpus:
      tf.config.experimental.set_memory_growth(gpu, True)
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Memory growth must be set before GPUs have been initialized
    print(e)
2 Physical GPUs, 2 Logical GPUs

דרך נוספת לאפשר אפשרות זו היא להגדיר את המשתנה הסביבתי TF_FORCE_GPU_ALLOW_GROWTH true . תצורה זו ספציפית לפלטפורמה.

השיטה השנייה היא קביעת תצורה של מכשיר GPU וירטואלי עם tf.config.experimental.set_virtual_device_configuration והגדרת מגבלה קשה על הזיכרון הכולל להקצאה ב- GPU.

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only allocate 1GB of memory on the first GPU
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Virtual devices must be set before GPUs have been initialized
    print(e)
2 Physical GPUs, 2 Logical GPUs

זה שימושי אם ברצונך לאגד באמת את כמות זיכרון ה- GPU הזמין לתהליך TensorFlow. זה נוהג נפוץ לפיתוח מקומי כאשר ה- GPU משותף עם יישומים אחרים כגון ממשק משתמש של תחנת עבודה.

שימוש ב- GPU יחיד במערכת מרובת GPU

אם יש לך יותר מ- GPU אחד במערכת שלך, ה- GPU עם המזהה הנמוך ביותר ייבחר כברירת מחדל. אם תרצה לרוץ על GPU אחר, תצטרך לציין את ההעדפה במפורש:

tf.debugging.set_log_device_placement(True)

try:
  # Specify an invalid GPU device
  with tf.device('/device:GPU:2'):
    a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
    b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
    c = tf.matmul(a, b)
except RuntimeError as e:
  print(e)
/job:localhost/replica:0/task:0/device:GPU:2 unknown device.

אם המכשיר שציינת אינו קיים, תקבל RuntimeError : .../device:GPU:2 unknown device .

אם תרצה ש- TensorFlow יבחר באופן אוטומטי מכשיר קיים ותומך להפעלת הפעולות במקרה tf.config.set_soft_device_placement(True) לא קיים, תוכל להתקשר ל- tf.config.set_soft_device_placement(True) .

tf.config.set_soft_device_placement(True)
tf.debugging.set_log_device_placement(True)

# Creates some tensors
a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
c = tf.matmul(a, b)

print(c)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

שימוש במספר GPUs

פיתוח למספר GPUs יאפשר למודל להתמקד עם המשאבים הנוספים. אם מתפתחים במערכת עם GPU יחיד, אנו יכולים לדמות מספר GPUs עם מכשירים וירטואליים. זה מאפשר בדיקה קלה של הגדרות מרובות GPU ללא צורך במשאבים נוספים.

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Create 2 virtual GPUs with 1GB memory each
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024),
         tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPU,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Virtual devices must be set before GPUs have been initialized
    print(e)
2 Physical GPU, 3 Logical GPUs

ברגע שיש לנו מספר GPUs לוגיים זמינים לזמן הריצה, אנו יכולים להשתמש ב- GPUs המרובים בעזרת tf.distribute.Strategy או עם מיקום ידני.

עם tf.distribute.Strategy

השיטה הטובה ביותר לשימוש במספר GPUs היא להשתמש ב- tf.distribute.Strategy . הנה דוגמה פשוטה:

tf.debugging.set_log_device_placement(True)

strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
  inputs = tf.keras.layers.Input(shape=(1,))
  predictions = tf.keras.layers.Dense(1)(inputs)
  model = tf.keras.models.Model(inputs=inputs, outputs=predictions)
  model.compile(loss='mse',
                optimizer=tf.keras.optimizers.SGD(learning_rate=0.2))
Executing op RandomUniform in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Sub in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Mul in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Add in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarIsInitializedOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op LogicalNot in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Assert in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op ReadVariableOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op Identity in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op VarIsInitializedOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op LogicalNot in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op Assert in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op AssignVariableOp in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op Reshape in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op VarHandleOp in device /job:localhost/replica:0/task:0/device:GPU:1

תוכנית זו תריץ עותק של המודל שלך על כל GPU, ויחלק את נתוני הקלט ביניהם, המכונים גם " מקביליות נתונים ".

למידע נוסף על אסטרטגיות הפצה, עיין במדריך כאן .

מיקום ידני

tf.distribute.Strategy עובד מתחת למכסה המנוע על ידי שכפול חישוב על פני מכשירים. אתה יכול ליישם שכפול ידנית על ידי בניית המודל שלך על כל GPU. לדוגמה:

tf.debugging.set_log_device_placement(True)

gpus = tf.config.experimental.list_logical_devices('GPU')
if gpus:
  # Replicate your computation on multiple GPUs
  c = []
  for gpu in gpus:
    with tf.device(gpu.name):
      a = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
      b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
      c.append(tf.matmul(a, b))

  with tf.device('/CPU:0'):
    matmul_sum = tf.add_n(c)

  print(matmul_sum)
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:0
Executing op MatMul in device /job:localhost/replica:0/task:0/device:GPU:1
Executing op AddN in device /job:localhost/replica:0/task:0/device:CPU:0
tf.Tensor(
[[ 44.  56.]
 [ 98. 128.]], shape=(2, 2), dtype=float32)