发布在即!企业 AIGC 应用程度测评,3 步定制专属评估报告。抢首批测评权益>>> 了解详情
写点什么

如何使用 Kubernetes GPU 集群自动化深度学习训练

  • 2017-07-12
  • 本文字数:5940 字

    阅读完需:约 19 分钟

本文最初发布于 GitHub ,经原作者授权由 InfoQ 中文站翻译并分享。

该指南能帮助同行研究者和爱好者们轻松地使用 Kubernetex GPU 集群来自动化和加速他们的深度学习训练。因此,我将解释如何轻松地在多个 Ubuntu 16.04 裸机服务器上搭建一个 GPU 集群,并提供一些有用的脚本和.yaml 文件来完成这些工作。

另外,如果你需要把 Kubernetes GPU 集群用于其他地方,该指南可能对你也有帮助。

为什么写这个指南?

我一直在创业公司 understand.ai 实习,在那里我留意到了一个麻烦:首先得在本地设计一个机器学习算法,然后将其放到云上用不同的参数和数据集来训练模型。这第二步,将算法放到云上进行全面的训练,所耗费的时间要比想象的更长,通常让人很沮丧而且涉及到很多陷阱。

因此,我决定解决这个问题,让第二步变得容易、简单和快捷。

我写了这篇很有用的指南,描述了每个人如何设置他们自己的 Kubernetes GPU 集群来加速他们的工作。

给深度学习研究者的新处理过程:

用 Kubernetes GPU 集群进行自动化的深度学习训练,它能极大地改进在云上训练模型的过程。

(点击放大图像)

声明

下面的章节可能有些武断。Kubernetes 是一个进化的、快节奏的环境,这就意味着这个指南很可能会在某个时间过时,这取决于作者的空余时间和个人贡献。因此,非常感谢对此的贡献。

Kubernetes 快速参考

如果你需要重温下 Kubernetes 知识,下面这些文章很有用。

集群结构粗览

核心想法是用一个很小的只有 CPU 的 master 节点来控制一组 GPU worker 节点。

(点击放大图像)

初始化节点

在我们使用集群之前,要先对其初始化,这一点很重要。因此,要手动地初始化每个节点,随后将它加入集群中。

我的设置

该配置非常适合这里所描述的用例。对其他用例、操作系统等,需要进一步地调整配置。

Master

  • Ubuntu 16.04 带 root 权限
    • 我用了一个 Google Compute Engine VM 实例
  • SSH 权限
  • 停用 ufw
  • 可用端口(udp 和 tcp)
    • 6443,443,8080
    • 30000-32767(仅在需要时激活)
    • 这些将被用于获取集群外部的服务

Worker

  • Ubuntu 16.04 带 root 权限
    • 我用了一个 Google Compute Engine VM 实例
  • SSH 权限
  • 停用 ufw
  • 可用端口(udp 和 tcp)
    • 6443,443

关于安全:当然,如果你想在产品中使用,就应该启用某些防火墙;这里出于简单考虑我停用了 ufw。设置 Kubernetes 以用于实际的产品中,理所当然应该启用某些防火墙如 ufw、iptables 或者你的云提供商的防火墙。在云上设置集群会更加复杂。通常云提供商的防火墙与主机级别的防火墙是分开的。你可能需要停用 ufw、并开启云提供商防火墙的规则来让这篇文档里的步骤生效。

设置指南

这些指南涵盖了我在 Ubuntu 16.04 的经验,对其他操作系统可能适用,也可能不适用。

我创建了两个脚本对 master 和 worker 节点完全初始化。脚本如下所示。如果你想用快速通道,可以直接使用这些脚本。否则,我建议你阅读一步一步的指南。

快速通道设置脚本

将下面相应的脚本拷贝到你的 master worker 上。

MASTER 节点

运行初始化脚本,记下token。

Token 的格式类似于–token f38242.e7f3XXXXXXXXe231e。

复制代码
chmod +x init-master.sh
sudo ./init-master.sh <IP-of-master>

WORKER 节点

运行初始化脚本,使用正确的 token 和 master IP。

端口通常是 6443。

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

详细的一步一步指南

MASTER 节点

1. 将 Kubernetes Repository 加入 packagemanager

复制代码
sudo bash -c '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'

2. 安装 docker-engine、kubeadm、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. 由于我们想创建一个使用 GPU 的集群,我们要在 master 节点上启用 GPU 加速功能。记住,在 Kubernetes 之后的版本中,这一步可能被淘汰了或者完全更改了。

3.I 在集群初始化之前,添加 GPU 支持到 Kubeadm 配置。

这一步必须对集群中的每一个节点进行,即使某些节点没有 GPU。

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

