ปัจจุบันสาขาการอนุมานโมเดลภาษาขนาดใหญ่ (LLM) แสดงให้เห็นถึงรูปแบบการพัฒนาสองรางขนาน โดย GPU มุ่งเน้นประสิทธิภาพสูง ในขณะที่ CPU เน้นการปรับใช้ที่ง่าย อย่างไรก็ตาม กรอบงานอนุมานบน CPU กระแสหลักยังปรับตัวเข้ากับแพลตฟอร์ม ซีพียูแบบมัลติคอร์ (Many-core CPU) ซึ่งมีการใช้งานอย่างแพร่หลายในเว็บเซิร์ฟเวอร์และอุปกรณ์เครือข่ายระดับสูงได้อย่างมีประสิทธิภาพไม่เพียงพอ
แพลตฟอร์มประเภทนี้มักใช้สถาปัตยกรรมหน่วยความจำแบบไม่สม่ำเสมอ (Non-Uniform Memory Access – NUMA) โดยความล่าช้าในการเข้าถึงหน่วยความจำข้ามโหนดนั้นสูงกว่าการเข้าถึงในโหนดท้องถิ่นอย่างมาก ก่อให้เกิด “กำแพงการเข้าถึงหน่วยความจำข้าม NUMA” ที่รุนแรง ซึ่งกลายเป็นคอขวดหลักที่จำกัดประสิทธิภาพการอนุมาน LLM
กรอบงานที่มีอยู่ในปัจจุบันอาจไม่ได้ปรับแต่งเชิงลึกสำหรับสถาปัตยกรรม NUMA หรืออาจมีโค้ดที่ยุ่งเหยิงและนามธรรมที่ซับซ้อน ทำให้ยากต่อการปรับแต่งประสิทธิภาพในระดับละเอียด

ArcLight เป็นโซลูชันที่ถูกเสนอขึ้นเพื่อรับมือกับความท้าทายนี้โดยเฉพาะ มันคือกรอบงานอนุมาน LLM แบบเบาที่สร้างขึ้นจากศูนย์ โดยมีเป้าหมายเพื่อเป็นฐานการปรับใช้ที่มีประสิทธิภาพและโปร่งใสสำหรับซีพียูแบบมัลติคอร์ การออกแบบยึดหลักความเรียบง่ายและเป็นโมดูลาร์ ผ่านการผสานรวมเทคโนโลยี การจัดการหน่วยความจำที่ตระหนักถึง NUMA, การจัดตารางเธรดแบบหลายมุมมอง และ เทคนิคการแบ่งส่วนเทนเซอร์ (Tensor Parallelism) ที่ควบคุมได้ในระดับละเอียด เพื่อปรับแต่งโดยตรงกับปัญหาหลักของการเข้าถึงหน่วยความจำข้ามโหนด
การทดสอบยืนยันว่า ArcLight บนแพลตฟอร์มซีพียูแบบมัลติคอร์สามารถทำลายขีดจำกัดประสิทธิภาพสูงสุดของกรอบงานกระแสหลักได้สำเร็จ โดยปริมาณงานการอนุมาน (Throughput) เพิ่มสูงขึ้นได้ถึง 46% พร้อมทั้งยังรักษาความเข้ากันได้กับซีพียูทุกประเภทได้เป็นอย่างดี
1. บทนำ
การแพร่หลายอย่างรวดเร็วของโมเดลภาษาขนาดใหญ่ได้กระตุ้นความต้องการกรอบงานอนุมานที่มีประสิทธิภาพสูง ปัจจุบันสาขานี้แบ่งออกเป็นสองแนวทางหลัก: ระบบที่ใช้ GPU ประสิทธิภาพสูง และระบบปลายทางที่ใช้ CPU ซึ่งปรับใช้ได้ง่าย ในจำนวนนี้ llama.cpp ในฐานะกรอบงานบุกเบิกการอนุมานบน CPU ด้วยการนำ C++ ที่มีประสิทธิภาพมาใช้ ทำให้สามารถรัน LLM บน CPU ได้สำเร็จ
อย่างไรก็ตาม กรอบงานอนุมานบน CPU กระแสหลักเผชิญกับความท้าทายอย่างมีนัยสำคัญเมื่อปรับใช้กับแพลตฟอร์มซีพียูแบบมัลติคอร์ แพลตฟอร์มประเภทนี้มักใช้สถาปัตยกรรมหน่วยความจำแบบไม่สม่ำเสมอ (NUMA) ซึ่งแบ่งแกนประมวลผลและหน่วยความจำออกเป็นหลายโ结点 ในสถาปัตยกรรมนี้ ค่าใช้จ่ายในการเข้าถึงหน่วยความจำระยะไกลข้ามโ结点นั้นสูงกว่าการเข้าถึงหน่วยความจำท้องถิ่นอย่างมาก ดังแสดงในรูปที่ 1

