5 tips för multi-GPU-träning med Keras PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

5 tips för multi-GPU-utbildning med Keras

Deep Learning (favoritordet från slutet av 2010-talet tillsammans med blockchain/bitcoin och Data Science/Machine Learning) har gjort det möjligt för oss att göra några riktigt coola saker de senaste åren. Förutom framstegen inom algoritmer (som visserligen är baserade på idéer som redan är kända sedan 1990-talet, även kallat "Data Mining-eran"), kan huvudorsakerna till dess framgång tillskrivas tillgången till stora gratis datauppsättningar, införandet av bibliotek med öppen källkod och användningen av GPU:er. I det här blogginlägget kommer jag att fokusera på de två sista och jag ska dela med mig av några tips som jag lärt mig den hårda vägen.

Varför TensorFlow & Keras?

TensorFlow är ett mycket populärt Deep Learning-bibliotek utvecklat av Google som låter dig prototyper snabbt av komplexa nätverk. Den kommer med massor av intressanta funktioner som automatisk differentiering (vilket sparar dig från att uppskatta/koda gradienterna för kostnadsfunktionerna) och GPU-stöd (som gör att du enkelt kan få en 200x hastighetsförbättring med anständig hårdvara). Dessutom erbjuder den ett Python-gränssnitt som innebär att du snabbt kan prototyper utan att behöva skriva C- eller CUDA-kod. Visserligen finns det massor av andra ramverk man kan använda istället för TensorFlow, som Torch, MXNet, Theano, Caffe, Deeplearning4j, CNTK, etc, men allt handlar om ditt användningsfall och dina personliga preferenser.

Men varför Keras? För mig är att använda TF direkt som att göra maskininlärning med Numpy. Ja det är genomförbart och då och då måste du göra det (speciellt om du skriver anpassade lager/förlustfunktioner) men vill du verkligen skriva kod som beskriver de komplexa nätverken som en serie vektoroperationer (ja, jag vet det finns metoder på högre nivå i TF men de är inte lika coola som Keras)? Och vad händer om du vill flytta till ett annat bibliotek? Då skulle du förmodligen behöva skriva om koden, vilket suger. Ta ta taaa, Keras till undsättning! Keras låter dig beskriva dina nätverk med hjälp av koncept på hög nivå och skriva kod som är backend-agnostisk, vilket innebär att du kan köra nätverken över olika djupinlärningsbibliotek. Få saker jag älskar med Keras är att den är välskriven, den har en objektorienterad arkitektur, den är lätt att bidra med och den har en vänlig gemenskap. Om du gillar det, säg tack till Francois Chollet för att utveckla den och öppna den.

Tips och Gotchas för Multi-GPU-träning

Utan vidare, låt oss hoppa till några tips om hur du får ut det mesta av GPU-träning på Keras och ett par gotchas som du bör ha i åtanke:

1. Multi-GPU-träning är inte automatisk

Utbildningsmodeller på GPU med Keras & Tensorflow är sömlös. Om du har ett NVIDIA-kort och du har installerat CUDA kommer biblioteken automatiskt att upptäcka det och använda det för träning. Så cool! Men vad händer om du är en bortskämd brat och du har flera GPU:er? Tja, tyvärr kommer du att behöva arbeta lite för att uppnå multi-GPU-träning.
5 tips för multi-GPU-träning med Keras PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.
Det finns flera sätt att parallellisera ett nätverk beroende på vad du vill uppnå, men de två huvudsakliga metoderna är modell- och dataparallellisering. Den första kan hjälpa dig om din modell är för komplex för att passa i en enda GPU medan den senare hjälper dig när du vill påskynda exekveringen. Vanligtvis när folk pratar om multi-GPU-träning menar de det senare. Det brukade vara svårare att uppnå men tack och lov har Keras nyligen inkluderat en verktygsmetod som heter mutli_gpu_model vilket gör den parallella träningen/förutsägelserna enklare (för närvarande endast tillgänglig med TF backend). Huvudtanken är att du skickar din modell genom metoden och den kopieras över olika GPU:er. Den ursprungliga ingången delas upp i bitar som matas till de olika GPU:erna och sedan aggregeras de som en enda utgång. Denna metod kan användas för att uppnå parallell träning och förutsägelser, tänk ändå på att för träning skalas den inte linjärt med antalet GPU:er på grund av den nödvändiga synkroniseringen.

2. Var uppmärksam på batchstorleken

När du tränar multi-GPU, var uppmärksam på batchstorleken eftersom den har flera effekter på hastighet/minne, konvergens av din modell och om du inte är försiktig kan du skada dina modellvikter!

Hastighet/minne: Uppenbarligen ju större batch desto snabbare träning/förutsägelse. Detta beror på att det finns en overhead på att sätta in och ta ut data från GPU:erna, så små batcher har mer overhead. På baksidan, ju större batch desto mer minne behöver du i GPU:n. Speciellt under träning hålls ingångarna för varje lager i minnet eftersom de krävs i steget för bakåtförökning, så att öka din batchstorlek för mycket kan leda till fel i minnet.