因此,在 ExecStart 后追加上标签–feature-gates=“Accelerators=true”,最终格式如下:

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

3.II 重启 kubelet

复制代码
sudo systemctl daemon-reload
sudo systemctl restart kubelet

4. 现在初始化 master 节点。

你需要 master 节点的 IP。而且,这一步会向你提供认证信息,用于添加 worker 节点,因为要记住你的 token。

Token 的格式类似于–token f38242.e7f3XXXXXXXXe231e 130.211.XXX.XXX:6443。

复制代码
sudo kubeadm init --apiserver-advertise-address=<ip-address>

5. 由于 Kubernetes 1.6 从 ABAC 卷管理变成了 RBAC 式,因此我们需要向用户公布认证信息。每一次登录机器,都需要执行这一步。

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

6. 安装网络插件让节点能相互通信。Kubernetes 1.6 对网络插件有一些要求,如:

  • 基于 CNI 的网络
  • RBAC 支持

这篇 GoogleSheet 文档包含很多合适的网络插件。链接: GoogleSheet Network Add-on comparison

出于个人的偏好,我会使用 wave-works。

复制代码
kubectl apply -f https://git.io/weave-kube-1.6

7. 现在都设置好了。检查所有的 pod 都在线上,确认一切运转顺利。

复制代码
kubectl get pods --all-namespaces

N. 如果你想撤掉 master 节点,你需要重置它。

复制代码
sudo kubeadm reset

WORKER NODE

前面几步对你而言应该很熟悉了,能让进程加快一些。

1. 将 Kubernetes Repository 加入 packagemanager

复制代码
sudo bash -c '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'

2. 安装 docker-engine、kubeadm、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. 由于我们想创建一个使用 GPU 的集群,我们要在 master 节点上启用 GPU 加速功能。记住,在 Kubernetes 之后的版本中,这一步可能被淘汰了或者完全更改了。

3.I 在集群初始化之前,添加 GPU 支持到 Kubeadm 配置。

这一步必须对集群中的每一个节点进行,即使某些节点没有 GPU。

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

因此,在 ExecStart 后追加上标签–feature-gates=“Accelerators=true”,最终格式如下:

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

3.II 重启 kubelet

复制代码
sudo systemctl daemon-reload
sudo systemctl restart kubelet

4. 现在我们将 worker 加入到集群中。

你需要记住 master 节点的 token,所以查看下节点。

复制代码
sudo kubeadm join --token f38242.e7f3XXXXXXe231e 130.211.XXX.XXX:6443

5. 完成。在 master 上检查节点,看看是否一切运转顺利。

复制代码
kubectl get nodes

N. 如果你想撤掉 worker 节点,你需要将该节点从集群中移除,然后重置该节点。从集群中移除 worker 节点是很有帮助的。

在 master 节点上:

复制代码
kubectl delete node <worker node name>

在 worker 节点上

复制代码
sudo kubeadm reset

客户端

为了控制你的集群,如从客户端控制 master,你需要对客户端的正确用户进行认证。该指南中并没有为客户端创建一个单独的用户,我们只是从 master 节点复制用户。相信我,这样做会更简单。

[会在将来加入如何添加用户的指导]

1. 在客户端安装 kubectl。我只在 mac 上测试过,但应该也适用 linux。我不知道是否适用于 windows,但又有谁关心 windows 呢。

Mac

复制代码
brew install kubectl

Ubuntu 你要么遵循官方指南 https://kubernetes.io/docs/tasks/tools/install-kubectl/ ,要么从上面的 worker 指南中提取需要的步骤(可能只在 Ubuntu 上可行)。

2. 将 master 的 admin 认证拷贝到客户端。

复制代码
scp uai@130.211.XXX.64:~/admin.conf ~/.kube/

3. 将 admin.conf 配置和认证信息添加到 Kubernetes 配置中。你需要对每个代理都执行该步骤。

复制代码
export KUBECONFIG=~/.kube/admin.conf

你可以在本地的客户端上使用 kubectl 了。

4. 你可以测试列出所有的 pod

复制代码
kubectl get pods --all-namespaces

安装 Kubernetes dashboard

Kubernetes dashboard 非常的漂亮,它向那些跟我一样喜欢摆弄脚本的人提供了很多功能。要使用 dashboard 的话,你需要让客户端运行,RBAC 会确保这一点。

你可以直接在 master 节点上或者从客户端运行下面的步骤。

1. 检查已经安装了 dashboard: kubectl get pods --all-namespaces | grep dashboard

2. 如果没有安装,则安装它

复制代码
kubectl create -f https://git.io/kube-dashboard

