Ray for Den Nysgjerrige

Dean Wampler

Følg

19. Des · 2019 * 10 min lese

(Forbedringer, februar 8, 2020)

TL; DR Ray ER et system for skalering Python-programmer på tvers beregne klynger med minimal innsats. Dette innlegget forklarer problemene Ray løser og hvordan du bruker Det.

Ray-Prosjektet Lokalt,
Ray-Prosjektet, tilgjengelig på https://ray.io

Ray (nettsted, GitHub) er et åpen kildekode-system for skalering Av Python-applikasjoner fra enkeltmaskiner til store klynger. Dens design er drevet av de unike behovene til NESTE generasjons ML / AI-systemer, som står overfor flere unike utfordringer, inkludert ulike beregningsmønstre, styring av distribuert, utviklende tilstand og ønsket om å møte alle disse behovene med minimal programmeringsinnsats.

Typiske ML/AI-systemer krever ulike beregningsmønstre for å støtte datarensing og forberedelse, hyperparameterjustering, modellopplæring og servering og andre oppgaver. Den opprinnelige MapReduce-modellen for big data-arbeidsbelastninger fungerer godt for datarensing, forberedelse og også for analysearbeidsbelastninger, men maskinlæringsarbeidsbelastninger krever en blanding av finkornet til grovkornet oppgaver, sammen med varierte kommunikasjonsmønstre mellom komponenter. Hyperparameter tuning og modell trening er svært beregningsintensiv, krever cluster ressurser til å fullføre i rimelig tidsrammer. Ray gir grunnlaget for å bygge MODERNE ML / AI-systemer og applikasjoner ved å tilfredsstille disse ulike kravene på en effektiv MÅTE, med en minimal OG intuitiv API.

