หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

ใช้ GPU

ดูใน TensorFlow.org เรียกใช้ใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดสมุดบันทึก

รหัส TensorFlow และรุ่น tf.keras จะทำงานบน GPU ตัวเดียวอย่างโปร่งใสโดยไม่จำเป็นต้องเปลี่ยนแปลงโค้ด

วิธีที่ง่ายที่สุดในการทำงานบน GPU หลายเครื่องบนเครื่องเดียวหรือหลายเครื่องคือการใช้ กลยุทธ์การกระจาย

คู่มือนี้มีไว้สำหรับผู้ใช้ที่ลองใช้แนวทางเหล่านี้แล้วและพบว่าพวกเขาต้องการการควบคุมอย่างละเอียดว่า TensorFlow ใช้ GPU อย่างไร

ติดตั้ง

ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง TensorFlow gpu รุ่นล่าสุดแล้ว

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

ภาพรวม

TensorFlow รองรับการรันการคำนวณบนอุปกรณ์หลากหลายประเภทรวมถึง CPU และ GPU ซึ่งจะแสดงด้วยตัวระบุสตริงเช่น:

  • "/device:CPU:0" : CPU ของเครื่องของคุณ
  • "/GPU:0" : สัญลักษณ์สั้น ๆ สำหรับ GPU ตัวแรกของเครื่องของคุณที่ TensorFlow มองเห็นได้
  • "/job:localhost/replica:0/task:0/device:GPU:1" : ชื่อเต็มของ GPU ตัวที่สองของเครื่องของคุณที่ TensorFlow มองเห็นได้

หากการดำเนินการ TensorFlow มีทั้งการใช้งาน CPU และ GPU โดยค่าเริ่มต้นอุปกรณ์ GPU จะได้รับลำดับความสำคัญเมื่อกำหนดการดำเนินการให้กับอุปกรณ์ ตัวอย่างเช่น tf.matmul มีทั้งเมล็ด CPU และ GPU ในระบบที่มีอุปกรณ์ CPU:0 และ GPU:0 อุปกรณ์ GPU:0 จะถูกเลือกให้เรียกใช้ tf.matmul เว้นแต่คุณจะร้องขออย่างชัดเจนให้เรียกใช้บนอุปกรณ์อื่น

การบันทึกตำแหน่งอุปกรณ์

หากต้องการทราบว่าอุปกรณ์ใดที่คุณกำหนดการทำงานและเทนเซอร์ของคุณให้ใส่ 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 เพื่อสร้างบริบทของอุปกรณ์และการดำเนินการทั้งหมดภายในบริบทนั้นจะทำงานบนอุปกรณ์ที่กำหนดไว้เดียวกัน .

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 ในตัวอย่างนี้) และจะคัดลอก tensors ระหว่างอุปกรณ์ในกรณีที่จำเป็น

จำกัด การเติบโตของหน่วยความจำ GPU

ตามค่าเริ่มต้น TensorFlow จะแมปหน่วยความจำ GPU เกือบทั้งหมดของ GPU ทั้งหมด (ขึ้นอยู่กับ CUDA_VISIBLE_DEVICES ) ที่มองเห็นได้ในกระบวนการ สิ่งนี้ทำเพื่อใช้ทรัพยากรหน่วยความจำ GPU ที่ค่อนข้างมีค่าบนอุปกรณ์อย่างมีประสิทธิภาพมากขึ้นโดยการลดการกระจายตัวของหน่วยความจำ ในการ จำกัด TensorFlow ไว้ที่ชุด GPU เฉพาะเราใช้เมธอด 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 ร่วมกับแอปพลิเคชันอื่น ๆ เช่น GUI ของเวิร์กสเตชัน

ใช้ GPU ตัวเดียวบนระบบ multi-GPU

หากคุณมี GPU มากกว่าหนึ่งตัวในระบบของคุณ GPU ที่มี ID ต่ำสุดจะถูกเลือกโดยค่าเริ่มต้น หากคุณต้องการใช้ 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.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)

ใช้ GPU หลายตัว

การพัฒนาสำหรับ GPU หลายตัวจะช่วยให้โมเดลสามารถปรับขนาดได้ด้วยทรัพยากรเพิ่มเติม หากพัฒนาบนระบบด้วย GPU ตัวเดียวเราสามารถจำลอง GPU หลายตัวด้วยอุปกรณ์เสมือนได้ ซึ่งช่วยให้ทดสอบการตั้งค่าหลาย 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

เมื่อเรามี GPU แบบลอจิคัลหลายตัวสำหรับรันไทม์แล้วเราสามารถใช้ GPU หลายตัวด้วย tf.distribute.Strategy หรือด้วยการจัดวางด้วยตนเอง

ด้วย tf.distribute.Strategy

แนวทางปฏิบัติที่ดีที่สุดสำหรับการใช้ GPU หลายตัวคือการใช้ 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 แต่ละตัวโดยแยกข้อมูลอินพุตระหว่างกันหรือที่เรียกว่า " data parallelism "

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับกลยุทธ์การจัดจำหน่ายโปรดดูคู่มือ ที่นี่

ตำแหน่งด้วยตนเอง

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)