Artikkelen er skrevet av Rakshith Vasudev og John Lockman – HPC AI Innovation Lab i oktober 2019
Innledning
Horovod er et distribuert rammeverk for dyp læring for å fremskynde opplæring på ulike rammeverk for dyp læring, for eksempel Tensorflow, Keras, Pytorch og MXNet. Den ble utviklet for å gjøre det enklere å etablere distribuerte dyplæringsprosjekter og øke hastigheten med TensorFlow. Horovod støtter å kjøre opplæringsprosesser parallelt. Den støtter både dataparallelitet og modellparallelitet. Når det kjøres en jobb med nevronettverksopplæring som bruker horovod, kan disse tipsene brukes til feilsøking og til å se etter forbedringer i ytelsen.
Beskrivelse
Denne artikkelen bruker CheXNet som et eksempel å referere til fra. CheXNet er en assistentmodell for ai-radiologer som bruker DenseNet til å identifisere opptil 14 patologier fra et gitt x-ray-bilde i braketten.
- Riktig miljøoppsett kan spare mye tid når du feilsøker etter ytelsesproblemer. Pass på at du bruker GPU-versjonen av dyplæringsrammeverket. I dette eksemplet brukes tensorflow-gpu pakket av anaconda.
-
Bruk av horovodrun eller mpirun med bindende parametere kan gi ytelsesforbedringer. Ideelt sett skal prosessen som styrer kontroll av GPU, være bundet til den nærmeste CPU-sokkelen. På Dell EMC PowerEdge C4140 vil det optimale alternativet være --map-by socket. Det er ikke nødvendig å angi noen bindingsalternativer.
Det vil se omtrent slik ut:
mpirun --map-by socket -np x python pyfile.py - -pyoptions
- Jobben bør konfigureres slik at én MPI-prosess fungerer på én GPU. Hvis det er flere prosesser enn det er GPU-er, vil prosessene konkurrere for ressurser og ikke være i stand til å kjøre jobben med god ytelse. I eksemplet ovenfor skal x være lik antall GPU-er som skal brukes.
-
Hvis du vil angi én prosess per GPU, bruker du tensorflows ConfigProto() på følgende måte:
config.gpu_options.visible_device_list=str(hvd.local_size())
-
Hvis du vil kontrollere antall prosesser ved hjelp av GPU-en, kan du bruke minneforbruket til GPU-en «watch nvidia-smi» (se nvidia-smi). Dette gjør også at man kan se strømforbruket.
Figur 1: Skjermbilde av nvidia-smi-kommandoutdata som viser minne-, strøm- og GPU-utnyttelse.
- Hvis datapipelinen er riktig konfigurert og mpirun-parameterne er riktige, bør GPU-bruken overstige 90 % når modellopplæringen starter. Uregelmessig bølgedaler på 10–25 % er akseptabelt, men de bør være sjeldne.
- Angi den gruppevisestørrelsen, slik at GPU-minnet nesten er fullt, men begrenset slik at minnekravene ikke overstiges. Det er viktig å tenke på måten skaleringen av opplæringshastigheten oppnås. Skaleringen av opplæringshastigheten er et konsept der opplæringshastigheten multipliseres med en faktor som er proporsjonal med antall GPU-er. Dette gjør at modellen kan konvergere på en effektiv måte. Slik kan antall i/u-operasjoner reduseres ved å få maksimalt antall mulige imager på en GPU uten at det går ut over modellkonvergeringen. Merk at skaleringen av opplæringshastigheten ikke alltid er den beste løsningen for å forbedre modellkonvergering i en distribuert workload-innstilling.
Slik kontrollerer du om det er nødvendig å skalere opplæringshastigheten:
a) Oppgrader modellen med og uten skalering av opplæringshastighet i distribuert modus.
b) Hvis modellen uten skalering av opplæringshastighet fungerer bedre enn modellen med skalering av opplæringshastighet, er det ikke nødvendig å skalere opplæringshastigheten.
Når det er behov for mer konvergens, er det ikke alltid en regel å bruke det høyeste antallet bilder per gruppe. Det er vanligvis en avveining mellom gruppestørrelse og konvergens (uansett om skalering av opplæringshastighet er brukt eller ikke) som dataforskeren må være i stand til å ta basert på tilfellet.
Igjen kan du se på forbruket av GPU-minne ved hjelp av "se nvidia-smi". I denne saksstudien ble skalering av opplæringshastighet ikke brukt fordi den ga en bedre modell med AUC-verdier . Den lokale minisanjstørrelsen var 64. Det er vanlig å ha oppvarmingsperioder som beskrevet i dette dokumentet ved å skalere opplæringshastigheten.
-
Profiler jobbene dine ved hjelp av horovod tidslinje og nvprof for å se eventuelle flaskehalser som kan oppstå. Ofte kommer flaskehalsen på grunn av det følgende:
a) Tf data pipeline not setup well, and thus a lot of time is spent preparing the data while the accelerator is idle (a) Tf data pipeline not setup well, and thus a lot of time is spent preparing the data while the accelerator is idle (a) Tf data pipeline not setup well (Tf-dataforløp er ikke riktig konfigurert), og dermed brukes mye tid på å forberede For å løse dette må tf pipeline korrigeres.
Les denne artikkelen for å få informasjon om hvordan du konfigurerer en tf data pipeline.
b) Det kan hende at kommunikasjonen ikke bruker riktig struktur – sørg for at du bruker InfiniBandfor å se at infrastrukturbruken inkluderer –x NCCL_DEBUG=INFO mens du kjører mpirun på følgende måte:
mpirun -np 8 --map-by socket -x NCCL_DEBUG=INFO python $HOME/models/chexnet/chexnet.py --batch_size=128 --epochs=15
eller bruk horovodrun som inkluderer –x-bindingen.
- For å implementere distribusjon på riktig måte må GPU-er kunne kommunisere effektivt med hverandre. Hvis de ikke kommuniserer effektivt, vil dette føre til en flaskehals i kommunikasjonslinjen. For å kontrollere optimal kommunikasjon er det best å bruke følgende fremgangsmåte:
Først kan du se hvordan GPU-er snakker sammen ved hjelp av X-bindingen som vist ovenfor i punkt 8b,
hvis GPU-er snakker sammen:
1) I noden på en optimal måte vil se omtrent slik ut:
gpu002:1299562:1299573 [0] NCCL INFO Ring 00: 0 [0] - > 1 [1] via P2P / IPC
2) Utenfor noden på optimal måte vil se omtrent slik ut:
gpu028:149460:149495 [0] NCCL INFO Ring 01: 16 -> 0 [send] via NET/IB/0
gpu009:164181:164216 [0] NCCL INFO Ring 01: 12 -> 8 [motta] via NET/IB/0
gpu009:164181:164216 [0] NCCL INFO Ring 01: 4 -> 8 [motta] via NET/IB/0
Det kan noen ganger være utfordrende å distribuere dyplæringsjobber, spesielt når antall noder/GPU-er som brukes, ikke er i samsvar med den tilsvarende ytelsen. For å sikre størst mulig utbytte av investeringen i akseleratorer må du forsikre deg om at følgende beste praksis er implementert:
- de riktige alternativene for binding er på plass,
- vurdering av flere prosesser som ikke sløser med GPU-minnet,
- bruk av moderne pipelining-tilnærming,
- profilering for å se GPU-er brukes minst 80 % av tiden mens jobben kjører,
- ved hjelp av de nyeste CUDA-relaterte bibliotekene