NVIDIA Technical Blog: Agentic AI / Generative AI
85

Thủ thuật

NVIDIA ra mắt AIPerf: Công cụ đo lường hiệu năng suy luận LLM quy mô lớn trên vLLM

(giờ Việt Nam)

Tóm tắt AI

NVIDIA giới thiệu AIPerf, phiên bản nâng cấp của GenAI-Perf với kiến trúc đa tiến trình giúp loại bỏ nút thắt cổ chai khi đo lường hiệu năng. Công cụ hỗ trợ đa dạng mô hình truy vấn và các kịch bản tải thực tế, tối ưu cho việc kiểm thử hệ thống LLM quy mô lớn.

Bản dịch AI

Benchmarking LLM Inference at Scale with AIPerf

Bạn đang triển khai một mô hình trên hệ thống. Nó khởi động, các câu lệnh (prompt) bắt đầu nhận được phản hồi. Bây giờ là câu hỏi hóc búa: Liệu tốc độ này có nhanh không?

Bản năng có thể khiến bạn gửi các lệnh curl, tự viết một script asyncio, hoặc vội vàng tạo ra một trình tạo tải (load generator) dùng một lần. Tất cả những cách này đều có chung một vấn đề: giới hạn hiệu năng của tiến trình đơn, GIL của Python làm hạn chế khả năng xử lý đồng thời, hoặc các con số được đo đạc dựa trên một tham chiếu do chính bạn xây dựng. Dù thế nào đi nữa, bạn cũng sẽ nhận được những kết quả không thể hoàn toàn tin tưởng, gắn liền với các công cụ mà bạn sẽ phải viết lại ngay khi yêu cầu thay đổi.

Điều bạn cần là một trình khách tải (load client) có khả năng làm bão hòa một máy chủ thực tế mà không trở thành nút thắt cổ chai, tạo ra kết quả mà bạn có thể hành động dựa trên đó, và chỉ mất năm phút để cấu hình thay vì năm giờ. Đó chính là NVIDIA AIPerf.

Những điểm khác biệt của AIPerf

AIPerf là phiên bản kế nhiệm chính thức của GenAI-Perf và được viết lại hoàn toàn từ đầu. Các lựa chọn thiết kế phản ánh những bài học xương máu từ việc chạy các benchmark LLM ở quy mô lớn:

Benchmark đầu tay của bạn: ISL/OSL tổng hợp trên vLLM

Trong hướng dẫn này, chúng ta sẽ sử dụng Qwen3-0.6B được phục vụ thông qua vLLM. Việc chọn mô hình này là có chủ đích; nó đủ nhỏ để chạy trên một GPU đơn lẻ và đủ nhanh để lặp lại mà không cần chờ đợi. Mục đích không phải là benchmark cụ thể Qwen3-0.6B, mà là thiết lập vòng lặp đo lường. Khi đã có vòng lặp đó, việc thay đổi mô hình hoặc endpoint khác chỉ là thay đổi một flag.

Khởi động máy chủ

Kéo (pull) và khởi động vLLM với trình phân tích suy luận (reasoning parser) được kích hoạt:

Cài đặt AIPerf

Chúng ta có thể sử dụng uv để cài đặt một bản sao trung tâm:

Hoặc cho một môi trường ảo (virtual environment):

Một lưu ý về nền tảng: trên aarch64, phụ thuộc crick chỉ được cung cấp dưới dạng mã nguồn và yêu cầu một bộ công cụ C (build-essential trên Debian/Ubuntu, Development Tools trên RHEL). Nếu quá trình cài đặt bị dừng ở gói đó, thì đây chính là lý do.

Chạy benchmark

Với máy chủ đã sẵn sàng và AIPerf đã được cài đặt, giờ đây chúng ta có thể chạy cấu hình (profile) đầu tiên:

Một vài flag ở đây đang thực hiện nhiều công việc hơn vẻ ngoài của chúng:

--synthetic-input-tokens-stddev 0 và --output-tokens-stddev 0 cố định khối lượng công việc ở mức chính xác 128 token đầu vào và 128 token đầu ra mỗi yêu cầu. Điều này tái tạo một benchmark tĩnh thường được sử dụng để giữ cho độ dài yêu cầu và đầu ra không đổi.

--extra-inputs min_tokens:128 và --extra-inputs ignore_eos:true yêu cầu mô hình thực sự xuất ra 128 token thay vì dừng sớm. Nếu không có các tham số này, số lượng token đầu ra chỉ mang tính gợi ý. Mô hình sẽ dừng bất cứ khi nào nó kết thúc tự nhiên, điều này có thể thấp hơn nhiều so với mục tiêu OSL của bạn. Các con số về thông lượng (throughput) cuối cùng sẽ thấp hơn mức đáng lẽ phải có và không thể tái lập qua các lần chạy.

--streaming là bắt buộc nếu bạn muốn đo TTFT và ITL. Nếu không có streaming, máy chủ sẽ gom nhóm (batch) toàn bộ phản hồi trước khi gửi đi, và sẽ không có các sự kiện token đầu tiên hoặc token giải mã để đo lường.

Những gì bạn sẽ thấy

Chúng ta sẽ tìm hiểu cách đọc các con số này trong phần tiếp theo. Hiện tại, hãy chú ý đến hình dạng của kết quả đầu ra trong Hình 2 bên dưới: độ trễ được phân tách theo phân vị (percentile), thông lượng tính bằng token mỗi giây, và các thống kê ở cấp độ yêu cầu, tất cả ở cùng một nơi. Đó là đường cơ sở (baseline) mà bạn sẽ dùng để so sánh với mọi thứ khác.

