แนวทางปฏิบัติที่ดีที่สุดสำหรับการฝึกอบรมการเร่งความเร็ว TensorFlow 1.x บน Amazon SageMaker PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI.

แนวทางปฏิบัติที่ดีที่สุดสำหรับการฝึกอบรมการเร่งความเร็ว TensorFlow 1.x บน Amazon SageMaker

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

อเมซอน SageMaker เป็นแพลตฟอร์มแมชชีนเลิร์นนิงที่มีการจัดการเต็มรูปแบบ (ML) ที่สามารถช่วยให้นักวิทยาศาสตร์ข้อมูลมุ่งเน้นไปที่โมเดลแทนโครงสร้างพื้นฐาน โดยได้รับการสนับสนุนแบบเนทีฟสำหรับอัลกอริทึมและเฟรมเวิร์กที่นำมาใช้เอง เช่น TensorFlow และ PyTorch SageMaker เสนอตัวเลือกการฝึกอบรมแบบกระจายที่ยืดหยุ่นซึ่งปรับให้เข้ากับเวิร์กโฟลว์เฉพาะของคุณ เนื่องจากนักวิทยาศาสตร์ด้านข้อมูลจำนวนมากอาจขาดประสบการณ์ในกระบวนการฝึกอบรมการเร่งความเร็ว ในโพสต์นี้ เราจึงแสดงปัจจัยที่สำคัญสำหรับการฝึกโมเดล Deep Learning อย่างรวดเร็วและแนวทางปฏิบัติที่ดีที่สุดของการฝึกการเร่งความเร็วสำหรับ TensorFlow 1.x บน SageMaker เรายังมีโค้ดตัวอย่างของ ดีพเอฟเอ็ม แจกจ่ายการฝึกอบรมเกี่ยวกับ SageMaker บน repo GitHub.

มีหลายปัจจัยที่คุณควรพิจารณาเพื่อเพิ่มการใช้งาน CPU/GPU ให้สูงสุดเมื่อคุณเรียกใช้สคริปต์ TensorFlow บน SageMaker เช่น โครงสร้างพื้นฐาน ประเภทของตัวเร่งความเร็ว วิธีการฝึกอบรมแบบกระจาย วิธีการโหลดข้อมูล การฝึกอบรมที่มีความแม่นยำแบบผสม และอื่นๆ

เราหารือเกี่ยวกับแนวทางปฏิบัติที่ดีที่สุดในด้านต่อไปนี้:

  • เร่งการฝึกอบรมในอินสแตนซ์เดียว
  • เร่งการฝึกอบรมในหลาย ๆ อินสแตนซ์
  • ไปป์ไลน์ข้อมูล
  • การฝึกอบรมความแม่นยำแบบผสมอัตโนมัติ

เร่งการฝึกอบรมในอินสแตนซ์เดียว

เมื่อเรียกใช้สคริปต์ TensorFlow ของคุณในอินสแตนซ์เดียว คุณสามารถเลือกซีรีส์ที่ปรับให้เหมาะกับคอมพิวเตอร์ เช่น อเมซอน อีลาสติก คอมพิวท์ คลาวด์ (Amazon EC2) C5 ซีรีส์หรือซีรีส์การประมวลผลแบบเร่งความเร็วที่มี GPU หลายตัวในอินสแตนซ์เดียว เช่น p3.8xlarge, p3.16xlarge, p3dn.24xlarge และ p4d.24xlarge

ในส่วนนี้ เราจะพูดถึงกลยุทธ์สำหรับ CPU หลายตัวในอินสแตนซ์เดียว และการฝึกอบรมแบบกระจายด้วย GPU หลายตัวในอินสแตนซ์เดียว

CPU หลายตัวในอินสแตนซ์เดียว

ในส่วนนี้ เราจะพูดถึงการตั้งค่าความขนานของผู้ปฏิบัติงานบนอุปกรณ์ CPU, วิธีทาวเวอร์, TensorFlow MirroredStrategy และ Horovod ด้วยตนเอง

ตั้งค่าความขนานของผู้ปฏิบัติงานบนอุปกรณ์ CPU ด้วยตนเอง

TensorFlow จะเลือกจำนวนเธรดที่เหมาะสมโดยอัตโนมัติเพื่อขนานการคำนวณการดำเนินการในกระบวนการฝึกอบรม อย่างไรก็ตาม คุณสามารถตั้งค่า intra_op สระเธรดและ inter_op การตั้งค่าความขนานที่จัดเตรียมโดย TensorFlow และใช้ตัวแปรสภาพแวดล้อมของ MKL-DNN เพื่อตั้งค่าการเชื่อมโยงสำหรับเธรด OS ดูรหัสต่อไปนี้:

