重点在modelscope
modelscope框架设计思路
modelscope的设计思路是基于插件注册的思维
最无语的是它会在运行开始时注册所有插件浪费时间空间资源,
然后再根据.json
配置文件一个一个构建需要的插件,最后组成一个pipline
注册是如何进行的呢?
首先初始化一个注册表
PREDICTORS = Registry('predictor')
然后通过装饰器注册模块
@PREDICTORS.register_module()
class FaceKeypointsPredictor(PredictorV2):
这样就是注册完毕,后面通过configuration.json构建各个组件
可以自己看一下配置文件的指南:
ModelScope Configuration详解
本文简单写一下个人理解
一个推理pipline
的主要组成:
- framework(必填): 模型运行所需的框架, 例如pytorch,tensorflow,kaldi等。
- task(必填): 模型所支持的任务类型,可以是str或者 str列表。
- pipeline(必选): 推理使用的pipeline类型。
- model (可选): 模型实例化相关参数配置,具体参数请直接参考对应模型库的configuration.json示例。
- dataset(可选): 训练评估过程中使用的数据集配置信息。
- preprocessor(可选): 训练评估过程中使用的预处理配置
- train(可选):用以配置训练过程中的超参数,例如模型保存目录、训练轮数、优化器、学习率等参数。
- evaluation(可选): 用以配置评估过程中数据读取、评估指标等参数。
其实可以灵活调整, 举个例子:
pipline是一系列操作的集合,当只有一个操作时:
"pipeline": {
"type": "mobilenet_face-2d-keypoints_alignment",
"predictor_config": {
"type": "FaceKeypointsPredictor"
}
当pipline作为数据预处理操作时,由好几个操作集成:
"pipeline": [
{"type":"FaceKeypointNorm","input_size":96},
{"type":"MMToTensor"},
{"type":"NormalizeTensor","mean":[0.4076,0.458,0.485],"std":[1.0,1.0,1.0]},
{"type":"Collect","keys":["img","target_point","target_point_mask","target_pose","target_pose_mask"]}
]
type
是一个操作的名字,一般一个操作是一个类,并且一般与类同名,后面跟着的则是类的参数,在构建时调用build_from_cfg
函数从注册表中用type
名搜索类并通过参数实例化
比如模型的构建:
"model": {
"type": "face-2d-keypoints",
"backbone": {...},
"keypoint_head": {
},
"pose_head": {
}
},
"__easycv_arch__": {
"type": "FaceKeypoint"
}
},
可以看到模型face-2d-keypoints
由backbone
,keypoint_head
,pose_head
构成
再根据官网的结构图可以验证