GPT-OSS al Day 0

Supporto Day‑0 per GPT‑OSS su H200 adattando ROSE con FP8, sink attention e ottimizzazioni MoE

AutoriPerplexity Engineering

Perplexity si impegna a mettere a disposizione i migliori modelli di IA alle persone curiose che richiedono risposte accurate e affidabili, nonché azioni agentiche. OpenAI ha recentemente annunciato i propri modelli a pesi aperti (gpt-oss-20b e gpt-oss-120b). Come per molti modelli leader, Perplexity è tra le prime organizzazioni a valutare gpt-oss-20b e gpt-oss-120b.

In questo articolo condividiamo le decisioni infrastrutturali del nostro stack di inferenza interno che hanno reso possibile il supporto al Day-0. Ci concentriamo sull'esecuzione di questi modelli su GPU NVIDIA H200, illustrando le modifiche al kernel, le scelte di implementazione e i compromessi tra velocità e costo.

GPT-OSS su Hopper

I modelli a pesi aperti sono distribuiti utilizzando la quantizzazione MXFP4, che li aiuta ad adattarsi alla memoria sull'hardware di classe consumer o a raggiungere il throughput di picco su NVIDIA Blackwell. Tuttavia, per la valutazione iniziale, volevamo eseguirli su cluster H200 Hopper esistenti con modifiche minime al motore di inferenza. Hopper non dispone di tensor core FP4 dedicati, introdotti da Blackwell. Di conseguenza, abbiamo deciso di servire i modelli con precisione FP8 per ridurre al minimo la necessità di kernel personalizzati e sfruttare al meglio l'hardware disponibile.

A livello generale, i LLM transformer sono strutturalmente semplici:

Embedding di input

Una sequenza di strati transformer. Ognuno contiene un blocco di attenzione e un blocco MLP denso o MoE sparso.

Proiezione dei logit di output

Quando si introduce un nuovo modello transformer, siamo principalmente interessati a comprendere in che misura corrispondano ai modelli esistenti per identificare le modifiche necessarie. OpenAI ha gentilmente condiviso una panoramica dei propri modelli in anticipo, permettendoci di ottimizzare di conseguenza la nostra configurazione di inferenza. Abbiamo riscontrato che il modello richiedeva un numero considerevole di piccole modifiche.

Attenzione: GQA con Attention Sinks

Ogni testa di attenzione ha un parametro sink pre-addestrato che viene incluso nel Softmax

Codifica posizionale YaRN, simile a DeepSeek-V3

Le proiezioni QKV presentano bias, simili a Qwen 2

La proiezione di output presenta bias

MLP: Sparse Mixture-of-Expert (MoE)

Funzione di attivazione SwiGLU, diversa dalla maggior parte dei modelli a pesi aperti

Softmax dopo Top-K per i pesi degli esperti

Gli esperti presentano bias

Prevedendo che il numero di parametri si aggiri tra 100B e 200B, abbiamo deciso di:

Estendere FlashInfer per supportare gli attention sink

Riutilizzare l'implementazione MoE già creata per la famiglia di modelli DeepSeek-V3

Scegliere lo scaling a blocchi FP8 128x128 come schema di quantizzazione, estendendo i kernel DeepGEMM per supportare un termine di bias.

Motore di inferenza interno

I nostri sforzi di inferenza sono supportati dal nostro motore di inferenza interno, ROSE. Stiamo sviluppando ROSE affinché sia un framework flessibile che consenta di implementare rapidamente nuovi modelli. Inoltre, una volta che ci impegniamo a servire un modello su scala, fornisce una piattaforma per ottimizzare e incrementare le prestazioni per raggiungere lo stato dell'arte.

ROSE espone un motore LLM, in grado di caricare un modello e generare token decodificati attraverso più decoder, inclusi i decoder speculativi e MTP. I modelli stessi sono composti da un insieme personalizzato di strati, che supportano varie configurazioni per la quantizzazione e il parallelismo. Sotto gli strati, raggruppa sia kernel Triton che CUDA che implementano e fondono in modo efficiente i calcoli eseguiti dai singoli strati.

ROSE è costruito principalmente in Python e si affida a PyTorch per le definizioni dei modelli. Sebbene Python ci consenta di essere flessibili e di adattarci a nuovi modelli, stiamo migrando in Rust la maggior parte dei componenti sensibili alle prestazioni, come il serving e la pianificazione batch.

Per implementare un nuovo modello, definiamo innanzitutto la gerarchia del modello e costruiamo un convertitore di pesi per esso. Dopo che tutti i pesi sono stati contabilizzati, definiamo un forward pass per il caso d'uso più semplice TP=1 e ci assicuriamo che funzioni end-to-end. Infine, implementiamo e testiamo il supporto per varie forme di parallelismo prima di rilasciare un nuovo container e distribuire il modello su un cluster per la valutazione. Successivamente, iteriamo sulle prestazioni, basandoci sul feedback sia delle dashboard che di benchmark più granulari.

