Apache MXNet - การฝึกอบรมแบบกระจาย

บทนี้เกี่ยวกับการฝึกอบรมแบบกระจายใน Apache MXNet เริ่มต้นด้วยการทำความเข้าใจว่าโหมดการคำนวณใน MXNet คืออะไร

โหมดการคำนวณ

MXNet ซึ่งเป็นไลบรารี ML หลายภาษานำเสนอโหมดการคำนวณสองโหมดต่อไปนี้ให้กับผู้ใช้ -

โหมดจำเป็น

โหมดการคำนวณนี้แสดงอินเทอร์เฟซเช่น NumPy API ตัวอย่างเช่นใน MXNet ให้ใช้รหัสจำเป็นต่อไปนี้เพื่อสร้างจำนวนศูนย์บน CPU และ GPU -

import mxnet as mx
tensor_cpu = mx.nd.zeros((100,), ctx=mx.cpu())
tensor_gpu= mx.nd.zeros((100,), ctx=mx.gpu(0))

ดังที่เราเห็นในโค้ดด้านบน MXNets ระบุตำแหน่งที่จะเก็บเทนเซอร์ไม่ว่าจะในอุปกรณ์ CPU หรือ GPU ในตัวอย่างข้างต้นอยู่ที่ตำแหน่ง 0 MXNet สามารถใช้ประโยชน์จากอุปกรณ์ได้อย่างไม่น่าเชื่อเนื่องจากการคำนวณทั้งหมดเกิดขึ้นอย่างเฉื่อยชาแทนที่จะเป็นแบบทันทีทันใด

โหมดสัญลักษณ์

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

ในทางกลับกันโหมด Symbolic จะแสดงกราฟการคำนวณเช่น TensorFlow ช่วยขจัดข้อเสียเปรียบของ API ที่จำเป็นโดยอนุญาตให้ MXNet ทำงานกับสัญลักษณ์หรือตัวแปรแทนโครงสร้างข้อมูลคงที่ / กำหนดไว้ล่วงหน้า หลังจากนั้นสัญลักษณ์สามารถตีความเป็นชุดการทำงานได้ดังนี้ -

import mxnet as mx
x = mx.sym.Variable(“X”)
y = mx.sym.Variable(“Y”)
z = (x+y)
m = z/100

ชนิดของความเท่าเทียมกัน

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

ต่อไปนี้เป็นสองวิธีที่เราสามารถกระจายภาระงานของการฝึกอบรม NN ไปยังอุปกรณ์ต่างๆ CPU หรือ GPU ได้ -

ความขนานของข้อมูล

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

แบบจำลองความเท่าเทียมกัน

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

การทำงานของการฝึกอบรมแบบกระจาย

แนวคิดที่ระบุด้านล่างเป็นกุญแจสำคัญในการทำความเข้าใจการทำงานของการฝึกอบรมแบบกระจายใน Apache MXNet -

ประเภทของกระบวนการ

กระบวนการสื่อสารซึ่งกันและกันเพื่อบรรลุการฝึกอบรมของรูปแบบ Apache MXNet มีสามกระบวนการดังต่อไปนี้ -

คนงาน

งานของโหนดคนงานคือการฝึกอบรมชุดตัวอย่างการฝึกอบรม โหนดผู้ปฏิบัติงานจะดึงน้ำหนักจากเซิร์ฟเวอร์ก่อนประมวลผลทุกชุด โหนดผู้ปฏิบัติงานจะส่งการไล่ระดับสีไปยังเซิร์ฟเวอร์เมื่อชุดงานได้รับการประมวลผล

เซิร์ฟเวอร์

MXNet สามารถมีเซิร์ฟเวอร์หลายเครื่องสำหรับจัดเก็บพารามิเตอร์ของโมเดลและเพื่อสื่อสารกับโหนดของผู้ปฏิบัติงาน

เครื่องมือจัดกำหนดการ

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

เค. วี. สโตร์

ร้าน KV ย่อมาจาก Key-Valueเก็บ. เป็นองค์ประกอบสำคัญที่ใช้สำหรับการฝึกอบรมหลายอุปกรณ์ เป็นสิ่งสำคัญเนื่องจากการสื่อสารของพารามิเตอร์ระหว่างอุปกรณ์ในเครื่องเดียวและหลายเครื่องจะถูกส่งผ่านเซิร์ฟเวอร์หนึ่งเครื่องขึ้นไปโดยมี KVStore สำหรับพารามิเตอร์ มาทำความเข้าใจการทำงานของ KVStore ด้วยความช่วยเหลือของประเด็นต่อไปนี้ -

  • แต่ละค่าใน KVStore แสดงด้วยไฟล์ key และก value.

  • อาร์เรย์พารามิเตอร์แต่ละตัวในเครือข่ายถูกกำหนด a key และน้ำหนักของอาร์เรย์พารามิเตอร์นั้นถูกอ้างถึงโดย value.

  • หลังจากนั้นผู้ปฏิบัติงานก็โหน pushการไล่ระดับสีหลังจากประมวลผลชุดงาน พวกเขาด้วยpull ปรับปรุงน้ำหนักก่อนประมวลผลชุดใหม่

