5 tips til multi-GPU-træning med Keras PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

5 tips til multi-GPU-træning med Keras

Deep Learning (det foretrukne buzzword i slutningen af ​​2010'erne sammen med blockchain/bitcoin og Data Science/Machine Learning) har gjort os i stand til at lave nogle virkelig fede ting de sidste par år. Bortset fra fremskridtene inden for algoritmer (som ganske vist er baseret på ideer, der allerede er kendt siden 1990'erne alias "Data Mining-æraen"), kan hovedårsagerne til dens succes tilskrives tilgængeligheden af ​​store gratis datasæt, introduktionen af ​​open source-biblioteker og brugen af ​​GPU'er. I dette blogindlæg vil jeg fokusere på de to sidste, og jeg vil dele nogle tips med dig, som jeg har lært på den hårde måde.

Hvorfor TensorFlow & Keras?

TensorFlow er et meget populært Deep Learning-bibliotek udviklet af Google, som giver dig mulighed for at prototype hurtigt komplekse netværk. Den kommer med masser af interessante funktioner såsom auto-differentiering (som sparer dig fra at estimere/kode gradienterne af omkostningsfunktionerne) og GPU-understøttelse (som giver dig mulighed for nemt at få en 200x hastighedsforbedring ved hjælp af anstændig hardware). Desuden tilbyder den en Python-grænseflade, som betyder, at du kan prototype hurtigt uden at skulle skrive C- eller CUDA-kode. Ganske vist er der masser af andre rammer, man kan bruge i stedet for TensorFlow, såsom Torch, MXNet, Theano, Caffe, Deeplearning4j, CNTK osv., men det hele koger ned til din use-case og din personlige præference.

Men hvorfor Keras? For mig er det at bruge TF direkte som at lave Machine Learning med Numpy. Ja det er muligt, og fra tid til anden skal du gøre det (især hvis du skriver brugerdefinerede lag/tabsfunktioner), men vil du virkelig skrive kode, der beskriver de komplekse netværk som en række vektoroperationer (ja, jeg ved det der er metoder på højere niveau i TF, men de er ikke så seje som Keras)? Og hvad hvis du vil flytte til et andet bibliotek? Så skal du nok omskrive koden, hvilket er ærgerligt. Ta ta taaa, Keras til undsætning! Keras giver dig mulighed for at beskrive dine netværk ved hjælp af koncepter på højt niveau og skrive kode, der er backend-agnostisk, hvilket betyder, at du kan køre netværkene på tværs af forskellige deep learning-biblioteker. Få ting, jeg elsker ved Keras, er, at det er velskrevet, det har en objektorienteret arkitektur, det er nemt at bidrage med, og det har et venligt fællesskab. Hvis du kan lide det, så sig tak til Francois Chollet for at udvikle det og open-source det.

Tips og Gotchas til Multi-GPU-træning

Lad os uden videre hoppe til et par tips til, hvordan du får mest muligt ud af GPU-træning på Keras og et par gotchas, som du bør have i tankerne:

1. Multi-GPU træning er ikke automatisk

Træningsmodeller på GPU ved hjælp af Keras & Tensorflow er problemfri. Hvis du har et NVIDIA-kort, og du har installeret CUDA, vil bibliotekerne automatisk finde det og bruge det til træning. Så sejt! Men hvad hvis du er en forkælet møgunge, og du har flere GPU'er? Nå, desværre bliver du nødt til at arbejde lidt for at opnå multi-GPU træning.
5 tips til multi-GPU-træning med Keras PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
Der er flere måder at parallelisere et netværk på, afhængigt af hvad du ønsker at opnå, men de to vigtigste tilgange er model- og dataparallelisering. Den første kan hjælpe dig, hvis din model er for kompleks til at passe ind i en enkelt GPU, mens den sidste hjælper, når du vil fremskynde udførelsen. Når folk taler om multi-GPU-træning, mener de typisk det sidste. Det plejede at være sværere at opnå, men heldigvis har Keras for nylig inkluderet en hjælpemetode kaldet mutli_gpu_model hvilket gør den parallelle træning/forudsigelser nemmere (p.t. kun tilgængelig med TF backend). Hovedideen er, at du sender din model gennem metoden, og den kopieres på tværs af forskellige GPU'er. Det originale input opdeles i bidder, som føres til de forskellige GPU'er, og derefter aggregeres de som et enkelt output. Denne metode kan bruges til at opnå parallel træning og forudsigelser, men husk ikke desto mindre, at den til træning ikke skaleres lineært med mængden af ​​GPU'er på grund af den nødvendige synkronisering.