# Set parallelism of intra_op and inter_op
num_cpus = int(os.environ['SM_NUM_CPUS'])
config = tf.ConfigProto(allow_soft_placement=True, device_count={'CPU': num_cpus}, intra_op_parallelism_threads=num_cpus, inter_op_parallelism_threads=num_cpus)
run_config = tf.estimator.RunConfig().replace(session_config = config)

# Use Intel MKL-DNN Setting to accelerate training speed
os.environ["KMP_AFFINITY"]= "verbose,disabled"
os.environ['OMP_NUM_THREADS'] = str(num_cpus)
os.environ['KMP_SETTINGS'] = '1'

ตัวแปรสภาพแวดล้อม KMP_AFFINITY ของ MKL-DNN ถูกตั้งค่าเป็น granularity=fine,compact,1,0 โดยค่าเริ่มต้น. หลังจากตั้งค่าทั้งอินทราและอินเตอร์ของ TensorFlow เป็นจำนวนสูงสุดของ vCPU ของอินสแตนซ์ปัจจุบัน ขีดจำกัดสูงสุดของการใช้งาน CPU จะใกล้เคียงกับจำนวนคอร์จริงของอินสแตนซ์การฝึก

หากตั้งไว้ os.environ["KMP_AFFINITY"]= "verbose,disabled"เธรด OS ไม่ได้ผูกกับไฮเปอร์เธรดของฮาร์ดแวร์ และการใช้งาน CPU อาจเกินจำนวนฟิสิคัลคอร์

เกี่ยวกับการตั้งค่าของ TensorFlow intra parallelism, TensorFlow inter parallelism และจำนวนเธรด MKL-DNN การรวมกันของพารามิเตอร์ทั้งสามนี้ส่งผลให้ความเร็วในการฝึกอบรมต่างกัน ดังนั้น คุณต้องทดสอบแต่ละกรณีเพื่อหาชุดค่าผสมที่ดีที่สุด สถานการณ์ทั่วไปคือการตั้งค่าสามพารามิเตอร์ (intra_op_parallelism_threads และ inter_op_parallelism_threads สำหรับ TensorFlow os.environ['OMP_NUM_THREADS'] สำหรับ MKL-DNN) ให้เหลือครึ่งหนึ่งของ vCPU (คอร์จริง) หรือจำนวน vCPU ทั้งหมด

วิธีทาวเวอร์

ในการทำซ้ำโมเดลบน GPU นั้น GPU แต่ละตัวจะได้รับอินสแตนซ์ Forward Pass ของตัวเอง ตัวอย่างของการส่งต่อเรียกว่าa หอคอย. วิธีการแบบทาวเวอร์มักใช้กับอุปกรณ์ GPU เพื่อเปรียบเทียบความเร็วในการฝึกกับวิธีอื่นๆ ในที่นี้ เรายังใช้วิธีทาวเวอร์สำหรับอุปกรณ์ CPU ของเราด้วย

หากคุณไม่ได้ตั้งค่าอุปกรณ์ CPU ด้วยตนเอง TensorFlow จะไม่ใช้วิธีทาวเวอร์ในการเฉลี่ยการไล่ระดับสี ดังนั้นคุณจึงไม่จำเป็นต้องปรับขนาดขนาดแบทช์ในกรณีดังกล่าว

  1. ตั้งค่าอุปกรณ์ CPU ด้วยตนเอง:
device_list = []
if manual_CPU_device_set:
		cpu_prefix=’/cpu:’
		for I in range(1, num_cpus):
			devices_list.append(cpu_prefix + str(i))

  1. ใช้ replicate_model_fn ห่อ model_fn:
DeepFM = tf.estimator.Estimator(model_fn=tf.contrib.estimator.replicate_model_fn(model_fn, devices=device_list), model_dir=FLAGS.model_dir, params=model_params, config=config)

  1. ใช้ TowerOptimizer ห่อ optimizer:
optimizer = tf.contrib.estimator.TowerOptimizer(optimizer)

  1. ห่อไฟล์ model_fn:
with tf.variable_scope(‘deepfm_model’, reuse=tf.AUTO_REUSE)

  1. ปรับขนาดแบทช์เป็น (NUM_CPU – 1)

มาดูความแตกต่างของการใช้งาน CPU ที่เปิดใช้งานโหมดทาวเวอร์กัน รูปต่อไปนี้แสดงการใช้งาน CPU ของอินสแตนซ์ ml.c5.18xlarge พร้อมการกำหนดค่าต่อไปนี้:

ไม่มีข้อมูล Tower + LibSVM + โหมดไปป์ + MKL-DNN ปิดใช้งานการเชื่อมโยง + การตั้งค่า TensorFlow intra/inter op Parallelism เป็นจำนวนสูงสุดของ vCPU ของอินสแตนซ์

