新购 续费 升级
超多折扣优惠
阿里云服务器限时两折起
年付每月仅需24元,低至0.73元/天起
阿里云服务器ECS    
弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新 [咨询更多]
阿里云存储OSS
简单易用、多重冗余、数据备份高可靠、多层次安全防护安全性更强、低成本 [咨询更多]
阿里云数据库RDS
稳定可靠、可弹性伸缩、更拥有容灾、备份、恢复、监控、迁移等方面的全套解决方案 [咨询更多]
阿里云安全产品
DDoS高防IP、web应用防火墙、安骑士、sll证书、态势感知众多阿里云安全产品热销中 [咨询更多]
阿里云折扣优惠    
云服务器ECS、数据库、负载均衡等产品新购、续费、升级联系客服获取更多专属折扣 [咨询更多]
阿里云GPU云服务器机器学习
2020-11-11    点击量:

  典名科技本文介绍阿里云服务器GPU云服务器机器学习,如何在GPU实例上安装和使用cGPU服务,FastGPU构建一键训练任务,希望对您有所帮助。

  使用cGPU服务隔离GPU资源


  cGPU服务可以隔离GPU资源,实现多个容器共用一张显卡。典名科技介绍如何在GPU实例上安装和使用cGPU服务。
  
  前提条件

  安装cGPU服务前,请完成以下准备工作:
  提交工单获取cGPU安装包下载链接。
  确保GPU实例满足以下要求:
  GPU实例规格为gn6i、gn6v、gn6e、gn5i、gn5、ebmgn6i或ebmgn6e。
  GPU实例操作系统为CentOS 7.6、CentOS 7.7、Ubuntu 16.04、Ubuntu 18.04或Aliyun Linux。
  GPU实例已安装418.87.01或更高版本的NVIDIA驱动。
  GPU实例已安装19.03.5或更高版本的Docker。
  
  背景信息    为了提高GPU硬件资源的利用率,需要在单张显卡上运行多个容器,并在多个容器间隔离GPU应用。
  
  阿里云cGPU服务通过自研的内核驱动为容器提供虚拟的GPU设备,在保证性能的前提下隔离显存和算力,为充分利用GPU硬件资源进行训练和推理提供有效保障。您可以通过命令方便地配置容器内的虚拟GPU设备。
  
  使用cGPU服务具有以下优势:
  适配开源标准的Kubernetes和NVIDIA Docker方案。
  无需重编译AI应用,无需替换CUDA库,升级CUDA、cuDNN的版本后无需重新配置。
  支持同时隔离显存和算力。

安装cGPU服务

  1. 下载并解压cGPU安装包。
  2. 查看安装包文件。
    说明 安装包版本不同时,安装包中包含的文件可能不同。
    # cd cgpu
    # ls
    cgpu-container-wrapper  cgpu-km.c  cgpu.o  cgpu-procfs.c  install.sh  Makefile  os-interface.c  README  uninstall.sh  upgrade.sh  version.h
  3. 安装cGPU服务。
    sh install.sh
  4. 验证安装结果。
    # lsmod | grep cgpu
    cgpu_km                71355  0

    显示cgpu服务的状态信息,表示已成功安装cGPU服务。

  运行cGPU服务
  影响cGPU服务的环境变量如下表所示,您可以在创建容器时指定环境变量的值,控制容器可以通过cGPU服务获得的算力。

环境变量名称取值类型说明示例
CGPU_DISABLEBoolean是否启用cGPU服务,取值范围:
  • false:启用cGPU服务。
  • true:禁用cGPU服务,使用默认的NVIDIA容器服务。
