- GPU เป็นโปรเซสเซอร์แบบขนานขนาดใหญ่ที่มีคอร์นับพัน และถูกออกแบบมาเพื่อประมวลผลงานจำนวนมากพร้อมกัน
- CPU โดดเด่นในงานที่ซับซ้อนและทำงานตามลำดับ แต่มีข้อจำกัดด้านจำนวนงานที่ประมวลผลได้ในคราวเดียว
- ในทางกลับกัน GPU มีจุดแข็งในการประมวลผลงานแบบขนานผ่านเธรดนับพัน ทำให้จัดการข้อมูลปริมาณมากได้อย่างรวดเร็ว
- ตัวอย่างเช่น GPU NVIDIA RTX 4090 มี CUDA core จำนวน 16,384 คอร์ ซึ่งเมื่อนำไปเทียบกับ CPU ระดับสูงจะมีเพียง 16~24 คอร์
- คอร์แต่ละตัวของ GPU ช้ากว่าคอร์ของ CPU แต่ด้วยการประมวลผลแบบขนานของคอร์จำนวนมหาศาล จึงเหมาะกับการคำนวณขนาดใหญ่ เช่น การคำนวณเมทริกซ์
CUDA และ Python
- CUDA (Compute Unified Device Architecture) ของ NVIDIA เป็นทั้งแพลตฟอร์มและส่วนขยายของ C++ ที่ช่วยให้สามารถเขียนโปรแกรมที่รันบน GPU ได้
- CUDA มีทั้งโมเดลการเขียนโปรแกรมและ API ที่ช่วยให้นักพัฒนาสามารถเขียนโค้ดที่รันบน GPU ได้โดยตรง
- ด้วยสิ่งนี้ งานที่สามารถประมวลผลแบบขนานได้จึงสามารถย้ายจาก CPU ไปยัง GPU เพื่อเพิ่มประสิทธิภาพได้
- นักพัฒนา Python สามารถใช้เครื่องมืออย่าง Numba เพื่อใช้ประโยชน์จาก GPU acceleration ได้
- Numba เป็นคอมไพเลอร์สำหรับ Python ที่คอมไพล์โค้ด Python ให้ไปรันบน GPU ที่รองรับ CUDA ได้
- ทำให้นักพัฒนา Python สามารถเริ่มต้นใช้การประมวลผลแบบเร่งด้วย GPU ได้ง่าย โดยต้องเรียนรู้ไวยากรณ์และคำศัพท์ใหม่เพียงเล็กน้อย
- CUDA Python มี Cython/Python wrapper สำหรับ CUDA driver และ runtime API เพื่อให้นักพัฒนา Python ใช้ประโยชน์จากการประมวลผลแบบขนานของ GPU ได้
- สามารถติดตั้ง CUDA Python ได้ผ่าน PIP และ Conda
โครงสร้างเธรดและบล็อกของ CUDA
- ใน CUDA, kernel คือฟังก์ชันที่รันบน GPU และเมื่อเรียกใช้ kernel จะมีเธรดแบบขนานหลายร้อยหรือหลายพันเธรดทำงานพร้อมกันเพื่อประมวลผลข้อมูลที่แตกต่างกัน
- โมเดลนี้เรียกว่า SIMT (Single-Instruction Multiple-Thread)
- เธรดจะถูกรวมเป็น warp (กลุ่มเธรด 32 ตัว) และ warp จะถูกรวมเป็น block
- แต่ละ block จะรันบน Streaming Multiprocessor (SM) โดย SM มีทรัพยากรที่จำกัด เช่น register และ shared memory
- ขนาดของ block ส่งผลต่อการจัดสรรทรัพยากรเหล่านี้และจำนวน warp ที่สามารถรันพร้อมกันได้ (occupancy)
- การกำหนดจำนวนและขนาดของ thread block อย่างเหมาะสมจะช่วยให้ใช้ทรัพยากรของ GPU ได้อย่างมีประสิทธิภาพ
การจัดการหน่วยความจำและการเพิ่มประสิทธิภาพ
- ในการเขียนโปรแกรม CUDA จำเป็นต้องจัดการหน่วยความจำระหว่าง CPU (host) และ GPU (device) อย่างชัดเจน
- ลำดับการทำงานทั่วไปมีดังนี้:
- จัดสรรหน่วยความจำบน GPU (
cudaMalloc)
- คัดลอกข้อมูลจาก host ไปยัง device (
cudaMemcpy)
- รัน kernel
- คัดลอกผลลัพธ์จาก device กลับไปยัง host (
cudaMemcpy)
- คืนหน่วยความจำของ GPU (
cudaFree)
- Shared memory เป็นหน่วยความจำแบบ on-chip ที่ช่วยให้เธรดภายใน block สามารถแชร์ข้อมูลกันได้อย่างรวดเร็ว ซึ่งช่วยเพิ่มความเร็วในการเข้าถึงหน่วยความจำ
- การซิงโครไนซ์ระหว่างเธรดทำได้ด้วย
__syncthreads() ซึ่งช่วยป้องกัน race condition ได้
Custom CUDA kernel สำหรับ LLM
- ในงานของโมเดลภาษาขนาดใหญ่ (LLM) มีการพัฒนา custom CUDA kernel ที่รวมหลายโอเปอเรชันเข้าไว้ใน kernel เดียว เพื่อลด memory overhead และเพิ่มประสิทธิภาพ
- ตัวอย่างเช่น FlashAttention ปรับแต่ง self-attention ของ Transformer ให้มีประสิทธิภาพมากขึ้น ด้วยการลดการอ่านและเขียนหน่วยความจำลงอย่างมาก
- FlashAttention ใช้ shared memory เพื่อทำ tiling ของการคำนวณ จึงทำงานได้อย่างมีประสิทธิภาพสูงแม้กับลำดับข้อมูลที่ยาว
- การเพิ่มประสิทธิภาพลักษณะนี้ช่วยแก้ปัญหาคอขวดจาก memory bandwidth ในงาน deep learning ได้
เปรียบเทียบการใช้งาน PyTorch กับ CUDA
- ใน PyTorch สามารถทำงานบน GPU ได้ง่ายผ่าน abstraction ระดับสูง
- ตัวอย่างเช่น การหาผลบวกของเวกเตอร์สองตัวสามารถเขียนได้อย่างง่ายดายดังนี้:
import torch
# GPU에서 두 개의 큰 벡터 생성
a = torch.rand(1000000, device='cuda')
b = torch.rand(1000000, device='cuda')
# 요소별로 더하기
c = a + b
- อย่างไรก็ตาม หากต้องการปรับจูนประสิทธิภาพอย่างจริงจัง ก็สามารถเขียน custom kernel โดยใช้ CUDA โดยตรงได้
- เมื่อใช้ CUDA จะสามารถควบคุมรูปแบบการเข้าถึงหน่วยความจำ การจัดโครงสร้างเธรด การใช้ shared memory และองค์ประกอบอื่น ๆ ได้อย่างละเอียดเพื่อดึงประสิทธิภาพสูงสุด
- ตัวอย่างเช่น การ implement FlashAttention ด้วย CUDA จะปรับแต่งการเข้าถึงหน่วยความจำและทำ tiling ของการคำนวณใน shared memory เพื่อเพิ่มประสิทธิภาพ
- การปรับแต่งในระดับต่ำลักษณะนี้ช่วยให้ได้ประสิทธิภาพสูงกว่าการใช้งานผ่าน abstraction ระดับสูงของ PyTorch
สรุป
- การใช้ความสามารถในการประมวลผลแบบขนานของ GPU ช่วยให้จัดการข้อมูลขนาดใหญ่และการคำนวณที่ซับซ้อนได้อย่างมีประสิทธิภาพ
- CUDA เป็นแพลตฟอร์มที่ช่วยดึงประสิทธิภาพของ GPU ออกมาได้สูงสุด และนักพัฒนา Python ก็สามารถใช้ประโยชน์จากข้อดีของ CUDA ได้ผ่านเครื่องมืออย่าง Numba
- หากเข้าใจโครงสร้างเธรดและบล็อกของ CUDA รวมถึงเทคนิคการจัดการหน่วยความจำ ก็จะสามารถเขียนโปรแกรม GPU ได้อย่างมีประสิทธิภาพมากขึ้น
- โดยเฉพาะในงานอย่าง deep learning สามารถยกระดับประสิทธิภาพได้สูงสุดด้วยการเขียน custom CUDA kernel
- แม้จะใช้เฟรมเวิร์กระดับสูงอย่าง PyTorch ก็ยังสามารถเลือกใช้การปรับแต่ง CUDA ระดับต่ำเมื่อจำเป็น เพื่อให้ได้ประสิทธิภาพที่สูงกว่า
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
คำถามงี่เง่านิดหน่อย: ในฐานะวิศวกร เป็นไปได้ไหมที่จะลงลึกถึงระดับล่างของ CUDA หรือสถาปัตยกรรม GPU โดยไม่ต้องเรียนด้านคณิตศาสตร์ของ AI? ถ้าเป็นไปได้ ควรเริ่มอย่างไร? คิดว่าน่าจะต้องเรียนรู้เรื่องการเพิ่มประสิทธิภาพและเหตุผลที่ใช้ GPU กับการคำนวณบางประเภท
บทความยอดเยี่ยมมาก แบบทดสอบสั้นแทรกในเนื้อหา (QnA) ที่ดูเหมือน AI สร้างขึ้นมีประโยชน์มากในการทดสอบความเข้าใจ อยากให้ทุกบทเรียนมีฟีเจอร์แบบนี้
สงสัยว่าบทเรียน CUDA ทั้งหมดมุ่งเป้าไปที่ AI หรือมีแบบสำหรับการคำนวณทางวิทยาศาสตร์ทั่วไปด้วย เช่น น่าจะสนุกดีถ้าได้ลองอะไรอย่างการไหลของอากาศเหนือปีกเพื่อการประมวลผลสมรรถนะสูง
ขอบคุณที่แชร์ อ่านแล้วเพลินมาก มีคำถามที่เกี่ยวข้องนิดหน่อย: สงสัยว่ามีมุมมองอะไรไหมเกี่ยวกับวิธีที่ DeepSeek ทำให้การรันมีประสิทธิภาพขึ้นโดยอ้อม CUDA
Jensen ให้มา แล้ว Guido ก็เอาคืนไป
หนังสือเล่มนี้: "Programming Massively Parallel Processors" ดูเหมือนจะออกแบบมาสำหรับคนที่ย้ายจากสถาปัตยกรรม CPU ไปสู่ GPU โดยเฉพาะ
นอกจากนี้แนะนำให้ดู https://github.com/rust-gpu/rust-gpu และ https://github.com/rust-gpu/rust-cuda
ลิงก์ที่เกี่ยวข้อง: https://sakana.ai/ai-cuda-engineer/ และ https://reddit.com/r/MachineLearning/…
สงสัยว่ามีไอเดียไหมว่าเมื่อเร็ว ๆ นี้มีอะไรเปลี่ยนไป และอะไรทำให้เราสามารถรันการจำลองที่เมื่อก่อนทำได้แค่บน CPU ไปจนจบบน GPU ได้แล้ว (เช่น isaac sim)
เนื่องจากนี่อยู่บนเว็บไซต์ของ PySpur เลยสงสัยว่ามีใครมีประสบการณ์กับเครื่องมือ UI สำหรับ AI agent อย่าง PySpur และ n8n ไหม กำลังมองหาสิ่งที่น่าจะช่วยได้สำหรับลองทำต้นแบบไอเดียบางอย่างเล่น ๆ ต้องโฮสต์เองด้วย($) จึงอยากได้อะไรที่ตั้งค่าง่ายพอสมควรแบบ Open Hands