ไม่มีทาวเวอร์

รูปต่อไปนี้แสดงการใช้งาน CPU ของอินสแตนซ์ ml.c5.18xlarge พร้อมการกำหนดค่าต่อไปนี้:

Tower พร้อมชุดอุปกรณ์ CPU + ข้อมูล LibSVM + โหมดไปป์ + MKL-DNN ปิดใช้งานการเชื่อมโยง + การตั้งค่า TensorFlow intra/inter op Parallelism เป็นจำนวนสูงสุดของ vCPU ของอินสแตนซ์

การใช้งาน CPU จะสูงขึ้นเมื่อใช้วิธีทาวเวอร์ และมีจำนวนคอร์เกินจริง

TensorFlow Mirroredกลยุทธ์

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

เมื่อใช้ TensorFlow MirroredStrategy หากคุณไม่ได้ตั้งค่าอุปกรณ์ CPU ไว้ TensorFlow จะใช้ CPU เพียงตัวเดียวในฐานะผู้ปฏิบัติงานคนเดียว ซึ่งเป็นการสิ้นเปลืองทรัพยากร เราแนะนำให้ตั้งค่าอุปกรณ์ CPU ด้วยตนเอง เนื่องจากจะทำการลดการทำงานบน /CPU:0ดังนั้น /CPU:0 อุปกรณ์ไม่ได้ใช้เป็นแบบจำลองที่นี่ ดูรหัสต่อไปนี้:

device_list = []
if manual_CPU_device_set:
		cpu_prefix=’/cpu:’
		for I in range(1, num_cpus):
			devices_list.append(cpu_prefix + str(i))
mirrored_strategy = tf.distribute.MirroredStrategy(devices=devices_list)
	else:
mirrored_strategy = tf.distribute.MirroredStrategy()

# Set strategy to config:
config = tf.estimator.RunConfig(train_distribute=mirrored_strategy,
eval_distribute=mirrored_strategy,
session_config = config)

คุณต้องปรับขนาดแบทช์เมื่อใช้ MirroredStrategy ตัวอย่างเช่น ปรับขนาดแบทช์เป็นหลาย ๆ ของอุปกรณ์ GPU

สำหรับกลยุทธ์ย่อยเมื่อคุณตั้งค่าอุปกรณ์ CPU หากคุณไม่ได้ตั้งค่า cross_device_ops พารามิเตอร์ใน tf.distribute.MirroredStrategy(), TensorFlow ใช้ ReductionToOneDevice กลยุทธ์ย่อยโดยค่าเริ่มต้น อย่างไรก็ตาม หากคุณตั้งค่า HierarchicalCopyAllReduce ในฐานะที่เป็นกลยุทธ์ย่อย TensorFlow ก็แค่ลดการทำงานบน /CPU:0. เมื่อคุณใช้ API ชุดข้อมูล TensorFlow และแจกจ่ายกลยุทธ์ร่วมกัน ควรส่งคืนวัตถุชุดข้อมูลแทนคุณลักษณะและป้ายกำกับในฟังก์ชัน input_fn.

โดยปกติ TensorFlow MirroredStrategy จะช้ากว่าวิธีทาวเวอร์ในการฝึก CPU ดังนั้นเราจึงไม่แนะนำให้ใช้ MirroredStrategy บนโฮสต์เดี่ยวที่มี CPU หลายตัว

ฮอโรวอด

ฮอโรวอด เป็นเฟรมเวิร์กการฝึกอบรมการเรียนรู้เชิงลึกแบบกระจายสำหรับ TensorFlow, Keras, PyTorch และ Apache MXNet เป้าหมายของ Horovod คือการทำให้การเรียนรู้เชิงลึกแบบกระจายอย่างรวดเร็วและใช้งานง่าย

มีพารามิเตอร์ของ distribution ใน SageMaker Python SDK Estimator API ซึ่งคุณสามารถใช้เพื่อระบุการฝึกอบรมแบบกระจาย Horovod SageMaker จัดเตรียมโครงสร้างพื้นฐานและเรียกใช้สคริปต์ของคุณด้วย MPI ดูรหัสต่อไปนี้:

hvd_processes_per_host = 4
distribution = {'mpi': { 
'enabled': True, 
'processes_per_host': hvd_processes_per_host,
'custom_mpi_options': '-verbose --NCCL_DEBUG=INFO -x OMPI_MCA_btl_vader_single_copy_mechanism=none' 
} 
}

เมื่อเลือกอินสแตนซ์ GPU เช่น ml.p3.8xlarge คุณต้องตรึง GPU แต่ละตัวสำหรับผู้ปฏิบัติงานทุกคน:

config = tf.ConfigProto()
config.gpu_options.visible_device_list = str(hvd.local_rank())

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