ALIYUN_COM_GPU_MEM_DEVInteger设置GPU实例上每张显卡的总显存大小,和实例规格有关。
说明 显存大小按GiB取整数。
一台GPU实例规格为ecs.gn6i-c4g1.xlarge,配备1张NVIDIA ® Tesla ® T4显卡。在GPU实例上执行nvidia-smi查看总显存大小为15109 MiB,取整数为15 GiB。
ALIYUN_COM_GPU_MEM_CONTAINERInteger设置容器内可见的显存大小,和ALIYUN_COM_GPU_MEM_DEV结合使用。如果不指定本参数或指定为0,则不使用cGPU服务,使用默认的NVIDIA容器服务。在一张总显存大小为15 GiB的显卡上,设置环境变量ALIYUN_COM_GPU_MEM_DEV=15ALIYUN_COM_GPU_MEM_CONTAINER=1,效果是为容器分配1 GiB的显存。
ALIYUN_COM_GPU_VISIBLE_DEVICESInteger或uuid指定容器内可见的GPU显卡。在一台有4张显卡的GPU实例上,执行nvidia-smi -L查看GPU显卡设备号和UUID。返回示例如下所示:
GPU 0: Tesla T4 (UUID: GPU-b084ae33-e244-0959-cd97-83****)
GPU 1: Tesla T4 (UUID: GPU-3eb465ad-407c-4a23-0c5f-bb****)
GPU 2: Tesla T4 (UUID: GPU-2fce61ea-2424-27ec-a2f1-8b****)
GPU 3: Tesla T4 (UUID: GPU-22401369-db12-c6ce-fc48-d7****)
然后,设置以下环境变量:
  • ALIYUN_COM_GPU_VISIBLE_DEVICES=0,1,效果是为容器分配第1和第2张显卡。
  • ALIYUN_COM_GPU_VISIBLE_DEVICES=GPU-b084ae33-e244-0959-cd97-83****,GPU-3eb465ad-407c-4a23-0c5f-bb****,GPU-2fce61ea-2424-27ec-a2f1-8b****,效果是为容器分配3张指定UUID的显卡。
ALIYUN_COM_GPU_SCHD_WEIGHTInteger设置容器的算力权重,取值范围:1~min(max_inst, 16)。

以ecs.gn6i-c4g1.xlarge为例演示2个容器共用1张显卡。

  1. 执行以下命令创建容器并设置容器内可见的显存。
    docker run -d -t --gpus all --privileged --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --name gpu_test1 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=6 -e ALIYUN_COM_GPU_MEM_DEV=15 nvcr.io/nvidia/tensorflow:19.10-py3
    docker run -d -t --gpus all --privileged --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --name gpu_test2 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=8 -e ALIYUN_COM_GPU_MEM_DEV=15 nvcr.io/nvidia/tensorflow:19.10-py3
    备注 该命令以使用TensorFlow镜像nvcr.io/nvidia/tensorflow:19.10-py3为例,请根据实际情况更换为您自己的容器镜像。使用TensorFlow镜像搭建TensorFlow深度学习框架的操作。
    本示例中,通过设置环境变量ALIYUN_COM_GPU_MEM_CONTAINER和ALIYUN_COM_GPU_MEM_DEV指定显卡的总显存和容器内可见的显存。命令执行结果是创建了2个容器:
    • gpu_test1:分配6 GiB显存。
    • gpu_test2:分配8 GiB显存。
  2. 进入容器。
    本示例中,以gpu_test1为例。
    docker exec -it gpu_test1 bash
  3. 执行以下命令查看显存等GPU信息。
    nvidia-smi
    容器gpu_test1中可见的显存为6043 MiB,如下图所示。gpu_test1

查看procfs节点

