Hypura – ตัวจัดตารางอนุมาน LLM แบบรับรู้ลำดับชั้นการจัดเก็บข้อมูลสำหรับ Apple Silicon
(github.com/t8)- เพิ่มประสิทธิภาพการจัดวางเทนเซอร์ระหว่าง GPU·RAM·NVMe เพื่อรัน ตัวจัดตารางอนุมานแบบรับรู้ลำดับชั้นการจัดเก็บข้อมูล สำหรับโมเดลภาษาขนาดใหญ่
- บน Mac Mini 32GB สามารถรันโมเดล Mixtral 8x7B(31GB) ที่ความเร็ว 2.2 tok/s และโมเดล Llama 70B(40GB) ที่ความเร็ว 0.3 tok/s
- วิเคราะห์รูปแบบการเข้าถึงและแบนด์วิดท์ของฮาร์ดแวร์เพื่อให้ โมเดลที่ใหญ่เกินหน่วยความจำจริงทำงานได้อย่างเสถียร รวมถึงโมเดลที่เดิม
llama.cppล้มเหลวด้วย OOM ก็ยังประมวลผลได้ - ลด I/O ได้สูงสุด 75% และทำแคชฮิตเรตได้ 99.5% ผ่าน การกำหนดเส้นทางผู้เชี่ยวชาญของ MoE, นิวรอนแคช, และ การพรีเฟตช์
- เลือกโหมด Full-resident, Expert-streaming, Dense FFN-streaming โดยอัตโนมัติตามขนาดโมเดลและฮาร์ดแวร์ เพื่อคงประสิทธิภาพที่เหมาะสมที่สุด
- มี HTTP API ที่เข้ากันได้กับ Ollama จึงเชื่อมต่อกับ OpenClaw เป็นต้นได้ และใช้ SSD แบบอ่านอย่างเดียวเพื่อรองรับ การอนุมานบน NVMe โดยไม่กระทบอายุการใช้งาน
ภาพรวม
- Hypura เป็น ตัวจัดตารางอนุมาน LLM แบบรับรู้ลำดับชั้นการจัดเก็บข้อมูล สำหรับสภาพแวดล้อม Apple Silicon โดยเป็นเครื่องมือที่ทำ การเพิ่มประสิทธิภาพการจัดวางเทนเซอร์ ระหว่าง GPU·RAM·NVMe
- กระจายการจัดวางเทนเซอร์ตามรูปแบบการเข้าถึง ต้นทุนแบนด์วิดท์ และประสิทธิภาพฮาร์ดแวร์ ทำให้ โมเดลขนาดใหญ่ที่เกินหน่วยความจำจริงสามารถทำงานได้อย่างเสถียร
- บน Mac Mini 32GB สามารถรันโมเดล Mixtral 8x7B(31GB) ที่ความเร็ว 2.2 tok/s และโมเดล Llama 70B(40GB) ที่ความเร็ว 0.3 tok/s
- ในสภาพแวดล้อมเดียวกัน llama.cpp ไม่สามารถรันได้เนื่องจาก OOM (Out of Memory)
ที่มาของปัญหา
- Mac สำหรับผู้บริโภคมี หน่วยความจำรวมความเร็วสูงและอุปกรณ์จัดเก็บ NVMe แต่มีข้อจำกัดด้านความจุหน่วยความจำ
- ตัวอย่างเช่น M1 Max 32GB ไม่สามารถโหลดโมเดลขนาด 40GB ได้โดยตรง จึงเกิด การสว็อปมากเกินไปและจบการทำงานด้วย OOM
- Hypura แก้ปัญหานี้ด้วยการวิเคราะห์โครงสร้างของโมเดลและจัดวางให้เหมาะสมในแต่ละชั้น
การจัดวางตามชั้นโดยอิงจากโครงสร้างโมเดล
- Norms และ Embeddings: มีขนาดเล็กแต่ถูกเข้าถึงทุกโทเคน จึงตรึงไว้บน GPU
- MoE Expert Routing: ใช้ประโยชน์จากความ sparse โดยจะเปิดใช้งานผู้เชี่ยวชาญเพียง 2 จาก 8 คนต่อโทเคน
- ดักจับเราเตอร์เพื่อระบุผู้เชี่ยวชาญที่ถูกเปิดใช้งาน แล้วโหลดเฉพาะส่วนที่จำเป็นจาก NVMe
- ทำได้ทั้ง ลด I/O ลง 75% และ นิวรอนแคชฮิตเรต 99.5%
- ใช้ การติดตามการเปิดใช้งานร่วม (co-activation tracking) เพื่อคาดการณ์ผู้เชี่ยวชาญที่จะถูกเปิดใช้งานถัดไปและทำการพรีเฟตช์ล่วงหน้า
- Dense FFN Weights: คิดเป็นประมาณ 60% ของขนาดโมเดล
- สตรีมจาก NVMe ผ่าน dynamic pool buffer
- prefetch lookahead depth จะปรับอัตโนมัติตามหน่วยความจำที่มีให้ใช้
- ผลลัพธ์คือ แม้แต่โมเดลที่เดิมแครชเมื่อใช้วิธี
mmapแบบเดิมก็ยังรันได้ และสำหรับโมเดลที่พอดีกับหน่วยความจำก็ทำงานที่ ความเร็วระดับ Metal GPU โดยไม่มีโอเวอร์เฮด
วิธีการทำงาน
- Hypura จะ อ่านไฟล์ GGUF และโปรไฟล์แบนด์วิดท์ของ GPU·RAM·NVMe
- จากนั้นจัดวางแต่ละเทนเซอร์ลงในหนึ่งในสามชั้นต่อไปนี้
- GPU(Metal): ชั้น Attention, Norm, Embedding
- RAM: ชั้น overflow ที่ไม่สามารถโหลดขึ้น GPU ได้
- NVMe: ชั้นที่เหลือ โดยใช้
F_NOCACHE+preadเพื่อทำ I/O โดยตรง
- เลือก โหมดอนุมาน โดยอัตโนมัติตามขนาดโมเดลและฮาร์ดแวร์
- Full-resident: โหลดโมเดลทั้งหมดไว้ใน GPU+RAM ไม่มี NVMe I/O
- Expert-streaming: สำหรับโมเดล MoE โดยให้เฉพาะเทนเซอร์ที่ไม่ใช่ผู้เชี่ยวชาญอยู่บน GPU และสตรีมเทนเซอร์ผู้เชี่ยวชาญจาก NVMe
- Dense FFN-streaming: สำหรับโมเดลขนาดใหญ่ที่ไม่ใช่ MoE โดยให้ Attention+Norm อยู่บน GPU และสตรีม FFN จาก NVMe
- ขนาดพูลบัฟเฟอร์, ความลึกการพรีเฟตช์, งบหน่วยความจำ จะคำนวณอัตโนมัติตามโปรไฟล์ฮาร์ดแวร์
ประสิทธิภาพ
- สภาพแวดล้อมทดสอบ: M1 Max, หน่วยความจำรวม 32GB, NVMe 5.1GB/s
- ผลการวัดประสิทธิภาพหลัก
- Qwen 2.5 14B Q4_K_M (8.4GB): โหลดเต็มบน GPU, 21 tok/s
- Mixtral 8x7B Q5_K_M (30.9GB): โหมด Expert-streaming, 2.2 tok/s, แคชฮิตเรต 99.5%
- Llama 3.3 70B Q4_K_M (39.6GB): โหมด Dense FFN-streaming, 0.3 tok/s, พูล 24 สล็อต, พรีเฟตช์ 7 ชั้น
- โมเดลที่พอดีกับหน่วยความจำมี โอเวอร์เฮด 0 และโมเดลที่เกินหน่วยความจำก็ยัง คงสถานะพร้อมใช้งานได้ด้วย Hypura
การติดตั้งและการรัน
- ต้องใช้ Rust 1.75+ และ CMake
- ขั้นตอนการติดตั้ง
git clone --recurse-submodules https://github.com/hypura/hypura.git cd hypura cargo build --release - ตัวอย่างการรัน
hypura profile hypura run ./model.gguf --prompt "Hello, world" hypura run ./model.gguf --interactive hypura bench ./model.gguf hypura inspect ./model.gguf - สำหรับโมเดลที่ยังไม่ผ่านการตรวจสอบ แนะนำให้ทดสอบด้วย
--max-tokens 10
เซิร์ฟเวอร์ที่เข้ากันได้กับ Ollama
- Hypura มี HTTP API ที่เข้ากันได้กับ Ollama จึง เข้ากันได้เต็มรูปแบบกับเครื่องมือที่อิง Ollama เช่น OpenClaw
hypura serve ./model.gguf Endpoint: http://127.0.0.1:8080 API: /api/generate, /api/chat, /api/tags - เอนด์พอยต์หลัก
Endpoint ฟังก์ชัน GET /ตรวจสอบสถานะ GET /api/tagsรายการโมเดลที่โหลดอยู่ GET /api/versionเวอร์ชันเซิร์ฟเวอร์ POST /api/showเมทาดาทาของโมเดล POST /api/generateสร้างข้อความ POST /api/chatสร้างบทสนทนาแบบโต้ตอบ - การเชื่อมต่อ OpenClaw ให้กำหนด Ollama base URL เป็น Hypura ใน
~/.openclaw/openclaw.json - ตัวเลือกของเซิร์ฟเวอร์
hypura serve [OPTIONS] --host ค่าเริ่มต้น 127.0.0.1 --port ค่าเริ่มต้น 8080 --context ค่าเริ่มต้น 4096
สถาปัตยกรรม
- ใช้โครงสร้างแบบ Cargo workspace และประกอบด้วยสอง crate
hypura: ไบนารีหลักและไลบรารีhypura-sys: FFI binding ของ llama.cpp (บิลด์ด้วย CMake)
- โมดูลหลัก
โมดูล บทบาท scheduler/placement.rsเพิ่มประสิทธิภาพการจัดวางเทนเซอร์ระหว่าง GPU/RAM/NVMe compute/inference.rsเอนจินอนุมานและฟังก์ชันโหลด/สร้างสำหรับเซิร์ฟเวอร์ compute/nvme_backend.rsNVMe streaming, นิวรอนแคช, evaluation callback server/routes.rsHTTP handler ที่เข้ากันได้กับ Ollama profiler/การโปรไฟล์ฮาร์ดแวร์ cli/bench.rsเครื่องมือเบนช์มาร์ก model/tensor_role.rsการจัดประเภทบทบาทของเทนเซอร์
FAQ
-
ไม่มีปัญหาเรื่องอายุการใช้งาน SSD
- Hypura อ่านจาก SSD เท่านั้น ไม่มีการเขียน
- NVMe I/O ทำแบบอ่านอย่างเดียวด้วย
pread()+F_NOCACHE - SSD ทำหน้าที่เพียง cold storage ส่วนการคำนวณทำบน RAM/GPU
- การเขียนที่เกิดขึ้นมีเพียงระดับเล็กน้อยแค่ หน่วย KB เช่น JSON ผลเบนช์มาร์ก ไฟล์สถิติ เป็นต้น
แนวทางความปลอดภัย
- หากโมเดลเกินขีดจำกัด RAM (เผื่อไว้ –4GB) จะบล็อก
bench --baseline - สำหรับโมเดลที่ยังไม่ผ่านการตรวจสอบ ให้ทดสอบด้วย
--max-tokens 10 - โมเดลทดสอบถูกเก็บไว้ในไดเรกทอรี
./test-models/
ไลเซนส์
- MIT License
ประกาศด้านจริยธรรม
- โค้ดในรีโพซิทอรีไม่ได้เขียนขึ้นโดยผู้สร้างเองทั้งหมด
- สร้างขึ้นจาก การทดลองสร้างโค้ดตามคำสั่งโดยใช้ LLM
- เป็นโปรเจกต์เพื่อสำรวจความเป็นไปได้ของการอนุมานบน NVMe
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
อยากเสนอให้ผู้ดูแลพิจารณา ปัจจุบันตารางเปรียบเทียบยังมี โมเดลเก่า อย่าง Qwen 2.5 14B, Mixtral 8x7B และ Llama 3.3 70B อยู่
ช่วงหลังมีรายงานมากมายว่าโมเดล Qwen 3.5 MoE ทำผลงานได้อย่างน่าทึ่งบนฮาร์ดแวร์ Apple
ลองดู บทความของ Simon Willison ประกอบได้
ถ้าเป็นไปได้ อยากให้เพิ่มโมเดล Kimi K2.5 (1T พารามิเตอร์) ลงในตารางด้วย
ทวีตที่เกี่ยวข้อง: seikixtc, danpacary
มีข้อความผิดพลาดเกี่ยวกับ Heroku ขึ้นมา แต่ตอนนี้กลับมาใช้งานได้ตามปกติแล้ว
ฉันเข้าไปดู โพสต์นี้ แล้วก็เห็นว่าคุณเขียนเรื่อง litellm ไว้แล้วด้วย อ่านได้ดีมาก
สำหรับงานในเครื่อง ความเร็วต่ำกว่า 1 โทเค็นต่อวินาทีก็ยัง ใช้งานได้ ถ้าเป็น งานเบื้องหลัง
ความต่างระหว่าง “จบทันที” กับ “เสร็จข้ามคืน” ก็ยังเป็น การก้าวกระโดดด้านประสิทธิภาพ ที่มีความหมาย
ในความเป็นจริง สิ่งสำคัญคือรูปแบบการอ่านมีความ ต่อเนื่อง (sequential) แค่ไหน
NVMe อ่านแบบต่อเนื่องได้ 5–7GB/s แต่ถ้าเป็นการอ่านแบบสุ่มจะลดลงเหลือราว 500MB/s
สำหรับโมเดล 1T หากคิดแบบ fp16 จะต้องสตรีมข้อมูล 2TB ต่อหนึ่ง forward pass ดังนั้นตามทฤษฎีแล้วจะใช้เวลามากกว่า 300 วินาทีต่อโทเค็น
ไม่เหมาะกับงานโต้ตอบ แต่ยังพอมีความเป็นไปได้สำหรับ batch inference
แต่กับโมเดล MoE ขนาดเล็ก สามารถสร้างได้หลายโทเค็นต่อวินาที จึงพอใช้งานได้จริง
ไม่ได้อ่านครบทั้ง 2TB แต่เข้าถึงเฉพาะ expert layer บางส่วน
แต่ละเลเยอร์มีขนาดระดับไม่กี่ MiB ทำให้ประสิทธิภาพการเข้าถึง NVMe ก็ไม่ได้แย่นัก
ฉันสงสัยว่า “โมเดล 1T พารามิเตอร์” มาจากไหน เพราะในรีโปเห็นมีแต่โมเดล 70B หรือต่ำกว่า
โมเดลที่สมจริงกว่าคือกลุ่ม MoE ที่เล็กกว่าแต่ยังสร้างได้หลายโทเค็นต่อวินาที
ประเด็นของ MoE คือด้วย sparse activation จึงไม่ต้องอ่านครบทั้ง 2TB
แต่รูปแบบการเข้าถึงจะ กระจัดกระจายแบบสุ่ม ซึ่งเป็นเงื่อนไขที่แย่ที่สุดสำหรับ NVMe
สำหรับงานอย่าง agent inference ที่ latency สำคัญ ประเด็นนี้ถือเป็นหัวใจหลัก
เหมือน Intel Optane จะพลิกตัวอยู่ในหลุมศพ
แต่ในทางปฏิบัติมันไม่ได้เร็วกว่า NVMe เท่าไร ซอฟต์แวร์ที่รองรับ การอ่าน/เขียนแบบขนาน แทบไม่เห็นความต่าง
ถึงอย่างนั้นถ้าเอา 4 ตัวมามัด RAID 0 ก็น่าจะอัดแบนด์วิดท์ PCIe 16x ได้เต็ม
ฮาร์ดแวร์ Mac สำหรับผู้บริโภคมีทั้ง unified memory และ NVMe ที่เร็ว แต่ความจุมีจำกัด
ถ้าโหลดโมเดล 40GB บน M1 Max 32GB จะเกิด swap หนักมากและสุดท้ายเข้าสู่สถานะ panic
macOS ไม่มี OOM killer แบบ Linux และจะลงเอยแค่พื้นที่ swap ไม่พอ
การมี “หน่วยความจำให้มากที่สุด” สำคัญก็จริง แต่ แบนด์วิดท์ (bandwidth) เป็นตัวแปรที่สำคัญกว่า
M4 Pro อยู่ที่ 273GB/s, M4 Max ที่ 546GB/s และ M4 Ultra ที่ 819GB/s
หลังจากโมเดลเข้าไปอยู่ในหน่วยความจำแล้ว แบนด์วิดท์จะเป็นตัวกำหนด ความเร็วโทเค็น
สำหรับ Hypura นั้น M4 Max คือ sweet spot เพราะ 64GB ก็รันโมเดล 70B (Q4) ได้สบาย และสร้างได้เร็วกว่า Pro ราว 2 เท่า
โปรเจกต์นี้ทำงานคล้าย swap memory อัจฉริยะ
จุดที่น่าสนใจคือมันคอยควบคุมไม่ให้ใช้ NVMe มากเกินไป
แต่ถ้าใช้งาน NVMe หนักจริง ๆ ก็ยังน่ากังวลเรื่อง อายุการใช้งานที่สั้นลง
SSD มีอายุเซลล์ลดลงตามจำนวนครั้งที่เขียนก็จริง แต่แทบไม่มีกรณีที่ ภาระการอ่าน จะทำให้คอนโทรลเลอร์เสียหาย
ถ้าเกิดแบบนั้นจริง แปลว่าระบบน่าจะมีปัญหาอย่างอื่น
น่าจะดีถ้าเอาโปรเจกต์นี้ไปเทียบกับการทดลองก่อนหน้า, ความพยายามอีกอัน
อันนี้ใช้ mmap-based และมีรายงานว่า overhead สูง