โดยทั่วไป เฉพาะหลัก (Horovod rank 0) เท่านั้นที่จะบันทึกจุดตรวจและแบบจำลองตลอดจนการดำเนินการประเมินผล คุณไม่จำเป็นต้องปรับขนาดแบทช์เมื่อใช้ Horovod ข้อเสนอของ SageMaker โหมดท่อ เพื่อสตรีมข้อมูลจาก บริการจัดเก็บข้อมูลอย่างง่ายของ Amazon (Amazon S3) ลงในอินสแตนซ์การฝึกอบรม เมื่อคุณเปิดใช้งานโหมดไปป์ โปรดทราบว่าผู้ปฏิบัติงานที่แตกต่างกันบนโฮสต์เดียวกันจำเป็นต้องใช้ช่องทางที่แตกต่างกันเพื่อหลีกเลี่ยงข้อผิดพลาด เนื่องจากกระบวนการของผู้ปฏิบัติงานแรกอ่านข้อมูล FIFO/ช่องทาง และกระบวนการของผู้ปฏิบัติงานอื่นๆ ในอินสแตนซ์เดียวกันจะหยุดทำงาน เนื่องจากไม่สามารถอ่านข้อมูลจาก FIFO/ช่องทางเดียวกันได้ ดังนั้น Horovod จึงทำงานไม่ถูกต้อง เพื่อหลีกเลี่ยงปัญหานี้ ให้ตั้งค่าช่องทางตามจำนวนผู้ปฏิบัติงานต่ออินสแตนซ์ อย่างน้อยต้องแน่ใจว่าผู้ปฏิบัติงานต่างกันในโฮสต์เดียวกันใช้ช่องทางต่างกัน ผู้ปฏิบัติงานสามารถใช้ช่องทางเดียวกันบนโฮสต์อื่นได้

เมื่อใช้ Horovod คุณอาจพบข้อผิดพลาดต่อไปนี้:

“One or more tensors were submitted to be reduced, gathered or broadcasted by subset of ranks and are waiting for remainder of ranks for more than 60 seconds. This may indicate that different ranks are trying to submit different tensors or that only subset of ranks is submitting tensors, which will cause deadlock.”

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

การแบ่งกลุ่มข้อมูลถือเป็นหนึ่งในสิ่งสำคัญที่สุดที่ควรพิจารณาเมื่อใช้การฝึกอบรมแบบกระจาย คุณสามารถใช้ TensorFlow dataset.shard() ในสคริปต์ของคุณ SageMaker ยังมีฟีเจอร์ชาร์ดชุดข้อมูลใน ช่องสัญญาณเข้า โดยการตั้งค่า distribution=S3shardbykey ในช่องชุดข้อมูล ดูรหัสต่อไปนี้:

dataset = PipeModeDataset(channel, record_format='TFRecord')

number_host = len(FLAGS.hosts)

if FLAGS.enable_data_multi_path : # If there are multi channels mapping with different S3 path
    if FLAGS.enable_s3_shard == False :
        if number_host > 1:
            index = hvd.rank() // FLAGS.worker_per_host
            dataset = dataset.shard(number_host, index)
else :
    if FLAGS.enable_s3_shard :
        dataset = dataset.shard(FLAGS.worker_per_host, hvd.local_rank())
    else :
        dataset = dataset.shard(hvd.size(), hvd.rank())

รูปต่อไปนี้แสดงผลเมื่อใช้ Horovod (ml.c5.18xlarge, Horovod + LibSVM + การตั้งค่า intra op และ inter op เริ่มต้น) ซึ่งคุณสามารถเปรียบเทียบกับวิธีทาวเวอร์ได้

โฮโรโวด

การฝึกอบรมแบบกระจายด้วย GPU หลายตัวในอินสแตนซ์เดียว

เป็นเรื่องปกติที่จะเริ่มการฝึกอบรมแบบกระจายด้วย GPU หลายตัวในอินสแตนซ์เดียว เนื่องจากนักวิทยาศาสตร์ข้อมูลจำเป็นต้องจัดการเพียงอินสแตนซ์เดียวและใช้ประโยชน์จากการเชื่อมโยงความเร็วสูงระหว่าง GPU งานการฝึกอบรม SageMaker รองรับอินสแตนซ์หลายประเภทที่มี GPU หลายตัวในอินสแตนซ์เดียว เช่น ml.p3.8xlarge, ml.p3.16xlarge, ml.p3dn.24xlarge และ ml.p4d.24xlarge วิธีการนี้เหมือนกับ CPU หลายตัวในอินสแตนซ์เดียว แต่มีการเปลี่ยนแปลงเล็กน้อยในสคริปต์

วิธีทาวเวอร์

