Usi la GPU da un contenitore mobile?


164

Sto cercando un modo per utilizzare la GPU all'interno di un contenitore docker.

Il contenitore eseguirà un codice arbitrario, quindi non voglio usare la modalità privilegiata.

Qualche consiglio?

Da ricerche precedenti ho capito che run -ve / o LXC cgroupera la strada da percorrere, ma non sono sicuro di come farlo esattamente


Vedi stackoverflow.com/questions/17792161/… che è simile alle tue esigenze.
Nicolas Goy,

1
@NicolasGoy Il link era buono ma non molto utile poiché non posso usare i privilegi per motivi di sicurezza. Il lxc-cgroups era un buon puntatore, ma non abbastanza. Ho trovato un modo e risponderò da solo quando tutto sarà lucidato.
Regan,

Risposte:


132

La risposta di Regan è ottima, ma è un po 'obsoleta, poiché il modo corretto per farlo è evitare il contesto di esecuzione di lxc poiché Docker ha lasciato cadere LXC come contesto di esecuzione predefinito a partire dalla docker 0.9.

Invece è meglio dire alla finestra mobile i dispositivi nvidia tramite il flag --device e usare semplicemente il contesto di esecuzione nativo piuttosto che lxc.

Ambiente

Queste istruzioni sono state testate sul seguente ambiente:

  • Ubuntu 14.04
  • CUDA 6.5
  • Istanza GPU AWS.

Installa il driver nvidia e cuda sul tuo host

Vedi CUDA 6.5 sull'istanza della GPU AWS che esegue Ubuntu 14.04 per configurare il tuo computer host.

Installa Docker

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
$ sudo sh -c "echo deb https://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
$ sudo apt-get update && sudo apt-get install lxc-docker

Trova i tuoi dispositivi nvidia

ls -la /dev | grep nvidia

crw-rw-rw-  1 root root    195,   0 Oct 25 19:37 nvidia0 
crw-rw-rw-  1 root root    195, 255 Oct 25 19:37 nvidiactl
crw-rw-rw-  1 root root    251,   0 Oct 25 19:37 nvidia-uvm

Esegui il contenitore Docker con il driver nvidia preinstallato

Ho creato un'immagine docker con i driver cuda preinstallati. Il file docker è disponibile su dockerhub se si desidera sapere come è stata creata questa immagine.

Ti consigliamo di personalizzare questo comando per abbinare i tuoi dispositivi nvidia. Ecco cosa ha funzionato per me:

 $ sudo docker run -ti --device /dev/nvidia0:/dev/nvidia0 --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm tleyden5iwx/ubuntu-cuda /bin/bash

Verifica che CUDA sia installato correttamente

Questo dovrebbe essere eseguito dall'interno del contenitore della finestra mobile appena avviato.

Installa esempi CUDA:

$ cd /opt/nvidia_installers
$ ./cuda-samples-linux-6.5.14-18745345.run -noprompt -cudaprefix=/usr/local/cuda-6.5/

Build deviceQuery sample:

$ cd /usr/local/cuda/samples/1_Utilities/deviceQuery
$ make
$ ./deviceQuery   

Se tutto ha funzionato, dovresti vedere il seguente output:

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 6.5, CUDA Runtime Version = 6.5, NumDevs =    1, Device0 = GRID K520
Result = PASS

3
Perché installi lxc-docker se non hai bisogno di lxc allora?
MP0,

4
Ho CUDA 5.5 sull'host e CUDA 6.5 in un contenitore creato dalla tua immagine. CUDA sta lavorando sull'host e ho passato i dispositivi al contenitore. Il contenitore vede passare le GPU ls -la /dev | grep nvidiama CUDA non riesce a trovare alcun dispositivo compatibile con CUDA: ./deviceQuery ./deviceQuery Starting... CUDA Device Query (Runtime API) version (CUDART static linking) cudaGetDeviceCount returned 38 -> no CUDA-capable device is detected Result = FAIL è a causa della mancata corrispondenza delle librerie CUDA sull'host e nel contenitore?
Brunetto,

1
Non lo so, potresti chiedere sul forum nvidia. Supponendo che la mancata corrispondenza della versione sia un problema, è possibile prendere questo Dockerfile e modificarlo per avere i driver CUDA 5.5, quindi ricostruire una nuova immagine docker da esso e usarla.
tleyden,

3
Puoi spiegare perché l'immagine deve installare il driver nvidia? Ho pensato che solo l'host che installa il driver nvidia (e usa --device ...) sia sufficiente?
Helin Wang,