cGPU服务运行时会在/proc/cgpu_km下生成并自动管理多个procfs节点,您可以通过procfs节点查看和配置cGPU服务相关的信息。下面介绍各procfs节点的用途。

  1. 执行以下命令查看节点信息。
    # ls /proc/cgpu_km/
    0  default_memsize  inst_ctl  major  version
    节点信息说明如下表所示。
    节点读写类型说明
    0读写cGPU服务会针对GPU实例中的每张显卡生成一个的目录,并使用数字作为目录名称,例如0、1、2。本示例中只有一张显卡,对应的目录ID为0。
    default_memsize读写如果没有设置ALIYUN_COM_GPU_MEM_CONTAINER参数,默认为新创建的容器分配的显存大小。
    inst_ctl读写控制节点。
    major只读cGPU内核驱动的主设备号。
    version只读cGPU的版本。
  2. 执行以下命令查看显卡对应的目录内容。
    本示例中,以显卡0为例。
    # ls /proc/cgpu_km/0
    012b2edccd7a   0852a381c0cf   free_weight    max_inst    policy
    目录内容说明如下表所示。
    节点读写类型说明
    容器对应的目录读写cGPU服务会针对运行在GPU实例中的每个容器生成一个的目录,并使用容器ID作为目录名称。您可以执行docker ps查看已创建的容器。
    free_weigt只读用于查询和修改可用的权重。如果free_weight=0,新创建容器的权重值为0,该容器不能获取GPU算力,不能用于运行需要GPU算力的应用。
    max_inst读写用于设置容器的最大数量,取值范围为1~16。
    policy读写cGPU服务支持以下算力调度策略:
    • 0:平均调度。每个容器占用固定的时间片,时间片占比为1/max_inst
    • 1:抢占调度。每个容器占用尽量多的时间片,时间片占比为1/当前容器数
    • 2:权重抢占调度。当ALIYUN_COM_GPU_SCHD_WEIGHT的取值大于1时,自动使用权重抢占调度。

    您可以通过修改policy的值实时调整调度策略。

  3. 执行以下命令查看容器对应的目录内容。
    本示例中,以012b2edccd7a容器为例。
    # ls /proc/cgpu_km/0/012b2edccd7a
    id  meminfo  memsize  weight
    目录内容说明如下表所示。
    节点读写类型说明
    id只读容器的ID。
    memsize读写用于设置容器内的显存大小。cGPU服务会根据ALIYUN_COM_GPU_MEM_DEV参数自动设定此值。
    meminfo只读包括容器内剩余显存容量、正在使用GPU的进程ID及其显存用量。输出如下所示:
    Free: 6730809344
    PID: 19772 Mem: 200278016
    weight读写用于设置容器获取显卡最大算力的权重,默认值为1。所有运行中的容器的权重之和必须小于等于max_inst。
了解procfs节点的用途后,您可以在GPU实例中执行命令进行切换调度策略、修改权重等操作,示例命令如下表所示。
命令效果
echo 2 > /proc/cgpu_km/0/policy将调度策略切换为权重抢占调度。
cat /proc/cgpu_km/0/free_weight查看显卡上可用的权重。 如果free_weight=0,新创建容器的权重值为0,该容器不能获取GPU算力,不能用于运行需要GPU算力的应用。
cat /proc/cgpu_km/0/$dockerid/weight查看指定容器的权重。
echo 4 > /proc/cgpu_km/0/$dockerid/weight修改容器获取GPU算力的权重。

升级cGPU服务

  1. 关闭所有运行中的容器。
    docker stop (docker ps -a | awk '{ print $1}' | tail -n +2)
  2. 执行upgrade.sh脚本升级cGPU服务至最新版本。
    sh upgrade.sh

卸载cGPU服务

  1. 关闭所有运行中的容器。
    docker stop (docker ps -a | awk '{ print $1}' | tail -n +2)
  2. 执行sh uninstall.sh脚本卸载cGPU服务。
    sh uninstall.sh

cGPU服务算力调度示例