วิธีการแบบทาวเวอร์ที่นี่เกือบจะเหมือนกับในการฝึกอบรมแบบหลาย CPU คุณต้องปรับขนาดแบทช์ตามจำนวน GPU ที่ใช้งาน

TensorFlow Mirroredกลยุทธ์

กลยุทธ์ย่อยเริ่มต้นของ MirroredStrategy is NcclAllReduce. คุณต้องปรับขนาดแบทช์ตามจำนวน GPU ที่ใช้งาน ดูรหัสต่อไปนี้:

mirrored_strategy = tf.distribute.MirroredStrategy()
config = tf.estimator.RunConfig(train_distribute=mirrored_strategy,
				eval_distribute=mirrored_strategy)

เร่งการฝึกอบรมในหลาย ๆ อินสแตนซ์

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

CPU หลายตัวที่มีหลายอินสแตนซ์

มีสี่วิธีหลักในการใช้ CPU หลายตัวกับหลายอินสแตนซ์เมื่อเปิดใช้งานการฝึกอบรมแบบกระจาย:

    • เซิร์ฟเวอร์พารามิเตอร์โดยไม่ต้องตั้งค่าความขนานของผู้ปฏิบัติงานบนอุปกรณ์ CPU
    • เซิร์ฟเวอร์พารามิเตอร์พร้อมการตั้งค่าความขนานของตัวดำเนินการบนอุปกรณ์ CPU ด้วยตนเอง
    • เซิร์ฟเวอร์พารามิเตอร์พร้อมทาวเวอร์ (ตั้งค่าอุปกรณ์ CPU ด้วยตนเอง และตั้งค่า allow_soft_placement=True in tf.ConfigProto)
    • ฮอโรวอด

เมื่อใช้เซิร์ฟเวอร์พารามิเตอร์ใน tf.estimator API เส้นทางของจุดตรวจจะต้องเป็นเส้นทางที่แชร์ได้ เช่น Amazon S3 หรือเส้นทางท้องถิ่นของ บริการไฟล์ Amazon Elastic (Amazon EFS) การแมปไปยังคอนเทนเนอร์ สำหรับเซิร์ฟเวอร์พารามิเตอร์ใน tf.kerasสามารถกำหนดเส้นทางจุดตรวจเป็นเส้นทางท้องถิ่นได้ สำหรับ Horovod เส้นทางของจุดตรวจสอบสามารถตั้งค่าเป็นเส้นทางท้องถิ่นของอินสแตนซ์การฝึกอบรมได้

เมื่อใช้เซิร์ฟเวอร์พารามิเตอร์และ tf.estimator API ที่มีเส้นทางของจุดตรวจสอบไปยัง Amazon S3 หากโมเดลมีขนาดค่อนข้างใหญ่ คุณอาจพบข้อผิดพลาดของหลักติดอยู่ที่จุดตรวจสอบการบันทึกไปยัง S3 คุณสามารถใช้คอนเทนเนอร์ในตัวของ SageMaker TensorFlow 1.15 หรือ TensorFlow 1.15.2 หรือใช้ Amazon EFS เป็นเส้นทางจุดตรวจสอบของการแชร์ได้

เมื่อใช้เซิร์ฟเวอร์พารามิเตอร์สำหรับหลายโฮสต์ โหลดพารามิเตอร์ในแต่ละกระบวนการเซิร์ฟเวอร์พารามิเตอร์อาจไม่สมดุล (โดยเฉพาะเมื่อมีตัวแปรตารางการฝังที่ค่อนข้างใหญ่) ซึ่งอาจทำให้เกิดข้อผิดพลาดได้ คุณสามารถตรวจสอบขนาดไฟล์ของแต่ละจุดตรวจสอบของชาร์ดใน Amazon S3 เพื่อตรวจสอบว่าพารามิเตอร์บนเซิร์ฟเวอร์พารามิเตอร์มีความสมดุลหรือไม่ เนื่องจากเซิร์ฟเวอร์พารามิเตอร์แต่ละตัวสอดคล้องกับชาร์ดของไฟล์จุดตรวจสอบ เพื่อหลีกเลี่ยงปัญหาดังกล่าว คุณสามารถใช้ฟังก์ชันตัวแบ่งพาร์ติชันเพื่อพยายามทำให้พารามิเตอร์ของเซิร์ฟเวอร์พารามิเตอร์แต่ละตัวกระจายเท่าๆ กัน:

with tf.variable_scope('deepfm_model', reuse=tf.AUTO_REUSE, partitioner = tf.fixed_size_partitioner(num_shards=len(FLAGS.hosts))):

GPU เดียวที่มีหลายอินสแตนซ์

