快速提交PAI-DLC训练任务
learn
手动配置
40
教程简介
在本教程中,您将学习如何使用阿里云机器学习平台PAI控制台提交分布式训练(DLC)任务。
PAI-DLC(Deep Learning Containers)是基于云原生容器服务的深度学习训练平台,为您提供灵活、稳定、易用和较优性能的深度学习训练环境。PAI平台同时还提供了完善的SDK和OpenAPI,实现了基于代码提交任务,使得PAI-DLC更灵活地应用到您的日常生产中。
我能学到什么
学会使用控制台界面提交DLC训练任务的流程。
操作难度 | 中 |
所需时间 | 40分钟 |
使用的阿里云产品 | |
所需费用 | 阿里云免费试用在华北2(北京)、华东2(上海)、华东1(杭州)、华南1(深圳)为您提供了一定数量的DLC免费资源包供您使用,超出免费额度后将收取费用。DLC的计费详情请参见通用计算资源(DSW/DLC)计费说明。 【重要】PAI-DLC免费资源包只适用于本教程中的PAI-DLC产品。如果您领取了PAI-DLC资源包后,使用了PAI-DLC及PAI的其他产品功能(如PAI-DSW、PAI-EAS等),PAI-DLC产品产生的费用由资源包抵扣,其他产品功能产生的费用无法抵扣,会产生对应的费用账单。 |
准备环境及资源
10
开始教程前,请按以下步骤准备环境和资源:
【重要】PAI-DLC免费资源包只适用于本教程中的PAI-DLC产品。如果您领取了PAI-DLC资源包后,使用了PAI-DLC及PAI的其他产品功能(如PAI-DSW、PAI-EAS等),PAI-DLC产品产生的费用由资源包抵扣,其他产品功能产生的费用无法抵扣,会产生对应的费用账单。
访问阿里云免费试用。单击页面右上方的登录/注册按钮,并根据页面提示完成账号登录(已有阿里云账号)、账号注册(尚无阿里云账号)或实名认证(根据试用产品要求完成个人实名认证或企业实名认证)。
申请免费试用OSS,并创建Bucket。
【说明】本教程以使用OSS创建数据集来存储代码文件为例,来说明如何提交训练任务。
领取对象存储OSS资源抵扣包。
进入OSS免费资源包申请页面,单击立即试用,在确认并了解相关信息后,根据页面提示申请试用。
【注意】:如果您的对象存储OSS资源抵扣包已使用完毕或无领取资格,开通PAI试用后,将正常收取费用,计费详情请参见OSS按量付费。
创建OSS Bucket。
登录OSS控制台,在Bucket列表页面单击创建Bucket开始创建Bucket。本教程的核心配置参数如下,其他参数可保持默认值,详细创建步骤请参见创建有地域属性Bucket。
地域:选择有地域属性,华南1(深圳)地域。
其他参数:保持默认值即可。
申请开通免费试用PAI。
进入模型训练PAI-DLC免费资源包申请页面,并在模型训练PAI-DLC卡片上单击立即试用。
【说明】:如果您此前已申请过试用PAI的免费资源包,此时界面会提示为已试用,您可以直接单击已试用按钮,进入PAI的控制台。
在模型训练PAI-DLC面板,勾选服务协议后,单击立即试用,进入免费开通页面。
开通机器学习PAI并创建默认工作空间。其中关键参数配置如下,更多详情内容,请参见开通并创建默认工作空间。如果您后续使用RAM用户来提交DLC训练任务,您需要将RAM用户添加为默认工作空间的成员,并配置管理员角色,详情请参见管理工作空间成员。
本教程选择的地域为:华南1(深圳)。
单击免费开通并创建默认工作空间:在弹出的开通页面中配置订单详情。配置要点如下。
本教程不需要开通除OSS产品外的其他产品,您需要在组合开通配置模块,去勾选其他产品的复选框。
在服务角色授权模块单击去授权,根据界面提示为PAI完成授权,然后返回开通页面,刷新页面,继续开通操作。
开通成功后,单击进入PAI控制台。
【重要】以下几种情况可能产生额外费用。
使用了除免费资源类型外的计费资源类型:
您申请试用的是PAI-DLC免费资源包,但您提交DLC训练任务使用的资源类型非阿里云免费试用提供的资源类型。当前可申请免费使用的资源类型有:ecs.gn6v-c8g1.2xlarge、ecs.g6.xlarge、ecs.gn7i-c8g1.2xlarge。
申请试用的免费资源包与使用的产品资源不对应:
您提交了DLC训练任务,但您申请试用的是PAI-DSW或PAI-EAS产品的免费资源包。您使用DLC产品产生的费用无法使用免费资源包抵扣,会产生后付费账单。
您申请试用的是PAI-DLC免费资源包,但您使用的产品是PAI-DSW或PAI-EAS。使用PAI-DSW和PAI-EAS产品产生的费用无法使用DLC免费资源包抵扣,会产生后付费账单。
免费额度用尽或超出试用期:
领取免费资源包后,请在免费额度和有效试用期内使用。如果免费额度用尽或试用期结束后,若继续使用计算资源,将会产生后付费账单。
准备训练脚本
5
在本地创建torch_ddp_sample_code.py(Python)代码文件,文件内容如下。
import datetime import logging import os import argparse from math import ceil from random import Random import torch import torch.distributed as dist import torch.nn as nn import torch.nn.functional as F import torch.optim as optim import torch.utils.data import torch.utils.data.distributed from torch._utils import _flatten_dense_tensors, _unflatten_dense_tensors from torch.autograd import Variable from torch.nn.modules import Module from torchvision import datasets, transforms gbatch_size = 128 epochs = 10 world_size = os.environ.get("WORLD_SIZE", "{}") rank = os.environ.get("RANK", "{}") class DistributedDataParallel(Module): def __init__(self, module): super(DistributedDataParallel, self).__init__() self.module = module self.first_call = True def allreduce_params(): if self.needs_reduction: self.needs_reduction = False buckets = {} for param in self.module.parameters(): if param.requires_grad and param.grad is not None: tp = type(param.data) if tp not in buckets: buckets[tp] = [] buckets[tp].append(param) for tp in buckets: bucket = buckets[tp] grads = [param.grad.data for param in bucket] coalesced = _flatten_dense_tensors(grads) dist.all_reduce(coalesced) coalesced /= dist.get_world_size() for buf, synced in zip(grads, _unflatten_dense_tensors(coalesced, grads)): buf.copy_(synced) for param in list(self.module.parameters()): def allreduce_hook(*unused): Variable._execution_engine.queue_callback(allreduce_params) if param.requires_grad: param.register_hook(allreduce_hook) def weight_broadcast(self): for param in self.module.parameters(): dist.broadcast(param.data, 0) def forward(self, *inputs, **kwargs): if self.first_call: logging.info("first broadcast start") self.weight_broadcast() self.first_call = False logging.info("first broadcast done") self.needs_reduction = True return self.module(*inputs, **kwargs) class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 10, kernel_size=5) self.conv2 = nn.Conv2d(10, 20, kernel_size=5) self.conv2_drop = nn.Dropout2d() self.fc1 = nn.Linear(320, 50) self.fc2 = nn.Linear(50, 10) def forward(self, x): x = F.relu(F.max_pool2d(self.conv1(x), 2)) x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) x = x.view(-1, 320) x = F.relu(self.fc1(x)) x = F.dropout(x, training=self.training) x = self.fc2(x) return F.log_softmax(x) def partition_dataset(rank): dataset = datasets.MNIST( './data{}'.format(rank), train=True, download=True, transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ])) size = dist.get_world_size() bsz = int(gbatch_size / float(size)) train_sampler = torch.utils.data.distributed.DistributedSampler(dataset) train_set = torch.utils.data.DataLoader( dataset, batch_size=bsz, shuffle=(train_sampler is None), sampler=train_sampler) return train_set, bsz def average_gradients(model): size = float(dist.get_world_size()) group = dist.new_group([0]) for param in model.parameters(): dist.all_reduce(param.grad.data, op=dist.ReduceOp.SUM, group=group) param.grad.data /= size def run(gpu): rank = dist.get_rank() torch.manual_seed(1234) train_set, bsz = partition_dataset(rank) model = Net() if gpu: model = model.cuda() model = torch.nn.parallel.DistributedDataParallel(model) else: model = DistributedDataParallel(model) optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) num_batches = ceil(len(train_set.dataset) / float(bsz)) logging.info("num_batches = %s", num_batches) time_start = datetime.datetime.now() for epoch in range(epochs): epoch_loss = 0.0 for data, target in train_set: if gpu: data, target = Variable(data).cuda(), Variable(target).cuda() else: data, target = Variable(data), Variable(target) optimizer.zero_grad() output = model(data) loss = F.nll_loss(output, target) epoch_loss += loss.item() loss.backward() average_gradients(model) optimizer.step() logging.info('Epoch {} Loss {:.6f} Global batch size {} on {} ranks'.format( epoch, epoch_loss / num_batches, gbatch_size, dist.get_world_size())) if gpu: logging.info("GPU training time= {}".format( str(datetime.datetime.now() - time_start))) else: logging.info("CPU training time= {}".format( str(datetime.datetime.now() - time_start))) if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) parser = argparse.ArgumentParser(description='Train Pytorch model using DDP') parser.add_argument('--gpu', action='store_true', help='Use GPU and CUDA') parser.set_defaults(gpu=False) args = parser.parse_args() if args.gpu: logging.info("\n======= CUDA INFO =======") logging.info("CUDA Availability: %s", torch.cuda.is_available()) if torch.cuda.is_available(): logging.info("CUDA Device Name: %s", torch.cuda.get_device_name(0)) logging.info("CUDA Version: %s", torch.version.cuda) logging.info("=========================\n") dist.init_process_group(backend='gloo', init_method='env://',world_size=int(world_size),rank=int(rank)) run(gpu=False) dist.destroy_process_group()
支持使用以下两种方式保存代码数据,供后续模型训练使用。本教程以创建数据集为例。
单击,选择已创建的Bucket。
单击新建目录,输入目录名称,单击确定。
进入新创建的目录中,单击上传文件,按照界面操作指引上传步骤1中在本地创建的torch_ddp_sample_code.py代码文件。
选中步骤b创建的目录,单击确定。
创建数据集
创建阿里云对象存储(OSS)类型数据集,其中关键参数配置如下,其他参数取默认配置即可。更多详细内容,请参见创建及管理数据集。
参数 | 描述 |
数据集名称 | 自定义数据集名称,本教程配置为:dataset-oss。 |
属性 | 选择文件夹。 |
从阿里云云存储创建 | 按照以下操作步骤选择代码文件所在的Bucket路径。 |
默认挂载路径 | 保持默认配置: |
创建代码集
提交训练任务
15
进入新建任务页面。
登录PAI控制台。
在页面左上方,选择工作空间所在地域。本教程选择:华南1(深圳)。
在左侧导航栏单击工作空间列表,在工作空间列表页面中单击默认工作空间名称,进入对应工作空间内。
在工作空间页面的左侧导航栏选择模型开发与训练>分布式训练(DLC),在分布式训练(DLC)页面,单击新建任务。
配置训练任务的参数。
在基本信息区域配置以下关键参数,其他参数取默认配置即可,更多详细内容,请参见创建训练任务。
参数
描述
任务名称
自定义任务名称,本教程配置为:doc_test_for_dlc。
节点镜像
目前PAI-DLC支持使用PAI官方镜像和用户自定义镜像。
本教程选择PAI官方镜像:pytorch-training:1.8PAI-gpu-py36-cu101-ubuntu18.04。
数据集配置
单击添加按钮,配置类型选择按数据集:
数据集:选择已创建的数据集dataset-oss。
挂载路径:配置为
/mnt/data/
。
代码配置
本教程无需配置该参数。
【说明】如果您将代码文件保存为代码集,需要配置该参数。
执行命令
本教程配置为:
python /mnt/data/torch_ddp_sample_code.py
。【说明】如果您将代码文件保存为代码集,需要根据实际情况来配置执行命令。
在资源配置区域,配置以下关键参数。
参数
描述
资源配额
本教程选择:公共资源(后付费)。
框架
本教程选择:PyTorch。
任务资源
单击,配置资源规格。本教程选择
。阿里云免费试用提供的节点规格包括以下几种规格:ecs.gn7i-c8g1.2xlarge
ecs.g6.xlarge
ecs.gn6v-c8g1.2xlarge
单击确定,大约需要持续10分钟,任务运行成功。
完成
5
完成以上操作后,您的DLC训练任务已提交成功。您可以在分布式训练(DLC)页面查看已提交的训练任务。
清理及后续
5
清理
领取免费资源包后,请在免费额度和有效试用期内使用。如果免费额度用尽或试用期结束后,继续使用计算资源,会产生后付费账单。
您可前往资源实例管理页面,查看免费额度使用量和过期时间。
如果无需继续使用DLC训练任务,您可以删除DLC任务。
在分布式训练(DLC)页面,当目标任务状态为已成功、已停止或已失败,您可以单击操作列下的删除,来删除目标任务。当目标任务状态为其他状态时,您可以先单击操作列下的停止,再单击操作列下的删除,即可删除任务。
对象存储OSS资源清理
删除对象存储空间,详情请参见删除存储空间。
后续
在试用有效期期间,您还可自行提交DLC训练任务进行模型训练。
总结
常用知识点
问题1:新建任务页面,本教程必须完成的配置有哪些?(单选题)
任务名称&节点镜像&任务类型&执行命令&数据集配置
代码配置
最长运行时长
正确答案是任务名称&节点镜像&任务类型&执行命令&数据集配置。
问题2:提交DLC训练任务后,可以到哪个页面查看已提交的训练任务?(单选题)
分布式训练(DLC)
镜像
数据集
正确答案是分布式训练(DLC)。