更新时间:2025-02-20 GMT+08:00
分享

算法文件说明

上传到Octopus平台的本地算法文件包需要满足Octopus平台要求,本章节介绍算法文件基本要求及相关环境变量说明。

算法文件基本要求

算法文件目录结构可参考如下,需要包括启动文件“xxx.py”(启动文件名可自定义),以及一些必要的训练文件。

  • 启动文件(必选)

    算法的启动文件,直接填写相对路径,如 “main.py” 或“tools/main.py”。

  • 需要编译的依赖(可选)

    如果使用了第三方的需要编译的算法库,将编译脚本或编译产物或依赖库添加到算法文件根目录下。推荐将通用依赖编译安装操作放在算法绑定的用户自定义镜像。

    不支持动态联网安装依赖,包括但不限于apt/apt-get/pip等命令,建议提前安装在自定义镜像中。

相关参数说明

表1 相关参数说明

名称

环境变量

默认值

备注

数据集目录

DATASET

  • CCE: /tmp/data/dataset
  • ModelArts: /home/ma-user/datasets

数据集在训练任务容器中的存放路径,可自行获取各种数据集信息。

数据集映射

DATASET_MAP

{key1: value1, key2: value2}

以键值对提供数据集名称和容器内路径的变量,其中容器内路径参考数据集目录

数据缓存目录

CACHED_DATASET

  • CCE: /tmp/data/cached-dataset
  • ModelArts: /home/ma-user/cached-datasets

缓存数据集在训练任务容器中的挂载路径。

模型存放目录

RESULT

  • CCE: /tmp/result
  • ModelArts: /home/ma-user/modelarts/result

训练产物的存放路径,产物输出到此路径后,在任务结束时。可在任务详情页的输出模型版本中浏览及执行各种操作。

增量训练模型目录

MODEL

  • CCE: /tmp/data/model
  • ModelArts: /home/ma-user/modelarts/user-job-dir/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)]

分布式训练环境变量说明

表2 相关参数说明

名称

环境变量

示例值

备注

节点地址

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)

相关文档