I denne artikkelen vil vi dykke ned i GPU-programmering med Python. Ved hjelp av Python er det enkelt å låse opp den utrolige datakraften til skjermkortets GPU (grafikkbehandlingsenhet). I dette eksemplet vil vi jobbe med NVIDIAs CUDA-bibliotek.
Krav
For denne øvelsen trenger du enten en fysisk maskin med Linux og en NVIDIA-basert GPU, eller starter en GPU-basert forekomst på Amazon Web Services. Enten skal fungere bra, men hvis du velger å bruke en fysisk maskin, må du sørge for at NVIDIA-proprietære drivere er installert, se instruksjonene: https: // linuxhint.no / install-nvidia-drivers-linux
Du trenger også CUDA Toolkit installert. Dette eksemplet bruker Ubuntu 16.04 LTS spesifikt, men det er nedlastinger tilgjengelig for de fleste store Linux-distribusjoner på følgende URL: https: // utvikler.nvidia.com / cuda-nedlastinger
Jeg foretrekker .deb-basert nedlasting, og disse eksemplene antar at du valgte den ruten. Filen du laster ned er en .deb-pakke, men har ikke en .deb-utvidelse, så endre navn på den for å ha en .deb på slutten hans hjelpsomme. Deretter installerer du den med:
sudo dpkg -i pakkenavn.deb
Hvis du blir bedt om å installere en GPG-nøkkel, kan du følge instruksjonene for å gjøre det.
Nå må du installere selve cuda-pakken. For å gjøre det, løp:
sudo apt-get oppdater sudo apt-get install cuda -y
Denne delen kan ta en stund, så det kan være lurt å ta en kopp kaffe. Når det er gjort, anbefaler jeg å starte på nytt for å sikre at alle modulene lastes riktig på nytt.
Deretter trenger du Anaconda Python-distribusjonen. Du kan laste det ned her: https: // www.anakonda.no / nedlasting / # linux
Ta tak i 64-biters versjonen og installer den slik:
sh Anaconda *.sh
(stjernen i kommandoen ovenfor vil sikre at kommandoen kjøres uavhengig av mindre versjon)
Standardinstallasjonsplasseringen skal være bra, og i denne opplæringen bruker vi den. Som standard installeres den til ~ / anaconda3
På slutten av installasjonen blir du bedt om å bestemme om du vil legge Anaconda til din vei. Svar ja her for å gjøre det enklere å kjøre de nødvendige kommandoene. For å sikre at denne endringen finner sted, må du logge av og deretter logge på kontoen din etter at installasjonsprogrammet er ferdig.
Mer informasjon om installering av Anaconda: https: // linuxhint.no / install-anaconda-python-on-ubuntu /
Endelig må vi installere Numba. Numba bruker LLVM-kompilatoren til å kompilere Python til maskinkode. Dette forbedrer ikke bare ytelsen til vanlig Python-kode, men gir også limet som er nødvendig for å sende instruksjoner til GPU i binær form. For å gjøre dette, løp:
conda installere numba
Begrensninger og fordeler med GPU-programmering
Det er fristende å tenke at vi kan konvertere ethvert Python-program til et GPU-basert program, og dramatisk akselerere ytelsen. Imidlertid fungerer GPU på et skjermkort betydelig annerledes enn en vanlig CPU i en datamaskin.
CPUer håndterer mange forskjellige innganger og utganger og har et bredt utvalg av instruksjoner for å håndtere disse situasjonene. De er også ansvarlige for tilgang til minne, håndtering av systembussen, håndtering av beskyttelsesringer, segmentering og inngang / utgang. De er ekstreme multitaskere uten spesifikt fokus.
GPUer derimot er bygget for å behandle enkle funksjoner med blendende høy hastighet. For å oppnå dette forventer de en mer jevn tilstand av input og output. Ved å spesialisere seg i skalarfunksjoner. En skalarfunksjon tar en eller flere innganger, men returnerer bare en enkelt utgang. Disse verdiene må være typer som er forhåndsdefinert av numpy.
Eksempel på kode
I dette eksemplet lager vi en enkel funksjon som tar en liste over verdier, legger dem sammen og returnerer summen. For å demonstrere kraften til GPUen, kjører vi en av disse funksjonene på CPU og en på GPU og viser tidene. Den dokumenterte koden er under:
importer numpy som np fra timeit importer standard_timer som timer fra numba import vectorize # Dette skal være en betydelig høy verdi. På testmaskinen min tok dette # 33 sekunder å kjøre via CPU og litt over 3 sekunder på GPU. NUM_ELEMENTS = 100000000 # Dette er CPU-versjonen. def vector_add_cpu (a, b): c = np.nuller (NUM_ELEMENTS, dtype = np.float32) for i innen rekkevidde (NUM_ELEMENTS): c [i] = a [i] + b [i] return c # Dette er GPU-versjonen. Legg merke til @vectorize-dekoratøren. Dette forteller # numba å gjøre dette til en GPU-vektorisert funksjon. @vectorize (["float32 (float32, float32)"], target = "cuda") def vector_add_gpu (a, b): returner a + b; def main (): a_source = np.de (NUM_ELEMENTS, dtype = np.float32) b_source = np.de (NUM_ELEMENTS, dtype = np.float32) # Tid CPU-funksjon start = timer () vector_add_cpu (a_source, b_source) vector_add_cpu_time = timer () - start # Time GPU-funksjon start = timer () vector_add_gpu (a_source, b_source) vector_add_gpu_time = timer () - start # Rapporter ganger utskrift ("CPU-funksjonen tok% f sekunder."% vector_add_cpu_time) print (" GPU-funksjonen tok% f sekunder."% vector_add_gpu_time) return 0 if __name__ ==" __main__ ": main ()
For å kjøre eksemplet, skriv:
python gpu-eksempel.py
MERKNAD: Hvis du får problemer når du kjører programmet, kan du prøve å bruke "conda install accelerate".
Som du ser, kjører CPU-versjonen betydelig tregere.
Hvis ikke, er gjentagelsene dine for små. Juster NUM_ELEMENTS til en større verdi (på min side syntes breakeven-merket å være rundt 100 millioner). Dette er fordi installasjonen av GPUen tar liten, men merkbar tid, så for å gjøre operasjonen verdt det, er det behov for en høyere arbeidsbelastning. Når du løfter den over terskelen for maskinen din, vil du legge merke til betydelige ytelsesforbedringer av GPU-versjonen over CPU-versjonen.
Konklusjon
Jeg håper du har hatt glede av vår grunnleggende introduksjon til GPU-programmering med Python. Selv om eksemplet ovenfor er trivielt, gir det rammene du trenger for å ta ideene dine videre ved å utnytte kraften til GPUen din.