รูปที่ 1: แผนภาพของแพลตฟอร์มซีพียูแบบมัลติคอร์ที่มี 128 แกน และ 4 โหนด NUMA
กรอบงานที่มีอยู่ส่วนใหญ่ละเลยกำแพงการเข้าถึงหน่วยความจำข้าม NUMA นี้ เมื่องานอนุมาน LLM ขยายไปสู่หลายสิบแกน ค่าใช้จ่ายจากการซิงโครไนซ์ข้อมูลบ่อยครั้งและการเข้าถึงหน่วยความจำที่ไม่ใช่ท้องถิ่นกลายเป็นคอขวดหลักด้านประสิทธิภาพ ส่งผลให้ระบบไม่สามารถใช้ประโยชน์จากพลังการคำนวณทางทฤษฎีของฮาร์ดแวร์ได้อย่างเต็มที่
การปรับปรุงกรอบงานที่成熟แล้วอย่าง llama.cpp ให้ตระหนักถึง NUMA อย่างลึกซึ้งนั้นยากมาก ต้องมีการ “ปรับโครงสร้างอย่างละเอียด” แบบเต็มสแต็ก ตั้งแต่การจัดสรรหน่วยความจำระดับล่าง การจัดการเธรด ไปจนถึงการกำหนดโมเดลระดับบน นอกจากนี้ กรอบงานกระแสหลักที่มีการพัฒนาต่อเนื่องอย่างต่อเนื่องทำให้โค้ดมีความยุ่งเหยิงมากขึ้นเรื่อยๆ โค้ดเก่าและเลเยอร์นามธรรมที่ซับซ้อนทำให้ตรรกะภายในไม่โปร่งใส เป็นอุปสรรคต่อการปรับแต่งประสิทธิภาพในระดับละเอียดหรือการปรับตัวให้เข้ากับสถาปัตยกรรมโมเดลใหม่ๆ อย่างรวดเร็ว
เพื่อเติมเต็มช่องว่างทางเทคนิคนี้ บทความนี้เสนอ ArcLight — กรอบงานอนุมาน LLM แบบเบาที่ออกแบบจากศูนย์สำหรับซีพียูแบบมัลติคอร์ ArcLight ยึดหลักปรัชญาการออกแบบที่เรียบง่ายและเป็นโมดูลาร์ โดยรักษาเฉพาะองค์ประกอบหลักที่จำเป็นสำหรับการอนุมานประสิทธิภาพสูง ขอบเขตโมดูลที่ชัดเจนทำให้นักพัฒนาสามารถขยายฟังก์ชันการทำงานหรือรวมโมเดลใหม่ได้อย่างง่ายดายโดยไม่ต้องดูแลฐานโค้ดโมโนลิธขนาดใหญ่ ที่สำคัญกว่านั้น ArcLight ให้การปรับแต่งเฉพาะทางสำหรับสภาพแวดล้อมมัลติคอร์ รวมถึงการจัดการหน่วยความจำและเธรดที่ตระหนักถึง NUMA และการแบ่งส่วนเทนเซอร์ที่ควบคุมได้ในระดับละเอียด เพื่อบรรเทาการสูญเสียประสิทธิภาพจากการเข้าถึงหน่วยความจำข้ามโ结点ได้อย่างมีประสิทธิภาพ
ผลการทดลองแสดงให้เห็นว่า บนแพลตฟอร์มซีพียูแบบมัลติคอร์ ArcLight เมื่อเทียบกับ llama.cpp กระแสหลักในปัจจุบัน สามารถเพิ่มปริมาณงานการอนุมานได้สูงสุดถึง 46% ทำลายขีดจำกัดประสิทธิภาพของกรอบงานที่มีอยู่ได้อย่างมีนัยสำคัญ ข้อเสนอหลักของบทความนี้มีดังนี้:
1. กรอบงานอนุมานแบบเบา: เปิดตัวกรอบงานแบบโมดูลาร์ที่รวบรวมความสามารถหลักของการอนุมาน LLM เพื่อเป็นฐานการปรับใช้ LLM บน CPU ที่โปร่งใสและปรับแต่งได้สำหรับนักวิจัย หลีกเลี่ยงค่าใช้จ่ายส่วนเกินของกรอบงานดั้งเดิม
2. การปรับแต่งหลายมิติสำหรับซีพียูแบบมัลติคอร์: เสนอชุดโซลูชันการปรับแต่งแบบเต็มมิติสำหรับซีพียูแบบมัลติคอร์ โดยการปรับแต่งการจัดตารางเธรดและกำแพงการเข้าถึงหน่วยความจำ เพิ่มขอบเขตประสิทธิภาพของการอนุมาน LLM บน CPU อย่างมาก
2. การออกแบบระบบ
ArcLight ใช้การออกแบบแบบโมดูลาร์ที่เรียบง่ายและชัดเจน เพื่อนำฟังก์ชันหลักของการอนุมานบน CPU ไปใช้ในรูปแบบที่เรียบง่ายที่สุด เพื่อความสะดวกในการขยายและพัฒนาต่อไป บทนี้จะอธิบายสถาปัตยกรรมโดยรวมของ ArcLight และรายละเอียดการออกแบบหลัก
2.1 สถาปัตยกรรมโดยรวม
ดังแสดงในรูปที่ 2 ArcLight ใช้สถาปัตยกรรมแบบแยกส่วน แบ่งออกเป็นส่วนหน้า (Frontend) สำหรับถอดรหัสระดับสูง และส่วนหลัง (Backend) สำหรับการอนุมานระดับล่าง