A screenshot of the statistics summary displayed in the terminal at the end of an AIPerf benchmark run. The screenshot shows from top to bottom three tables: effective metrics, active metrics, and sum

Đọc các con số: Những gì AIPerf hiển thị

Sau khi một lần chạy hoàn tất, AIPerf in một bảng số liệu ra bảng điều khiển và ghi kết quả đầy đủ vào tệp CSV và JSON. Đây là những gì bạn đang xem.

Bốn chỉ số cốt lõi:

Để biết định nghĩa đầy đủ của các chỉ số này và mọi chỉ số khác mà AIPerf báo cáo, hãy xem Tài liệu tham khảo về Chỉ số (Metrics Reference).

Có cái nhìn toàn cảnh. Mỗi chỉ số trên đều được báo cáo theo phân vị (p25, p50, p75, p90, p95, p99) cùng với giá trị tối thiểu, tối đa, trung bình và độ lệch chuẩn. Những phân tích này rất quan trọng vì chúng có thể làm nổi bật các phân phối đuôi dài (long tail distributions); một máy chủ có TTFT trung bình ổn định nhưng lại có giá trị p99 ngoại lai trông có vẻ ổn khi nhìn tổng thể nhưng lại thất bại trong môi trường sản xuất.

Ngoài bốn chỉ số cốt lõi. Với DCGM hoặc pynvml được kích hoạt, AIPerf cũng thu thập mức tiêu thụ điện năng, mức sử dụng GPU và mức tiêu thụ bộ nhớ vào cùng một kết quả chạy. Việc tương quan giữa một cú sốc độ trễ với một sự kiện áp lực bộ nhớ không cần một phiên profiling riêng biệt, dữ liệu đo từ xa đã có sẵn ở đó.

Đi xa hơn: Cấu hình mô hình lưu lượng

Bây giờ khi đã làm quen với benchmark tĩnh, chúng ta có thể bắt đầu khám phá thứ gì đó năng động hơn. Phần trên đã cung cấp một mô hình lưu lượng cực kỳ cố định, nhưng lưu lượng suy luận thực tế không tuân theo một mô hình tĩnh. Để benchmark với một kịch bản ít cứng nhắc hơn, chúng ta có thể sử dụng một số núm điều chỉnh khối lượng công việc tổng hợp của AIPerf để tạo ra sự biến thiên cho các yêu cầu.

Một vài thứ đã thay đổi so với benchmark tĩnh ở trên.

--arrival-pattern poisson với --request-rate 10 nghĩa là các yêu cầu đến với tốc độ trung bình 10 yêu cầu mỗi giây, với thời gian giữa các lần đến được rút ra từ phân phối mũ. Máy chủ bây giờ sẽ trải qua các đợt bùng phát và khoảng trống thay vì một luồng người dùng đơn lẻ, đó chính là cách hàng đợi thực sự hoạt động dưới lưu lượng thực tế.

--synthetic-input-tokens-stddev 128 tạo ra sự biến thiên xung quanh mức trung bình 512 token, tạo ra sự kết hợp giữa các câu lệnh ngắn và dài. Máy chủ phải xử lý các độ dài câu lệnh khác nhau trong quá trình prefill thay vì các câu lệnh giống hệt nhau.

--output-tokens-stddev 32 thêm sự biến thiên ở phía đầu ra. Lưu ý rằng min_tokens và ignore_eos đã bị loại bỏ khỏi lệnh này. Trong benchmark tĩnh, các flag đó cố định đầu ra ở mức chính xác 128 token để giữ cho đường cơ sở sạch sẽ; chúng ta đang cố tình gỡ bỏ ràng buộc đó để phân phối đầu ra có thể thay đổi.

--random-seed 42 giúp cho thời gian Poisson và các độ dài tổng hợp có thể tái lập được. Chạy lại lệnh này sẽ tạo ra cùng một chuỗi yêu cầu.

--streaming là bắt buộc. Nếu không có streaming, máy chủ sẽ gom nhóm toàn bộ phản hồi trước khi gửi đi, và không có các sự kiện token đầu tiên hoặc token giải mã để đo lường.

Nhìn vào các chỉ số LLM từ lần chạy này, các phân phối rộng hơn đáng kể so với đường cơ sở tĩnh — điều này là dự kiến khi có nhiều yêu cầu cùng lúc cạnh tranh quyền truy cập GPU và độ dài prefill thay đổi theo từng yêu cầu.

A screenshot that zooms in on the summary table from Figure 2. It shows aggregate metrics such as time to first token, request latency, inter-token latency, and a number of other metrics. Each metric

Nhìn vào các biểu đồ trong Hình 4 bên dưới, bạn có thể thấy rằng dòng lệnh Poisson đã tạo ra một tốc độ yêu cầu tập trung quanh mức 10 yêu cầu/giây, nhưng không hoàn toàn khớp chính xác. Tốc độ đến này mô phỏng sự biến động (jitter) về thời điểm các yêu cầu đến so với chế độ hằng số vốn đảm bảo cố định 10 yêu cầu/giây.

NVIDIALLMvLLMHiệu năngAIPerf
Đọc bài gốc

Bài viết được AI dịch và tổng hợp tự động từ NVIDIA Technical Blog: Agentic AI / Generative AI. Liên kết bài gốc ở phía trên. AIHOT.vn luôn dẫn nguồn đầy đủ — nếu bạn thấy điểm cần chỉnh sửa, hãy gửi ý kiến tại trang phản hồi.