Konvergens: Om du använder Stochastic Gradient Decent (SGD) eller några av dess varianter för att träna din modell, bör du ha i åtanke att batchstorleken kan påverka ditt nätverks förmåga att konvergera och generalisera. Typiska batchstorlekar i många datorseendeproblem är mellan 32-512 exempel. Som Keskar et al uttryckte det, "Det har observerats i praktiken att när man använder en större batch (än 512) finns det en försämring av modellens kvalitet, mätt med dess förmåga att generalisera." Observera att andra olika optimerare har olika egenskaper och specialiserade distribuerade optimeringstekniker kan hjälpa till med problemet. Om du är intresserad av de matematiska detaljerna rekommenderar jag att du läser Joeri Hermans avhandling "Om skalbar djupinlärning och parallellisering av gradientnedstigning".
5 tips för multi-GPU-träning med Keras PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.
Fördärva vikterna: Detta är en otäck teknisk detalj som kan få förödande resultat. När du tränar multi-GPU är det viktigt att mata alla GPU:er med data. Det kan hända att den allra sista batchen av din epok har mindre data än vad som definierats (eftersom storleken på din datauppsättning inte kan delas exakt med storleken på din batch). Detta kan göra att vissa GPU:er inte tar emot någon data under det sista steget. Tyvärr kan vissa Keras-lager, framför allt batchnormaliseringslagret, inte hantera det som leder till att nan-värden visas i vikterna (det löpande medelvärdet och variansen i BN-lagret). För att göra sakerna ännu otäckare kommer man inte att observera problemet under träningen (medan inlärningsfasen är 1) eftersom det specifika lagret använder batchens medelvärde/varians i uppskattningarna. Icke desto mindre under förutsägelser (inlärningsfasen satt till 0) används löpande medelvärde/varians som i vårt fall kan bli nan vilket leder till dåliga resultat. Så gör dig själv en tjänst och se alltid till att din batchstorlek är fast när du tränar multi-GPU. Två enkla sätt att uppnå detta är antingen genom att avvisa batcher som inte matchar den fördefinierade storleken eller upprepa posterna inom batchen tills du når den fördefinierade storleken. Sist men inte minst kom ihåg att i en multi-GPU-inställning bör batchstorleken vara en multipel av antalet tillgängliga GPU:er på ditt system.

3. GPU-data Svält aka processorerna kan inte hänga med GPU:erna

Vanligtvis är den dyraste delen när man tränar/förutsäger djupa nätverk den uppskattning som sker på GPU:erna. Data förbehandlas i processorerna i bakgrunden och de matas till GPU:erna med jämna mellanrum. Ändå bör man inte underskatta hur snabba GPU:erna är; det kan hända att om ditt nätverk är för grunt eller förbearbetningssteget är för komplext att dina CPU:er inte kan hänga med dina GPU:er eller med andra ord att de inte matar dem med data tillräckligt snabbt. Detta kan leda till lågt GPU-utnyttjande vilket leder till bortkastade pengar/resurser.
5 tips för multi-GPU-träning med Keras PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.
Keras utför vanligtvis uppskattningarna av satserna parallellt, men på grund av Pythons GIL (Global Interpreter Lock) kan du inte riktigt uppnå äkta multi-threading i Python. Det finns två lösningar för det: använd antingen flera processer (observera att det finns massor av gotchas i den här som jag inte kommer att täcka här) eller håll ditt förbearbetningssteg enkelt. Tidigare har jag skickat en Pull-Request på Keras för att lindra en del av den onödiga påfrestning som vi lade på CPU:erna under bildförbehandling, så de flesta användare bör inte påverkas om de använder standardgeneratorerna. Om du har anpassade generatorer, försök att driva så mycket logik som möjligt till C-bibliotek som Numpy eftersom vissa av dessa metoder faktiskt släpp GIL vilket gör att man kan öka graden av parallellisering. Ett bra sätt att upptäcka om du står inför GPU-datasvält är att övervaka GPU-användningen, men varna dig för att detta inte är den enda anledningen till att observera det (synkroniseringen som sker under träning över flera GPU:er är också skyldig till lågt utnyttjande ). Vanligtvis kan GPU-datasvält upptäckas genom att observera GPU-skurar följt av långa pauser utan användning. Tidigare har jag skapat ett tillägg för Dstat med öppen källkod som kan hjälpa dig att mäta din GPU-användning, så ta en titt på original blogginlägg.

4. Spara dina parallella modeller

Säg att du använde mutli_gpu_model-metoden för att parallellisera din modell, träningen avslutad och nu vill du fortsätta med dess vikter. Den dåliga nyheten är att du inte bara kan ringa save() på den. För närvarande har Keras en begränsning som inte tillåter dig spara en parallell modell. Det finns två sätt att kringgå detta: antingen anropa save() på referensen till originalmodellen (vikterna uppdateras automatiskt) eller så måste du serialisera modellen genom att skära ner den parallelliserade versionen och rensa upp alla onödiga anslutningar. Det första alternativet är mycket enklare men i framtiden planerar jag att öppna en serialize()-metod som utför den senare.

5. Att räkna de tillgängliga GPU:erna har en otäck bieffekt

Tyvärr finns det för närvarande en otäck bieffekt på metoden tensorflow.python.client.device_lib.list_local_devices() som gör att en ny TensorFlow-session skapas och initieringen av alla tillgängliga GPU:er på systemet. Detta kan leda till oväntade resultat som att se fler GPU:er än vad som anges eller att initiera nya sessioner i förtid (du kan läsa alla detaljer om detta pull-begäran). För att undvika liknande överraskningar rekommenderas du att istället använda Keras K.get_session().list_devices()-metod, som kommer att returnera alla för närvarande registrerade GPU:er på sessionen. Sist men inte minst, kom ihåg att det är dyrt att anropa list_devices()-metoden på något sätt, så om du bara är intresserad av antalet tillgängliga GPU:er ring metoden en gång och lagra deras nummer på en lokal variabel.

Det är allt! Hoppas du tyckte att den här listan var användbar. Om du hittade andra gotchas/tips för GPU-träning på Keras, dela dem nedan i kommentarerna. 🙂

Tidsstämpel:

Mer från Datumbox