cGPU服务加载cgpu_km的模块时,会按照容器最大数量(max_inst)为每张显卡设置时间片(X ms),用于为容器分配GPU算力,本示例中以Slice 1、Slice 2...Slice N表示。使用不同调度策略时的调度示例如下所示。
  • 平均调度
    在创建容器时,为容器分配时间片。cGPU服务会从Slice 1时间片开始调度,提交任务到物理GPU,并执行一个时间片(X ms)的时间,然后切换到下一个时间片。每个容器获得的算力相同,都为1/max_inst。如下图所示。平均调度
  • 抢占调度

    在创建容器时,为容器分配时间片。cGPU服务会从Slice 1开始调度,但如果没有使用某个容器,或者容器内没有进程打开GPU设备,则跳过调度,切换到下一个时间片。

    示例如下:
    1. 只创建一个容器Docker 1,获得Slice 1时间片,在Docker 1中运行2个TensorFlow进程,此时Docker 1最大获得整个物理GPU的算力。
    2. 再创建一个容器Docker 2,获得Slice 2时间片。如果Docker 2内没有进程打开GPU设备,调度时会跳过Docker 2的时间片Slice 2。
    3. 当Docker 2内有进程打开GPU设备时,Slice 1和Slice 2都加入调度,Docker 1和Docker 2最大分别获得1/2物理GPU的算力。如下图所示。抢占调度
  • 权重抢占调度

    如果在创建容器时设置ALIYUN_COM_GPU_SCHD_WEIGHT大于1,则自动使用权重抢占调度。cGPU服务按照容器数量(max_inst)将物理GPU算力划分成max_inst份,但如果ALIYUN_COM_GPU_SCHD_WEIGHT大于1,cGPU服务会将数个时间片组合成一个更大的时间片分配给容器。

    设置示例如下:
    • Docker 1:ALIYUN_COM_GPU_SCHD_WEIGHT=m
    • Docker 2:ALIYUN_COM_GPU_SCHD_WEIGHT=n
    调度效果如下:
    • 如果只有Docker 1运行, Docker 1抢占整个物理GPU的算力。
    • 如果Docker 1和Docker 2同时运行,Docker 1和Docker 2获得的理论算力比例是m:n。和抢占调度不同的是,即使Docker 2中没有GPU进程也会占用n个时间片的时间。
      说明 m:n设置为2:1和8:4时的运行表现存在差别。在1秒内切换时间片的次数,前者是后者的4倍。
    权重抢占调度
    权重抢占调度限制了容器使用GPU算力的理论最大值。但对算力很强的显卡(例如NVIDIA ® V100显卡),如果显存使用的较少,在一个时间片内即可完成计算任务。此时如果m:n值设置为8:4,则剩余时间片内GPU算力会闲置,限制基本失效。因此建议根据显卡算力设置适当的权重值,例如:
    • 如果使用NVIDIA ® V100显卡,将m:n设置为2:1,尽量降低权重值,避免GPU算力闲置。
    • 如果使用NVIDIA ® Telsa ® T4显卡,将m:n设置为8:4, 尽量增大权重值,保证分配足够的GPU算力。
  FastGPU构建一键训练任务
  FastGPU是一套阿里云推出的人工智能计算任务构建工具,提供便捷的接口和命令行,供您在阿里云IaaS资源上构建人工智能计算任务。本文以Ubuntu 18.04 64位为例介绍如何安装和使用FastGPU,并列出了FastGPU支持的运行时接口和命令行。
  
  前提条件  客户端已安装Python 3.6或以上版本。
  
  备注 您的ECS实例和本地机器、阿里云Cloud Shell工具等均可以作为客户端安装FastGPU来构建人工智能计算任务。
  
  背景信息    FastGPU作为衔接您的线下人工智能算法和线上阿里云海量GPU计算资源的关键一环,方便您将人工智能计算任务构建在阿里云的IaaS资源上。使用FastGPU构建人工智能计算任务时,您无需关心IaaS层的计算、存储、网络等资源部署操作,达到简单适配、一键部署、随处运行的效果。
  
  FastGPU提供以下两套组件:
  
  运行时组件ncluster:提供便捷的接口将线下的人工智能训练和推理脚本快速部署在阿里云的IaaS资源上,更多运行时组件使用说明请参见运行时说明。
  
  命令行组件ecluster:提供便捷的命令行工具,用于管理阿里云上人工智能计算任务的运行状态和集群的生命周期,更多命令行组件使用说明请参见命令行说明。
  
  FastGPU的组成模块如下图所示。


