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

กระจายการฝึกอบรมด้วย TensorFlow

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

ภาพรวม

tf.distribute.Strategy คือ TensorFlow API เพื่อเผยแพร่การฝึกอบรมใน GPU หลายเครื่องหลายเครื่องหรือ TPU เมื่อใช้ API นี้คุณสามารถแจกจ่ายโมเดลและรหัสการฝึกอบรมที่มีอยู่ของคุณได้โดยมีการเปลี่ยนแปลงโค้ดเพียงเล็กน้อย

tf.distribute.Strategy ได้รับการออกแบบโดยคำนึงถึงเป้าหมายสำคัญเหล่านี้:

  • ใช้งานง่ายและรองรับกลุ่มผู้ใช้หลายกลุ่มรวมถึงนักวิจัยวิศวกร ML เป็นต้น
  • ให้ประสิทธิภาพที่ดีนอกกรอบ
  • สลับกลยุทธ์ได้ง่าย

tf.distribute.Strategy สามารถใช้ได้กับ API ระดับสูงเช่น Keras และยังสามารถใช้เพื่อกระจายลูปการฝึกอบรมแบบกำหนดเอง (และโดยทั่วไปการคำนวณใด ๆ โดยใช้ TensorFlow)

ใน TensorFlow 2.x คุณสามารถเรียกใช้โปรแกรมของคุณได้อย่างกระตือรือร้นหรือในกราฟโดยใช้ tf.function tf.distribute.Strategy ตั้งใจที่จะสนับสนุนโหมดการทำงานทั้งสองนี้ แต่ทำงานได้ดีที่สุดกับ tf.function แนะนำให้ใช้โหมด Eager เพื่อวัตถุประสงค์ในการดีบักเท่านั้นและไม่รองรับ TPUStrategy แม้ว่าการฝึกอบรมจะเป็นจุดสำคัญของคู่มือนี้ แต่ API นี้ยังสามารถใช้สำหรับการกระจายการประเมินและการคาดคะเนบนแพลตฟอร์มต่างๆ

คุณสามารถใช้ tf.distribute.Strategy มีการเปลี่ยนแปลงโค้ดของคุณน้อยมากเนื่องจากเราได้เปลี่ยนส่วนประกอบพื้นฐานของ TensorFlow ให้กลายเป็นข้อมูลเชิงกลยุทธ์ ซึ่งรวมถึงตัวแปรเลเยอร์โมเดลเครื่องมือเพิ่มประสิทธิภาพเมตริกสรุปและจุดตรวจ

ในคู่มือนี้เราจะอธิบายกลยุทธ์ประเภทต่างๆและวิธีที่คุณสามารถใช้กลยุทธ์เหล่านี้ในสถานการณ์ต่างๆ หากต้องการเรียนรู้วิธีการแก้ไขปัญหาด้านประสิทธิภาพโปรดดูที่คู่มือ Optimize TensorFlow GPU Performance

# Import TensorFlow
import tensorflow as tf

ประเภทของกลยุทธ์

tf.distribute.Strategy ตั้งใจที่จะครอบคลุมกรณีการใช้งานจำนวนมากตามแกนต่างๆ ขณะนี้ชุดค่าผสมเหล่านี้บางส่วนได้รับการสนับสนุนและจะมีการเพิ่มชุดค่าผสมอื่น ๆ ในอนาคต แกนเหล่านี้บางส่วน ได้แก่ :

  • การฝึกอบรมแบบซิงโครนัสและแบบอะซิงโครนัส: เป็นวิธีการทั่วไปสองวิธีในการกระจายการฝึกอบรมโดยใช้ข้อมูลแบบขนาน ในการฝึกอบรมการซิงค์พนักงานทุกคนจะฝึกอบรมเกี่ยวกับข้อมูลอินพุตส่วนต่างๆในการซิงค์และรวบรวมการไล่ระดับสีในแต่ละขั้นตอน ในการฝึกอบรมแบบอะซิงโครไนซ์พนักงานทุกคนจะได้รับการฝึกอบรมอย่างอิสระเกี่ยวกับข้อมูลอินพุตและอัปเดตตัวแปรแบบอะซิงโครนัส โดยทั่วไปการฝึกอบรมการซิงค์ได้รับการสนับสนุนผ่าน all-reduction และ async ผ่านสถาปัตยกรรมเซิร์ฟเวอร์พารามิเตอร์
  • แพลตฟอร์มฮาร์ดแวร์: คุณอาจต้องการปรับขนาดการฝึกอบรมของคุณไปยัง GPU หลายตัวในเครื่องเดียวหรือหลายเครื่องในเครือข่าย (ที่มี GPU 0 ตัวขึ้นไปอย่างละตัว) หรือบน Cloud TPU

เพื่อรองรับกรณีการใช้งานเหล่านี้มีกลยุทธ์หกประการ ส่วนถัดไปจะอธิบายว่าสิ่งเหล่านี้รองรับสถานการณ์ใดใน TF นี่คือภาพรวมโดยย่อ:

API การฝึกอบรม มิเรอร์กลยุทธ์ TPUS กลยุทธ์ MultiWorkerMirrored ยุทธศาสตร์ CentralStorageStrategy ParameterServerStrategy
Keras API ได้รับการสนับสนุน ได้รับการสนับสนุน การสนับสนุนการทดลอง การสนับสนุนการทดลอง รองรับโพสต์ที่วางแผนไว้ 2.3
ลูปการฝึกที่กำหนดเอง ได้รับการสนับสนุน ได้รับการสนับสนุน การสนับสนุนการทดลอง การสนับสนุนการทดลอง รองรับโพสต์ที่วางแผนไว้ 2.3
Estimator API การสนับสนุนที่ จำกัด ไม่รองรับ การสนับสนุนที่ จำกัด การสนับสนุนที่ จำกัด การสนับสนุนที่ จำกัด

