เราขอแนะนำกลไกการอัปเดตน้ำหนักแบบ peer-to-peer (P2P) ที่ใช้ RDMA สำหรับงาน Reinforcement Learning ใน SGLang ซึ่งเป็นส่วนเสริมของวิธีการกระจายเสียงแบบ NCCL แบบดั้งเดิม โดยกลไกนี้เข้ากันได้กับโมเดลโอเพนซอร์สหลักทั้งหมด
- อัปเดตพารามิเตอร์ 1T ภายในไม่กี่วินาที – การถ่ายโอนน้ำหนักแบบ P2P ใน Reinforcement Learning แบบกระจายขนาดใหญ่
- https://www.lmsys.org/blog/2026-04-29-p2p-update/
- บทความเต็มประมาณ 6,000 คำ ใช้เวลาอ่าน 40 นาที เวอร์ชันพอดแคสต์ประมาณ 22 นาที
ด้วยการใช้ประโยชน์จากสำเนาเอ็นจิ้น CPU ฝั่งต้นทาง และ借助 Mooncake TransferEngine สำหรับการถ่ายโอน RDMA แบบ P2P เราสามารถเร่งเวลาการถ่ายโอนน้ำหนักของโมเดล Kimi-K2 ขนาด 1T พารามิเตอร์ได้ 7 เท่า (จาก 53 วินาทีเหลือ 7.2 วินาที) โดยมีค่าใช้จ่ายเพิ่มเติมคือสำเนาเอ็นจิ้นอนุมานผลบน CPU (ประมาณ 32GB) ต่อ rank การฝึกหนึ่งอัน
ตารางด้านล่างเปรียบเทียบประสิทธิภาพของโมเดลขนาดใหญ่ต่างๆ ภายใต้แผนการถ่ายโอนน้ำหนักทั้งแบบ NCCL และ RDMA ผลการทดสอบตั้งแต่โมเดล 9B ถึง 1T พารามิเตอร์แสดงให้เห็นว่าเมื่อขนาดโมเดลใหญ่ขึ้น ข้อได้เปรียบของ RDMA ก็ยิ่งเด่นชัด: สำหรับโมเดลขนาดเล็ก (เช่น GLM4-9B) อัตราเร่งเพียง 0.98 เท่า ในขณะที่โมเดล 744B และ 1T มีอัตราเร่งถึง 6.88 เท่า และ 7.37 เท่า ตามลำดับ โดยเวลาที่ใช้ลดลงจากหลายหมื่นมิลลิวินาทีเหลือเพียงไม่กี่พันมิลลิวินาที ซึ่งบ่งชี้ว่า RDMA มีประสิทธิภาพการถ่ายโอนที่เหนือกว่า NCCL อย่างมากในสถานการณ์ขนาดใหญ่และหลายโหนด และเหมาะสมกับความต้องการในการย้ายน้ำหนักของโมเดลขนาดใหญ่
การปรับให้เหมาะสมเหล่านี้ช่วยลดความซ้ำซ้อนของเครือข่ายได้สูงสุด และช่วยให้เซิร์ฟเวอร์อนุมานผลสามารถกู้คืนการทำงาน rollout ได้เร็วขึ้นอย่างเห็นได้ชัด
สารบัญ
- ประเด็นสำคัญ
- ประเด็นที่ 1 กับดักความสามารถในการขยายขนาดของ “แลกหน่วยความจำเพื่อแบนด์วิธ”: สำเนาเอ็นจิ้น CPU จะกลายเป็นคอขวดของผู้เช่าหลายรายรายใหม่หรือไม่?
- ประเด็นที่ 2 ความเสี่ยงของ “แคชชิ้นส่วน” ในการแมปแบบ many-to-one: ท่อส่งข้อมูลแบบ zero-copy จะถูกบล็อกอย่างเงียบๆ หรือไม่?
- ศูนย์. พื้นฐานการวิจัย
- RDMA (Remote Direct Memory Access)
- ปัญหาการถ่ายโอนน้ำหนักใน Reinforcement Learning
- หนึ่ง. ความท้าทายของการกระจายเสียง NCCL ในปัจจุบัน
- สอง. การออกแบบ
- 2.1 ขั้นตอนการเริ่มต้น
- 2.2 การอัปเดตแต่ละครั้ง
- สาม. ผลลัพธ์การนำไปใช้
- สี่. วิธีการใช้งาน
- ห้า. แผนงานในอนาคต
- หก. ภาคผนวกทางวิศวกรรม
- 6.1 การออกแบบซ้ำ
- 6.2 แผนการถ่ายโอนแบบ P2P
- 6.3 การระบุเทนเซอร์ SGLang ที่ต้องถ่ายโอน
- 6.4 ขั้นตอนการถ่ายโอนด้วยสำเนาที่ใช้ร่วมกัน
- 6.5 วิธีการ量化และหลังการประมวลผลอื่นๆ
ประเด็นสำคัญ
ประเด็นที่ 1 กับดักความสามารถในการขยายขนาดของ “แลกหน่วยความจำเพื่อแบนด์วิธ”: สำเนาเอ็นจิ้น CPU จะกลายเป็นคอขวดของผู้เช่าหลายรายรายใหม่หรือไม่?
แนวคิดหลักของบทความนี้คือการใช้สำเนาเอ็นจิ้นอนุมานผลฝั่ง CPU แบบเต็มรูปแบบเพิ่มเติมต่อ rank การฝึกฝั่งต้นทาง เพื่อขจัดการถ่ายโอนที่ซ้ำซ้อนของการกระจายเสียง NCCL สำหรับ Kimi-K2 ขนาด 1T พารามิเตอร์ ค่าใช้จ่ายเพิ่มเติมนี้คือหน่วยความจำ CPU 32GB ต่อ rank และมีอยู่พร้อมกันบนโหนดฝึก 32 โหนด บทความนี้ไม่ได้กล่าวถึงว่าเมื่อการกำหนดค่าการฝึกมีระดับความขนานของไปป์ไลน์ (pipeline parallelism) สูงขึ้น หรือจำเป็นต้องให้บริการอินสแตนซ์การอนุมานผลแบบต่างชนิดกันหลายตัวพร้อมกัน จำนวนสำเนาที่แต่ละ rank การฝึกต้องดูแลรักษาจะถูกบังคับให้เพิ่มขึ้นเป็นเส้นตรงหรือไม่ (เช่น แต่ละ rank ของ pipeline parallelism ต้องรักษามุมมองน้ำหนักแยกกันสำหรับสำเนา expert parallelism หลายชุด) เมื่อขนาดโมเดลพัฒนาไปสู่ 10T+ หน่วยความจำ CPU ของโหนดต้นทางจะกลายเป็นจุดพังทลายของระบบก่อนแบนด์วิธเครือข่ายหรือไม่? กลยุทธ์ “แลกพื้นที่เพื่อเวลา” นี้จำกัดความสามารถในการขยายขนาดของโซลูชันนี้สำหรับโมเดล Mixture of Experts ขนาดใหญ่พิเศษโดยพื้นฐานหรือไม่?
จะไม่ระเบิดเนื่องจากการเช่าหลายรายในการออกแบบปัจจุบัน แต่จะถึงเพดานความจุสัมบูรณ์แบบเส้นตรงเมื่อขนาดโมเดลเพิ่มขึ้น
ในการออกแบบ แต่ละ rank การฝึกฝั่งต้นทางจะดูแลรักษาสำเนาเอ็นจิ้นอนุมานผลเพียงชุดเดียวบน CPU (Kimi-K2 ขนาด 1T คือ 32GB) และใช้สำเนานี้ซ้ำแบบ isomorphic เพื่อส่งน้ำหนักไปยัง rank การอนุมานผลเป้าหมายหลายอัน ผู้เขียนระบุอย่างชัดเจนว่า “SGLang ranks ทั้งหมดเป็น isomorphic” ดังนั้นจึงหลีกเลี่ยงภัยพิบัติ O(M×N) ของการเพิ่มสำเนาตามจำนวนเป้าหมาย และปัญหา OOM ที่เกิดจากการระเบิดของสำเนา GPU ในช่วงแรกของการออกแบบได้รับการแก้ไขแล้วเมื่อย้ายไปยัง CPU
อย่างไรก็ตาม ความจุของสำเนาจะเพิ่มขึ้นเป็นเส้นตรงตามจำนวนพารามิเตอร์ของโมเดล เมื่อโมเดลขยายไปถึง 10T+ และใช้ความแม่นยำที่สูงขึ้น หน่วยความจำ CPU ที่จำกัดของโหนดเดียว (น้อยกว่าหน่วยความจำ GPU มาก) จะกลายเป็นคอขวดก่อนแบนด์วิธเครือข่าย ผู้เขียนไม่ได้เสนอแผนการใดๆ ในการบีบอัดขนาดสำเนา “แผนงานในอนาคต” กล่าวถึงเฉพาะเทคโนโลยี huge page เพื่อเร่งการลงทะเบียนหน่วยความจำ แต่ไม่ได้แตะต้องเพดานหน่วยความจำเอง ดังนั้น กลยุทธ์ “แลกพื้นที่เพื่อเวลา” นี้มีข้อจำกัดเชิงโครงสร้างในแง่ของความจุหน่วยความจำสัมบูรณ์ และภายใต้ขนาดที่ใหญ่พิเศษ หน่วยความจำ CPU คือจุดพังทลายที่แข็งเกร็ง
ประเด็นที่ 2 ความเสี่ยงของ “แคชชิ้นส่วน” ในการแมปแบบ many-to-one: ท่อส่งข้อมูลแบบ zero-copy จะถูกบล็อกอย่างเงียบๆ หรือไม่?
บทความนี้กล่าวถึงการแมปแบบ many-to-one จากเทนเซอร์ Hugging Face ไปยังเทนเซอร์ SGLang (เช่น q_proj/k_proj/v_proj → qkv_proj) ซึ่งจำเป็นต้องรอให้ชิ้นส่วนทั้งหมดถูกรวบรวมก่อนจึงจะสามารถเริ่มการถ่ายโอน RDMA ได้ และในช่วงเวลานั้นจำเป็นต้องแคชชิ้นส่วนเพิ่มเติมในสำเนา CPU (ทำให้บัฟเฟอร์ที่ต้องการ K* มีขนาดใหญ่กว่าค่าทางทฤษฎี K) *แม้ว่าบทความจะอ้างว่า “บัฟเฟอร์เพิ่มเติมจริงมีขนาดเล็ก” แต่ในสถานการณ์ที่รุนแรงต่อไปนี้ – เมื่อชิ้นส่วนเทนเซอร์กระจายอยู่ในการอัปเดตแบบ bucketed หลายครั้ง และลำดับการมาถึงของแต่ละชิ้นส่วนไม่ต่อเนื่องกันสูง – “การรอแคช” นี้จะสร้างความหน่วงแฝงส่วนท้ายที่ซ่อนอยู่หรือไม่? หรือแม้กระทั่งทำให้เกิดแคชล้นในการกำหนดค่า expert parallelism/tensor parallelism ขนาดใหญ่ บังคับให้�่ายฝึกต้องทำ secondary full collection? การพึ่งพาสมมติฐานเชิงประจักษ์ที่ว่า “พารามิเตอร์ที่มีชื่อเรียงลำดับกันเฉพาะที่” จะล้มเหลวเมื่อโครงสร้างโมเดลวิวัฒนาการหรือแผนการ quantization ที่กำหนดเองเปลี่ยนแปลงไปหรือไม่ ซึ่งจะทำลายท่อส่งข้อมูลแบบ zero-redundancy, zero-copy ที่ประกาศไว้ในปัจจุบัน?
ในโมเดลปัจจุบันและข้อตกลงการตั้งชื่อ ความเสี่ยงถูกกดไว้โดยเจตนา แต่ถ้าสมมติฐานเชิงประจักษ์ที่พึ่งพาล้มเหลว จะเกิดการบล็อกส่วนท้ายหรือแม้แต่แคชล้น
เนื่องจากการแมปแบบ many-to-one จากเทนเซอร์ Hugging Face ไปยังเทนเซอร์ SGLang (เช่น q_proj, k_proj, v_proj → qkv_proj) จำเป็นต้องรอให้ชิ้นส่วนทั้งหมดมาถึงก่อนจึงจะสามารถทริกเกอร์การส่ง RDMA ได้ จึงจำเป็นต้องมีบัฟเฟอร์เพิ่มเติม K* ในกรณีที่เลวร้ายที่สุด บัฟเฟอร์อาจมีขนาดเป็นหลายเท่าของจำนวนชิ้นส่วน *แต่ผู้เขียนเน้นย้ำว่า “โดยปกติแล้ว named_parameters จะจัดเรียงเทนเซอร์ที่เกี่ยวข้องกันไว้ด้วยกัน ดังนั้นบัฟเฟอร์เพิ่มเติมจริงจึงมีขนาดเล็กมาก” ดังนั้นความน่าจะเป็นที่ท่อส่งข้อมูลจะถูกบล็อกโดยชิ้นส่วนที่ไม่ต่อเนื่องกันเป็นเวลานานจึงต่ำ* การออกแบบจะวางการส่งไปยัง rank เป้าหมายแรกไว้บนเส้นทางวิกฤตเพื่อบังคับรอ และปล่อยการส่งไปยังเป้าหมายสุดท้ายลงใน thread pool เพื่อดำเนินการแบบอะซิงโครนัส ซึ่งช่วยซ่อนความหน่วงแฝงส่วนท้ายจากการรอชิ้นส่วนได้อีก
ความเสี่ยงอยู่ที่สมมติฐานนี้ไม่มีการรับประกันที่แข็งเกร็ง เมื่อโครงสร้างโมเดลวิวัฒนาการ แผนการ quantization เปลี่ยนแปลง หรือลำดับการตั้งชื่อชิ้นส่วนไม่เรียงลำดับเฉพาะที่อีกต่อไป การรวบรวมชิ้นส่วนจะครอบคลุมการอัปเดตแบบ bucketed หลายครั้ง ทำให้เส้นทางวิกฤตถูกระงับเป็นเวลานาน หากไม่มีการควบคุมล้น แคชฝั่ง CPU อาจหมดลง บังคับให้ระบบถอยกลับไปใช้ secondary full collection ซึ่งจะทำลายท่อส่งข้อมูลแบบ zero-copy โดยสิ้นเชิง ผู้เขียนไม่ได้ให้ขีดจำกัดบนที่แข็งเกร็งหรือกลไกการกู้คืนจากความล้มเหลวใดๆ โดยพึ่งพาข้อจำกัดทางวิศวกรรมเชิงประจักษ์เท่านั้น
ศูนย์. พื้นฐานการวิจัย
RDMA (Remote Direct Memory Access)
ปัญหาการถ่ายโอนน้ำหนักใน Reinforcement Learning
ข้อจำกัดของ NCCL และการพลิกเกมของ RDMA
NCCL ของ NVIDIA จะปรับให้เหมาะสมกับ primitives การสื่อสาร เช่น all-gather และ broadcast โดยการตรวจจับโทโพโลยีฮาร์ดแวร์โดยอัตโนมัติและประสานงานการไหลของข้อมูล โดยใช้อัลกอริทึมแบบ ring หรือ tree ในฐานะ backend การสื่อสารเริ่มต้นของ PyTorch FSDP, DeepSpeed และ Megatron-LM มันได้กลายเป็นมาตรฐานอุตสาหกรรมในด้านการฝึกแบบสมมาตร
อย่างไรก็ตาม NCCL อาศัย semantics การสื่อสารแบบรวม (collective communication) อย่างมาก ซึ่งกำหนดให้ ranks ทั้งหมดเรียกใช้การดำเนินการเดียวกันพร้อมกันด้วยรูปร่างข้อมูลที่ตรงกัน แม้ว่าการออกแบบนี้จะมีประสิทธิภาพสูงภายใต้ปริมาณงานที่สมดุล แต่ในสภาพแวดล้อมแบบไดนามิกกลับกลายเป็นอุปสรรค: NCCL ทำงานในลักษณะ lock-step ซึ่งหมายความว่า “การเริ่มต้นช้า” ของผู้รับเพียงรายเดียวอาจทำให้กลุ่มการสื่อสารทั้งหมดหยุดทำงานและทำให้ทรัพยากรว่างเปล่า
RDMA: การเข้าถึงหน่วยความจำระยะไกลโดยเลี่ยง CPU และเคอร์เนล
RDMA (Remote Direct Memory Access) อนุญาตให้เครื่องหนึ่งเข้าถึงหน่วยความจำของเครื่องระยะไกลได้โดยตรง โดยเลี่ยง CPU และสแต็กโปรโตคอลเครือข่ายของเคอร์เนลระยะไกลโดยสิ้นเชิง ประสิทธิภาพสูงของมันมาจากคุณสมบัติหลักสามประการ:
- Kernel Bypass: แอปพลิเคชันส่งคำขอทำงานไปยังการ์ดเครือข่ายโดยตรง ไม่ต้องผ่าน system call และ context switch ที่มีค่าใช้จ่ายสูง
- Zero Copy: ข้อมูลถูกถ่ายโอนโดยตรงระหว่างพื้นที่หน่วยความจำที่ลงทะเบียนกับเครือข่ายผ่าน DMA ไม่มีการคัดลอก中間ในบัฟเฟอร์เคอร์เนล
- การดำเนินการทางเดียว (One-sided Operations): การดำเนินการอ่าน/เขียนของ RDMA เริ่มต้นโดยฝ่ายเดียว ฝ่ายระยะไกลไม่จำเป็นต้องมี CPU เข้าร่วมหรือจัดการอินเทอร์รัปต์
แตกต่างจากการซิงโครไนซ์ทั่วโลกของ NCCL RDMA อนุญาตให้จุดปลายทางสองจุดใดๆ สื่อสารกันอย่างอิสระและพร้อมกัน ซึ่งทำให้มันเป็นรากฐานที่เหมาะสำหรับการถ่ายโอนน้ำหนักความเร็วสูง นี่คือเหตุผลที่กลไกการอัปเดตน้ำหนักแบบ P2P ในโซลูชันนี้ใช้การถ่ายโอนที่ใช้ RDMA และใช้ Mooncake TransferEngine เป็นโครงสร้างพื้นฐานระดับล่าง
ปัญหาการถ่ายโอนน้ำหนักในการฝึก RL
ในการฝึก RL แบบกระจายขนาดใหญ่ การถ่ายโอนน้ำหนักจาก Trainer ไปยัง Inference Engine เป็นการดำเนินการบนเส้นทางวิกฤต: ในระหว่างการถ่ายโอน การฝึก RL ทั้งหมดจะหยุดชะงัก – ทั้ง Trainer และ Inference ไม่มีความคืบหน้า ทรัพยากรมักจะอยู่ในสถานะว่าง
เมื่อขนาดโมเดลเพิ่มขึ้น การถ่ายโอนนี้ต้องขยายข้ามโฮสต์และแร็คหลายตัว ในขณะที่โหนดทั้งหมดแย่งชิงแบนด์วิธที่มีจำกัด เวิร์กโฟลว์ NCCL ที่มีอยู่ซึ่งใช้โซลูชันโอเพนซอร์ส เช่น miles/slime/verl อาศัย primitive การกระจายเสียงจาก rank ต้นทางเดียว ซึ่งจะกลายเป็นคอขวดอย่างรวดเร็วในระหว่างการถ่ายโอน
- รูปซ้าย: เวิร์กโฟลว์การถ่ายโอนน้ำหนักปัจจุบันใน miles ระหว่างการฝึก/อนุมาน RL แบบกระจาย ฝั่งต้นทาง โหนดทั้งหมดเข้าร่วมใน all-gather ในมิติ TP และ EP ทำให้ได้เทนเซอร์ที่รวมกันบน head rank ของแต่ละ PP rank head rank นี้เข้าร่วมในกลุ่มการอัปเดตแบบกระจาย โดยกระจายน้ำหนักเต็มรูปแบบไปยัง engine rank แต่ละตัวผ่าน API
update_weight_from_distributedซึ่ง rank ท้องถิ่นจะโหลดชิ้นส่วนที่สอดคล้องกัน กระบวนการนี้ทำงานสำหรับแต่ละ PP rank และแต่ละ bucketed weight tensor - รูปขวา: การออกแบบการอัปเดตแบบ P2P อาศัยสำเนา engine ฝั่งต้นทางเป็นตัวกลาง ขั้นตอนแรก all-gather ของการอัปเดตน้ำหนักแบบ bucketed จะเหมือนกับ miles แต่หลังจากนั้น น้ำหนักจะถูกโหลดลงในสำเนาท้องถิ่นของ SGLang engine shard บนหน่วยความจำ CPU ซึ่งจะส่งน้ำหนักของมันในรูปร่างที่ถูกต้องไปยัง SGLang น้ำหนักของแต่ละสำเนาสามารถส่งไปยัง SGLang rank หลายตัว SGLang TP rank เป้าหมายแต่ละตัวจำเป็นต้องรับข้อมูลจาก source pp แต่ละตัว
หนึ่ง. ความท้าทายสามประการของการกระจายเสียง NCCL ในปัจจุบัน
โซลูชันการกระจายเสียง NCCL ที่มีอยู่เผชิญกับความท้าทายดังต่อไปนี้:
- ความซ้ำซ้อนของข้อมูล: ข้อมูลเดียวกันถูกส่งผ่านเครือข่ายหลายครั้ง
- การบล็อกแบบซิงโครนัส: ความหน่วงของโหนดเดียวจะบล็อกกลุ่มการสื่อสารทั้งหมด ในสถานการณ์แบบไดนามิก จำเป็นต้องสร้างกลุ่ม NCCL ขึ้นใหม่
- ความสามารถในการขยายขนาดต่ำ: ในสถานการณ์โมเดลขนาดใหญ่และหลายโหนด การกระจายเสียงเองกลายเป็นคอขวดในการถ่ายโอน
ตารางด้านล่างเปรียบเทียบประสิทธิภาพของการถ่ายโอนโมเดล Kimi K2 FP8 ขนาด 1T (ประมาณ 1TB) หมายเหตุ: อินเทอร์เฟซ update_weights_from_tensor ถูกแยกออกเนื่องจากรองรับเฉพาะสถานการณ์การปรับใช้บนเครื่องเดียวกัน
ตารางเปรียบเทียบกลยุทธ์การโหลดน้ำหนักโมเดลขนาดใหญ่สี่แบบ โดยประเมินจากมิติต่างๆ เช่น ประสิทธิภาพ การรองรับโอเพนซอร์ส และความเป็นไดนามิก: Disk I/O ช้าแต่เรียบง่าย; NCCL Broadcast ค่อนข้างเร็วแต่มีความเป็นไดนามิกต่ำ; fabric-lib P2P เร็วที่สุดแต่ไม่ใช่โอเพนซอร์สและซับซ้อนมาก; RDMA P2P ที่พัฒนาขึ้นเองมีประสิทธิภาพปานกลาง สร้างสมดุลระหว่างโอเพนซอร์สและความเป็นไดนามิก มีความซับซ้อนปานกลาง รองรับหลาย API ทำให้เกิดความสมดุลระหว่างประสิทธิภาพและความสะดวกในการใช้งาน
แม้ว่าจะมีการแลกเปลี่ยนประสิทธิภาพการถ่ายโอนเมื่อเทียบกับวิธีการของ Perplexity แต่โซลูชันของเราให้การปรับปรุงประสิทธิภาพอย่างมีนัยสำคัญเมื่อเทียบกับอินเทอร์เฟซ SGLang ที่มีอยู่ นอกจากนี้ เรายังบรรลุความยืดหยุ่นทางสถาปัตยกรรมในระดับสูง โดยการห่อหุ้มความสามารถเหล่านี้ไว้ในอินเทอร์เฟซ API ใหม่ โปรดดูคำแนะนำการรันของ miles และรายการโมเดลที่รองรับทั้งหมด[1]
สอง. แนวคิดการออกแบบ
การออกแบบของเราเปลี่ยนจากการกระจายเสียงแบบรวมศูนย์ไปเป็นการแมป P2P แบบกระจายผ่าน RDMA ในขณะที่ยังคงความเข้ากันได้กับโมเดลโอเพนซอร์สที่มีอยู่ทั้งหมดและการกำหนดค่าขนานใดๆ และใช้ซ้ำอินเทอร์เฟซที่มีอยู่
- สำเนา Engine ฝั่งต้นทาง: เราสร้างสำเนาโมเดลในหน่วยความจำ CPU ของ training rank ซึ่งหลีกเลี่ยงการสิ้นเปลืองหน่วยความจำ GPU จากการลงทะเบียนและยกเลิกการลงทะเบียนซ้ำๆ
- ฮิวริสติกการแมป P2P: เรานำการแมปแบบ point-to-point ระหว่างเลเยอร์ Trainer และเลเยอร์ Inference มาใช้ แทนที่เลเยอร์จำนวนน้อยจะกระจายเสียงทุกอย่าง แต่ละเลเยอร์ Trainer จะเข้าร่วมโดยการส่งชิ้นส่วนเฉพาะของมันไปยังเป้าหมายโดยตรง
- การถ่ายโอนแบบ Zero-Copy: ด้วย TransferEngine หน่วยความจำจะถูกลงทะเบียนเพียงครั้งเดียวเมื่อเริ่มต้น ไม่จำเป็นต้องดำเนินการทำให้ handle IPC (Inter-Process Communication) ของ CUDA เป็นอนุกรมซึ่งใช้เวลานาน และไม่จำเป็นต้องดำเนินการคัดลอกฝั่งเคอร์เนล
การนำไปใช้นี้ขึ้นอยู่กับโครงสร้างพื้นฐานและอินเทอร์เฟซที่มีอยู่เป็นอย่างมาก:
- Transfer Engine[2] ทำหน้าที่เป็นเลเยอร์การขนส่งพื้นฐาน รองรับการถ่ายโอน RDMA แบบ zero-copy ระหว่าง CPU และ GPU บนเครือข่าย
- ใช้ Rfork[3] เพื่อนำข้อมูลการลงทะเบียนน้ำหนักกลับมาใช้ใหม่ ซึ่งเป็นกลไกการโหลดน้ำหนักอินสแตนซ์ระยะไกลรูปแบบใหม่ที่เปิดเผยผ่าน SGLang API
- SGLang API มาตรฐาน
load_weight(huggingface_tensor)รองรับการกำหนดค่า quantization และ sharding ทั้งหมด
ฝั่ง SGLang จำเป็นต้องเพิ่มอินเทอร์เฟซใหม่สองสามตัว:
- เปิดเผย model parallelism สำหรับการสร้างสำเนา: PR #20907[4]
- แมปเทนเซอร์ Hugging Face ไปยัง SGLang tensor shard ที่สอดคล้องกัน: PR #17326[5]
- เอ็นจิ้นการประมวลผลน้ำหนักภายหลัง (post-processing weight engine) ที่ต้องดำเนินการในเครื่อง GPU เช่น การประมวลผลหลัง quantization ที่คล้ายกับ PR #15245[6]
เนื้อหาเหล่านี้ถูกรวมเข้ากับสาขา sglang-miles ซึ่งมีเป้าหมายเป็น miles ในระหว่างการอัปเดตน้ำหนัก ฝ่ายเรียกใช้จะดำเนินการดังนี้:
2.1 ขั้นตอนการเริ่มต้น
กระบวนการสำคัญในการย้ายน้ำหนักโมเดลจากสภาพแวดล้อมการฝึกไปยังสภาพแวดล้อมการอนุมานผล: ขั้นแรกเรียก API เพื่อรับข้อมูลการลงทะเบียนน้ำหนัก จากนั้นรับการกำหนดค่าขนาน เช่น tensor parallelism (tp) และ expert parallelism (ep) จากนั้นสร้างความสัมพันธ์การแมประหว่าง training rank และ inference rank และสุดท้ายสร้างสำเนา engine CPU หัวใจของกระบวนการนี้คือการจัดแนวกลยุทธ์แบบขนานและการกระจายน้ำหนักระหว่างการฝึกและการอนุมานผล โดยการแมปที่แม่นยำเพื่อหลีกเลี่ยงข้อผิดพลาดในการโหลดที่เกิดจากความแตกต่างแบบขนาน เป็นรากฐานสำหรับการถ่ายโอนน้ำหนักที่มีประสิทธิภาพในภายหลัง (เช่น RDMA P2P) ทำให้การเชื่อมต่อระหว่างการฝึกและการอนุมานผลเป็นไปอย่างราบรื่น และเพิ่มประสิทธิภาพการปรับใช้โมเดลอย่างมาก
2.2 การอัปเดตแต่ละครั้ง
กระบวนการอัปเดตน้ำหนักโมเดลแบบ Hot Update: ขั้นแรกเรียก API เพื่อหยุด engine ชั่วคราวและลงทะเบียนน้ำหนักสำเนา จากนั้นอัปเดตน้ำหนักเป็นชิ้นส่วน (อัปเดตเลเยอร์ที่ไม่ใช่ expert ก่อน ตามด้วยเลเยอร์ expert เพื่อปรับให้เข้ากับโมเดล MoE) จากนั้นดำเนินการประมวลผลภายหลัง เช่น quantization กับน้ำหนักที่โหลด อัปเดตเวอร์ชันน้ำหนัก และสุดท้ายกู้คืนการทำงานของ engine กระบวนการนี้ผ่านการหยุดชั่วคราวที่ควบคุมได้ การอัปเดตเป็นชิ้นส่วน และการจัดการเวอร์ชัน ทำให้เกิดการวนซ้ำน้ำหนักที่มีผลกระทบต่อธุรกิจน้อยที่สุด รับประกันความเสถียรของบริการ รองรับการปรับให้เหมาะสมด้วย quantization ปรับให้เข้ากับโครงสร้างโมเดลขนาดใหญ่ เช่น MoE และเป็นโซลูชันการอัปเดตน้ำหนักโมเดลแบบ Hot Update ที่มีประสิทธิภาพและปลอดภัย
ผลลัพธ์ที่ได้คือการออกแบบการอัปเดตน้ำหนักแบบสากลที่สามารถจัดการกับโมเดลใดๆ และตรรกะ quantization ทั่วไปทั้งหมด ในขณะเดียวกันก็实现การถ่ายโอน RDMA แบบ zero-copy ที่รวดเร็วและไม่ซ้ำซ้อน และเพิ่มอัตราการใช้แบนด์วิธ
ลองนึกภาพสถานการณ์นี้:
- มีโหนดต้นทาง M โหนดสำหรับการฝึก และโหนดเป้าหมาย N โหนดสำหรับการอนุมานผล SGLang
- pp_size ของโหนดต้นทางสอดคล้องกับ pp และ ep_size ของโหนดเป้าหมายสอดคล้องกับ ep
- แต่ละโหนด engine มีพารามิเตอร์ P ตัว จัดสรร K เป็นบัฟเฟอร์หน่วยความจำสำหรับ all gather แบบเป็นชิ้นส่วน สมมติว่าโมเดลมีเฉพาะน้ำหนัก expert
ตารางนี้แสดงให้เห็นว่าการออกแบบ RDMA P2P สร้างสมดุลในการจัดสรรหน่วยความจำอย่างไร เพื่อลดการรับส่งข้อมูลเครือข่ายและเพิ่มอัตราการใช้ทรัพยากร กลุ่มกระบวนการต้นทางทั้งหมดเข้าร่วม ในขณะที่เมื่อใช้ NCCL เฉพาะกลุ่มกระบวนการหัวหน้าในแต่ละกลุ่ม pipeline parallelism เท่านั้นที่เข้าร่วมในการส่ง; เฉพาะเทนเซอร์ที่จำเป็นเท่านั้นที่ถูกส่งผ่านเครือข่าย ในขณะที่ NCCL จำเป็นต้องส่งเทนเซอร์ all-gather แบบเต็มไปยังแต่ละกลุ่มกระบวนการ RDMA P2P บรรลุความสมดุลนี้โดยการจัดสรรหน่วยความจำเพิ่มเติมขนาด P บน CPU ฝั่งต้นทาง ในขณะที่ฝั่งรับไม่จำเป็นต้องจัดสรรหน่วยความจำใดๆ เราสังเกตว่าในสถานการณ์จริง เนื่องจากเทนเซอร์ Hugging Face บางส่วนจำเป็นต้องถูกแคชในเครื่องก่อนที่จะอัปเดตเทนเซอร์ SGLang แบบเต็ม และโดยทั่วไปแล้วจะมีการแมปเทนเซอร์แบบ many-to-one (เช่น ใน SGLang q_proj, k_proj, v_proj จะถูกแมปไปยัง qkv_proj) ดังนั้นค่า K* จริงจะมากกว่า K เล็กน้อย
ตารางด้านล่างเปรียบเทียบต้นทุนทรัพยากรของแผนการถ่ายโอนน้ำหนักสองแบบ:
- NCCL Broadcast: จำนวน source rank ที่เข้าร่วมคือจำนวน pipeline parallelism
ppแต่ละ inference rank ต้องรับพารามิเตอร์ep*P(จำนวน expert parallelism × พารามิเตอร์ชุดเดียว) และทั้งฝั่งต้นทางและเป้าหมายต้องจัดสรรบัฟเฟอร์เพิ่มเติมขนาดK - RDMA P2P: จำนวน source rank ที่เข้าร่วมคือ
Mแต่ละ inference rank รับเฉพาะพารามิเตอร์ขนาดPฝั่งเป้าหมายไม่ต้องใช้บัฟเฟอร์เพิ่มเติม มีเพียงฝั่งต้นทางเท่านั้นที่ต้องใช้ค่าใช้จ่ายเล็กน้อย (K*+P)
แบบหลังช่วยลดแรงกดดันด้านหน่วยความจำฝั่งเป้าหมายได้อย่างมากผ่านการกระจายพารามิเตอร์ที่แม่นยำ ลดการสิ้นเปลืองทรัพยากร และเหมาะสมกับสถานการณ์การย้ายน้ำหนักโมเดลขนาดใหญ่ โดยมีประสิทธิภาพการถ่ายโอนที่ดีกว่า
สาม. ผลลัพธ์การนำไปใช้
เราวิเคราะห์ความเร็วในการถ่ายโอนของโมเดลโอเพนซอร์สทั่วไปบนโฮสต์ H100 8 GPU ที่เชื่อมต่อกับ InfiniBand การจับเวลาจะเริ่มนับจากเวลาที่ engine หยุดชั่วคราวและส่งคืนการควบคุม จนถึงเวลาที่เรียก
continue_generation
ตารางเปรียบเทียบประสิทธิภาพของโมเดลขนาดใหญ่ต่างๆ ภายใต้แผนการถ่ายโอนน้ำหนักทั้งแบบ NCCL และ RDMA ผลการทดสอบตั้งแต่โมเดล 9B ถึง 1T พารามิเตอร์แสดงให้เห็นว่าเมื่อขนาดโมเดลใหญ่ขึ้น ข้อได้เปรียบของ RDMA ก็ยิ่งเด่นชัด: สำหรับโมเดลขนาดเล็ก (เช่น GLM4-9B) อัตราเร่งเพียง 0.98 เท่า ในขณะที่โมเดล 744B และ 1T มีอัตราเร่งถึง 6.88 เท่า และ 7.37 เท่า ตามลำดับ โดยเวลาที่ใช้ลดลงจากหลายหมื่นมิลลิวินาทีเหลือเพียงไม่กี่พันมิลลิวินาที ซึ่งบ่งชี้ว่า RDMA มีประสิทธิภาพการถ่ายโอนที่เหนือกว่า NCCL อย่างมากในสถานการณ์ขนาดใหญ่และหลายโหนด และเหมาะสมกับความต้องการในการย้ายน้ำหนักของโมเดลขนาดใหญ่
หมายเหตุ: การจัดการพิเศษสำหรับ Kimi-K2: เราปรับ Kimi K2 ให้ใช้ขนาด quantization แบบ block [64, 64] ในรูปแบบ fp8 เพื่อให้เหมาะกับการกำหนดค่าการวิเคราะห์ประสิทธิภาพของเรา
ในสถาปัตยกรรม Mixture of Experts (MoE) ขนาดใหญ่ที่มีระดับ expert parallelism สูง ฝั่งปรับใช้ การปรับปรุงประสิทธิภาพจะเด่นชัดที่สุด ในการกำหนดค่าโหนดต่ำของตัวอย่าง GLM4-MoE ข้างต้น เมื่อ expert parallelism (EP) มีขนาดเล็ก ต้นทุนในการโหลดเทนเซอร์ในเครื่องไปยังโมเดล CPU มีมากกว่าผลประโยชน์ของการถ่ายโอนแบบ point-to-point (P2P) เมื่อมีโหนดเข้าร่วมมากขึ้น การถ่ายโอนแบบ point-to-point จะปรับขนาดได้ดี
สี่. วิธีการใช้งาน
ใน Miles สามารถเปิดใช้งานการอัปเดตแบบ P2P ได้ผ่าน --update-weight-transfer-mode p2p ซึ่งจะทำให้ SGLang engine ลงทะเบียนหน่วยความจำน้ำหนักของมันผ่าน --sglang-remote-instance-weight-loader-start-seed-via-transfer-engine และเลือกใช้กระบวนการอัปเดตแบบ P2P แทนการกระจายเสียง NCCL Miles อาศัยสาขา sglang-miles บน SGLang ซึ่งคุณสมบัติการทดลองขั้นสูงกว่าสนับสนุนการถ่ายโอนแบบ P2P
ห้า. แผนงานในอนาคต
- การสนับสนุนเพิ่มเติม: ให้การสนับสนุนอย่างเป็นทางการสำหรับฮาร์ดแวร์ใหม่ เช่น GB200 และ pipeline parallelism ฝั่ง SGLang สนับสนุนวิธีการ quantization เพิ่มเติม รวมการแก้ไขฝั่ง SGLang เข้ากับสาขาหลัก
- การทดลองจัดสรรหน่วยความจำแบบ Huge Page: แทนที่จะจัดสรรหน่วยความจำ CPU อย่างถาวร อาจพิจารณาเปิดใช้งานฟังก์ชันการจัดสรร GPU แบบ Huge Page ของ Transfer Engine ซึ่งจะลดต้นทุนการลงทะเบียนและยกเลิกการลงทะเบียนได้อย่างมาก ซึ่งจะช่วยให้สามารถสร้างสำเนา GPU และลงทะเบียนหน่วยความจำ ณ จุดที่ทำการถ่ายโอนได้
หก. ภาคผนวกทางวิศวกรรม
6.1 การออกแบบซ้ำ
การออกแบบเริ่มต้นของเราวางสำเนาฝั่งต้นทางไว้บน GPU เพื่อหลีกเลี่ยงการสิ้นเปลืองอัตราการใช้หน่วยความจำ GPU ระหว่างการฝึก เราใช้ความพยายามในการปรับให้เหมาะสมอย่างมากในขั้นตอนนี้ – จะทำการลงทะเบียน ถ่ายโอน และยกเลิกการลงทะเบียนในลักษณะไปป์ไลน์ได้อย่างไร? เราสามารถรักษาการลงทะเบียนหน่วยความจำบนการ์ดเครือข่ายผ่านหน่วยความจำเสมือน ในขณะที่ย้ายโมเดลไปยัง CPU ได้หรือไม่?
ที่น่าประหลาดใจคือ เมื่อพิจารณาถึงแบนด์วิธมหาศาลของคลัสเตอร์สมัยใหม่ การถ่ายโอนใช้เวลาน้อยที่สุด ในทางตรงกันข้าม ในสถานการณ์ RDMA การลงทะเบียนน้ำหนักเป็นขั้นตอนที่ใช้เวลามากที่สุด การลงทะเบียนสำเนาทั้งหมดใช้เวลาหลายสิบวินาที การย้ายโมเดลไปยัง CPU ช่วยแก้ปัญหานี้ได้
อุปสรรคอีกประการหนึ่งคือ CPU อาจประสบปัญหาหน่วยความจำไม่เพียงพอ (OOM) ในช่วงเริ่มต้น GPU หลายตัวใช้ HBM (High Bandwidth Memory) ร่วมกัน หากสร้างสำเนาสำหรับแต่ละโหนดเป้าหมายบนแต่ละโหนดต้นทาง จะจัดการได้ยากอย่างรวดเร็ว – แต่เราตระหนักได้อย่างรวดเร็วว่าโหนด SGLang ทั้งหมดถูกสร้างขึ้นแบบ isomorphic ซึ่งหมายความว่าเราสามารถเสียสละความพร้อมกันในการถ่ายโอนเล็กน้อยเพื่อให้ได้การ复用หน่วยความจำ การออกแบบสุดท้ายของเราใช้หน่วยความจำกายภาพ底层เดียวกันซ้ำ และจัดตารางข้อมูลอย่างระมัดระวังเพื่อส่งไปยัง engine shard ต่างๆ ทีละตัว
6.2 แผนการถ่ายโอนแบบ P2P
⚠️ หมายเหตุ: เนื้อหาได้รับการแปลโดย AI และตรวจสอบโดยมนุษย์ หากมีข้อผิดพลาดโปรดแจ้ง
☕ สนับสนุนค่ากาแฟทีมงาน
หากคุณชอบบทความนี้ สามารถสนับสนุนเราได้ผ่าน PromptPay
SCAN TO PAY WITH ANY BANK本文来自网络搜集,不代表คลื่นสร้างอนาคต立场,如有侵权,联系删除。转载请注明出处:https://www.itsolotime.com/th/archives/33333
