GPT-OSS op Day 0
Day-0-ondersteuning voor GPT-OSS op H200 door ROSE aan te passen met FP8, sink attention en MoE-optimalisaties
Perplexity zet zich in om de beste AI-modellen beschikbaar te stellen aan nieuwsgierige mensen die vragen om nauwkeurige en betrouwbare antwoorden en agent-acties. OpenAI heeft onlangs hun open-weight modellen (gpt-oss-20b en gpt-oss-120b) aangekondigd. Zoals bij vele toonaangevende modellen, behoort Perplexity tot de eerste organisaties die gpt-oss-20b en gpt-oss-120b evalueren.
In dit bericht delen we de infrastructuurkeuzes van onze interne inferentiestack die Day-0-ondersteuning mogelijk hebben gemaakt. We richten ons op het serveren van deze modellen op NVIDIA H200 GPU's, waarbij we de kernelwijzigingen, implementatiekeuzes en de afwegingen tussen snelheid en kosten toelichten.
GPT-OSS op Hopper
De open-weight modellen worden uitgebracht met MXFP4-kwantisering, wat hen helpt in het geheugen op hardware van consumentenkwaliteit te passen of piekdoorvoer te behalen op NVIDIA Blackwell. Voor de initiële evaluatie wilden we ze echter draaien op bestaande H200 Hopper-clusters met minimale wijzigingen aan de inferentie-engine. Hopper heeft geen speciale FP4-tensorcores, die door Blackwell werden geïntroduceerd. Daarom hebben we besloten de modellen in plaats daarvan met FP8-precisie te serveren om de behoefte aan aangepaste kernels te minimaliseren en optimaal gebruik te maken van de beschikbare hardware.
Op hoofdlijnen zijn transformer-LLM's structureel eenvoudig:
Input-embedding
Een sequentie van transformer-lagen. Elke laag bevat een attention-blok en een dense MLP- of sparse MoE-blok.
Output logit-projectie
Bij het in gebruik nemen van een nieuw transformer-model zijn we er primair in geïnteresseerd in hoeverre ze overeenkomen met bestaande modellen om de vereiste wijzigingen te identificeren. OpenAI heeft vriendelijkerwijs vooraf een overzicht van hun modellen gedeeld, waardoor we onze inferentie-opstelling dienovereenkomstig konden aanpassen. We ontdekten dat het model wel degelijk een aantal kleine wijzigingen vereiste.
Attention: GQA met Attention Sinks
Elke attention-head heeft een voorgetrainde sink-parameter die wordt meegerekend in Softmax
YaRN positionele codering, vergelijkbaar met DeepSeek-V3
QKV-projecties hebben biases, vergelijkbaar met Qwen 2
Output-projectie heeft bias
MLP: Sparse Mixture-of-Expert (MoE)
SwiGLU-activatiefunctie, anders dan de meeste open-weight modellen
Softmax na Top-K voor expert-gewichten
Experts hebben biases
Verwachtend dat het aantal parameters rond de 100B-200B ligt, hebben we besloten om:
FlashInfer uit te breiden ter ondersteuning van attention sinks
De MoE-implementatie te hergebruiken die al was gebouwd voor de DeepSeek-V3-familie van modellen
FP8 128x128 blokschaling te kiezen als kwantiseringsschema, en de DeepGEMM-kernels uit te breiden ter ondersteuning van een bias-term.
Interne inferentie-engine
Onze inferentie-inspanningen worden ondersteund door onze interne inferentie-engine, ROSE. We bouwen ROSE uit tot een flexibel raamwerk waarmee nieuwe modellen snel kunnen worden opgezet. Bovendien biedt het, zodra we ons committeren aan het op schaal serveren van een model, een platform om prestaties te optimaliseren en te verbeteren tot op het state-of-the-art niveau.
ROSE biedt een LLM-engine die een model kan laden en gedecodeerde tokens kan genereren via meerdere decoders, inclusief speculatieve en MTP-decoders. De modellen zelf zijn samengesteld uit een aangepaste set lagen, die diverse configuratieparameters ondersteunen voor kwantisering en parallellisatie. Onder de lagen bundelt het zowel Triton- als CUDA-kernels die de berekeningen van individuele lagen efficiënt implementeren en fuseren.
ROSE is primair gebouwd in Python en vertrouwt op PyTorch voor modeldefinities. Hoewel Python ons flexibel maakt en in staat stelt ons aan te passen aan nieuwe modellen, migreren we de meeste prestatiegevoelige componenten, zoals serveren en batch-planning, naar Rust.
Om een nieuw model op te zetten, definiëren we eerst de modelhiërarchie en bouwen we een gewichtsomzetter hiervoor. Nadat alle gewichten zijn verwerkt, definiëren we een forward pass voor de eenvoudigste TP=1 use case en zorgen we dat deze end-to-end werkt. Tot slot implementeren en testen we de ondersteuning voor diverse vormen van parallellisatie voordat we een nieuwe container vrijgeven en het model op een cluster implementeren voor evaluatie. Vervolgens itereren we op prestaties, vertrouwend op feedback van zowel dashboards als fijnmazige benchmarks.
ROSE werkt met numerieke tokens, met weinig kennis van Chat-indelingen buiten integratietests. Tegelijkertijd moesten we kijken naar het aanpassen van de omliggende infrastructuur om de Harmony-tokenizer te ondersteunen en verzoeken correct te mappen naar input-tokensequenties.
Bij het GPT OSS-model merkten we dat er geen wijzigingen nodig waren aan onze decoders, CUDA-graph harnesses of omliggende infrastructuur, waardoor we ons konden concentreren op het finetunen van de kernels die het model ondersteunen.
Kernels voor GPT-OSS
Sink Attention
Sink attention introduceert een extra bias-factor vóór softmax, geaccumuleerd met het product van Q en K:
attn = softmax(q @ k^T * sm_scale + sink) * VHoewel een naïeve implementatie redelijk triviaal is, parallelliseren efficiënte attention-implementaties, zoals FlashInfer, de berekening van attention over zowel onafhankelijke heads als over de KV-sequentielengte. Bovendien wordt voor numerieke stabiliteit Softmax online berekend, terwijl ook het maximale element wordt afgetrokken voor numerieke stabiliteit:
softmax(x) = e^x / sum(e^x) = e ^ (x - max(x)) / sum(e ^ (x - max(x))De online implementatie houdt een lopend maximum m bij, geïnitialiseerd op -inf, en een schaal d op 1. Door het maximum te initialiseren op de sink-waarde van de huidige head, zorgen we ervoor dat deze correct in de Softmax wordt geaccumuleerd. We moesten ervoor zorgen dat dit maximum alleen in het eerste segment werd opgenomen als attention over meerdere blokken langs de sequentielengte werd gesplitst.
We hebben het FlashInfer FA2-kerneltemplate, gebruikt voor zowel prefill als decode, aangepast om de sink-parameters op te nemen.
MoE
Het voornaamste verschil tussen de MoE-laag van verschillende modellen is meestal het routeringsschema. Verwachtend dat er aanzienlijke variabiliteit zou zijn, implementeert ROSE deze kernel in Triton, waardoor we deze gemakkelijk kunnen aanpassen aan nieuwe modellen. In het geval van GPT-OSS moesten we de gewichtsscore aanpassen om softmax alleen uit te voeren over de Top-K geselecteerde experts, in tegenstelling tot sommige DeepSeek-stijl modellen die softmax over alle experts berekenen. We vonden het essentieel voor de nauwkeurigheid om de expert-gewichten te berekenen in bfloat16-precisie.
De uitdaging met de MoE-laag kwam door ons besluit om de bestaande DeepGEMM-kernels te hergebruiken, die geen ondersteuning hadden voor bias-termen. Gelukkig zijn we in de loop van de tijd nauw met hen geïntegreerd, waardoor we wijzigingen hebben aangebracht om ze beter te verbinden met onze aangepaste all-to-all dispatch-kernels. We hebben bias-ondersteuning toegevoegd aan DeepGEMM door de WGMMA-accumulatorregisters te initialiseren met de bias-waarden die uit het geheugen zijn geladen. Dit is een eenmalige actie tijdens de verwerking van een MN-blok, dus de kosten zijn waarschijnlijk verwaarloosbaar en de L2-cache zorgt voor efficiënte toegang tot deze waarden.
Omdat deze modellen niet direct profiteren van Data-parallellisatie, hebben we TP-only dispatch en combine-kernels hergebruikt. De inputs voor dispatch worden gerepliceerd over alle ranks, dus dispatch selecteert de tokens voor de lokaal beschikbare experts. Combine voert de gewogen accumulatie uit via NVLink.
Prestatie-tweaks
Hoewel ons doel was om de modellen snel op te zetten, wilden we er wel voor zorgen dat de prestaties redelijk bleven. Na het garanderen van de correctheid ten opzichte van een referentie-implementatie geleverd door OpenAI, hebben we onze implementatie geprofileerd met de standaard PyTorch-profiler, waarbij we alert waren op blok- en draad-toewijzingen over kernels heen. De functionaliteit die we hergebruikten was gebouwd voor modellen met een grotere verborgen dimensie van 7168, aanzienlijk groter dan de 2880 van de GPT-OSS-modellen. We hebben kernellaunchers gespecialiseerd om betere grid-dimensies te kiezen, wat de doorvoer aanzienlijk heeft verhoogd.
Tokenisatie en kanalen
Harmony’s Chat-indeling heeft verschillende belangrijke concepten voor het structureren van gesprekken, redeneerinhoud en functie-aanroepen. In deze indeling bestaat elk bericht uit een header en inhoud:
<|start|>{header}<|message|>{content}<|end|>De header bevat metadata — het belangrijkste is de rol (systeem, ontwikkelaar, gebruiker, assistent, tool), het kanaal en een ontvanger zoals to=functions.<function-name> bij het aanroepen van een tool.
Kanalen (zoals analyse, commentaar en eindantwoord) maken de output van het model transparanter en gesegmenteerd. Omdat de indeling deze scheiding afdwingt, kan het model transparant redeneren (en geïnspecteerd worden voor foutopsporing) zonder dat chain-of-thought in productie lekt. Ontvanger-tags (to= headers) vertellen de runtime precies welke actor de volgende payload moet ontvangen — of dat nu een functie is, het model zelf of de eindgebruiker.
Onze inferentie-engine ROSE is indeling-agnostisch. Deze ontvangt een batch input-tokens en streamt output-tokens terug. In onze inferentie-stack wordt de taak van het formatteren van inputs naar een getokeniseerde prompt en het parseren van LLM-resultaten terug naar gestructureerde berichten afgehandeld door de toegewezen JSON API-frontend-service. We hebben Harmony geïntegreerd door een nieuwe pluggable formatter/parser aan deze frontend toe te voegen, waardoor de backend ongewijzigd kon blijven terwijl de frontend de Chat-indeling-regels, tool-aanroepen en streaming beheert. Deze scheiding van verantwoordelijkheden houdt de architectuur modulair, wat snelle acceptatie van nieuwe indelingen en responsfuncties mogelijk maakt met minimale backend-wijzigingen.
Kosten en prestaties
Gezien de relatief kleine omvang van de GPT-OSS-modellen, beperken we de implementatie van een replica tot een enkele node om overhead van communicatie tussen nodes te voorkomen. Onze implementatie ondersteunt flexibele combinaties van expert-parallellisatie (EP), data-parallellisatie (DP) en tensor-parallellisatie (TP). Om de optimale implementatie-opstelling te bepalen, hebben we alle combinaties van sharding-strategieën gebenchmarkt over batchgroottes van 1 tot 128. Dankzij Prefill-Decode Disaggregation kunnen we de prestatie-kosten-afweging afzonderlijk bespreken voor prefill en decode.
Voor kostenramingen gaan we uit van een nominale H200-marktprijs van $3,00/uur (opmerking: dit is niet onze werkelijke GPU-prijs).
We ontdekten dat het instellen van batch_size=1 en DP=1 de beste prefill-prestaties oplevert. Verschillende TP-configuraties bieden vervolgens variërende afwegingen tussen de latentie van de eerste token en kosten. De onderstaande tabellen tonen de prefill-latentie en kosten per miljoen input-tokens voor diverse configuraties en input-lengtes.
GPT-OSS 120B:
Input-lengte | 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 |
GPT-OSS 120B prefill-latentie en kosten per miljoen invoertokens per parallelismeconfiguratie en invoerlengte.
GPT-OSS 20B:
Input-lengte | 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 |
GPT-OSS 20B prefill-latentie en kosten per miljoen invoertokens per parallelismeconfiguratie en invoerlengte.
Voor decode ontdekten we dat EP4 DP1 TP4 de beste configuratie is voor de meeste gevallen. De vier onderstaande grafieken illustreren de afweging tussen decode-snelheid en kosten per miljoen output-tokens voor zowel de 120B- als de 20B-modellen bij sequentielengtes van 8192 en 32768.
We hebben ook overwogen om het kleinere 20B-model te gebruiken als een speculatieve decoding-draftmodel voor het grotere 120B-model. Echter, omdat het aantal geactiveerde parameters vergelijkbaar is (3B vs. 5B), waren de resulterende snelheidsverbeteringen marginaal.
Referenties
Gedisaggregeerde Prefill en Decode
Sonar versnellen door speculatie
Lagere latentie en hogere doorvoer met Multi-node DeepSeek-implementatie
Efficiënte en draagbare Mixture-of-Experts-communicatie
FlashInfer: Efficiënte en aanpasbare Attention-engine voor LLM-inferentie-serving
Efficiënte streaming-taalmodellen met Attention Sinks
DeepSeek-V3 technisch rapport
OpenAI Harmony-antwoordindeling | OpenAI Cookbook
Citaat
@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}
}