安装FastGPU

  1. 在客户端下载FastGPU软件包。
    wget https://ali-perseus-release.oss-cn-huhehaote.aliyuncs.com/fastgpu/ncluster-1.0.8-py3-none-any.whl
  2. 安装FastGPU。
    pip install ncluster-1.0.8-py3-none-any.whl

运行FastGPU demo

本步骤以在Cloud Shell中运行BERT finetune任务为例,展示如何使用FastGPU。demo中自动创建的实例规格为ecs.gn6v-c10g1.20xlarge(8卡V100机型),任务部署时间约2.5分钟,训练时长约11.5分钟,总共耗时约14分钟,训练精度达到0.88以上。

  1. 打开Cloud Shell
    本次测试时,Cloud Shell中使用Ubuntu 18.04 64,且默认已安装FastGPU,您可以直接开始准备项目文件并运行任务。
  2. 准备项目文件。
    git clone https://github.com/aliyun/alibabacloud-aiacc-demo
  3. 进入任务脚本目录。
    cd alibabacloud-aiacc-demo/tensorflow/bert
  4. 运行任务脚本。
    python train_news_classifier.py
    运行任务时需要自动创建实例等资源,会提示涉及计费,请按提示确认继续。prompt-fee
    注意 您可以在任务完成后手动释放实例,避免任务完成后实例继续计费。
    脚本运行成功后显示如下图所示。training-complete
  5. 查看运行任务时自动创建的实例。
    ecluster ls
    ecluster-ls
  6. 登录实例查看训练过程日志。
    ecluster tmux task0.perseus-bert
    显示以下结果时,表明已完成训练。log

运行时说明

您可以通过ncluster的接口将人工智能训练和推理脚本快速部署到云上进行计算。ncluster的接口主要提供以下功能:
  • 获取阿里云账号AccessKey、默认地域、默认可用区等信息。
    export ALIYUN_ACCESS_KEY_ID=L****      # Your actual aliyun access key id
    export ALIYUN_ACCESS_KEY_SECRET=v****   # Your actual aliyun access key secret
    export ALIYUN_DEFAULT_REGION=cn-hangzhou  # The actual region the resource you want to use
    export ALIYUN_DEFAULT_ZONE=cn-hangzhou-i  # The actual zone of the region you want to use
  • ncluster是一套Python库,使用时需要在Python脚本中导入ncluster。
    import ncluster
  • 创建任务所需的资源或者复用已经存在的资源。
    job = ncluster.make_job(name=args.name,
                            run_name=f"{args.name}-{args.machines}",
                            num_tasks=args.machines,
                            image_name=IMAGE_NAME,
                            instance_type=INSTANCE_TYPE)
    ncluster.make_job的参数如下表所示。
    参数名称参数说明参数示例
    namejob的名称。'perseus-bert'
    run_name运行时的环境名,一般设置为job名+实例数量。f"perseus-bert-1"
    num_tasks需要创建实例的个数。1

    表示创建1台实例,名称为task0.perseus-bert,对应perseus-bert.tasks[0]。

    image_name实例使用的镜像,支持公共镜像和自定义镜像。'ubuntu_18_04_64_20G_alibase_20190624.vhd'
    instance_type需要创建实例的实例规格。'ecs.gn6v-c10g1.20xlarge'
  • 运行任务。支持以job或task的形式运行任务,job为一组task。
    说明 job和task支持相同的API,调用job的API作用于所有的task,调用task的API只作用于指定的task。
    示例如下:
    • 调用job的API
      # 为job中所有实例打开perseus-bert文件夹
      job.run('cd perseus-bert') 
      
      # 将当前目录中的perseus-bert文件夹上传到job中所有实例的/root目录下
      job.upload('perseus-bert')
    • 调用task的API
      # 为task0对应实例打开perseus-bert文件夹
      job.tasks[0].run('cd perseus-bert') 
      
      # 将当前目录中的perseus-bert文件夹上传到task0对应实例的/root目录下
      job.tasks[0].upload('perseus-bert')

命令行说明

