- Tối ưu phân bổ tensor giữa GPU·RAM·NVMe để chạy các mô hình ngôn ngữ lớn bằng một bộ lập lịch suy luận nhận biết tầng lưu trữ
- Trên Mac mini 32GB, có thể chạy mô hình Mixtral 8x7B(31GB) ở tốc độ 2.2 tok/s và mô hình Llama 70B(40GB) ở tốc độ 0.3 tok/s
- Phân tích mẫu truy cập và băng thông phần cứng để vận hành ổn định cả những mô hình vượt quá bộ nhớ vật lý, xử lý được cả các mô hình mà llama.cpp trước đây thất bại do OOM
- Thông qua định tuyến chuyên gia của kiến trúc MoE, bộ nhớ đệm neuron và prefetch, giảm I/O tới 75% và đạt tỷ lệ cache hit 99.5%
- Tự động chọn các chế độ Full-resident, Expert-streaming, Dense FFN-streaming theo kích thước mô hình và phần cứng để duy trì hiệu năng tối ưu
- Cung cấp HTTP API tương thích Ollama để tích hợp với OpenClaw và các công cụ khác, đồng thời dùng SSD chỉ ở chế độ đọc để hỗ trợ suy luận dựa trên NVMe mà không làm giảm tuổi thọ
Tổng quan
- Hypura là một bộ lập lịch suy luận LLM nhận biết tầng lưu trữ trên môi trường Apple Silicon, thực hiện tối ưu phân bổ tensor giữa GPU·RAM·NVMe
- Dựa trên mẫu truy cập, chi phí băng thông và hiệu năng phần cứng, nó phân bố tensor trên nhiều tầng để chạy ổn định các mô hình lớn vượt quá bộ nhớ vật lý
- Trên Mac Mini 32GB, có thể chạy mô hình Mixtral 8x7B(31GB) ở tốc độ 2.2 tok/s và mô hình Llama 70B(40GB) ở tốc độ 0.3 tok/s
- Trong cùng môi trường, llama.cpp không thể chạy do OOM (Out of Memory)
Bối cảnh vấn đề
- Máy Mac cho người dùng phổ thông có bộ nhớ hợp nhất nhanh và lưu trữ NVMe, nhưng dung lượng bộ nhớ lại bị giới hạn
- Ví dụ, M1 Max 32GB không thể nạp trực tiếp mô hình 40GB nên xảy ra swap quá mức và bị dừng do OOM
- Hypura giải quyết vấn đề này bằng cách phân tích cấu trúc mô hình và thực hiện phân bổ tối ưu theo từng tầng
Phân bổ theo tầng dựa trên cấu trúc mô hình
- Norms và Embeddings: nhỏ nhưng được truy cập ở mọi token nên được cố định trên GPU
- Định tuyến chuyên gia MoE: tận dụng tính thưa, chỉ kích hoạt 2 chuyên gia trong số 8 cho mỗi token
- Chặn router để xác định các chuyên gia đang hoạt động, sau đó chỉ nạp phần cần thiết từ NVMe
- Giảm I/O 75%, đạt tỷ lệ bộ nhớ đệm neuron 99.5%
- Dùng theo dõi đồng kích hoạt (co-activation tracking) để dự đoán chuyên gia sẽ hoạt động tiếp theo và thực hiện prefetch trước
- Dense FFN Weights: chiếm khoảng 60% kích thước mô hình
- Stream từ NVMe thông qua dynamic pool buffer
- Độ sâu prefetch nhìn trước (prefetch lookahead depth) được tự động điều chỉnh theo lượng bộ nhớ khả dụng
- Kết quả là ngay cả các mô hình từng bị crash với cách mmap truyền thống cũng có thể chạy được; còn các mô hình vừa với bộ nhớ thì chạy ở tốc độ Metal GPU mà không có overhead
Cách hoạt động
- Hypura đọc tệp GGUF và profiling băng thông GPU·RAM·NVMe
- Mỗi tensor được đặt vào một trong ba tầng sau
- GPU(Metal): các tầng Attention, Norm, Embedding
- RAM: các tầng tràn không thể nạp lên GPU
- NVMe: các tầng còn lại, thực hiện I/O trực tiếp bằng
F_NOCACHE + pread
- Tự động chọn chế độ suy luận theo kích thước mô hình và phần cứng
- Full-resident: nạp toàn bộ mô hình vào GPU+RAM, không có I/O NVMe
- Expert-streaming: cho mô hình MoE, chỉ các tensor không phải chuyên gia cư trú trên GPU, tensor chuyên gia được stream từ NVMe
- Dense FFN-streaming: cho các mô hình lớn không phải MoE, Attention+Norm ở GPU, FFN được stream từ NVMe
- Kích thước pool buffer, độ sâu prefetch, ngân sách bộ nhớ được tự động tính theo hồ sơ phần cứng
Hiệu năng
- Môi trường thử nghiệm: M1 Max, 32GB bộ nhớ hợp nhất, NVMe 5.1GB/s
- Kết quả benchmark chính
- Qwen 2.5 14B Q4_K_M (8.4GB): nạp hoàn toàn lên GPU, 21 tok/s
- Mixtral 8x7B Q5_K_M (30.9GB): chế độ Expert-streaming, 2.2 tok/s, tỷ lệ cache hit 99.5%
- Llama 3.3 70B Q4_K_M (39.6GB): chế độ Dense FFN-streaming, 0.3 tok/s, pool 24 slot, prefetch 7 tầng
- Các mô hình vừa với bộ nhớ có overhead bằng 0, còn các mô hình vượt ngưỡng thì nhờ Hypura vẫn duy trì được khả năng chạy
Cài đặt và chạy
- Cần Rust 1.75+ và CMake
- Quy trình cài đặt
git clone --recurse-submodules https://github.com/hypura/hypura.git
cd hypura
cargo build --release
- Ví dụ chạy
hypura profile
hypura run ./model.gguf --prompt "Hello, world"
hypura run ./model.gguf --interactive
hypura bench ./model.gguf
hypura inspect ./model.gguf
- Với các mô hình chưa được kiểm chứng, khuyến nghị thử bằng
--max-tokens 10
Máy chủ tương thích Ollama
- Hypura cung cấp HTTP API tương thích Ollama và hoàn toàn tương thích với các công cụ dựa trên Ollama như OpenClaw
hypura serve ./model.gguf
Endpoint: http://127.0.0.1:8080
API: /api/generate, /api/chat, /api/tags
- Các endpoint chính
| Endpoint |
Chức năng |
GET / |
Kiểm tra trạng thái |
GET /api/tags |
Danh sách mô hình đã nạp |
GET /api/version |
Phiên bản máy chủ |
POST /api/show |
Metadata mô hình |
POST /api/generate |
Tạo văn bản |
POST /api/chat |
Tạo hội thoại |
- Để tích hợp OpenClaw, đặt Ollama base URL thành Hypura trong
~/.openclaw/openclaw.json
- Tùy chọn máy chủ
hypura serve [OPTIONS]
--host mặc định 127.0.0.1
--port mặc định 8080
--context mặc định 4096
Kiến trúc
- Cấu trúc Cargo workspace, gồm hai crate
hypura: binary và thư viện chính
hypura-sys: binding FFI cho llama.cpp (build bằng CMake)
- Các mô-đun chính
| Mô-đun |
Vai trò |
scheduler/placement.rs |
Tối ưu phân bổ tensor giữa GPU/RAM/NVMe |
compute/inference.rs |
Engine suy luận và các hàm nạp/tạo cho máy chủ |
compute/nvme_backend.rs |
Stream NVMe, bộ nhớ đệm neuron, callback đánh giá |
server/routes.rs |
HTTP handler tương thích Ollama |
profiler/ |
Profiling phần cứng |
cli/bench.rs |
Công cụ benchmark |
model/tensor_role.rs |
Phân loại vai trò tensor |
FAQ
-
Không có vấn đề về tuổi thọ SSD
- Hypura chỉ đọc từ SSD, không ghi
- NVMe I/O được thực hiện chỉ đọc bằng
pread() + F_NOCACHE
- SSD chỉ đóng vai trò lưu trữ nguội, còn tính toán được thực hiện trên RAM/GPU
- Việc ghi chỉ ở mức rất nhỏ tính bằng KB như JSON kết quả benchmark, tệp thống kê, v.v.
Hướng dẫn an toàn
- Nếu mô hình vượt quá giới hạn RAM (–4GB dung lượng dự phòng),
bench --baseline sẽ bị chặn
- Với các mô hình chưa được kiểm chứng, hãy thử bằng
--max-tokens 10
- Các mô hình thử nghiệm được lưu trong thư mục
./test-models/
Giấy phép
Thông báo đạo đức
- Mã trong kho lưu trữ không phải do tác giả tự viết hoàn toàn
- Đây là sản phẩm của một thử nghiệm sinh mã theo chỉ dẫn bằng LLM
- Là một dự án nhằm khám phá khả năng ứng dụng của suy luận dựa trên NVMe
1 bình luận
Ý kiến trên Hacker News
Muốn đề xuất với người duy trì dự án. Bảng so sánh hiện tại có các mô hình cũ như Qwen 2.5 14B, Mixtral 8x7B, Llama 3.3 70B
Gần đây có nhiều báo cáo cho thấy các mô hình Qwen 3.5 MoE cho hiệu năng ấn tượng trên phần cứng Apple
Có thể tham khảo bài viết của Simon Willison
Nếu có thể thì cũng nên thêm mô hình Kimi K2.5 (1T tham số) vào bảng
Tweet liên quan: seikixtc, danpacary
Có hiện thông báo lỗi liên quan đến Heroku, nhưng giờ đã hoạt động bình thường trở lại
Tôi vào để đọc bài này, và thấy bạn cũng đã viết bài về litellm rồi. Đọc rất hay
Trong công việc cục bộ, dù tốc độ dưới 1 token/giây thì nếu là tác vụ nền vẫn đủ dùng
Sự khác biệt giữa “xong ngay” và “xong sau một đêm” vẫn là một bước nhảy hiệu năng có ý nghĩa
Trên thực tế, điều quan trọng là mẫu đọc có tuần tự (sequential) đến mức nào
NVMe đạt 5–7GB/s khi đọc tuần tự, nhưng với đọc ngẫu nhiên thì tụt xuống khoảng 500MB/s
Với mô hình 1T, nếu tính theo fp16 thì một lần forward pass phải stream 2TB, nên về lý thuyết sẽ mất hơn 300 giây cho mỗi token
Không phù hợp cho tương tác, nhưng có tiềm năng cho suy luận theo lô (batch inference)
Nhưng với các mô hình MoE nhỏ thì có thể tạo ra nhiều token mỗi giây nên thực sự dùng được
Không phải đọc toàn bộ 2TB mà chỉ truy cập một phần các expert layer
Mỗi layer có kích thước cỡ vài MiB nên hiệu quả truy cập NVMe cũng không quá tệ
Tôi từng thắc mắc “mô hình 1T tham số” xuất hiện từ đâu. Trong repo chỉ thấy các mô hình 70B trở xuống
Các mô hình thực tế hơn là dòng MoE nhỏ nhưng có thể tạo nhiều token mỗi giây
Ý chính của MoE là nhờ kích hoạt thưa nên không phải đọc toàn bộ 2TB
Nhưng mẫu truy cập lại bị ngẫu nhiên hóa, khiến đây trở thành điều kiện tệ nhất cho NVMe
Với các tác vụ mà độ trễ (latency) quan trọng như suy luận agent thì đây là điểm mấu chốt
Tình huống này khiến Intel Optane như đang trằn trọc dưới mồ
Dù vậy trên thực tế nó không nhanh hơn NVMe. Với phần mềm hỗ trợ đọc/ghi song song, gần như không có khác biệt
Dù sao nếu ghép 4 cái bằng RAID 0 thì chắc có thể tận dụng hết băng thông PCIe 16x
Phần cứng Mac tiêu dùng có bộ nhớ hợp nhất và NVMe nhanh, nhưng dung lượng lại hạn chế
Nếu tải mô hình 40GB trên M1 Max 32GB thì swap sẽ tăng vọt và cuối cùng rơi vào trạng thái panic
macOS không có OOM killer kiểu Linux, mà chỉ đơn giản là hết chỗ cho swap
Việc có “càng nhiều bộ nhớ càng tốt” cũng quan trọng, nhưng băng thông (bandwidth) mới là biến số lớn hơn
M4 Pro là 273GB/s, M4 Max là 546GB/s, M4 Ultra là 819GB/s
Sau khi mô hình đã nằm trong bộ nhớ, băng thông sẽ quyết định tốc độ token
Theo Hypura thì M4 Max là điểm cân bằng tốt nhất. Với 64GB có thể chạy thoải mái mô hình 70B (Q4), và tốc độ sinh token gấp đôi so với Pro
Dự án này về cơ bản hoạt động như một dạng bộ nhớ swap thông minh
Điểm thú vị là nó điều tiết để không sử dụng NVMe quá mức
Tuy vậy, nếu thực sự dồn tải nặng lên NVMe thì có thể lo ngại về giảm tuổi thọ
SSD đúng là giảm tuổi thọ cell theo số lần ghi, nhưng việc controller bị hỏng vì tải đọc thì hầu như không xảy ra
Nếu đúng là thế thì hệ thống đang có vấn đề khác
Sẽ hay nếu so sánh dự án này với các thử nghiệm trước đó, một thử nghiệm khác
Bản này là dựa trên mmap nên từng có báo cáo là overhead lớn