Chạy Gemma 4 26B ở 5 token/giây trên Xeon 13 năm tuổi không cần GPU
(neomindlabs.com)- Đã chạy Gemma 4 26B-A4B Q8_0 chỉ bằng CPU trên một máy chủ dùng dual Xeon E5-2690 v2 đời 2013 và DDR3, đạt khoảng 5,2 token/giây khi giải mã và khoảng 16 token/giây khi đánh giá prompt
- Đường chạy tốc độ cao của
ik_llama.cppgiả định có AVX2·FMA3, nhưng CPU Ivy Bridge chỉ hỗ trợ AVX1, nên cần sửa phần biên dịch và fallback phép toán cho bản build không AVX2 - Graph builder tạo
MOE_FUSED_UP_GATEvàFUSED_UP_GATEvô điều kiện, trong khi dispatcher không AVX2 không có đường xử lý, khiến mỗi lượt truyền xuôi có khoảng 240 tensor không được tính toán, dẫn đến đầu ra đa ngôn ngữ lộn xộn - Claude đã tìm ra lỗi bằng cách đo logit và phân tích mã, thay thế phép toán hợp nhất bằng hai lần
ggml_mul_mat_idvàggml_fused_mul_unary; người dùng chạy thử nghiệm và xác định tiêu chí cho kết quả đúng - Máy chủ doanh nghiệp cũ vẫn có thể dùng làm phương án thay thế cục bộ khi API trả phí gặp sự cố hoặc cho các tác vụ batch chậm, nhưng không được dùng
--run-time-repackvì nó tạo layout chỉ dành cho AVX2
Môi trường chạy trên máy chủ lưu trữ 13 năm tuổi
- Thiết bị HP StoreVirtual được tái sử dụng dùng dual Xeon E5-2690 v2 đời 2013 và bộ nhớ DDR3, không có GPU
- Thuộc thế hệ Ivy Bridge nên chỉ hỗ trợ AVX1, không hỗ trợ AVX2 và FMA3
- Ban đầu được chế tạo để lưu trữ đĩa, chi phí mua dưới 300 USD
- Mô hình chạy là Gemma 4 26B-A4B của Google, một mô hình mixture-of-experts (MoE) trọng số mở với 26 tỷ tham số
- Trên mô hình lượng tử hóa Q8_0, tốc độ đo được là khoảng 5,2 token/giây khi giải mã và khoảng 16 token/giây khi đánh giá prompt
Trường hợp Xeon đời 2016 làm điểm xuất phát
- A 10 year old Xeon is all you need được chia sẻ trên Hacker News là một trường hợp chạy Gemma 4 không cần GPU trên một Xeon đơn đời 2016 và 128GB DDR3
- Cấu hình đó dùng ik_llama.cpp và khoảng 25 cờ chạy tinh chỉnh
- Giải mã suy đoán
- Định tuyến MoE có xét đến CPU
- Flash attention cho CPU
- Đóng gói lại trọng số khi chạy
- Áp dụng cùng cách tiếp cận cho máy chủ Ivy Bridge, nhưng chương trình dừng ngay ở giai đoạn khởi động
- Khác với CPU Broadwell đời 2016, E5-2690 v2 không có AVX2 và FMA3
- Các tập lệnh này xuất hiện từ Haswell năm 2014, tức thế hệ v3 của Intel, và các kernel tốc độ cao được viết với giả định có chúng
Chẩn đoán và vá lỗi bằng Claude
- Sau khi nhận thông tin lỗi khởi động, Claude xác định nguyên nhân là khác biệt về tập lệnh CPU
- Tiếp nối một cách tiếp cận chưa hoàn chỉnh từng thử với mô hình miễn phí, Claude sửa để các đường C++ quan trọng về hiệu năng fallback đúng trên CPU trước AVX2
- Công việc không kết thúc bằng một yêu cầu
fix itduy nhất- Đọc mã C++ thiên về hiệu năng do nhà phát triển khác viết
- Phân tích vì sao kernel không hợp lệ trên một vi kiến trúc cụ thể
- Né các đường không được hỗ trợ mà không bỏ các tối ưu hóa sẵn có của fork
- Thay vì tự viết fallback kernel C++, người dùng chạy thử nghiệm, đọc đầu ra, quyết định câu hỏi tiếp theo và đóng vai trò xác định tiêu chí cho kết quả đúng
- Việc chẩn đoán và vá lỗi được thực hiện bởi một instance Claude chạy trên chính máy chủ đó
Đường phép toán bị hỏng trong bản build không AVX2
ik_llama.cppdùng cho suy luận Gemma 4 MoE là một fork củallama.cpp, về mặc định giả định AVX2 là điều kiện tối thiểu- Khi tắt
GGML_USE_IQK_MULMATlúc build, hầu hết đường tốc độ cao bị loại trừ và fallback về phép toán scalar/SSE thông thường- Fallback này hoạt động với phép nhân ma trận Q8_0 thông thường
- Tuy nhiên fallback không được áp dụng cho hai phép toán đồ thị
- Mạng feedforward MoE của Gemma 4 tạo ra các phép toán sau
MOE_FUSED_UP_GATE: phép toán kết hợp phép nhân ma trận gate·up theo từng expert và SwiGLUFUSED_UP_GATE: phiên bản phép toán dense dùng trong các tầng không MoE
- Hai phép toán trong compute dispatcher được bảo vệ bằng điều kiện
GGML_USE_IQK_MULMAT, nhưng graph builder lại tạo phép toán không điều kiện- Dispatcher của bản build không AVX2 không có
casexử lý enum tương ứng - Phép toán rơi vào nhánh mặc định, khiến tensor đích của mọi mạng feedforward expert âm thầm không được tính toán
- Dispatcher của bản build không AVX2 không có
- Gemma 4 26B dùng 8 expert hoạt động cho mỗi token trên 30 tầng, nên mỗi lượt truyền xuôi tiêu thụ khoảng 240 tensor chứa các giá trị còn sót trong buffer bộ nhớ
Manh mối lộ ra từ đầu ra lộn xộn
- Đầu ra lỗi trông có vẻ trôi chảy nhưng là chuỗi đa ngôn ngữ vô nghĩa
- Token ID phân bố đều trên toàn bộ 262.000 mục từ vựng
- Tiếng Thái, tiếng Hàn, sentinel
<unused>, mảnh tiếng Anh, v.v. được tạo với tần suất tương tự nhau
- Ở nhiệt độ 0, đầu ra có tính quyết định; kết quả chạy đơn luồng và đa luồng cũng giống nhau đến từng byte và không xuất hiện NaN
- Dạng lỗi cho thấy các hằng số lớn ở từng tầng đẩy trạng thái ẩn, khiến softmax cuối cùng trở nên phẳng
- Claude đo logit thô trước bước sampling để in ra 5 token đứng đầu, phạm vi, trung bình và số lượng NaN
- Logit trung bình của token dự đoán đầu tiên không nằm gần 0 mà là +16
- Khoảng 80% toàn bộ từ vựng có logit dương
- Vì độ lệch là ổn định chứ không giống hư hỏng ngẫu nhiên, phạm vi được thu hẹp vào việc phần lớn trạng thái ẩn đang dùng bộ nhớ chưa khởi tạo còn lại các giá trị dấu phẩy động dương nhỏ
Bản sửa gồm ba bước
- Bản vá gồm ba commit đặt trên
maincủa fork -
Sửa biên dịch không AVX2
- Nhánh scalar
#elsetrongquantize_row_q8_0_x4vàquantize_row_q8_1_x4_Tcủaiqk_quantize.cppthực tế vẫn tham chiếu các helper AVX2 nhưhsum_i32_8 - Viết lại nhánh đó thành vòng lặp scalar có tính portable
- Thêm điều kiện bảo vệ
#if GGML_USE_IQK_MULMATcho một số lời gọi IQK bị rò sangggml.cvàggml-quants.c - Thêm include bị thiếu để
iqk_cpu_ops.cppcó thể biên dịch độc lập - Nếu không có sửa đổi này, bản fork tự nó không build được trên phần cứng không AVX2
- Nhánh scalar
-
Fallback đồ thị khi chạy
- Thay vì sửa dispatcher, thay đổi graph builder để trong bản build này nó tạo các phép toán đã có đường tính toán
- Trong
ggml_moe_up_gate, xử lý trọng sốup_gate_expsđã kết hợp khiGGML_USE_IQK_MULMATbị tắt - Dạng tensor là
[n_embd, 2*n_ff, n_experts], trong đó nửa đầu là gate, nửa sau là up - Tách bằng hai lát
ggml_view_3d - Chạy
ggml_mul_mat_idtrên từng lát - Kết hợp hai kết quả bằng
ggml_fused_mul_unary(gate, up, SILU) - Nếu trọng số gate và up đã được tách sẵn, dùng hai lần
ggml_mul_mat_idvà phép nhân hợp nhất·phép toán đơn ngôi mà không cần lát cắt - Áp dụng fallback tương tự cho
ggml_fused_up_gatedùng trong các tầng không MoE mul_mat_iddùng triển khai ggml mặc định, cònfused_mul_unaryxử lý SILU và phép nhân trong một lần, nên mọi phép toán cấu thành đều đã có triển khai không IQK- Toàn bộ thay đổi nằm sau
#if !GGML_USE_IQK_MULMAT, nên kết quả của bản build AVX2 vẫn giống bit-for-bit như trước
-
Dọn dẹp stub CI
- Stub
#elsetrong mã nguồn IQK khác vớiiqk_mul_mat.h, khiếnci/run.shcũng không build được trên phần cứng không AVX2 - Thiếu include
<cstdint> - Một số stub có chữ ký khác nhau, như có tham số đầu không cần thiết hoặc thiếu tham số
sinks - Một số hàm không có stub, gây tham chiếu chưa được định nghĩa ở bước liên kết
- Sau khi căn stub khớp với header, test suite cũng có thể chạy trong môi trường không AVX2
- Stub
Chi phí hiệu năng của fallback và lỗi repack
- Fallback phát sinh chi phí bổ sung vì chạy hai lần
mul_mat_idthay cho một kernel hợp nhất - CPU này vốn đã bị giới hạn bởi băng thông bộ nhớ, còn kernel hợp nhất ban đầu cũng chỉ dành cho AVX2, nên trong môi trường này không có đường chạy hiện hữu nào bị từ bỏ
- Hiệu năng cuối cùng trên MoE 26B-A4B là khoảng 5,2 token/giây khi giải mã và khoảng 16 token/giây khi đánh giá prompt
--run-time-repacksắp xếp lại trọng số lượng tử hóa thành định dạng xen kẽ chỉ dành cho AVX2,Q8_0_R8, khi khởi động- Đây là một bug riêng làm hỏng lại đầu ra trong môi trường AVX1
- Bản vá hiện tại không sửa lỗi này và loại bỏ cờ đó khỏi script chạy
Quá trình thu hẹp nguyên nhân
- Sự không khớp về tập lệnh dễ xác nhận, nhưng việc dispatcher rơi vào nhánh mặc định mà không báo lỗi thì khó tìm hơn
- Qua rà soát mã, nhiều ứng viên đã bị loại trừ
- Helper RMSNorm trông đúng
- Fallback AVX1 của
ggml_vec_dot_q8_0_q8_0cũng trông đúng - Kết quả đơn luồng giống bit-for-bit giúp loại trừ lỗi threading
- Việc logit trung bình cố định ở +16 và các token đuôi dài có giá trị tương tự nhau cho thấy phần lớn residual stream chưa được khởi tạo
- Sau khi tìm
#if GGML_USE_IQK_MULMATtrong dispatcher, hai đường phép toán bị thiếu được phát hiện trong khoảng 1 phút
Điều kiện tái hiện và phạm vi sử dụng
- Điều kiện tái hiện trên thiết bị trước AVX2 như sau
- Phần cứng: dual Xeon E5-2690 v2, Ivy Bridge, AVX1, DDR3, không GPU
- Build: biên dịch
ik_llama.cpptừ nhánh vá lỗi không cóGGML_USE_IQK_MULMAT - Mô hình: Gemma 4 26B-A4B Q8_0
- Chạy: dùng các cờ CPU thông thường của
ik_llama.cppnhưng loại trừ--run-time-repack
- Có thể xem thay đổi chính xác tại ikawrakow/ik_llama.cpp PR #2138
- Tại thời điểm viết, PR vẫn đang mở và chờ maintainer xem xét, nên cần chạy trực tiếp từ branch
- Bug xảy ra trên cùng thiết bị có thể được báo trong luồng PR
- Duy trì mô hình cục bộ trên máy chủ doanh nghiệp cũ có thể dùng làm phương án thay thế khi API trả phí bị gián đoạn, hoặc xử lý các tác vụ batch chậm không phù hợp với cách tính phí theo token
- Bài viết coi trọng năng lực tự đào sâu vào mã lạ và hệ thống cũ hơn là dùng dịch vụ thuê bao; cách này cũng áp dụng tương tự cho việc bảo trì ứng dụng Rails 15 năm tuổi hoặc cơ sở dữ liệu mà người phụ trách đã rời đi
1 bình luận
Ý kiến trên Hacker News
Dự đoán rằng đến giữa năm 2027, mô hình MoE vượt 200 tỷ tham số sẽ có thể chạy trên phần cứng tiêu dùng phổ thông
Đang chạy Qwen3.6-35B-A3B cục bộ trên Mac 16GB và đạt 7–9 token/giây: https://github.com/deepanwadhwa/samosa-chat
Nghĩa là một mô hình cấp độ GPT-4 đang chạy cục bộ trên MacBook Air 16GB với tốc độ như vậy
Nó đã nằm trong cùng khoảng số tham số hoạt hóa với phần lớn các mô hình trên 200 tỷ tham số, nên nếu Prism muốn thì họ có thể tung ra một mô hình như vậy. Tuy nhiên, mạng nơ-ron hồi quy như HRM không cần nhiều tham số đến thế, nên việc quy mô đó có thực sự cần thiết hay không vẫn còn có thể tranh luận: https://huggingface.co/sapientinc/HRM-Text-1B
Ví dụ, nếu mỗi tầng chỉ có một seed 256-bit rồi đưa vào hàm nhiễu để sinh ra 16K trọng số thực, thì dung lượng lưu trữ trên mỗi trọng số có thể giảm xuống dưới 1 bit
Có vẻ trong tháng này và tháng sau sẽ liên tiếp có các mô hình mới làm thay đổi cuộc chơi, nên khá háo hức. Ornith thực sự đáng thử
Dù có người không thích nghe, tôi nghĩ chi phí token của nhà cung cấp suy luận rẻ hơn tiền điện để chạy cục bộ
Nếu đơn giản hóa và chỉ tính phần sinh đầu ra, thì 5 token/giây là 18.000 token/giờ, và chi phí từ nhà cung cấp chỉ khoảng 0,005 USD. Giả sử máy chủ dùng khoảng 500W khi suy luận và lấy Đức làm chuẩn với giá điện 0,3 USD/kWh, thì tạo ra cùng lượng đó cục bộ sẽ tốn 0,15 USD, tức đắt hơn 30 lần
Nếu lo ngại quyền riêng tư thì chạy cục bộ vẫn là lựa chọn tốt, nhưng cần hiểu rằng nó kém hiệu quả hơn rất nhiều so với nhà cung cấp suy luận. Khi GPU mới tiếp tục nâng hiệu suất suy luận, khoảng cách này sẽ còn nới rộng đáng kể
Ban đầu tôi tính nhầm thành 180.000 token, nhưng thực tế là 18.000 token, nên trừ khi điện gần như miễn phí thì rất khó cạnh tranh. Các nhà cung cấp cũng vẫn đang dùng H200/H100 cho các mô hình nhỏ, nhưng khi chuyển sang GB300 hay GPU Ruby vào năm sau, chi phí suy luận có thể giảm thêm 30 lần, và giá trị chính của mô hình cục bộ có lẽ sẽ là quyền riêng tư
Trong một giờ, nó có thể xử lý 3,6 triệu token đầu vào hoặc sinh 144.000 token, với tiền điện khoảng 0,15 USD. Nếu dùng Sonnet cho cùng khối lượng đó thì đầu vào là 7,2 USD và phần sinh là 1,4 USD, nghĩa là cloud đắt hơn 10 lần ở phần sinh và gần 50 lần ở phần xử lý
Các nhà cung cấp suy luận đang gánh khoản nợ khổng lồ và cạnh tranh giành thị phần, nên giá chắc chắn sẽ tăng
Nếu AI được dân chủ hóa đến mức cộng đồng có thể trực tiếp kiểm soát, thì vấn đề trung tâm dữ liệu cũng được giải quyết, còn mức độ kiểm duyệt và căn chỉnh cũng có thể do cộng đồng quyết định một cách dân chủ. Đây là ý tưởng khá giống một số bài viết của Geohotz
Các mô hình mã nguồn mở sắp đủ tốt và đủ hiệu quả để có thể phục vụ rẻ bằng phần cứng cũ. Mỗi cộng đồng nhỏ chỉ cần một người rành kỹ thuật huy động vài trăm USD chi phí ban đầu, rồi sau đó có thể vận hành gần như miễn phí ngoài điện
https://solar.lowtechmagazine.com/
Nếu không có phương án thay thế là cục bộ, giá của các mô hình cloud sẽ còn đắt hơn nhiều
Thế hệ dual Xeon này khi có tải rất dễ tiêu thụ hơn 300W. Với giá điện trung bình ở Mỹ thì tốn 1,35 USD mỗi ngày, và nếu mùa hè còn phải làm mát không gian thì chi phí sẽ tăng thêm
Bỏ qua thời gian xử lý prompt, chạy 24 giờ cũng chỉ được khoảng 400 nghìn token mỗi ngày, nên chi phí rơi vào khoảng 0,30 USD cho mỗi 1 triệu token đầu ra. Trùng hợp là mức này đúng bằng giá hiện tại của model trên OpenRouter, nhưng tốc độ sinh của OpenRouter thì nhanh hơn 8 lần
Có nhiều lý do để thử nghiệm LLM cục bộ, như giữ dữ liệu không rời khỏi nhà, nhưng để có lợi về tiền bạc thì khá khó. Với tư cách là người đã đầu tư nhiều tiền hơn rất nhiều vào dàn suy luận cục bộ ở nhà, tôi thấy nó vui thì có vui nhưng không phải là cách để tiết kiệm
Đã tổng hợp kết quả chạy nhiều model trên dual Xeon và DDR4 256GB mà không có GPU
https://gist.github.com/hparadiz/f3596d00a62d8ebb2dadcc46ee5822c7
Khá chậm. Tôi đang đạt 8~12 token/giây ngay cả trên CPU 13 năm tuổi, dù còn phụ thuộc vào kích thước ngữ cảnh và các thiết lập khác
https://news.ycombinator.com/item?id=48354801
Tôi là tác giả bài gốc. Có vẻ bình luận ban đầu đã bị report vì lý do nào đó. Tôi đã mở phần chỉnh sửa trong PR #2138 của dự án upstream: https://github.com/ikawrakow/ik_llama.cpp/pull/2138
Có vẻ thiết bị StoreVirtual này không có cổng nào đủ hữu ích để cài phần mềm. Chỉ thấy cỡ như cổng USB, nên tôi thắc mắc không biết có phải cài qua serial console không
Tôi đang chạy Gemma 4 26B trên Mac Pro 2013 với cùng cấu hình và đạt khoảng 5 token/giây. Card đồ họa kép ở đây không có ích, nhưng với một số tác vụ thì vẫn đủ thực dụng
Nó sẽ tới vào thứ Sáu nên tôi rất háo hức tự thử
https://echalupa.com/blog/mac-pro-6-1-llama-cpp-firepro-d300-vulkan-ubuntu
https://matthewgribben.com/blog/mac-pro-6-1-llama-cpp-firepro-d700-vulkan-ubuntu
Tôi đã tận mắt thấy dàn máy trong tầng hầm, thật sự rất ấn tượng. Lần tới mong bạn cũng giới thiệu cả máy in 3D
Một video hơi liên quan: chạy LLM trên Pentium 4 và đặt biệt danh là NetburstGPT. Tất nhiên là rất chậm
https://www.youtube.com/watch?v=ILV-eu90te8