Nvidia gav mig en data science-arbejdsstation til 100.000 kr.: Her er hvad jeg gjorde med den

At genskabe et stort PubMed litteratur-søgeprojekt på en WhisperStation på et par timer i stedet for uger.
Brødtekst

Da NVIDIA spurgte, om jeg kunne tænke mig at prøve en af deres datavidenskabsarbejdsstationer, var jeg spændt, men en tanke fulgte med denne følelse: Hvad skal jeg dog bruge denne til?

Som en maksinlærings-ingeniør arbejder jeg med en masse deep-learning, men jeg helt sikkert ikke en forsker hos Google Brain. Jeg kunne køre bench-marking-tests, time jobs osv. men jeg arbejder ikke hos Nvidia og ærlig talt, så lød det heller ikke så sjovt.

arbejdsstation
Illustration: Kyle Gallatin

Jeg blev ved med at give mig selv ideer og startede med at tænke over den sande værdi af en stærk regnekræfter for en data scientist. Godt udviklede GPU-regneevner kan føre til omkostningsbesparelser, low-latency serving og nem træning af store modeller, men hvad nu hvis jeg var mere interesseret i hurtige resultater.

Datavidenskab er et felt, der er velfunderet i eksperimentering. Med big data eller store modeller, antallet af gange videnskabsmand kan prøve forskellige konfigurationer eller parametre er begrænset uden enorme ressourcer. Alle kender til smerten af at starte en regneintensiv proces for kun at blive blændet af uforudsette fejl flere timer inde i processen. Så skal du rette fejlen og starte forfra.

Jeg tænkte tilbage på mit første datavidenskabs-projekt: en enorm, flersproget søgemaskine til medicinsk litteratur. Hvis jeg havde haft adgang til de regne og GPU biblioteker jeg har nu i 2020 tilbage 2017, hvad kunner jeg så have nået? Og hvor meget hurtigere vil jeg kunne nå det?

Og så prøvede jeg at svare på det sprøgsmål ved at bygge en PubMed-søgemaskine udelukkende ved at bruge GPU-ressourcer.

Projektet 

