GPT-OSS trên Ngày 0

Hỗ trợ Ngày 0 cho GPT‑OSS trên H200 bằng cách điều chỉnh ROSE với FP8, sink attention và tối ưu hóa MoE

Tác giảPerplexity Engineering

Perplexity cam kết cung cấp các mô hình AI tốt nhất cho những người tò mò, những người đòi hỏi câu trả lời chính xác, đáng tin cậy và các tác vụ mang tính tác nhân. OpenAI gần đây đã công bố các mô hình có trọng số mở của họ (gpt-oss-20b và gpt-oss-120b). Giống như nhiều mô hình hàng đầu khác, Perplexity là một trong những tổ chức đầu tiên đánh giá gpt-oss-20b và gpt-oss-120b.

Trong bài viết này, chúng tôi chia sẻ các quyết định về cơ sở hạ tầng của ngăn xếp suy luận nội bộ giúp cho việc hỗ trợ Ngày 0 (Day-0) trở nên khả thi. Chúng tôi tập trung vào việc phục vụ các mô hình này trên GPU NVIDIA H200, trình bày chi tiết các thay đổi về kernel, lựa chọn triển khai và đánh đổi giữa tốc độ và chi phí.

GPT-OSS trên Hopper

Các mô hình có trọng số mở được xuất xưởng bằng cách sử dụng lượng tử hóa MXFP4, giúp chúng vừa vặn với bộ nhớ trên phần cứng cấp người tiêu dùng hoặc đạt được thông lượng đỉnh trên NVIDIA Blackwell. Tuy nhiên, để đánh giá ban đầu, chúng tôi muốn chạy chúng trên các cụm Hopper H200 hiện có với các thay đổi tối thiểu đối với công cụ suy luận. Hopper không có lõi tensor FP4 chuyên dụng, vốn được giới thiệu bởi Blackwell. Do đó, chúng tôi quyết định phục vụ các mô hình bằng độ chính xác FP8 thay thế để giảm thiểu nhu cầu về kernel tùy chỉnh và tận dụng tối đa phần cứng có sẵn.

Ở mức độ cao, các mô hình ngôn ngữ lớn (LLM) dạng transformer có cấu trúc đơn giản:

Nhúng đầu vào

Một chuỗi các lớp transformer. Mỗi lớp chứa một khối attention và một khối MLP dày đặc hoặc MoE thưa thớt.

Phép chiếu logit đầu ra

Khi đưa vào hoạt động một mô hình transformer mới, chúng tôi chủ yếu quan tâm đến việc tìm hiểu mức độ chúng khớp với các mô hình hiện có để xác định các thay đổi cần thiết. OpenAI đã chia sẻ tổng quan về các mô hình của họ trước thời hạn, cho phép chúng tôi điều chỉnh thiết lập suy luận của mình cho phù hợp. Chúng tôi thấy rằng mô hình thực sự đòi hỏi khá nhiều thay đổi nhỏ.

Attention: GQA với Attention Sinks

Mỗi đầu attention có một tham số sink được huấn luyện trước được đưa vào tính toán Softmax

Mã hóa vị trí YaRN, tương tự như DeepSeek-V3

Phép chiếu QKV có độ lệch (bias), tương tự như Qwen 2

Phép chiếu đầu ra có độ lệch (bias)

MLP: Hỗn hợp Chuyên gia Thưa thớt (Sparse Mixture-of-Expert - MoE)

Hàm kích hoạt SwiGLU, khác với hầu hết các mô hình có trọng số mở

Softmax sau Top-K cho trọng số chuyên gia

Các chuyên gia có độ lệch (bias)

Dự kiến số lượng tham số nằm trong khoảng 100B-200B, chúng tôi quyết định:

Mở rộng FlashInfer để hỗ trợ các attention sink

Tái sử dụng cơ chế triển khai MoE đã được xây dựng cho dòng mô hình DeepSeek-V3

Chọn tỷ lệ khối FP8 128x128 làm sơ đồ lượng tử hóa, mở rộng các kernel DeepGEMM để hỗ trợ thuật ngữ độ lệch (bias term).

