GPT-OSS ביום אפס

תמיכה ביום אפס (Day-0) עבור GPT-OSS על H200 באמצעות התאמת ROSE עם FP8, sink attention ואופטימיזציות MoE

מחבריםPerplexity Engineering

Perplexity מחויבת להנגשת מיטב מודעות ה-AI לאנשים סקרנים הדורשים תשובות מדויקות ומהימנות ופעולות סוכנותיות. OpenAI הכריזה לאחרונה על מודעות המשקל הפתוח שלה (gpt-oss-20b ו-gpt-oss-120b). כמו במודעות מובילות רבות, Perplexity היא בין הארגונים הראשונים שמעריכים את gpt-oss-20b ו-gpt-oss-120b.

בפוסט זה, אנו משתפים את החלטות התשתית של מחסנית ההסקה הפנימית שלנו שאפשרו תמיכה ביום אפס (Day-0). אנו מתמקדים בהרצת מודעות אלו על גבי מעבדי GPU מסוג NVIDIA H200, תוך פירוט שינויי ה-kernel, בחירות ההטעמה, ושיקולי העלות-מהירות.

GPT-OSS על גבי Hopper

מודעות המשקל הפתוח מסופקות תוך שימוש בכימות MXFP4, המסייע להן להשתלב בזיכרון בחומרה ברמת הצרכן או להשיג תפוקת שיא על גבי NVIDIA Blackwell. עם זאת, לצורך הערכה ראשונית, רצנו להריץ אותם על אשכולות H200 Hopper קיימים עם מינימום שינויים במנוע ההסקה. ל-Hopper אין ליבות טנסור FP4 ייעודיות, שהוצגו על ידי Blackwell. כתוצאה מכך, החלטנו להגיש את המודעות עם דיוק FP8 במקום זאת כדי לצמצם את הצורך ב-kernels מותאמים אישית ולהפיק את המיטב מהחומרה הזמינה.

ברמה גבוהה, מודעות שפה גדולות (LLMs) מבוססות טרנספורמר פשוטות מבחינה מבנית:

הטמעת קלט (Input embedding)

רצף של שכבות טרנספורמר. כל אחת מהן מכילה בלוק תשומת לב (attention), ובלוק MLP צפוף או MoE דליל.

תחזית לוגיט פלט (Output logit projection)

בעת הטמעת מודעת טרנספורמר חדשה, אנו מעוניינים בעיקר ללמוד באיזו מידה הם תואמים למודעות קיימות כדי לזהות את השינויים הנדרשים. OpenAI שיתפה באדיבות סקירה כללית של המודעות שלה מראש, מה שאפשר לנו לכוונן את הגדרת ההסקה שלנו בהתאם. מצאנו שהמודעה אכן דרשה לא מעט שינויים קטנים.

תשומת לב (Attention): GQA עם Attention Sinks

לכל ראש תשומת לב יש פרמטר sink מאומן מראש המובא בחשבון ב-Softmax

קידוד מיקומי YaRN, בדומה ל-DeepSeek-V3

לתחזיות QKV ישטיות (biases), בדומה ל-Qwen 2

לתחזית הפלט יש הטיה (bias)

MLP: תערובת מומחים דלילה (Sparse Mixture-of-Expert - MoE)

פונקציית הפעלה SwiGLU, שונה מרוב מודעות המשקל הפתוח

Softmax לאחר Top-K עבור משקלי מומחים

למומחים יש הטיות (biases)

מתוך ציפייה שמספר הפרמטרים יהיה סביב 100B-200B, החלטנו:

להרחיב את FlashInfer כדי לתמוך ב-attention sinks

לעשות שימוש חוזר ביישום ה-MoE שכבר נבנה עבור משפחת מודעות DeepSeek-V3

בחרו בסכימת הכימות FP8 עם קנה מידה של בלוקים בגודל 128x128, והרחיבו את קרנלי DeepGEMM כדי לתמוך במונח bias.

מנוע הסקה פנימי

מאמצי ההסקה שלנו נתמכים על ידי מנוע ההסקה הפנימי שלנו, ROSE. אנו בונים את ROSE כך שתהיה מסגרת גמישה המאפשרת להטמיע מודעות חדשות במהירות. בנוסף, ברגע שאנו מחויבים להגיש מודעה בקנה מידה רחב, היא מספקת פלטפורמה לאופטימיזציה ולשיפור ביצועים כדי להגיע לחזית הטכנולוגיה.

