Gỡ lỗi suy giảm hiệu suất LLM tự host trên phần cứng cũ
Một nhà phát triển đã chẩn đoán nguyên nhân gây chậm nghiêm trọng khi chạy mô hình 125 tỷ tham số trên hai GPU Tesla P40, truy vết vấn đề đến một thay đổi mã duy nhất trong engine suy luận.
Bài được dịch tự động từ bản gốc tiếng Anh.
Một nhà phát triển chạy mô hình ngôn ngữ lớn trên phần cứng tiêu dùng đời cũ đã gặp phải sự sụt giảm đột ngột về tốc độ suy luận kéo dài suốt một tuần. Bằng cách loại trừ có hệ thống các vấn đề về cấu hình và phần cứng, họ đã truy vết nguyên nhân đến một phiên bản cụ thể của engine mã nguồn mở Strata. Giải pháp đến từ một báo cáo lỗi cộng đồng xác định được một dòng mã chịu trách nhiệm cho sự suy giảm này.
Chuyện gì đã xảy ra
Cấu hình bao gồm một máy chủ EPYC 7302 với 128 GB RAM và hai card đồ họa Tesla P40 mua với giá $403. Các card này dựa trên kiến trúc Pascal năm 2016, thiếu các tính năng hiện đại như Tensor Cores. Bất chấp tuổi đời của silicon, hệ thống vẫn đang chạy Qwen3.8-Flash-Next, một mô hình mixture-of-experts với 125 tỷ tham số. Engine suy luận Strata quản lý điều này bằng cách giữ hầu hết trọng số của các chuyên gia (experts) trong bộ nhớ video, đạt tỷ lệ cache hit là 99,9%.
Trong một tuần vào tháng Mười, hệ thống chỉ giải mã văn bản ở mức 17 đến 18 token mỗi giây. Tốc độ này chậm hơn đáng kể so với 23 token mỗi giây mà một mô hình đặc (dense model) nhỏ hơn đạt được trên cùng phần cứng. Nó cũng chậm hơn so với engine llama.cpp gốc khi chạy cùng trọng số. Nhà phát triển đã dành nhiều ngày để kiểm tra các giả thuyết khác nhau, bao gồm thay đổi chiến lược song song hóa, loại bỏ chi phí container và điều chỉnh kích thước batch. Không có thay đổi nào cải thiện được tốc độ giải mã đơn luồng.
Đột phá xuất hiện khi nhà phát triển tìm thấy một báo cáo lỗi do người dùng khác gửi trên trình theo dõi dự án Strata. Báo cáo lưu ý rằng phiên bản 0.1.40.2 chạy với tốc độ bằng một nửa so với phiên bản 0.1.40.0 trên phần cứng Pascal tương tự. Người bảo trì đã xác định rằng một commit gần đây đã xóa từ khóa __restrict__ khỏi các con trỏ activation và thêm một lệnh prefetch mà các kiến trúc Pascal không thể chồng lấn với quá trình tính toán. Việc quay lại phiên bản 0.1.40.4, vốn bao gồm bản vá, đã tăng gấp đôi tốc độ giải mã lên hơn 35 token mỗi giây.
Chi tiết chính
- Phần cứng bao gồm hai GPU Tesla P40, có khả năng tính toán (compute capability) 6.1 và không hỗ trợ NVLink.
- Sự suy giảm hiệu suất ảnh hưởng đến các phiên bản Strata 0.1.40.2 và 0.1.40.3, làm giảm tốc độ từ ~36 xuống ~17 token mỗi giây.
- Nguyên nhân gốc rễ là một thay đổi mã giới thiệu lệnh prefetch không tương thích với pipeline thực thi của kiến trúc Pascal.
- Thành viên cộng đồng paulhothersall đã gửi issue #1469, cung cấp dữ liệu benchmark giúp cô lập phạm vi phiên bản gây lỗi.
- Người bảo trì Niko1221 đã đẩy bản vá khoảng 75 phút sau khi issue được gửi, khôi phục lại từ khóa
__restrict__. - Nâng cấp lên phiên bản 0.1.44.1 mang lại thêm 8% tăng tốc, nhưng yêu cầu tắt một số mặc định nhất định để đảm bảo đầu ra nhất quán.
Bối cảnh
Các mô hình mixture-of-experts chia nhỏ tham số thành nhiều nhóm, chỉ kích hoạt một tập hợp con nhỏ cho mỗi token được tạo ra. Điều này cho phép các mô hình với hàng trăm tỷ tham số chạy trên phần cứng có bộ nhớ hạn chế, vì chỉ cần tải nhanh các experts đang hoạt động. Engine Strata tối ưu hóa điều này bằng cách ghim một vùng lớn các experts trong RAM của host và cache những experts thường dùng trong bộ nhớ video của GPU. Cách này giảm thiểu việc truyền dữ liệu qua bus PCIe, vốn thường là nút thắt cổ chai trong các thiết lập đa GPU.
Từ khóa __restrict__ trong C++ cho biết với trình biên dịch rằng hai con trỏ không trỏ đến các vùng bộ nhớ chồng lấn. Điều này cho phép trình biên dịch tạo ra mã máy hiệu quả hơn bằng cách tránh việc nạp lại bộ nhớ không cần thiết. Khi gợi ý này bị xóa, hoặc khi các lệnh prefetch không phù hợp được thêm vào, CPU hoặc GPU có thể bị stall (đứng chờ) trong khi đợi dữ liệu, đặc biệt là trên các kiến trúc cũ thiếu khả năng thực thi ngoài thứ tự (out-of-order execution) tiên tiến. Đây là lý do tại sao lỗi chỉ ảnh hưởng đến các card Pascal cũ và không ảnh hưởng đến phần cứng mới hơn.
Tại sao điều này quan trọng
Đối với các đội ngũ vận hành hạ tầng AI tự host, trường hợp này nhấn mạnh tầm quan trọng của việc giám sát chặt chẽ các phiên bản phần mềm. Suy giảm hiệu suất có thể xảy ra mà không có bất kỳ thay đổi nào đối với cấu hình cục bộ hoặc phần cứng. Trong trường hợp này, sự chậm chạp là do một bản cập nhật upstream vô tình làm hỏng tính tương thích với phần cứng cũ nhưng vẫn được sử dụng rộng rãi. Nếu không theo dõi phiên bản cẩn thận, các vấn đề như vậy có thể dẫn đến lãng phí thời gian kỹ thuật để gỡ lỗi các vấn đề cục bộ không tồn tại.
Nó cũng chứng minh giá trị của các dự án mã nguồn mở do cộng đồng thúc đẩy. Lỗi được tìm thấy và sửa chữa nhanh chóng vì người dùng đã chia sẻ dữ liệu benchmark chi tiết. Đối với các tổ chức phụ thuộc vào phần cứng ngách hoặc legacy, việc tham gia vào các trình theo dõi issue của dự án có thể mang lại giải pháp nhanh hơn so với việc tự gỡ lỗi nội bộ. Tính minh bạch của dự án Strata cho phép nhà phát triển nhìn thấy chính xác commit nào gây ra vấn đề, giúp rollback và xác minh nhanh chóng.
Cuối cùng, câu chuyện nhấn mạnh rằng tốc độ tạo token thô không phải là chỉ số duy nhất quan trọng. Ngay cả sau khi tăng gấp đôi tốc độ, các giai đoạn "suy nghĩ" (thinking) dài trong các mô hình phức tạp có thể dẫn đến độ trễ đáng kể trước khi bất kỳ văn bản nào xuất hiện. Các đội ngũ phải cân bằng giữa tối ưu hóa engine và hành vi của mô hình để đáp ứng kỳ vọng trải nghiệm người dùng.
Bạn có thể làm gì
- Kiểm tra trình theo dõi issue của các dependency cốt lõi khi gặp sự sụt giảm hiệu suất không rõ nguyên nhân, ngay cả khi cấu hình của bạn không thay đổi.
- Ghim (pin) các phiên bản cụ thể của engine suy luận trong môi trường production để ngăn ngừa suy giảm không mong muốn từ các bản cập nhật tự động.
- So sánh kết quả benchmark của bạn với các báo cáo công khai từ những người dùng khác có phần cứng tương tự để xác định xem vấn đề có phổ biến hay không.
- Kiểm tra các phiên bản engine mới với các cài đặt mặc định được giữ nguyên để cô lập thay đổi hiệu suất khỏi thay đổi hành vi của mô hình.
- Sử dụng ghi đè theo từng request cho các tham số tinh chỉnh như draft token gates để thử nghiệm cải tiến mà không cần khởi động lại toàn bộ dịch vụ.
- Duy trì kế hoạch rollback, chẳng hạn như giữ lại các image Docker trước đó, để nhanh chóng quay lại trạng thái tốt đã biết nếu một bản cập nhật thất bại.



