Comment automatiser l'apprentissage profond avec le cluster Kubernetes GPU

Ce guide devrait aider les chercheurs et les passionnés à automatiser et à accélérer facilement l’entraînement en profondeur avec leur propre cluster Kubernetes GPU.
Par conséquent, je vais expliquer comment facilement configurer un cluster GPU sur plusieurs serveurs de métal Ubuntu 16.04 et fournir quelques scripts utiles et des fichiers.yaml qui font l'intégralité de la configuration pour vous.

Par ailleurs: Si vous avez besoin d'un cluster GPU Kubernetes pour d'autres raisons, ce guide pourrait vous aider aussi.

Pourquoi ai-je écrit ce guide?
J'ai travaillé en interne pour le start-upComprendre.aiEt il a remarqué l’hassle de concevoir d’abord un algorithme d’apprentissage automatique localement et plutôt que de l’amener dans la nuée pour la formation avec différents paramètres et données.
La seconde partie, en le portant dans le nuage pour une formation approfondie, prend toujours plus longtemps que pensée, est frustrante et implique généralement beaucoup de pistes.

C'est pour cette raison que j'ai décidé de travailler sur ce problème et de faire de la deuxième partie sans effort, facile et rapide.
Le résultat de ce travail est ce guide pratique, qui décrit comment tout le monde peut configurer son propre cluster Kubernetes GPU pour accélérer leur travail.

Le nouveau processus pour les chercheurs d'apprentissage profond :
L’apprentissage en profondeur automatisé avec un cluster de GPU Kubernetes améliore considérablement le processus de préparation de votre algorithme pour l’apprentissage dans le cloud.

Cette illustration visualisera le nouveau flux de travail, qui implique seulement deux étapes simples:
My inspiration for the project, designed by Langhalsdino.

Disclaimer
Veuillez noter que les sections suivantes pourraient être évaluées. Kubernetes est un environnement évoluant, rapide, ce qui signifie que ce guide sera probablement obsolète parfois, en fonction du temps libre des auteurs et des contributions individuelles.

Table des contenus

Quick Kubernetes réveille

Ces articles pourraient être utiles, si vous avez besoin de renouveler vos connaissances Kubernetes:

Vue complète sur la structure du cluster

L'idée principale est, d'avoir un petit CPU uniquement le noyau maîtrisé, qui contrôle un groupe de nœuds de travailleur GPU. Rough overview on the structure of the cluster, designed by Langhalsdino

Démarrer les nodes

Avant que nous puissions utiliser le cluster, il est important d’abord d’initier le cluster.
Par conséquent, chaque node doit être initié manuellement et rejoint le cluster.

Les limites de ma configuration

Ce sont les contraintes pour ma configuration, j'ai été dans certains endroits plus rigoureux que nécessaire, mais c'est ma configuration et elle a fonctionné pour moi

