查看原文
其他

保姆级神器,再也不用担心搞崩了!

Jack Cui 2022-07-26

吕昱峰 | https://zhuanlan.zhihu.com/p/422462131

大家好,我是 Jack。

所谓工欲善其事,必先利其器。

做深度学习相关的任务,GPU 不可或缺,但是等到买了一堆卡,配置好了裸机之后,问题也就接踵而来了。

由于是经验总结,也不避讳什么,相信下面的情况各个组里的同学都有遇到过:

  • 实验室多人混用一个物理机,来个小白装库分分钟给你把环境乃至系统搞崩了;
  • 没有清晰的存储区域划分,/root或者/home/user_name 代码数据乱放,随时满;
  • 多人使用一台物理机需要抢占;
  • 实验室新人不敢让他碰环境,老人又不想当运维;
  • 有的人爱在终端起任务,有的人爱开notebook写;
  • 。。。。

今天,给大家带来一款神器,解决这些的痛点!

实验室GPU管理的需求


  1. 环境稳定!环境稳定!环境稳定!重要的事情说三遍!没有人希望公用的环境时不时的崩了,而且高校基本上不存在运维的人(名义上招进来实际在干啥相信同学们也知道)。
  2. 兼容性好,即可以满足各种版本的Nvidia-driver+CUDA+框架的组合。为什么?因为你要复现别人的代码啊,起码要跑一下吧,作者能给开源就不错了,不会给你持续更新,你只能装人家readme要求的版本。这时候物理机装着一大堆的环境,不断升级降级,换谁不崩溃。
  3. 升级+维护简单。理由也很简单,因为没有运维。
  4. 屏蔽物理机权限(开docker镜像),谁刚来都可能是小白,但谁也都不希望小白给自己瞎整,甚至给小白擦屁股。
  5. 任务式管理。如果遇上需要抢占显卡的情况,能够排队。相信一起共用物理机的同学都体会过kill和被kill进程的“快感”。

Determined——完美的解决方案

Determined是一家国外创业公司做的集群管理+可视化作业+模型调优一体的解决方案,当然这里我选择它的原因主要还是集群管理。从2019年开始我就在各处找合适的方案,期间也用过微软的OpenPAI,基本能够满足上述的1,2,4,5。但是难受就难受在环境依赖一大堆,科学上网只要不稳,升个级要费上好几天。手动改了一些shell脚本替换成国内源,但是更新了几个大版本要跟着改,实验室就我一个人会升级,就很难顶。

下面再说说为什么Determined是完美解决方案:

  1. 安装只需要一个Python包,pip install一下就OK了。包括升级也是一行搞定,省事。
  2. 操作系统随便apt update/upgrade, nvidia-driver随便升级最新版,不影响使用。
  3. 只有docker本身pull镜像依赖科学上网。
  4. 前面提到的所有GPU管理的需求都能满足。

说白了,安装简单,升级没限制,用起来舒适。

Determined安装

这里就事无巨细的把所有的安装步骤都写一下,当然官网文档其实写的已经很清楚了,先放个链接:

https://docs.determined.ai/latest/sysadmin-deploy-on-prem/index.html

下面开始进行安装步骤说明:

1. 安装全新的Ubuntu系统,建议选择18.04或20.04的长期维护版。

为什么选择Ubuntu?CentOS官方已经放弃了,另外apt直装nvidia-driver非常友好,非要用run包的请绕道。

2. 安装Docker

这里给出两个安装方式,首先是determined官方给的方式(注意此方式需要科学上网):

sudo apt-get update && sudo apt-get install -y software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

sudo apt-get update && sudo apt-get install -y --no-install-recommends docker-ce
sudo systemctl reload docker
sudo usermod -aG docker $USER

或者:

sudo apt install docker.io
3. 安装nvidia-container-toolkit

用于Docker容器内调用GPU(注意需要科学上网)

curl -fsSL https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
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 --no-install-recommends nvidia-container-toolkit
sudo systemctl restart docker
4. 配置docker代理,方便后续pull镜像能够顺利

创建配置文件目录和配置文件

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo touch /etc/systemd/system/docker.service.d/http-proxy.conf

添加HTTP_PROXY环境变量。其中[proxy-addr]和[proxy-port]分别改成实际情况的代理地址和端口:

[Service]
Environment="HTTP_PROXY=http://[proxy-addr]:[proxy-port]/"
Environment="HTTPS_PROXY=https://[proxy-addr]:[proxy-port]/"

更新配置并重启Docker

systemctl daemon-reload
systemctl restart docker

最后查看一下是否生效

docker info

输出中包含如图的HTTP PROXY和HTTPS PROXY即可。

5. 安装Determined
pip install determined

至此安装准备工作完成,下面进行集群配置。

Determined集群配置

先放一个Determined的AWS部署图,本地部署结构也是类似的:

可以看到Determined集群节点由一个Master和无数个Agent构成,其中Master作为Client访问入口,即通过网页、CLI等方式发起请求,通过Master发送到agents进行调度。此外还需要有独立的存储位置。

这里给出一套简单的集群配置:

  1. Master节点1个,简单的server,不需要GPU
  2. 存储节点1个,具体空间自定,建议不小于4T(可与Master为同一节点)
  3. Agent节点若干,GPU服务器,建议将同型号卡分组
  4. 万兆交换机连接,保证网络存储速度。

首先将所有节点连接到同一局域网,并按照上面的安装教程安装给所有机器安装依赖环境(Master和存储节点不需要安装nvidia相关的内容)

然后启动Master节点:

det deploy local master-up

一般直接启动即可,web访问端口为8080,有具体配置需求可以参考详细配置文档。