ROSE opera su token numerici, con scarsa conoscenza dei formati di Chat al di fuori dei test di integrazione. In parallelo, abbiamo dovuto esaminare l'adeguamento dell'infrastruttura circostante per supportare il tokenizer Harmony e mappare correttamente le richieste alle sequenze di token di input.

Con il modello GPT OSS, abbiamo riscontrato che non erano necessarie modifiche ai nostri decoder, agli harness dei grafi CUDA o all'infrastruttura circostante, consentendoci di concentrare i nostri sforzi sull'ottimizzazione dei kernel alla base del modello.

Kernel per GPT-OSS

Sink Attention

La sink attention introduce un fattore di bias extra prima del softmax, accumulato con il prodotto di Q e K:

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

Mentre un'implementazione ingenua è abbastanza banale, implementazioni di attenzione efficienti, come FlashInfer, parallelizzano il calcolo dell'attenzione sia attraverso teste indipendenti che attraverso la lunghezza della sequenza KV. Inoltre, per la stabilità numerica, Softmax viene calcolato online sottraendo contemporaneamente l'elemento massimo per la stabilità numerica:

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

L'implementazione online tracciava un massimo corrente m inizializzato a -inf e una scala d a 1. Inizializzando il massimo al valore sink della testa corrente, avremmo assicurato che venisse accumulato correttamente nel Softmax. Abbiamo dovuto prestare attenzione per garantire che questo massimo venisse incluso solo nel primo blocco se l'attenzione era divisa tra più blocchi lungo la lunghezza della sequenza.

Abbiamo adattato il template del kernel FlashInfer FA2, utilizzato sia per il prefill che per la decodifica, per includere i parametri sink.

MoE

La differenza principale tra lo strato MoE di diversi modelli è solitamente lo schema di routing. Prevedendo una variabilità sostanziale, ROSE implementa questo kernel in Triton, permettendoci di adattarlo facilmente a nuovi modelli. Nel caso di GPT-OSS, abbiamo dovuto regolare il punteggio dei pesi per eseguire il softmax solo tra gli esperti selezionati Top-K, a differenza di alcuni modelli in stile DeepSeek che calcolano il softmax tra tutti gli esperti. Abbiamo riscontrato che è fondamentale per l'accuratezza calcolare i pesi degli esperti con precisione bfloat16.

La sfida con lo strato MoE era dovuta alla nostra decisione di riutilizzare i kernel DeepGEMM esistenti, che non supportavano i termini di bias. Fortunatamente, nel tempo ci siamo integrati profondamente con essi, apportando modifiche per connetterli meglio con i nostri kernel di dispatch all-to-all personalizzati. Abbiamo aggiunto il supporto per il bias a DeepGEMM inizializzando i registri dell'accumulatore WGMMA ai valori di bias caricati dalla memoria. Si tratta di un'operazione singola durante l'elaborazione di un blocco MN, quindi il costo è probabilmente trascurabile e la cache L2 garantisce un accesso efficiente a questi valori.

Poiché questi modelli non beneficiano facilmente del parallelismo dei dati, abbiamo riutilizzato i kernel di dispatch e combine solo per TP. Gli input per il dispatch sono replicati su tutti i rank, quindi il dispatch seleziona i token per gli esperti disponibili localmente. Combine esegue l'accumulo ponderato tramite NVLink.

Ottimizzazioni delle prestazioni

Anche se il nostro obiettivo era implementare i modelli rapidamente, volevamo assicurarci che le prestazioni fossero comunque ragionevoli. Dopo aver garantito la correttezza rispetto a un'implementazione di riferimento fornita da OpenAI, abbiamo profilato la nostra implementazione utilizzando il profiler predefinito di PyTorch, monitorando le allocazioni di blocchi e thread tra i kernel. La funzionalità che abbiamo riutilizzato è stata creata per modelli con una dimensione nascosta maggiore di 7168, sostanzialmente più grande dei 2880 dei modelli GPT-OSS. Abbiamo specializzato i launcher dei kernel per scegliere dimensioni della griglia migliori, aumentando significativamente il throughput.

Tokenizzazione e canali

Il formato Chat di Harmony presenta diversi concetti importanti per strutturare le conversazioni, i contenuti di ragionamento e le chiamate di funzione. In questo formato, ogni messaggio consiste in un'intestazione e un contenuto:

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

L'intestazione contiene i metadati — soprattutto il ruolo (sistema, sviluppatore, utente, assistente, strumento), il canale e un destinatario come to=functions.<function-name> quando si invoca una chiamata di strumento.