รูปที่ 2: แผนภาพสถาปัตยกรรมระบบ ArcLight
การออกแบบนี้ทำให้ส่วนคำนวณหลักยังคงเบาและไม่ขึ้นกับฮาร์ดแวร์ ในขณะเดียวกันก็สนับสนุนการปรับแต่งเฉพาะทางภายในเอนจินอนุมาน
* ส่วนหลังการอนุมาน นำชุดโมดูลขั้นต่ำที่จำเป็นสำหรับการอนุมานประสิทธิภาพสูงบน CPU ไปใช้ รวมถึงห้าโมดูลหลัก: ตัวจัดการหน่วยความจำ ตัวจัดการเธรด ไลบรารีเทนเซอร์ ตัวสร้างกราฟคำนวณแบบ Forward และตัวจัดตารางกราฟคำนวณ นอกจากนี้ เอนจินยังมีไลบรารีโอเปอเรเตอร์เฉพาะทางในตัว ซึ่งรวมถึงเคอร์เนลทางคณิตศาสตร์ที่จำเป็นสำหรับการคำนวณ LLM (เช่น GEMM, Softmax)
* ส่วนหน้าถอดรหัส มีปฏิสัมพันธ์ผ่าน API ที่เรียบง่ายซึ่งเปิดเผยโดยเอนจิน รับผิดชอบงานต่างๆ เช่น การโหลดน้ำหนัก การกำหนดโมเดล และลูปการถอดรหัสแบบออโต้รีเกรสซีฟ
สถาปัตยกรรมทั้งหมดประกอบด้วยไฟล์เฮดเดอร์และไฟล์ต้นฉบับ C++ ประมาณ 10 ไฟล์ สะท้อนถึงเป้าหมายการออกแบบที่เบา
2.2 ไลบรารีเทนเซอร์
ไลบรารีเทนเซอร์กำหนดโครงสร้างข้อมูลเทนเซอร์และการดำเนินการทั้งหมด (ยกเว้นเคอร์เนลคำนวณ) ใน ArcLight ต่างจาก llama.cpp ที่ใช้การกำหนดแบบสไตล์ C ArcLight ใช้คลาส C++ เพื่อสร้างการห่อหุ้มแบบอ็อบเจ็กต์ที่เข้มงวด ซึ่งช่วยเพิ่มระดับความเป็นโมดูลาร์และความสามารถในการบำรุงรักษาของโค้ด
เทนเซอร์ใน ArcLight ประกอบด้วยสองส่วน: ส่วนหัว (Header) และ พื้นที่ข้อมูล (Data Area)
* ส่วนหัวเทนเซอร์ เก็บเมตาดาต้าหลัก รวมถึงชื่อเทนเซอร์ รูปร่าง (Shape) ประเภทข้อมูล ประเภทการดำเนินการ พารามิเตอร์เสริม และพอยน์เตอร์เทนเซอร์ต้นทางสำหรับสร้างกราฟคำนวณ
* พื้นที่ข้อมูล เป็นบล็อกหน่วยความจำเสมือนที่ต่อเนื่องกัน
ไลบรารีนี้มีอินเทอร์เฟซระดับสูงเพื่อจัดการคุณสมบัติข้างต้น เช่น วิธีการรับ/ตั้งชื่อและรูปร่าง คำนวณจำนวนไบต์ทั้งหมดที่ต้องการสำหรับการจัดสรรหน่วยความจำ เป็นต้น
2.3 ตัวจัดการหน่วยความจำ
ตัวจัดการหน่วยความจำรับผิดชอบการจัดการวงจรชีวิตของหน่วยความจำขณะรัน หน้าที่หลักคือการจัดสรรหน่วยความจำพูลขนาดใหญ่เพียงพอให้กับระบบปฏิบัติการล่วงหน้าเมื่อโปรแกรมเริ่มทำงาน จากนั้นจึงจัดสรรหน่วยความจำจากพูลให้กับเทนเซอร์น้ำหนักและเทนเซอร์แอคติเวชันตามความต้องการ
2.3 ตัวจัดการหน่วยความจำ
ต่างจากกลยุทธ์บัฟเฟอร์โมโนลิธแบบการเข้าถึงหน่วยความจำแบบสม่ำเสมอ (UMA) ที่ใช้โดย llama.cpp เมื่อเปิดใช้งานการรับรู้ NUMA แล้ว ArcLight จะจัดสรรบัฟเฟอร์แยกกันในหน่วยความจำท้องถิ่นของแต่ละโหนด NUMA การออกแบบนี้ทำให้กระบวนการผูกเทนเซอร์กับโหนด NUMA อย่างชัดเจนง่ายขึ้นอย่างมาก ดังแสดงในรูปที่ 3

