算法文件说明
上传到Octopus平台的本地算法文件包需要满足Octopus平台要求,本章节介绍算法文件基本要求及相关环境变量说明。
算法文件基本要求
算法文件目录结构可参考如下,需要包括启动文件“xxx.py”(启动文件名可自定义),以及一些必要的训练文件。
- 启动文件(必选)
- 需要编译的依赖(可选)
如果使用了第三方的需要编译的算法库,将编译脚本或编译产物或依赖库添加到算法文件根目录下。推荐将通用依赖编译安装操作放在算法绑定的用户自定义镜像。
不支持动态联网安装依赖,包括但不限于apt/apt-get/pip等命令,建议提前安装在自定义镜像中。
相关参数说明
|
名称 |
环境变量 |
默认值 |
备注 |
|---|---|---|---|
|
数据集目录 |
DATASET |
|
数据集在训练任务容器中的存放路径,可自行获取各种数据集信息。 |
|
数据集映射 |
DATASET_MAP |
{key1: value1, key2: value2} |
以键值对提供数据集名称和容器内路径的变量,其中容器内路径参考数据集目录 |
|
数据缓存目录 |
CACHED_DATASET |
|
缓存数据集在训练任务容器中的挂载路径。 |
|
模型存放目录 |
RESULT |
|
训练产物的存放路径,产物输出到此路径后,在任务结束时。可在任务详情页的输出模型版本中浏览及执行各种操作。 |
|
增量训练模型目录 |
MODEL |
|
待增量模型版本在训练任务中的存放路径,可自行获取模型文件信息。 |
如果平台支持多类型资源池,建议用户使用环境变量适配算法提交任务,可免去更换默认值的环节。
示例:若任务的“数据输入”中选择了名为“增量数据集1”和“增量数据集2”的两个“数据集”,和名为“全量数据集缓存”的“数据缓存”。
- DATASET_MAP取值:
{ "增量数据集1": "/home/ma-user/datasets/dataset-0", "增量数据集2": "/home/ma-user/datasets/dataset-1", "全量数据集缓存": "/home/ma-user/cached-datasets/12fdb1cd-6afa-4e63-b031-7484b95df74f/dataset" }
- 使用环境变量获取以上变量:
# 获取数据集根目录 dataset_dict= json.loads(os.getenv("DATASET_MAP")) # 训练任务最多可使用5个数据集,通过迭代方式获取每个数据集路径 DATASETS_DIR_LIST = [os.path.join(DATASET_DIR), path for path in os.listdir(DATASET_DIR)]
分布式训练环境变量说明
|
名称 |
环境变量 |
示例值 |
备注 |
|---|---|---|---|
|
节点地址 |
VC_WORKER_HOSTS |
modelarts-job-8f3a5ced-d3d0-486fa236-19a075ec7259-worker0.modelarts-job-8f3a5ced-d3d0-486fa236-19a07 |
包含多个节点HOST地址,用逗号分隔,一般取第一个作为主节点通信地址。 |
|
主节点通信端口 |
VC_WORKER_PORT |
6789 |
主角点通信端口,用户可从环境变量获取或自设定,推荐使用os.getenv带默认参数的方法,例如port=int(os.getenv("VC_WORKER_PORT", "6789"))。 |
|
计算节点数量 |
MA_NUM_HOSTS |
8 |
表示计算节点数量,8表示当前任务使用8个节点。 |
|
单节点GPU数量 |
MA_NUM_GPUS |
8 |
表示每个节点有8张GPU卡。 |
|
节点编号 |
VC_TASK_INDEX |
0 |
若选择8节点,则节点编号从0~7排列,0号节点称为主节点。 |
分布式训练启动脚本参考示例如下,其中train.py为原算法启动脚本。
# -*- coding: UTF-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2012-2024. All rights reserved.
import argparse
import os
import subprocess
import time
import sys
import torch
print(torch.cuda.is_available())
# 获取分布式训练的相关环境变量
MASTER_HOST = os.getenv("VC_WORKER_HOSTS")
MASTER_ADDR = MASTER_HOST.split(",")[0]
# 通信端口建议自行设定,若使用环境变量需要确保包含默认值,防止None类型触发错误
MASTER_PORT = 6060
NNODES = os.getenv("MA_NUM_HOSTS")
NODE_RANK=os.getenv("VC_TASK_INDEX")
NGPUS_PER_NODE = os.getenv("MA_NUM_GPUS")
if not NGPUS_PER_NODE:
NGPUS_PER_NODE = "1"
print("MASTER_HOST: " + MASTER_HOST)
print("MASTER_ADDR: " + MASTER_ADDR)
print("MASTER_PORT: " + MASTER_PORT)
print("NNODES: " + NNODES)
print("NODE_RANK: " + NODE_RANK)
print("NGPUS_PER_NODE: " + NGPUS_PER_NODE)
if int(NNODES) <= 1:
# 若节点数为1,则为单机训练 若GPU大于1则为多卡训练,否则为单卡训练
if int(NGPUS_PER_NODE) > 1:
print("multi-gpus training.")
command = "python -m torch.distributed.launch"
command += " --nproc_per_node=" + str(NGPUS_PER_NODE)
command += " " + os.path.split(os.path.realpath(__file__))[0] + "/Main.py"
else:
print("single-gpu training.")
command = "python -u " + os.path.split(os.path.realpath(__file__))[0] + "/Main.py"
else:
# 多机分布式训练,使用python torch.distributed.launch或torchrun
# 用户若聚焦多机分布式训练,仅需关注当前段
print("multi-machies training.")
command = "python -u -m torch.distributed.launch"
command += " --nproc_per_node=" + str(NGPUS_PER_NODE)
command += " --nnodes=" + str(NNODES)
command += " --node_rank=" + str(NODE_RANK)
command += " --master_addr=" + str(MASTER_ADDR)
command += " --master_port=" + str(MASTER_PORT)
# 拼接原启动脚本和外部传参
command += " " + os.path.split(os.path.realpath(__file__))[0] + "/train.py"
user_args = " " + " ".join(sys.argv[1:])
command += user_args
print(command)
# 启动训练脚本并监测退出状态
start = time.time()
process = subprocess.Popen(command, shell=True)
end = time.time()
process.wait()
print("training time:" + str(end - start))
message = process.returncode
print("training message:" + str(message))
sys.exit(message)