I canali (come analisi, commento e risposta finale) rendono gli output del modello più trasparenti e segmentati. Poiché il formato impone questa separazione, il modello può ragionare in modo trasparente (ed essere ispezionato per il debug) senza far trapelare la catena di pensiero in produzione. I tag dei destinatari (intestazioni to=) indicano al runtime esattamente quale attore deve ricevere il payload successivo, che si tratti di una funzione, del modello stesso o dell'utente finale.

Il nostro motore di inferenza ROSE è agnostico rispetto al formato. Riceve un batch di token di input e trasmette indietro i token di output. Nel nostro stack di inferenza, l'attività di formattazione degli input in un prompt tokenizzato e l'analisi dei risultati LLM in messaggi strutturati è gestita dal servizio frontend API JSON dedicato. Abbiamo integrato Harmony aggiungendo un nuovo formattatore/parser collegabile a questo frontend, consentendo al backend di rimanere invariato mentre il frontend gestisce in modo pulito le regole del formato Chat, le chiamate di strumento e lo streaming. Questa separazione delle responsabilità mantiene l'architettura modulare, consentendo l'adozione rapida di nuovi formati e funzionalità di risposta con modifiche minime al backend.

Costo e prestazioni

Data la dimensione relativamente piccola dei modelli GPT-OSS, limitiamo la distribuzione di una replica a un singolo nodo per evitare l'overhead di comunicazione tra nodi. La nostra implementazione supporta combinazioni flessibili di parallelismo degli esperti (EP), parallelismo dei dati (DP) e parallelismo dei tensori (TP). Per determinare la configurazione di distribuzione ottimale, abbiamo eseguito il benchmark di tutte le combinazioni di strategie di sharding su dimensioni batch da 1 a 128. Grazie alla disaggregazione Prefill-Decode, siamo in grado di discutere separatamente il compromesso tra prestazioni e costo per il prefill e la decodifica.

Per le stime dei costi, assumiamo una tariffa di mercato nominale H200 di $3,00/ora (nota: questo non è il nostro prezzo effettivo delle GPU).

Abbiamo scoperto che impostare batch_size=1 e DP=1 produce le migliori prestazioni di prefill. Diverse configurazioni TP offrono quindi vari compromessi tra latenza del primo token e costo. Le tabelle seguenti presentano la latenza di prefill e il costo per milione di token di input per varie configurazioni e lunghezze di input.

GPT-OSS 120B:

Lunghezza input

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

Latenza di prefill di GPT-OSS 120B e costo per milione di token di input in base alla configurazione di parallelismo e alla lunghezza dell'input.

GPT-OSS 20B:

Lunghezza input

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

Latenza di prefill di GPT-OSS 20B e costo per milione di token di input in base alla configurazione di parallelismo e alla lunghezza dell'input.

Per la decodifica, abbiamo scoperto che EP4 DP1 TP4 è la configurazione migliore per la maggior parte dei casi. I quattro grafici seguenti illustrano il compromesso tra velocità di decodifica e costo per milione di token di output sia per i modelli 120B che 20B a lunghezze di sequenza di 8192 e 32768.

Costo di sola decodifica per milione di token di output rispetto alla velocità di decodifica per GPT-OSS 120B con lunghezza della sequenza 8.192, a confronto delle configurazioni EP1, EP2, EP4 ed EP8.
Costo di sola decodifica per milione di token di output rispetto alla velocità di decodifica per GPT-OSS 120B con lunghezza della sequenza 32.768, a confronto delle configurazioni EP1, EP2, EP4 ed EP8.
Costo di sola decodifica per milione di token di output rispetto alla velocità di decodifica per GPT-OSS 20B con lunghezza della sequenza 8.192, a confronto delle configurazioni EP1, EP2, EP4 ed EP8.
Costo di sola decodifica per milione di token di output rispetto alla velocità di decodifica per GPT-OSS 20B con lunghezza della sequenza 32.768, a confronto delle configurazioni EP1, EP2, EP4 ed EP8.

Abbiamo anche considerato l'utilizzo del modello più piccolo 20B come modello di bozza per la decodifica speculativa per il modello più grande 120B. Tuttavia, poiché il numero di parametri attivati è simile (3B contro 5B), i miglioramenti di velocità risultanti sono stati marginali.

Riferimenti

Disaggregazione Prefill e Decode

Accelerare Sonar tramite la speculazione​

Minore latenza e throughput maggiore con la distribuzione multi-nodo di DeepSeek

​Comunicazione Mixture-of-Experts efficiente e portatile

​pplx-kernels

DeepGEMM

FlashInfer: Motore di attenzione efficiente e personalizzabile per il serving di inferenza LLM

Modelli linguistici di streaming efficienti con Attention Sinks

Rapporto tecnico DeepSeek-V3​

​Formato di risposta OpenAI Harmony | Libro di cucina OpenAI​

Citazione

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