รูปที่ 3: การเปรียบเทียบกลยุทธ์การจัดการบัฟเฟอร์ระหว่างการเข้าถึงหน่วยความจำแบบสม่ำเสมอ (บน) และแบบไม่สม่ำเสมอ (ล่าง) ในกลยุทธ์การเข้าถึงหน่วยความจำแบบสม่ำเสมอ โหนด NUMA จะโปร่งใสต่อระบบ
นอกจากนี้ เพื่อลดค่าใช้จ่ายหน่วยความจำในกระบวนการอนุมานแบบเลเยอร์ต่อเลเยอร์ เราได้นำกลไกบัฟเฟอร์คู่ (Double Buffering) ไปใช้สำหรับบัฟเฟอร์แอคติเวชัน บัฟเฟอร์แอคติเวชันสองตัวจะถูกใช้สลับกันตามความคี่-คู่ของเลเยอร์ ซึ่งช่วยลดการใช้หน่วยความจำขณะรันได้อย่างมีนัยสำคัญ ดังแสดงในรูปที่ 4

รูปที่ 4: แผนภาพกลไกบัฟเฟอร์คู่
2.4 ตัวจัดการเธรด
ตัวจัดการเธรดจะสร้างกลุ่มเธรดงานก่อนเริ่มการอนุมาน และทำงานร่วมกันเพื่อดำเนินการคำนวณเทนเซอร์ขณะรัน วิธีการทั่วไปเช่น llama.cpp จัดระเบียบเธรดงานเป็นพูลเธรดเดียว โดยที่เธรดทั้งหมดทำงานคำนวณเดียวกัน ซึ่งเหมาะสำหรับกราฟคำนวณ Forward เดียวเท่านั้น