แนวคิดของเซิร์ฟเวอร์ KVStore มีเฉพาะในระหว่างการฝึกอบรมแบบกระจายและโหมดกระจายของเซิร์ฟเวอร์จะเปิดใช้งานโดยการโทร mxnet.kvstore.create ฟังก์ชันที่มีอาร์กิวเมนต์สตริงที่มีคำ dist -

kv = mxnet.kvstore.create(‘dist_sync’)

การกระจายคีย์

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

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

แยกข้อมูลการฝึกอบรม

ในฐานะผู้ใช้เราต้องการให้แต่ละเครื่องทำงานในส่วนต่างๆของชุดข้อมูลโดยเฉพาะอย่างยิ่งเมื่อเรียกใช้การฝึกอบรมแบบกระจายในโหมดขนานข้อมูล เรารู้ว่าในการแยกกลุ่มตัวอย่างที่จัดเตรียมโดยตัววนข้อมูลสำหรับการฝึกอบรมข้อมูลแบบขนานกับผู้ปฏิบัติงานคนเดียวเราสามารถใช้ได้mxnet.gluon.utils.split_and_load จากนั้นโหลดแต่ละส่วนของแบตช์บนอุปกรณ์ซึ่งจะประมวลผลต่อไป

ในทางกลับกันในกรณีของการฝึกอบรมแบบกระจายในตอนแรกเราจำเป็นต้องแบ่งชุดข้อมูลออกเป็น nส่วนต่างๆเพื่อให้คนงานทุกคนได้รับส่วนที่แตกต่างกัน เมื่อได้มาแล้วผู้ปฏิบัติงานแต่ละคนสามารถใช้งานได้split_and_loadเพื่อแบ่งส่วนของชุดข้อมูลอีกครั้งในอุปกรณ์ต่างๆในเครื่องเดียว ทั้งหมดนี้เกิดขึ้นผ่าน data iteratormxnet.io.MNISTIterator และ mxnet.io.ImageRecordIter เป็นตัวทำซ้ำสองตัวใน MXNet ที่รองรับคุณสมบัตินี้

กำลังอัปเดตน้ำหนัก

สำหรับการอัปเดตน้ำหนัก KVStore รองรับสองโหมดต่อไปนี้ -

  • วิธีแรกจะรวบรวมการไล่ระดับสีและอัปเดตน้ำหนักโดยใช้การไล่ระดับสีเหล่านั้น

  • ในวิธีที่สองเซิร์ฟเวอร์จะรวบรวมเฉพาะการไล่ระดับสี

หากคุณใช้ Gluon มีตัวเลือกให้เลือกระหว่างวิธีการที่ระบุไว้ข้างต้นโดยการส่งผ่าน update_on_kvstoreตัวแปร. มาทำความเข้าใจกันด้วยการสร้างไฟล์trainer วัตถุดังต่อไปนี้ -

trainer = gluon.Trainer(net.collect_params(), optimizer='sgd',
   optimizer_params={'learning_rate': opt.lr,
      'wd': opt.wd,
      'momentum': opt.momentum,
      'multi_precision': True},
      kvstore=kv,
   update_on_kvstore=True)

รูปแบบของการฝึกอบรมแบบกระจาย

หากสตริงการสร้าง KVStore มีคำว่า dist หมายความว่ามีการเปิดใช้งานการฝึกอบรมแบบกระจาย ต่อไปนี้เป็นโหมดต่างๆของการฝึกอบรมแบบกระจายที่สามารถเปิดใช้งานได้โดยใช้ KVStore ประเภทต่างๆ -

dist_sync

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

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

dist_async

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

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

dist_sync_device

โหมดนี้เหมือนกับ dist_syncโหมด. ข้อแตกต่างเพียงอย่างเดียวคือเมื่อมีการใช้ GPU หลายตัวในทุกโหนดdist_sync_device รวมการไล่ระดับสีและอัปเดตน้ำหนักบน GPU ในขณะที่ dist_sync รวมการไล่ระดับสีและปรับปรุงน้ำหนักของหน่วยความจำ CPU

ช่วยลดการสื่อสารที่มีราคาแพงระหว่าง GPU และ CPU นั่นคือเหตุผลที่มันเร็วกว่าdist_sync. ข้อเสียคือเพิ่มการใช้หน่วยความจำบน GPU

dist_async_device

โหมดนี้ใช้งานได้เช่นเดียวกับ dist_sync_device โหมด แต่อยู่ในโหมดอะซิงโครนัส