งานการฝึกอบรม SageMaker รองรับอินสแตนซ์ที่มี GPU เพียงตัวเดียว เช่น ml.p3.xlarge, ml.g4dn และ ml.g5 ซีรีส์ มีสองวิธีหลักที่ใช้ในสถานการณ์นี้: เซิร์ฟเวอร์พารามิเตอร์และ Horovod

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

สำหรับ Horovod เพียงแค่ตั้งค่า processes_per_host=1 ในพารามิเตอร์การกระจายของ SageMaker Python Estimator API

GPU หลายตัวพร้อมหลายอินสแตนซ์

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

สำหรับ Horovod ให้ตั้งค่า process_per_host ในพารามิเตอร์การแจกจ่ายเป็นจำนวน GPU ของอินสแตนซ์การฝึกอบรมแต่ละรายการ หากคุณใช้โหมดไปป์ จำนวนผู้ปฏิบัติงานต่ออินสแตนซ์จะต้องตรงกับจำนวนช่องสัญญาณ

ไปป์ไลน์ข้อมูล

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

เมื่อคุณพยายามเพิ่มประสิทธิภาพไปป์ไลน์การป้อนข้อมูล TensorFlow ให้พิจารณาลำดับ API ที่ใช้ใน ชุดข้อมูล TensorFlow, ขนาดข้อมูลการฝึก (ไฟล์ขนาดเล็กจำนวนมากหรือไฟล์ขนาดใหญ่หลายไฟล์) ขนาดแบทช์เป็นต้น

มาดูการโต้ตอบระหว่าง GPU และ CPU ระหว่างการฝึกกัน ตัวเลขต่อไปนี้เปรียบเทียบการโต้ตอบที่มีและไม่มีไปป์ไลน์

ท่อ

ไปป์ไลน์ที่ดีขึ้นสามารถลดเวลาที่ไม่ได้ใช้งานของ GPU ได้ พิจารณาคำแนะนำต่อไปนี้:

  • ใช้ตรรกะของฟังก์ชันอย่างง่ายในการแยกคุณลักษณะและป้ายกำกับ
  • ดึงตัวอย่างไปยังหน่วยความจำล่วงหน้า
  • ลดดิสก์ I/O และเครือข่าย I/O . ที่ไม่จำเป็น
  • แคชคุณสมบัติและป้ายกำกับที่ประมวลผลในหน่วยความจำ
  • ลดจำนวนครั้งการจำลองระหว่าง CPU และ GPU
  • ให้พนักงานแต่ละคนจัดการกับส่วนต่าง ๆ ของชุดข้อมูลการฝึกอบรม
  • ลดเวลาในการเรียกชุดข้อมูล TensorFlow API

TensorFlow จัดเตรียม API การแปลงที่เกี่ยวข้องกับรูปแบบชุดข้อมูล และลำดับของ API การแปลงใน TensorFlow ส่งผลต่อความเร็วในการฝึกอบรมเป็นอย่างมาก ต้องทดสอบลำดับที่ดีที่สุดในการเรียกใช้ชุดข้อมูล TensorFlow ต่อไปนี้เป็นหลักการพื้นฐานบางประการ:

  • ใช้แผนที่เวกเตอร์ ซึ่งหมายความว่าเรียกชุดข้อมูลชุดข้อมูล TensorFlow ก่อน แล้วจึงเรียก API ชุดข้อมูล ฟังก์ชันการแยกวิเคราะห์แบบกำหนดเองที่มีให้ในฟังก์ชันแผนที่ เช่น decode_tfrecord ในโค้ดตัวอย่าง แยกวิเคราะห์ชุดข้อมูลขนาดเล็ก ในทางตรงกันข้าม แมปก่อนแล้วจึงแบทช์เป็นแมปสเกลาร์ และฟังก์ชัน parser ที่กำหนดเองจะประมวลผลเพียงตัวอย่างเดียว
  • ใช้ API แคชชุดข้อมูล TensorFlow เพื่อแคชคุณสมบัติและป้ายกำกับ วาง API แคชชุดข้อมูล TensorFlow ก่อน API ซ้ำชุดข้อมูล TensorFlow มิฉะนั้น การใช้ RAM จะเพิ่มขึ้นตามยุคเชิงเส้นตามยุค หากชุดข้อมูลมีขนาดใหญ่เท่ากับ RAM อย่าใช้ API แคชชุดข้อมูล TensorFlow หากคุณต้องการใช้ API แคชชุดข้อมูล TensorFlow และ API สับเปลี่ยน ให้พิจารณาใช้ลำดับต่อไปนี้: สร้างวัตถุชุดข้อมูล TensorFlow -> แคช API -> สับเปลี่ยน API -> แบตช์ API -> แผนที่ API -> ทำซ้ำ API -> ดึงข้อมูล API ล่วงหน้า
  • ใช้ tfrecord รูปแบบชุดข้อมูลมากกว่ารูปแบบ LibSVM
  • โหมดไฟล์หรือโหมดไปป์ขึ้นอยู่กับรูปแบบชุดข้อมูลและจำนวนไฟล์ของคุณ ดิ tfrecorddataset API สามารถตั้งค่าได้ num_parallel_reads เพื่ออ่านหลายไฟล์พร้อมกันและตั้งค่า buffer_size เพื่อเพิ่มประสิทธิภาพการอ่านข้อมูลในขณะที่ pipemodedataset API ไม่มีการตั้งค่าดังกล่าว โหมดไปป์เหมาะสำหรับสถานการณ์ที่ไฟล์เดียวมีขนาดใหญ่และจำนวนไฟล์ทั้งหมดมีขนาดเล็ก เราขอแนะนำให้ใช้งานการประมวลผลของ SageMaker เพื่อทำงานก่อนการประมวลผล เช่น การรวมหลายไฟล์เป็นไฟล์ที่ใหญ่กว่าตามป้ายกำกับ โดยใช้วิธีการสุ่มตัวอย่างเพื่อทำให้ชุดข้อมูลมีความสมดุลมากขึ้น และสับเปลี่ยนชุดข้อมูลที่สมดุล