รูปที่ 5: โครงสร้างองค์กรเธรดแบบหลายมุมมอง
เพื่อรองรับโหมดการดำเนินการกราฟเดียวและหลายซับกราฟได้อย่างยืดหยุ่น ArcLight ได้แนะนำการจัดองค์กรเธรดแบบหลายมุมมอง ดังแสดงในรูปที่ 5:
* เพิ่มนามธรรมเชิงตรรกะของกลุ่มเธรดภายในพูลเธรด การเริ่มต้นพูลและการดำเนินการกราฟมีอินเทอร์เฟซและโอเปอเรเตอร์ที่ชัดเจน ซึ่งสามารถปรับโครงสร้างองค์กรเธรดภายในได้แบบไดนามิก
* เมื่อพูลเธรดถูกแบ่งออกเป็น n กลุ่ม กลุ่มเหล่านี้สามารถดำเนินการดำเนินการเทนเซอร์อิสระ n ตัวแบบขนานกันได้
การซิงโครไนซ์แบบ Barrier ภายในกลุ่มเธรดเป็นการออกแบบทั่วไปของกรอบงานอนุมาน โดยที่เธรดทั้งหมดต้องผ่าน Barrier พร้อมกันเพื่อรับประกันความก้าวหน้าของการดำเนินการที่สอดคล้องกัน หลังจากแนะนำการจัดองค์กรเธรดเชิงตรรกะหลายกลุ่มแล้ว การจัดการ Barrier จะซับซ้อนขึ้น เพื่อจุดประสงค์นี้ เราได้เพิ่มกลไกBarrier แบบโกลบอล เพื่อให้สามารถซิงโครไนซ์ข้ามกลุ่มของพูลเธรดทั้งหมดได้ ดังแสดงในรูปที่ 6 เพื่อแยกความแตกต่างจาก Barrier ภายในกลุ่มแบบดั้งเดิม

รูปที่ 6: การเปรียบเทียบ Barrier แบบโลคอลและแบบโกลบอล “g0t0” หมายถึงเธรดหมายเลข 0 ในกลุ่มที่ 0
* เมื่อไม่ได้เปิดใช้งาน Barrier แบบโกลบอล การซิงโครไนซ์จะเกิดขึ้นภายในกลุ่มเธรดเชิงตรรกะเท่านั้น
* เมื่อเปิดใช้งาน Barrier แบบโกลบอลแล้ว เธรดของกลุ่มเชิงตรรกะทั้งหมดต้องมาถึงและผ่าน Barrier นี้ร่วมกัน
2.5 ตัวสร้างกราฟคำนวณแบบ Forward
คล้ายกับ llama.cpp ArcLight ใช้กราฟคำนวณแบบสแตติก โดยสร้างกราฟทั้งหมดให้เสร็จสิ้นก่อนการดำเนินการ
ตัวสร้างกราฟคำนวณนำอินเทอร์เฟซชุดหนึ่งสำหรับการดำเนินการเทนเซอร์ไปใช้และเปิดเผย เพื่อกำหนดโหนดกราฟ อินเทอร์เฟซเหล่านี้รับพอยน์เตอร์เทนเซอร์ต้นทางและพารามิเตอร์ที่จำเป็น แล้วส่งคืนเทนเซอร์เอาต์พุตที่สอดคล้องกับโหนดปัจจุบัน <
⚠️ หมายเหตุ: เนื้อหาได้รับการแปลโดย AI และตรวจสอบโดยมนุษย์ หากมีข้อผิดพลาดโปรดแจ้ง
☕ สนับสนุนค่ากาแฟทีมงาน
หากคุณชอบบทความนี้ สามารถสนับสนุนเราได้ผ่าน PromptPay
本文来自网络搜集,不代表คลื่นสร้างอนาคต立场,如有侵权,联系删除。转载请注明出处:http://www.itsolotime.com/th/archives/30451