您可以使用ecluster命令方便地管理资源的生命周期、查看运行过程的日志等操作。ecluster支持的命令如下表所示。
命令命令说明命令示例
export获取阿里云账号的信息,在本地机器使用FastGPU时需要获取AccessKey、默认地域、默认可用区等信息。
  • export ALIYUN_ACCESS_KEY_ID=L****
  • export ALIYUN_ACCESS_KEY_SECRET=v****
  • export ALIYUN_DEFAULT_REGION=cn-hangzhou
  • export ALIYUN_DEFAULT_ZONE=cn-hangzhou-i
ecluster [help,-h,--help]查看所有ecluster命令。ecluster --help
ecluster {command} --help查看指定的ecluser命令。ecluster ls --help
ecluster create --config create.cfg基于配置文件创建实例。create.cfg文件定义实例的配置环境,运行命令前您需要先创建create.cfg文件,具体内容请参见表格下方的示例。ecluster create --config create.cfg
ecluster create --name {instance_name} --machines {instance_num} ...基于参数创建实例。ecluster create --name task0.ncluster-v100 --machines 1
ecluster ls列出已自动创建的实例。包括以下信息:
  • name:实例名称。
  • hours_live:实例创建至今的时间,以小时为单位。
  • instance_type:实例规格。
  • public_ip:实例的公网IP。
  • key/owner:密钥对和账号名。
  • private_ip:实例的内网。
  • instance_id:实例的id。
ecluster ls
ecluster ssh {instance_name}登录指定的实例。ecluster ssh task0.ncluster-v100
ecluster tmux {instance_name}连接到运行中的任务,如果没有tmux会话,则使用ssh连接。ecluster tmux task0.ncluster-v100
ecluster stop {instance_name}停止指定的实例。
  • 停止task0对应的实例:ecluster stop task0.ncluster-v100
  • 停止一组实例:ecluster stop {ncluster-v100}
ecluster start {instance_name}启动指定的实例。
  • 启动task0对应的实例:ecluster start task0.ncluster-v100
  • 启动一组实例:ecluster start {ncluster-v100}
ecluster kill {instance_name}释放指定的实例。
  • 释放task0对应的实例:ecluster kill task0.ncluster-v100
  • 释放一组实例:ecluster kill {ncluster-v100}
ecluster mount {instance_name}为指定的实例挂载NAS文件系统到/ncluster目录。ecluster mount task0.ncluster-v100
ecluster scp {source} {destination}安全拷贝文件或目录。ecluster scp /local/path/to/upload task0.ncluster-v100:/remote/path/to/save
ecluster addip {instance_name}将指定任务中实例的固定公网IP添加到安全组。ecluster addip task0.ncluster-v100
ecluster rename {old_name} {new_name}重命名指定实例。ecluster rename task0.ncluster-v100 task1.ncluster-v100
基于配置文件创建实例时,您可以参考以下内容新建配置文件。
; config.ini

[ncluster]
; The job name for current creation job.
name=ncluster-v100
; The number of machine you want to create
machines=1
; The system disk size for instances in GB
system_disk_size=300
; The data disk size for instances in GB
data_disk_size=0
; The system image name you want to installed in the instances.
image_name=ubuntu_18_04_64_20G_alibase_20190624.vhd
; The instance type you want to create at Alibaba Cloud.
instance_type=ecs.gn6v-c10g1.20xlarge
; The spot instance option; If you want to buy spot instance, please set it to True.
spot=False
; If only used to create instances, it can set to True.
confirm_cost=False
; Confirm the next operation will cost money, if set to True will default confirmed.
skip_setup=True
; Nas create/mount options; Set True will disable nas mount for current job.
disable_nas=True
; The zone id info. The option provided to use resource in the zone.
zone_id=cn-hangzhou-i
; Specify the vpc name
vpc_name=ncluster-vpc

[cmd]
install_script=pwd
如果您还有什么疑问的话,可以联系我们。

推荐文章更多
联系客服免费领取更多阿里云产品新购、续费升级折扣,叠加官网活动折上折更优惠