上传数据和算法至SFS(首次使用时需要)
前提条件
- ECS服务器已挂载SFS,请参考ECS服务器挂载SFS Turbo存储。
- 在ECS中已经创建ma-user和ma-group用户,请参考在ECS中创建ma-user和ma-group。
- 已经安装obsutil,请参考下载和安装obsutil。
- 参考线下容器镜像构建及调试章节,构建容器镜像并调试,镜像构建及调试与单机单卡相同。
- 上传镜像,参考单机单卡训练的上传镜像章节操作。
准备数据
- 登录coco数据集下载官网地址:https://cocodataset.org/#download
- 下载coco2017数据集的Train(18GB)、Val images(1GB)、Train/Val annotations(241MB),分别解压后并放入coco文件夹中。
- 下载完成后,将数据上传至SFS相应目录中。由于数据集过大,推荐先通过obsutil工具将数据集传到OBS桶后,再将数据集迁移至SFS。
- 在本机机器上运行,通过obsutil工具将本地数据集传到OBS桶。
# 将本地数据传至OBS中 # ./obsutil cp ${数据集所在的本地文件夹路径} ${存放数据集的obs文件夹路径} -f -r # 例如 ./obsutil cp ./coco obs://your_bucket/ -f -r
- 登录ECS服务器,通过obsutil工具将数据集迁移至SFS,样例代码如下:
# 将OBS数据传至SFS中 # ./obsutil cp ${数据集所在的obs文件夹路径} ${SFS文件夹路径} -f -r # 例如 ./obsutil cp obs://your_bucket/coco/ /mnt/sfs_turbo/ -f -r
/mnt/sfs_turbo/coco文件夹内目录结构如下:
coco |---annotations |---train2017 |---val2017
更多obsutil的操作,可参考obsutil简介。
- 将文件设置归属为ma-user:
chown -R ma-user:ma-group coco
- 在本机机器上运行,通过obsutil工具将本地数据集传到OBS桶。
代码云上适配
- 下载YOLOX代码。代码仓地址:https://github.com/Megvii-BaseDetection/YOLOX.git。
git clone https://github.com/Megvii-BaseDetection/YOLOX.git cd YOLOX git checkout 4f8f1d79c8b8e530495b5f183280bab99869e845
- 修改“requirements.txt”中的onnx版本,改为“onnx>=1.12.0”。
- 将“yolox/data/datasets/coco.py”第59行的“data_dir = os.path.join(get_yolox_datadir(), "COCO")”改为“data_dir = '/home/ma-user/coco'”。
# data_dir = os.path.join(get_yolox_datadir(), "COCO") data_dir = '/home/ma-user/coco'
- 在“tools/train.py”的第13行前加两句代码。
# 加上这两句代码,防止运行时找不到yolox module import sys sys.path.append(os.getcwd()) # line13 from yolox.core import launch from yolox.exp import Exp, get_exp
- 将“yolox/layers/jit_ops.py”第122行的“fast_cocoeval”改为“fast_coco_eval_api”。
# def __init__(self, name="fast_cocoeval"): def __init__(self, name="fast_coco_eval_api"):
- 将“yolox\evaluators\coco_evaluator.py”第294行的“from yolox.layers import COCOeval_opt as COCOeval”改为“from pycocotools.cocoeval import COCOeval”。
try: # from yolox.layers import COCOeval_opt as COCOeval from pycocotools.cocoeval import COCOeval except ImportError: from pycocotools.cocoeval import COCOeval logger.warning("Use standard COCOeval.")
- 在tools目录下新建一个“run.sh”作为启动脚本,“run.sh”内容可参考:
#!/usr/bin/env sh set -x set -o pipefail export NCCL_DEBUG=INFO DEFAULT_ONE_GPU_BATCH_SIZE=32 BATCH_SIZE=$((${MA_NUM_GPUS:-8} * ${VC_WORKER_NUM:-1} * ${DEFAULT_ONE_GPU_BATCH_SIZE})) if [ ${VC_WORKER_HOSTS} ];then YOLOX_DIST_URL=tcp://$(echo ${VC_WORKER_HOSTS} | cut -d "," -f 1):6666 /home/ma-user/anaconda3/envs/pytorch/bin/python -u tools/train.py \ -n yolox-s \ --devices ${MA_NUM_GPUS:-8} \ --batch-size ${BATCH_SIZE} \ --fp16 \ --occupy \ --num_machines ${VC_WORKER_NUM:-1} \ --machine_rank ${VC_TASK_INDEX:-0} \ --dist-url ${YOLOX_DIST_URL} else /home/ma-user/anaconda3/envs/pytorch/bin/python -u tools/train.py \ -n yolox-s \ --devices ${MA_NUM_GPUS:-8} \ --batch-size ${BATCH_SIZE} \ --fp16 \ --occupy \ --num_machines ${VC_WORKER_NUM:-1} \ --machine_rank ${VC_TASK_INDEX:-0} fi
部分环境变量在Notebook环境中不存在,因此需要提供默认值。
- 将代码放到OBS上,然后通过OBS将代码传至SFS相应目录中。
- 在本机机器上运行,通过obsutil工具将本地数据集传到OBS桶。
# 将本地代码传至OBS中 ./obsutil cp ./YOLOX obs://your_bucket/ -f -r
- 登录ECS服务器,通过obsutil工具将数据集迁移至SFS,样例代码如下:
# 将OBS的代码传到SFS中 ./obsutil cp obs://your_bucket/YOLOX/ /mnt/sfs_turbo/code/ -f -r
本案例中以obsutils方式上传文件,除此之外也可通过SCP方式上传文件,具体操作步骤可参考本地Linux主机使用SCP上传文件到Linux云服务器。
- 在本机机器上运行,通过obsutil工具将本地数据集传到OBS桶。
- 在SFS中将文件设置归属为ma-user。
chown -R ma-user:ma-group YOLOX
- 执行以下命令,去除Shell脚本的\r字符。
cd YOLOX sed -i 's/\r//' run.sh
Shell脚本在Windows系统编写时,每行结尾是\r\n,而在Linux系统中行每行结尾是\n,所以在Linux系统中运行脚本时,会认为\r是一个字符,导致运行报错“$'\r': command not found”,因此需要去除Shell脚本的\r字符。