协议文档版本 | ymir 版本 | 说明 | 镜像适配方式 |
---|---|---|---|
0.0.0 | 0.0.0 - 1.1.0 | 初始版本 | |
1.0.0 | 1.2.0 - 1.2.2 | 增加关于中间模型的描述 | 使用 write_model_stage 方法保存训练产出的中间模型 |
1.1.0 | 2.0.0 - | 4.3.2 节,训练完成后,模型保存策略更改 4.4.2 节,推理完成后,推理结果保存的节点由 annotations 改为 boxes |
1. 保存中间模型时,将模型文件保存至以 中间模型名称 命名的子目录中2. 保存推理结果时,将原来的 annotations 键改为 boxes |
此文档用于规定 ymir 与功能性 docker container 之间的数据交互方式,这些 docker container 用于模型训练,挖掘及推理任务。
此文档面向的读者为模型训练,挖掘及推理镜像的开发者们。
ymir 系统有两种用户交互方式:web 方式和命令行方式。
web 用户在使用训练,挖掘与推理功能时,通过任务页面选择使用的镜像,而命令行用户在使用训练,挖掘与推理功能时,通过 --executor
参数来决定使用哪个镜像。
模型的训练过程分为以下几个步骤:
-
ymir 导出对应的训练集与验证集至指定的工作目录,并准备
config.yaml
文件; -
ymir 通过
nvidia-run
将指定的工作目录,以及训练所需要的全部配置文件挂载至 4.3 节所述的位置,启动训练镜像,并等待完成; -
在此过程中,镜像完成以下事务:
3.1. 读取
/in/train-index.tsv
及/in/val-index.tsv
中的训练集与验证集中的图片和标注信息;3.2. 启动训练流程;
3.3. 将训练结果保存至
/out/models
目录,并将最好的一个结果及其 mAP 写入/out/models/result.yaml
中。 -
训练成功完成后,ymir 读取位于
out/models
目录下的输出模型,校验其有效性,并将模型归档。
ymir 对挖掘与推理这两个动作有如下定义:
推理:使用模型对图像进行前处理-前向-后处理,从而得出结果的过程。
挖掘:在已经具备模型和图像的前提下,使用 active learning 等技术对图像进行打分,并将结果图像依据分数从高到低进行排序;
ymir 的挖掘与推理镜像需要支持以下几种场景的使用:
在此场景中,用户想在某个数据集上,或者某些图片上,对模型的效果进行初步验证,这个过程分为以下几个步骤:
-
ymir 将需要用到的图片导出到工作目录,并准备好
config.yaml
文件; -
ymir 通过
nvidia-run
将工作目录,以及推理所需要的全部配置文件挂载至 4.4 节所述的位置,启动镜像,并等待完成; -
在此过程中,镜像完成以下事务:
3.1. 从
/in/candidate-index.tsv
中读取所有图像资源;3.2. 使用
/in/models
位置的模型及预先写好的前后处理代码,完成推理;3.3. 如果是检测,将结果写入到
/out/infer-result.json
中,此文件的结构在后文详述;3.4. 如果是语义或实例分割,将结果转换成 coco json 格式,写入
/out/infer-result.json
中,此文件的结构在后文详述。 -
推理成功完成后,ymir 读取推理结果,如果是对于某个特定数据集(而不是图片)进行的推理,则将推理结果写入数据集中,形成一个新的数据集。
在此场景中,用户已经成功训练出了一个模型,希望进一步通过 active learning 等方式,在某个数据集中挑选出对模型下一步训练最为有效的图片,这个过程分为以下几个步骤:
-
ymir 将需要用到的图片导出到工作目录,并准备好
config.yaml
文件; -
ymir 通过
nvidia-run
将指定工作目录,以及推理所需要的全部配置文件挂载至 4.4 节所述的位置,启动镜像,并等待完成; -
在此过程中,镜像完成以下事务:
3.1 从
/in/candidate-index.tsv
中读取所有图像资源;3.2 使用上述模型以及合适的算法,对传入的每张图片进行打分,并将打分结果按分数由高到低排列,保存至
/out/result.tsv
中; -
镜像完成后,ymir 收集
/out/result.tsv
中的结果,根据其中 topk 的结果筛选数据集
在此场景中,用户已经成功训练出了一个模型,希望进一步通过 active learning 等方式,在某个数据集中挑选出对模型下一步训练最为有效的图片(挖掘过程),同时对这些图片使用这个已经训练好的模型进行一次推理,所得出的结果用于后续标注人员对这批图片进行标注,此过程分为以下几个步骤:
-
ymir 将需要用到的图片导出到工作目录;
-
ymir 通过
nvidia-run
将指定工作目录,以及推理所需要的全部配置文件挂载至 4.4 节所述的位置,启动镜像,并等待完成; -
在镜像启动过程中,镜像完成以下两个事务:
3.1. 推理:使用
/in/models
位置的模型及预先写好的前后处理代码,完成推理3.2. 如果是检测,将结果写入到
/out/infer-result.json
中;3.3. 如果是语义或实例分割,将结果转换成 coco json 格式,并写入
/out/infer-result.json
中;3.4. 挖掘:使用上述模型以及合适的算法,对传入的每张图片进行打分,并将打分结果保存至
/out/result.tsv
中。 -
镜像完成后,ymir 收集
/out/result.tsv
中的结果,根据其中 topk 的结果筛选数据集,并将/out/infer-result.json
中的推理保存并归档。
路径 | 说明 |
---|---|
/img-man/readme.md | 对此镜像功能的描述,主要作用,接受的图像数据格式、标注数据格式、输出结果样式等 |
/img-man/training-template.yaml | 训练镜像需要将自己使用的配置文件参考模板放在这个位置,供用户提取,并从命令行传入 |
/img-man/mining-template.yaml /img-man/infer-template.yaml |
挖掘和推理镜像需要将自己使用的配置文件参考模板放在这两个位置,供用户提取,并从命令行传入。当需要镜像同时进行推理和挖掘时,传入的配置文件是两个文件内容的合并 |
注:调用者事先将输入文件挂载到对应位置上,docker container 从这些固定位置上读取输入文件,同时,将输出文件写入到固定挂载的输出位置上。
以下章节,输入挂载点中所有 .tsv
和 .yaml
文件中出现的路径都是绝对路径。
路径 | 说明 |
---|---|
/out/monitor.txt | 必要,模型训练进度的输出文件。 只保留最新的一条记录,记录不累加。 记录格式参考注1 |
/out/ymir-executor-out.log | 系统维护的日志文件,镜像的所有控制台输出都将被保存到此日志文件中,镜像不应该读写此日志文件 |
注1. monitor.txt
的格式如下:
<task_id>\t<timestamp>\t<percent>\t<status>\n
<message>
其中:
-
task_id
是任务id,在任务启动时,由config.yaml
传入 -
timestamp
是写入监视信息的时间戳,单位为秒,保留六位小数。 -
percent
是一个0-1之间的数,标识了任务执行的百分比 -
status
状态标识,分为-
1(尚未开始)
-
2(正在进行)
-
4(出错,异常结束)
-
-
message
是自定义信息,比如异常结束可以写入具体的错误原因,backtrace 信息等
例如:
train_0 1622552974.081620 0.5 2
或者:
train_0 1622552974.040471 1 4
no training data found
-
所有docker image都通过
nvidia-docker run
命令启动 -
在
/usr/bin
下面都需要设置一个启动任务的脚本:/usr/bin/start.sh
(不带参数) -
任务所用的所有配置将由系统写入
/in/config.yaml
- 特别的,如果用户需要同时在一个镜像中完成挖掘和推理任务,传入的
/in/config.yaml
将是挖掘配置和推理配置的合并
- 特别的,如果用户需要同时在一个镜像中完成挖掘和推理任务,传入的
-
在任务执行过程中,所有输出过程如果遇到异常(比如写入失败、没有写入权限等),则直接报错退出,并相应在
/out/monitor.txt
写入错误原因; -
所有输入过程如果遇到异常(如
index.tsv
里面所指示的图像文件或标注文件不存在),也直接报错退出
路径 | 说明 |
---|---|
/in/train-index.tsv | 必要,训练集图像及标注的索引文件,每一行都是图片文件路径和标注路径 * 图片文件为jpg,png等常用格式(但不保证一定有扩展名); * 标注文件可以是csv,txt,xml,json格式,拥有和图片相同的主文件名。 |
/in/val-index.tsv | 必要,验证集图像及标注的索引文件,格式同/in/train-index.tsv |
/in/config.yaml | 必要,配置项所在的文件,YAML 格式,具体配置项由调用双方商定,注1中列出了几个固定的键 |
/in/assets | 必要,图像资源所在的目录,只读 |
/in/annotations | 必要,图像标注所在的目录 |
注1. config.yaml
文件的固定保留键:在任务开始时,这些键值对会根据任务的实际情况由 YMIR 系统自动填入,就算镜像作者在 training-template.yaml / mining-template.yaml / infer-template.yaml 三个模板文件中写入了其他的值,在任务开始的时候也会被系统写入的值替换掉。
-
task_id
: 任务id,只含英文数字下划线,用于标识或区别任务,会出现在/out/monitor.txt
中,也可以出现在日志中 -
class_names
:训练的物体类别名称 -
gpu_id
:使用哪几块 GPU,用逗号隔开,如果为空,则使用 CPU 训练 -
pretrained_model_params
: 预训练模型文件的路径列表,如果留空,则从头开始训练,如果非空,则从这个列表中找到镜像支持的模型文件,并在此模型的基础上继续训练 -
export_format
: 希望 ymir 向此镜像提供的数据格式,由标注格式
与图像格式
两部分组成,中间用英文冒号分隔,例如voc:raw
表示导出原始图像,以及 voc 格式的检测标注,如果此项留空或者不存在,则只导出图像,不导出标注-
标注格式
可取以下值:-
voc
: 导出 voc 格式的检测标注 -
ark
: 导出 csv 格式的检测标注(class id, x, y, w, h, annotation quality, rotate angle) -
coco
: 导出 coco json 格式的检测及分割标注
-
-
图像格式
目前只能指定为raw
-
-
object_type
: 本次训练任务的类别,2 - 目标检测,3 - 语义分割,4 - 实例分割
路径 | 说明 |
---|---|
/out/monitor.txt | 参考共同部分 |
/out/models | 必要,最终生成的模型的输出目录,模型文件存放在以 stage_name 命名的子目录中。 /out/models 下必须有一个 result.yaml 文件,格式参考注1 |
注1. result.yaml
文件的格式如下:
best_stage_name: epoch_50 # 最优的中间模型名称
model_stages:
epoch_10: # 中间模型名称:epoch_10
files: # 中间模型对应的文件列表,这些文件在 /out/models 下面
- 149_1.000-symbol.json
- 149_1.000-0149.params
mAP: 0.6 # 中间模型对应的 mean average precision
mAR: 0.6 # 中间模型对应的 mean average recall
TP: 50 # true positive 框个数
FP: 30 # false positive 框个数
FN: 30 # false negative 框个数
stage_name: epoch_10
timestamp: 1663934682 # 创建时间对应的 timestamp
epoch_50:
files:
- 149_1.000-symbol.json
- 149_1.000-0149.params
mAP: 0.8
stage_name: epoch_50
timestamp: 1663934682
evaluate_config: # 计算 mAP, mAR, TP, FP, FN 时使用的配置信息
conf_thr: 0.005
iou_thr: 0.5
路径 | 说明 |
---|---|
/in/candidate-index.tsv | 必要,图片索引文件,此文件的每一行内容都是一个指向图片的路径,图片文件为jpg,png等常用格式(但不保证一定有扩展名) |
/in/models | 推理时使用的模型所在的目录 |
/in/config.yaml | 必要,配置项所在的文件,YAML 格式,具体配置项由调用双方商定,注1中列出了几个固定的键 |
注1: config.yaml
文件的固定保留键
-
task_id
: 任务id,只含英文数字下划线,用于标识或区别任务,会出现在/out/monitor.txt
中,也可以出现在日志中 -
model_params_path
: 推理时使用的模型的路径列表,镜像从这个列表中找到镜像支持的模型文件,并使用此模型进行推理或挖掘 -
gpu_id
: 使用 GPU 的 ID,用英文逗号隔开,如果为空,则使用 CPU -
run_infer
: 取值为0或1,1表示需要将检测/分类结果写入/out/infer-result.json
中,0表示不需要进行推理 -
run_mining
: 取值为0或1,1表示需要将挖掘结果写入/out/result.tsv
中,0表示不需要进行挖掘 -
class_names
: 模型可以识别的类型名称列表 -
object_type
: 任务模型类型,2 - 目标检测,3 - 语义分割,4 - 实例分割
路径 | 说明 |
---|---|
/out/monitor.txt | 参考共同部分 |
/out/result.tsv | 最终 mining 结果文件路径,格式见注1 |
/out/infer-result.json | 推理结果,格式见注2 & 3 |
注1. result.tsv
文件的格式
每一行的内容为:
<asset_path>\t<results>
其中 asset_path 为 /in/data/index.tsv
中所指的资源路径(直接把那里面的内容copy过来),results为模型打分结果,具体数据项由调用双方事先约定
注2. infer-result.json
文件的格式(检测)
{
"detection": {
"asset-name-0": {
"boxes":
[
{
"box": {
"x": 30,
"y": 30,
"w": 50,
"h": 50
},
"class_name": "cat",
"score": 0.8
},
...
]
},
"asset-name-1": {}
}
}
其中:
-
asset-name-0, asset-name-1就是
/in/candidate-index.tsv
里面的资源名称 (base name) -
box的结构为:x, y, w, h,参考系为图片坐标系,左上角为原点
-
class_name:模型推断出的类别名称,此名称需要出现在
/in/config.yaml
中的class_names
列表中,未知的 class name 所对应的检测结果将会被系统忽略
注3. infer-result.json
文件格式(语义及实例分割)
{
"images": [
{
"license": 0,
"file_name": "2007_000032.jpg",
"coco_url": "",
"height": 281,
"width": 500,
"data_captured": "2013-11-24 13:47:05",
"flickr_url": "",
"id": 1
},
],
"categories": [
{
"supercategory": "object",
"id": 1,
"name": "cat"
},
{
"supercategory": "object",
"id": 2,
"name": "person"
}
],
"annotations": [
{
"segmentation": {
"counts": "^bl346O[>N`A10c05\\OO1OO91h<OlB00l0022RO8?HAN10O70;0Y:Q1UEZ20kL`1JW7l5eGTJZ8o5dGQJ\\8S6[GnI04a8n5^GWJb8U6O1O110OZOeGdJZ8^5f0O0000N2001O01O0O10000O10001O0000000000001O00000000000010O001OO1000000000000000001O0O1O100N2N2000O012N01N2O001O0000O13MN2001O10O1O12M5\\G_I\\8d600001O0000001O0000O2O0000N2N10100O1K5O100000O11N1001O0000001OO1000O1N201O01O00000cN\\G[Ld8e3]GZLc8[3\\G_K6U1_8\\3hGcLX8]3iGWLCXOh8]4iGVLe8g3]GXLc8h3]GXLc8g3^GYLb8g3^GYLa8h3_GWLc8h3]GXLb8h3_GXLb8g3^GZLY;0UD_OMKW1c0d=@cQ`3",
"size": [
281,
500
]
},
"area": 88715.0,
"iscrowd": 0,
"image_id": 1,
"bbox": [
0.0,
0.0,
586.0,
421.0
],
"confidence": 0.8,
"category_id": 1,
"id": 1000
}
]
}
有几个需要注意的点:
-
file_name 存放图片的文件名,图片的文件名可以从 /in/candidate-index.tsv 中读取
-
bbox 是一个拥有四个 float 的 list,分别是 x, y, w, h
-
segmentation 部分支持 str 类型的 mask,也支持 list 类型的 polygon,结构与 coco 官方格式一致
-
此文件增加了 confidence,用于存放实例分割框的置信度,语义分割不需要这个 key