en annen utfordring er distribuert, utviklende tilstand. I FORBINDELSE MED ML/AI inkluderer distribuert tilstand hyperparametrene, modellparametrene (f.eks. og for forsterkende læringsscenarier, tilstanden til simuleringer (eller samspill med den virkelige verden) som brukes til trening. Ofte er staten foranderlig, spesielt under trening, så forsiktig, samtidighet-sikre oppdateringer kreves. En mulig måte å håndtere distribuert databehandling på er å utnytte populære» serverløse » systemer, men ingen tilbyr for tiden fasiliteter for å håndtere distribuert, foranderlig tilstand. Utviklere må ty til å holde all stat i en database når de bruker serveless systemer, men databasen kan være en flaskehals og et enkelt feilpunkt.

I Stedet Bruker Ray Den populære Skuespillermodellen til å gi en intuitiv mekanisme for statlig styring. Ray skuespillere gi en stateful supplement Til Ray oppgaver, som er statsløse. Denne tilstanden er transparent tilgjengelig for Enhver Annen Ray-skuespiller eller oppgave gjennom en referanse til det tilsvarende Python-objektet (dvs.en forekomst av En Python-klasse). Ray holder styr på hvor skuespilleren befinner seg i klyngen, eliminerer behovet for å eksplisitt vite og administrere slike steder i brukerkode. Mutasjon av staten i skuespilleren håndteres på en trådsikker måte, uten behov for eksplisitte samtidighet primitiver. Derfor Gir Ray intuitiv, distribuert tilstandsstyring for applikasjoner, noe som betyr At Ray kan være en utmerket plattform for å implementere stateful serverløse applikasjoner generelt. Videre, når du kommuniserer mellom aktører eller oppgaver på samme maskin, staten er transparent forvaltes gjennom delt minne, med null-kopi serialisering mellom aktører og oppgaver, for optimal ytelse.

til Slutt, Fordi DE FLESTE ML/AI-systemer Er Python-baserte, trenger utviklere en måte å legge til disse skaleringsfunksjonene med minimal kodeendringer. En dekoratør, @ray.remote, markerer funksjoner og klasser som logiske enheter som kan startes og utføres i en klynge. Ray håndterer tråd-sikker mutasjon av staten, fordeling av staten, og intuitiv planlegging av avhengige oppgaver.

Ray-distribusjonen inneholder flere høyytelsesbiblioteker rettet MOT AI-applikasjoner, som også motiverte problemer som kjørte Etableringen Av Ray. De inkluderer RLlib for forsterkning læring og Tune for hyperparameter tuning. Begge demonstrerer Rays unike evner. Disse bibliotekene og andre, tilpassede programmer skrevet Med Ray er allerede brukt i mange produksjonsdistribusjoner.

Ray Er et åpen kildekode-prosjekt startet I Uc Berkeley RISELab. Det er nå utviklet På Anyscale med store bidrag fra mange andre organisasjoner. Kommersielle Brukere av Ray inkluderer Ant Financial, Jp Morgan, Intel, Microsoft, Ericsson, Skymind, Primer og mange andre.

Et Eksempel På Core Ray API

Merk: den fullstendige listen over følgende kodeeksempel finner du på slutten av dette innlegget.

Nå som vi forstår motivasjonene Og fordelene Med Ray, la oss undersøke hvordan Du vil bruke Ray API i programmene dine. Deretter ser vi nærmere på hvordan Ray forbedrer ytelsen gjennom parallellisering og distribusjon. Ray API er nøye utformet slik at brukerne kan skalere sine applikasjoner, selv på tvers av en klynge, med minimale kodeendringer.

Vurder eksemplet på en parameterserver, som er en nøkkelverdilager som brukes til å trene maskinlæringsmodeller i en klynge. Verdiene er parametrene til en maskinlæringsmodell (f. eks., et nevralt nettverk). Tastene indekserer modellparametrene. Hvis du ikke er kjent med parameterservere, kan du tenke på hvilken som helst frittstående tjeneste du trenger for å sende forespørsler om informasjon eller data.

i et system for filmanbefaling kan det for eksempel være en nøkkel per bruker og en nøkkel per film. For hver bruker og film er det tilsvarende brukerspesifikke og filmspesifikke parametere. I et språkmodelleringsprogram kan ord være nøklene, og deres innbygginger kan være verdiene.

i sin enkleste form kan en parameterserver ha en nokkel og tillate at alle parametrene hentes og oppdateres samtidig.

Her er et eksempel på en så enkel parameter server, for en enkelt NumPy rekke parametere. Det er implementert Som En Ray skuespiller i under 15 linjer med kode:

Import og definisjon Av ParameterServer actor

@ray.remote dekoratøren definerer en tjeneste. Det tar den vanlige Python-klassen, ParameterServer, og lar den bli instantiert som en ekstern tjeneste. Fordi forekomsten opprettholder tilstand (de nåværende parametrene, som er foranderlige), har vi en stateful tjeneste.

i dette eksemplet antar vi at en oppdatering til parametrene er gitt som en gradient som skal legges til gjeldende parametervektor. (Denne graderingen kan være et enkelt tall som legges til alle matriseelementer eller en rekke graderinger.) Mer sofistikerte design er mulig, selvfølgelig, Men Ray ville bli brukt på samme måte. Som en enkel øvelse, prøv å endre dette til en nøkkelverdi (ordbok) implementering.

en parameterserver finnes vanligvis som en ekstern prosess eller tjeneste. Klienter samhandler med det gjennom eksterne prosedyreanrop. For å instantiere parameterserveren som en ekstern skuespiller, gjør vi følgende trinn på den interaktive Python-prompten. (Vi antar at du allerede har definert klassen ParameterServer i samme økt). Først må Du starte Ray. Når du bruker en klynge, vil du sende valgfrie parametere til init() – metoden for å angi klyngeplasseringen:

Python interaktiv økt: start Ray

deretter oppretter du en ParameterServer forekomst for en rekke 10 parametere:

Konstruer En ParameterServer actor instance

I Stedet for å ringe ParameterServer(10) for å konstruere en forekomst, slik du ville gjort for en vanlig Python-forekomst, bruker du metoden remote() i stedet, som ble lagt til klassen av @ray.remote dekoratøren. Du passerer de samme argumentene du vil passere til den vanlige konstruktøren. Legg merke til at et skuespillerobjekt er konstruert.

på Samme måte, for å påkalle metoder på skuespilleren, bruker du remote() lagt til det opprinnelige metodenavnet, og sender de samme argumentene du vil passere til den opprinnelige metoden:

Kaller en ekstern metode

Actor method invocations retur Futures. For å hente de faktiske verdiene bruker vi blokkeringen ray.get(id) :

Hent verdier med ray.get (id))