Công cụ Suy luận Nội bộ

Các nỗ lực suy luận của chúng tôi được hỗ trợ bởi công cụ suy luận nội bộ của chúng tôi, ROSE. Chúng tôi đang xây dựng ROSE thành một framework linh hoạt cho phép đưa các mô hình mới vào hoạt động một cách nhanh chóng. Ngoài ra, một khi chúng tôi cam kết phục vụ một mô hình ở quy mô lớn, nó sẽ cung cấp một nền tảng để tối ưu hóa và thúc đẩy hiệu suất nhằm đạt đến trạng thái tiên tiến nhất.

ROSE hiển thị một công cụ LLM, có thể tải một mô hình và tạo các token đã giải mã cho nó thông qua nhiều bộ giải mã, bao gồm cả bộ giải mã suy đoán và MTP. Bản thân các mô hình bao gồm một tập hợp các lớp tùy chỉnh, hỗ trợ các cấu hình khác nhau cho việc lượng tử hóa và tính toán song song. Bên dưới các lớp này, nó đi kèm với cả kernel Triton và CUDA giúp thực hiện và hợp nhất các phép tính do các lớp riêng lẻ thực hiện một cách hiệu quả.

ROSE chủ yếu được xây dựng bằng Python và dựa vào PyTorch để định nghĩa mô hình. Mặc dù Python cho phép chúng tôi linh hoạt và thích ứng với các mô hình mới, chúng tôi đang di chuyển hầu hết các thành phần nhạy cảm về hiệu suất, chẳng hạn như phục vụ và lên lịch hàng đợi (batch scheduling), sang Rust.

Để đưa vào hoạt động một mô hình mới, trước tiên chúng tôi xác định hệ thống phân cấp mô hình và xây dựng bộ chuyển đổi trọng số cho nó. Sau khi tất cả trọng số được tính toán, chúng tôi xác định một lượt truyền thuận (forward pass) cho trường hợp sử dụng TP=1 đơn giản nhất và đảm bảo nó hoạt động từ đầu đến cuối. Cuối cùng, chúng tôi triển khai và kiểm tra hỗ trợ cho các hình thức tính toán song song khác nhau trước khi phát hành một container mới và triển khai mô hình trên một cụm để đánh giá. Sau đó, chúng tôi lặp lại việc cải thiện hiệu suất, dựa vào phản hồi từ cả bảng điều khiển (dashboard) và các điểm chuẩn chi tiết hơn.

ROSE hoạt động trên các token số, với ít kiến thức về các định dạng trò chuyện ngoài các bài kiểm tra tích hợp. Song song đó, chúng tôi phải xem xét việc điều chỉnh cơ sở hạ tầng xung quanh để hỗ trợ bộ mã hóa token Harmony và ánh xạ chính xác các yêu cầu đến các chuỗi token đầu vào.

Với mô hình GPT OSS, chúng tôi thấy rằng không cần thay đổi nào đối với các bộ giải mã, bộ khai thác đồ thị CUDA hoặc cơ sở hạ tầng xung quanh của chúng tôi, cho phép chúng tôi tập trung nỗ lực vào việc tinh chỉnh các kernel hỗ trợ mô hình.

Kernel cho GPT-OSS

Sink Attention

Sink attention giới thiệu một hệ số độ lệch bổ sung trước softmax, được tích lũy với tích của Q và K:

plaintext
attn = softmax(q @ k^T * sm_scale + sink) * V

Mặc dù việc triển khai đơn giản là khá tầm thường, nhưng các cách triển khai attention hiệu quả, chẳng hạn như FlashInfer, thực hiện song song việc tính toán attention trên cả các đầu độc lập và trên chiều dài chuỗi KV. Ngoài ra, để đảm bảo độ ổn định số, Softmax được tính toán trực tuyến trong khi đồng thời trừ đi phần tử lớn nhất để đảm bảo độ ổn định số:

