Hraðar innfellingar á GPU
Þessi grein kynnir innsýn í innviði Perplexity fyrir þennan sérstaka flokk líkana.
Fljótleg og nákvæm leit skiptir öllu máli fyrir Perplexity, frá Leit og Tölvu yfir í API-vettvanginn okkar. Á bak við tjöldin er erfiða vinnan unnin af innfellingar- og röðunarlíkönum, sem hjálpa kerfum okkar að bera kennsl á viðeigandi niðurstöður fyrir tiltekna fyrirspurn. Við náum nýjustu gæðum og töf með því að þjálfa og þjónusta okkar eigin líkön, svo sem pplx-embed.
Þessi grein kynnir innsýn í innviði Perplexity fyrir þennan sérstaka flokk líkana. Við ræðum okkar tækni til að mæta á skilvirkan hátt ályktunarþörfum gervigreindarmiðaðrar leitar, sem gerir kleift að útbúa frumgerðir og meta líkön á fljótlegan hátt á sama tíma og exabæta-skala leitarvísitala okkar knúin áfram. Þessar tækniaðferðir víkka út Pareto-jaðar leitarbæði og skilvirkni, sem gerir okkur kleift að þjónusta umboðsmenn (agents) og notendur með sem bestum árangri á lægsta kostnaði og lágri töf.
Innfellingar fyrir leit
Í dæmigerðri leitaruppsetningu er skjölum sem búið er að vísunarmappa vörpuð yfir á hávíðótt vinnusvæði vigurs með því að nota innfellingarlíkan og þau geymd í vigurgagnagrunni. Með því að innfella fyrirspurn með því sama líkani er hægt að staðsetja svipuð skjöl með því að finna þá vigra sem eru næststaddir vigri fyrirspurnarinnar. Þetta leiðir af sér tvö mismunandi umferðarmynstur fyrir ályktunarvél til að þjónusta:
- Runuinnfelling: þegar gagnagrunnurinn er byggður, stækkaður eða endurvísun gerð, verður að innfella magnskjöl í vinnusvæði vigursins, til að hámarka afköst til að lágmarka kostnað.
Í kjölfar vigurleitar þarf að einkunna stórar runur af skjölum, sem nær jafnvægi á milli afkasta og tafanna.
- Innfelling á netinu: þegar leitað er í gagnagrunninum þarf að innfella stutta fyrirspurn fyrir uppflettingu til að lágmarka töf.
Við byggðum upp ályktunarinnviði okkar til að nýta sem flesta sameiginlega þætti í öllum notkunartilvikum. Þar sem við notum venjulega lítil Transformer-líkön til að framleiða innfellingar, deilum við meginhluta útfærslunnar með LLM-ályktunarkóðanum okkar: runuinnfellingar eru svipaðar útreikningsbundinni forskráningu, en innfellingar á netinu, sem keyra oft á fáum táknm, eru reikningslega svipaðar minnisbundinni afkóðun. Við endurnýtum því bjartsýni fyrirfyllingar- og afkóðunarkjarna til að þjónusta innfellingarlíkön. Fyrir vikið getum við náð gríðarlegum afköstum í runuályktun með lágmarks viðbótarverkfræðivinnu, á meðan við höldum lágri töf fyrir innfellingaverkálag á netinu.
Tulip, Roses, og smá Ivy
Við bjóðum upp á ályktanir í gegnum staðlaða API, bæði innanhúss og utanaðkomandi í gegnum API-vettvanginn okkar. Á bak við tjöldin koma margar þjónustur að vinnslu á innfellingarfyrirspurn:
- Ivy er Rust HTTP-gátt sem Perplexity þjónustur kalla á.
Það sér um CPU-vinnu fyrir fyrirspurnir eins og JSON-þáttun, táknun, sniðmát fyrir inntak og runuskiptingu, og þýðir fyrirspurnir yfir í sérsniðið gRPC-samskiptareglur fyrir niðurstreymisþjóna. Þessi aðgreining gerir okkur kleift að stilla ákveðnar breytur í kringum táknun og inntakssnið án þess að þurfa að snerta þyngri ályktunarhylkin.
- Tulip er viðmót ályktunarþjónsins.
Þetta er gRPC þjónn útfærður með Rust, tokio og tonic. Tulip tekur við gRPC ályktunarfyrirspurnum og sér um tímasetningu og runugerð. Hún sendir síðan runurnar til ROSE vélarinnar og skilar loknum svörum til viðskiptavina.
- ROSE (Runtime-Optimized Serving Engine) útfærir líkanasetningu (model inference).
Það er að stærstum hluta skilgreint í Python, og býður upp á kjarna (kernels), lög og skilgreiningar fyrir fjölbreytt úrval líkana. ROSE útfærir áframhaldandi umferðir í gegnum líkön, og býður einnig upp á stjórnun á CUDA-gröfum sem er sérhæfð fyrir innfellingar. Það er tengt við Tulip í gegnum step() fall, sem tekur við runu og skilar tilvísun í þann útreikning sem það framkvæmir á hraðlinum.
Veitum athygli út fyrir kjarnann
Bæði Transformer-undirstaða líkön og undirliggjandi Hopper/Blackwell arkitektúrar eru þroskaðar tækniþróanir, þannig að innfellingarályktun (inference) hlaðborðsmegin (GPU) hefur runnið saman í að mestu leyti ákjósanlega útfærslu yfir ýmsar ályktunarvélar. Þrátt fyrir það fundum við viðbótartækifæri til að bæta keyrslutíma og búnað (harness) sem birta líkönin frá endum til enda fyrir viðskiptavin. Sérstaklega komust við að því að við getum bætt töf (latency) með því að stýra CUDA-gröfum vandlega og með því að smíða LazyTensor útdrátt til að fylgjast með niðurstöðu á GPU-hliðinni í rauntíma í innfæddu Rust-vélinni. Við útfærðum þessa eiginleika í Tulip, þannig að hún gæti á áhrifaríkan hátt tengst líkansútfærslum ROSE.
Tulip
Við hönnuðum Tulip til að vera eins létt og mögulegt er sem viðmót yfir líkaþjónustu okkar. Hún sér um innkomandi fyrirspurnir í Tokio ósamstilltum verkefnum, heldur utan um safn af fyrirspurnum sem hún fylgist með og tímasetur runur frá til að senda á hraðalinn. Tímasetningarkerfið í Tulip er mjög einfalt: fyrirspurnir safnast saman á meðan Tulip er að senda út vinnu eða bíða eftir niðurstöðum. Úr safnaðist fyrirspurnum eru raðir valdnar á fyrst-koma-fyrst-fá-reglu til að keyra í gegnum líkanið.
Einfalda tímasetningarkerfið er sprottið af athugun á afköstum líkansins. Fyrir lítil innfellingarlíkön, við þær runulengdir sem við þjónustum, tókum við eftir því að línulegur kostnaður þéttra laga er ríkjandi yfir veldakostnaði athyglinnar. Þar af leiðandi er töf að mestu í hlutfalli við fjölda tákna, en ekki fjölda raða. Þess vegna, þegar runa er nógu stór til að metta GPU, sem er um 512 tákn á líkani undir milljarði breyta, bætir það ekki skilvirkni að pakka fleiri röðum inn í hana.
Til að eiga í samskiptum við líkanið treystir Tulip á CUDA-gröf og seinkaða niðurstöðufylgni til að láta GPU- og CPU-vinnu skarast og nýta tiltæk auðklend að fullu.
Stjórnun CUDA-grafa
Keyrsla á áframhaldandi umferð líkans felur í sér bæði vinnu á CPU-hlið og GPU-hlið. CPU-hliðin sér um að tímasetja runur og ræsa kjarna með viðeigandi breytum, á meðan GPU-hliðin keyrir viðeigandi fylkjamargföldun, athygli, staðal eða virkjunarkjarna. Fyrir mikil afköst eins og þjálfun og endurvísun eru CPU-tengdir kostnaðarliðir hverfandi vegna þess að runustærðir og GPU-töf eru hvort tveggja stórar. Hins vegar, við minni runustærðir, getur vinna á CPU-hlið vegið þyngra en vinna á GPU-hlið.
Til að draga úr aukakostnaði, í stað þess að ræsa sjálfstæða kjarna, er hægt að smíða CUDA-graf til að taka upp lýsigögnin sem þarf til að ræsa alla kjarna áframhaldandi umferðar með einu kalli á CUDA-rekilinn. Þetta útilokar þörfina á að keyra dýran Python- og PyTorch-kóða aftur fyrir þær stillingar sem hægt er að taka upp CUDA-gröf fyrir.
Fyrir hvert líkan fylgjumst við með sveigjupunkti og ákveðum lágmarksfjölda tákna þar sem keyrsla á GPU er dýrari en ræsing kjarna á CPU. Vegna þess að innfellingarlíkön eru lítil sjáum við að þessi sveigjupunktur kemur við runur af þúsundum tákna og tugum raða. Sumir athyglisútfærslur treysta á kraftmikil inntak hýsilsmegin til að stilla ræsingar kjarna, sem kemur í veg fyrir fulla forfyllingu líkansins/þétt CUDA-gröf. Við sendum upp (upstreamed) breytingum á viðeigandi kjarna til að virkja þá í ályktunarvélinni okkar.
Til að bregðast við auknum kostnaði smíðum við CUDA-gröf fyrir allt líkanið fyrir öll innfellingarlíkön og látum CPU-vinnu skarast við GPU-vinnu. Þar sem CUDA-gröf lágmarka kostnað CPU-hliðarinnar höfum við frjálsan tíma til að ræsa og setja í biðröð keyrslu á næstu runu þegar hún er tiltæk. Niðurstöðum biðrunu er fylgt eftir með LazyTensor, sem leyfir ósamstilltu verkefni í Rust að loka þar til fyrri runa klárar keyrslu. CUDA-gröf hjálpa þjónustu með lágri töf með því að tryggja að við stöðvumst ekki vegna kostnaðar við kjarnaræsingar og auðvelda betri tímasetningu í tilviki mikilla afkösta þar sem þau losa CPU til að vinna að næstu runu fyrr.
Taka verður upp CUDA-gröf fyrir hverja sérstaka stillingu, sem fyrir innfellingar þýðir eitt graf á bakhlið fyrir samsetningu raðafjölda og táknfjölda. Þar sem þetta net er víðfeðmt fyllum við táknfjölda í fötu sem eru margfeldi af 64 eða 256. Þetta skilar samt þúsundum grafa sem getur tekið margar mínútur að taka upp fyrir dæmigerð líkan. Kostnaður við upptöku kemur úr tveimur áttum: ákafri áframhaldandi umferð sem verður að keyra til að þýða kjarna og setja upp buffa fyrir ýmsa kjarna sem þurfa á þeim að halda, fylgt eftir af upptökukeyrslunni sem keyrir Python-kóða aftur.
Við drögum úr upphafskostnaði með því að taka upp CUDA-gröf seinkað þegar vélin þjónustar. Við höldum utan um hverja stillingu og tryggjum að hún fari í gegnum ákafa upphitunarkeyrslu áður en grafupptaka og endurspilun er ræst á öðru höggi. Öll síðari keyrsla á sömu grafstillingu fer þá í gegnum CUDA-grafarendurspilun. Seinkuð grafupptaka hefur áhrif á p99 tafir við upphaf; hún er þó dýrmæt við að dreifa mörgum mínútum af ákafri vinnu yfir margar klukkustundir. Hraðari ræsiltímar leyfa okkur að skýla og stjórna innfellingardreifingum betur.
Seinkaðir vigrar (Lazy Tensors)
Í gegnum CUDA er GPU-vinna ósamstillt. Þar sem ræsing kjarna setur hana í biðröð á straumi verður hýsilkóði að samstilla sig sérstaklega til að lesa út úr tilheyrandi vigrum. Til að auðvelda meiri samhliðun og geta ræst framtíðarrunur á meðan beðið er eftir að sú fyrri ljúki á tækinu, treystum við á LazyTensor útdrátt til að fylgjast með gildum.
LazyTensor fylgist með hýsilbuffi í síðulæstu minni og cudaMemcpyAsync aðgerð í gegnum atburð sem afritar gögn frá tækinu. Það er gangsett eftir ræsingu á áframhaldandi umferð á sama straumi. Þar sem afritunaraðgerðin verður að bíða eftir að allir fyrri kjarnar á straumnum keyri, fylgist tilhyrandi atburður bæði með lokun áframhaldandi umferðar og framboði niðurstöðunnar á CPU.
Við nýtum LazyTensor í ROSE kóðara vélinni okkar til að skarist GPU- og CPU-vinna. Í stað þess að hvert step() kall keyri CUDA-grafið og bíði eftir að það klárist, skilar step() LazyTensor til að fylgjast með niðurstöðu sinni ásamt því að keyra ósamstillt. Saman með CUDA-gröfum hjálpar þetta okkur að ná lágri töf og betri afköstum.
ROSE
Við aðlöguðum ROSE vélina okkar, sem við smíðuðum upphaflega fyrir LLM þjónustu, til að sjá einnig um keyrslu á innfellingarlíkönum. Til að lágmarka þá vinnu sem þarf til að styðja við innfellingarlíkön endurnýtir ROSE kóða á árásargjarnan hátt milli LLM og innfellinga. Til dæmis fara pplx-embed þjónusta og Qwen3.5 LLM afkóðun öll í gegnum sömu kjarna. Þessi samnýting gerir okkur kleift að þjónusta auðveldlega innfellingarlíkan sem upphaflega var fínstillt út frá LLM fyrir frumgerðagerð, mat og framleiðsluályktun.
Fyrir þétt lög eru innfelling og LLM ályktun eins þar sem táknvigrar eru unnir sjálfstætt. Í athyglislögum er mismuninum stjórnað með því að bæta við stuðningi við óregluleg inntak, ásamt forfyllingu með síðum og afkóðunarstillingum sem LLM krefjast. Þegar þjónustað er innfellingarlíkan búum við ekki til KV skyndiminni og sendum á afbrigði af athygliskjörnum sem styðja óreglulega sniðið til að forðast fyllingu. Stuðningsbreytingar og kvörðunarrútínur eru einnig deilt með LLM.
Ivy
Ivy, HTTP-gáttarlagið okkar fyrir ályktanir, gegnir einnig mikilvægu hlutverki í afköstum. Þar sem burðarstærðir fyrirspurna eru breytilegar í framleiðslu getur beinun einstakra fyrirspurna á stök afrit valdið ójafnvægi á álagi. Ivy skiptir stórum runufyrirspurnum í hluta og jafnar álag á milli afrita, sem bætir nýtingu og sléttir úr töfum. Nýleg vinna okkar við eigin unigram táknun (tokenization), sem hefur verið fullkomlega innleidd í Ivy, bætir töf verulega umfram staðlaðar táknunartæki.
...en kjarnarnir skipta samt máli
ROSE styður ýmsa bakenda athyglis. Mismunandi kjarnar geta hentað tilteknum vandamálastærðum. Með tímanum samþættum við FlashInfer 2, FlashInfer 3 og FlashAttention 4 kjarna til að útfæra óreglulega athygli.
Almennt sjáum við að FlashAttention 4 er hraðvirkari. Hins vegar skilar FlashInfer 3 betri árangri á Qwen-undirstaða líkönum við mjög langar runulengdir. Þar sem afköst og fínstilling geta breyst eftir fjölda og stærð vídda athyglishausa, viðhöldum við stuðningi við margar samstillingar og tökum ákvörðun í hverju tilviki fyrir sig við þjónustu.
Viðmiðunarprófanir
Viðmiðunarprófanir okkar eru gerðar gegn vLLM v0.22.0, þar sem ályktanir eru keyrðar á BF16 nákvæmni á raunverulegum líkanþyngdum og inntökum sem fengin eru úr mats gagnasöfnum. Öllum tímatökum voru undanfarnar upphitunarkeyrslur sem staðfestu að frávik í kósínussamhverfu væri innan við 0,1%.
Innfellingar með lágri töf (p50 / p90 / p99 / hámark ms)
Við gefum upp keyrslutíma fyrir for-táknuðu runustærð fyrirspurnar 1, alveg raðbundnar fyrirspurnir, runulengdir 128, 512 og 4096 tákn.
Einkunnagjöf með lágri töf (p50 / p90 / p99 / hámark ms)
For-táknuð runustærð fyrirspurna 5, 25 og 50, runulengd 512 tákn.
Innfellingar með miklum afköstum (emb/s)
Fyrirspurnarunustærð 100, fjögur samtímis ferli sem senda inn fyrirspurnir, runulengdir 512, 1024 og 4096 tákn.
Innfellingar með mikilli samtímisnotkun (p50 / p90 / p99 / hámark ms)
Runulengd 512, runustærð 1, en við sendum 1, 2, 4, 8 og 16 samtímis fyrirspurnir. Þessi viðmiðunarprófun inniheldur einnig kostnað við táknun í gegnum Ivy, ásamt netkerfiskostnaði milli Ivy og Tulip.
Niðurstaða og framtíðarvinna
Þjónustuinnviðirnir sem samanstanda af Ivy, Tulip og ROSE gera okkur kleift að þjónusta innfellingar fyrir Perplexity með minni töf og betri afköstum, sem leiðir til nákvæmari leitar á lægri kostnaði samanborið við tilbúnar lausnir.
Með því að einbeita okkur að sérstökum líkönum og taka ábyrgð á öllum staflanum öðlumst við það frelsi sem þarf til að ná áhrifaríku jafnvægi á milli afkasta and sveigjanleika, þar sem mjög endurnýtanlegir og afkastagóðir Rust-grunneiningar eru blandaðar saman við almennari Python-líkanakóða. Margar opnar ályktunarvélar, svo sem vLLM, SGLang, og TokenSpeed, eru að samþætta tungumál eins og Rust og C++ í sinn stafla. Við höfum fjárfest í Rust undanfarin tvö ár og uppskorið mikinn árangur í bæði afköstum og viðhaldshæfni. Með því að deila meginhluta innfellingarútgáfunnar með LLM-þjónustustaflanum okkar náum við einnig fram aukningum í afköstum, án þess að þörf sé á talsverðri verkfræðivinnu við viðhald innfellingarlíkana.
Þegar líkön þróast munum við halda áfram að bæta hvert lag í staflanum okkar til að draga úr bæði CPU-tengdum og GPU-tengdum töfum. Sérsniðnu gRPC-undirstaða samskiptareglurnar okkar innan Ivy og Tulip gerir okkur kleift að fínstilla samskipti til að draga úr nettöfum, á meðan ROSE veitir grunn til að bæta útreikningsafköst. Að auki, eftir því sem stuðningur við frjálsa-þræða Python vex um allt vistkerfið, munum við geta bætt samvirkni Python og Rust enn frekar til að draga úr kostnaði.
Tilvísanir
- Hönnun og mat á gervigreindarmiðuðu leitar-API
- pplx-embed: Fullkomnustu innfellingarlíkönin fyrir heimsklassa endurheimt (Web-Scale Retrieval)
- Bæting á CPU-afköstum Unigram-táknara
- vLLM
- FlashInfer
- FlashAttention
Tilvitnun
@online{perplexity2026FastEmbeddingsOnGpus,
author = {{Perplexity} and Nandor Licker and Sebastian Sepulveda and Phi Hoang and Jerry Ma},
title = {{Fast embeddings on GPUs}},
date = {2026-09-04},
url = {https://www.perplexity.ai/hub/blog/fast-embeddings-on-gpus}
}