som vi forventer, er de første parameterverdiene alle nuller. Hva ray.get(id) faktisk gjør er å trekke verdien ut av distributed state store-tjenesten Som Ray gir. Verdien ble skrevet til distributed state store av skuespilleren da den oppdaterte sin tilstand. Hvis verdien og klienten er begge pa samme maskin, trekkes verdien fra delt minne for rask ytelse. Hvis verdien og klienten er bosatt på forskjellige maskiner, blir verdien trukket over til maskinen som trenger den.

for fullstendighet kan koden din også skrive verdier eksplisitt til denne lagringen ved hjelp av ray.put(id, value). Når du vil hente flere verdier etter hvert som de blir tilgjengelige, er det en praktisk ray.wait(…) – funksjon tilgjengelig. Se Ray API for mer informasjon.

etter skuespillermodellen, når klienter påkaller disse skuespillermetodene, blir påkallingene rutet til skuespillerinstansen, uansett hvor den befinner seg i klyngen. Siden samtidige påkallinger kan forekomme, Sikrer Ray at hver påkalling behandles på en trådsikker måte, slik at risikoen for å ødelegge tilstanden forhindres uten behov for eksplisitt trådsynkroniseringskode. Dette pålegger imidlertid ikke noen form for global bestilling av når disse påkallingene behandles; det er først til mølla.

Notat: På grunn Av Pythons dynamiske natur, ville Det vært mulig For Ray å tillate deg å ringe skuespilleren metoder uten remote(), men det ble bestemt at den eksplisitte kodeendringen er nyttig dokumentasjon for leserne av koden, siden det er viktige ytelsesimplikasjoner når du bytter fra en lokal metodekall til EN RPC-lignende påkalling. Også det returnerte objektet er nå annerledes, en fremtid, som krever bruk av blokkeringsanropet, ray.get(), for å trekke ut verdien.

anta nå at vi vil kjøre flere arbeidsoppgaver som kontinuerlig beregner gradienter og oppdaterer modellparametrene. Hver arbeidstaker vil kjøre i en løkke som gjør følgende tre ting:

  1. Få de nyeste parametrene.
  2. Beregn en oppdatering til parametrene.
  3. Oppdater parametrene.

disse arbeiderne vil være statsløse, så vi bruker En Ray-oppgave (en ekstern funksjon) i stedet for en skuespiller. Funksjonen worker tar et håndtak til parameterserverskuespilleren som et argument, som gjør at arbeideroppgaven kan aktivere metoder på parameterserveren:

Definer en ekstern arbeider som utfører parameteroppdateringer

så kan vi starte to av disse arbeidsoppgavene som følger. Ray oppgaver (funksjoner) startes med samme remote() påkalling:

Bruk to oppgaver til å beregne parameteroppdateringer samtidig

da kan vi hente parametrene fra driverprosessen gjentatte ganger og se at de oppdateres av arbeiderne:

Gjenta spørringer for gjeldende parameterverdier

når oppdateringene stopper, blir de endelige verdiene 200.

Merk At Ray gjør Det like enkelt å starte opp en ekstern tjeneste eller skuespiller som det er å definere En Python-klasse. Håndtak til skuespilleren kan sendes rundt til andre aktører og oppgaver for å tillate vilkårlige og intuitive meldinger og kommunikasjonsmønstre. Nåværende alternativer er mye mer involvert. Tenk for eksempel på hvordan tilsvarende kjøretidsopprettelse og tjenestehåndtering vil bli gjort MED GRPC, som i denne dokumentasjonen.

Samlende Oppgaver Og Skuespillere

vi har sett at oppgaver og skuespillere bruker Samme Ray API og brukes på samme måte. Denne samlingen av parallelle oppgaver og aktører har viktige fordeler, både for å forenkle Bruken Av Ray og for å bygge kraftige applikasjoner gjennom komposisjon.

til sammenligning tillater populære databehandlingssystemer Som Apache Hadoop og Apache Spark statsløse oppgaver (funksjoner uten bivirkninger) å operere på uforanderlige data. Denne antagelsen forenkler den generelle systemdesignen og gjør det lettere for applikasjoner å begrunne om korrekthet.

delt foranderlig tilstand er imidlertid vanlig i maskinlæringsprogrammer. Denne tilstanden kan være vektene i et nevralt nettverk, tilstanden til en tredjeparts simulator eller en representasjon av samspill med den fysiske verden. Rays skuespiller abstraksjon gir en intuitiv måte å definere og administrere foranderlig tilstand på en trådsikker måte.