มิเรอร์กลยุทธ์

tf.distribute.MirroredStrategy รองรับการฝึกอบรมแบบกระจายซิงโครนัสบน GPU หลายตัวในเครื่องเดียว สร้างหนึ่งแบบจำลองต่ออุปกรณ์ GPU ตัวแปรแต่ละตัวในโมเดลจะถูกมิเรอร์ในแบบจำลองทั้งหมด เมื่อรวมกันแล้วตัวแปรเหล่านี้จะรวมกันเป็นตัวแปรแนวคิดเดียวที่เรียกว่า MirroredVariable ตัวแปรเหล่านี้จะซิงค์กันโดยใช้การอัปเดตที่เหมือนกัน

อัลกอริธึมการลดทั้งหมดที่มีประสิทธิภาพใช้เพื่อสื่อสารการอัปเดตตัวแปรระหว่างอุปกรณ์ต่างๆ ลดการรวมเทนเซอร์ในอุปกรณ์ทั้งหมดโดยการเพิ่มและทำให้พร้อมใช้งานในแต่ละอุปกรณ์ เป็นอัลกอริทึมแบบผสมผสานที่มีประสิทธิภาพมากและสามารถลดค่าใช้จ่ายในการซิงโครไนซ์ลงได้มาก มีอัลกอริทึมและการใช้งานแบบลดขั้นตอนทั้งหมดที่พร้อมใช้งานขึ้นอยู่กับประเภทของการสื่อสารระหว่างอุปกรณ์ โดยค่าเริ่มต้นจะใช้ NVIDIA NCCL เป็นการลดการใช้งานทั้งหมด คุณสามารถเลือกจากตัวเลือกอื่น ๆ หรือเขียนเองก็ได้

นี่คือวิธีที่ง่ายที่สุดในการสร้าง MirroredStrategy :

mirrored_strategy = tf.distribute.MirroredStrategy()
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

สิ่งนี้จะสร้างอินสแตนซ์ MirroredStrategy ซึ่งจะใช้ GPU ทั้งหมดที่ TensorFlow มองเห็นได้และใช้ NCCL เป็นการสื่อสารข้ามอุปกรณ์

หากคุณต้องการใช้ GPU บางตัวในเครื่องของคุณคุณสามารถทำได้ดังนี้:

mirrored_strategy = tf.distribute.MirroredStrategy(devices=["/gpu:0", "/gpu:1"])
WARNING:tensorflow:Some requested devices in `tf.distribute.Strategy` are not visible to TensorFlow: /job:localhost/replica:0/task:0/device:GPU:1,/job:localhost/replica:0/task:0/device:GPU:0
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0', '/job:localhost/replica:0/task:0/device:GPU:1')

หากคุณต้องการแทนที่การสื่อสารข้ามอุปกรณ์คุณสามารถทำได้โดยใช้อาร์กิวเมนต์ cross_device_ops โดยการจัดหาอินสแตนซ์ของ tf.distribute.CrossDeviceOps ปัจจุบัน tf.distribute.HierarchicalCopyAllReduce และ tf.distribute.ReductionToOneDevice เป็นสองตัวเลือกนอกเหนือจาก tf.distribute.NcclAllReduce ซึ่งเป็นค่าเริ่มต้น

mirrored_strategy = tf.distribute.MirroredStrategy(
    cross_device_ops=tf.distribute.HierarchicalCopyAllReduce())
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

TPUS กลยุทธ์

tf.distribute.TPUStrategy ช่วยให้คุณสามารถเรียกใช้การฝึกอบรม TensorFlow ของคุณในหน่วยประมวลผล Tensor (TPU) TPU เป็น ASIC เฉพาะของ Google ที่ออกแบบมาเพื่อเร่งปริมาณงานแมชชีนเลิร์นนิงอย่างมาก พร้อมใช้งานบน Google Colab, TensorFlow Research Cloud และ Cloud TPU

ในแง่ของสถาปัตยกรรมการฝึกอบรมแบบกระจาย TPUStrategy เป็น MirroredStrategy เดียวกัน - ใช้การฝึกอบรมแบบกระจายซิงโครนัส TPU ช่วยให้การดำเนินการลดลงทั้งหมดและการดำเนินการโดยรวมอื่น ๆ ที่มีประสิทธิภาพเป็นของตัวเองในแกน TPU หลายแกนซึ่งใช้ใน TPUStrategy

นี่คือวิธีที่คุณจะสร้างอินสแตนซ์ TPUStrategy :

cluster_resolver = tf.distribute.cluster_resolver.TPUClusterResolver(
    tpu=tpu_address)
tf.config.experimental_connect_to_cluster(cluster_resolver)
tf.tpu.experimental.initialize_tpu_system(cluster_resolver)
tpu_strategy = tf.distribute.TPUStrategy(cluster_resolver)

อินสแตนซ์ TPUClusterResolver ช่วยค้นหา TPUClusterResolver ใน Colab คุณไม่จำเป็นต้องระบุข้อโต้แย้งใด ๆ