plaintext
softmax(x) = e^x / sum(e^x) = e ^ (x - max(x)) / sum(e ^ (x - max(x))

Việc triển khai trực tuyến theo dõi mức tối đa đang chạy m được khởi tạo thành -inf và tỷ lệ d thành 1. Bằng cách khởi tạo mức tối đa thành giá trị sink của đầu hiện tại, chúng ta sẽ đảm bảo rằng nó được tích lũy vào Softmax một cách chính xác. Chúng tôi phải cẩn thận để đảm bảo rằng mức tối đa này sẽ chỉ được bao gồm trong khối đầu tiên nếu attention được chia thành nhiều khối dọc theo chiều dài chuỗi.

Chúng tôi đã điều chỉnh mẫu kernel FlashInfer FA2, được sử dụng cho cả giai đoạn prefill và decode, để bao gồm các tham số sink.

MoE

Sự khác biệt chính giữa lớp MoE của các mô hình khác nhau thường là sơ đồ định tuyến. Dự đoán sự biến đổi đáng kể, ROSE thực hiện kernel này bằng Triton, cho phép chúng tôi dễ dàng thích ứng nó với các mô hình mới. Trong trường hợp của GPT-OSS, chúng tôi phải điều chỉnh việc chấm điểm trọng số để thực hiện softmax chỉ trên các chuyên gia được chọn Top-K, không giống như một số mô hình kiểu DeepSeek tính toán softmax trên tất cả các chuyên gia. Chúng tôi thấy rằng việc tính toán trọng số chuyên gia ở độ chính xác bfloat16 là rất quan trọng đối với độ chính xác.

Thách thức với lớp MoE là do quyết định tái sử dụng các kernel DeepGEMM hiện có của chúng tôi, vốn thiếu hỗ trợ cho các thuật ngữ độ lệch (bias terms). May mắn thay, theo thời gian, chúng tôi đã tích hợp sâu với chúng, thực hiện các thay đổi để kết nối chúng tốt hơn với các kernel điều调度 (dispatch) all-to-all tùy chỉnh của chúng tôi. Chúng tôi đã thêm hỗ trợ độ lệch vào DeepGEMM bằng cách khởi tạo các thanh ghi tích lũy WGMMA thành các giá trị độ lệch được tải từ bộ nhớ. Đây là một thao tác diễn ra một lần trong quá trình xử lý khối MN, do đó chi phí có thể không đáng kể và bộ nhớ đệm L2 đảm bảo quyền truy cập hiệu quả vào các giá trị này.

Vì các mô hình này không dễ dàng hưởng lợi từ Data Parallelism, chúng tôi đã tái sử dụng các kernel điều phối và kết hợp chỉ dành cho TP. Các đầu vào cho việc điều phối được nhân bản trên tất cả các xếp hạng, do đó việc điều phối chọn các token cho các chuyên gia có sẵn cục bộ. Combine thực hiện việc tích lũy có trọng số qua NVLink.

Tinh chỉnh Hiệu suất

Mặc dù mục tiêu của chúng tôi là đưa các mô hình vào hoạt động một cách nhanh chóng, chúng tôi vẫn muốn đảm bảo rằng hiệu suất vẫn hợp lý. Sau khi đảm bảo tính chính xác so với việc triển khai tham khảo do OpenAI cung cấp, chúng tôi đã phân tích cấu hình việc triển khai của mình bằng trình phân tích cú pháp PyTorch mặc định, chú ý đến việc phân bổ khối và chuỗi trên các kernel. Chức năng mà chúng tôi tái sử dụng đã được xây dựng cho các mô hình có kích thước chiều ẩn lớn hơn là 7168, lớn hơn đáng kể so với 2880 của các mô hình GPT-OSS. Chúng tôi đã chuyên biệt hóa các trình khởi chạy kernel để chọn kích thước lưới tốt hơn, giúp tăng đáng kể thông lượng.

Token hóa và các kênh

Định dạng trò chuyện của Harmony có một số khái niệm quan trọng để cấu trúc các cuộc trò chuyện, nội dung suy luận và lệnh gọi hàm. Trong định dạng này, mỗi tin nhắn bao gồm một tiêu đề và nội dung:

plaintext
<|start|>{header}<|message|>{content}<|end|>

Tiêu đề mang siêu dữ liệu — quan trọng nhất là vai trò (hệ thống, nhà phát triển, người dùng, trợ lý, công cụ), kênh và người nhận chẳng hạn như to=functions.<function-name> khi gọi lệnh gọi hàm.

Các kênh (chẳng hạn như phân tích, bình luận và câu trả lời cuối cùng) làm cho đầu ra của mô hình trở nên minh bạch và được phân đoạn hơn. Bởi vì định dạng thực thi việc tách biệt này, mô hình có thể suy luận một cách minh bạch (và được kiểm tra để gỡ lỗi) mà không làm rò rỉ chuỗi suy nghĩ (chain-of-thought) vào môi trường sản xuất. Các thẻ người nhận (tiêu đề to=) cho thời gian chạy biết chính xác tác nhân nào nên nhận tải trọng tiếp theo — cho dù đó là một hàm, chính mô hình hay người dùng cuối.

Công cụ suy luận ROSE của chúng tôi không phụ thuộc vào định dạng. Nó nhận một loạt các token đầu vào và phát trực tuyến trả về các token đầu ra. Trong ngăn xếp suy luận của chúng tôi, tác vụ định dạng đầu vào thành một prompt đã được mã hóa token và phân tích kết quả LLM thành các tin nhắn có cấu trúc được xử lý bởi dịch vụ giao diện API JSON chuyên dụng. Chúng tôi đã tích hợp Harmony bằng cách thêm một trình định dạng/phân tích cú pháp có thể cắm mới vào giao diện này, cho phép phần phụ trợ (backend) giữ nguyên trong khi phần giao diện (frontend) quản lý rõ ràng các quy tắc định dạng trò chuyện, lệnh gọi hàm và phát流 (streaming). Sự tách biệt các mối quan tâm này giúp kiến trúc mang tính mô đun, cho phép áp dụng nhanh chóng các định dạng mới, các tính năng phản hồi với những thay đổi tối thiểu đối với phần phụ trợ.

Chi phí và Hiệu suất

Do kích thước tương đối nhỏ của các mô hình GPT-OSS, chúng tôi giới hạn việc triển khai một bản sao thành một nút duy nhất để tránh chi phí giao tiếp liên nút. Viễn cảnh triển khai của chúng tôi hỗ trợ các kết hợp linh hoạt giữa expert parallelism (EP), data parallelism (DP) và tensor parallelism (TP). Để xác định thiết lập triển khai tối ưu, chúng tôi đã đo điểm chuẩn tất cả các kết hợp của các chiến lược phân đoạn trên các kích thước batch từ 1 đến 128. Nhờ Prefill-Decode Disaggregation, chúng tôi có thể thảo luận riêng về sự đánh đổi giữa hiệu suất và chi phí cho quá trình prefill và decode.

Đối với ước tính chi phí, chúng tôi giả định mức giá thị trường danh nghĩa của H200 là $3.00/giờ (lưu ý: đây không phải là giá GPU thực tế của chúng tôi).

Chúng tôi phát hiện ra rằng việc thiết lập batch_size=1 và DP=1 mang lại hiệu suất prefill tốt nhất. Các cấu hình TP khác nhau sau đó cung cấp các mức đánh đổi khác nhau giữa độ trễ token đầu tiên và chi phí. Các bảng bên dưới trình bày độ trễ prefill và chi phí trên một triệu token đầu vào cho các cấu hình và độ dài đầu vào khác nhau.

GPT-OSS 120B:

Độ dài đầu vào

8192

32768

65536

128000

EP1 DP1 TP1

0.364s, $0.037

2.421s, $0.062

7.375s, $0.094

23.902s, $0.156

EP2 DP1 TP2

0.190s, $0.039

1.245s, $0.063

3.786s, $0.096

12.116s, $0.158

EP4 DP1 TP4

0.165s, $0.067

0.900s, $0.092

2.449s, $0.125

7.165s, $0.187

EP8 DP1 TP8

0.179s, $0.145

0.839s, $0.171

2.003s, $0.204

5.119s, $0.267

Độ trễ prefill của GPT-OSS 120B và chi phí trên mỗi triệu token đầu vào theo cấu hình song song và độ dài đầu vào.

GPT-OSS 20B:

Độ dài đầu vào

8192

32768

65536

128000

EP1 DP1 TP1

0.239s, $0.024

1.610s, $0.041

4.895s, $0.062

16.037s, $0.104

EP2 DP1 TP2

0.127s, $0.026

0.833s, $0.042

2.522s, $0.064

8.143s, $0.106

EP4 DP1 TP4

0.108s, $0.044

0.593s, $0.060

1.616s, $0.082

4.766s, $0.124

EP8 DP1 TP8

0.116s, $0.094

0.547s, $0.111

1.310s, $0.133

3.365s, $0.175

Độ trễ prefill của GPT-OSS 20B và chi phí trên mỗi triệu token đầu vào theo cấu hình song song và độ dài đầu vào.

Đối với quá trình decode, chúng tôi phát hiện ra rằng EP4 DP1 TP4 là cấu hình tốt nhất cho hầu hết các trường hợp. Bốn biểu đồ bên dưới minh họa sự đánh đổi giữa tốc độ decode và chi phí trên một triệu token đầu ra cho cả hai mô hình 120B và 20B ở độ dài chuỗi 8192 và 32768.

Chi phí chỉ decode trên mỗi triệu token đầu ra so với tốc độ giải mã cho GPT-OSS 120B ở độ dài chuỗi 8.192, so sánh các cấu hình EP1, EP2, EP4 và EP8.
Chi phí chỉ decode trên mỗi triệu token đầu ra so với tốc độ giải mã cho GPT-OSS 120B ở độ dài chuỗi 32.768, so sánh các cấu hình EP1, EP2, EP4 và EP8.
Chi phí chỉ decode trên mỗi triệu token đầu ra so với tốc độ giải mã cho GPT-OSS 20B ở độ dài chuỗi 8.192, so sánh các cấu hình EP1, EP2, EP4 và EP8.
Chi phí chỉ decode trên mỗi triệu token đầu ra so với tốc độ giải mã cho GPT-OSS 20B ở độ dài chuỗi 32.768, so sánh các cấu hình EP1, EP2, EP4 và EP8.

Chúng tôi cũng đã xem xét việc sử dụng mô hình 20B nhỏ hơn làm mô hình nháp giải mã suy đoán (speculative decoding) cho mô hình 120B lớn hơn. Tuy nhiên, vì số lượng tham số được kích hoạt tương tự nhau (3B so với 5B), mức tăng tốc đạt được không đáng kể.

Tài liệu tham khảo

Prefill và Decode được phân tách

Tăng tốc Sonar thông qua suy đoán​

Độ trễ thấp hơn và Thông lượng cao hơn với Triển khai DeepSeek đa nút

​Giao tiếp Hỗn hợp Chuyên gia Hiệu quả và Di động

​pplx-kernels

DeepGEMM

FlashInfer: Công cụ Attention Hiệu quả và Có thể tùy chỉnh cho Phục vụ Suy luận LLM

Mô hình Ngôn ngữ Phát trực tuyến Hiệu quả với Attention Sinks

Báo cáo Kỹ thuật DeepSeek-V3​

​Định dạng Phản hồi OpenAI Harmony | Sách nấu ăn OpenAI​

Trích dẫn

BibTeX
@online{perplexity2025GptOssOnDay0,
  author = {{Perplexity} and Nandor Licker and Lequn Chen and Vladimir Zaytsev and Kevin Hu and Lauren Kolm and Jesse Dwyer},
  title = {{GPT-OSS on day 0}},
  date = {2025-08-08},
  url = {https://www.perplexity.ai/hub/blog/gpt-oss-on-day-0}
}