Giti skaleerimine OpenAI-s
Agentide töömahule vastava versioonihalduse loomine ja panustamine Giti ökosüsteemi.
Viimase aasta jooksul on meie monovaramu maht ja sellele esitatavad nõuded kasvanud hämmastava kiirusega. Oli selge, et peame oma versioonihaldussüsteemi uuendama, et see tuleks toime paralleelse töö mahuga, mille Codex võimalikuks teeb.
Lõime Pando, uue tagasüsteemi Giti varamutele, katkestamata arendustööd või muutmata seda, kuidas meie meeskond Giti kasutab. Nüüd toetub kogu OpenAI monovaramu arendus Pandole. Pando on loodud täitma kaht ambitsioonikat eesmärki. Esiteks horisontaalselt skaleeritav kirjutamine, mis on optimeeritud samaaegseteks üleslükkamisteks paljudesse harudesse. Teiseks lugemise läbilaske maksimeerimine, et kliendid saaksid andmeid alla laadida piisavalt kiiresti, kasutamaks kogu saadaolevat võrgu ribalaiust.
Saavutasime need eesmärgid, säilitades ühilduvuse Giti protokolli ja kliendiga. Nii said meie arendajad ja agendid Pando sujuvalt oma senistes töövoogudes kasutusele võtta. Tootmiskeskkonnas vähendas Pando üleslükkamise mediaanviivitust ligi viis korda. Praegu edastab see iga päev ligi petabaidi Giti andmeid.
Siin selgitame, miks otsustasime luua uue versioonihaldussüsteemi ja säilitada ühilduvuse Gitiga. Võrdleme oma süsteemi Giti skaleerimise levinud lähenemisviisidega ning selgitame, miks just Pando suudab täita OpenAI skaleerimisvajadusi. Räägime ka edasistest plaanidest ja sellest, kuidas jätkame Giti arendamisse panustamist, et toetada agentide töömahtu.
Codex on muutnud OpenAI arenduse mahtu ja tempot, võimaldades arendajatel teha palju rohkem tööd paralleelselt. See tähendab rohkem harusid, üleslükkamisi ja ühendamisi ning rohkem toomisi ja kloonimisi arenduskeskkondadest, uurimistöödest ja pidevast integratsioonist (CI).
Need koormused võimendavad üksteist. Ühel arendajal on nüüd korraga CI jaoks valmis mitu muudatust ning iga üleslükkamine võib käivitada mitu tööd, mis toovad sama sissekannet.
Umbes eelmise aasta lõpust alates oli meie monovaramut toetavatel süsteemidel raske tempoga sammu pidada. Toomised ja üleslükkamised olid aeglased, ühendamised nurjusid ning töökindlus langes kohati alla 90%. Kas olime jõudnud Giti enda piirini või piiras meid viis, kuidas monovaramut teenindasime? Git kasvas välja kogukonnast, mis vahetas operatsioonisüsteemi tuuma paiku e-posti teel. Enam kui kahe aastakümne jooksul on arendajad tarkvara loomise viiside muutudes oma tööriistu Giti ümber kohandanud. Kui meie enda monovaramus hakkasid tekkima takistused, oli meile oluline, et saaksime sellele tööle jätkuvalt toetuda.
Nägime võimalust säilitada tuttav töövoog, ehitades tagasüsteemi ümber nii, et see töötleks paralleelselt üleslükkamisi eri harudesse ja edastaks sama ajalugu korraga paljudele lugejatele. Giti säilitamine versioonihalduse töövoo alusena tähendas, et kliendi täiustustest võiks olla kasu ka väljaspool OpenAI-d. Tahtsime anda need täiustused oma Giti koopiast(avaneb uues aknas) tagasi põhiprojekti ja jagada neid laiema kogukonnaga.
Versioonihaldussüsteemi skaleerimisel on kaks põhisuunda: paljud kirjutajad lükkavad muudatusi üles eri harudesse ning paljud lugejad toovad sama ajalugu. Pando optimeerib mõlemat.
Esiteks koordineerib Pando iga haru uuendusi eraldi. Omavahel mitteseotud harusid saab uuendada paralleelselt ning haru toov lugeja saab selle versiooni jaoks vajaliku ajaloo. Kompromissina võib mitut haru vaatav lugeja näha neid eri ajahetkede seisuga.
Teiseks taaskasutab Pando toomiste vahel pakifaile (Giti vorming mitme objekti kokkupakkimiseks), selle asemel et luua igale kliendile eraldi pakifail. Klient võib alla laadida mõne objekti, mis tal juba olemas on, kuid server saab samad baidid edastada paljudele klientidele vähese arvutustööga.
Need valikud võimaldavad meil kirjutamist harude vahel skaleerida ja lugemispäringuid vahemälust teenindada. Et mõista, kuidas need omavahel kokku sobivad, vaatame esmalt, kuidas Git ajalugu salvestab ja edastab.
Git peab suutma hoida sünkroonis varamu kaht osa: objekte ja viitu.
Giti varamu salvestab failide hetkeseise ja neid ühendavat ajalugu objektide graafina. Objekt võib olla bloob, puu, sissekanne või silt. Bloobid sisaldavad üksikute failide sisu ning puud seostavad nimesid bloobide või teiste puudega, moodustades kataloogistruktuuri. Sissekanded osutavad juurpuule ja nullile või enamale eellassissekandele, moodustades varamu ajaloo.
Objektide identifikaatoriks on nende tüübi ja sisu räsi. Objektid on ka muutumatud: muudetud faili salvestamine loob uue bloobi, muutmata failid ja kataloogid saavad aga taaskasutada olemasolevaid objekte.
Harud ja sildid on viidad, mis osutavad sissekannetele. Harus muudatuste kinnitamine loob uue sissekande ja uuendab haru viita sellele osutama.
Giti objektid viitavad üksteisele ID kaudu: sissekanded puudele ning puud teistele puudele ja bloobidele. Haru refs/heads/main osutab sissekandele C2, mille eellane on C1. C1 osutab juurpuule T1, kus parser.py viitab bloobile B1. C2 osutab juurpuule T2, kus parser.py viitab bloobile B2. Mõlemas juurpuus viitab docs/ samale puule T3. Selle kirje README.md osutab bloobile B3 ja usage.md bloobile B4.
Git salvestab objekte kas „eraldi“ või „pakitult“. Eraldi objekte hoitakse üksikutes failides, mida tuvastatakse objekti ID järgi. Pakitud objekte hoitakse koos pakifailis, mis võimaldab sarnaseid objekte salvestada üksteise suhtes erinevustena.
Git saab bloobe salvestada eraldi failidena või pakkida need kokku, kodeerides ühe bloobi erinevusena teisest.
Gitis on objekt sissekandest kättesaadav, kui Git leiab selle, järgides sissekande seoseid selle eellaste, puude ja bloobide kaudu. Toomise ajal teatab klient serverile, milliseid sissekandeid ta soovib ja millised tal juba olemas on. Server leiab soovitud sissekannetest kättesaadavad objektid, jätab välja need, mis teadaolevalt on kliendil juba olemas, ning saadab ülejäänud pakifailina samas vormingus, mida Git kasutab kettal. Täielik kloonimine algab ilma ühegi objektita, seega vajab see kõiki kloonitavast ajaloost kättesaadavaid objekte.
Üleslükkamine edastab objekte vastassuunas, paludes serveril uuendada üht või mitut viita. Klient kasutab serveri väljakuulutatud viitade hulka, et vältida serveril juba olemasolevate objektide saatmist. Saadetav pakk võib seega sõltuda olemasolevatest objektidest: uue ajaloo taastamiseks ei piisa ainult paki vastuvõtmisest.
Giti varamu replitseerimine tähendab nii objektide kui ka viitade kättesaadavana hoidmist mitmes serveris. Enne kui koopia saab pakkuda viida uut väärtust, peab see suutma edastada sellest väärtusest kättesaadavad objektid. Teenus peab koordineerima ka konkureerivaid viidauuendusi ehk üleslükkamisi, mis püüavad viia sama haru samast vanast tipust eri uute sissekannete peale. Süsteemides, mis seavad kõik varamusse kirjutamised ühte järjekorda, võivad ka mitteseotud harudesse üleslükkamised üksteise järel ootama jääda.
Pando kavandamisel hindasime Giti-põhise versioonihalduse skaleerimise tavapäraseid lahendusi. Üks koordineerib viidauuendusi varamu koopiate vahel kolmefaasilise kinnitamisega (3PC, mitme sõlme vahel tehingu kinnitamist koordineeriv protokoll). Teine järjestab uuendused bloobihoidlas asuva ühise eellogi kaudu (WAL, kuhu muudatused kirjutatakse enne nende rakendamist).
Meie modelleeritud kolmefaasilise kinnitamise lahenduses hoiab Giti teenus mitmes replikas varamu täielikku koopiat. Kui mõni server võtab vastu üleslükkamise, kopeeritakse saabuv pakifail ja saadetakse paralleelselt kõigile replikatele. Üleslükkamise avaldamiseks peab enamik replikaid viidauuenduse heaks kiitma. Seda haldav server on koordinaator ning protsess nõuab koordinaatori ja iga teise replika vahel mitut suhtlusringi.
Viidauuenduse vastuvõtmiseks lukustab iga replika oma viidakoopia ja kontrollib, et see osutaks endiselt kliendi eeldatud sissekandele. Seejärel saadab koordinaator nõustunud replikatele eelkinnituse sõnumi. Kui enamik on eelkinnituse sõnumile jaatavalt vastanud, annab koordinaator neile korralduse uuendus teha. Seejärel saab iga ajakohane replika kuulutada oma kohalikust varamukoopiast välja haru uue tipu.
Täielike koopiate hoidmine võimaldab lugemispäringuid kohapeal teenindada ja tagab klientidele kõigist viitadest kooskõlalise vaate, olenemata valitud replikast. Seetõttu uuendatakse viitu ükshaaval ning iga üleslükkamine nõuab viidauuenduse koordineerimiseks replikate vahel mitut päringu-vastuse ringi.
Kvoorumi ootamise tõttu sõltub üleslükkamise kiirus replikate kettajõudlusest ja sideviivitusest. Kirjutamismahu kasvades peavad replikad toime tulema nii saabuvate pakkide kui ka lugemisliiklusega.
Meie modelleeritud WAL-põhises lahenduses kasutab Giti teenus varamuüleste uuenduste järjestamiseks bloobihoidlas asuvat ühist manifesti. Kui server võtab vastu üleslükkamise, laadib see saabuva pakifaili bloobihoidlasse ja valmistab viidauuenduse ette oma kohalikus varamukoopias. Üleslükkamise avaldamiseks lisab server bloobihoidlas asuvasse ühisesse manifesti kirje, mis salvestab viidauuenduse ja osutab pakifailile. Seejärel uuendab Giti server manifesti võrdle-ja-vaheta-toiminguga. See kas asendab manifesti atomaarselt või lükkab muudatuse tagasi. Kui teine kirjutaja on manifesti vahepeal uuendanud, loeb server lisandunud kirjeid, kontrollib, et tema viidauuendus on endiselt kehtiv, ja proovib juba üles laaditud pakifailiga uuesti.
Kirjutajad saavad oma pakifaile paralleelselt üles laadida, kuid ka mitteseotud harudesse üleslükkamine nõuab sama manifesti uuendamist. Eduka võrdle-ja-vaheta-toimingu päringu-vastuse aeg piirab sagedust, millega varamu saab uut manifesti avaldada. Väikese viivitusega bloobihoidla teeb selle sammu kiireks. Rühmitamine võimaldab ühe manifestiga uuendada korraga mitut viita, kuid selle hinnaks on uuenduste järjekorda kogumine ja suurem viivitus.
Bloobihoidla saab pakifaile vastu võtta paralleelselt, kuid ühise manifesti uuendused konkureerivad endiselt omavahel. Ainuüksi bloobihoidla võimsuse suurendamine seda kitsaskohta ei kõrvalda. Iga replika peab endiselt bloobihoidlast pakid lugema ja indekseerima, enne kui saab neid kohapealt edastada. Kui kirjutamisi saabub kiiremini, kui seda tööd teha jõutakse, jäävad replikad maha ja kliendid peavad äsja üleslükatud sissekannete toomist kauem ootama.
See toobki meid Pando juurde. Pando on Giti varamute teenindamise uus arhitektuur, mille eesmärk on toetada suurt hulka samaaegselt üleslükkavaid kliente. See töötab järgmiselt:
Enne Pando arendamist aimasime, et suudame oma nõuded täita Gitist loobumata. Küll aga tuli teha järeleandmisi mõnes eelduses, mida enamik Giti süsteeme peab nõueteks:
Varamuülene kooskõla: kõigist viitadest kooskõlalise hetkeseisu pakkumine nõuab kogu varamu hõlmavat koordineerimist. Süsteemis, mis järjestab kõik viitade uuendused ühiselt, konkureerivad omavahel mitteseotud harudesse üleslükkamised ühe koordineerimispunkti pärast.
Igale kliendile eraldi pakifail: kui kaks erineva kohaliku ajalooga klienti toovad sama haru, võib serveril olla vaja luua kummalegi eraldi pakk, et vältida juba olemasolevate objektide saatmist. Nende vastuste loomine kulutab protsessoriaega ja ketta sisend-väljundressurssi, mistõttu on suure hulga lugejate teenindamine keeruline.
Pando kasutab selle asemel kirjutamise skaleerimiseks leebemat kooskõlamudelit (põhjuslikku kooskõla) ning lugemise skaleerimiseks pakifailide taaskasutust.
Kui klient lükkab muudatused harusse üles, salvestab Pando saabuva pakifaili muutumatu bloobina bloobihoidlasse. Iga kord, kui haru tipp muutub, salvestab Pando metaandmehoidlasse viidaversiooni, mis sisaldab uut tippu, seda sisaldavat pakki ja kõiki varasemaid viidaversioone, millest pakk sõltub. Nii bloobihoidla kui ka metaandmehoidla on horisontaalselt skaleeritavad.
Sissekande või viida toomiseks Pandost tuleb kliendile edastada viidaversioonide kogum (pakifailid), taastades nii selle kliendi oleku, mis lõi toodava viidaversiooni. See tagab kogu varamu ulatuses nõrgema kooskõla, kuid üksikute viitade uuendused on serialiseeritavad. Klientide vahel tekib konflikt ainult siis, kui nad lükkavad muudatusi samaaegselt üles samale viidale. Mitut haru lugev klient ei saa eeldada, et loetud andmed kirjeldavad kogu varamu sama ajahetke.
Põhiharusse üleslükkamine lisab juurdekasvupaki, mis sisaldab üht või mitut sissekannet. Iga kõrvalharusse üleslükkamine sisaldab uuesti teemaharu varasemaid sissekandeid, et klient, millel on väljakuulutatud põhiharu versioon, saaks teemaharu tuua ühe pakina.
See on üks põhjusliku kooskõla vorme. Viida toomiseks näeb lugeja selle loonud kirjutaja ajalugu. Üleslükkamise ajal määrab Pando, millises ühises ajaloos klient ja server kokku lepivad, et kliendid looksid hõlpsamini jagatavaid pakifaile.
Seetõttu ei paku Pando Giti toimingute ajal kõigi viitade ühist hetkeseisu ega taga kloonimise või toomise käigus viidauuenduste ühist järjestust. Oletame näiteks, et täieliku kloonimise läbirääkimisfaasis uuendatakse nii haru foo kui ka haru bar. Läbirääkimiste ajal võib üks klient näha haru foo versiooni 1 ja haru bar versiooni 2, teine aga haru foo versiooni 2 ja haru bar versiooni 1. Praktikas ei sõltu kasutajad ega agendid viidauuenduste globaalsest järjestusest, vaid ühe viida uuenduste järjekorrast.
Selles kolme kooskõlamudeli simulatsioonis seadistame 1000 klienti nii, et igaüks valib eraldi haru ja lükkab sinna korduvalt üles kordumatuid sissekandeid. Mõõdame tegelikku kogukestust ning viivitust üleslükkamisest toomiseni. Viimane on töökoormuste jaoks oluline mõõdik, sest näitab, kui kaua kulub kasutajatel ja agentidel koostööks või versioonihaldusel põhinevate teiste süsteemide kasutamiseks vajalikule päringu-vastuse tsüklile. Simulatsioon modelleerib eri võimekusega riistvara, alates tavalistest kuni tippklassi virtuaalmasinate ja bloobihoidlateni. Selles simulatsioonis oleme kolmefaasilise kinnitamise puhul varamuülese kooskõla nõuet leevendanud.
Simulating Git Server Implementations
Follow each writer through repeated pushes, and separately measure when an independent reader can check out each commit.
Käivita simulatsioon, mis võrdleb Pandot kahe teise lähenemisviisiga. Vali taristu tavalisest kuni tippklassi riistvarani, määra klientide arv ja muud sätted ning vaata tulemuste võrdlust.
Modelleeritud kolmefaasilise kinnitamise süsteemis kasvab kirjutamise viivitus koormuse all märgatavalt, kui ketaste jõudluspiir saabub. Eellogimisel põhinevates süsteemides suureneb samal põhjusel oluliselt lugemise viivitus, sest serverid ei jõua logist piisavalt kiiresti lugeda. Nii meie monovaramu tegelikes katsetes kui ka selles simulatsioonis toetab Pando tuhandeid samaaegselt üleslükkavaid kliente, ilma et jõudlus koormuse all halveneks.
Üleslükkamist töödeldes valideerib Pando saabuvat pakifaili selle bloobihoidlasse voogedastamise ajal, pakkimata seda kohalikku varamusse lahti. Kui klient alustab toomist, valib Pando välja lugejale vajalikud salvestatud pakid ning lugeja laadib need alla. Ükski server ei pea rakendama pakifaile kohalikule varamule ega tegema kulukaid lahtipakkimis- ja pakkimistoiminguid. Kuna Pando serverid tegelevad peamiselt läbirääkimiste ja pakifailide valikuga, saavad need töötada tavalisel riistvaral.
See võimaldab Pandol skaleeruda klientide, klientide ja Pando vahelise võrgu ning bloobihoidla teenuse võimekuse piirini. Piisava võimsuse korral saab iga sõltumatul harul töötav klient pakke edastada nii kiiresti, kui tema ühendus võimaldab. Rohkemate klientide sama kiireks teenindamiseks saame lisada Pando servereid ning suurendada koos nendega metaandmehoidla ja bloobihoidla võimsust.
Pushing and Fetching a Branch in Pando
Pando stores the writer’s packfile in blob storage and records the ref version in metadata service. On fetch, Pando selects the packs the reader needs, and Express serves them.
Agent muudab faile, loob kohaliku sissekande ja käivitab käsu git push, mis loob nendest muudatustest haru uuendamiseks pakifaili. Pando võtab paki vastu ja voogedastab selle bloobihoidlasse. Pärast saabuva üleslükkamise valideerimist ühe läbimisega dekodeerimise abil salvestab Pando mitut võtit hõlmava tehinguga meie metaandmehoidlasse viidaversiooni ja uuendab atomaarselt viida osutit. Nii saab Pando tagada kooskõla põhimõttel „loe enda kirjutatut“. Kogu see kirjutamistoiming nõuab metaandmete lugemist ja kirjutamist.
Kui teine klient toob haru, valib Pando salvestatud pakkide kogumi kliendil juba olemasoleva ajaloo põhjal. See toiming nõuab metaandmete lugemist, kus on lühim vahemaa viidaversioonides kliendil olemasoleva ja tema soovitu vahel. Server tagastab pakifailide URI-d ning klient laadib failid alla teenuse Express kaudu, mis hoiab pakifaile piirkondlikes vahemäludes.
See lahendus toetub Pando arhitektuuri kolmele kesksele teenusele: üleslükkamine, toomine ja tihendamine.
Kui klient lükkab muudatusi üles, käitub tavapärane Giti server nagu pokkerimängija, kes näitab kõiki oma kaarte, paljastades kliendile iga olemasoleva haru. Seejärel kogub klient sissekanded, puud ja bloobid kokku ning loob pakifaili, millest jäetakse välja objektid, mis teadaolevalt on serveril juba olemas.
Rohkemate viitade väljakuulutamine võib üleslükatavate andmete mahtu vähendada. Samas võib see raskendada paki taaskasutamist, sest teisel kliendil võivad kirjutaja välja jäetud objektid puududa.
Pando läheneb asjale teisiti. Kõigi kaartide näitamise asemel kuulutab see kliendile välja ainult valitud harud. Sellel on kaks põhjust:
Kõigist viitadest kooskõlalise vaate pakkumine on kulukas. Miljonite harude korral võib ainuüksi viitade väljakuulutamise maht ületada 100 MiB. Selleks peab iga server kas hoidma ajakohast vastendust, millega kaasneb märkimisväärne koordineerimiskulu, või tegema andmebaasipäringu, mille maht kasvab koos viitade arvuga.
Kui kliendile antakse ainult osa viitadest, loob ta paki, mis sõltub üksnes sellest, mida server on tal sõnaselgelt lubanud välja jätta. Sõltuvuste jälgimine võimaldab Pandol taaskasutada kliendi ühe üleslükkamise käigus loodud pakifaili hilisema toomise vastusena.
Mida rohkem viitu Giti server välja kuulutab, seda rohkem on üleslükkavatel klientidel allikaid, mille põhjal objekte välja jätta, ning seda väiksemaid pakke nad saavad luua. Nende pakifailide taaskasutamiseks peab server aga suutma tõendada, et toovatel klientidel on kõik sõltuvused olemas. Vastasel juhul võivad pakifailist puududa kliendile vajalikud objektid.
Kui Giti server ei kuuluta aga välja ühtegi viita, loob klient pakifaili, mis sisaldab varamu kogu ajalugu. Seda pakifaili saab kasutada iga teine klient, kuid sellel on suur hind: mis tahes haru toomine muutub sisuliselt täielikuks kloonimiseks.
Rohkemate viitade väljakuulutamine annab väiksemad pakifailid. Suurem osa mahu vähenemisest võib tulla juba üheainsa viida väljakuulutamisest.
Kui klient lükkab üles uue funktsiooniharu, kuulutab Pando vaikimisi alusena välja ainult määratud põhiharu. Nii jääb väljakuulutuse maht harude lisandumisel samaks, kuid sellega kaasnevad kompromissid. Kui arendaja lükkab korduvalt üles samasse harusse või loob ühe funktsiooniharu teise peale, peab klient kõik põhiharust väljapoole jääva uuesti saatma.
Seetõttu on järjestikused haru üleslükkamised suuremad, võivad sisaldada korduvaid objekte ja kulutavad kliendi ribalaiust rohkem. Meie monovaramus oli sel viisil loodud pakifaili mediaansuurus alla 20 KiB ja 99. protsentiil alla 3 MiB. Meie jaoks oli see mõistlik kompromiss, sest lugeja, kellel on väljakuulutatud põhiharu ajalugu juba olemas, saab haru tuua selle ühe pakifailiga.
Pärast kliendile väljakuulutatavate viitade valimist võtab Pando üleslükkamise vastu ja uuendab oma metaandmehoidlat. Pando jagab metaandmete uuendamise sünkroonseks ja asünkroonseks osaks. Sünkroonne metaandmete uuendus tagab, et kliendid saavad äsja uuendatud sissekande kohe tuua. Selle käigus kirjutatakse uus viidaversioon ja suunatakse viida osuti sellele. Salvestatakse uus tipp, pakifaili läbirääkimistel kasutatud sõltuvused ja link üleslükatud pakifailile.
Sama tehinguga registreeritakse ka asünkroonsed tööd, näiteks tihendamise ajastamine. Väga suurte üleslükkamiste korral kirjutatakse sünkroonselt ainult osa sissekannetest. Nii piisab metaandmehoidlas konstantsest arvust lugemistest ja kirjutamistest, olenemata üleslükkamise mahust.
Oluline on, et Pando serverid saavad omavahel mitteseotud viitadele tehtavaid üleslükkamisi vastu võtta sõltumatult. Ainus võti, mille pärast konkureeritakse, on viida osuti. Seda kaitseme atomaarse võrdle-ja-vaheta-laadse toiminguga. Kirjutamise läbilaset saame suurendada Pando serverite, metaandmehoidla skaleerimisüksuste või bloobihoidlate lisamisega.
Toomisel annab klient serverile kaks sissekannete ID-de hulka, mida protokollis tähistavad have ja want. Tavapärane Giti server arvutab soovitud sissekannetest kättesaadavate objektide ja olemasolevatest sissekannetest kättesaadavate objektide hulkade vahe, pakib need objektid kokku ja saadab tulemuse kliendile. Kuigi avatud lähtekoodiga Giti serveril on selle toimingu kiirendamiseks mitmesuguseid kohalikke indekseid, võib nende pakifailide arvutamine olla kulukas ja neid on üldiselt raske vahemälus taaskasutada.
Pando kasutab selle asemel üleslükkamistel salvestatud sissekannete vastendusi, et leida kliendi have ja want väärtustele vastavad viidaversioonid, mis neid sissekandeid sisaldavad. Iga selline viidaversioon viitab Pandosse varem saabunud pakifailile. Server määrab selle põhjal kliendi vajadused ja valib pakifailid, mis katavad vajalike objektide hulga.
Planning fetches in Pando
Pando compares what a client has with what it wants, then selects the stored packfiles needed—including any missing branch dependencies.
Fetch 27 trunk packs.
Select a branch to include its trunk dependencies.
Pando seostab Giti protokolli olemasolevad ja soovitud sissekanded viidaversioonide jadaga. Kõrvalharu soovimine tähendab ka selle sõltuvuste soovimist kuni põhiharuni.
Giti protokoll lubab kloonimise või toomise HTTP-vastuses saata ainult ühe pakifaili. Giti protokolli vähetuntud võimalus packfile-uri lubab aga serveril tagastada linke lisapakkide eraldi allalaadimiseks. Pando kasutab üksnes seda võimalust ning saadab vastuse sees tühja pakifaili. Selle võimaluse toetamiseks andis OpenAI Giti põhiprojekti mitu packfile-uri täiustust.
OpenAI süsteemid töötavad paljudes geograafilistes piirkondades, mistõttu hoiame igas neist kohalike vahemäludega Pando klastreid. Pakkide edastamise teenus Express hoiab vahemälus meie bloobihoidla andmeid, eraldi teenus aga metaandmehoidla andmeid. Nende vahemälude abil saab Pando vastata sissekande ID päringutele või viida spetsiaalsetele lugemispäringutele täielikult vastava klastri vahemällu salvestatud oleku põhjal. Kasutame pakifailipäringute suunamiseks Expressi serveritesse järjepidevat räsimist ning vahemälu tabamusmäär ületab 99%.
See vahemälusüsteem tagab äärmiselt suure läbilaske, mis suudab täielikult ära kasutada klientide ja Pando vahelise võrgu läbilaskevõime. Oleme kinnitanud, et nende pakifaili URI-de ja kohalike vahemäludega kasutavad kloonimine ja toomine täielikult ära 10 Gbit/s võrguühendused, töötades üksnes pilveteenuse pakkuja tavalistel virtuaalmasinatel.
Enamik Giti servereid vajab kasvava varamu jõudluse säilitamiseks ümberpakkimist ja prügikoristust. Mõlemad vabastavad ruumi, kuid nõuavad palju arvutus- ning sisend-väljundressurssi.
Kiiresti muutuvas varamus, nagu OpenAI monovaramu, pole otstarbekas saata eraldi pakifaili URI-d iga üleslükkamise kohta, mis on toimunud pärast viimast toomist. Põhiharu ajakohastamiseks peaks klient iga päev alla laadima kümneid tuhandeid pakifaile.
Selle asemel ühendab Pando pakke taustal, et lisakulu vähendada, kasutades logistruktuursete liitmispuude tihendamisega sarnast lahendust. Iga üleslükkamine loob pakifaili, mida Pando nimetab „L0“-ks. See on väikseim andmeühik, mida Pando saab edastada. Aja jooksul koondavad taustatöötlused need pakifailid viidaversioonide jadasid katvateks kogumiteks, mille ulatus kasvab L0-st alates geomeetriliselt. Praegu kasutab meie monovaramu kuni L4 taseme pakifailikogumeid.
Neil kogumitel on kaks eesmärki. Kui kogum on piisavalt täis, võtab tihendustöötlus selle ette ja loob ühe pakifaili. Objektide ümberkorraldamine pakifailis parandab tihendussuhet. Ühtlasi kiirendab see toomise läbirääkimisi, toimides viidaversioonide üle hüppeloendina. Kõigi tasemete indekseid samaaegselt läbi vaadates saab Pando valida kliendile saadetavate pakkide kogumi logaritmilise ajaga. Need pakifailikogumid võimaldavad toomist tõhusamalt kavandada olenemata sellest, kas need on ümber pakitud või mitte, vähendades Pandole esitatavaid läbilaske- ja viivitusnõudeid.
Compaction in Pando
Small packfiles are grouped into larger covers across levels, improving compression and speeding up fetches.
Tihendamine ühendab taustal paljude viidaversioonide pakifaile, võimaldades tõhusamat toomist väiksema failide arvuga.
Erinevalt paljudest Giti serveritest säilitatakse pakifailid igal tasemel: neid ei hüljata ega eemaldata prügikoristusega. Kõigi tasemete pakke kasutatakse pidevalt klientide teenindamiseks, lähtudes toomisel esitatud have ja want väärtustest. Pando API-t kasutavatel klientidel nõuab suvalise objekti lugemine pakifailist tavaliselt vähem andmete lugemist L0 kui L4 tasemelt, sest seal on objekt väiksema tõenäosusega tihendatud.
Pando tihendamine vähendab märgatavalt klientidele edastatavate andmete kogumahtu ning võimaldab pakkide kavandamise kulul kasvada aeglasemalt kui lineaarselt võrreldes sellega, kui palju klient on ajaloost maha jäänud. See on eriti oluline suurte ja kiiresti muutuvate varamute puhul, mis saavad meie hinnangul tarkvaraarenduses uueks normiks.
Lõime Pando Codexi abil, jõudes projekti algusest tootmiskeskkonda kõigest kümne nädalaga. Pando tuuma kavandas üks arendaja, teostasid agentide meeskonnad ja juurutas käputäis arendajaid. Pando hakkas tootmiskeskkonna liiklust teenindama selle aasta aprillis ning on üks osa OpenAI-s kasutatavast laiemast versioonihalduse tööriistade süsteemist.
Kasutasime Pando lahenduse valideerimiseks paljusid eri lähenemisviise. Rakendasime oma turvalisemate tarkvaraaluste loomise põhimõtteid. Kuna alustasime puhtalt lehelt, otsustasime Pando kirjutada Rustis ja vältida pärandsõltuvusi. Kirjutasime vastavustestide komplekti, et agendid saaksid kontrollida oma muudatusi Giti standardse käitumise suhtes. Arendasime ka deterministlike simulatsioonitestide täitmiskeskkonnad süsteemi invariantide ja omaduste kontrollimiseks. Nende abil saime leida ja leevendada raskesti märgatavaid võistlusolukordi ning regressioone läbirääkimistes ja pakkide kavandamises.
Süsteemi loomisse panustasid paljud mudelid. Uute mudelite lisandudes kasutasime neid Pando jõudluse ja töökindluse parandamiseks. GPT‑6 Astra abil kirjutasid agendid Leanis ja TLA+-is „Pando teooria“ formaliseeringu, millega leidsime ja parandasime teostusvigu ning tõestasime süsteemi omadusi. Mitu katkematut seanssi kestis sadu tunde, otsides ja parandades Pando piirjuhtumeid. Lisaks laseme agentidel ööpäev läbi Giti ja Pando turvalisust ründetestidega proovile panna, kasutades Daybreaki võimekusega mudeleid.
Esialgu juurutasime Pando olemasoleva versioonihaldussüsteemi lugemis- ja kirjutamispäringuid läbiva puhverserverina. See võimaldas hoida Pando ja eelmise süsteemi sünkroonis, nii et saime liikluse turvaliselt ja seisakuteta Pandole üle viia.
Pando vahemälulahendus võimaldab enne päringute vahendamist ka duplikaate eemaldada ja päringuid ühendada. Nii saime süsteeme ükshaaval Pandole üle viies hoida olemasolevad tööriistad töökorras. Mida rohkem töökoormusi Pandole üle viisime, seda enam täitsid nende üleslükkamised Pando vahemälu ja parandasid meie eelmise tagasüsteemi töökindlust.
Pando kasutamise jõudluse optimeerimiseks hakkasime levitama oma avalikku Giti distributsiooni arendajate arvutitesse ja ChatGPT töölauarakenduse koosseisus. Klientide etapiviisiliseks üleviimiseks Pandole kasutasime Giti käsurealiidese ümber loodud sisemist ümbrist. Lõime veel palju tööriistu muudatustaotluste ja koodiülevaatuste haldamiseks ning API-sid automatiseerimiseks. Koos Giti liiklusega viisime üle sadu integratsioone, mis sõltusid pärand-API-dest, veebihaakidest ja varamute allalaadimisest.
Ka Codex ise aitas arendajatel ja meeskondadel üle minna. Lõime oskused olemasolevate töökoopiate ettevalmistamiseks ja agentide juhendamiseks uue süsteemi kasutamisel. Nii said arendajad lihtsalt paluda Codexil oma arenduskeskkonnad ja teenused üle viia.
Pandole üleminek parandas ühendamiste töökindlust ja vähendas üleslükkamise mediaanviivitust ligi 80%.
Pando suudab vaid käputäie protsessorituumadega edastada päevas petabaidi Giti andmeid. Pando on ühe tunni jooksul edastanud üle 57 terabaidi Giti pakke, kusjuures üle 99% neist baitidest pärines kohalikust kettavahemälust.
Pakkide taaskasutamine võimaldab paljudel klientidel laadida alla sama varamu ajaloo, nõudes teenindavatelt sõlmedelt vähe arvutustööd. See näide puudutab üht varamut, kuid Pando on loodud toetama palju rohkemaid. Nõudluse kasvades saame andmete edastamist ja Giti läbirääkimisi skaleerida teineteisest sõltumatult.
Pando rajamine Giti protokollile ja kliendile aitas meil leida vigu ning võimalusi Giti enda jõudluse parandamiseks.
Näiteks edastab Pando taaskasutatavaid pakke otse klientidele, mistõttu sai nende allalaadimisest ja indekseerimisest süsteemi kiiruse ning töökindluse keskne osa. See töö tõi esile piirjuhtumeid samaaegsetes allalaadimistes, katkestatud edastuste järel koristamises ja juba lõppenud allalaadimiste jätkamises. Parandasime need kooditeed, lisasime olemasoleva paki toomisel vastuvõtmise kontrollid ja andsime selle töö tagasi põhiprojekti.
Pidime ka nägema, kuhu kuluvad aeg ja ribalaius. Seetõttu lisasime packfile-uri allalaadimiste jälituse ning pakkide loomise baidiloendurid, et oleks lihtsam eristada, kas aeglane toomine kulutab aega pakkide loomisele või edastamisele.
OpenAI Giti versioonis(avaneb uues aknas) saab klient sõltumatuid pakke paralleelselt alla laadida ja indekseerida. Lisasime „sõnaselgelt määratud olemasolevate sissekannete“ mõiste, et server saaks haru praeguse tipu välja kuulutada eraldi ajaloost, mille üleslükkav klient võib oma pakist välja jätta. Pandoga saavad kliendid kasutada suvandit --force-with-lease, et kontrollida, kas funktsiooniharu tipp on püsinud muutumatuna, ja koostada paki ainult põhiharu alusel. Igaüks, kellel on see põhiharu ajalugu olemas, saab seejärel haru sama paki abil tuua.
Mitu neist täiustustest on juba Giti põhiprojektis ja paljud teised meie avalikus varamus. Jätkame koostööd Giti kogukonnaga, et neist täiustustest oleks kasu ka väljaspool Pandot. Seda tööd saad jälgida meie avalikus paikade jälgijas(avaneb uues aknas).
Giti varamute skaleerimise tavapäraseid arusaamu ümber mõtestades võimaldab Pando meil oma monovaramut kasvatada, muutmata Giti töövooge, mida meie arendajad ja agendid juba kasutavad. Pando on võimaldanud meie monovaramus rohkem paralleelset tööd, parandanud ühendamiste töökindlust ja lühendanud koodimuudatuste avaldamiseks kuluvat aega. Lisaks monovaramule uurime Pandole OpenAI sees ka muid kasutusvõimalusi, sealhulgas töökoormusi, kus suur hulk agente peab ühises Giti varamus koostööd tegema.
Kui arendajad ja agendid loovad üha rohkem tarkvara, jõuavad ka paljud OpenAI-välised meeskonnad samade versioonihalduse piiranguteni, millega meie kokku puutusime. Uurime praegu võimalusi, kuidas jagada Pando aluseks olevat tehnoloogiat oma kasutajatega.
Pando toetub Giti varamute kasutajate ja haldajate kahe aastakümne pikkusele kogemusele. Jätkame Pando arendamist ning teeme koostööd Giti avatud lähtekoodi kogukonnaga, et jagada täiustusi, millest on kasu Giti kasutajatele laiemalt.


