前言
一、注册
二、导入项目
三、修改代码适配在线环境
1、下载预训练模型
2、上传模型
3、下载数据集
4、修改数据集
5、上传数据集
四、编写启动文件
1、修改train.py
2、单独启动文件
五、创建调试任务
1、路径说明
2、创建任务
3、开始调试
4、导出镜像
六、创建训练任务
1、路径说明
2、创建任务
3、开始训练
4、下载训练结果
问题
1、无法解压代码
总结
前言
当前启智平台每天能够稳定白嫖5个小时Nvidia T4、5小时ascend 910或者其他算力。
一、注册
点击这里进入注册链接。

填写相关信息,完成注册。
二、导入项目
在首页右上角选择迁移外部项目。

如下图所示,填写相关信息
url:https://github.com/ultralytics/yolov5.git
迁移类型:因为我们要做修改,因此不勾选

点击迁移,耐心等待迁移结束。
三、修改代码适配在线环境
1、下载预训练 模型
平台访问github有一定几率失败,因此我们需要提前上传。
我个人使用的是yolov5s的预训练模型,这里贴出下载地址:https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt
其他几个模型只需要将yolov5s的s修改为n,s,m,l,x,n6,s,6,m6,l6,x6即可。老规矩,下不动丢迅雷。
区别如下:

2、上传模型
因为我目前只用yolov5s,且模型不大,因此我将其上传到仓库的models文件夹 内了。
其他模型请按如下步骤上传

如果是你自己的模型,可以设置为私有



3、下载数据集
这里使用coco128数据集做演示。
下载地址:https://ultralytics.com/assets/coco128.zip
4、修改数据集
为方便接下来的操作,请将数据集调整到这样

coco128.yaml内设置好相关信息,以下仅供参考
# YOLOv5 ? by Ultralytics, AGPL-3.0 license
# COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics
# Example usage: python train.py --data coco128.yaml
# parent
# ├── yolov5
# └── datasets
# └── coco128 ← downloads here (7 MB)
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: ../datasets/coco128 # dataset root dir
train: images/train2017 # train images (relative to 'path') 128 images
val: images/train2017 # val images (relative to 'path') 128 images
test: # test images (optional)
# Classes
names:
0: person
1: bicycle
2: car
3: motorcycle
4: airplane
5: bus
6: train
7: truck
8: boat
9: traffic light
10: fire hydrant
11: stop sign
12: parking meter
13: bench
14: bird
15: cat
16: dog
17: horse
18: sheep
19: cow
20: elephant
21: bear
22: zebra
23: giraffe
24: backpack
25: umbrella
26: handbag
27: tie
28: suitcase
29: frisbee
30: skis
31: snowboard
32: sports ball
33: kite
34: baseball bat
35: baseball glove
36: skateboard
37: surfboard
38: tennis racket
39: bottle
40: wine glass
41: cup
42: fork
43: knife
44: spoon
45: bowl
46: banana
47: apple
48: sandwich
49: orange
50: broccoli
51: carrot
52: hot dog
53: pizza
54: donut
55: cake
56: chair
57: couch
58: potted plant
59: bed
60: dining table
61: toilet
62: tv
63: laptop
64: mouse
65: remote
66: keyboard
67: cell phone
68: microwave
69: oven
70: toaster
71: sink
72: refrigerator
73: book
74: clock
75: vase
76: scissors
77: teddy bear
78: hair drier
79: toothbrush
最后打包压缩,名称要和coco128.yaml中的path一致,否则解压数据的时候会比较麻烦。
为了简单,假设数据集名称为xxx,请将xxx.yaml(path路径为…/datasets/xxx)和相关数据打包到xxx.zip
5、上传数据集
注意:此处应分为CPU/GPU或NPU两种,且互相不能调用