ดูตัวอย่างโค้ดต่อไปนี้:

def decode_tfrecord(batch_examples):
        # The feature definition here should BE consistent with LibSVM TO TFRecord process.
        features = tf.parse_example(batch_examples,
                                           features={
                                               "label": tf.FixedLenFeature([], tf.float32),
                                               "ids": tf.FixedLenFeature(dtype=tf.int64, shape=[FLAGS.field_size]),
                                               "values": tf.FixedLenFeature(dtype=tf.float32, shape=[FLAGS.field_size]) 
                                           })
        
        batch_label = features["label"]
        batch_ids = features["ids"]
        batch_values = features["values"]
        
        return {"feat_ids": batch_ids, "feat_vals": batch_values}, batch_label


    def decode_libsvm(line):
        columns = tf.string_split([line], ' ')
        labels = tf.string_to_number(columns.values[0], out_type=tf.float32)
        splits = tf.string_split(columns.values[1:], ':')
        id_vals = tf.reshape(splits.values,splits.dense_shape)
        feat_ids, feat_vals = tf.split(id_vals,num_or_size_splits=2,axis=1)
        feat_ids = tf.string_to_number(feat_ids, out_type=tf.int32)
        feat_vals = tf.string_to_number(feat_vals, out_type=tf.float32)
        return {"feat_ids": feat_ids, "feat_vals": feat_vals}, labels

if FLAGS.pipe_mode == 0:
        dataset = tf.data.TFRecordDataset(filenames)
    else :
        # Enter Pipe mode
        dataset = PipeModeDataset(channel, record_format='TFRecord')
        
    if FLAGS.enable_s3_shard == False:
        host_rank = FLAGS.hosts.index(FLAGS.current_host)
        number_host = len(FLAGS.hosts)
        dataset = dataset.shard(number_host, host_rank)
    
    dataset = dataset.batch(batch_size, drop_remainder=True) # Batch size to use
    dataset = dataset.map(decode_tfrecord,
                          num_parallel_calls=tf.data.experimental.AUTOTUNE) 

    if num_epochs > 1:
        dataset = dataset.repeat(num_epochs)
    dataset = dataset.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)

สำหรับการฝึกอบรมเกี่ยวกับอินสแตนซ์ CPU ให้ตั้งค่าการขนานของ intra op, inter opและตัวแปรสภาพแวดล้อมของ MKL-DNN เป็นจุดเริ่มต้นที่ดี

การฝึกอบรมความแม่นยำแบบผสมอัตโนมัติ

สิ่งสุดท้ายที่เราพูดถึงคือการฝึกอบรมความแม่นยำแบบผสมอัตโนมัติ ซึ่งสามารถเร่งความเร็วและส่งผลให้ประสิทธิภาพของโมเดล ในขณะที่เขียนนี้ Nvidia V100 GPU (อินสแตนซ์ P3) และ A100 (อินสแตนซ์ P4dn) รองรับ Tensor core คุณสามารถเปิดใช้งานการฝึกอบรมที่มีความแม่นยำแบบผสมใน TensorFlow เมื่อใช้อินสแตนซ์ประเภทเหล่านั้น ตั้งแต่เวอร์ชัน 1.14 TensorFlow ได้รองรับการฝึกอบรมที่มีความแม่นยำแบบผสมอัตโนมัติ คุณสามารถใช้คำสั่งต่อไปนี้เพื่อรวมเครื่องมือเพิ่มประสิทธิภาพดั้งเดิมของคุณ:

tf.train.experimental.enable_mixed_precision_graph_rewrite(optimizer)