หากคุณต้องการใช้สิ่งนี้สำหรับ Cloud TPU:

  • คุณต้องระบุชื่อทรัพยากร TPU ของคุณในอาร์กิวเมนต์ tpu
  • คุณต้องเริ่มต้นระบบ tpu อย่างชัดเจนเมื่อ เริ่มต้น โปรแกรม สิ่งนี้จำเป็นก่อนที่จะใช้ TPU สำหรับการคำนวณ การเริ่มต้นระบบ tpu จะลบหน่วยความจำ TPU ออกไปด้วยดังนั้นสิ่งสำคัญคือต้องทำขั้นตอนนี้ให้เสร็จก่อนเพื่อหลีกเลี่ยงการสูญเสียสถานะ

MultiWorkerMirrored ยุทธศาสตร์

tf.distribute.experimental.MultiWorkerMirroredStrategy นั้นคล้ายกับ MirroredStrategy มาก ดำเนินการฝึกอบรมแบบกระจายซิงโครนัสให้กับพนักงานหลายคนโดยแต่ละคนอาจมี GPU หลายตัว เช่นเดียวกับ MirroredStrategy จะสร้างสำเนาของตัวแปรทั้งหมดในแบบจำลองบนอุปกรณ์แต่ละเครื่องในพนักงานทั้งหมด

ใช้ CollectiveOps เป็นวิธีการสื่อสารแบบ multi-worker all-reduction ที่ใช้เพื่อให้ตัวแปรซิงค์กัน การทำงานร่วมกันคือการดำเนินการเดียวในกราฟ TensorFlow ซึ่งสามารถเลือกอัลกอริธึมที่ลดทั้งหมดโดยอัตโนมัติในรันไทม์ TensorFlow ตามฮาร์ดแวร์โครงสร้างเครือข่ายและขนาดเทนเซอร์

นอกจากนี้ยังดำเนินการเพิ่มประสิทธิภาพการทำงานเพิ่มเติม ตัวอย่างเช่นรวมถึงการเพิ่มประสิทธิภาพแบบคงที่ที่แปลงการลดทั้งหมดหลายครั้งบนเทนเซอร์ขนาดเล็กให้เป็นการลดทั้งหมดน้อยลงสำหรับเทนเซอร์ขนาดใหญ่ นอกจากนี้ยังได้รับการออกแบบให้มีสถาปัตยกรรมปลั๊กอิน - ดังนั้นในอนาคตคุณจะสามารถใช้อัลกอริทึมปลั๊กอินที่ปรับแต่งให้เหมาะกับฮาร์ดแวร์ของคุณได้ดีขึ้น โปรดทราบว่าหน่วยปฏิบัติการร่วมยังใช้การดำเนินการร่วมอื่น ๆ เช่นการออกอากาศและการรวบรวมทั้งหมด

นี่คือวิธีที่ง่ายที่สุดในการสร้าง MultiWorkerMirroredStrategy :

multiworker_strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy()
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Using MirroredStrategy with devices ('/device:GPU:0',)
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CollectiveCommunication.AUTO

ปัจจุบัน MultiWorkerMirroredStrategy ช่วยให้คุณสามารถเลือกระหว่างการใช้งานแบบรวมที่แตกต่างกันสองแบบ CollectiveCommunication.RING สร้าง CollectiveCommunication.RING ใช้วงแหวนโดยใช้ gRPC เป็นเลเยอร์การสื่อสาร CollectiveCommunication.NCCL ใช้ NCCL ของ Nvidia เพื่อใช้งาน Collective CollectiveCommunication.AUTO เลื่อนตัวเลือกไปที่รันไทม์ ทางเลือกที่ดีที่สุดของการใช้งานร่วมกันขึ้นอยู่กับจำนวนและประเภทของ GPU และการเชื่อมต่อเครือข่ายในคลัสเตอร์ คุณสามารถระบุได้ด้วยวิธีต่อไปนี้:

multiworker_strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy(
    tf.distribute.experimental.CollectiveCommunication.NCCL)
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.
INFO:tensorflow:Using MirroredStrategy with devices ('/device:GPU:0',)
INFO:tensorflow:Single-worker MultiWorkerMirroredStrategy with local_devices = ('/device:GPU:0',), communication = CollectiveCommunication.NCCL

ความแตกต่างที่สำคัญอย่างหนึ่งในการฝึกอบรมผู้ปฏิบัติงานหลายคนเมื่อเทียบกับการฝึกอบรมแบบหลาย GPU คือการตั้งค่าผู้ปฏิบัติงานหลายคน ตัวแปรสภาวะแวดล้อม TF_CONFIG เป็นวิธีมาตรฐานใน TensorFlow เพื่อระบุการกำหนดค่าคลัสเตอร์ให้กับผู้ปฏิบัติงานแต่ละคนที่เป็นส่วนหนึ่งของคลัสเตอร์ เรียนรู้เพิ่มเติมเกี่ยวกับ การตั้งค่า TF_CONFIG

CentralStorageStrategy

tf.distribute.experimental.CentralStorageStrategy ทำการฝึกอบรมแบบซิงโครนัสเช่นกัน ตัวแปรจะไม่ถูกมิเรอร์ แต่จะถูกวางไว้บน CPU และการดำเนินการจะถูกจำลองแบบใน GPU ในเครื่องทั้งหมด หากมี GPU เพียงตัวเดียวตัวแปรและการดำเนินการทั้งหมดจะถูกวางไว้ใน GPU นั้น

สร้างอินสแตนซ์ของ CentralStorageStrategy โดย:

central_storage_strategy = tf.distribute.experimental.CentralStorageStrategy()
INFO:tensorflow:ParameterServerStrategy (CentralStorageStrategy if you are using a single machine) with compute_devices = ['/job:localhost/replica:0/task:0/device:GPU:0'], variable_device = '/job:localhost/replica:0/task:0/device:GPU:0'

สิ่งนี้จะสร้างอินสแตนซ์ CentralStorageStrategy ซึ่งจะใช้ GPU และ CPU ที่มองเห็นได้ทั้งหมด การอัปเดตตัวแปรบนแบบจำลองจะถูกรวบรวมก่อนที่จะนำไปใช้กับตัวแปร

ParameterServerStrategy

ใน TF1 ParameterServerStrategy จะใช้ได้เฉพาะกับตัวประมาณค่าผ่านสัญลักษณ์ tf.compat.v1.distribute.experimental.ParameterServerStrategy และการใช้งานใน TF2 กำลังได้รับการพัฒนาสำหรับรีลีสในภายหลัง สำหรับกลยุทธ์นี้เครื่องบางเครื่องถูกกำหนดให้เป็นคนงานและบางเครื่องเป็นเซิร์ฟเวอร์พารามิเตอร์ ตัวแปรแต่ละตัวของโมเดลถูกวางไว้บนเซิร์ฟเวอร์พารามิเตอร์เดียว การคำนวณถูกจำลองแบบในคนงานทั้งหมด

กลยุทธ์อื่น ๆ

นอกเหนือจากกลยุทธ์ข้างต้นแล้วยังมีอีกสองกลยุทธ์ที่อาจเป็นประโยชน์สำหรับการสร้างต้นแบบและการดีบักเมื่อใช้ tf.distribute API

กลยุทธ์เริ่มต้น

กลยุทธ์เริ่มต้นคือกลยุทธ์การกระจายที่เกิดขึ้นเมื่อไม่มีกลยุทธ์การกระจายอย่างชัดเจนอยู่ในขอบเขต มันใช้อินเทอร์เฟซ tf.distribute.Strategy แต่เป็น pass-through และไม่มีการแจกจ่ายจริง ตัวอย่างเช่น strategy.run(fn) เรียกง่ายๆว่า fn โค้ดที่เขียนโดยใช้กลยุทธ์นี้ควรทำงานเหมือนกับโค้ดที่เขียนโดยไม่มีกลยุทธ์ใด ๆ คุณอาจคิดว่าเป็นกลยุทธ์ "ไม่ต้องใช้"

กลยุทธ์เริ่มต้นคือซิงเกิลตันและไม่มีใครสามารถสร้างอินสแตนซ์ของมันได้อีก สามารถรับได้โดยใช้ tf.distribute.get_strategy() นอกขอบเขตของกลยุทธ์ที่ชัดเจน (API เดียวกับที่สามารถใช้เพื่อรับกลยุทธ์ปัจจุบันภายในขอบเขตของกลยุทธ์ที่ชัดเจน)

default_strategy = tf.distribute.get_strategy()

กลยุทธ์นี้ตอบสนองวัตถุประสงค์หลักสองประการ:

  • ช่วยให้สามารถเขียนโค้ดไลบรารีที่รับรู้การแจกจ่ายโดยไม่มีเงื่อนไข ตัวอย่างเช่นใน tf.optimizer s สามารถใช้ tf.distribute.get_strategy() และใช้กลยุทธ์นั้นในการลดการไล่ระดับสี - มันจะส่งคืนวัตถุกลยุทธ์ที่เราสามารถเรียกลด API ได้เสมอ
# In optimizer or other library code
# Get currently active strategy
strategy = tf.distribute.get_strategy()
strategy.reduce("SUM", 1., axis=None)  # reduce some values
1.0
  • เช่นเดียวกับรหัสไลบรารีสามารถใช้เพื่อเขียนโปรแกรมของผู้ใช้ปลายทางเพื่อทำงานร่วมกับและไม่มีกลยุทธ์การแจกจ่ายโดยไม่ต้องใช้ตรรกะเงื่อนไข ตัวอย่างข้อมูลโค้ดที่แสดงสิ่งนี้:
if tf.config.list_physical_devices('gpu'):
  strategy = tf.distribute.MirroredStrategy()
else:  # use default strategy
  strategy = tf.distribute.get_strategy() 

with strategy.scope():
  # do something interesting
  print(tf.Variable(1.))
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>

OneDeviceStrategy

tf.distribute.OneDeviceStrategy เป็นกลยุทธ์ในการวางตัวแปรและการคำนวณทั้งหมดบนอุปกรณ์ที่ระบุเพียงเครื่องเดียว

strategy = tf.distribute.OneDeviceStrategy(device="/gpu:0")

กลยุทธ์นี้แตกต่างจากกลยุทธ์เริ่มต้นในหลายวิธี ในกลยุทธ์เริ่มต้นตรรกะตำแหน่งตัวแปรจะไม่เปลี่ยนแปลงเมื่อเทียบกับการเรียกใช้ TensorFlow โดยไม่มีกลยุทธ์การกระจายใด ๆ แต่เมื่อใช้ OneDeviceStrategy ตัวแปรทั้งหมดที่สร้างขึ้นในขอบเขตจะถูกวางไว้อย่างชัดเจนในอุปกรณ์ที่ระบุ ยิ่งไปกว่านั้นฟังก์ชันใด ๆ ที่เรียกผ่าน OneDeviceStrategy.run จะถูกวางไว้ในอุปกรณ์ที่ระบุด้วย

อินพุตที่กระจายผ่านกลยุทธ์นี้จะถูกดึงไปยังอุปกรณ์ที่ระบุไว้ล่วงหน้า ในกลยุทธ์เริ่มต้นไม่มีการกระจายอินพุต