Maître

  • Mise à jour de Ubuntu 16.04
  • Accès SSH avec utilisateur sudo
  • Accès Internet
  • UFO désactivé (pas recommandé, mais pour facilité d'utilisation)
  • Ports actifs (udp et tcp)
    • 6443, 443 et 8080
    • 30000-32767 (uniquement si vos applications en ont besoin)
    • Ceux-ci seront utilisés pour accéder aux services de l’extérieur du cluster.

travailleur

  • Mise à jour de Ubuntu 16.04
  • Accès SSH avec utilisateur sudo
  • Accès Internet
  • UFO désactivé (pas recommandé, mais pour facilité d'utilisation)
  • Ports actifs (udp et tcp)
    • 6443 et 443

Instructions de configuration

Ces instructions couvrent mon expérience sur Ubuntu 16.04 et peuvent ou ne peuvent pas être adaptées à la transmission à d'autres systèmes d'exploitation.

J'ai créé deux scripts qui initient complètement le noyau maître et travailleur comme décrit dans le bellow. Si vous voulez prendre la piste rapide, juste les utiliser.

Fast Track - Setup script

Ok, lets take the fast track. Copy the corresponding scripts on your master and workers.
Furthermore make sure that your setup fits into my constraints.

Maître Node

Exécutez le script d'initialisation et souvenez-vous du token ?
Le token sera comme ça :—token f38242.e7f3XXXXXXXXe231e.

chmod +x init-master.sh
sudo ./init-master.sh <IP-of-master>

Node de travailleur

Exécutez le script d'initialisation avec le token et l'IP correct de votre maître.
Le port est généralement6443.

chmod +x init-worker.sh
sudo ./init-worker.sh <Token-of-Master> <IP-of-master>:<Port>

Detailed step by step instructions

Maître Node

1.Ajouter Kubernetes Repository au gestionnaire d'emballages

sudo su -
apt-get update && apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
exit

2.Installation du moteur docker, kubectl, kubernetes-cni

sudo apt-get install -y docker-engine
sudo apt-get install -y kubelet kubeadm kubectl kubernetes-cni
sudo groupadd docker
sudo usermod -aG docker $USER
echo 'You might need to reboot / relogin to make docker work correctly'

3.Étant donné que nous voulons construire un cluster qui utilise des GPU, nous devons permettre l’accélération de GPU dans le noyau principal. Gardez à l'esprit que cette instruction peut devenir obsolète ou changer complètement dans une version ultérieure de Kubernetes!

3 I Ajouter le support GPU à la configuration Kubeadm, tandis que le cluster n'est pas initialisé.

sudo vim /etc/systemd/system/kubelet.service.d/<<Number>>-kubeadm.conf

append ExecStart avec le drapeau—feature-gates="Accelerators=true"Et ça va paraître comme ça :

ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS [...] --feature-gates="Accelerators=true"

3 IIRécupérer le cube

sudo systemctl daemon-reload
sudo systemctl restart kubelet

QuatreMaintenant, nous allons initialiser le noyau maître.
Vous aurez donc besoin de l’IP de votre noyau principal. En outre, cette étape vous fournira les crédits pour ajouter des nœuds de travailleur supplémentaires, donc rappelez-vous votre token ?
Le token sera comme ça :—token f38242.e7f3XXXXXXXXe231e 130.211.XXX.XXX:6443

sudo kubeadm init --apiserver-advertise-address=<ip-address>

5Depuis que Kubernetes 1.6 a changé d'ABAC roll-management à RBAC, nous avons besoin de publier les créances de l'utilisateur. Vous devrez effectuer cette étape pour chaque fois que vous vous connectez à la machine!!

sudo cp /etc/kubernetes/admin.conf $HOME/
sudo chown $(id -u):$(id -g) $HOME/admin.conf
export KUBECONFIG=$HOME/admin.conf

6.Installez un add-on réseau que vos sous peuvent communiquer les uns avec les autres. Kubernetes 1.6 a quelques exigences pour le add-on réseau, dont certaines sont:

  • Réseaux basés sur le CNI
  • Soutien RBAC

Ce GoogleSheet contient une sélection d’ajouts de réseau appropriés sur GoogleSheet-Network-Add-on-vergleich. Je vais utiliser des travaux d'onde, juste à cause de mes préférences personnelles ;)

kubectl apply -f https://git.io/weave-kube-1.6

5 et 2Vous êtes prêt à aller, peut-être vérifier vos sous pour confirmer que tout fonctionne ;)

kubectl get pods —all-namespaces

et n.Si vous voulez débarrasser votre maître, vous aurez besoin de réinstaller le noyau maître

sudo kubeadm reset

Node de travailleur

Le début devrait être connu pour vous et rendre ce processus beaucoup plus rapide ;)

1.Ajouter Kubernetes Repository au gestionnaire d'emballages

sudo su -
apt-get update && apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
exit

2.Installation du moteur docker, kubectl, kubernetes-cni

sudo apt-get install -y docker-engine
sudo apt-get install -y kubelet kubeadm kubectl kubernetes-cni
sudo groupadd docker
sudo usermod -aG docker $USER
echo 'You might need to reboot / relogin to make docker work correctly'

3.Étant donné que nous voulons construire un cluster qui utilise des GPU, nous devons permettre l’accélération de la GPU dans les nœuds du travailleur qui ont un GPU installé. Gardez à l'esprit que cette instruction peut devenir obsolète ou changer complètement dans une version ultérieure de Kubernetes!

3 I Ajouter le support GPU à la configuration Kubeadm, tandis que le cluster n'est pas initialisé.