2
Attualmente non è possibile farlo se si dispone di Windows come host.
Souradeep Nanda,

46

Scrivere una risposta aggiornata poiché la maggior parte delle risposte già presenti sono obsolete al momento.

Versioni precedenti a quelle Docker 19.03richieste nvidia-docker2e --runtime=nvidiabandiera.

Da allora Docker 19.03, è necessario installare il nvidia-container-toolkitpacchetto e quindi utilizzare il --gpus allflag.

Quindi, ecco le basi,

Installazione del pacchetto

Installa il nvidia-container-toolkitpacchetto come da documentazione ufficiale su Github .

Per i sistemi operativi basati su Redhat, eseguire il seguente set di comandi:

$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | sudo tee /etc/yum.repos.d/nvidia-docker.repo

$ sudo yum install -y nvidia-container-toolkit
$ sudo systemctl restart docker

Per i sistemi operativi basati su Debian, eseguire il seguente set di comandi:

# Add the package repositories
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

$ sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
$ sudo systemctl restart docker

Esecuzione della finestra mobile con supporto GPU

docker run --name my_all_gpu_container --gpus all -t nvidia/cuda

Nota: il flag --gpus allviene utilizzato per assegnare tutto il gpus disponibile al contenitore della finestra mobile.

Per assegnare gpu specifica al contenitore docker (nel caso di più GPU disponibili nel computer)

docker run --name my_first_gpu_container --gpus device=0 nvidia/cuda

O

docker run --name my_first_gpu_container --gpus '"device=0"' nvidia/cuda

5
A partire dal 2019 questo è il modo giusto di usare la GPU all'interno dei container docker.
Timur Bakeyev,

1
Qualcuno lo ha mai provato dall'interno di un processo batch su AWS?
medley56

1
Credo che questo sia molto rilevante. Vorrei averlo trovato prima, anche se ho dovuto adattare le istruzioni di github.com/NVIDIA/nvidia-docker per lavorare con Ubuntu 20.04
VictorLegros

40

Ok, finalmente sono riuscito a farlo senza usare la modalità --privileged.

Sto correndo su Ubuntu Server 14.04 e sto usando l'ultimo cuda (6.0.37 per Linux 13.04 64 bit).


Preparazione