Det som gjør Dette spesielt kraftig, er Måten Ray forener skuespillerens abstraksjon med oppgaven-parallell abstraksjon som arver fordelene ved begge tilnærmingene. Ray bruker en underliggende dynamisk oppgavegraf for å implementere både aktører og statsløse oppgaver i samme rammeverk. Som en konsekvens er disse to abstraksjonene helt interoperable. Oppgaver og skuespillere kan opprettes fra andre oppgaver og skuespillere. Begge retur futures, som kan overføres til andre oppgaver eller aktørmetoder for å introdusere planlegging og dataavhengigheter på en naturlig måte. Som et resultat arver Ray-applikasjoner de beste funksjonene til både oppgaver og skuespillere.

Her er noen av kjernekonseptene som brukes internt Av Ray:

Dynamiske Oppgavegrafer: Når du bruker en ekstern funksjon eller skuespiller-metode, legges oppgaver til en dynamisk voksende graf, som Ray planlegger og utfører på tvers av en klynge (eller en enkelt multi-core maskin). Oppgaver kan opprettes av» driver » – programmet eller av andre oppgaver.

Data: Ray serialiserer data effektivt ved Hjelp Av Apache-Pilens dataoppsett. Objekter deles mellom arbeidere og skuespillere på samme maskin gjennom delt minne, noe som unngår behovet for kopier eller deserialisering. Denne optimaliseringen er helt avgjørende for å oppnå god ytelse.

Planlegging: Ray bruker en distribuert planlegging tilnærming. Hver maskin har sin egen planlegger, som styrer arbeiderne og skuespillerne på den maskinen. Oppgaver sendes av søknader og arbeidere til planleggeren på samme maskin. Derfra kan de tilordnes til andre arbeidere eller sendes til andre lokale planleggere. Dette gjør Det mulig For Ray å oppnå vesentlig høyere oppgavegjennomstrømning enn det som kan oppnås med en sentralisert planlegger, en potensiell flaskehals og et enkelt feilpunkt. Dette er viktig for mange maskinlæringsprogrammer.

Konklusjon

Systemer som parameterservere implementeres normalt og sendes som frittstående systemer med en ubehagelig mengde kode, som for det meste kan være standardtekst for håndtering av distribusjon, påkalling, statlig styring, etc. Vi har sett At Rays abstraksjoner og funksjoner gjør det mulig å eliminere det meste av det boilerplate. Derfor er noen funksjonsforbedringer relativt enkle og produktiviteten din maksimeres.

Mange av de felles tjenestene vi trenger i dagens produksjonsmiljøer kan implementeres på denne måten, raskt og effektivt. Eksempler er logging, stream behandling, simulering, modell servering, graf behandling, og mange andre.

jeg håper du fant Denne korte introduksjonen Til Ray spennende. Vennligst gi det et forsøk og la meg vite hva du synes!

For Å Lære Mer

for mer informasjon Om Ray, ta en titt på følgende lenker:

  • Ray website
  • Ray GitHub page
  • Ray dokumentasjon: destinasjonsside, installasjonsinstruksjoner
  • Ray tutorials
  • en forskningsartikkel som beskriver Ray system i detalj
  • en forskningsartikkel som beskriver fleksible primitiver internt Til Ray for dyp læring
  • rask serialisering med ray og apache arrow
  • rllib: skalerbar Forsterkning Læring Med Ray (og dette rllib forskning papir)
  • tune: effektiv hyperparameter tuning med ray
  • modin: påskynde pandaer med ray
  • flow: et beregningsrammeverk som bruker forsterkningslæring for trafikkontrollmodellering
  • Anyscale: selskapet bak Ray

Spørsmål skal rettes til Ray Discourse eller Ray Slack-arbeidsområdet.

Tillegg: Kjøre Koden

for å kjøre hele programmet, må Du først installere Ray med pip install ray (eller se Ray installasjonsinstruksjonene). Kjør deretter følgende kode med Python. Den implementerer parameterserveren som diskutert tidligere, men legger til sharding av parametrene i arbeiderne. Du kan også finne en mer omfattende versjon av dette eksemplet som En Jupyter notatbok her.

Merk at dette eksemplet fokuserer på enkelhet og at mer kan gjøres for å optimalisere denne koden.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.