2. Vær opmærksom på batchstørrelsen

Når du træner med multi-GPU, skal du være opmærksom på batchstørrelsen, da den har flere effekter på hastighed/hukommelse, konvergens af din model, og hvis du ikke er forsigtig, kan du ødelægge din modelvægt!

Hastighed/hukommelse: Jo større batch jo hurtigere er træningen/forudsigelsen. Dette skyldes, at der er en overhead på at sætte ind og udtage data fra GPU'erne, så små batches har mere overhead. På bagsiden, jo større batch, jo mere hukommelse har du brug for i GPU'en. Især under træning opbevares input fra hvert lag i hukommelsen, da de er påkrævet på tilbage-udbredelsestrinnet, så at øge din batchstørrelse for meget kan føre til fejl uden hukommelse.

Konvergens: Hvis du bruger Stochastic Gradient Decent (SGD) eller nogle af dens varianter til at træne din model, skal du huske på, at batchstørrelsen kan påvirke dit netværks evne til at konvergere og generalisere. Typiske batchstørrelser i mange computersynsproblemer er mellem 32-512 eksempler. Som Keskar et al udtrykte det: "Det er blevet observeret i praksis, at når man bruger en større batch (end 512), er der en forringelse af modellens kvalitet, målt ved dens evne til at generalisere." Bemærk, at andre forskellige optimeringsprogrammer har forskellige egenskaber, og at specialiserede distribuerede optimeringsteknikker kan hjælpe med problemet. Hvis du er interesseret i de matematiske detaljer, anbefaler jeg at læse Joeri Hermans' speciale "Om skalerbar Deep Learning og Parallelizing Gradient Descent".
5 tips til multi-GPU-træning med Keras PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
At ødelægge vægtene: Dette er en grim teknisk detalje, som kan have ødelæggende resultater. Når du laver multi-GPU-træning, er det vigtigt at fodre alle GPU'erne med data. Det kan ske, at den allersidste batch af din epoke har færre data end defineret (fordi størrelsen af ​​dit datasæt ikke kan divideres nøjagtigt med størrelsen af ​​dit batch). Dette kan forårsage, at nogle GPU'er ikke modtager nogen data under det sidste trin. Desværre kan nogle Keras-lag, især Batch Normalization Layer, ikke klare det, hvilket fører til, at nan-værdier vises i vægtene (den løbende middelværdi og varians i BN-laget). For at gøre tingene endnu mere grimme, vil man ikke observere problemet under træning (mens indlæringsfase er 1), fordi det specifikke lag bruger batchens middelværdi/varians i estimeringerne. Ikke desto mindre under forudsigelser (indlæringsfasen sat til 0), bruges den løbende middelværdi/varians, som i vores tilfælde kan blive nan, hvilket fører til dårlige resultater. Så gør dig selv en tjeneste, og sørg altid for, at din batchstørrelse er fast, når du laver multi-GPU-træning. To enkle måder at opnå dette på er enten ved at afvise batches, der ikke matcher den foruddefinerede størrelse, eller gentage registreringerne i batchen, indtil du når den foruddefinerede størrelse. Sidst men ikke mindst skal du huske på, at i en multi-GPU-opsætning skal batchstørrelsen være et multiplum af antallet af tilgængelige GPU'er på dit system.

3. GPU data Starvation aka CPU'erne kan ikke følge med GPU'erne

