人像卡通画训练营:课时1:ModelScope社区Library技术架构介绍
ModelScope社区Library技术架构介绍
内容介绍
一、 ModelScope社区介绍
二、 Modelscope Library架构介绍
三、 使用方式&源码解读
四、 贡献流程
本节课主要学习以下五部分内容:
第一部分,ModelScope社区介绍;
第二部分,ModelScope Library架构介绍;
第三部分,ModelScope社区中各种模型的使用方式及源代码深入解读;
第四部分,用户自身模型对社区的贡献流程及提升模型工作在算法方面的影响力。
一、ModelScope社区介绍
1、基本介绍
以下二维码是社区网站的入口,用户直接可以扫描二维码或者登录https://www.modelscope.cn访问网站,查看各种模型和数据集,了解当前社区的情况。
ModelScope社区是由CCIF开源开发委员会和达摩院共同建立的中文开源模型社区,该社区中汇集了来自多个领域的优秀AI模型,目前共有667个模型,其中305个模型支持在线体验,197个模型支持模型的finetune定制化。此外,社区还提供了众多不同领域的数据集,总计有370个数据集,以便配合用户模型进行训练。除此之外,社区还提供了云端Notebook功能,其中包含免费的GPU使用资源,用户可以实现轻松访问,查看每个模型的使用指南,并运行每个模型的推理和训练示例代码。
2、核心理念
即MaaS:Model as a Service,如下图所示:
ModelScope社区致力于以模型为中心,构建模型级别的服务概念,覆盖不同层次的AI开发者。
AI爱好者可以通过网站的在线体验界面进行模型体验,初级AI使用者可以轻松使用API接口进行模型推理和自定义finetune,需要进行模型定制化的用户可以使用finetune接口修改参数调优自己的模型。同时,用户还可以参与开源代码的修改,完成自己模型的开发和调整。
ModelScope社区中提供了大量的SOTA模型,AI研究者可在这些资源的基础上进行创新性研究。
二、Modelscope Library架构介绍
1、目标
从ModelScope社区的构造思路出发,可以发现其中有3个关键性的要素,即模型、开发者和数据集。
Library的目标是将这三个要素有机结合在一起,使用户能够直接使用数据集 + 模型产出自身领域的模型,或者将模型用于生产领域解决AI需求。此外,用户还可以通过Library进行模型的finetune及进行定制化开发,以及贡献用户的模型代码和数据集访问代码,使得更多的用户可以想用贡献者的贡献成果。
2、核心设计理念
平台围绕以下四个核心理念构建:
(1)以模型为中心(Model Centric)
平台设计了以模型为中心的API,打造以模型为核心的开发应用体验,支持用户的全链路支持MLOps。
(2)简单易用(Simple)
平台在用户层面的接口尽量减少概念的学习,仅仅通过3个简单的接口即可完成模型的推理、finetune及部署,便于用户进行应用的开发及demo的制作。
(3)模块化设计(Modular design)
主要针对高阶的开发者,保证功能横向扩展的便利,方便用户贡献更多的模型及模型的二次开发。
(4)云原生(Cloud Native)
提供本地开发环境的支持,同时对接阿里云方便开发者这云上进行更多的模型推理、部署及finetune。
2、整体架构
(1)运行环境
对于本地环境,Library支持Linux、Max及Windows操作系统。
支持云上环境,包括网站提供的Notebook免费CPU和GPU资源,以及阿里云EAIS资源和PAI-DSW产品,同时支持模型部署为在线服务,通过PAI-EAS产品完成。
(2)底层计算框架
支持PyTorch、Tensorflow、Kaldi、ONNX,目前在推理方面支持良好;在训练方面,目前主要支持PyTorch,但未来将扩展更多Tensorflow的训练支持。
(3)Library核心功能
从底层构建开始,提供Hub功能,以便进行模型、数据集的创建、上传和下载。同时,还包括了日志和文件读取功能,其中文件读取包括OS、HTTP URL和本地文件的统一封装。由于Library将承载成千上万个模型的代码接入,模型的依赖会变得非常复杂,通过Lazyimport模块解耦各个模型之间的依赖,使得每个模型只需安装其所需的依赖就可以运行其所有功能。此外,还提供了与服务部署和访问相关的模块,以方便用户进行API调用。
(4)工作划分
共分为四个层次,这四个层次是整个架构中相对核心且面向算法的重要部分,包括数据、模型、训练和用户接口。
①数据
封装了Dataset数据预处理等功能,使用户可以加载Modelscope及自定义数据集用于模型训练。
②模型
涵盖了自然语言处理,计算机视觉、语音、多模态以及科学计算等多领域的丰富的模型。
③训练
提供开箱即用的Trainer,通过hooks机制完成训练流程的搭建,快速扩展整个训练流程。此外,还包括一些评估方面的功能,实现不同评估的Metrics,方便用户进行不同任务的评估。同时在分布式方面通过Parallel模块提供不同的分布式训练策略,如模型的数据并行、模型并行和混合并行等策略。值得注意的是,训练模型和数据模块都经过模块化设计和抽象,所有模块都支持在注册表中进行注册,用户只需在配置文件中进行简单配置,即可轻松构建和调用。
④用户接口
平台为用户提供了pipeline接口用于推理,提供Trainer模块进行训练和评估功能。Exporter提供了模型导出功能,以便后期模型部署的对接,Deployer目前主要用于在线服务的部署,未来可能也计划支持端侧或其他平台的部署。
三、使用方式&源码解读
1、环境安装
用户可以方便地在本地Python环境中安装工具,为了实现快速安装,平台提供了不同版本的CPU和GPU镜像,每个版本都会定期更新,用户可以在本地启动对应版本的Docker镜像就可以进行开发和调试。
同时,用户还可以通过pip或conda的方式安装Modelscope环境。首先通过conda创建Modelscope环境,安装基础的框架,通过pip install Modelscope或特定领域如multi-modal(语音领域)、nlp(自然语言处理领域)安装特定的环境。
值得注意的是,pip install Modelscope方式中,modelscope的所有下游算法模型领域的依赖不会被安装,若要安装的所有领域,则依次安装各个领域的模型即可。
此外,还支持用户克隆git clone的代码,通过这种方式用户可以拿到最新的代码,因为有些功能可能不会及时发布,用户可以使用源代码安装方式使用工具。
2、使用示例
(1)推理功能(Inference)
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
s
egmentation_pipeline=pipeline(task=Tasks
.
word_segmentation)
print(segmentation_pipeline(input="ModelScope汇聚各领域先进模型,在这里共建模型开源社区"))
通过pipeline接口即可完成所有任务的不同模型推理。
(2)训练功能(Train)
from modelscope.msdatasets import MsDataset
from modelscope
.
metainfo import Trainers
from modelscope
.
trainers import build
_
trainer
trainer=build_trainer(
Trainers.default
default_args=dict(
model='damo/nlp_structbert_sentence-similarity_chinese-base',
train_dataset=MsDataset.load(
'
clue
'
,subset='afqmc
'
,split=
'
train')
eval_dataset=MsDataset.load(
'
clue
'
,subset=
'
afqmc
'
,split=
'
evaluation')
)
trainer.train()
构建trainer,通过train.train即可完成模型的训练。
(3)评估功能(Evaluate)
from modelscope.msdatasets import MsDataset
from modelscope.
metainfo import Trainers
from modelscope.trainers import build
_
trainer
from modelscope.utils.hub import read_config
m
ode
l
_id = 'dano/speech_frcrn_ans_cirm_16k'
cfg=read_conf
ig
(mode
l_
id)
build_trainer(
Trainers.speech_frcm_ans_cim_16k,
dict(mode
l
_id,
train_dataset
=
MsDataset.load(
'
ICASSP_2021_DNS_Chal
l
e
nge
'
,split
'
train
'
)
eval_dataset=MsDataset.load(
'
ICASSP_221_DNS_Challen
ge
'
,split
'
evaluation
'
).train()
for i in range
(
cfg.train.
m
ax_epochs):
evaluation=trainer.evaluate(get_checkpoint(epoch=1))
print(f'epoch
{
i} evaluation result;
{evaluation}')
通过trainer.evaluate即可完成模型的评估。
3、功能介绍
(1)推理
所有的任务都可以通过统一的接口以及简单的几行代码轻松完成本地推理的调用。除此之外,还提供了API,如deploy model,以便用户将其模型部署到云端服务,进而集成到相应的生产环境中。
①pipeline的功能:
A. 批量预测
pipeline._call_(input,batch_size=n)
有些用户可能有大量的数据,同时其GPU显存也很大,在这种情况下,可以在pipeline运行过程中指定batch_size完成批量推理,提高GPU的使用率。
B. 指定device
pipeline.init_(xxx,device='gpu:0')
有些用户可能使用多卡机器,要指定特定的卡,可以通过在构建pipeline时指定device参数来实现。如果指定为CPU,pipeline将仅使用CPU推理;如果指定为GPU,则pipeline默认使用0卡的GPU推理;如果有多个卡,用户可以通过指定“gpu:卡ID”来实现。
另外,还有一种通用的方法,即CUDA_VISIBLE_DEVICE=0 python your_program.py,通过该环境变量的设置指定卡,可以在程序运行之前设置这个环境变量,以实现卡的指定运行。
②推理代码的运行
此处对pipeline进行了模块化设计,将其分为三个部分,即预处理、模型推理和后处理,如下图所示:
要查看给定模型背后的实现,首先可以在modelscope的模型仓库中获取配置文件Configuration.json。
在该配置文件中,可以找到有关模型用途、model类型及自定义的model参数的描述,还包括所使用的预处理器种类及其初始化参数,这是与推理最相关的是三个核心部分。通过pipeline的type可以找到其对应在Library中使用的pipeline,据此可定位到pipeline的实现文件中,并确定其在模块中具体的实现。
该过程中,通过将预处理抽象到Pre-Procession中,将整个模型放入了模型类中。
在整个pipeline调用过程中,它执行了推理的过程。首先,在初始化函数中进行模型的初始化。
在pipeline_call函数内部,按顺序调用Pre-Procession预处理过程、model_forward过程、pipeline后处理的实现。通过这种模块化的串联方式,可以完成前处理、模型推理和后处理的整个流程,从而完成特定任务和特定模型的推理流程。
当然,如果要自定义一些流程,则可以在特定模块中进行相应的修改和开发。
以上提到的pipeline的输入通常是单个样本,但其也可以支持dataset输入来完成对整个dataset数据集的推理。我们主要使用 MsDataset接口来加载数据集对象,然后传递给pipeline即可完成。
关于数据集的使用,如下图:
如果要使用最简单的方式加载整个数据集,实际上只需使用MsDataset.load即可,若要加载特定版本的数据集,可以指定相应的vision。
除此之外,还可以指定split参数以及subset参数。对于subset参数,其意义在于:一个大型数据集通常会分成多个子数据集,只需加载其中一个子数据集则可通过subset指定。对于split参数,每个子数据集均可能会有不同的分片,如训练集和验证集,可以通过split参数指定加载不同的分片。
有时用户可能希望在本地使用本地文件进行加载,而不希望访问网络,或者想先将数据准备好,然后运行。这种情况下,可以将数据准备成CSV文件格式,然后通过load接口加载CSV文件。对于图像数据,也可以使用imagefolder将整个目录下的所有图像加载进来。值得一提的是,这种方式更适用于图像分类任务,即其中一个大目录下包含多个子目录,每个子目录下均为一个类别的图片,系统会自动将这些图像加载并将label ID作为映射。
对于非结构化数据,例如语音或文本,可能具有更复杂的目录结构。在这种情况下,MsDataset提供使用自定义格式数据集的支持,使用者只需将训练数据和测试数据的目录打包为对应的zip文件并上传,并在数据集的配置文件中指定相应的数据分片和文件映射(如train对应哪个zip)。在调用MsDataset.load时,系统会自动将这些zip文件下载到本地并解压缩,通过返回的信息,可以访问解压缩后的目录以及json构建是配置的参数,从而实现自定义数据集的本地加载,与本地开发体验保持一致。
(2)训练
在数据集的基础上,可以利用modelscope已有的模型进行特定的调试。这里使用了gpt text-generation_chinese.large模型,如果使用该模型直接调用pipeline,输入“落木旧山寺”只是对其进行简单介绍,通过加载modelscope中诗歌生成的数据集,通过train模块对该模型进行finetune,可以看到在finetune之后,输入不同的诗歌第一句的内容,都可以生成整首诗歌。
在finetune过程中会涉及到调整参数的步骤,调整参数有多种方式。
首先,每个模型下都有一个配置文件,对于可以用于训练的模型,其配置信息会更加完整。代码中涉及推理的部分不再详述,重点关注与训练和评估相关的部分。
训练部分包括模型保存的目录、训练轮数、每个GPU上的batch size、每个GPU上的数据预取数以及其他功能性参数,如模型保存间隔和训练指标等。此外,还有与训练数据和评估相关的参数。用户可以直接下载这些配置文件,并根据需要修改参数。然后,在train构建时,通过传递修改后的配置文件即可使用使用者自己的参数进行训练。
①训练代码的运行
在代码的背后进行了train loop的抽象。在训练开始之前,插入一系列的装点(上图中红色的部分),它们后续可以通过hooks执行一些额外的操作。训练开始后,进入开始训练的loop,每个训练轮次都包含了一个循环,每次迭代都会执行一些loop,包括model forward、通过hook进行对应梯度计算和参数更新。通过train loop,整个训练流程被抽象成了两个层次。
通过hooks机制,可以在不同的地方插入和扩展特定功能。例如,可以在每个训练前执行特定操作,对应的装点可以在before.train_epoch函数中实现这些操作。
对于已有的hook也提供了一些常用的功能,如Lr的调整、OptimizerHook、模型保存、定期保存和保存最佳模型,EvaluationHook可以在每个epoch或一定间隔之后对模型进行评估,TextLogger与IterTimeHook用于记录训练指标和训练速度信息,并且可以将相关信息通过文字的形式记录到日志文件中,TensorBoard中可以对记录到日志文件中的信息进行可视化。关于配置文件可以通过参数的修改进行模型微调,也可以通过cfg_modify_fn{cfg}的方式在程序中动态修改属性以完成对应参数的修改。
(3)评估
评估过程与训练类似,我们都可以使用相同的方式构建train,并通过调用trainer.evaluate的方式完成相应的评估。在评估中,与训练不同的是,我们要配置不同的metric以适应不同的任务。
四、贡献流程
Modelscope平台提供了许多能力,如下图:
包括庞大的用户活跃度、示例演示的支持,从事运营的使用者也可以通过官方媒体和社交渠道进行联合宣传和培训,帮助提升自身模型的影响力;同时,通过平台提供免费的 GPU 资源和在线体验功能可以帮助使用者收集用户反馈,提升模型的使用量;此外,还有一些商务合作机会,可以帮助平台使用者的模型在不同的实际业务领域落地。因此,平台鼓励使用者在平台内贡献自己的模型。
1、贡献模型的流程
如下图所示:
(1)创建模型库
在平台网站点击“创建”按钮,通过创建模型仓库来创建自己的模型。在创建模型仓库时,需要填写模型的名称以及是否开源,若选择不公开,可以将其设置为私有,仅自己或内部组织使用。
(2)编写READMe.md文件
可以在该md文件中编写模型介绍和使用说明,此外,还需要进行一些配置,包括指定模型可用于的任务、配置在线体验的演示,通过简单的配置可以创建演示,从而让更多用户直观地体验模型的效果。还有一些其他参数,可以配置自身模型的简短说明,帮助用户更精确地搜索到贡献者的模型。
(3)贡献代码
如果贡献者的模型是平台现有模型的一部分,只需上传模型文件即可完成该模型的贡献。
(4)上传模型并设置版本
如果贡献者的模型不在已有模型之列,则需要将模型代码上传至Modelscope Library,然后上传模型文件及相应配置,实现模型的贡献。关于模型的版本,其目的是保障不同版本的模型的可用性。在每次SDK发布都只会使用其发布之前最新的模型版本,而无法使用SDK发布之后的模型版本,只有在下次发布或用户指定使用新的模型版本之后才可以使用。平台通过模型版本的控制,避免因贡献者随意更改线上模型导致其他用户模型不可以的情况发生。
以上提到了两种不同情形下的不同贡献方式,具体说明如下:
该方式对应已有的模型实现以及使用者根据已有模型通过finetune产出的模型文件,只需通过修改配置文件,并将对应的模型相关的介绍和配置上传即可完成模型贡献。若需要贡献代码,则首先需要了解Modelscope的运行机制;然后拉分支并提交一个PR表明贡献者在平台内贡献或开发的模型的目的,并提供技术支持和方案讨论;接下来,贡献者要在本地开发自己的模块代码,准备好模型文件、测试用例,并在本地正常测试运行;测试通过后,将相关的模型文件上传到模型仓库;关于训练和开发导出流程是可选的,如果要提供finetune功能,则需要提供finetune接入相关的支持;最后,完善docstr并推送PR。至此,开发功能已基本完成,后续可以与开发团队合作,根据反馈进行修改即可完成代码的接入。
2、不同功能接入的具体操作
(1)Pipeline接入
包括几个关键模块,包括预处理模块、模型部分以及pipeline部分。
关于pipeline部分,可以先查看源代码中已有模块的功能,如果可以复用现有模块,那就可以直接复用,只需编写预处理和模型部分即可。如果无法满足需求,也可以新增pipeline。然后,准备配置文件,并在配置文件中编写各个模块的名称和传递的参数,即可完成推理功能的开发。
(2)Finetune接入
相对于推理,finetune会更复杂一些。同样,首先需要提供一个配置文件,但此配置文件需要包含train和evaluation的相关参数。在代码开发方面,需要在预处理和模型部分进行额外的工作,预处理方面主要涉及训练时的功能,而模型部分则更多涉及前向计算等。
此外,还需要定期评估模型性能,并实现模型相应的metrics。Metrics与Pipeline类似,先查看是否已经有满足需求的功能,如果已经存在相关功能,可以直接使用;如果没有,则可以在代码中进行自定义开发。
对于整个训练流程,平台提供了EpochBaseTrainer封装整个训练过程的接口,贡献者可以继承该trainer,并修改其中的特定函数以实现自己的逻辑。如果已有的default trainer功能可以满足需求,则可以通过简单的配置完成。
如果涉及到特定的实现逻辑,现有实现无法满足,则可以在继承的基础上再进行自定义实现。上图中给出了一个finetune接入代码的示例,涵盖了预处理部分、模型整体实现、评估代码实现、配置文件等。
最后,如果要向平台贡献代码,建议贡献者在各个用户接口层面提供详细的描述,包括模块功能、输入输出和示例使用代码,而平台遵循google-doc格式规范,因此在提交代码之前要使用代码格式化工具,以保持代码格式一致。此外,所有import模块都有遵循Lazyimport语法来支持模型之间的依赖的解耦。
有关模型和预处理参数的详细说明如下:
模型的forward函数输入参数args为Batched Tensor,输出为dict of Batched Tensor;关于模型复用,标准backbone复用,模型各自的子模块的实现不要求复用;关于preprocessormodelscope/preprocesso
rs/存放领域公共的原子preprocessor,未来可以扩充原子preprocess
or能力。
如果一个preprocessor只适用于一个模型,该preprocessor放到 modelscope/models/xxx/preprocessor.py中。