หากรุ่นมีขนาดเล็กและการใช้งาน GPU ต่ำ ก็ไม่มีประโยชน์ใด ๆ ของการฝึกอบรมความแม่นยำแบบผสมอัตโนมัติ หากโมเดลมีขนาดใหญ่ การฝึกความแม่นยำแบบผสมอัตโนมัติสามารถเร่งความเร็วในการฝึกได้

สรุป

เมื่อคุณเริ่มการฝึกโมเดลการเรียนรู้เชิงลึกใน SageMaker ให้พิจารณาเคล็ดลับต่อไปนี้เพื่อให้ได้ความเร็วในการฝึกอบรมที่เร็วขึ้น:

  • ลองใช้ multi-CPU, single-instance method หรือ single-GPU, single-instance method ก่อน หากการใช้งาน CPU/GPU สูงมาก (เช่น มากกว่า 90%) ให้ไปที่ขั้นตอนถัดไป
  • ลองใช้ CPU เพิ่มเติมในโฮสต์เดียวหรือหลาย GPU ในโฮสต์เดียว หากการใช้งานใกล้ถึงการใช้งานสูงสุดของ CPU หรือ GPU ให้ไปยังขั้นตอนถัดไป
  • ลองใช้ CPU หลายตัวหรือ GPU หลายตัวกับหลายโฮสต์
  • คุณต้องแก้ไขรหัสเมื่อใช้พารามิเตอร์เซิร์ฟเวอร์หรือ Horovod การแก้ไขโค้ดไม่เหมือนกันสำหรับ API แบบอิงเซสชัน TensorFlow tf.estimator API และ tf.keras เอพีไอ เซิร์ฟเวอร์พารามิเตอร์หรือ Horovod อาจแสดงความเร็วในการฝึกอบรมที่แตกต่างกันในกรณีการฝึกอบรมและงานที่แตกต่างกัน ดังนั้นให้ลองใช้ทั้งสองวิธีหากคุณมีเวลาและงบประมาณเพื่อกำหนดวิธีที่ดีที่สุด

จำคำแนะนำต่อไปนี้:

  • ตรวจสอบการใช้งานก่อนปรับขนาด เพิ่มประสิทธิภาพไปป์ไลน์ข้อมูลของคุณ และทำให้ CPU และ GPU ทับซ้อนกันในไทม์ไลน์
  • ขั้นแรกขยายขนาดแล้วขยายออก
  • หากคุณไม่สามารถสร้างการใช้งาน GPU ได้หลังจากวิธีการทั้งหมด ให้ลองใช้ CPU มีหลายกรณี (โดยเฉพาะสำหรับโมเดลการจัดอันดับอัตราการคลิกผ่าน) ที่เวลาการฝึกอบรมทั้งหมดของอินสแตนซ์ CPU นั้นสั้นกว่าและคุ้มค่ากว่าการฝึกอินสแตนซ์ GPU

เรายังมีตัวอย่างโค้ดใน repo GitHubซึ่งเราแสดงตัวอย่าง DeepFM สองตัวอย่างแบบกระจายการฝึกอบรมบน SageMaker หนึ่งคือเซิร์ฟเวอร์พารามิเตอร์ TensorFlow บนอินสแตนซ์ของ CPU อีกอันหนึ่งคือ Horovod บนอินสแตนซ์ GPU


เกี่ยวกับผู้เขียน

แนวทางปฏิบัติที่ดีที่สุดสำหรับการฝึกอบรมการเร่งความเร็ว TensorFlow 1.x บน Amazon SageMaker PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI. ยูฮุยเหลียง เป็นสถาปนิก Sr. Machine Learning Solutions เขามุ่งเน้นไปที่การส่งเสริมและการประยุกต์ใช้แมชชีนเลิร์นนิง และมีส่วนร่วมอย่างลึกซึ้งในโครงการแมชชีนเลิร์นนิงของลูกค้าจำนวนมาก เขามีประสบการณ์มากมายในการเรียนรู้เชิงลึกแบบกระจายการฝึกอบรม ระบบการแนะนำ และการโฆษณาทางคอมพิวเตอร์

แนวทางปฏิบัติที่ดีที่สุดสำหรับการฝึกอบรมการเร่งความเร็ว TensorFlow 1.x บน Amazon SageMaker PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI.ฉือฉ่วย หวัง เป็นสถาปนิก Sr. Machine Learning Solutions เขาทำงานร่วมกับลูกค้า AWS เพื่อช่วยให้พวกเขานำแมชชีนเลิร์นนิงมาใช้ในวงกว้าง เขาชอบดูหนังและเดินทางรอบโลก

ประทับเวลา:

เพิ่มเติมจาก AWS Machine Learning AWS