Typisk er den dyreste del, når man træner/forudsiger Deep-netværk, det skøn, der sker på GPU'erne. Dataene forbehandles i CPU'erne i baggrunden, og de føres til GPU'erne med jævne mellemrum. Ikke desto mindre bør man ikke undervurdere, hvor hurtige GPU'erne er; det kan ske, at hvis dit netværk er for lavt, eller forbehandlingstrinnet er for komplekst, at dine CPU'er ikke kan følge med dine GPU'er eller med andre ord, de ikke fodrer dem med data hurtigt nok. Dette kan føre til lav GPU-udnyttelse, hvilket betyder spildte penge/ressourcer.
5 tips til multi-GPU-træning med Keras PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
Keras udfører typisk estimeringerne af batchene parallelt, men på grund af Pythons GIL (Global Interpreter Lock) kan du ikke rigtig opnå ægte multi-threading i Python. Der er to løsninger til det: enten brug flere processer (bemærk, at der er masser af gotchas i denne, som jeg ikke vil dække her) eller hold dit forbehandlingstrin enkelt. Tidligere har jeg sendt en Pull-Request på Keras for at afhjælpe noget af den unødvendige belastning, som vi lagde på CPU'erne under billedforbehandling, så de fleste brugere bør ikke blive påvirket, hvis de bruger standardgeneratorerne. Hvis du har brugerdefinerede generatorer, så prøv at skubbe så meget logik som muligt til C-biblioteker såsom Numpy, fordi nogle af disse metoder faktisk frigiv GIL hvilket betyder at man kan øge graden af ​​parallelisering. En god måde at opdage, om du står over for GPU-datasult, er at overvåge GPU-udnyttelsen, men vær dog advaret om, at dette ikke er den eneste grund til at observere det (synkroniseringen, der sker under træning på tværs af flere GPU'er, er også skyld i lav udnyttelse ). GPU-datasult kan typisk detekteres ved at observere GPU-bursts efterfulgt af lange pauser uden brug. Tidligere har jeg åbnet en udvidelse til Dstat, der kan hjælpe dig med at måle din GPU-udnyttelse, så tag et kig på originale blogindlæg.

4. Gem dine parallelle modeller

Lad os sige, at du brugte mutli_gpu_model-metoden til at parallelisere din model, træningen er færdig, og nu vil du fortsætte med dens vægte. Den dårlige nyhed er, at du ikke bare kan kalde save() på den. I øjeblikket har Keras en begrænsning, der ikke tillader dig gemme en parallel model. Der er 2 måder at omgå dette på: enten kalder save() på referencen til den originale model (vægtene opdateres automatisk), eller du skal serialisere modellen ved at skære den paralleliserede version ned og rydde op i alle unødvendige forbindelser. Den første mulighed er meget nemmere, men i fremtiden planlægger jeg at open-source en serialize()-metode, der udfører sidstnævnte.

5. At tælle de tilgængelige GPU'er har en ubehagelig bivirkning

Desværre i øjeblikket er der en ubehagelig bivirkning på tensorflow.python.client.device_lib.list_local_devices()-metoden, som forårsager, at der oprettes en ny TensorFlow-session og initialiseringen af ​​alle de tilgængelige GPU'er på systemet. Dette kan føre til uventede resultater såsom visning af flere GPU'er end specificeret eller for tidlig initialisering af nye sessioner (du kan læse alle detaljer om dette pull-anmodning). For at undgå lignende overraskelser anbefales det at bruge Keras' K.get_session().list_devices() metode i stedet, som vil returnere alle de aktuelt registrerede GPU'er på sessionen. Sidst men ikke mindst skal du huske på, at det på en eller anden måde er dyrt at kalde metoden list_devices(), så hvis du bare er interesseret i antallet af tilgængelige GPU'er, ring til metoden én gang og gem deres nummer på en lokal variabel.

Det er det! Håber du fandt denne liste nyttig. Hvis du fandt andre gotchas/tips til GPU-træning på Keras, så del dem nedenfor i kommentarerne. 🙂

Tidsstempel:

Mere fra Datumboks