ROSE חושפת מנוע LLM, שיכול לטעון מודעה ולייצר עבורה אסימונים מפוענחים (tokens) באמצעות מפענחים מרובים, כולל מפענחים ספקולטיביים ו-MTP. המודעות עצמן מורכבות סט מותאם אישית של שכבות, התומכות בידיעות תצורה שונות עבור כימות ומקביליות. מתחת לשכבות, היא משלבת גם Triton וגם CUDA kernels המיישמים ומאחים ביעילות את החשבובים המבוצעים על ידי שכבות בודדות.

ROSE נבנה בעיקר ב-Python ומסתמך על PyTorch להגדרות המודל. בעוד ש-Python מאפשר לנו להיות גמישים ולהתאים עצמנו למודלים חדשים, אנו מעבירים את רוב הרכיבים הרגישים לביצועים, כמו serving ותזמון batch, ל-Rust.

כדי להעלות מודל חדש, אנו מגדירים תחילה את היררכיית המודל ובונים עבורו ממיר משקולות. לאחר שכל המשקולות נלקחו בחשבון, אנו מגדירים מעבר forward עבור מקרֵה השימוש הפשוט ביותר של TP=1 ומוודאים שהוא עובד מקצה לקצה. לבסוף, אנו מממשים ובודקים תמיכה בצורות שונות של מקביליות לפני שאנו משחררים container חדש ומפרסים את המודל על cluster לצורך הערכה. לאחר מכן אנו מבצעים איטרציות על הביצועים, בהסתמך על משוב הן מלוחות מחוונים והן מבנצ'מרקים מפורטים יותר.

ROSE פועלת על אסימונים (tokens) מספריים, עם ידע מועט על פורמטים של צ׳אט מחוץ לבדיקות אינטגרציה. במקביל, נאלצנו לבחון התאמה של התשתית המסביב כדי לתמוך במאפיין הטוקנייזציה של Harmony ולמפות נכון בקשות לרצפי אסימוני קלט.

עם מודעת GPT OSS, מצאנו שלא נדרשו שינויים במפענחים שלנו, ב-CUDA graph harnesses או בתשתית שמסביב, מה שאפשר לנו למקד את מאמצינו בכונון ה-kernels המריצים את המודעה.

Kernels עבור GPT-OSS

Sink Attention

Sink attention מציגה גורם הטיה נוסף לפני Softmax, המצטבר עם המכפלה של Q ו-K:

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

בעוד שיישום נאיבי הוא פשוט למדי, יישומי תשומת לב יעילים, כגון FlashInfer, ממקבלים את החישוב של תשומת לב הן על פני ראשים עצמאיים והן על פני אורך רצף ה-KV. בנוסף, עבור יציבות נומרית, Softmax מחושב באופן מקוון תוך חיסור האלמנט המקסימלי לשם יציבות נומרית:

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

היישום המקוון עקב אחר מקסימום רץ m שאתחל ל--inf וקנה מידה d ל-1. על ידי אתחול המקסימום לערך ה-sink של הראש הנוכחי, היינו מוודאים שהוא יצטבר ב-Softmax בצורה נכונה. דאגנו להבטיח שמקסימום זה ייכלל רק בגוש הראשון אם התשומת לב פוצלה על פני בלוקים מרובים לאורך אורך הרצף.

התאמנו את תבנית ה-kernel של FlashInfer FA2, המשמשת גם למילוי מקדים (prefill) וגם לפענוח (decode), כך שתכלול את פרמטרי ה-sink.

MoE

ההבדל העיקרי בין שכבת ה-MoE של מודלים שונים הוא בדרך כלל סכימת הניתוב. מכיוון שאנו מצפים לשונות משמעותית, ROSE מממשת את הקרנל הזה ב-Triton, מה שמאפשר לנו להתאים אותו בקלות למודלים חדשים. במקרה של GPT-OSS, היינו צריכים להתאים את ניקוד המשקולות כדי לבצע softmax רק על פני המומחים שנבחרו ב-Top-K, בניגוד לכמה מודלים בסגנון DeepSeek שמחשבים softmax על פני כל המומחים. מצאנו שקריטי לדיוק לחשב את משקולות המומחים בדיוק bfloat16.