如果不成功,检查.yaml 中定义的容器 git.io/kube-dashboard 是否存在。(这个软件故障曾让我花费了很多时间)

为了能访问你的 dashboard,你需要在客户端进行认证。

3. 添加 dashboard 代理到客户端。

在客户端运行:

复制代码
kubectl proxy

4. 用浏览器访问 dashboard,访问 127.0.0.1:8001/ui。

如何构建你的 GPU 容器

这里帮助你运行一个需要 GPU 权限的 Docker 容器。

在该指南中,我选择创建一个 Docker 容器的例子,它用 TensorFlow GPU 二进制文件,并能在 Jupyter 笔记本中运行 TensorFlow 程序。

请记住,该指南适用于 Kubernetes 1.6,因此可能不适用于今后的变化。

.yml 的关键部分

为了能够让你的带 CUDA 的 Nvidia GPU 运行,你需要将 Nvidia 驱动和 CUDA 库文件传给容器。因此,我们将使用 hostPath,让 Kubernetes pod 能访问它们。实际的路径因机器而异,因为它们是由 Nvidia 驱动和 CUDA 安装程序来设置的。

复制代码
volumes:
- hostPath:
path: /usr/lib/nvidia-375/bin
name: bin
- hostPath:
path: /usr/lib/nvidia-375
name: lib

将包含有驱动和 CUDA 的卷加载到容器中的正确目录下。根据你的容器的具体要求,这些设置可能有所不同。

复制代码
volumeMounts:
- mountPath: /usr/local/nvidia/bin
name: bin
- mountPath: /usr/local/nvidia/lib
name: lib

因为你要告诉 Kubernetes 你需要 n 个 GPU,所以你可以在这里定义这些需求。

复制代码
resources:
limits:
alpha.kubernetes.io/nvidia-gpu: 1

这就是你需要创建 Kuberntes 1.6 容器的所有东西。

这是我的所有经验:

Kubernetes + Docker + Machine Learning + GPUs = 顶呱呱

GPU 部署例子

文件 example-gpu-deployment.yaml 描述了两部分,部署和服务,因为我想让 juptyer 笔记本能被外部访问。

运行 kubectl 来让其对外可见。

复制代码
kubectl create -f deployment.yaml

文件 deployment.yaml 内容如下:

复制代码
---
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
---

为了验证这些设置是正确的,你可以访问 JupyterNotebook 实例,链接是 http://:30061。

现在我们要验证你的 JupyterNotebook 实例可以访问 GPU。因此,在一个新的笔记本中运行下面的程序。它将列出 tensorflow 可用的所有服务。

复制代码
from tensorflow.python.client import device_lib
def get_available_devices():
local_device_protos = device_lib.list_local_devices()
return [x.name for x in local_device_protos]
print(get_available_devices())

输出结果应该类似于 [u’/cpu:0’, u’/gpu:0’]。

一些有用的命令

Get 命令,输出基本信息

复制代码
kubectl get services # 列出该命名空间的所有服务
kubectl get pods --all-namespaces # 列出所有命名空间的所有 pod
kubectl get pods -o wide # 列出该命名空间的所有 pod,给出细节
kubectl get deployments # 列出所有部署
kubectl get deployment my-dep # 列出给定部署

Describe 命令,输出冗长的信息

复制代码
kubectl describe nodes <node-name>
kubectl describe pods <pod-name>

删除资源

复制代码
kubectl delete -f ./pod.yaml # 删除 pod,其类型和名字被定义在 pod.yaml 中
kubectl delete pod,service baz foo # 删除名字为“baz”和“foo”的 pod 和服务
kubectl delete pods,services -l name=<myLabel> # 删除标签名为 myLabel 的 pod 和服务
kubectl -n <namespace> delete po,svc --all # 删除命名空间 my-ns 的所有 pod 和服务

进入某个 pod 的 bash 控制台:

复制代码
kubectl exec -it <pod-name> -- /bin/bash

致谢

有很多指南、github 仓库、问题和帮助过我的人们。

我想感谢每一个人的帮助。

特别感谢创业公司 understand.ai 的支持。

作者

Frederic Tausch - 原创 - Langhalsdino

许可

该项目采用 MIT 许可,具体细节请查看 LICENSE.md 文件。

查看英文原文: How to automate deep learning training with Kubernetes GPU-cluster

感谢陈思对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

公众号推荐:

2024 年 1 月,InfoQ 研究中心重磅发布《大语言模型综合能力测评报告 2024》,揭示了 10 个大模型在语义理解、文学创作、知识问答等领域的卓越表现。ChatGPT-4、文心一言等领先模型在编程、逻辑推理等方面展现出惊人的进步,预示着大模型将在 2024 年迎来更广泛的应用和创新。关注公众号「AI 前线」,回复「大模型报告」免费获取电子版研究报告。

