分布式训练部署系统及其方法与流程

    专利2022-07-08  82


    本公开涉及一种数据处理技术。更具体地说,本公开涉及一种针对分布式训练进行自动部署系统及其方法。



    背景技术:

    随着深度学习的快步发展,为了提升神经网络的精度和泛化能力,数据集和参数量都在呈指数级向上攀升。分布式并行训练成为一种解决超大规模网络性能瓶颈的发展趋势。训练深度学习模型需要大量的计算,在一台具有一个gpu的单台机器上完成一次基于imagenet等基准数据集的训练可能要耗费多达一周的时间,而使用2048个gpu的集群却能将训练时间缩短到4分钟。对于分布式训练的算法和技术,众多现代分布式训练框架已经给出了优秀的方案,但关于如何便捷地为分布式训练提供基础的运行环境,却不像前者那么有讨论热度。为分布式训练任务提供运行环境是一项非常复杂的工作,从依赖安装到脚本分发,步骤多而且重复性高,还可能因为疏忽而引发故障。

    现有算力平台在解决此问题时,往往需要很多步骤,这些步骤对用户过于复杂。以amazonaws为例,如果需要在两个gpu节点上运行pytorch的分布式训练任务,则必须先创建节点,使用aws提供的指定镜像(内含cuda,cudnn和nccl),挑选适合多路gpu分布式训练的计算单元,手动调整实例数,配置存储空间,设置安全组并加入节点,使节点之间可以通信。在编写训练脚本时,还必须找到并记住节点的ip地址。如果有个性化的依赖,还需要依次登录节点,才能进行安装配置。可以发现,整个部署过程常常需要用户参与,对平台的使用者也有很高的要求。使用者不但要关心分布式训练脚本,还需要了解aws的基本架构,在讨论如何让代码运行起来之前,已经在平台的操作上耗费了多余的精力。

    因此,本领域技术人员期望能够在搭建分布式训练运行环境时简化搭建的复杂度,并能够减少对不同分布式训练平台特性的依赖,并实现异构设备集群管理,实现对成规模计算节点的资源分布、任务调度、状态监控等多机协同工作降低用户的使用门槛,让用户将更多的精力放在算法上。



    技术实现要素:

    为此,为解决上述技术问题之一,本公开提供了一种分布式训练部署系统,其基于容器编排引擎执行分布式训练部署,所述容器编排引擎对应用进行自动部署和管理,所述系统包括:从容器创建组件,基于用户输入的分布式任务创建申请包含的资源清单创建从容器集,并确认所创建的从容器处于可备用状态;主容器创建组件,基于用户输入的资源清单创建主容器,并确认所创建的主容器处于可备用状态;容器ip获取组件,获取所创建的主容器和从容器的ip,并基于所获取的ip创建js对象简谱文件,并将该js对象简谱文件写入所有主容器和从容器的指定位置;以及免密认证组件,通过对属于同一分布式任务的主容器和从容器配置安全密钥和认证信息,建立主容器和从容器之间的网络通讯的ssh免密认证。

    根据本公开的分布式训练部署系统,其还包括:合法确定组件,确定用户输入的分布式任务创建申请包含的资源清单的参数是否符合容器编排引擎所确定的规则,并将符合所述规则的分布式任务创建申请确定为合法申请。

    根据本公开的分布式训练部署系统,其还包括:重复拒绝组件,确定用户输入的分布式任务创建申请是否与合容器编排引擎中的已有分布式任务创建申请重复,并拒绝重复的申请。

    根据本公开的分布式训练部署系统,其还包括:闭锁解除组件,当所述属于同一分布式任务的主容器和从容器都处于可备用状态并且彼此建立网络通讯的ssh免密认证时,解除主容器和从容器之间的闭锁,以便开始执行训练脚本。

    根据本公开的分布式训练部署系统,其还包括:状态更新组件,当分布式任务的行训练脚本执行后,更新基于分布式任务组织并提交给容器编排引擎的的自定义资源cr以及分布式训练的状态。

    根据本公开的另一个方面,提供了一种分布式训练部署方法,其基于容器编排引擎执行分布式训练部署,所述容器编排引擎对应用进行自动部署和管理,所述方法包括:通过从容器创建组件基于用户输入的分布式任务创建申请包含的资源清单创建从容器集,并确认所创建的从容器处于可备用状态;通过主容器创建组件基于用户输入的资源清单创建主容器,并确认所创建的主容器处于可备用状态;通过容器ip获取组件,获取所创建的主容器和从容器的ip,并基于所获取的ip创建js对象简谱文件,并将该js对象简谱文件写入所有主容器和从容器的指定位置;以及通过免密认证组件,通过对属于同一分布式任务的主容器和从容器配置安全密钥和认证信息,建立主容器和从容器之间的网络通讯的ssh免密认证。

    根据本公开的分布式训练部署方法,其还包括:通过合法确定组件,确定用户输入的分布式任务创建申请包含的资源清单的参数是否符合容器编排引擎所确定的规则,并将符合所述规则的分布式任务创建申请确定为合法申请。

    根据本公开的分布式训练部署方法,其还包括:通过重复拒绝组件确定用户输入的分布式任务创建申请是否与合容器编排引擎中的已有分布式任务创建申请重复,并拒绝重复的申请。

    根据本公开的分布式训练部署方法,其还包括:通过闭锁解除组件在所述属于同一分布式任务的主容器和从容器都处于可备用状态并且彼此建立网络通讯的ssh免密认证时,解除主容器和从容器之间的闭锁,以便开始执行训练脚本。

    根据本公开的分布式训练部署方法,其还包括:状态更新组件,当分布式任务的行训练脚本执行后,更新基于分布式任务组织并提交给容器编排引擎的的自定义资源cr以及分布式训练的状态。

    本发明的其它优点、目标和特征将部分通过下面的说明体现,部分还将通过对本发明的研究和实践而为本领域的技术人员所理解。

    附图说明

    图1所示的是根据本公开的分布式训练部署系统100原理示意图。

    图2所示的是根据本公开的分布式训练部署方法的流程图。

    具体实施方式

    下面结合实施例和附图对本发明做进一步的详细说明,以令本领域技术人员参照说明书文字能够据以实施。

    这里将详细地对示例性实施例进行说明,其示例表示在附图中。下面的描述涉及附图时,除非另有表示,不同附图中的相同数字表示相同或相似的要素。以下示例性实施例中所描述的实施方式并不代表与本公开相一致的所有实施方式。相反,它们仅是与如所附权利要求书中所详述的、本公开的一些方面相一致的装置和方法的例子。

    在本公开使用的术语是仅仅出于描述特定实施例的目的,而非旨在限制本开。在本公开和所附权利要求书中所使用的单数形式的“一种”、“所述”和“该”也旨在包括多数形式,除非上下文清楚地表示其他含义。还应当理解,本文中使用的术语“和/或”是指并包含一个或多个相关联的列出项目的任何或所有可能组合。

    应当理解,尽管在本公开可能采用术语第一、第二、第三等来描述各种信息,但这些信息不应限于这些术语。这些术语仅用来将同一类型的信息彼此区分开。例如,在不脱离本公开范围的情况下,在下文中,两个可能从容器之一可以被称为第一从容器也可以被称为第二从容器,类似地,两个可能从容器的另一个可以被称为第二从容器也可以被称为第一从容器。取决于语境,如在此所使用的词语“如果”可以被解释成为“在……时”或“当……时”或“响应于确定”。

    为了使本领域技术人员更好地理解本公开,下面结合附图和具体实施方式对本公开作进一步详细说明。

    深度学习本质上属于特征学习的一种,从这个角度考虑,可以将深度学习直接应用于从原始数据提取特征。而自动编码器是实现特征提取这一功能的重要模型之一。

    图1所示的是根据本公开的分布式训练部署系统200原理示意图。如图1所示,分布式训练部署系统200基于容器编排引擎100执行分布式训练部署,所述容器编排引擎100,例如kubernetes,其可以对应用进行自动部署和管理。以kubernetes为例,是google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。在kubernetes中,可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。但是现有的kubernetes依然对成规模计算节点的资源分布、任务调度、状态监控需要人工进行。为了实现对成规模计算节点的资源分布、任务调度、状态监控等多机协同工作降低用户的使用门槛,让使用者将更多的精力放在算法上,本申请在kubernetes为例的容器编排引擎100提供了一种分布式训练部署系统200,以便简化搭建分布式训练运行环境的复杂度,实现异构设备集群管理,支持模型并行、流水并行、数据并行以及自动混合并行功能,从而大幅提升计算性能和分布式易用性。

    如图1所示,所述分布式训练部署系统200包括:从容器创建组件210、主容器创建组件220、容器ip获取组件230以及免密认证组件240。从容器创建组件210基于用户输入的分布式任务创建申请包含的资源清单创建从容器集,并确认所创建的从容器处于可备用状态。主容器创建组件220基于用户输入的资源清单创建主容器,并确认所创建的主容器处于可备用状态。容器ip获取组件230获取所创建的主容器和从容器的ip,并基于所获取的ip创建js对象简谱文件,并将该js对象简谱文件写入所有主容器和从容器的指定位置。免密认证组件240通过对属于同一分布式任务的主容器和从容器配置安全密钥和认证信息,建立主容器和从容器之间的网络通讯的ssh免密认证。从而实现分布式训练的部署。

    上述分布式训练部署系统200承载在一种被称为onebrain的平台上。承载有根据被公开的分布式训练部署系统200的onebrain是面向ai工程师的大规模分布式算力平台,基于高性能gpu计算节点提供一站式托管ai训练任务服务。用户在提交ai训练任务后,无需担心计算节点调度、训练环境准备、数据上传下载以及容灾等问题。如上所述,分布式训练部署系统200统一采用主从模式部署分布式任务,所有任务的计算节点均由gpu物理云主机组成,主从实例通过kubernetes申请资源配额(主容器和从容器),被调度到具体的物理主机上,主从的比例为1:n(n>=1)。分布式训练所使用的输入数据可以来自不同的数据源,目前onebrain支持通过nfs或minio作为数据存储。以nfs为例,onebrain平台在训练执行之前,会将对应的nfs数据映射到训练执行的主从容器的指定目录下,指定一个nfs目录或minio网盘作为output输出源,onebrain平台在训练执行之后,会将对应的存储设备映射到每一个主从容器的指定目录下,在训练脚本中可以使用此目录保存训练模型,或者模型的检查点(checkpoint)。如果用户有特殊的环境需求,可以基于平台的标准应用容器引擎文件(dockerfile)制作并上传自己的镜像。onebrain平台接收到一个分布式训练任务部署的申请时,会首先将分布式训练任务组织成自定义资源(customresource)提交给容器编排引擎100,例如kubernetes,容器编排引擎100会将此信息传递给对应的分布式训练部署系统200(distribute-train-operator)。onebrain平台通过分布式训练部署系统200(distribute-train-operator)实现分布式训练的自动调度,完成分布式训练任务的部署。

    概括而言,在分布式训练部署系统200中,从容器创建组件210基于用户输入的分布式任务创建申请包含的资源清单创建从容器集(slave),并等待所创建的从容器状态全部处于可备用状态(ready)。如果在创建过程中,所创建的从容器的状态不处于ready状态,则需要创建另一个从容器替代。与此同时,主容器创建组件220基于用户输入的资源清单创建主容器(master),并等待所创建的主容器的状态全部处于可备用状态(ready)。容器ip获取组件230获取所创建的主容器和从容器的ip(pod(plainolddatastructure)ip),并将所获取的podip组成一个json文件(js对象简谱文件,javascriptobjectnotationfile),并将该js对象简谱文件写入所有主容器和从容器的指定位置。最后免密认证组件240通过对属于同一分布式任务的主容器和从容器配置安全密钥和认证信息,建立主容器和从容器之间的网络通讯的ssh免密认证,从而打通各容器间的网络通路。

    可选择地,在创建容器之前,分布式训练部署系统200中合法确定组件250确定用户输入的分布式任务创建申请包含的资源清单的参数是否符合容器编排引擎100所确定的规则,并将符合所述规则的分布式任务创建申请确定为合法申请。如果不符合所述规则,驳回将分布式任务创建申请,并向用户反馈信息,提示用户参数不合法,以便用户进行相应的修改。此外,可选择地,在创建容器之前,重复拒绝组件260可以通过容器编排引擎100针对分布式任务创建申请进行重复性检查,确定用户输入的分布式任务创建申请是否与合容器编排引擎中的已有分布式任务创建申请重复,并拒绝重复的申请,从而避免因生成相同的任务和产生冲突。

    所部署分布式训练任务在所有状态或条件都满足之后,主容器和对应的从容器之间的闭锁状态将会被解除,从而开始执行训练脚本。具体而言,闭锁解除组件270在所述属于同一分布式任务的主容器和从容器都处于可备用状态并且彼此建立网络通讯的ssh免密认证时,解除主容器和从容器之间的闭锁状态,以便开始执行训练脚本。举例而言,所有用于执行训练任务的主容器和从容器的各自的状态机的条件都得到满足时,将自动开始执行训练脚本。可选择地,状态更新组件280当分布式任务的行训练脚本执行后,更新基于分布式任务组织并提交给容器编排引擎的的自定义资源cr(customresource)以分布式训练的状态。

    图2所示的是根据本公开的分布式训练部署方法的流程图。尽管图2显示了分布式训练部署方法的一些步骤,但是,并不意味着根据本公开的方法必需包含所示的流程图中的所有步骤。如图2所示,在用户输入分布式训练任务之后,在步骤s01处,合法确定组件250首先确定用户输入的分布式任务创建申请包含的资源清单的参数是否符合容器编排引擎100所确定的规则,并将符合所述规则的分布式任务创建申请确定为合法申请。如果不符合所述规则,驳回将分布式任务创建申请,并向用户反馈信息,提示用户参数不合法,以便用户进行相应的修改。如果确定合法确定组件250确定分布式任务创建申请包含的资源清单的参数符合合容器编排引擎100所确定的规则,则步骤s02处,在创建容器之前,进行资源重复性检查,即重复拒绝组件260可以通过容器编排引擎100针对分布式任务创建申请进行重复性检查,确定用户输入的分布式任务创建申请是否与合容器编排引擎中的已有分布式任务创建申请重复,并拒绝重复的申请,从而避免因生成相同的任务和产生冲突。

    在获得合法的新的分布式任务创建申请后,在步骤s03处,创建从容器集(slave),即按照指定的尺寸(size)创建副本数为size-1的有状态应用(statefulset),并在步骤s04处,等待或确定所创建的从容器(slave)的pod(plainolddatastructure)全部变为ready状态。也就是从容器创建组件210基于用户输入的分布式任务创建申请包含的资源清单创建从容器集(slave),并等待所创建的从容器状态全部处于可备用状态(ready)。如果在创建过程中,所创建的从容器的状态不处于ready状态,则需要创建另一个从容器替代。接着,在步骤s05处,创建主容器(master),即按照指定的参数创建job(任务)。并且在创建job之后,在步骤s06处,等待或确认master的pod变为ready状态。也就是主容器创建组件220基于用户输入的资源清单创建主容器(master),并等待所创建的主容器的状态全部处于可备用状态(ready)。在主容器以及从容器被创建以及都ready之后,在步骤s07处,收集master和slave的podip,并以json文件形式传入pod。即,容器ip获取组件230获取所创建的主容器和从容器的ip(pod(plainolddatastructure)ip),并将所获取的podip组成一个json文件(js对象简谱文件,javascriptobjectnotationfile),并将该js对象简谱文件写入所有主容器和从容器的指定位置,以便随后用于打通主容器与从容器之间的网络通路。随后在步骤s08处,为所有的pod生成公私钥、认证文件,并进行ssh免密登录,从而打通主容器与从容器之间的网络通路。通过上述步骤,所述分布式训练部署已经完成。尽管描述了步骤s01和s02,但是这两个步骤并不进行分布式训练自动部署所必需的。当所输入的申请为合法的新申请时,起初的两个步骤并不是必需的。

    在部署完成后,在步骤s09处,解除主容器与从容器闭锁。主容器与从容器都没有ready之前以及彼此之间的网络通路打通之前,所有任务执行脚本都不能执行,因此,主容器与从容器彼此处于闭锁状态。在训练任务执行条件都满足之后,主容器与从容器之间的闭锁被解除,并开始训练,执行训练任务脚本。最后在步骤s10处进行状态更新,即基于分布式任务组织并提交给容器编排引擎的的自定义资源cr(customresource)以分布式训练的状态。

    如上所述,根据本公开的快速部署分布式训练任务的解决方案,可兼容多种流行深度学习框架,充分地利用了kubernetes隔离资源、便于调度、易于管理的特性,实现了分布式训练任务部署的改造和自动并行训练流程改造简化搭建环境的繁杂流程,使算法工程师可以专注于训练本身。目前包含根据本公开的分布式训练部署系统的onebrain平台已支持tensorflow、pytorch和oneflow框架的分布式训练。用户只需要在平台上提交训练任务,上传训练脚本和数据集,即可按要求分配所需的资源,并启动任务。平台为每一个人工智能的训练任务都单独分配了一个虚拟容器去进行训练,各个训练任务之间相互隔离,互不干扰,提高了训练任务的可靠性。

    当分布式训练开始执行时,通过分布式训练部署系统(operator)可以监控日志和资源使用情况。当训练任务完成或因异常失败时,所占用的gpu资源会自动释放。如需停止任务,只需要删除customresource,相关的资源也会自动释放。

    用户通过在onebrain平台上点击和添加表单,即可轻松部署分布式训练任务。以通过tensorflow进行图像识别为例。mnist数据集来自美国国家标准与技术研究所,是机器学习中最常见的图像识别数据集,该数据集由250个不同人手写的数字构成,其中50%是高中学生,50%来自人口普查局工作人员.测试集(testset)也是同样比例的手写数字数据。为了在平台上进行训练,首先要上传数据集,我们将mnist.npz通过平台的文件服务上传到指定目录。然后下载训练脚本源代码onebrain_tf_mnist.py,对它做如下修改:

    修改读入数据源的地址为固定映射的挂载地址,如/dataset/mnist.npz

    修改输出模型地址为固定映射的挂载地址,如/models

    修改gpu_num,改为从环境变量gpu_num来读取。

    将修改后的脚本通过平台的文件服务上传到指定目录。

    在平台中创建分布式训练任务,调整节点数量和资源配额,选择所使用的数据集为上传的数据集,选择使用的训练脚本为上传的脚本,输入启动训练脚本的命令,并提交。等待分布式训练任务就绪,并查看日志。在训练过程中,随时可以停止当前的训练任务。当训练完成后,可以通过平台下载训练导出的模型。kubeflow的几种分布式训练crd(自定义资源定义)或可实现相同的需求。

    以上结合具体实施例描述了本公开的基本原理,但是,需要指出的是,对本领域的普通技术人员而言,能够理解本公开的方法和装置的全部或者任何步骤或者部件,可以在任何计算装置(包括处理器、存储介质等)或者计算装置的网络中,以硬件、固件、软件或者它们的组合加以实现,这是本领域普通技术人员在阅读了本公开的说明的情况下运用他们的基本编程技能就能实现的。

    因此,本公开的目的还可以通过在任何计算装置上运行一个程序或者一组程序来实现。所述计算装置可以是公知的通用装置。因此,本公开的目的也可以仅仅通过提供包含实现所述方法或者装置的程序代码的程序产品来实现。也就是说,这样的程序产品也构成本公开,并且存储有这样的程序产品的存储介质也构成本公开。显然,所述存储介质可以是任何公知的存储介质或者将来所开发出来的任何存储介质。

    还需要指出的是,在本公开的装置和方法中,显然,各部件或各步骤是可以分解和/或重新组合的。这些分解和/或重新组合应视为本公开的等效方案。并且,执行上述系列处理的步骤可以自然地按照说明的顺序按时间顺序执行,但是并不需要一定按照时间顺序执行。某些步骤可以并行或彼此独立地执行。

    上述具体实施方式,并不构成对本公开保护范围的限制。本领域技术人员应该明白的是,取决于设计要求和其他因素,可以发生各种各样的修改、组合、子组合和替代。任何在本公开的精神和原则之内所作的修改、等同替换和改进等,均应包含在本公开保护范围之内。


    技术特征:

    1.一种分布式训练部署系统,其基于容器编排引擎执行分布式训练部署,所述容器编排引擎对应用进行自动部署和管理,所述系统包括:

    从容器创建组件,基于用户输入的分布式任务创建申请包含的资源清单创建从容器集,并确认所创建的从容器处于可备用状态;

    主容器创建组件,基于用户输入的资源清单创建主容器,并确认所创建的主容器处于可备用状态;

    容器ip获取组件,获取所创建的主容器和从容器的ip,并基于所获取的ip创建js对象简谱文件,并将该js对象简谱文件写入所有主容器和从容器的指定位置;以及

    免密认证组件,通过对属于同一分布式任务的主容器和从容器配置安全密钥和认证信息,建立主容器和从容器之间的网络通讯的ssh免密认证。

    2.如权利要求1所述的分布式训练部署系统,其还包括:

    合法确定组件,确定用户输入的分布式任务创建申请包含的资源清单的参数是否符合容器编排引擎所确定的规则,并将符合所述规则的分布式任务创建申请确定为合法申请。

    3.如权利要求1所述的分布式训练部署系统,其还包括:

    重复拒绝组件,确定用户输入的分布式任务创建申请是否与合容器编排引擎中的已有分布式任务创建申请重复,并拒绝重复的申请。

    4.如权利要求1-3之一所述的分布式训练部署系统,其还包括:

    闭锁解除组件,当所述属于同一分布式任务的主容器和从容器都处于可备用状态并且彼此建立网络通讯的ssh免密认证时,解除主容器和从容器之间的闭锁,以便开始执行训练脚本。

    5.如权利要求4所述的分布式训练部署系统,其还包括:

    状态更新组件,当分布式任务的行训练脚本执行后,更新基于分布式任务组织并提交给容器编排引擎的的自定义资源cr以及分布式训练的状态。

    6.一种分布式训练部署方法,其基于容器编排引擎执行分布式训练部署,所述容器编排引擎对应用进行自动部署和管理,所述方法包括:

    通过从容器创建组件基于用户输入的分布式任务创建申请包含的资源清单创建从容器集,并确认所创建的从容器处于可备用状态;

    通过主容器创建组件基于用户输入的资源清单创建主容器,并确认所创建的主容器处于可备用状态;

    通过容器ip获取组件,获取所创建的主容器和从容器的ip,并基于所获取的ip创建js对象简谱文件,并将该js对象简谱文件写入所有主容器和从容器的指定位置;以及

    通过免密认证组件,通过对属于同一分布式任务的主容器和从容器配置安全密钥和认证信息,建立主容器和从容器之间的网络通讯的ssh免密认证。

    7.如权利要求6所述的分布式训练部署方法,其还包括:

    通过合法确定组件,确定用户输入的分布式任务创建申请包含的资源清单的参数是否符合容器编排引擎所确定的规则,并将符合所述规则的分布式任务创建申请确定为合法申请。

    8.如权利要求7所述的分布式训练部署方法,其还包括:

    通过重复拒绝组件确定用户输入的分布式任务创建申请是否与合容器编排引擎中的已有分布式任务创建申请重复,并拒绝重复的申请。

    9.如权利要求6-8之一所述的分布式训练部署方法,其还包括:

    通过闭锁解除组件在所述属于同一分布式任务的主容器和从容器都处于可备用状态并且彼此建立网络通讯的ssh免密认证时,解除主容器和从容器之间的闭锁,以便开始执行训练脚本。

    10.如权利要求9所述的分布式训练部署方法,其还包括:

    状态更新组件,当分布式任务的行训练脚本执行后,更新基于分布式任务组织并提交给容器编排引擎的的自定义资源cr以及分布式训练的状态。

    技术总结
    本发明公开了一种分布式训练部署系统。所述系统包括:从容器创建组件,基于用户输入的分布式任务创建申请包含的资源清单创建从容器集,并确认所创建的从容器处于可备用状态;主容器创建组件,基于用户输入的资源清单创建主容器,并确认所创建的主容器处于可备用状态;容器IP获取组件,获取所创建的主容器和从容器的IP,并基于所获取的IP创建JS对象简谱文件,并将该JS对象简谱文件写入所有主容器和从容器的指定位置;以及免密认证组件,通过对属于同一分布式任务的主容器和从容器配置安全密钥和认证信息,建立主容器和从容器之间的网络通讯的SSH免密认证。

    技术研发人员:俞再亮;单海军;李倞;鲍虎军;王志伟;靳懿;李科
    受保护的技术使用者:之江实验室;北京一流科技有限公司
    技术研发日:2020.11.30
    技术公布日:2021.03.12

    转载请注明原文地址:https://wp.8miu.com/read-23064.html

    最新回复(0)