האתגר בשכבת ה-MoE נבע מההחלטה שלנו לעשות שימוש חוזר ב-kernels של DeepGEMM הקיימים, אשר חסרו תמיכה במונחי הטיה (bias terms). למרבה המזל, לאורך זמן השתלבנו עמם עמוקות, וביצענו שינויים כדי לחבר אותם טוב יותר עם ה-all-to-all dispatch kernels המותאמים אישית שלנו. הוספנו תמיכה בהטיה ל-DeepGEMM על ידי אתחול אגרי המצבר של WGMMA לערכי ההטיה הנטענים מהזיכרון. זוהי פעולה חד-פעמית במהלך עיבוד של בלוק MN, כך שהעלות ככל הנראה זניחה ומטמון L2 מבטיח גישה יעילה ערכים אלו.

מכיוון שמודעות אלו אינן נהנות מיד מהקבילות נתונים (Data Parallelism), עשינו שימוש חוזר ב-TP-only dispatch ו-combine kernels. הקלט ל-dispatch משוכפל בכל הדרגות (ranks), כך ש-dispatch בוחר את האסימונים עבור המומחים הזמינים מקומית. Combine מבצע את הצבירה המשוקללת על פני NVLink.

כונוני ביצועים (Performance Tweaks)

אף על פי שמטרתנו הייתה להטמיע את המודעות במהירות, רצינו לוודא שהביצועים עדיין סבירים. לאחר וידוא תקינות מול יישום ייחוס שסופק על ידי OpenAI, הפעלנו פרופיילינג על היישום שלנו באמצעות פרופיילר PyTorch ברירת המחדל, תוך שימת לב להקצאות בלוקים ושרשורים (threads) על פני ה-kernels. הפונקציונליות שעשינו בה שימוש חוזר נבנתה עבור מודעות בעלות ממד מוסתר גדול יותר של 7168, גדול משמעותית מ-2880 של מודעות GPT-OSS. התמחנו במשגרי kernel כדי לבחור ממדי רשת טובים יותר, מה שהאיץ משמעותית את התפוקה.

טוקניזציה וערוצים

פורמט הצ׳אט של Harmony כולל כמה מושגים חשובים למבנה שיחות, תוכן הסקת מסקנות (reasoning) וקריאות לפונקציות. בפורמט זה, כל הודעה מורכבת מכותרת ותוכן:

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

הכותרת נושאת מטא-דאטה — חשוב מכל התפקיד (system, developer, user, assistant, tool), הערוץ, ומקבל כגון to=functions.<function-name> בעת הפעלת קריאה לפונקציה.

ערוצים (כגון ניתוח, פרשנות ותשובה סופית) הופכים את פטי המודעה לשקופים ומקטעים יותר. מכיוון שהפורמט אוכף הפרדה זו, המודעה יכולה להסיק מסקנות בשקיפות (ולהיבדק לצורך ניפוי באגים) מבלי לדלוף שרשרת מחשבה (chain-of-thought) לייצור. תגי נמען (כותרות to=) אומרים לסביבת הריצה בדיוק איזה שחקן צריך לקבל את מטען העבודה הבא — בין אם מדובר בפונקציה, במודעה עצמה או בקצה משתמש הקצה.

מנוע ההסקה שלנו ROSE הוא אגנוסטי לפורמט. הוא מקבל batch של טוקני קלט ומזרים בחזרה טוקני פלט. ב-stack ההסקה שלנו, המשימה של עיצוב קלטים להנחיה מטוקנת וניתוח תוצאות LLM בחזרה להודעות מובנות מטופלת על ידי שירות ה-frontend הייעודי של JSON API. שילבנו את Harmony על ידי הוספת formatter/parser חדש וניתן לחיבור ל-frontend הזה, מה שמאפשר ל-backend להישאר ללא שינוי בעוד שה-frontend מנהל בצורה נקייה כללי פורמט צ'אט, קריאות לכלים והזרמה. הפרדת תחומי האחריות הזו שומרת על ארכיטקטורה מודולרית, ומאפשרת אימוץ מהיר של פורמטים חדשים ותכונות תגובה עם שינויים מינימליים ב-backend.

עלות וביצועים (Cost and Performance)