AI 前线公众号
2017-07-12 17:206784
用户头像

发布了 21 篇内容, 共 88413 次阅读, 收获喜欢 3 次。

关注

评论 1 条评论

发布
用户头像
但是这里似乎没有涉及到gpu的调度相关,只是自己指定了gpu,那么使用k8s的目的是什么?我们平时训练深度学习任务也可以直接在代码中指定gpu啊
2019-12-06 16:14
回复
没有更多了
发现更多内容

任务调度之时间轮实现 | 京东云技术团队

京东科技开发者

定时任务 数据结构与算法 时间轮 企业号 7 月 PK 榜

程序员「求生宝典」!AI大发展下的程序员求生指南,干货满满

Openlab_cosmoplat

为什么强调数智底座能力?

用友BIP

数智底座

用友BIP:助力企业数智化转型,实现数智化国产替代

用友BIP

国产替代

从TL、ITL到TTL | 京东物流技术团队

京东科技开发者

ThreadLocal ThreadLocalMap 企业号 7 月 PK 榜

识别led显示屏扫描方式及常见分类指南

Dylan

分类 识别 扫描 LED显示屏

火山引擎DataLeap如何解决SLA治理难题(一):应用场景与核心概念介绍

字节跳动数据平台

数据中台 数据治理 SLA 数据研发 企业号 7 月 PK 榜

Nautilus Chain NautDID NFT 将上主网,Layer3 数字身份时代开启

西柚子

Seal AppManager如何基于Terraform简化基础设施管理

SEAL安全

Kubernetes Terraform 平台工程 SealAppManager 企业号 7 月 PK 榜

NFTScan | 07.10~07.16 NFT 市场热点汇总

NFT Research

NFT\

WiFi 7 (802.11be)-IPQ9574+QCN9274-ultra-wide 320 MHz spectrum channel

wifi6-yiyi

qcn9274 WiFi 7 802.11be

六步带你体验EDS交换数据全流程

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 7 月 PK 榜

大模型时代,科技企业入局能源行业需要新范本

TE智库

新能源 特斯联

华为云云原生数据库,让企业离应用更进一步

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 7 月 PK 榜

基于ClickHouse解决活动海量数据问题 | 京东云技术团队

京东科技开发者

数据库 Clickhouse 数据处理 企业号 7 月 PK 榜

七年老程序员的五六月总结:十一件有意义的事

拭心

android 程序员 程序人生 成长记录

等保测评包过是真的吗?安全吗?

行云管家

等保 等级保护 等保测评

数智底座成竞争焦点,用友能否再创辉煌?

用友BIP

数智底座

大型民营集团如何构建全面预算管理体系?

用友BIP

全面预算

等保定级标准是怎样的?是否系统定级越低越好?

行云管家

网络安全 等保 堡垒机 等级

灵活预算,畅享高性能!月付香港主机助你建设理想网站!

一只扑棱蛾子

香港主机

何为低代码?何为高代码?

互联网工科生

软件开发 低代码 JNPF 高代码

如何学习ABAQUS有限元仿真分析软件

思茂信息

abaqus abaqus软件 abaqus有限元仿真 有限元分析 有限元仿真

一文了解什么是ISO 9001认证,以及在静态分析和代码质量领域有哪些通过此认证的工具

龙智—DevSecOps解决方案

代码扫描 静态代码分析 代码分析

手机直播app源码部署搭建:带货潮流,商城功能!——山东布谷科技创作

山东布谷科技

软件开发 直播 源码搭建 直播APP源码 手机直播源码

常用语言的线程模型(Java、go、C++、python3) | 京东云技术团队

京东科技开发者

Java c++ Go 线程模型 企业号 7 月 PK 榜

书画家点赞!基于飞桨绘制中国水墨山水画

飞桨PaddlePaddle

人工智能 paddle 飞桨 百度飞桨 AIGC

应对618、双十一等大促期间的高负载,API性能测试应该怎么做?负载测试、基线测试、冒烟测试、浸泡测试、峰值测试和尖峰测试详解

龙智—DevSecOps解决方案

自动化测试 API 测试自动化

含CPU芯片的PCB可制造性设计问题详解

华秋PCB

工具 芯片 PCB PCB设计 可制造性

一文了解JNPF低代码开发平台

高端章鱼哥

低代码 低代码开发 JNPF

如何使用Kubernetes GPU集群自动化深度学习训练_语言 & 开发_Frederic Tausch_InfoQ精选文章