เช่นเดียวกับกลยุทธ์เริ่มต้นกลยุทธ์นี้ยังสามารถใช้เพื่อทดสอบโค้ดของคุณก่อนที่จะเปลี่ยนไปใช้กลยุทธ์อื่นซึ่งจะแจกจ่ายไปยังอุปกรณ์ / เครื่องหลายเครื่อง สิ่งนี้จะใช้กลไกกลยุทธ์การกระจายค่อนข้างมากกว่ากลยุทธ์เริ่มต้น แต่จะไม่เต็มขอบเขตเหมือนการใช้ MirroredStrategy หรือ TPUStrategy เป็นต้นหากคุณต้องการโค้ดที่ทำงานราวกับว่าไม่มีกลยุทธ์ให้ใช้กลยุทธ์เริ่มต้น

จนถึงตอนนี้คุณได้เห็นกลยุทธ์ต่างๆที่มีอยู่และคุณจะสร้างอินสแตนซ์ได้อย่างไร สองสามส่วนถัดไปจะแสดงวิธีต่างๆที่คุณสามารถใช้เพื่อเผยแพร่การฝึกอบรมของคุณ

ใช้ tf.distribute.Strategy กับ tf.keras.Model.fit

tf.distribute.Strategy รวมอยู่ใน tf.keras ซึ่งเป็นการใช้งานข้อกำหนด Keras API ของ TensorFlow tf.keras เป็น API ระดับสูงสำหรับสร้างและฝึกโมเดล ด้วยการรวมเข้า tf.keras แบ็กเอนด์ tf.keras เราได้ทำให้การฝึกอบรมของคุณเป็นไปอย่างราบรื่นซึ่งเขียนในกรอบการฝึกอบรม model.fit โดยใช้ model.fit

นี่คือสิ่งที่คุณต้องเปลี่ยนในรหัสของคุณ:

  1. สร้างอินสแตนซ์ของ tf.distribute.Strategy ที่เหมาะสม
  2. ย้ายการสร้างโมเดล Keras เครื่องมือเพิ่มประสิทธิภาพและเมตริกภายใน strategy.scope

เรารองรับโมเดล Keras ทุกประเภท - ตามลำดับฟังก์ชันและคลาสย่อย

นี่คือตัวอย่างโค้ดสำหรับทำสิ่งนี้สำหรับโมเดล Keras ที่เรียบง่ายโดยมีเลเยอร์หนาแน่นหนึ่งชั้น:

mirrored_strategy = tf.distribute.MirroredStrategy()

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])

model.compile(loss='mse', optimizer='sgd')
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

