- เอนจินอนุมานที่พัฒนาด้วย C/Metal ซึ่งสามารถรัน โมเดล Mixture-of-Experts ขนาด 397B พารามิเตอร์ บน MacBook Pro (RAM 48GB) ได้ที่มากกว่า 4.4 โทเค็นต่อวินาที
- สตรีมโมเดลขนาดรวม 209GB จาก SSD และสร้างขึ้นด้วย C และ Metal shaders เท่านั้น โดยไม่ใช้ Python หรือเฟรมเวิร์ก
- เพิ่มประสิทธิภาพการทำงานแบบขนานของ GPU·SSD·CPU ให้สูงสุดด้วย SSD Expert Streaming, เคอร์เนล FMA ที่ปรับแต่งแล้ว, Deferred GPU Compute เป็นต้น
- การตั้งค่า ควอนไทซ์แบบ 4-bit ให้สมดุลระหว่างคุณภาพและความเร็ว พร้อมสร้างผลลัพธ์ระดับโปรดักชันที่มี ความสามารถในการเรียกใช้เครื่องมือ รวมอยู่ด้วย
- เป็นกรณีศึกษาด้านการทำให้เบาและการปรับแต่งที่ทำให้ โมเดล MoE ขนาดใหญ่มากสามารถอนุมานแบบเรียลไทม์ได้แม้ในสภาพแวดล้อมโน้ตบุ๊ก
ผลลัพธ์ด้านประสิทธิภาพ
- การตั้งค่า ผู้เชี่ยวชาญ 4-bit (เคอร์เนล FMA) ทำได้ 4.36 tok/s คุณภาพดี และใช้ดิสก์รวม 209GB
- การตั้งค่าพื้นฐานแบบ 4-bit ทำได้ 3.90 tok/s เป็นขั้นก่อนการปรับแต่ง FMA
- การตั้งค่า ผู้เชี่ยวชาญ 2-bit (trust OS) ทำได้ 5.74 tok/s เร็วกว่าแต่มีข้อผิดพลาดในการส่งออก JSON จึงไม่สามารถเรียกใช้เครื่องมือได้
- โทเค็นเดี่ยวที่พีกของ 2-bit ไปได้ถึง 7.05 tok/s แต่ไม่เหมาะกับการใช้งานจริง
- การควอนไทซ์แบบ 4-bit เป็นการตั้งค่าที่เหมาะกับการใช้งานจริง
สภาพแวดล้อมฮาร์ดแวร์
- MacBook Pro (Apple M3 Max), CPU 16 คอร์ (12P+4E), GPU 40 คอร์, ANE 16 คอร์
- หน่วยความจำแบบรวม 48GB, แบนด์วิดท์ประมาณ 400GB/s
- SSD คือ 1TB Apple Fabric, ความเร็วอ่านแบบ sequential 17.5GB/s
- สภาพแวดล้อม macOS 26.2 (Darwin 25.2.0)
สถาปัตยกรรมโมเดล
- รวม 60 ชั้นของทรานส์ฟอร์เมอร์: 45 ชั้น GatedDeltaNet (linear attention) + 15 ชั้น full attention
- แต่ละชั้นมี ผู้เชี่ยวชาญ 512 คน และมีการเปิดใช้งาน K=4 คน ต่อโทเค็น (รวมผู้เชี่ยวชาญที่ใช้ร่วมกัน 1 คน)
- มิติซ่อน 4096
-
เทคโนโลยีหลัก
-
SSD Expert Streaming
- โหลดน้ำหนักของผู้เชี่ยวชาญ (209GB ในกรณี 4-bit) จาก NVMe SSD ด้วย
pread() แบบขนาน ตามต้องการ
- ในแต่ละชั้นจะโหลดเฉพาะ ผู้เชี่ยวชาญที่ถูกเปิดใช้งาน 4 คนเท่านั้น (ประมาณ 6.75MB ต่อคน)
- OS page cache จัดการแคชให้อัตโนมัติ จึงไม่จำเป็นต้องมีแคชแยกต่างหาก
- โครงสร้างนี้ได้รับแรงบันดาลใจจากงานวิจัย “LLM in a Flash” ของ Apple
-
เคอร์เนล dequant แบบปรับแต่ง FMA
- จัดรูปการคำนวณ
(nibble * scale + bias) * x ใหม่เป็น fma(nibble, scale*x, bias*x)
- คำนวณ
scale*x และ bias*x ล่วงหน้าเพื่อให้ หน่วย FMA ของ GPU ทำงานได้ด้วยคำสั่งเดียว
- เร็วขึ้น 12% เมื่อเทียบกับการติดตั้งแบบเรียบง่าย
-
Metal Compute Shaders
- นำ 4-bit/2-bit dequant matrix-vector multiplication, SwiGLU activation, RMS normalization, GPU attention (Q@Kᵀ, softmax, scores@V), RoPE, การรวม MoE+residual+gate เป็นต้น ไปเขียนเป็น เคอร์เนล Metal แบบ hand-coded
-
Deferred GPU Expert Compute
- ส่งคำสั่ง CMD3 (expert forward pass) แบบ asynchronous เพื่อให้ CPU เตรียมชั้นถัดไปขณะที่ GPU กำลังรัน
- การคำนวณ รวม+normalization+residual ก็ทำบน GPU เช่นกัน และส่งต่อไปยังชั้นถัดไปโดยตรง
-
การใช้ Accelerate BLAS
- ใช้
cblas_sscal, cblas_sgemv, cblas_sger กับการคำนวณแบบเวียนกลับของ GatedDeltaNet
- เร็วกว่าโค้ดแบบ scalar 64%
-
Trust the OS
- ตัด custom cache ออก และให้ OS page cache (อิง LRU, ประมาณ 35GB) รับหน้าที่แคชข้อมูลผู้เชี่ยวชาญ
- ช้ากว่าไม่ว่าจะเป็น Metal LRU ที่ทำเอง, malloc cache หรือ LZ4 compression cache
- ได้ อัตรา cache hit ตามธรรมชาติ 71%
-
ข้อจำกัดของหน่วยความจำแบบรวม
- บน Apple Silicon นั้น SSD DMA และการคำนวณของ GPU ใช้ตัวควบคุมหน่วยความจำเดียวกัน
- เมื่อทำงานแบบขนาน หากแบนด์วิดท์ GPU อิ่มตัวจะทำให้ latency พุ่งสูงขึ้น
- ไปป์ไลน์แบบลำดับ GPU → SSD → GPU เป็นรูปแบบที่ เหมาะกับฮาร์ดแวร์ที่สุด
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
มีอีกวิธีในการรัน Qwen 3.5 397B บนอุปกรณ์สำหรับผู้บริโภค
มีเวอร์ชัน quant 2.5 BPW ที่ทำให้รันบนอุปกรณ์ที่มีหน่วยความจำ 128GB ได้สบาย
ฉันเคยรันบน M1 Ultra ได้ดีที่ราว 20 tok/s โดยคงคอนเท็กซ์ 256k ไว้
ผล lm-evaluation-harness อยู่ที่ mmlu 87.86%, gpqa diamond 82.32%, gsm8k 86.43%, ifeval 75.90% โดยประมาณ
ประสบการณ์แบบละเอียดสรุปไว้ใน ลิงก์สนทนา Hugging Face 1 และ ลิงก์ 2
เป็นโมเดลที่ยอดเยี่ยมสำหรับงาน inference แบบออฟไลน์
ลดจำนวน expert ต่อ token จาก 10 เหลือ 4 ทำให้คุณภาพแย่ลงไปอีก
สำหรับพรอมป์ต์สั้น ๆ ยังพอใช้ได้ แต่กับเซสชันยาว ๆ ใช้งานแทบไม่ได้
ยังมีปัญหาที่มันสร้าง
"name"เป็น\name\ในผลลัพธ์ JSON ทำให้ tool calling ไม่เสถียรและยังทำงานได้ดีไหมเมื่อคอนเท็กซ์ยาว
อีกอย่าง ดีใจที่ได้เห็นชื่อคุณอีกครั้ง — คนสร้าง Neovim นี่เอง ช่างเป็นความสำเร็จที่น่าทึ่งจริง ๆ
ฉันเองก็ใช้ทุกวัน
บางทีอาจประเมินได้ด้วย CoconutBattery
ดูจากรายละเอียดแล้วเหมือนจะได้ราว 5 tok/s ด้วยการทำ 2-bit quantization และลดจำนวน expert จาก 10 เหลือ 4
เป็น proof of concept ที่น่าสนใจ แต่ห่างไกลจากคุณภาพของโมเดล 397B ดั้งเดิมมาก
การปรับแต่งสุดโต่งแบบนี้ทำให้เกิด การสูญเสียความฉลาด ของโมเดล
ยังมีปัญหาที่มันสร้าง
"name"เป็น\name\ในผลลัพธ์ JSON จึงไม่เหมาะกับการใช้งานจริงยอมรับว่าเป็นความพยายามที่แสดงให้เห็นว่าการทดลองแบบนี้ทำได้ในทางเทคนิค แต่ยังไม่ถึงระดับที่ใช้งานได้จริง
ช่วงนี้รู้สึกเหนื่อยกับ งานเขียน AI แบบนี้ที่มีเยอะเกินไป
แต่ในทางปฏิบัติก็ได้ยินมาว่าแม้แต่ LLM เชิงพาณิชย์ก็ยังมีความแม่นยำด้าน tool calling ต่ำ
น่าจะเป็นส่วนที่ทำได้ยาก หรืออาจเป็นข้อจำกัดเชิงโครงสร้างที่ทำไม่ได้เลย
มีการพูดคุยที่เกี่ยวข้องใน r/LocalLLaMA เช่นกัน
ตามหน้า GitHub การเข้าถึงแบบ mmap ตรง ๆ จะติดคอขวดจาก overhead ระดับ page
เลยสงสัยว่าบน macOS ถ้าตั้งค่า huge page หรือทำ prefetch ด้วย
posix_fadviseจะช่วยได้ไหมคุณภาพที่ลดลงจาก 2-bit quantization เป็นปัญหาร้ายแรงจริง ๆ
จากประสบการณ์ งานจริงมักได้ผลดีกว่าถ้าใช้ โมเดล 30B 4-bit ที่จูนมาดี แทน 70B+ 2-bit
พอลดจำนวน expert ลง มันก็แทบจะกลายเป็นคนละโมเดลแล้ว
ถึงอย่างนั้น การทดลองทดสอบขีดจำกัดของฮาร์ดแวร์ผู้บริโภคก็น่าสนใจอยู่ดี
พาดหัวว่า “รันบนโน้ตบุ๊ก” แต่สุดท้ายก็มักหมายถึง MacBook ราคา $3000 ทุกที มันชวนล้าเหมือนกัน
เทคนิคการบีบอัดน่าประทับใจ แต่ไม่ใช่ตัวเลือกที่สมจริงสำหรับผู้ใช้ทั่วไป
แต่ก็ไม่ได้เห็นพาดหัวแล้วคาดหวังว่าจะรันได้บนโน้ตบุ๊กอะไรก็ได้
ฉันค่อนข้างสนุกกับการทดลองพวกนี้มากกว่าจะมองแบบประชดประชันเกินไป
หลายคนก็มี MacBook แรง ๆ แบบนี้อยู่แล้วจากงานตัดต่อวิดีโอหรืออย่างอื่น
ข้อดีคือสามารถทดลองบนโน้ตบุ๊กที่มีอยู่เดิมได้โดยไม่ต้องซื้ออุปกรณ์เพิ่ม
ได้ความเร็วราว 20 tok/s และคิดว่าถือว่าเข้าถึงได้พอสมควรแม้สำหรับบุคคลทั่วไป
สำหรับงานอาชีพก็คุ้มค่าที่จะลงทุน
“No Python. No frameworks. Just C, Objective-C, and hand-tuned Metal shaders.”
พอเห็นประโยคนี้ก็พอนึกออกทันทีว่า token มาจากไหน
บอกว่าเป็น “Hand-written Metal kernels” แต่หรือว่าจะเป็น GPT เขียนเอง? 😉
เป็นผลลัพธ์ที่น่าประทับใจมาก
สงสัยว่าบน Linux จะทำแนวทางคล้ายกันได้ไหม โดยใช้ การเข้าถึงผ่านหน่วยความจำระบบ แทน SSD
หรือแม้แต่แนวคิดเก็บ weight ในรูปแบบ ROM ก็น่าสนใจ
เพียงแต่โปรเจกต์นี้ใช้ Metal เลยเป็น macOS เท่านั้น
แต่โมเดล MoE ก็ยังติดข้อจำกัดด้าน แบนด์วิดท์ มาก
แต่ในขั้น decode ค่า overhead จากการส่งผ่าน CPU มักสูงกว่า GPU จึงได้ประโยชน์ไม่มาก
การใช้ GPU เร่งเฉพาะส่วนที่เป็น shared จะมีประสิทธิภาพกว่า
แต่ถ้าโมเดลล้นไปอยู่ใน RAM ของระบบหรือดิสก์เมื่อไร ประสิทธิภาพจะตกฮวบ
มีคำอธิบายว่า SSD เป็นคอขวด แต่ผู้เขียนบอกว่าได้ 15GB/s
เท่าที่ฉันรู้ แบนด์วิดท์สูงสุดน่าจะราว 8GB/s เอง ฉันพลาดอะไรไปรึเปล่า?
เมื่อผลจาก router ออกมา ก็จะต้องโหลด expert จาก SSD ทันที ซึ่งเป็นจังหวะที่ SSD ถูกใช้งานเต็มที่
IO เฉลี่ยอยู่ราว 2970MB/s ซึ่งต่ำกว่าขีดจำกัดของ SSD มาก
ถ้าทำการอ่าน tensor บางส่วนแบบ asynchronous ให้ขนานกันได้ก็น่าจะดีขึ้นอีก
ตอนฉันทดลองบน Linux ด้วย io_uring พบว่าประมาณ 20% ของการอ่านเสร็จขนานไประหว่างการคำนวณ