使用SDK调测单机训练作业
代码中涉及到的OBS路径,请用户替换为自己的实际OBS路径。
代码是以PyTorch为例编写的,不同的AI框架之间,整体流程是完全相同的,仅需修改6和10中的framework_type参数值即可,例如:MindSpore框架,此处framework_type=Ascend-Powered-Engine。
- Session初始化。
代码如下:这里只列出最常用的一种方式,更多方式请参考《Session鉴权章节》
from modelarts.session import Session session = Session()
- 准备训练数据,这里支持三种形式,用户可根据自己的情况选择一种。
import os from modelarts.train_params import InputData base_bucket_path = "obs://modelarts-xxx-a0de02a6/dis-train/cifar10/" base_local_path = "/home/ma-user/work/cifar10/" # 形式1,数据在OBS上,且是一个压缩文件 obs_path = os.path.join(base_bucket_path, "dataset-zip/dataset.zip") data_local = os.path.join(base_local_path, "dataset/") input_data = InputData(obs_path=obs_path, local_path=data_local, is_local_source=False) # 形式2,数据在OBS上,且是一个目录 #obs_path = os.path.join(base_bucket_path, "dataset/") #data_local = os.path.join(base_local_path, "dataset/") #input_data = InputData(obs_path=obs_path, local_path=data_local, is_local_source=False) # 形式3,数据在Notebook中,且是一个目录,一般是使用SFS挂载磁盘的场景 #obs_path = os.path.join(base_bucket_path, "dataset-local/") #data_local = os.path.join(base_local_path, "dataset/") #input_data = InputData(obs_path=obs_path, local_path=data_local, is_local_source=True)
参数解释:
- is_local_source:可选参数,默认为False,指定训练数据的保存位置。
- False:训练数据保存在参数obs_path指定的位置中;
- True:训练数据保存在notebook中,由local_path指定。
- obs_path:obs地址。根据is_local_source值的变化,有不同的含义。
- is_local_source=False,此时是必选参数,代表训练数据位置,支持文件夹和压缩文件。
- is_local_source=True,此时是可选参数。如果用户填写了该参数,则开始训练时会将Notebook中的训练数据压缩并上传到该位置,不可重复上传。如果第一次上传后,建议将is_local_source修改为False,obs_path指向刚才上传的压缩数据文件位置;如果用户没有填写,则不会进行压缩上传。
- local_path:必选参数,Notebook中的路径。用户的训练脚本需要从该目录中读取数据,完成训练任务。根据is_local_source值的变化,有不同的含义。
- is_local_source=True,此时代表训练数据位置,仅支持文件夹。
- is_local_source=False,训练过程中SDK会帮助用户将数据下载到该位置,如果训练数据是压缩文件,下载完成后会进行解压缩。
- is_local_source:可选参数,默认为False,指定训练数据的保存位置。
- 准备训练脚本。
from modelarts.train_params import TrainingFiles code_dir = os.path.join(base_local_path, "train/") # 这里提前将训练脚本放在了obs中,实际上训练脚本可以是任何来源,只要能够放到Notebook里边就行 session.obs.download_file(os.path.join(base_bucket_path, "train/test-pytorch.py"), code_dir) training_file = TrainingFiles(code_dir=code_dir, boot_file="test-pytorch.py", obs_path=base_bucket_path + 'train/')
参数解释:
- code_dir:必选参数,训练脚本所在的目录。在训练任务调测的情况下,必须是notebook中的目录,不能是OBS目录。
- boot_file:必选参数,训练启动文件路径,路径格式为基于code_dir目录的相对路径,如实例代码中boot_file的完整路径为/home/ma-user/work/cifar10/train/test-pytorch.py,这里就只需要填写test-pytorch.py。
- obs_path:可选参数,一个OBS目录。仅在本地单机调试时不需要该参数,提交远程训练时必选,会将训练脚本压缩并上传到该路径。
- 准备训练输出,如果用户不需要将训练输出上传到OBS,可以省略这一步。
from modelarts.train_params import OutputData output = OutputData(local_path=os.path.join(base_local_path, "output/"), obs_path=os.path.join(base_bucket_path, 'output/'))
- local_path:必选参数,一个notebook中的路径,训练脚本需要将输出的模型或其他数据保存在该目录下。
- obs_path:必选参数,一个OBS目录。SDK会将local_path中的模型文件自动上传到这里。
- 查看训练支持的AI框架。
from modelarts.estimatorV2 import Estimator Estimator.get_framework_list(session)
参数session即是第一步初始化的数据。如果用户知道要使用的AI框架,可以略过这一步。
- Estimator初始化。
from modelarts.estimatorV2 import Estimator parameters = [] parameters.append({"name": "data_url", "value": data_local}) parameters.append({"name": "output_dir", "value": os.path.join(base_local_path, "output/")}) parameters.append({"name": "epoc_num", "value": 2}) estimator = Estimator(session=session, training_files=training_file, outputs=[output], parameters=parameters, framework_type='PyTorch', train_instance_type='local', train_instance_count=1, script_interpreter="/home/ma-user/anaconda3/envs/PyTorch-1.4/bin/python", log_url=base_bucket_path + 'log/', job_description='This is a image net train job')
参数解释:
- session:必选参数,1中初始化的参数。
- training_files:必选参数,3中初始化的训练文件。
- outputs:可选参数,这里传入的是一个list,每个元素都是4中初始化的训练输出。
- parameters:可选参数,一个list,每个元素都是一个字典,包含"name"和"value"两个字段,以"--name=value"的形式传递给训练启动文件。value支持字符串,整数,布尔等类型。对于布尔类型,建议用户在训练脚本中使用action='store_true'的形式来解析。
- framework_type:必选参数,训练作业使用的AI框架类型,可参考步骤5查询的返回结果。
- train_instance_type:必选参数,训练实例类型,这里指定'local'即为在notebook中进行训练。
- train_instance_count:必选参数,训练使用的worker个数,单机训练时为1,训练作业只在当前使用的notebook中运行。
- script_interpreter:可选参数,指定使用哪个python环境来执行训练任务,如果未指定,会默认使用当前的kernel。
- log_url:可选参数,一个OBS地址,训练过程中,SDK会自动将训练的日志上传到该位置。但是如果训练任务运行在Ascend上,则是必选参数。
- job_description:可选参数,训练任务的描述。
- 开始训练。
estimator.fit(inputs=[input_data], job_name="cifar10-dis")
参数解释:
- inputs:可选参数,一个list,每个元素都是2生成的实例。
- job_name:可选参数,训练任务名,便于区分和记忆。
本地单机调试训练任务开始后,SDK会依次帮助用户完成以下流程:同时,可以在任务名后增加时间后缀,区分不同的任务名称。
from datetime import datetime, timedelta import time base_name = "cifar10-dis" job_name = base_name + '-' + (datetime.now() + timedelta(hours=8)).strftime('%Y%m%d-%H%M%S') estimator.fit(inputs=[input_data], job_name=job_name)
- 查询训练支持的计算节点类型和最大个数。
from modelarts.estimatorV2 import Estimator Estimator.get_spec_list(session=session)
参数session即是1初始化的数据。返回的是一个字典,其中flavors值是一个列表,描述了训练服务支持的所有规格的信息。每个元素中flavor_id是可直接用于远程训练任务的计算规格,max_num是该规格的最大节点数。如果用户知道要使用的计算规格,可以略过这一步。
- 提交远程训练作业。
from modelarts.estimatorV2 import Estimator parameters = [] parameters.append({"name": "data_url", "value": data_local}) parameters.append({"name": "output_dir", "value": os.path.join(base_local_path, "output/")}) parameters.append({"name": "epoch_num", "value": 2}) estimator = Estimator(session=session, training_files=training_file, outputs=[output], parameters=parameters, framework_type='PyTorch', train_instance_type='modelarts.vm.cpu.8u', train_instance_count=1, script_interpreter="/home/ma-user/anaconda3/envs/PyTorch-1.4/bin/python", log_url=base_bucket_path + 'log/', job_description='This is a image net train job') estimator.fit(inputs=[input_data], job_name="cifar10-dis")
在本地调测完成的基础上,只需要Estimator初始化时将参数train_instance_type修改为训练服务支持的规格即可(即第10步查询出来的flavor_id的值)。执行fit函数后,即可提交远程训练任务。
训练任务提交后,SDK会依次帮助用户完成以下流程:
- 将训练脚本打包成zip文件,上传到3中指定的obs_path中。
- 当训练数据保存在Notebook中,则将其打包成zip文件并上传到指定的obs_path中。
- 向ModelArts训练服务提交自定义镜像训练作业,使用的镜像为当前Notebook的镜像,这样保证了远程训练作业和在Notebook中的训练作业使用的运行环境一致。
- 训练任务得到的输出上传到4指定的obs_path中,日志上传到这一步log_url指定的位置中。
在这一步中需要注意的一个问题:
如果用户在自己的训练脚本中要创建新的目录或文件,请在以下几种目录中创建:
- /home/ma-user/work;
- /cache;
- inputs或者outputs中指定的local_path,如在步骤2中初始化InputData时,填写了local_path="/home/ma-user/work/xx/yy/",则在该目录下也可以创建新目录或文件。