בהינתן הגודל הקטן יחסית של מודעות GPT-OSS, אנו מגבילים את הפריסה של עותק (replica) לצומת יחיד כדי להימנע מעלויות תקשורת בין צמתים. היישום שלנו תומך בשילובים גמישים של מקביליות מומחים (EP), מקביליות נתונים (DP) ומקביליות טנסור (TP). כדי לקבוע את הגדרת הפריסה האופטימלית, ביצענו השוואת ביצועים לכל השילובים של אסטרטגיות שארדינג על פני גדלי אצווה מ-1 עד 128. הודות ל-הפרדת מילוי מקדים ופענוח (Prefill-Decode Disaggregation), אנו יכולים לדון בפשרה שבין ביצועים לעלות בנפרד עבור מילוי מקדים ופענוח.

עבור הערכות עלות, אנו מניחים שיעור שוק נומינלי של H200 העומד על 3.00 דולר לשעה (הערה: זהו אינו מחיר ה-GPU האמיתי שלנו).

גילינו שהגדרת batch_size=1 ו-DP=1 מניבה את ביצועי המילוי המקדים הטובים ביותר. תצורות TP שונות מספקות לאחר מכן פשרות משתנות בין השהיית אסימון ראשון (first-token latency) לבין עלות. הטבלאות שלהלן מציגות את השהיית המילוי המקדים והעלות למיליון אסימוני קלט עבור תצורות ואורכי קלט שונים.

GPT-OSS 120B:

אורך קלט (Input Length)

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

השיהוי של שלב ה-prefill והעלות למיליון אסימוני קלט ב-GPT-OSS 120B לפי תצורת המקביליות ואורך הקלט.

GPT-OSS 20B:

אורך קלט (Input Length)

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

השיהוי של שלב ה-prefill והעלות למיליון אסימוני קלט ב-GPT-OSS 20B לפי תצורת המקביליות ואורך הקלט.

עבור פענוח (decode), גילינו ש-EP4 DP1 TP4 היא התצורה הטובה ביותר ברוב המקרים. ארבעת הגרפים שלהלן ממחישים את הפשרה שבין מהירות פענוח לבין עלות למיליון אסימוני פלט עבור מודעות ה-120B וה-20B באורכי רצף של 8192 ו-32768.

עלות שלב ה-decode בלבד למיליון אסימוני פלט לעומת מהירות הפענוח עבור GPT-OSS 120B באורך רצף 8,192, בהשוואה בין תצורות EP1, EP2, EP4 ו-EP8.
עלות שלב ה-decode בלבד למיליון אסימוני פלט לעומת מהירות הפענוח עבור GPT-OSS 120B באורך רצף 32,768, בהשוואה בין תצורות EP1, EP2, EP4 ו-EP8.
עלות שלב ה-decode בלבד למיליון אסימוני פלט לעומת מהירות הפענוח עבור GPT-OSS 20B באורך רצף 8,192, בהשוואה בין תצורות EP1, EP2, EP4 ו-EP8.
עלות שלב ה-decode בלבד למיליון אסימוני פלט לעומת מהירות הפענוח עבור GPT-OSS 20B באורך רצף 32,768, בהשוואה בין תצורות EP1, EP2, EP4 ו-EP8.

שקלנו גם להשתמש במודעת ה-20B הקטנה יותר כמודעת טיוטה לפענוח ספקולטיבי (speculative decoding) עבור מודעת ה-120B הגדולה יותר. עם זאת, מכיוון שמספר הפרמטרים המופעלים דומה (3B לעומת 5B), שיפורי המהירות שהתקבלו היו שוליים.

מקורות והפניות (References)

מילוי מקדים ופענוח מפורקים (Disaggregated Prefill and Decode)

האצת Sonar באמצעות ספקולציה​

השהייה נמוכה ותפוקה גבוהה עם פריסת DeepSeek מרובת צמתים

​תקשורת מומחים יעילה וניידת ב-Mixture-of-Experts

​pplx-kernels

DeepGEMM

FlashInfer: מנוע תשומת לב יעיל וניתן להתאמה אישית להגשת הסקות LLM

מודעות שפה מוזרמות ביעילות עם Attention Sinks

דוח טכני של DeepSeek-V3​

​פורמט תגובה OpenAI Harmony | ספר בישול של OpenAI​

ציטוט

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}
}