ตัวอย่างนี้ใช้ MirroredStrategy เพื่อให้คุณสามารถรันบนเครื่องที่มี GPU หลายตัวได้ strategy.scope() ระบุถึง Keras ว่าจะใช้กลยุทธ์ใดในการกระจายการฝึกอบรม การสร้างแบบจำลอง / เครื่องมือเพิ่มประสิทธิภาพ / เมตริกภายในขอบเขตนี้ทำให้เราสามารถสร้างตัวแปรแบบกระจายแทนที่จะเป็นตัวแปรปกติ เมื่อตั้งค่าแล้วคุณสามารถใส่แบบจำลองของคุณได้ตามปกติ MirroredStrategy ดูแลการจำลองการฝึกอบรมของโมเดลบน GPU ที่มีอยู่การไล่ระดับสีแบบรวมและอื่น ๆ

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(10)
model.fit(dataset, epochs=2)
model.evaluate(dataset)
Epoch 1/2
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/data/ops/multi_device_iterator_ops.py:601: get_next_as_optional (from tensorflow.python.data.ops.iterator_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.data.Iterator.get_next_as_optional()` instead.
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
10/10 [==============================] - 0s 2ms/step - loss: 2.0391
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 0.9013
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
10/10 [==============================] - 0s 2ms/step - loss: 0.5597

0.5597171783447266

นี่คือ tf.data.Dataset ให้ข้อมูลการฝึกอบรมและการประเมินผล คุณยังสามารถใช้อาร์เรย์ numpy:

import numpy as np
inputs, targets = np.ones((100, 1)), np.ones((100, 1))
model.fit(inputs, targets, epochs=2, batch_size=10)
Epoch 1/2
10/10 [==============================] - 0s 2ms/step - loss: 0.3984
Epoch 2/2
10/10 [==============================] - 0s 2ms/step - loss: 0.1761

<tensorflow.python.keras.callbacks.History at 0x7f674c585a90>

ในทั้งสองกรณี (ชุดข้อมูลหรือตัวเลข) ชุดข้อมูลที่ระบุแต่ละชุดจะถูกแบ่งเท่า ๆ กันระหว่างแบบจำลองหลายรายการ ตัวอย่างเช่นหากใช้ MirroredStrategy กับ GPU 2 ตัวแต่ละชุดขนาด 10 จะถูกแบ่งออกเป็น GPU 2 ตัวโดยแต่ละชุดจะได้รับ 5 ตัวอย่างอินพุตในแต่ละขั้นตอน แต่ละยุคจะฝึกได้เร็วขึ้นเมื่อคุณเพิ่ม GPU มากขึ้น โดยทั่วไปคุณจะต้องการเพิ่มขนาดแบทช์ของคุณเมื่อคุณเพิ่มตัวเร่งความเร็วมากขึ้นเพื่อให้สามารถใช้พลังประมวลผลเพิ่มเติมได้อย่างมีประสิทธิภาพ คุณจะต้องปรับอัตราการเรียนรู้ของคุณใหม่ขึ้นอยู่กับรุ่น คุณสามารถใช้ strategy.num_replicas_in_sync เพื่อรับจำนวนแบบจำลอง

# Compute global batch size using number of replicas.
BATCH_SIZE_PER_REPLICA = 5
global_batch_size = (BATCH_SIZE_PER_REPLICA *
                     mirrored_strategy.num_replicas_in_sync)
dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100)
dataset = dataset.batch(global_batch_size)

LEARNING_RATES_BY_BATCH_SIZE = {5: 0.1, 10: 0.15}
learning_rate = LEARNING_RATES_BY_BATCH_SIZE[global_batch_size]

ตอนนี้มีอะไรรองรับบ้าง?

API การฝึกอบรม มิเรอร์กลยุทธ์ TPUS กลยุทธ์ MultiWorkerMirrored ยุทธศาสตร์ CentralStorageStrategy ParameterServerStrategy
Keras API ได้รับการสนับสนุน ได้รับการสนับสนุน การสนับสนุนการทดลอง การสนับสนุนการทดลอง สนับสนุนโพสต์ที่วางแผนไว้ 2.3

ตัวอย่างและบทช่วยสอน

นี่คือรายการของบทช่วยสอนและตัวอย่างที่แสดงให้เห็นถึงการผสานรวมข้างต้นจนจบด้วย Keras:

  1. บทช่วยสอน ในการฝึก MNIST ด้วย MirroredStrategy
  2. บทช่วยสอน ในการฝึก MNIST โดยใช้ MultiWorkerMirroredStrategy
  3. คำแนะนำ ในการฝึกอบรม MNIST โดยใช้ TPUStrategy
  4. พื้นที่เก็บข้อมูล TensorFlow Model Garden ที่มีคอลเล็กชันของโมเดลล้ำสมัยที่ใช้กลยุทธ์ต่างๆ

ใช้ tf.distribute.Strategy กับลูปการฝึกอบรมที่กำหนดเอง

อย่างที่คุณเคยเห็นการใช้ tf.distribute.Strategy กับ Keras model.fit ต้องเปลี่ยน model.fit เพียงสองสามบรรทัด ด้วยความพยายามเพียงเล็กน้อยคุณยังสามารถใช้ tf.distribute.Strategy กับลูปการฝึกอบรมที่กำหนดเองได้

หากคุณต้องการความยืดหยุ่นและการควบคุมลูปการฝึกอบรมมากกว่าที่เป็นไปได้ด้วย Estimator หรือ Keras คุณสามารถเขียนลูปการฝึกอบรมที่กำหนดเองได้ ตัวอย่างเช่นเมื่อใช้ GAN คุณอาจต้องการใช้ตัวสร้างหรือตัวเลือกจำนวนที่แตกต่างกันในแต่ละรอบ ในทำนองเดียวกันกรอบระดับสูงไม่เหมาะสำหรับการฝึกอบรม Reinforcement Learning

คลาส tf.distribute.Strategy จัดเตรียมชุดหลักของวิธีการผ่านเพื่อสนับสนุนลูปการฝึกอบรมที่กำหนดเอง การใช้สิ่งเหล่านี้อาจต้องมีการปรับโครงสร้างโค้ดเล็กน้อยในตอนแรก แต่เมื่อเสร็จแล้วคุณควรจะสามารถสลับไปมาระหว่าง GPU, TPU และหลาย ๆ เครื่องได้ง่ายๆเพียงแค่เปลี่ยนอินสแตนซ์กลยุทธ์

ที่นี่เราจะแสดงตัวอย่างสั้น ๆ ที่แสดงถึงกรณีการใช้งานนี้สำหรับตัวอย่างการฝึกอบรมง่ายๆโดยใช้โมเดล Keras เดียวกันกับก่อนหน้านี้

ขั้นแรกสร้างโมเดลและเครื่องมือเพิ่มประสิทธิภาพภายในขอบเขตของกลยุทธ์ เพื่อให้แน่ใจว่าตัวแปรใด ๆ ที่สร้างขึ้นด้วยโมเดลและเครื่องมือเพิ่มประสิทธิภาพเป็นตัวแปรที่มิเรอร์

with mirrored_strategy.scope():
  model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
  optimizer = tf.keras.optimizers.SGD()

จากนั้นสร้างชุดข้อมูลอินพุตแล้วเรียก tf.distribute.Strategy.experimental_distribute_dataset เพื่อแจกจ่ายชุดข้อมูลตามกลยุทธ์

dataset = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(
    global_batch_size)
dist_dataset = mirrored_strategy.experimental_distribute_dataset(dataset)

จากนั้นกำหนดขั้นตอนหนึ่งของการฝึกอบรม ใช้ tf.GradientTape เพื่อคำนวณการไล่ระดับสีและเครื่องมือเพิ่มประสิทธิภาพเพื่อใช้การไล่ระดับสีเหล่านั้นเพื่ออัปเดตตัวแปรของโมเดลของเรา ในการกระจายขั้นตอนการฝึกอบรมนี้ให้วางไว้ในฟังก์ชัน train_step และส่งต่อไปยัง tf.distrbute.Strategy.run พร้อมกับอินพุตชุดข้อมูลที่คุณได้รับจาก dist_dataset สร้างขึ้นก่อนหน้านี้:

loss_object = tf.keras.losses.BinaryCrossentropy(
  from_logits=True,
  reduction=tf.keras.losses.Reduction.NONE)

def compute_loss(labels, predictions):
  per_example_loss = loss_object(labels, predictions)
  return tf.nn.compute_average_loss(per_example_loss, global_batch_size=global_batch_size)

def train_step(inputs):
  features, labels = inputs

  with tf.GradientTape() as tape:
    predictions = model(features, training=True)
    loss = compute_loss(labels, predictions)

  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  return loss

@tf.function
def distributed_train_step(dist_inputs):
  per_replica_losses = mirrored_strategy.run(train_step, args=(dist_inputs,))
  return mirrored_strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_losses,
                         axis=None)

สิ่งอื่น ๆ ที่ควรทราบในโค้ดด้านบน:

  1. ใช้ tf.nn.compute_average_loss เพื่อคำนวณการสูญเสีย tf.nn.compute_average_loss รวมการสูญเสียต่อตัวอย่างและหารผลรวมด้วย global_batch_size นี้เป็นสิ่งสำคัญเพราะต่อมาหลังจากการไล่ระดับสีที่มีการคำนวณในแต่ละแบบจำลองที่พวกเขาจะรวบรวมจากแบบจำลองจากข้อสรุปพวกเขา
  2. ใช้ tf.distribute.Strategy.reduce API เพื่อรวมผลลัพธ์ที่ส่งคืนโดย tf.distribute.Strategy.run tf.distribute.Strategy.run ส่งคืนผลลัพธ์จากแบบจำลองท้องถิ่นแต่ละรายการในกลยุทธ์และมีหลายวิธีในการใช้ผลลัพธ์นี้ คุณสามารถ reduce เพื่อให้ได้ค่ารวม คุณยังสามารถทำ tf.distribute.Strategy.experimental_local_results เพื่อรับรายการค่าที่มีอยู่ในผลลัพธ์หนึ่งรายการต่อแบบจำลองท้องถิ่น
  3. เมื่อใช้ apply_gradients ภายในขอบเขตกลยุทธ์การแจกจ่ายพฤติกรรมจะถูกแก้ไข โดยเฉพาะอย่างยิ่งก่อนที่จะใช้การไล่ระดับสีในแต่ละอินสแตนซ์แบบขนานในระหว่างการฝึกอบรมแบบซิงโครนัสจะทำการจำลองการไล่ระดับแบบรวมทั้งหมด

ในที่สุดเมื่อคุณกำหนดขั้นตอนการฝึกอบรมแล้วเราสามารถทำซ้ำบน dist_dataset และเรียกใช้การฝึกแบบวนซ้ำ:

for dist_inputs in dist_dataset:
  print(distributed_train_step(dist_inputs))
tf.Tensor(0.80679005, shape=(), dtype=float32)
tf.Tensor(0.8006732, shape=(), dtype=float32)
tf.Tensor(0.7946168, shape=(), dtype=float32)
tf.Tensor(0.78862023, shape=(), dtype=float32)
tf.Tensor(0.782683, shape=(), dtype=float32)
tf.Tensor(0.77680445, shape=(), dtype=float32)
tf.Tensor(0.77098423, shape=(), dtype=float32)
tf.Tensor(0.7652217, shape=(), dtype=float32)
tf.Tensor(0.7595164, shape=(), dtype=float32)
tf.Tensor(0.75386775, shape=(), dtype=float32)
tf.Tensor(0.7482752, shape=(), dtype=float32)
tf.Tensor(0.74273825, shape=(), dtype=float32)
tf.Tensor(0.7372565, shape=(), dtype=float32)
tf.Tensor(0.7318293, shape=(), dtype=float32)
tf.Tensor(0.7264561, shape=(), dtype=float32)
tf.Tensor(0.7211364, shape=(), dtype=float32)
tf.Tensor(0.71586984, shape=(), dtype=float32)
tf.Tensor(0.7106557, shape=(), dtype=float32)
tf.Tensor(0.7054935, shape=(), dtype=float32)
tf.Tensor(0.7003829, shape=(), dtype=float32)

ในตัวอย่างข้างต้นคุณได้ทำซ้ำในชุดข้อมูล dist_dataset เพื่อให้ข้อมูลในการฝึกอบรมของคุณ เรายังมี tf.distribute.Strategy.make_experimental_numpy_dataset เพื่อรองรับอินพุตที่เป็น tf.distribute.Strategy.make_experimental_numpy_dataset คุณสามารถใช้ API นี้เพื่อสร้างชุดข้อมูลก่อนที่จะเรียกใช้ tf.distribute.Strategy.experimental_distribute_dataset

อีกวิธีหนึ่งในการทำซ้ำข้อมูลของคุณคือการใช้ตัววนซ้ำอย่างชัดเจน คุณอาจต้องการทำเช่นนี้เมื่อคุณต้องการเรียกใช้ตามจำนวนขั้นตอนที่กำหนดซึ่งต่างจากการทำซ้ำในชุดข้อมูลทั้งหมด การทำซ้ำข้างต้นจะได้รับการแก้ไขเพื่อสร้างตัววนซ้ำก่อนแล้วจึงเรียกอย่างชัดเจนใน next เพื่อรับข้อมูลอินพุต

iterator = iter(dist_dataset)
for _ in range(10):
  print(distributed_train_step(next(iterator)))
tf.Tensor(0.69532317, shape=(), dtype=float32)
tf.Tensor(0.690314, shape=(), dtype=float32)
tf.Tensor(0.68535477, shape=(), dtype=float32)
tf.Tensor(0.680445, shape=(), dtype=float32)
tf.Tensor(0.67558426, shape=(), dtype=float32)
tf.Tensor(0.67077184, shape=(), dtype=float32)
tf.Tensor(0.66600746, shape=(), dtype=float32)
tf.Tensor(0.66129065, shape=(), dtype=float32)
tf.Tensor(0.6566208, shape=(), dtype=float32)
tf.Tensor(0.6519975, shape=(), dtype=float32)

ซึ่งครอบคลุมกรณีที่ง่ายที่สุดในการใช้ tf.distribute.Strategy API เพื่อแจกจ่ายลูปการฝึกอบรมที่กำหนดเอง

ตอนนี้มีอะไรรองรับบ้าง?

API การฝึกอบรม มิเรอร์กลยุทธ์ TPUS กลยุทธ์ MultiWorkerMirrored ยุทธศาสตร์ CentralStorageStrategy ParameterServerStrategy
Custom Training Loop ได้รับการสนับสนุน ได้รับการสนับสนุน การสนับสนุนการทดลอง การสนับสนุนการทดลอง สนับสนุนโพสต์ที่วางแผนไว้ 2.3

ตัวอย่างและบทช่วยสอน

นี่คือตัวอย่างบางส่วนสำหรับการใช้กลยุทธ์การกระจายกับลูปการฝึกอบรมที่กำหนดเอง:

  1. บทช่วยสอน ในการฝึก MNIST โดยใช้ MirroredStrategy
  2. คำแนะนำ ในการฝึกอบรม MNIST โดยใช้ TPUStrategy
  3. พื้นที่เก็บข้อมูล TensorFlow Model Garden ที่มีคอลเล็กชันของโมเดลล้ำสมัยที่ใช้กลยุทธ์ต่างๆ

หัวข้ออื่น ๆ

ส่วนนี้ครอบคลุมหัวข้อบางส่วนที่เกี่ยวข้องกับกรณีการใช้งานหลายกรณี

การตั้งค่าตัวแปรสภาพแวดล้อม TF_CONFIG

สำหรับการฝึกอบรมผู้ปฏิบัติงานหลายคนดังที่กล่าวไว้ก่อนหน้านี้คุณต้องตั้งค่าตัวแปรสภาพแวดล้อม TF_CONFIG สำหรับแต่ละไบนารีที่ทำงานในคลัสเตอร์ของคุณ ตัวแปรสภาพแวดล้อม TF_CONFIG เป็นสตริง JSON ซึ่งระบุว่างานใดบ้างที่ประกอบเป็นคลัสเตอร์แอดเดรสและแต่ละบทบาทของงานในคลัสเตอร์ เทน เซอร์โฟลว์ / repo ระบบนิเวศ มีเทมเพลต Kubernetes ซึ่งตั้งค่า TF_CONFIG สำหรับงานฝึกอบรมของคุณ

TF_CONFIG มีสององค์ประกอบ: คลัสเตอร์และงาน คลัสเตอร์ให้ข้อมูลเกี่ยวกับคลัสเตอร์การฝึกอบรมซึ่งเป็นคำสั่งที่ประกอบด้วยงานประเภทต่างๆเช่นผู้ปฏิบัติงาน ในการฝึกอบรมผู้ปฏิบัติงานหลายคนมักจะมีผู้ปฏิบัติงานหนึ่งคนที่รับผิดชอบมากกว่าเล็กน้อยเช่นการบันทึกจุดตรวจสอบและการเขียนไฟล์สรุปสำหรับ TensorBoard นอกเหนือจากสิ่งที่คนงานประจำทำ คนงานดังกล่าวเรียกว่าคนงาน 'หัวหน้า' และเป็นธรรมเนียมที่คนงานที่มีดัชนี 0 จะได้รับการแต่งตั้งให้เป็นหัวหน้าคนงาน (อันที่จริงนี่คือวิธีการใช้ tf.distribute.Strategy) ในทางกลับกันงานจะให้ข้อมูลของงานปัจจุบัน คลัสเตอร์คอมโพเนนต์แรกจะเหมือนกันสำหรับผู้ปฏิบัติงานทั้งหมดและงานคอมโพเนนต์ที่สองจะแตกต่างกันสำหรับผู้ปฏิบัติงานแต่ละคนและระบุประเภทและดัชนีของผู้ปฏิบัติงานนั้น

ตัวอย่างหนึ่งของ TF_CONFIG คือ:

os.environ["TF_CONFIG"] = json.dumps({
    "cluster": {
        "worker": ["host1:port", "host2:port", "host3:port"],
        "ps": ["host4:port", "host5:port"]
    },
   "task": {"type": "worker", "index": 1}
})

TF_CONFIG นี้ระบุว่ามีคนงานสามคนและงาน ps สองงานในคลัสเตอร์พร้อมกับโฮสต์และพอร์ตของพวกเขา ส่วน "งาน" ระบุว่าบทบาทของงานปัจจุบันในคลัสเตอร์ผู้ปฏิบัติงาน 1 (ผู้ปฏิบัติงานคนที่สอง) บทบาทที่ถูกต้องในคลัสเตอร์คือ "หัวหน้า" "คนงาน" "ps" และ "ผู้ประเมิน" ไม่ควรมีงาน "ps" ยกเว้นเมื่อใช้ tf.distribute.experimental.ParameterServerStrategy

อะไรต่อไป?

tf.distribute.Strategy อยู่ระหว่างการพัฒนา ลองใช้และให้และข้อเสนอแนะของคุณโดยใช้ ปัญหา GitHub