Det orginale projekt kom fra et hold i Kina, hvor der eksisterer en stor byrde for farmaceutiske virksomheder i at give non-branded medicinsk information til sundhedsprakisser. Holdet ville bygge et nyt søgeværketøj der skulle være:

  • multisproget
  • tilgængelig via flere forskellige kanaler (web/WeChat)
  • mulig at ændre (i stand til at indstille algoritme for optimale resultater)
  • low latency (for hutige søgeresultater)
  • big data (all PubMed abstracts - de sidste 10 år)
  • præcise (bedre resultater end PubMed

Mit job var at konstruere en løsning, der ville møde og støtte alle disse krav. Endvidere, vil denne løsning blive nødt til relativt hurtigt at kunne ændre igennem interationer, så vi hurtigt kan teste, evaluere og opdatere systemet baseret på input fra eksperter på emnet (SMEs).

Men som data scientist havde jeg et stort problem...

Dataen

Til dem der ikke kender PubMed, PubMed er en database af biomedicinsk litteratur med mere end 30 mio. citater. Mens alle ikke er fuld-tekst artikler ikke er åbne kilder, så har hver citering  et abstract. Al den informaiton er tilgængelig via en API eller i bulk download som XML-filer som uheldigt for mig er omkring 300GB spredt over tusinde af filer.

Når du har analyseret hver XML for at udtrække nyttige felter (titel, abstract, publikationsår osv.), Reduceres datastørrelsen til en størrelse, der er nærmere 25 GB. Dette er dog stadig ikke superhåndterbart lokalt. Som jeg sagde før, handler videnskab om eksperimentering - og det var jeg nødt til at gøre meget af. Som en noget ny data scientist (og en forfærdelig ingeniør) havde jeg dybest set én ressource: Python. Der var ingen 20-node Spark- eller Elasticsearch-klynger, der kom til min redning.

Men hvad nu hvis jeg havde én GPU eller to?

Arbejdsstationen

Arbejdsstationen WhisperStation som jeg blev givet adgang til af Microway & Nvidia har de følgende specifikationer:

  • Dual Intel Xeon 10-core CPUs
  • 192GB hukommelse
  • High-speed 1TB scratch drive
  • Dual NVIDIA Quadro RTX 6000 GPUs with NVLink
  • Præinstalleret og konfigureret med Python, Docker, RAPIDs og alle de andre machine learning bibloteker jeg skal bruge i dette projekt

Det som vi virkelig interesserer os for, er disse to sidste punkter. Som du sandsynligvis ved, er GPU-beregning enormt populær inden for datavidenskab. At køre arbejdsgange med GPU-biblioteker kan fremskynde koden efter størrelsesordrer - hvilket kan betyde timer i stedet for uger med hvert eksperiment, der køres.

Hvis du nogensinde har oprettet et datavidenskabsmiljø fra bunden af, ved du, at det virkelig kan sutte. Har Docker, RAPID'er, tensorflow, pytorch og alt andet installeret og konfigureret out-of-the-box gemte timer i opsætningstiden.

Indtil for nylig blev GPU'er mest brugt til dyb læring i datavidenskab. For ikke så længe siden frigav Nvidia imidlertid RAPIDS - et generelt videnskabeligt datavidenskabsbibliotek til GPU'er. RAPIDS består af:

  • cudf (pandas)
  • cuml (sckit-learn)
  • cugraph (network-X)

Med disse generelle datavidenskabelige biblioteker, der tilbyder enorme beregningsforbedringer til traditionelt CPU-bundne processer (dataindlæsning, rensning, funktionsteknologi, lineære modeller osv.), Banes banen til en helt ny grænse for datavidenskab. 

Fra Pandas til RAPIDs

I moderne tid er den enkle søgning en ret ligetil proces. Ord kan repræsenteres som numeriske vektorer, og derefter kan afstanden mellem disse vektorer beregnes for at se, hvor "ens" passagerne er. Den mest simple metode til dette bruger kosinus-lighed med TF-IDF-ordvektorer.

RAPIDs
Illustration: RAPIDs

For at "vektorisere" vores tekst skal vi dog først læse den ind og forarbejde den. Antag, at XML → csv-forarbejdning allerede er afsluttet, og nu er vi bare nødt til at læse disse ind som dataframes og udføre den tilhørende forarbejdning.

Nu har vi cirka 23 GB data og kun to GPU'er. Jeg har ingen illusioner om at kunne passe alt dette i GPU-hukommelsen med Python. Heldigvis, som det er tilfældet med videnskabelig litteratur, er det kun nyere artikler, der har tendens til at være relevante. For at evaluere nøjagtigheden af søgningen med eksperter har jeg virkelig kun brug for de sidste 10 år med Pubmed-data - som med mit datasæt var omkring 8 millioner artikler.

Brug af CPU-bundne processer ville være temmelig omkostningsfuldt, men at fremskynde tingene med cuda gør hele forskellen. Jeg vil gerne:

  • Læse dataframen
  • Rens strings i "abstract' kollonen
  • Behold kun år > 2009
  • Genskrive til csv

Det her er hvor cudf kommer ind. Jeg skrev bogtaveligtalt pandaskode, lavede find og replacde og jeg havde GPU acceleret kode!

Det behandler dataframen meget hurtigere end, hvis de var blevet behandlet lokalt i CPU'en. Her er et eksempel paa output lokalt behandlet med pandas:

Processed 13783 abstracts in 0.84604811668396 seconds
Processed 21714 abstracts in 1.2190630435943604 seconds
Processed 20259 abstracts in 1.1971170902252197 seconds

Og her er output fra den proces på arbejdsstationen, der bruger cudf:

Processed 23818 abstracts in 0.3909769058227539 seconds
Processed 23609 abstracts in 0.5951714515686035 seconds
Processed 23929 abstracts in 0.3672349452972412 seconds

Hver fil behandles mere end dobbelt så hurtigt, og koden behøver kun en GPU! Endnu bedre kan vi bruge al hukommelse i begge GPU'er ved at oprette en cuda-klynge og anvende dask.

Hvis jeg bare vil læse i alle abstracts og gøre noget andet med dem, gør dask dette meget effektivt med få linjers kode.

Koden opover producerede følgende på en del af PubMed data (hele PubMed giver hukommelsesfejl - igen overaskelse).

Read 7141779 abstract in 64.332682 seconds

Når du kontrollerer output fra GPU-brugen i et separat vindue med ur -n 0,5 nvidia-smi, kan du se dine processer køre og overvåge hukommelsesforbruget.

Monitoring GPU Usage on the Workstation
Illustration: Monitoring GPU Usage on the Workstation

 GPU-accellereret Cosinus Similaritet

Da jeg nu ved, at jeg kan indlæse de sidste ti år med Pubmed-data i GPU-hukommelsen, kan jeg gå videre til den sjove del: selve TF-IDF-vektoriseringen. I scikit-learning er dette temmelig let, se min fulde CPU-implementering her. Ved hjælp af cuml skulle vi være i stand til bare at finde og erstatte som vi gjorde med pandaer, men desværre….

Failure
Illustration: Failure

I henhold til dette Github-emne er tekstfunktionsekstraktionsbibliotekerne for cuml stadig i værkerne på skrivningstidspunktet (men når jeg er færdig med at opdatere med kode!). Dette betyder, at vores vektorizer stadig skal implementeres med scikit-learning, og vi kan endnu ikke få GPU-acceleration på denne TF-IDF-opgave. Dette er bare til træningstrinnet, men det betyder, at vores TF-IDF-vektorizer forbliver CPU-bundet og derfor ineffektiv.

Dette var dog ikke ovre endnu. Selv hvis selve uddannelsen er ineffektiv, behøver dette trin virkelig kun at ske en gang. Heldigvis er output sklearns TF-IDF-vektorize bare en sparsom matrix, og når vi er tilbage til at håndtere matrixer, kan vi få hjælp fra nogle klassiske tensorbiblioteker. Jeg besluttede at bruge tensorflow.

Som man kunne forvente er matrixmultiplikation en implicit del af ethvert tensor-bibliotek. Efter at have trent min vectorizer i sklearn, kunne jeg port de faktiske vektorer tilbage til GPU med tensorflow for at udføre matrixmultiplikationen.

I teorien fungerede dette godt med små portioner af Pubmed - men det skalereres ikke. I hele Pubmed (og endda vores undergruppe) er der en hel del unikke ord. Da vi også har en vektor for hver citation i Pubmed efter 2009, bliver vores sparsomme matrixer store. Jeg tror, det blev omtrent 8 millioner med 1 million.

Yeah big surprise Kyle nice job dude
Illustration: Yeah big surprise Kyle nice job dude

Hæmmet ikke af hardware men software. Forsøg på at bevæge sig frem og tilbage fra sklearn og tensorflow førte til en række problemer. At indse denne tilgang ville tage mere tid og dygtighed, end jeg havde let tilgængelig, var det tid til at gå videre eller blive en bedre ingeniør. Det var tid til at gå videre til dybe læringsrepræsentationer.

At lave et GPU-accellereret BERT Index

Vektorisering af PubMed ved brug af BERT

De seneste fremskridt med transformere i NLP har vist massive forbedringer i en række forskellige opgaver. Mens adskillige modeller er kommet siden, er oprindelsen af ​​denne revolution Googles BERT. Som nogle andre DL-baserede modeller producerer BERT en kontekstuel vektor til sætninger. Antallet af dimensioner (længden på vektoren) er lig med den skjulte lagstørrelse, som i den seneste anbefalede BERT-store model er 1024.

Dette er enormt. Selv hvis vi ikke længere kan bruge sparsomme matrixer, går størrelsen på vores vektor fra millioner x millioner → millioner x tusinder. På GPU'er, hvor pladsen kan være lidt begrænset, gør dette hele forskellen.

Normalt bruges BERT til klassificeringsopgaver, men i vores tilfælde ønsker vi bare at bruge det til at udtrække den vectoriserede repræsentation af vores Pubmed-abstracts, så de kan indekseres og søges. Takket være Tencent Research har vi allerede et veludviklet bibliotek med GPU-kapacitet: BERT som en service.

Du kan følge instruktionerne i repoen for faktisk at installere tjenesten. Når du først har den tilgængelig i dit miljø, skal du kun hente din foretrukne BERT-model og starte den op.

Nu hvor du har tjenesten kørt, kan enkle Python påberåbes for at hente vektorerne for enhver tekst, du vil have BERT-repræsentation til.

Let nok. Med BERT-tjenesten, der bruger de to GPU'er på arbejdsstationen, føres en stor mængde abstrakter gennem modellen flammende hurtigt. Nedenfor vises output, når jeg tidsbestiller det for hver csv:

Vectorized 23727 abstracts in 53.800883 seconds
Vectorized 25402 abstracts in 56.999314 seconds
Vectorized 25402 abstracts in 57.235494 seconds
Vectorized 23575 abstracts in 50.786675 seconds
Vectorized 17773 abstracts in 33.936309 seconds
Vectorized 24190 abstracts in 53.914434 seconds

Selv med arbejdsstationen tager denne proces et stykke tid - hvilket giver dig en idé om, hvor lang tid det tager uden det. Det er også værd at bemærke, at denne gang inkluderer læsning af dataene med cudf. For at illustrere, hvor stort mellemrummet mellem GPU-acceleration og lokal beregning er, er her den samme proces ved hjælp af min personlige bærbare computer i stedet:

Vectorized 13172 abstracts in 2048.069033 seconds

30 minutter. Det tog næsten 30 minutter at vektorisere halvdelen af de abstrakter, jeg behandler på arbejdsstationen på <60 sekunder. Selv for bare at hente vektorerne fra en så stor model, sparer GPU-beregning mig fulde dage med at vride mine tommelfingre, mens min kode kører.

Indeks ved at bruge Faiss

Denne gang, i stedet for at lave matrixmultiplikation selv, overgår jeg det til et veludviklet hurtigt indeksbibliotek. Facebooks faiss er let at bruge, og GPU er i stand til at gøre det til det perfekte værktøj til at indeksere vores BERT-vektorer. For at oprette en flad GPU-baseret i faiss, behøver vi kun ~ 10 linjer med kode.

Når du først har indekset, skal du bare smide vektorerne i. For at gemme GPU-hukommelse anbefaler jeg at vectorisere teksten ved hjælp af BERT-tjenesten separat separat og gemme på disk. Derefter kan du indlæse og indeksere vektorerne uden, at tjenesten også kører i baggrunden. Du kan dog også gøre alt på én gang, hvis du vælger det.

Efter oprettelse af selve indekset kan søgninger udføres på en enkelt linje. Men vil denne skala? Hvis jeg ville bruge denne kode til at hente resultater eller endda sætte en model i produktion, vil jeg sikre mig, at søgninger køres så hurtigt som muligt. Jeg benchmarkede søgninger op til ~ 3 millioner abstrakter, og søgeresultaterne tog stadig < 0,1 sekunder.

Even at 2.5M abstracts, the search query time using faiss is still less than 10 ms on the workstation
Illustration: Even at 2.5M abstracts, the search query time using faiss is still less than 10 ms on the workstation

Endelig? Sanitetskontrol. Hele tiden har jeg udført søgninger under forudsætningerne om, at SMV'er vil være i stand til at evaluere dem for nøjagtighed. Men hvis søgningerne er så dårlige, er det meningsløst, at jeg skulle starte igen eller helt re-faktorere min tilgang. Heldigvis er dette ikke tilfældet.

output
Illustration: Kyle Gallatin

Et hurtigt kig viser, at en en kontekstuel søgning efter “Parkinsons sygdom” returnerer relevante abstrakter i feltet (til min lægmands evaluering).

Så lad os se tilbage på kravene og se, om denne fremgangsmåde løste alle kravene til dette projekt:

Flersproget (en / zh) ✅: BERT understøtter 104 sprog!

Fås via flere kanaler (web / WeChat) ✅: Pak det op i en API og serve away.

Tilpasbar (i stand til at indstille algoritme for optimale resultater) ✅: Jeg brugte BERT-base, men det er muligt at bruge Bio-BERT eller en hvilken som helst anden finjusteret BERT her. Derudover kan vi stable letvægtsklassificeringsalgoritmer eller heuristikker om disse resultater for at forbedre nøjagtigheden endnu mere.

Lav latenstid (hurtige søgeresultater) ✅: Brug af næsten 1/3 af PubMed-sammendragene var latensen stadig < 0,1 sekunder og så ud til at skalere med rimelighed.

Understøtte store data (alle Pubmed-abstracts og mere) ✅: Vi brugte kun citater ≥ 2009 for validering, men med flere GPU'er og en bedre ingeniør kunne du nemt skalere dette til alle Pubmed.

Præcise (bedre søgeresultater end Pubmed) 🤔: Forbliver at blive set. SMV'er skulle bedømme og sammenligne søgeresultater med Pubmed-søgning og indstille algoritmen over tid. Men med en så kort omsætning på ~ 7 millioner abstracts gør arbejdsstationen dette meget muligt at gøre med relativt hurtig vending. Selvom sundhedskontrollen manglede skala, viser den i det mindste denne fremgangsmåde kan være værd at udforske.

Konklusion

Indhentning af oplysninger er enorm i store virksomheder, der er fyldt med uorganiserede dokumenter. Intelligente løsninger til at hente disse dokumenter er meget efterspurgte. Mens mange leverandører tilbyder robuste løsninger i enterprise-størrelse, er det kun muligt at organisere information i så stor skala på så kort tid nu gennem hardware- og softwareudviklingen i slutningen af 2010'erne.

Jeg skabte, iterated og revideret min tilgang til dette problem på min fritid over et par uger. Takket være kraften i arbejdsstationen og open-source lykkedes det mig faktisk at nå mit mål på det tidspunkt. I stedet for at vente uger på, at koden kørte, modtog jeg konstant feedback og tacklede fejl tidligt. Som et resultat gik min kode, og dette personlige projekt eksponentielt hurtigere.

docker
Illustration: Docker

Da jeg dybest set allerede arbejder i et produktionsmiljø, er det også let at skifte til mere administrerede cloud-hosts til implementering. Da min kode ikke var produktionskode, gav Docker mig mulighed for at sikre, at alt, hvad jeg byggede, kunne pakkes, og pakkes uanset billedregistrerings- og installationsprogram, til det jeg kunne lide.

Naturligvis er 100.000 kr. meget at lægge for noget hardware. Men hvis du er en virksomhedsorganisation, der leder efter mulighed for hurtig eksperimentering og omsætning, er det fornuftigt. Som sammenligning er her et tilbud på en dedikeret AWS p3.8x stor (4 Tesla V100s). $ 75K for 1 år og hovedpinen ved installation af installation af alle biblioteker og værktøjer selv.

AWS Pricing on Dedicated GPU Resource
Illustration: Kyle Gallatin

Der er løsninger på dette problem, der ikke involverer GPU. Da elasticsearch nu har understøttelse af vektorscoring, kan du distribuere den samme løsning på en 20-knude-klynge temmelig let med meget flere klokker og fløjter end de ~ 30 kodelinjer, jeg brugte her.

Nvidia DGX
Illustration: Nvidia DGX

Effektiviteten og skalaen, der blev opnået på kun to DGX'er her, skal imidlertid vise, hvad der virker når man bruger GPU. Tilgængelighed igennem Python API'er gør det nu muligt for den gennemsnitlige data scientist at udføre højt optimerede opgaver med minimal indsats.

Tak for at læse med og prøv endelig at forbedre disse løsninger selv!

Skamløst Twitter-plug: arbejder på mit Twitter-game og du er også velkommen til at oprette forbindelse på LinkedIn!

 

Translated and posted with the consent of Kyle Gallatin. Orginalt bragt på Medium.