- เคอร์เนล CUDA-C ที่สร้างโดย AI แสดงประสิทธิภาพใกล้เคียงหรือดีกว่า เคอร์เนลที่ผู้เชี่ยวชาญของ PyTorch ปรับแต่งไว้
- LLM (โมเดลภาษาขนาดใหญ่) เพียงตัวเดียวทำซ้ำทั้งการ สร้างไอเดียการปรับแต่งด้วยภาษาธรรมชาติ และการแตกแขนง โค้ดหลายแนวทาง จนทำได้ดีกว่าวิธีเดิมทั้งในด้าน ความหลากหลายของการปรับแต่ง และ การสำรวจแบบขนาน
- ผลเบนช์มาร์กเด่น ๆ ได้แก่ Matmul(101%), Conv2D(179.9%), Softmax(111.8%), LayerNorm(484.4%), Conv2D+ReLU+MaxPool(290.1%) ซึ่งเหนือกว่า PyTorch อย่างชัดเจน
- เพื่อก้าวข้ามข้อจำกัดของการ “ปรับปรุงเคอร์เนลแบบลำดับขั้น” เดิม งานนี้ใช้ การให้เหตุผลด้วยภาษาธรรมชาติ + โครงสร้างการแตกแขนง เพื่อสร้างเคอร์เนลประสิทธิภาพสูงได้อย่างรวดเร็ว
- กำลังก้าวหน้าไปถึงเวิร์กโหลด ML สมัยใหม่อย่าง FP16 และ Flash Attention และชี้ให้เห็นว่าในอนาคต AI อาจเป็นผู้ค้นหาและปรับปรุงเคอร์เนลที่เร็วกว่าได้ด้วยตนเอง จนกลายเป็นแนวทางหลัก
TL;DR ผลลัพธ์สำคัญ
- ทีมวิจัย Stanford CRFM พบตัวอย่างที่ เคอร์เนล CUDA-C ประสิทธิภาพสูงที่ AI สร้างขึ้น ทำงานได้เร็วใกล้เคียงหรือเร็วกว่าที่เคอร์เนลซึ่งผู้เชี่ยวชาญของ PyTorch ออกแบบไว้
- เดิมทีเป้าหมายคือฝึกโมเดลสร้างเคอร์เนลอัตโนมัติที่ดีขึ้นผ่านข้อมูลสังเคราะห์ แต่กลับพบว่าเพียงแค่กระบวนการสร้างข้อมูลสังเคราะห์ก็สามารถสร้างเคอร์เนลที่เร็วอย่างน่าทึ่งได้โดยอัตโนมัติ
- ด้วยเหตุนี้ ทีมจึงเผยแพร่วิธีการ ผลเบนช์มาร์ก กลยุทธ์การปรับแต่ง และทิศทางต่อไปออกมาก่อนกำหนด
- เบนช์มาร์ก: อ้างอิงจาก GPU Nvidia L40S. ประสิทธิภาพ(%): เวลาในการรันของ PyTorch ÷ เวลาในการรันของเคอร์เนลที่สร้างขึ้น
- Matmul (FP32): 101.3% เทียบกับ PyTorch (เมทริกซ์ 4096x4096)
- Conv2D: 179.9% (อินพุต: 100, 3, 224, 224; สเปก AlexNet Conv1)
- Softmax: 111.8% (เทนเซอร์ 4096x65536)
- LayerNorm: 484.4% (เทนเซอร์ 16, 64, 256, 256)
- Conv2D + ReLU + MaxPool: 290.1% เทียบกับ PyTorch reference และ 189.0% เทียบกับ
torch.compile()
แรงจูงใจของงานวิจัยและวิธีการ
- เป้าหมายเดิมคือการสร้าง ข้อมูลสังเคราะห์สำหรับฝึกโมเดลสร้างเคอร์เนล แต่ระหว่างการทดลองพบว่าเคอร์เนลที่สร้างขึ้นเองสามารถทำประสิทธิภาพสูงเกินคาดได้
- ใช้ KernelBench (เบนช์มาร์กที่ Stanford เผยแพร่ต่อสาธารณะในเดือนธันวาคม 2024)
- สำหรับโค้ด
torch ที่กำหนดให้ LLM เขียนเคอร์เนลที่เร็วที่สุดขึ้นมาใหม่
- ตรวจสอบความถูกต้องด้วยการเช็กความเท่ากันเชิงตัวเลขของผลลัพธ์อินพุต/เอาต์พุต
- วิธีเดิม: วนลูป แก้ไขแบบลำดับขั้น โดยค่อย ๆ ปรับเคอร์เนลทีละน้อยเพื่อให้ดีขึ้น
- ข้อเสีย: ความหลากหลายของไอเดียน้อย, ทำการปรับแต่งซ้ำ ๆ แบบเดิม, และติดอยู่กับจุดเหมาะสมเฉพาะที่
- แนวคิดที่ปรับปรุงใหม่
- คิดและบันทึกไอเดียการปรับแต่งเป็นภาษาธรรมชาติ ก่อน แล้วจึงสร้างสายแตกแขนงของการนำไอเดียเหล่านั้นไปเขียนเป็นโค้ดหลายแบบพร้อมกัน
- ในแต่ละรอบให้ลองการปรับแต่งหลายแบบแบบขนาน → เลือกเคอร์เนลที่เร็วที่สุดเป็นเมล็ดตั้งต้นของรอบถัดไป
- วิธีนี้ทำให้สามารถ สำรวจกลยุทธ์การปรับแต่งที่หลากหลายและค้นหาแบบขนาน ได้ภายใต้จำนวนรอบการค้นหาที่จำกัด
ตัวอย่างไอเดียการปรับแต่ง
- การปรับแต่งการเข้าถึงหน่วยความจำ: ปรับปรุงประสิทธิภาพของลำดับชั้นหน่วยความจำ global/shared/register
- การประมวลผลแบบอะซิงโครนัสและการซ่อน latency: ซ้อนทับการคำนวณกับการย้ายข้อมูล
- การปรับแต่งชนิดข้อมูล/ความแม่นยำ: ใช้ FP16/BF16 และคำสั่งเฉพาะฮาร์ดแวร์
- การปรับแต่งการคำนวณและชุดคำสั่ง: ลดปริมาณการคำนวณ จำนวนคำสั่ง และใช้คำสั่งพิเศษของฮาร์ดแวร์ให้คุ้มค่า
- ความขนานและ occupancy: ใช้งาน SM (Streaming Multiprocessors) ให้สูงสุด
- การปรับแต่งลูป/การแตกแขนง/การทำดัชนี: ลดลูป ตัดการคำนวณดัชนีที่ไม่จำเป็น
กระบวนการปรับแต่งเคอร์เนลจริง (ตัวอย่าง Conv2D)
- ลำดับของไอเดียการปรับแต่งในแต่ละรอบและการเพิ่มขึ้นของประสิทธิภาพ
- เริ่มต้น (รอบ 0): พอร์ตเป็น CUDA แบบพื้นฐาน (ความเร็ว 20% เมื่อเทียบกับ PyTorch)
- รอบถัด ๆ ไป: → ใช้ read cache → การคำนวณ FP16 Tensor Core (แปลงเป็น GEMM) → double buffering/pipelining → คำนวณดัชนีล่วงหน้า/ใช้ shared memory → vectorization → buffering พร้อมกันใน K-loop ฯลฯ ซึ่งเป็นการใช้สถาปัตยกรรม GPU ขั้นสูงอย่างเข้มข้น
- รอบสุดท้าย (รอบ 13): ทำประสิทธิภาพได้ 179.9% เทียบกับ PyTorch
- โค้ดจริงมีการใช้ เทคนิคการเขียนโปรแกรม CUDA ระดับสูง จำนวนมาก
- ในแต่ละรอบจะสร้างไอเดียใหม่ด้วยภาษาธรรมชาติ แล้วทดลอง implementation หลายแบบแบบขนานเพื่อเลือกโค้ดที่ดีที่สุด
Takeaways และนัยสำคัญ
- การสร้างเคอร์เนลด้วย AI สามารถก้าวข้ามระดับผู้เชี่ยวชาญมนุษย์ได้ด้วย ลูปการค้นหาที่ทรงพลังและการผสมผสานไอเดียการปรับแต่งที่หลากหลายบนฐานภาษาธรรมชาติ
- โอเปอเรเตอร์สมัยใหม่บางตัว (FP16 matmul, Flash Attention) ณ ตอนนี้ยังทำประสิทธิภาพต่ำกว่า PyTorch
- การคำนวณ FP32 บนฮาร์ดแวร์รุ่นใหม่ ๆ ยังได้รับการปรับแต่งน้อยกว่า FP16/BF16 อยู่บ้าง → ทำให้มีโอกาสแสดงความเหนือกว่าในด้านนี้
- แม้อยู่ภายใต้ข้อจำกัดของโทเคนสำหรับการค้นหา (รวมอินพุต/เอาต์พุต 7 ล้านโทเคน) ก็ยังเห็นการปรับปรุงประสิทธิภาพอย่างต่อเนื่อง
- งานวิจัยล่าสุดอย่าง AlphaEvolve และ Gemini 2.5 Pro ก็ชี้เช่นกันว่า การค้นหาแบบแตกแขนงจำนวนมากร่วมกับการตรวจสอบความถูกต้อง สามารถยกระดับประสิทธิภาพได้อย่างก้าวกระโดดโดยไม่ต้องฝึกใหม่
- ต่อจากนี้ แนวทางลักษณะนี้จะสามารถ สร้างข้อมูลสังเคราะห์และเคอร์เนลประสิทธิภาพสูงจำนวนมาก และพัฒนาไปสู่ ลูป AI ที่ปรับปรุงตัวเองได้ (self-improving AI)
บทสรุป
- การสร้างและปรับแต่งเคอร์เนลอัตโนมัติด้วย AI ไปถึงระดับเทียบเท่าการเขียนมือโดยผู้เชี่ยวชาญแล้ว และในอนาคตอันใกล้มีแนวโน้มจะเกิดระบบ AI ที่ปรับปรุงตัวเองได้จากการผสาน โมเดล + การค้นหาแบบแตกแขนง + การตรวจสอบความถูกต้อง
- มีความเป็นไปได้ที่ AI จะก้าวข้ามข้อจำกัดด้านประสิทธิภาพของเฟรมเวิร์กอย่าง PyTorch และ TensorFlow ได้ด้วยตนเอง
ภาคผนวก: โค้ดเต็มของเคอร์เนล Conv2D
- มีซอร์สโค้ดเต็มของฟังก์ชันและเคอร์เนลจริงรวมอยู่ด้วย (ละรายละเอียดโค้ดไว้)
- คุณลักษณะสำคัญในโค้ด:
- shared memory vectorization, double-buffering แบบลำดับชั้นใน K-dim, CUDA WMMA, warp-level output buffer เป็นต้น
- การคำนวณดัชนีแบบไดนามิกแบบเรียลไทม์, การจัดการ bias, การโหลดข้อมูลที่มี latency พร้อมกันภายใน K loop เป็นต้น
- ดูตัวอย่างโค้ดและเคอร์เนลฉบับสมบูรณ์ได้ที่ GitHub repository
2 ความคิดเห็น
น่าจะเรียกว่าเป็นเทคนิคแบบเอนเซมเบิลชนิดหนึ่งได้ไหมนะ น่าทึ่งมากครับ
ความเห็นใน Hacker News
ฉันคิดว่าวิธีที่ผู้เขียนบทความนี้มอง "AI agent" ค่อนข้างน่าสนใจ
คนส่วนใหญ่มักนึกถึง agent เหมือนพนักงานมนุษย์
ตั้งค่า agent แบบขนานไว้ไม่กี่ตัว (บ่อยครั้งมีแค่ตัวเดียว) แล้วให้แต่ละตัววนลูปทำงานทีละอย่าง
ยังคงติดอยู่กับโลกที่มีจำนวนคนตายตัว พนักงานทำได้ทีละงาน และสลับงานได้ช้า
แต่ LLM ไม่ได้เป็นแบบนั้น
เราสามารถสร้าง agent ได้แทบไม่จำกัดทุกเมื่อเท่าที่ต้องการ
ต้นทุนของการส่งคำขอไปยัง LLM ไม่ต่างกันว่าจะทำแบบเรียงลำดับหรือขนาน
เมื่อเข้าใจจุดนี้ รูปแบบที่แต่ละ agent แตกแขนงตัวเองออกเป็น sub-agent หลายตัวตามความจำเป็นก็เป็นสิ่งที่นึกออกมาได้อย่างเป็นธรรมชาติ
นี่คือแนวทางที่ผู้เขียนลองทำ
รู้สึกว่าการมอง agent เป็น "task" หรือ "job" แล้วนำสิ่งที่เรียนรู้จาก Celery หรือ Sidekiq มาปรับใช้จะเหมาะกว่า
"ทุกวันนี้ FP32 ถูกใช้น้อยลงมากใน ML workload สมัยใหม่ และบนฮาร์ดแวร์รุ่นใหม่ก็ได้รับการ optimize น้อยกว่า FP16 หรือ BF16 ด้วย ดังนั้นนี่อาจเป็นหนึ่งในเหตุผลที่ทำให้ปรับปรุงประสิทธิภาพเหนือ PyTorch ได้ง่ายกว่าในเคอร์เนล FP32"
ตลอดหลายปีที่ผ่านมาแทบไม่มีนักพัฒนาคนไหนลงทุนเวลาไปกับการ optimize เคอร์เนลเวอร์ชัน fp32
สิ่งที่น่าสนุกจริง ๆ คือถ้าสามารถเพิ่มประสิทธิภาพในฝั่งเคอร์เนลที่มีการพัฒนาอย่างเข้มข้นและเป็นสิ่งที่ผู้คนใช้งานกันจริงได้
ฉันคิดว่าผลลัพธ์ที่ดีแบบนี้อธิบายได้บางส่วนจากการที่ NVIDIA ไม่ได้ให้เอกสารเกี่ยวกับ GPU อย่างละเอียดเพียงพอ
ถ้าเป็นโปรเซสเซอร์ที่มีการทำเอกสาร microarchitecture ไว้อย่างดี โปรแกรมเมอร์หรือคอมไพเลอร์ก็สามารถเขียนโปรแกรมที่เหมาะที่สุดได้อย่างเป็นเชิงกำหนดอยู่แล้ว ดังนั้นการนำ ML/AI มาใช้ให้เกิดการปรับปรุงที่น่าทึ่งจนเกินกว่าการค้นหาวิธีที่รู้กันอยู่แล้วจึงไม่ง่าย
แต่ในกรณีที่มีเอกสารน้อยกว่าอย่าง GPU ของ NVIDIA การหาว่าโปรแกรมที่ดีที่สุดคืออะไร มักต้องอาศัยการค้นหาแบบสุ่มโดยอ้างอิงตัวอย่างโปรแกรมที่เคยถูก optimize มาก่อน หรือไม่ก็ต้องทำ reverse engineering เพื่อดูว่าฮาร์ดแวร์จริงทำงานอย่างไรในบางสถานการณ์
ในบริบทแบบนี้ ML/AI จึงอาจแสดงศักยภาพได้ และด้วยการเรียนรู้จากโปรแกรมที่เขียนมาดีแล้วจำนวนมาก มันอาจจับพฤติกรรมที่ไม่มีเอกสารรองรับซึ่งแม้แต่นักพัฒนามนุษย์ก็หาได้ยาก
ฉันสงสัยว่า การปรับปรุงที่ทราบกันอยู่แล้วสำหรับเคอร์เนล fp16/bf16 อาจแค่ถูกย้ายมาใช้กับ fp32 หรือเปล่า
"นี่หมายความว่าคนไม่ได้แตะเคอร์เนล fp32 เลยมาหลายปีแล้วหรือ?"
ว้าว ถ้าเป็นแบบนั้นจริง ฉันคิดว่ามันเจ๋งมาก เพราะเท่ากับว่า AI สร้างอัลกอริทึมใหม่ขึ้นมาในพื้นที่ที่ไม่มีคำตอบสำเร็จรูปมาก่อน
ข้อสรุปของฉันจากบทความนี้, AlphaEvolve ของ Google(ที่นี่), และข่าวล่าสุดที่ o3 พบ zero day ในลินุกซ์เคอร์เนล(ที่นี่)
คือรู้สึกว่าโดยเฉพาะ Gemini Pro 2.5 และ o3 ได้ไปถึงระดับความสามารถใหม่ที่จู่ ๆ ก็ทำไอเดียที่โมเดลก่อนหน้านี้ทำไม่ได้สำเร็จ
ฉันไม่ได้มองว่าอยู่ ๆ สิ่งที่เมื่อก่อนทำไม่ได้ก็กลายเป็นทำได้ขึ้นมา
แต่เป็นเพราะตอนนี้มันสามารถวนซ้ำและทดสอบได้เร็วกว่ามนุษย์มาก
และสามารถใช้ประโยชน์จากข้อมูลจำนวนมหาศาลได้ทันที
กล่าวคือ เรามาถึงจุดที่การผสมกันของข้อมูลมหาศาล ความก้าวหน้า และ brute force ที่ถูกใช้อย่างชาญฉลาด เริ่มประสบความสำเร็จในบางงานประยุกต์แล้ว
ฉันคิดว่าตัวอย่างที่คุณยกมากับผลลัพธ์ครั้งนี้มีความคล้ายกันมากจริง ๆ
ในเนื้อหาก็มีประโยคว่า "ลูปการวนซ้ำตอนทดสอบไม่ได้มีลักษณะเป็น interactive chatbot ที่คอยตรวจผลของการแก้โค้ดทีละขั้น แต่ใกล้เคียงกับการค้นหาแบบมีโครงสร้างที่ประเมินผลแบบขนานอย่างเชิงรุกตามสมมติฐานการปรับแต่งที่ชัดเจน"
ข้อสรุปของฉันคือ ตอนนี้เรารู้วิธีใช้ความสามารถของ LLM
เพื่อรับมือกับฟังก์ชันประเมินผลที่ชัดเจน หรือเพื่อลดขนาดของ solution space ที่มีรูปแบบคล้ายกันได้อย่างมีนัยสำคัญ
ประเด็นไม่ได้อยู่ที่ว่าโมเดลไหนแซงโมเดลไหน หรือมีเพียงโมเดลใดที่แก้ปัญหานี้ได้...
แต่ความจริงที่ว่าการประยุกต์ใช้งานลักษณะนี้เริ่มปรากฏออกมาอย่างชัดเจนนั้นมีความหมายมากกว่า
ฉันรู้สึกว่า Gemini Pro 2.5 เป็น AI ตัวแรกที่คนเอาไปใช้งานได้จริง แต่พูดอย่างเคร่งครัดมันก็เพิ่งข้าม threshold นั้นมาแบบเฉียด ๆ เท่านั้น
หลายครั้งอัตราความสำเร็จก็ยังตกลงไปต่ำกว่า 20%
ถ้า 3.0 ออกมา... ก็เริ่มรู้สึกน่ากลัวนิด ๆ แล้ว
เดี๋ยวก่อน หมายถึงอะไร? นี่ไม่ได้เกี่ยวกับลินุกซ์เคอร์เนลเลยนะ แต่มันคือ "kernel" ในความหมายของการเขียนโปรแกรม GPU
คุณเข้าใจบทความนี้ทั้งชิ้นผิดไปหรือเปล่า?
น่าสนใจดี แต่มีหลักฐานที่หนักแน่นกว่านี้ไหม? ผลลัพธ์เพียงครั้งเดียวแบบนี้ยังไม่น่าเชื่อพอ
"โค้ดอ้างอิงเป็น FP32 แบบค่าเริ่มต้น และค่าความคลาดเคลื่อนที่ยอมรับได้คือ 1e-02"
ความคลาดเคลื่อนระดับนี้สามารถแทนที่เคอร์เนล "fp32" ด้วยการคำนวณ fp16 ได้อย่างง่ายดาย
ถ้าคิดต่ออีกขั้น ฉันเริ่มสงสัยว่าหัวใจของงานนี้จริง ๆ อาจเป็นการสั่งให้เปลี่ยนการคำนวณ fp32 ในเคอร์เนลนั้นให้เป็น fp16 ให้ได้มากที่สุดหรือเปล่า
เรื่องนี้ย้ายกันได้ยากแค่ไหนคงต้องตรวจสอบอีกที
แต่โดยสัญชาตญาณแล้วฉันยังไม่รู้สึกว่ามันน่าประทับใจนัก
ถ้าความคิดฉันผิด ก็อยากให้ผู้เขียนอธิบายจุดนี้ให้ชัดเจน
ถ้าเป็นแบบนี้ ผลลัพธ์ก็จะไม่มีความหมาย
ไม่รู้ว่าเขาตรวจ relative error หรือเปล่า
การแทน float32 ด้วย float16 ไม่มีความหมาย
ดูเหมือนเหตุผลเดียวที่เลือก float32 ก็เพราะเรื่องความแม่นยำ
ถ้าเสียคุณสมบัตินี้ไป ก็ไม่เหลือความแตกต่างระหว่างเวอร์ชันแล้ว
มีแค่ฉันคนเดียวไหมที่เห็นชื่อบทความนี้แล้วนึกว่า AI สร้าง OS kernel ขึ้นมาจริง ๆ เลยกดเข้ามาอ่าน?
การเพิ่มความเร็ว 400% นั้นสุดยอดมาก
แต่สิ่งที่น่าสนใจกว่ายิ่งกว่าคือ ระเบียบวิธีที่ไม่ได้ optimize แค่การคำนวณง่าย ๆ ในแต่ละรอบ แต่บังคับให้มีขั้นตอนการให้เหตุผลทางภาษาเพื่อดึงความหลากหลายของการค้นหาออกมา
ที่น่าสนใจมากคือวิธีนี้ใช้งานได้ผลจริง
ฉันคิดว่ามันก็แค่วิวัฒนาการแบบ memetic ทั่วไป
เป็นผลลัพธ์ที่น่าสนใจมากจริง ๆ
ดูเหมือนคนกลุ่มนี้ตื่นเต้นมากจนรีบเอาออกมาลงบล็อก
จริง ๆ แล้วอาจตั้งใจจะขอฟีดแบ็กก่อนตีพิมพ์ก็ได้
ฉันไม่รู้ว่านี่ใช่เส้นทางในตำนานของ "self improvement" หรือเปล่า
แต่รู้สึกว่าผลลัพธ์แบบนี้แหละคือสิ่งที่น่าจะได้เห็นระหว่างทางนั้น
วิธีพวกนี้ได้ผลก็ต่อเมื่อมีฟังก์ชันประเมินผลที่ชัดเจนมากเท่านั้น
ขอแชร์ประสบการณ์ของฉัน: ตอนพยายามทำ replication ฉันมองว่าเคอร์เนล LayerNorm ไม่เสถียรเชิงตัวเลขจนตรวจสอบไม่ได้
เขาทดสอบแค่กับค่าเฉลี่ย 0 และส่วนเบี่ยงเบนมาตรฐาน 1 เลยไม่ได้เผยให้เห็นปรากฏการณ์ numerical cancellation ทันที
และเสริมอีกนิดว่าภายหลังฉันพบว่ามีการทำเวอร์ชันที่เสถียรเชิงตัวเลขขึ้นมาใหม่แล้ว
ฉันคิดว่านี่เป็นเรื่องที่ดีมาก
เป็นผลลัพธ์ที่เจ๋งมาก
แม้จะใช้ o3 และ Gemini 2.5 Pro
แต่น่าเสียดายที่ไม่ได้บอกว่าฝั่งไหนสร้างเคอร์เนลที่ดีกว่า
จุดที่น่าสนใจคือการสังเกตว่าโค้ดที่ AI สร้างขึ้นจัดการกับขอบเขตกว้างแบบ fused kernel อย่างไร
ตัวอย่างเช่น gemm + relu + gemm + normalization และอื่น ๆ
ถ้าจะไล่จูนด้วย tuner หรือให้คนเขียนทีละตัวคงเป็นงานที่เหนื่อยมาก
อย่างน้อยก็ชัดเจนว่าไม่ใช่ OS kernel