这里我已经在另一个项目中上传了,因此上传失败,你自己的数据集是不会这样的。
四、编写启动文件
启智在训练时会自动加载数据集和模型到指定文件夹,结果也需要保存到指定文件夹。当然,你可以通过调试去训练,但是麻烦程度+999.
这里,如果你在导入的时候没有勾选镜像的话,按照法一直接修改train.py即可。否则建议单独建立分支或者单独编写一个启动文件(法二)。
1、修改train.py
在模块导入最下方添加代码,创建输出目录
import zipfile
import shutil
import subprocess
if not os.path.exists("/tmp/output"): # 判断是否存在文件夹如果不存在则创建为文件夹
os.makedirs("/tmp/output")
print("create '/tmp/output' successed!")
在train函数return结果之前添加代码,保存结果到输出目录
def zip_runs_folder():
folder_path = "runs"
zip_path = "runs.zip"
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(folder_path):
for file in files:
file_path = os.path.join(root, file)
zipf.write(file_path, os.path.relpath(file_path, folder_path))
print("Successfully compressed the 'runs' folder and its contents!")
zip_runs_folder()
shutil.copy('runs.zip','/tmp/output')
shutil.copy('runs/train/exp/weights/best.pt','/tmp/output')
print("Save training output successfully!")
print("Start export onnx model!")
subprocess.call(f"python export.py --weights runs/train/exp/weights/best.pt --data {opt.data} --include onnx --opset=12 --simplify --device 0", shell=True)
shutil.copy('runs/train/exp/weights/best.onnx','/tmp/output')
print("Export onnx model successfully!")
在main函数开头添加代码,解压数据集
#Copy dataset and unzip
data_param = os.path.basename(opt.data) # 获取--data参数的文件名
data_name = data_param.split('.')[0] # 获取数据集名称,去除文件后缀
dataset_dir = "../datasets" # 数据集目录
dataset_path = f"/tmp/dataset/{data_name}.zip" # 数据集压缩文件路径
if not os.path.exists(os.path.join(dataset_dir, data_name)):
print("start unzip dataset,please wait some times!")
f = zipfile.ZipFile(os.path.join(dataset_path),'r')
for file in f.namelist():
f.extract(file,"../datasets") # 解压到的位置
f.close()
print("Dataset decompression completed!")
2、单独启动文件
在代码根目录新建start.py文件
import os
import zipfile
import shutil
import subprocess
import argparse
from pathlib import Path
import sys
FILE = Path(__file__).resolve()
ROOT = FILE.parents[0] # YOLOv5 root directory
if str(ROOT) not in sys.path:
sys.path.append(str(ROOT)) # add ROOT to PATH
ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative
# Parse command line arguments
parser = argparse.ArgumentParser()
parser.add_argument("--weights", type=str)
parser.add_argument("--cfg", type=str)
parser.add_argument("--data", type=str)
parser.add_argument("--hyp", type=str)
parser.add_argument("--epochs", type=int)
parser.add_argument("--batch-size", type=int)
parser.add_argument("--imgsz", "--img", "--img-size", type=int)
parser.add_argument("--rect", action="store_true")
parser.add_argument("--resume", nargs="?", const=True)
parser.add_argument("--nosave", action="store_true")
parser.add_argument("--noval", action="store_true")
parser.add_argument("--noautoanchor", action="store_true")
parser.add_argument("--noplots", action="store_true")
parser.add_argument("--evolve", type=int, nargs="?", const=300)
parser.add_argument("--evolve_population", type=str)
parser.add_argument("--resume_evolve", type=str)
parser.add_argument("--bucket", type=str)
parser.add_argument("--cache", type=str, nargs="?", const="ram")
parser.add_argument("--image-weights", action="store_true")
parser.add_argument("--device")
parser.add_argument("--multi-scale", action="store_true")
parser.add_argument("--single-cls", action="store_true")
parser.add_argument("--optimizer", type=str, choices=["SGD", "Adam", "AdamW"])
parser.add_argument("--sync-bn", action="store_true")
parser.add_argument("--workers", type=int)
parser.add_argument("--project")
parser.add_argument("--name")
parser.add_argument("--exist-ok", action="store_true")
parser.add_argument("--quad", action="store_true")
parser.add_argument("--cos-lr", action="store_true")
parser.add_argument("--label-smoothing", type=float)
parser.add_argument("--patience", type=int)
parser.add_argument("--freeze", nargs="+", type=int)
parser.add_argument("--save-period", type=int)
parser.add_argument("--seed", type=int)
parser.add_argument("--local_rank", type=int)
parser.add_argument("--entity")
parser.add_argument("--upload_dataset", nargs="?", const=True)
parser.add_argument("--bbox_interval", type=int)
parser.add_argument("--artifact_alias", type=str)
parser.add_argument("--ndjson-console", action="store_true")
parser.add_argument("--ndjson-file", action="store_true")
opt = parser.parse_args()
if not os.path.exists("/tmp/output"): # 判断是否存在文件夹如果不存在则创建为文件夹
os.makedirs("/tmp/output")
print("create '/tmp/output' successed!")
#Copy dataset and unzip
data_param = os.path.basename(opt.data) # 获取--data参数的文件名
data_name = data_param.split('.')[0] # 获取数据集名称,去除文件后缀
dataset_dir = "../datasets" # 数据集目录
dataset_path = f"/tmp/dataset/{data_name}.zip" # 数据集压缩文件路径
if not os.path.exists(os.path.join(dataset_dir, data_name)):
print("start unzip dataset,please wait some times!")
f = zipfile.ZipFile(os.path.join(dataset_path),'r')
for file in f.namelist():
f.extract(file,"../datasets") # 解压到的位置
f.close()
print("Dataset decompression completed!")
# zip runs folder
def zip_runs_folder():
folder_path = "runs"
zip_path = "runs.zip"
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(folder_path):
for file in files:
file_path = os.path.join(root, file)
zipf.write(file_path, os.path.relpath(file_path, folder_path))
print("Successfully compressed the 'runs' folder and its contents!")
#start train
print("Start train model!")
subprocess.call(f"python train.py --weights {opt.weights} --cfg {opt.cfg} --data {opt.data} --hyp {opt.hyp} --epochs {opt.epochs} --batch-size {opt.batch_size} --imgsz {opt.imgsz} --device {opt.device} --name {opt.name} --exist-ok --rect {'--resume' if opt.resume else ''} {'--nosave' if opt.nosave else ''} {'--noval' if opt.noval else ''} {'--noautoanchor' if opt.noautoanchor else ''} {'--noplots' if opt.noplots else ''} {'--evolve' if opt.evolve else ''} {'--resume_evolve' if opt.resume_evolve else ''} {'--cache' if opt.cache else ''} {'--image-weights' if opt.image_weights else ''} {'--multi-scale' if opt.multi_scale else ''} {'--single-cls' if opt.single_cls else ''} --optimizer {opt.optimizer} {'--sync-bn' if opt.sync_bn else ''} --workers {opt.workers} --project {opt.project} --patience {opt.patience} --freeze {' '.join(map(str, opt.freeze))} --save-period {opt.save_period} --seed {opt.seed} --local_rank {opt.local_rank}", shell=True)
print("Training is complete, start saving results!")
# Save training output
zip_runs_folder()
shutil.copy('runs.zip','/tmp/output')
shutil.copy('runs/train/exp/weights/best.pt','/tmp/output')
print("Save training output successfully!")
# Export onnx model
print("Start export onnx model!")
subprocess.call(f"python export.py --weights runs/train/exp/weights/best.pt --data {opt.data} --include onnx --opset=12 --simplify --device 0", shell=True)
shutil.copy('runs/train/exp/weights/best.onnx','/tmp/output')
print("Export and save onnx model successfully!")
五 、创建调试任务
以英伟达GPU环境为例
1、路径说明
第四步中的路径是英伟达 gpu训练环境的路径,调试时需要删除/tmp
/code:本目录对应控制台左侧的文件菜单栏,已经存放代码仓为 master.zip,需要用户手动解压
/dataset: 本目录下可以找到创建调试任务时选取的数据集,平台已解压
/pretrainmodel: 本目录下将加载创建调试任务时选取的预训练模型
2、创建任务
如下图所示

