GPT-OSS v deň 0
Podpora GPT-OSS v deň 0 na H200 pomocou adaptácie ROSE s FP8, sink attention a optimalizáciami MoE
Spoločnosť Perplexity sa zaviazala sprístupniť tie najlepšie modely umelej inteligencie zvedavým používateľom, ktorí požadujú presné a dôveryhodné odpovede a činnosti agentov. Spoločnosť OpenAI nedávno oznámila svoje modely s otvorenými váhami (gpt-oss-20b a gpt-oss-120b). Podobne ako mnohé popredné modely, aj Perplexity patrí medzi prvé organizácie, ktoré vyhodnocujú gpt-oss-20b a gpt-oss-120b.
V tomto príspevku zdieľame rozhodnutia o infraštruktúre nášho interného inferenčného zásobníka, vďaka ktorému bola možná podpora od prvého dňa (Day-0). Zameriavame sa na poskytovanie týchto modelov na GPU NVIDIA H200, pričom podrobne opisujeme zmeny jadra, možnosti nasadenia a kompromisy medzi rýchlosťou a nákladmi.
GPT-OSS na architektúre Hopper
Modely s otvorenými váhami sa dodávajú s kvantovaním MXFP4, čo im pomáha zmestiť sa do pamäte na hardvéri spotrebiteľskej triedy alebo dosiahnuť špičkovú priepustnosť na NVIDIA Blackwell. Na počiatočné vyhodnotenie sme ich však chceli spustiť na existujúcich clusteroch H200 Hopper s minimálnymi zmenami inferenčného motora. Hopper nemá vyhradené jadrá FP4 tensor cores, ktoré zaviedol Blackwell. V dôsledku toho sme sa rozhodli poskytovať modely s presnosťou FP8, aby sme minimalizovali potrebu vlastných jadier (custom kernels) a čo najlepšie využili dostupný hardvér.
Na vysokej úrovni sú transformátorové LLM štrukturálne jednoduché:
Vstupné vkladanie (Input embedding)
Sekvencia transformátorových vrstiev. Každá obsahuje bloku pozornosti (attention block) a hustý blok MLP alebo riedky blok MoE.
Výstupná projekcia logitov (Output logit projection)
Pri spúšťaní nového transformátorového modelu nás primárne zaujíma zistenie, do akej miery sa zhodujú s existujúcimi modelmi, aby sme identifikovali potrebné zmeny. Spoločnosť OpenAI nám vopred láskavo poskytla prehľad svojich modelov, čo nám umožnilo zodpovedajúcim spôsobom vyladiť naše inferenčné nastavenie. Zistili sme, že model si vyžadoval pomerne veľké množstvo malých zmien.
Pozornosť (Attention): GQA s mechanizmom Attention Sinks
Každá hlava pozornosti (attention head) má vopred trénovaný parameter sink, ktorý sa zohľadňuje v Softmax
Pozíciové kódovanie YaRN, podobne ako v DeepSeek-V3
QKV projekcie majú zamerania (biases), podobne ako Qwen 2
Výstupná projekcia má zaujatosť (bias)
MLP: Riedka zmes expertov (Sparse Mixture-of-Expert - MoE)
Aktivačná funkcia SwiGLU, odlišná od väčšiny modelov s otvorenými váhami
Softmax po Top-K pre váhy expertov
Experti majú zaujatosti (biases)
Keďže sme očakávali, že počty parametrov budú okolo 100B-200B, rozhodli sme sa:
Rozšíriť FlashInfer o podporu pre attention sinks
Znova použiť implementáciu MoE, ktorá už bola vytvorená pre rodinu modelov DeepSeek-V3
Zvoliť blokové škálovanie FP8 128x128 ako schému kvantovania, pričom sa jadrá DeepGEMM rozšíria o podporu pre člen zaujatosti (bias term).
Interný inferenčný motor
Naše inferenčné úsilie je podporované naším interným inferenčným motorom ROSE. Budujeme ROSE tak, aby bol flexibilným rámcom, ktorý umožňuje rýchle spúšťanie nových modelov. Okrem toho, akonáhle sa zaviažeme slúžiť modelu vo veľkom meradle, poskytuje platformu na optimalizáciu a zvýšenie výkonu na dosiahnutie najmodernejšej úrovne (state of the art).
ROSE sprístupňuje motor LLM, ktorý môže načítať model a generovať preň dekódované tokeny prostredníctvom viacerých dekodérov vrátane špekulatívnych a MTP dekodérov. Samotné modely sa skladajú z vlastnej sady vrstiev, ktoré podporujú rôzne konfiguračné znalosti pre kvantovanie a paralelizmus. Pod týmito vrstvami sú spojené jadrá Triton a CUDA, ktoré efektívne implementujú a spájajú výpočty vykonávané jednotlivými vrstvami.
ROSE je primárne postavený v Pythone a pre definície modelov sa spolieha na PyTorch. Hoci nám Python umožňuje byť flexibilní a prispôsobovať sa novým modelom, väčšinu komponentov citlivých na výkon, ako je obsluha (serving) a plánovanie dávok (batch scheduling), migrujeme do Rustu.
Na spustenie nového modelu najprv definujeme hierarchiu modelu a zostavíme preň prevodník váh. Po zaúčtovaní všetkých váh definujeme dopredný prechod (forward pass) pre najjednoduchší prípad použitia TP=1 a zabezpečíme jeho fungovanie end-to-end. Nakoniec implementujeme a otestujeme podporu pre rôzne formy paralelizmu pred vydaním novej schránky (container) a nasadením modelu na cluster na vyhodnotenie. Potom iterujeme výkon, pričom sa spoliehame na spätnú väzbu z dashboardov a jemnejších benchmarkov.
ROSE pracuje s numerickými tokenmi, pričom o formátoch chat vie len málo okrem integračných testov. Súbežne sme sa museli pozrieť na úpravu okolitej infraštruktúry tak, aby podporovala tokenizátor Harmony a správne mapovala požiadavky na vstupné sekvencie tokenov.
Pri modeli GPT OSS sme zistili, že nie sú potrebné žiadne zmeny v našich dekodéroch, postrojoch grafov CUDA ani v okolitej infraštruktúre, čo nám umožnilo sústrediť naše úsilie na ladenie jadier, ktoré podporujú model.
Jadrá pre GPT-OSS
Sink Attention
Sink attention zavádza dodatočný faktor zaujatosti pred softmaxom, ktorý sa akumuluje s produktom Q a K:
attn = softmax(q @ k^T * sm_scale + sink) * VZatiaľ čo naivná implementácia je pomerne triviálna, efektívne implementácie pozornosti, ako napríklad FlashInfer, paralelizujú výpočet pozornosti naprieč nezávislými hlavami aj naprieč dĺžkou sekvencie KV. Okrem toho sa kvôli numerickej stabilite Softmax počítá online a zároveň sa odpočítava maximálny prvok pre numerickú stabilitu:
softmax(x) = e^x / sum(e^x) = e ^ (x - max(x)) / sum(e ^ (x - max(x))Online implementácia sledovala bežiace maximum m inicializované na -inf a mierku d na 1. Inicializáciou maxima na hodnotu sink aktuálnej hlavy by sme zabezpečili, že sa správne akumuluje do Softmaxu. Museli sme dbať na to, aby toto maximum bolo zahrnuté iba v prvom chunku, ak bola pozornosť rozdelená do viacerých blokov pozdĺž dĺžky sekvencie.
Upravili sme šablónu jadra FlashInfer FA2, ktorá sa používa na prefill aj dekódovanie, tak, aby zahŕňala parametre sink.
MoE
Hlavným rozdielom medzi vrstvou MoE rôznych modelov je zvyčajne schéma smerovania (routing). Keďže ROSE očakáva podstatnú variabilitu, implementuje toto jadro v Tritone, čo nám umožňuje ľahko ho prispôsobiť novým modelom. V prípade GPT-OSS sme museli upraviť bodovanie váh tak, aby vykonávalo softmax iba naprieč vybranými expertmi Top-K, na rozdiel od niektorých modelov v štýle DeepSeek, ktoré počítajú softmax naprieč všetkými expertmi. Zistili sme, že pre presnosť je kritické vypočítať váhy expertov v presnosti bfloat16.
Výzva s vrstvou MoE pramenila z nášho rozhodnutia znova použiť existujúce jadrá DeepGEMM, ktorým chýbala podpora pre členy zaujatosti (bias terms). Našťastie sme sa s nimi časom hlboko integrovali a vykonali zmeny, aby sme ich lepšie prepojili s našimi vlastnými dispečerskými jadrami typu všetko-so-všetkým (all-to-all). Pridali sme podporu zaujatosti do DeepGEMM inicializáciou akumulátorových registrov WGMMA na hodnoty zaujatosti načítané z pamäte. Toto je jednorazová záležitosť počas spracovania bloku MN, takže náklady sú pravdepodobne zanedbateľné a vyrovnávacia pamäť L2 zaisťuje efektivny prístup k týmto hodnotám.
Keďže tieto modely nemajú priamy úžitok z dátového paralelizmu (Data Parallelism), opätovne sme použili dispečerské a kombinované jadrá iba pre TP. Vstupy do dispečingu sú replikované naprieč všetkými hodnosťami (ranks), takže dispečing vyberá tokeny pre lokálne dostupných expertov. Combine vykonáva váženú akumuláciu cez NVLink.
Optimalizácie výkonu (Performance Tweaks)
Hoci naším cieľom bolo rýchle spustenie modelov, chceli sme zabezpečiť, aby výkon bol stále primeraný. Po zaistení správnosti voči referenčnej implementácii poskytnutej spoločnosťou OpenAI sme profilovali našu implementáciu pomocou predvoleného profilovača PyTorch, pričom sme dávali pozor na alokácie blokov a vlákien naprieč jadrami. Funkcionalita, ktorú sme opätovne použili, bola vytvorená pre modely, ktoré mali väčší skrytý rozmer (hidden dimension) 7168, čo je podstatne viac než 2880 u modelov GPT-OSS. Špecializovali sme spúšťače jadier (kernel launchers), aby vybrali lepšie rozmery mriežky, čo výrazne zvýšilo priepustnosť.
Tokenizácia a kanály
Formát chat systému Harmony má niekoľko dôležitých konceptov na štruktúrovanie konverzácií, obsahu uvažovania a volaní funkcií. V tomto formáte sa každá správa skladá z hlavičky a obsahu:
<|start|>{header}<|message|>{content}<|end|>Hlavička nesie metadáta — najdôležitejšie je rola (system, developer, user, assistant, tool), kanál a príjemca, ako napríklad to=functions.<function-name> pri vyvolaní volania funkcie.
Kanály (ako sú analýza, komentár a konečná odpoveď) robia výstupy modelu transparentnejšími a segmentovanejšími. Pretože formát vynucuje toto oddelenie, model môže uvažovať transparentne (a byť kontrolovaný na ladenie) bez úniku reťazca myšlienok (chain-of-thought) do produkcie. Značky príjemcov (hlavičky to=) presne hovoria runtime, ktorý aktér by mal prijať ďalší dátový užitočný obsah (payload) — či už je to funkcia, samotný model alebo koncový používateľ.
Náš inferenčný motor ROSE je nezávislý od formátu. Prijíma dávku vstupných tokenov a streamuje späť výstupné tokeny. V našom inferenčnom zásobníku je úloha formátovania vstupov do tokenizovanej výzvy a parsovania výsledkov LLM späť do štruktúrovaných správ zabezpečená vyhradenou front-end službou JSON API. Integrovali sme Harmony pridaním nového zásuvného formátovača/parseru do tohto front-endu, čo umožňuje backendu zostať nezmenený, zatiaľ čo front-end prehľadne spravuje pravidlá formátu chat, volania nástrojov a streamovanie. Toto oddelenie záujmov udržuje architektúru modulárnu, čo umožňuje rýchle prijatie nových formátov a funkcií odpovedí s minimálnymi zmenami backendu.
Náklady a výkon
Vzhľadom na pomerne malú veľkosť modelov GPT-OSS obmedzujeme nasadenie repliky na jeden uzol, aby sme sa vyhli réžii komunikácie medzi uzlami. Naša implementácia podporuje flexibilné kombinácie paralelizmu expertov (EP), dátového paralelizmu (DP) a tenzorového paralelizmu (TP). Na určenie optimálneho nastavenia nasadenia sme porovnali všetky kombinácie stratégií shardingu naprieč veľkosťami dávok od 1 do 128. Vďaka disagregácii predbežného vyplnenia a dekódovania (Prefill-Decode Disaggregation) môžeme diskutovať o kompromise medzi výkonom a nákladmi pre prefill a dekódovanie zvlášť.
Pre odhady nákladov predpokladáme nominálnu trhovú sadzbu H200 vo výške 3,00 USD/hodinu (poznámka: toto nie je naša skutočná cena za GPU).
Zistili sme, že nastavenie batch_size=1 a DP=1 prináša najlepší výkon prefillu. Rôzne konfigurácie TP potom poskytujú rôzne kompromisy medzi latenciou prvého tokenu a nákladmi. Tabuľky nižšie uvádzajú latenciu prefillu a náklady na milión vstupných tokenov pre rôzne konfigurácie a vstupné dĺžky.
GPT-OSS 120B:
Vstupná dĺžka (Input Length) | 8192 | 32768 | 65536 | 128000 |
EP1 DP1 TP1 | 0,364 s, 0,037 USD | 2,421 s, 0,062 USD | 7,375 s, 0,094 USD | 23,902 s, 0,156 USD |
EP2 DP1 TP2 | 0,190 s, 0,039 USD | 1,245 s, 0,063 USD | 3,786 s, 0,096 USD | 12,116 s, 0,158 USD |
EP4 DP1 TP4 | 0,165 s, 0,067 USD | 0,900 s, 0,092 USD | 2,449 s, 0,125 USD | 7,165 s, 0,187 USD |
EP8 DP1 TP8 | 0,179 s, 0,145 USD | 0,839 s, 0,171 USD | 2,003 s, 0,204 USD | 5,119 s, 0,267 USD |
Latencia prefilla GPT-OSS 120B a cena za milión vstupných tokenov podľa konfigurácie paralelizmu a dĺžky vstupu.
GPT-OSS 20B:
Vstupná dĺžka (Input Length) | 8192 | 32768 | 65536 | 128000 |
EP1 DP1 TP1 | 0,239 s, 0,024 USD | 1,610 s, 0,041 USD | 4,895 s, 0,062 USD | 16,037 s, 0,104 USD |
EP2 DP1 TP2 | 0,127 s, 0,026 USD | 0,833 s, 0,042 USD | 2,522 s, 0,064 USD | 8,143 s, 0,106 USD |
EP4 DP1 TP4 | 0,108 s, 0,044 USD | 0,593 s, 0,060 USD | 1,616 s, 0,082 USD | 4,766 s, 0,124 USD |
EP8 DP1 TP8 | 0,116 s, 0,094 USD | 0,547 s, 0,111 USD | 1,310 s, 0,133 USD | 3,365 s, 0,175 USD |
Latencia prefilla GPT-OSS 20B a cena za milión vstupných tokenov podľa konfigurácie paralelizmu a dĺžky vstupu.
Pre dekódovanie sme zistili, že EP4 DP1 TP4 je najlepšia konfigurácia pre väčšinu prípadov. Štyri grafy nižšie znázorňujú kompromis medzi rýchlosťou dekódovania a nákladmi na milión výstupných tokenov pre modely 120B aj 20B pri dĺžkach sekvencií 8192 a 32768.
Zvažovali sme tiež použitie menšieho modelu 20B ako modelu pre špekulatívne dekódovanie (speculative decoding) pre väčší model 120B. Avšak, pretože počet aktivovaných parametrov je podobný (3B vs. 5B), výsledné zrýchlenia boli minimálne.
Referencie
Disagregované predbežné vyplnenie a dekódovanie (Disaggregated Prefill and Decode)
Urýchlenie Sonaru pomocou špekulácií
Nižšia latencia a vyššia priepustnosť pri viaczolovom nasadení DeepSeek
Efektívna a prenosná komunikácia Mixture-of-Experts
FlashInfer: Efektívny a prispôsobiteľný engine pozornosti pre LLM inference serving
Efektívne streamovacie jazykové modely s Attention Sinks
Formát odpovedí OpenAI Harmony | OpenAI Cookbook
Citácia
@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}
}