KVSplit - chạy ngữ cảnh dài hơn 2-3 lần trên Apple Silicon
(github.com/dipampaul17)- KVSplit là một dự án mã nguồn mở giúp chạy LLM cỡ lớn và cửa sổ ngữ cảnh dài trên Apple Silicon
- Thông qua phân bổ độ chính xác tách biệt cho key và value, dự án đạt giảm bộ nhớ tối đa 72% với mức suy giảm chất lượng dưới 1%
- Được tối ưu cho chip M1/M2/M3 và framework Metal
- Cải thiện tốc độ chạy và tiết kiệm bộ nhớ đã được chứng minh bằng benchmark đo đạc thực tế và công cụ trực quan hóa
- Cung cấp cài đặt dễ dàng, so sánh bằng một lệnh và nhiều công cụ benchmark và phân tích
Giới thiệu: Vì sao KVSplit quan trọng
KVSplit là một công cụ mã nguồn mở cho phép chạy LLM dung lượng lớn và cửa sổ ngữ cảnh dài hơn nhiều trên môi trường Apple Silicon (M1/M2/M3) bằng cách áp dụng lượng tử hóa với độ chính xác khác nhau cho key và value bên trong KV cache. Dự án vượt qua hạn chế của các dự án trước đây vốn lượng tử hóa key và value theo cùng một cách, đồng thời giảm mạnh mức sử dụng bộ nhớ nhưng vẫn giữ mức suy giảm chất lượng gần như khó nhận thấy. Benchmark thực tế, tốc độ và các chỉ số chất lượng đều được công khai, nên có độ tin cậy cao, đồng thời hỗ trợ Metal và các công cụ so sánh, trực quan hóa trực quan giúp nâng cao hiệu suất phát triển.
Những ưu điểm chính so với các dự án cùng loại gồm:
- Tách độ chính xác key-value để quản lý bộ nhớ hiệu quả hơn
- Chuyên biệt cho Apple Silicon và hỗ trợ tối ưu hóa đầy đủ cho framework Metal
- Tích hợp benchmark, perplexity, đo lường/trực quan hóa bộ nhớ, tốc độ và chất lượng
- Cài đặt bằng một lệnh, tương thích mô hình, tích hợp llama.cpp
- Trực quan hóa tiết kiệm bộ nhớ theo thời gian thực và nhiều công cụ kiểm thử so sánh
Tính năng chính và nội dung cốt lõi
Tổng quan
- Với KVSplit, có thể chạy LLM lớn hơn nhiều và độ dài ngữ cảnh dài hơn trên Apple Silicon so với trước đây
- Gán độ chính xác lượng tử hóa khác nhau cho từng key và value để vừa tiết kiệm bộ nhớ vừa cải thiện tốc độ
- Xác nhận được tiết kiệm bộ nhớ tối đa 72% và cải thiện tốc độ (5-15%↑), với mức suy giảm chất lượng dưới 1%
- Hỗ trợ Metal đầy đủ, đạt hiệu quả tăng tốc tối ưu trên Apple Silicon
Kết quả benchmark chính
- Với cấu hình K8V4 (key 8-bit, value 4-bit)
- Tiết kiệm 59% bộ nhớ và suy giảm chất lượng 0,86% (theo perplexity)
- Nhanh hơn 5,7% so với FP16
- Với cấu hình K4V4 (cả key/value đều 4-bit)
- Tiết kiệm bộ nhớ tối đa 72%
- Chất lượng giảm khoảng 6%. Phù hợp cho các trường hợp ít nhạy cảm với chất lượng
So sánh hiệu quả tiết kiệm bộ nhớ
- Theo mốc FP16, 176MB (8K token)
- K8V8 (key/value 8-bit) : 93.5MB (47%)
- K8V4 (key 8-bit, value 4-bit) : 71.5MB (41%)
- K4V4 (key/value 4-bit) : 49.5MB (28%)
Tính năng chính
- Lượng tử hóa riêng cho key và value của KV cache
- Tối ưu hóa hoàn toàn cho Apple Silicon và Metal
- Script phân tích benchmark/chất lượng (perplexity)/mức dùng bộ nhớ
- Công cụ trực quan hóa và tạo biểu đồ chất lượng xuất bản
- Thiết lập bằng một lệnh và so sánh theo thời gian thực
Cấu trúc thư mục dự án
- llama.cpp: bao gồm bản build tối ưu cho Metal
- models: lưu file mô hình
- scripts: gồm script benchmark/cài đặt/so sánh/trực quan hóa
- results, plots: lưu kết quả benchmark và file trực quan hóa
- README.md
Insight khoa học và kết quả thực nghiệm
Hiện tượng cốt lõi của KV cache
- Vector key có độ nhạy với lượng tử hóa cao hơn nhiều so với vector value → cần cấp độ chính xác cao hơn cho key để duy trì chất lượng
- K8V4 là điểm ngọt: phân bổ key 8-bit/value 4-bit là điểm cân bằng tối ưu giữa chất lượng và bộ nhớ
- Tiết kiệm 59% bộ nhớ, perplexity chỉ xấu đi 0,86%, và tốc độ còn nhanh hơn FP16
- K4V8 dù có cùng tổng số bit với K8V4 nhưng gây ra mức suy giảm chất lượng lớn hơn hơn 7 lần → chứng minh tầm quan trọng của độ chính xác phía key
Hàm ý tổng hợp
- Đạt được cả hiệu quả bộ nhớ lẫn bảo toàn chất lượng mô hình → cho phép vận hành mô hình lớn hơn và ngữ cảnh dài hơn nhiều trên phần cứng tiêu dùng
Ví dụ sử dụng và khuyến nghị cấu hình
Ví dụ chạy với nhiều mức độ chính xác lượng tử hóa khác nhau
- Mặc định (FP16): ./llama.cpp/build/bin/llama-cli -m models/your-model.gguf -p "prompt" -t 8 --flash-attn
- Khuyến nghị K8V4: --kvq 8
- K4V8 (DEMO): --kvq-key 4 --kvq-val 8
- K4V4 (tiết kiệm tối đa): --kvq 4
Ví dụ ngữ cảnh dài
- Ngữ cảnh 32K: FP16 cần khoảng ~1.4GB, nhưng K8V4 có thể chạy với ~400MB
Giải thích cờ dòng lệnh
-t 8: số luồng, khuyến nghị 8 cho M1/M2/M3--flash-attn: tối ưu cho Apple Silicon--kvq N: đặt cả key/value ở N-bit--kvq-key,--kvq-val: hỗ trợ thiết lập riêng-c N: số token ngữ cảnh (càng dài thì hiệu quả của KVSplit càng lớn)-n N: số token sinh ra-f FILE: file tài liệu đầu vào-m MODEL: đường dẫn mô hình
Benchmark nâng cao và trực quan hóa
- Dùng benchmark_kvsplit.py để đo đặc tính theo từng cấu hình, độ dài chuỗi, bộ nhớ/tốc độ/perplexity/khả năng mở rộng
- Dùng visualize_results.py để tạo biểu đồ chất lượng ở mức bài báo
- Kết quả được tự động lưu dưới dạng CSV/JSON và có kèm phần tóm tắt
Tối ưu hóa cho Apple Silicon và trực quan hóa bộ nhớ
- Tận dụng đầy đủ framework Metal
- Đặc biệt hiệu quả với các máy M1/M2/M3 có áp lực bộ nhớ cao
- Có thể trực quan hóa mức tiết kiệm bộ nhớ theo thời gian thực bằng capture_memory.sh
- Do căn chỉnh trang tùy biến, dung lượng tiết kiệm thực tế có thể chênh nhẹ so với giá trị lý thuyết
Tóm tắt tính năng
- Độ chính xác bit độc lập cho key/value và lượng tử hóa tùy biến
- Tối ưu hóa hoàn toàn cho Apple Silicon và Metal
- Cung cấp benchmark tổng hợp về bộ nhớ/tốc độ/chất lượng
- Hỗ trợ trực quan hóa chất lượng mức bài báo và so sánh thời gian thực, cùng khả năng capture bộ nhớ
- Giao diện cài đặt/sử dụng cực kỳ đơn giản
Trích dẫn và nghiên cứu tham khảo
- "More for Keys, Less for Values: Adaptive KV Cache Quantization" (2024)
- "Unifying KV Cache Compression for Large Language Models with LeanKV" (2025)
- Triển khai nền tảng: [llama.cpp], mô hình thử nghiệm: [TinyLlama]
Khuyến nghị cấu hình và kế hoạch tương lai
- K8V4 (key 8-bit/value 4-bit): mức cân bằng tối ưu với suy giảm chất lượng 0,86%, giảm 59% bộ nhớ, tốc độ +5,7%
- K4V4: tiết kiệm bộ nhớ tối đa (72%), chất lượng giảm khoảng 6%. Phù hợp khi ưu tiên bộ nhớ lên hàng đầu
- Đặc biệt mạnh trong chạy ngữ cảnh dài, có thể vận hành ngữ cảnh dài hơn 2-3 lần
Lộ trình sắp tới
- Độ chính xác thích ứng dựa trên tầm quan trọng của token
- Lượng tử hóa riêng theo từng layer
- Tối ưu hóa tùy biến theo từng mô hình (Mistral, Phi-3, v.v.)
- Dự kiến hỗ trợ web demo và di động (iOS/iPadOS)
Giấy phép và hướng dẫn đóng góp
- Giấy phép MIT
- Bất kỳ nhà phát triển/nhà nghiên cứu AI nào cũng có thể đóng góp qua Issue và PR
1 bình luận
Ý kiến trên Hacker News
Bày tỏ sự quan tâm vì thấy thú vị, hỏi trực giác vì sao hiện tượng này xuất hiện và quá trình đi đến phát hiện đó, đề xuất cải thiện tính thân thiện với người dùng như việc bước áp dụng patch trong script cài đặt còn dang dở và nên dùng git submodule, đồng thời gợi ý cần tách
llama.cppkhỏi các phụ thuộc Python để phù hợp với nhiều môi trường Python khác nhaullama.cpp, mã phân tích tham số đã chuyển sangarg.cppnên patch đó vô nghĩa, đồng thời giải thích rằng tùy chọn lượng tử hóa K/V đã được thêm vàollama.cpptừ năm 2023; đặt câu hỏi về ý nghĩa tồn tại của patch, cho rằng có vẻ chỉ đơn giản là thay đổi đối số dòng lệnh, và khuyến cáo mạnh mẽ không nên chạyinstall.shtừ một kho lưu trữ mới chỉ để áp dụng một file patch đơn giản như vậyHỏi liệu patch này có thể áp dụng được trong MLX hay không, vì MLX cho tốc độ tốt hơn và kỳ vọng cách tiếp cận này sẽ giúp người dùng Mac hỗ trợ hội thoại dài với tốc độ thực tế hơn
Hỏi liệu có khác biệt thực chất nào so với các tùy chọn
--cache-type-k,--cache-type-vhay khôngbf16cũng chỉ mới được thêm gần đây; trước kia trên GPU của Apple, với cáchtype_k/vthì thấp nhất cũng chỉ đến 16-bit (f16/bf16), nên dù không rõ nội bộllama.cpp, có thể đây là một cách tiếp cận hơi khácSau khi đọc code thì kết luận patch là không cần thiết, xác nhận qua liên kết PR rằng chức năng này đã được đưa vào
llama.cpptừ năm 2023; cảnh báo cần dè chừng việc hướng dẫn chạyinstall.shtheo kiểu áp dụng patch thay vì chỉ dùng kho fork; chỉ ra cấu trúc kho lưu trữ rối rắm với nhiều file patch, mã trùng lặp và cả việc ghi đè file patch; thực tế chỉ thêm tùy chọn--kvq, trong khi các tùy chọn lượng tử hóa K/V riêng đã tồn tại; nghi ngờ rằng tác giả không thể nào không biết các chức năng sẵn có này; không khuyến nghị chạy script từ những kho lưu trữ cung cấp script phức tạp như vậy; chỉ trích rằng bài đăng HN và số GitHub star cao nhưng nội dung dễ gây hiểu lầm, và cũng lo ngại việc tác giả liên tục né tránh câu hỏi; bổ sung rằng kho lưu trữ và script đều bị trộn lẫn với codebasellama.cppcũ, không khớp với cấu trúc hiện tại nên càng gây rốiHỏi liệu có thể áp dụng lượng tử hóa KV phân biệt (K8V4 v.v.) cho cả các mô hình định dạng
.ggufđã được chuyển đổi sẵn hay không, và có bị giới hạn bởi loại mô hình hoặc cấu hình tokenizer hay không.ggufhiện có mà không cần chuyển đổi đặc biệt; lượng tử hóa chỉ được áp dụng cho KV cache tại thời điểm chạy nên không liên quan đến trọng số mô hình; chỉ cần dùng cờ--kvq-keyvà--kvq-valđể chỉ định định dạng lưu trữ trong bộ nhớ; tác giả đã thử thành công trên nhiều mô hình như LLama-3, Mistral, Phi-2/Phi-3, TinyLlama, Qwen; tuy nhiên hiện chỉ dành cho backend Metal củallama.cpp, và vì Flash Attention hiện bỏ qua định dạng KV cache tùy chỉnh nên cần tùy chọn-fa 0; ngoài ra, nếu là kiến trúc transformer dùng attention thì đều có thể áp dụngHỏi liệu patch này có nhanh hơn hoặc tốt hơn trên các máy Apple Silicon RAM lớn như 64GB, 128GB hay không; đề cập tin đồn rằng mở rộng context window trên Apple Silicon thực tế khá chậm, và băn khoăn liệu nó có ý nghĩa thực chất trên máy bộ nhớ lớn hay không
Bày tỏ sự quan tâm và muốn có lời giải thích ở góc nhìn cao hơn một chút: có thể dùng nó để mở rộng mô hình 2048 token lên 4~6k hay không, hoặc dùng mô hình context 128k thành cửa sổ 256k+ hay không, và hỏi các trường hợp sử dụng lý tưởng của mô hình cục bộ là gì
Khen đây là một ý tưởng và thử nghiệm rất hay, rồi hỏi thêm liệu có thể áp dụng cho GPU hay không và có thể kết hợp với các kỹ thuật lượng tử hóa khác hay không
llama.cpphiện cũng đã hỗ trợ cấu hình tách riêng bằng--cache-type-k,--cache-type-v; patch hiện tại được tối ưu riêng cho Metal nhưng nguyên lý có thể port nguyên vẹn; cũng có thể dùng song song với các kỹ thuật lượng tử hóa khác, và vì lượng tử hóa KV cache chỉ áp dụng lúc chạy nên không xung đột với lượng tử hóa trọng số; đó là một bước tách biệt trong pipeline chuyển đổi; tuy nhiên với các engine dùng cấu trúc cache khác như vLLM, TensorRT-LLM thì cần triển khai riêng; trên GPU, hiệu quả lớn nhất sẽ đến khi tích hợp trực tiếp vào kiến trúc FlashAttention, nơi tiết kiệm bộ nhớ có thể chuyển hóa thành tăng tốc độNói rằng có những chỗ thực sự không hiểu và cảm thấy có gì đó lạ, khuyên tránh chạy script đó, đồng thời cho biết đã báo cáo
Hỏi hiệu năng thay đổi ra sao; dù đưa được context dài hơn vào bộ nhớ thì tốc độ tính toán cuối cùng có lẽ vẫn như nhau phải không
fp16,q8,q4thì tốc độ mỗi vòng lặp gần như tương đương; dù chưa kiểm tra hoạt động nội bộ, đã kỳ vọng vector sẽ được đóng gói để xử lý SIMD hàng loạt ở 4~8 bit, nhưng ấn tượng thực tế là dường như không có đóng gói như vậy