建议使用T4卡做前期调试,这样比较节省积分


镜像可以使用这个,这样需要配置的东西就少一些
数据集可以提前下载coco2017val,上传到数据集,节省调试时下载时间。
3、开始调试
不幸的是,笔者在写本文时,英伟达集群似乎都无法创建任务,这里没法放进图了。
首先,打开终端执行以下命令
su
apt update #这一步很重要
apt install unzip
cd /code
unzip master.zip
之后我们只需要打开对应的jupyter文件进行调试即可。
4、导出镜像
在调试完成后,我们需要导出镜像以便我们在训练时使用

注意,必须在任务处于运行状态时提交镜像
提交成功后,在下次创建任务的时候,在我的镜像内就可以看到。
六、创建训练任务
以英伟达GPU环境为例
1、路径说明
/tmp/code:存放训练脚本
/tmp/dataset:存放训练数据集
/tmp/pretrainmodel:存放预训练模型
/tmp/output:存放训练结果
2、创建任务
如下图所示

注意事项:
代码分支:选择存放你训练代码的分支,我这没有去修改master分支,选择从master分支派生出来的适配启智GPU平台的train_gpu分支
镜像:请选择你在上一步中提交的镜像,否则可能需要在开始运行前安装缺少的依赖(没有命令交互界面,需要写入main函数)
可以使用我的环境(仅保证GPU环境下可以正常训练和导出onnx模型):192.168.204.22:5000/default-workspace/99280a9940ae44ca8f5892134386fddb/image:yolov5_gpu_240124
启动文件:一般为train.py,如果你需要在训练开始前做一些配置的话,可能需要使用start.sh等
数据集:训练使用的数据集
运行参数:详见train.py内opt函数,和本地训练一致,只需要写与默认参数不同的参数即可
3、开始训练
新建任务后,等待其状态变为running,可以点击任务,日志查看其输出(可能需要手动刷新才会显示新的日志)
下图为任务开始时的日志

下图为训练结束后的日志

4、下载训练结果
点击结果下载,如果使用我的代码,将生成以下三个文件。

文件说明:
best.onnx:导出的onnx模型
best.pt:训练获得的原始pt模型
runs.zip:包含所有训练结果的压缩包
问题
1、无法解压代码
一定要先打开终端执行
su #这里是切换到root用户
apt update #不然没法安装软件
总结
具体细节直接点击平台首页右上角的问号,查看帮助。好像过段时间会统一各个集群的环境内代码等存放位置,请关注公告。