sudo vim /etc/systemd/system/kubelet.service.d/<<Number>>-kubeadm.conf

append ExecStart avec le drapeau—feature-gates="Accelerators=true"Et ça va paraître comme ça :

ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS [...] --feature-gates="Accelerators=true"

3 IIRécupérer le cube

sudo systemctl daemon-reload
sudo systemctl restart kubelet

QuatreMaintenant, nous allons ajouter le travailleur au cluster.
Par conséquent, vous devrez se souvenir du token de votre noyau maître, donc prenez une profonde immersion dans vos notes xD

sudo kubeadm join --token f38242.e7f3XXXXXXe231e 130.211.XXX.XXX:6443

5Finis, vérifiez vos nœuds sur votre maître et voyez si tout a fonctionné.

kubectl get nodes

et n.Si vous voulez débarrasser votre node de travailleur, vous devrez supprimer le node du cluster et réinstaller le node de travailleur. En outre, il sera bénéfique de retirer le node ouvrier du cluster
sur le maître :

kubectl delete node <worker node name>

Le node du travailleur

sudo kubeadm reset

client

Pour contrôler votre cluster par exemple votre maître de votre client, vous aurez besoin d’authentifier votre client avec le bon utilisateur. Ce guide ne couvrira pas la création d'un utilisateur séparé pour le client, nous ne copierons que l'utilisateur du noyau principal.
Ça va être plus facile, croyez-moi
[Instructions pour ajouter un utilisateur personnalisé, sera ajouté à l'avenir]

1.Installez kubectl sur votre client. j'ai seulement testé sur may mac, mais Linux devrait aussi fonctionner. Je ne sais pas sur les fenêtres, mais qui s'occupe des fenêtres en tout cas :D
sur Mac

brew install kubectl

2.Copiez l'authentification admin du maître à votre client

scp [email protected]:~/admin.conf ~/.kube/

3.Ajouter la configuration admin.conf et les créances à la configuration Kubernetes. Vous aurez besoin de le faire pour chaque agent

export KUBECONFIG=~/.kube/admin.conf

Vous êtes prêt à utiliser Kubectl sur votre client local.

3 IIVous pouvez tester en listant tous vos sous

kubectl get pods —all-namespaces

Installer le panneau de couverture Kubernetes

Le panneau de couverture est assez beau et donne aux scripts comme moi un accès à beaucoup de fonctionnalités. Afin d’utiliser le panneau de bord dont vous aurez besoin pour que votre client fonctionne, RBAC vous assure

Vous pouvez effectuer ces étapes directement sur le maître ou de votre client

1.Vérifier si le panneau est déjà installé Kubectl obtient des pouces --all-namespaces <p>

2.Si le panneau n'est pas installé, installez-le ;)

kubectl create -f https://git.io/kube-dashboard

Si cela ne fonctionne pas vérifier si le conteneur défini dans le.yamlGit.io / cube-dashboardExiste. (Ce bug me coûte beaucoup de temps)

Pour avoir accès à votre panneau de bord, vous aurez besoin d’être authentifié avec votre client.

3.Proxy le dashboard à votre client

kubectl proxy

QuatreAccès au dashboard dans votre navigateur en visitant 127.0.0.1 : 8001/ui

Comment construire votre conteneur GPU

Ce guide devrait vous aider à obtenir un conteneur Docker en cours, qui a besoin d'accès GPU.

Pour ce guide, j’ai choisi de construire un conteneur Docker par exemple, qui utilise des binaires TensorFlow GPU et peut exécuter des programmes TensorFlow dans un ordinateur portable Jupyter.

Gardez à l’esprit que ce guide a été écrit pour Kubernetes 1.6, de sorte que d’autres modifications peuvent compromettre ce guide.

Les éléments essentiels de.yml

Pour obtenir votre GPU NVIDIA avec CUDA, vous devez passer le pilote NVIDIA et les bibliothèques CUDA dans votre conteneur. Ainsi, nous allons utiliser HostPath pour les rendre disponibles sur le pod Kubernetes. Le chemin réel diffère de machine à machine, car ils sont définis par votre pilote NVIDIA et l'installation CUDA.

volumes:
    - hostPath:
        path: /usr/lib/nvidia-375/bin 
        name: bin
    - hostPath:
        path: /usr/lib/nvidia-375
        name: lib

Montrez les volumes avec le conducteur et le CUDA dans le bon catalogue pour votre conteneur. Ces volumes peuvent varier en raison des exigences spécifiques de votre conteneur.

volumeMounts:
    - mountPath: /usr/local/nvidia/bin
        name: bin
    - mountPath: /usr/local/nvidia/lib
        name: lib

Comme vous voulez dire à Kubernetes que vous avez besoin de GPU, vous pouvez définir vos exigences ici.

resources:
    limits:
        alpha.kubernetes.io/nvidia-gpu: 1

Ainsi, c'est tout ce dont vous avez besoin pour construire votre conteneur Kuberntes 1.6.

Quelques notes à la fin, qui décrivent mon expérience générale:
Kubernetes + Docker + Machine Learning + GPU = Sensibilité pure

Exemple de GPU

Mon exemple-gpu-deployment.yaml fichier décrit deux parties, un déploiement et un service, puisque je veux faire de jupyter notebook disponible la forme extérieure.

Run kubectl s'applique pour le rendre disponible à l'extérieur

kubectl create -f deployment.yaml

Le fichier deployment.yaml ressemble à ceci :

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: tf-jupyter
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: tf-jupyter
    spec:
      volumes:
      - hostPath:
          path: /usr/lib/nvidia-375/bin
        name: bin
      - hostPath:
          path: /usr/lib/nvidia-375
        name: lib
      containers:
      - name: tensorflow
        image: tensorflow/tensorflow:0.11.0rc0-gpu
        ports:
        - containerPort: 8888
        resources:
          limits:
            alpha.kubernetes.io/nvidia-gpu: 1
        volumeMounts:
        - mountPath: /usr/local/nvidia/bin
          name: bin
        - mountPath: /usr/local/nvidia/lib
          name: lib
---
apiVersion: v1
kind: Service
metadata:
  name: tf-jupyter-service
  labels:
    app: tf-jupyter
spec:
  selector:
    app: tf-jupyter
  ports:
  - port: 8888
    protocol: TCP
    nodePort: 30061
  type: LoadBalancer
---

Quelques commandes utiles

Obtenez les commandesavec la production de base

kubectl get services                 # List all services in the namespace
kubectl get pods --all-namespaces    # List all pods in all namespaces
kubectl get pods -o wide             # List all pods in the namespace, with more details
kubectl get deployment my-dep        # List a particular deployment

Décrivez les commandesAvec une production verbale

kubectl describe nodes <node-name>
kubectl describe pods <pod-name>

Supprimer les ressources

kubectl delete -f ./pod.yaml                   # Delete a pod using the type and name specified in pod.yaml
kubectl delete pod,service baz foo             # Delete pods and services with same names "baz" and "foo"
kubectl delete pods,services -l name=<Label>   # Delete pods and services with label name=myLabel
kubectl -n <namespace> delete po,svc --all     # Delete all pods and services in namespace my-ns

Rendez-vous sur la console bashde l’un de vos sous :

kubectl exec -it <pod-name> — /bin/bash

Problèmes communs

Certaines personnes m'ont contacté avec quelques questions sur leur déploiement de CUDA liées à l'expédition des conducteurs.
Si l'exemple-gpu-deployment.yaml ne fonctionne pas pour vous, je vous conseille d'essayer d'installer CUDA comme décrit dans ce guideInstaller Tenserflow sur Ubuntuen plus de détails et essayez l'exemple-gpu-déploi-nvidia-375-82.yaml. Il peut être nécessaire d'ajuster le numéro de version dans le fichier yaml.

Si vous avez rencontré un autre problème, vous vous sentez libre d'ouvrir un problème sur GitHub.

Reconnaissance

Il y a beaucoup de guides, de repositaires de GitHub, de questions et des gens là-bas qui m'ont beaucoup aidé.
Je voudrais remercier tous pour leur aide.
Surtout le start-upComprendre.aipour leur soutien.

Auteur

Licence

Ce projet est licencé sous la licence MIT - voir leMéditerranée.mdfichier pour les détails