Installa il driver nvidia e cuda sul tuo host. (può essere un po 'complicato, quindi ti suggerisco di seguire questa guida /ubuntu/451672/installing-and-testing-cuda-in-ubuntu-14-04 )

ATTENZIONE: è davvero importante conservare i file utilizzati per l'installazione dell'host cuda


Fai eseguire il Docker Daemon usando lxc

Dobbiamo eseguire il demone docker usando il driver lxc per poter modificare la configurazione e dare al contenitore l'accesso al dispositivo.

Utilizzo una volta:

sudo service docker stop
sudo docker -d -e lxc

Configurazione permanente Modifica il file di configurazione della finestra mobile situato in / etc / default / docker Cambia la riga DOCKER_OPTS aggiungendo '-e lxc' Ecco la mia riga dopo la modifica

DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 -e lxc"

Quindi riavviare il demone utilizzando

sudo service docker restart

Come verificare se il daemon utilizza effettivamente il driver lxc?

docker info

La riga del driver di esecuzione dovrebbe apparire così:

Execution Driver: lxc-1.0.5

Crea la tua immagine con i driver NVIDIA e CUDA.

Ecco un Dockerfile di base per creare un'immagine compatibile con CUDA.

FROM ubuntu:14.04
MAINTAINER Regan <http://stackoverflow.com/questions/25185405/using-gpu-from-a-docker-container>

RUN apt-get update && apt-get install -y build-essential
RUN apt-get --purge remove -y nvidia*

ADD ./Downloads/nvidia_installers /tmp/nvidia                             > Get the install files you used to install CUDA and the NVIDIA drivers on your host
RUN /tmp/nvidia/NVIDIA-Linux-x86_64-331.62.run -s -N --no-kernel-module   > Install the driver.
RUN rm -rf /tmp/selfgz7                                                   > For some reason the driver installer left temp files when used during a docker build (i don't have any explanation why) and the CUDA installer will fail if there still there so we delete them.
RUN /tmp/nvidia/cuda-linux64-rel-6.0.37-18176142.run -noprompt            > CUDA driver installer.
RUN /tmp/nvidia/cuda-samples-linux-6.0.37-18176142.run -noprompt -cudaprefix=/usr/local/cuda-6.0   > CUDA samples comment if you don't want them.
RUN export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64         > Add CUDA library into your PATH
RUN touch /etc/ld.so.conf.d/cuda.conf                                     > Update the ld.so.conf.d directory
RUN rm -rf /temp/*  > Delete installer files.

Esegui la tua immagine.

Innanzitutto è necessario identificare il numero principale associato al dispositivo. Il modo più semplice è eseguire il comando seguente:

ls -la /dev | grep nvidia

Se il risultato è vuoto, utilizzare l'avvio di uno dei campioni sull'host dovrebbe fare il trucco. Il risultato dovrebbe apparire così inserisci qui la descrizione dell'immagine Come puoi vedere c'è un set di 2 numeri tra il gruppo e la data. Questi 2 numeri sono chiamati numeri maggiori e minori (scritti in quell'ordine) e progettano un dispositivo. Useremo solo i numeri principali per comodità.

Perché abbiamo attivato il driver lxc? Utilizzare l'opzione conf di lxc che ci consente di consentire al nostro contenitore di accedere a tali dispositivi. L'opzione è: (consiglio di usare * per il numero minore perché riduce la lunghezza del comando di esecuzione)

--lxc-conf = 'lxc.cgroup.devices.allow = c [numero maggiore]: [numero minore o *] rwm'

Quindi, se voglio lanciare un container (supponendo che il nome della tua immagine sia cuda).

docker run -ti --lxc-conf='lxc.cgroup.devices.allow = c 195:* rwm' --lxc-conf='lxc.cgroup.devices.allow = c 243:* rwm' cuda

Puoi condividere il contenitore?
ChillarAnand

1
Docker ha --deviceun'opzione per consentire al container di accedere al dispositivo dell'host. Tuttavia, ho provato a utilizzare --device=/dev/nvidia0per consentire l'esecuzione del contenitore docker su cuda e non sono riuscito.
shiquanwang,

4
Ho poi riuscito con esponendo tutti /dev/nvidiao, /dev/nvidia1, /dev/nvidiactle /dev/nvidia-uvmcon --device. Anche se non so perché.
shiquanwang,

L'opzione --device non è stata implementata quando ho dovuto trovare questa soluzione. Sono necessari almeno nvidia0 o nvidia1 (scheda grafica) e nvidiactl (dispositivo nvidia generale) e nvidia-uvm (dispositivo di memoria United).
Regan,

2
Grazie per i tuoi suggerimenti su /dev/nvidia*@Regan. Per @ChillarAnand ho realizzato un cuda-
docker

29

Abbiamo appena rilasciato un repository sperimentale GitHub che dovrebbe facilitare il processo di utilizzo delle GPU NVIDIA all'interno dei container Docker.


4
Esiste il supporto di Windows? Non sembra, ma forse mi manca qualcosa.
Blaze,

6
Non c'è supporto per Windows. L'esecuzione del contenitore CUDA richiede i driver Nvidia per Linux e l'accesso ai dispositivi Linux che rappresentano GPU, ad esempio / dev / nvidia0. Questi dispositivi e driver non sono disponibili quando Docker è installato su Windows e in esecuzione all'interno della macchina virtuale VirtualBox.
Paweł Bylica,

Hai ancora bisogno delle dichiarazioni --device nel comando run? Ho creato un contenitore DA nvidia / cuda e il contenitore funziona correttamente, ma l'app (Wowza) non riconosce le GPU mentre funziona correttamente sull'host (questo host, quindi so che i driver vanno bene) . Sto correndo 361.28. L'host è EC2 utilizzando NVidia AMI su g2.8xlarge.
Rainabba,

Nvidia

22

I recenti miglioramenti di NVIDIA hanno prodotto un modo molto più efficace per farlo.

Fondamentalmente hanno trovato il modo di evitare la necessità di installare il driver CUDA / GPU all'interno dei container e farlo corrispondere al modulo del kernel host.

Al contrario, i driver si trovano sull'host e i container non ne hanno bisogno. Richiede un docker-cli modificato in questo momento.

Questo è fantastico, perché ora i contenitori sono molto più portatili.

inserisci qui la descrizione dell'immagine

Un rapido test su Ubuntu:

# Install nvidia-docker and nvidia-docker-plugin
wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
sudo dpkg -i /tmp/nvidia-docker*.deb && rm /tmp/nvidia-docker*.deb

# Test nvidia-smi
nvidia-docker run --rm nvidia/cuda nvidia-smi

Per ulteriori dettagli, consultare: Contenitore Docker abilitato per GPU e: https://github.com/NVIDIA/nvidia-docker


Funziona bene dopo aver completato tutti i passaggi. Nvidia non fornisce tutto in un unico posto, ma questo esempio fornisce tutto il necessario per farlo funzionare con un caso d'uso comune.
KobeJohn,

@KobeJohn - Ho appena seguito le istruzioni di installazione, come usare la riga di comando e assicurarmi che i miei contenitori ereditino da quelli Cuda. Funziona solo per me.
Matt,

1
In realtà, puoi dare degli scenari di vita reale in cui l'uso di nvidia-docker ha senso?
Suncatcher,

@Suncatcher - Lo sto usando in un cluster che richiede l'accesso alla GPU per il rendering 3D. La dockerizzazione delle app ha reso le cose più semplici da distribuire e gestire.
Matt,

17

Aggiornato per cuda-8.0 su Ubuntu 16.04

Dockerfile

FROM ubuntu:16.04
MAINTAINER Jonathan Kosgei <jonathan@saharacluster.com>

# A docker container with the Nvidia kernel module and CUDA drivers installed

ENV CUDA_RUN https://developer.nvidia.com/compute/cuda/8.0/prod/local_installers/cuda_8.0.44_linux-run

RUN apt-get update && apt-get install -q -y \
  wget \
  module-init-tools \
  build-essential 

RUN cd /opt && \
  wget $CUDA_RUN && \
  chmod +x cuda_8.0.44_linux-run && \
  mkdir nvidia_installers && \
  ./cuda_8.0.44_linux-run -extract=`pwd`/nvidia_installers && \
  cd nvidia_installers && \
  ./NVIDIA-Linux-x86_64-367.48.run -s -N --no-kernel-module

RUN cd /opt/nvidia_installers && \
  ./cuda-linux64-rel-8.0.44-21122537.run -noprompt

# Ensure the CUDA libs and binaries are in the correct environment variables
ENV LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-8.0/lib64
ENV PATH=$PATH:/usr/local/cuda-8.0/bin

RUN cd /opt/nvidia_installers &&\
    ./cuda-samples-linux-8.0.44-21122537.run -noprompt -cudaprefix=/usr/local/cuda-8.0 &&\
    cd /usr/local/cuda/samples/1_Utilities/deviceQuery &&\ 
    make

WORKDIR /usr/local/cuda/samples/1_Utilities/deviceQuery
  1. Esegui il contenitore

sudo docker run -ti --device /dev/nvidia0:/dev/nvidia0 --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm <built-image> ./deviceQuery

Dovresti vedere un output simile a:

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 8.0, CUDA Runtime Version = 8.0, NumDevs = 1, Device0 = GRID K520 Result = PASS


3
Ottengo il seguente output. cudaGetDeviceCount ha restituito 38 -> non è stato rilevato alcun dispositivo compatibile con CUDA Risultato = FAIL
Soichi Hayashi

Risposta in ritardo, ma significa che probabilmente non hai una GPU su quella macchina
Jonathan il

Una versione Cuda-9 sarebbe quasi uguale a questa?
huseyin tugrul buyukisik,

@huseyintugrulbuyukisik vedi questa risposta su askubuntu askubuntu.com/questions/967332/… , direi che potresti usare questa risposta come guida ma non ho lavorato con cuda 9 per confermare che si applicherebbero gli stessi passaggi
Jonathan

Non farlo in questo modo. Questo è alla vecchia maniera. Usa il nuovo modo. Vedi link alla mia risposta. Questo metodo è pieno di problemi.
Matt

3

Per utilizzare la GPU dal contenitore della finestra mobile, anziché utilizzare la finestra mobile nativa, utilizzare Nvidia-docker. Per installare la finestra mobile Nvidia utilizzare i seguenti comandi

curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey |  sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64/nvidia-
docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-docker
sudo pkill -SIGHUP dockerd # Restart Docker Engine
sudo nvidia-docker run --rm nvidia/cuda nvidia-smi # finally run nvidia-smi in the same container

1

Usa x11docker di mviereck:

https://github.com/mviereck/x11docker#hardware-acceleration dice

Accelerazione hardware

L'accelerazione hardware per OpenGL è possibile con l'opzione -g, --gpu.

Questo funzionerà immediatamente nella maggior parte dei casi con driver open source sull'host. Altrimenti dai un'occhiata a wiki: dipendenze delle funzionalità. I driver NVIDIA a sorgente chiuso richiedono alcune impostazioni e supportano meno opzioni del server x11docker X.

Questo script è davvero conveniente in quanto gestisce tutta la configurazione e l'installazione. Eseguire un'immagine docker su X con gpu è semplice come

x11docker --gpu imagename
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.