然后配置GPU节点,这里需要将不同型号的卡进行分组,需要配置yaml文件:

## The hostname or IP address of the Determined master.
master_host: ip_of_your_master_node
## The port of the Determined master.
master_port: 8080

## The ID of this agent; defaults to the hostname of the current machine. Agent IDs must be unique
## within a cluster.
agent_id: rtx3090_0
## The label of this agent. Agents with labels may only run workloads with the
## corresponding label.
label: rtx3090

## The GPUs that should be exposed as slots by the agent. A comma-separated list of GPUs,
## each specified by a 0-based index, UUID, PCI bus ID, or board serial number.
http_proxy: ip_of_proxy
https_proxy: ip_of_proxy

这里主要配置3个内容:

  • Master节点,用于识别Master节点
  • agent_id和label,分别对应本机id和组名,根据显卡型号命名即可
  • 科学上网代理

完成后,所有agent节点使用如下命令启动:

docker run --gpus all -v /var/run/docker.sock:/var/run/docker.sock -v "$PWD"/agent-config.yaml:/etc/determined/agent.yaml determinedai/determined-agent:0.15.6

注意最后的版本号要和安装的determined版本号对应,一般为最新。

除此之外,还需要讲存储节点进行分布式存储的配置,一般可以采用NFS或者Ceph,这里给出NFS的配置教程和Ceph官方文档,可参考配置,具体步骤不再赘述:

https://docs.ceph.com/en/pacific/ https://ubuntu.com/server/docs/service-nfs

注意:所有Agent挂载存储到同一位置,如/mnt/data,才能保证任意任务都可以使用同一配置启动。

使用Determined

Determined主要有两种使用方式,Web和CLI。其中web可以直接通过Master节点IP:8080进行访问,具体界面如下:

可以直接通过网页端创建任务(不推荐)。

这里详细介绍CLI的用法,因为网页端创建任务无法自定义存储路径和加载的Docker镜像,灵活度十分受限。

  1. 在终端机安装determined,pip install determined即可
  2. 在环境变量配置MASTER节点IP
nano ~/.bashrc
# 添加如下内容:
# export DET_MASTER=ip_of_your_master_node
source ~/.bashrc
  1. 使用determined cli创建任务

首先需要登录:

det user login
# 输入账号密码即可

admin用户可以管理用户添加删除,具体参考用户管理文档。

然后写一个开启任务的yaml配置文件,这里给出一个参考:

description: your_task_name
resources:
  agent_label: rtx3090
  slots: 1
bind_mounts:
  - host_path: /mnt/dl/lvyufeng/
    container_path: /run/determined/workdir/lv/
environment:
  image: determinedai/environments:cuda-11.1-pytorch-1.9-lightning-1.3-tf-2.4-gpu-0.16.3
  environment_variables:
  - http_proxy=your_proxy
  - https_proxy=your_proxy

以上涵盖了开启任务所需的基本设置,包括:

  • description: 任务名
  • resources: 要开启任务的GPU类型(对应label)和数量(对应slots)
  • bind_mounts: 挂载分布式存储到docker容器内,host_path为物理机路径(这是为什么我上面让所有agent设置同一个路径的原因),container_path为容器内路径,建议使用/run/determined/workdir/xxx, 因为notebook默认路径为/run/determined/workdir/这样进入即可使用。
  • environment: docker容器的环境配置,包括使用的镜像和环境变量。

完成后,可以选择开启notebook或者cmd终端,这取决于使用者的习惯。

# notebook
det notebook start --config-file config.yaml
# shell
det shell start --config-file config.yaml

这里还有一个比较实用的用法,VSCode配合Shell进行远程调试,可以参考官网文档使用:

https://docs.determined.ai/latest/features/commands-and-shells.html#visual-studio-code

自定义Docker镜像

安装和使用都OK之后,部分同学会有自定义Docker镜像的需求,即修改:

environment:
  image: determinedai/environments:cuda-11.1-pytorch-1.9-lightning-1.3-tf-2.4-gpu-0.16.3

自定义Docker镜像可以把自己需要的环境打包,如我个人需要的ROUGE包或者MindSpore环境,均可以通过自定义镜像完成,后续直接pull自己的镜像即可。

由于Determined官方其实给出了很多个版本的cuda和框架的组合,这里先给出链接供大家直接使用:

https://hub.docker.com/r/determinedai/environments/tags

大多数常用的环境都已经打包好,这里就不多说了。下面说一下自定义镜像的方法:

1. 克隆官方environments仓库
git clone https://github.com/determined-ai/environments
2. 添加想要安装的环境相关命令
cd det_dockerfile_scripts
touch your_script.sh
# add install instructions to your_script.sh
3. 修改Dockerfile
nano Dockerfile-base-gpu
# add `RUN /tmp/det_dockerfile_scripts/your_script.sh`
4. 参考Makefile里的命令打包Docker镜像,然后上传到dockerhub

这里不给出Docker镜像打包的教程,如有需求可以自行搜索,determined官方已经给出了非常完整的打包脚本,根据readme修改和运行即可。

结语

实验室用个GPU不容易,总之用Determined属于一劳永逸,后续再来新人随便在Docker容器里造,也没多大关系,如果你们还在苦哈哈的一起用同一台物理机,时不时因为环境崩溃导致人也崩溃了。

另外,环境搞不好从来不是research做不下去的理由,现在的调参侠们可能真的连装环境这种基础技能都没有,也能吃大组红利刷顶会,何其哀哉!大概就这样吧。

·················END·················

推荐阅读

•   我家小孩,长这样?•   获奖了!•   我,从高考到程序员的成长之路

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存