“前端智能化”存在的价值和意义,被不断拷问。
一部分人对“前端智能化”持拥抱态度,认为这是前端领域的一种革命性技术。
另一部分人则认为“前端智能化”可行性范围有限,大多是一些Demo性产品,对能否真正应用到业务生产持怀疑态度。
其最终目的还是要将产品和技术能力融入业务体系,释放技术红利,驱动业务增长。
本文将结合阿里云的业务场景,分析在中后台领域中,“前端智能化”如何降低开发成本,提升研发效能,从而创造更深远的业务价值。
01 让「前端智能化」真的运转起来
什么是前端智能化?
和垂直的“端智能”方向不同,前端智能化关注的领域更偏向于生产效率的提升。如果更准确的描述,“前端智能化”应该是“前端开发智能化”。
通过AI 与前端业务深入结合,基于AI能力提供的丰富预测、推荐信息,结合研发逻辑积累,打造更加人性化、智能化的前端代码。
当然,并不是机器能生成100%的代码去代替前端开发,出发点是让机器能自动化、智能化,为前端人员减少开发工作量,代替完成可抽象、可复用、UI编排、国际化等低成本、较为繁琐的工作,最后产出一份可以二次开发、可维护、高质量的源码Procode。
每一套技术方案背后,必然有完整的理论体系和运作机制。
Dumbo平台能力
阿里云在怎样的业务和技术背景下做边缘云 “前端智能化”?
从业务增长上来讲:由于云计算业务整合及调整,增加了大量的控制台、中后台管控等B端业务,在人力基本不变的情况下,团队如何快速支撑起这部分业务?
从业务特性上来讲:主要以ToB端、中后台为主, 重管控crud、UI编排较统一、研发逻辑相似等,云控制台产品的国际化等特性。
前端业务侧基于以上特性沉淀了前端技术框架,研发模式是基于组件化、场景化、模块化的方案。
通过这类研发方案,不仅能实现技术成本降低,组件化开发、最佳实践地积累等,还能通过统一的视觉标准规范,减少视觉沟通成本和沟通成本, 从而大大提高开发效率。
虽然,基于这种方式的研发方案能带来极大的提效,但在开发过程中也存在一些组件编排复杂、代码重复率高、大量无关核心业务逻辑开发的工作。
因此,我们思考如何基于现有研发方案,带来进一步提效?
首先,明确前端的研发成本。主要包括:UI 组件编排、业务逻辑(交互与数据)、文案国际化、工程链路、沟通成本(设计、后端、产品)等。
其次,站在巨人的肩膀上看问题。团队调研了一些现有的提效方案,主要包括:基于可视化搭建平台、基于可视化物料源码开发站、基于AI能力的效能提升平台等。
在此基础上,结合自身业务场景、现有研发方案、开发模式、学习成本等综合因素考虑,决定打造一个“智能化”的面向阿里云控制台、中后台源码开发平台。
02 Dumbo的智能化:“智能识别”
Dumbo「智能化」是一个利用图像识别算法,一键生成前端代码的智能解决方案。目前已经落地于多个阿里云控制台及中后台项目。
Dumbo的基本链路通过对标准化样本进行生成,基于样本来进行模型训练。用户只要输入图片,通过训练的模型就能识别及最终产出前端所需代码。
智能化的核心之一是“智能识别”,主要包含:目标检测算法、样本生成、模型训练及识别。
目标检测算法
即输入一张图片,输出图片中感兴趣物体的坐标信息。经典的目标检测算法有两种,one-stage与two-stage。one-stage算法即只对图片处理一次,它的速度通常优于two-stage算法,代表算法有yolo系列。
而two-stage算法会对图片处理两次,先找到可能存在目标的区域,再对该区域做一次预测。这类算法速度较慢但准确率更好,代表算法有Faster R-CNN。
主要使用的目标检测算法是SSD300。SSD300是2016年提出的一种目标检测算法,它是一种one-stage算法,同时吸收了yolo和Faster R-CNN的优点,兼具速度和准确率。虽然在最新的目标检测算法排名中,SSD已不再具有优势。
SSD算法在准确率和速度上都较YOLO有较大提升,SSD算法在经过一次VGG-16转换后,得到一个38 38 512的特征图,之后的每一次卷积运算的同时都会输出一次预测结果。
这么做可以兼顾大目标和小目标的检测,感受野小的feature map检测小目标,感受野大的feature map检测大目标。SSD同时引入了Faster RCNN中的Anchor,提出了相似的Prior box概念,在对样本做标记时,也是基于Prior box的偏移来做的。
在每一个不同尺寸的feature map中,都预先设置好了多个Prior box,这些先验框可通过人为规定或统计学方法计算得到。
在对目标做标记时,SSD要求找到与待检测目标真实框交并比最大的先验框,由它负责预测该目标,标记的数据为两个框之间差值。预测的时候也是同理,因此,在SSD中,会多出一步转换的过程,用来还原真实框的位置信息。
Dumbo把该套目标检测算法通过PAI深度学习训练来训练模型,并部署在PAI上的在线模型服务(ESA),通过函数计算来实现服务调用,实现了一套模型训练服务。
样本生成
目标检测的模型训练,样本集尤为重要。对于现有场景而言,样本集就是各种各样的控制台页面截图。
想要识别的组件,需要在图片中标注出来,标注格式有多种,常见的格式有xml、json、csv等。根据SSD算法需要的标准细节,采用了xml格式对组件进行标注。以Button为例,标注信息包括组件的左上角顶点坐标、组件的长度和宽度。
不同的目标检测算法需要的数据可能不同,有的需要组件中心点的坐标数据,有的则需要组件占图片的比例数据。这些数据都可以通过计算相互转换,本质并没有发生变化。
将图片中所有组件都标注完成后,得到了一对样本图片与标注文件的集合,大量这样的集合便构成了样本集。
仅使用真实控制台页面截图是远远不够的,并且手动标注费时又容易出错。对此分别使用了fusion构建了动态样本数据集。fusion风格样本主要以阿里云控制台标准为主,用于训练阿里云控制台场景模型。
下图是使用fusion构建的一个随机控制台页面,目前,各类型的组件分布算法采用的是围绕视觉规范为均值的正态分布,这么做可以在少量样本条件下训练出表现更好的模型。后续将使用更加均匀的分布算法改造样本集,因为在前端领域的目标检测中,并不适合完全均匀分布的布局算法。
举个例子,PageHeader组件,位置信息是其自身的一项特征,如果在页面底部出现了一个和PageHeader一模一样的组件,也不应该将其标注为PageHeader。
组件内部属性的随机化,也要遵循一些约束,比如Select组件,边框、右侧的arrow-down Icon是其主要特征,在使用代码生成时,最好不要忽略它们。圆角、边框颜色等则不是主要特征,可以尽量随机化,让训练出的模型更具鲁棒性。
一个值得思考的特征是placeholder,“请选择xxx”,这里的“请选择”实际上也是一项重要的特征,思考一下,如果一个组件,除了右侧没有arrow-down图标,其他特征和Select组件一致,那么,应该将其判断为Select还是Input?
总结起来,训练模型的过程,其实是让模型挖掘到组件的完整特征信息,并根据各项特征的重要程度做权重优化的过程。有了样本图片,还需要标注信息。在Dumbo中,使用js方法获取了每个组件的位置和长宽数据,在通过puppeteer截图的过程中,自动导出标注文件。
基于以上说明,产出样本生成服务如下:
模型训练及识别
Dumbo提供了整套的模型训练服务,可以方便的将已经生成好的样本文件进行模型训练,这块基于PAI的能力,把整个模型训练链路集成到项目中,下图为模型训练的整体链路。
通过OSS作为中间集,进行数据和模型部署,实现了整体的模型训练链路。
基于以上模型训练链路,在Dumbo的fusion场景中训练多种模型,包括整页模型、表单模型、图表模型、详情页模型、Icon模型等多个模型用于识别服务。
识别过程同时采用了递归识别和组合识别。这是为了提高小组件的识别准确率。同时将识别任务拆分到多个模型中,可降低各个模型的训练难度。
03 “智能出码”:一键生成前端代码
通过上述的智能识别,可以了解到Dumbo的全部训练和识别过程,识别产物非前端代码,需要根据边缘云前端框架及阿里云规范,对识别数据进行处理,最终生成前端同学可复用的布局和逻辑代码代码,从而提高研发效率。
下图是具体出码实现步骤:
图像分析
“目标检测 + 分类”看似能基本cover控制台视觉稿的识别,然而理想很美好, 现实不够理想。
在大量验证过程中,发现仅通过模型预测的结果精确度偏低,一些情况下预测结果位置信息存在一些偏差。同时为了模型收敛,也存在主体分类粒度不够,导致无法更好的完成后续的还原工作。
为了提高识别的准确率及视觉还原度,所以采用深度学习结合传统图像分析的方式,优化AI识别内容,丰富组件识别特征度,提供给上游链路更丰富有效的数据信息。
➢ 预处理:通过边界判断页面padding情况,是否需要切割和补充padding来规范预测图片内容、优化识别效果。
➢ 数据处理:在数据处理阶段做一个初步的去重操作,该操作主要判断:当两个组件没有父子关系且重叠阈值(交并比)大于某个值(这里根据经验取的 0.8), 删除置信度较低的组件。本步骤主要为了解决AI对同一个物体识别为多个不同标签的情况。
➢ 位置优化:主要通过OpenCV 进行图像分析轮廓识别,在比对轮廓的重叠阀指,收敛轮廓大小使轮廓区域和实际图像更加贴合。处理结果前后对比如下:
➢ 属性检测:主要通过OpenCV的颜色判断,来区分组件的属性类型,类似分析Message组件背景色,判断Type值为Success、Error、 Notice、Warning等。通过简单的CV分析,可以不断丰富组件识别特征度,不断提升还原度。
➢ 关系矫正:对于有父子嵌套关系的组件,识别优化无法处理嵌套关系异常的情况,需要加入逻辑判断。例如radioGroup/radio则为父子关系组件,当有父子关系嵌套不完整时,需要进一步处理判断radio 的siblings 节点,并纠正父组件的位置,将其siblings 包裹完整。
布局分析
视觉稿还原的主要目标是:布局还原准确、减少冗余重复代码,最大程度的贴合人工还原代码,所以需要对图像分析处理后的数据进行数据分析,增加部分节点数据,方便后续DSL转换和出码。
➢ 关系矩阵:分析其位置信息(x, y, width, height),将其生成一个N维关系矩阵。判断关系矩阵时,对行列位置进行了的阈值设置,规定在水平垂直等方向xOverlap、yOverlap 重叠阈值小于某个值可忽略重叠部分。具体示意图如下:
➢ 行列生成:主要目的是将关系矩阵结构转换成节点树,同时使用栅格化的方式处理行列结构布局。用Row节点表示一行, Col节点表示一列,递归调用transfer2Grid 方法,生成节点树。注意:此过程需要考虑到基于组件化布局方式特点。从而定义componentsInline 数组,包括'Button', 'Radio', 'Checkbox' 等。
➢ 组件设置:在此步骤中,以插件化的方式判断不同的类库包括Fusion样式属性,转换样式,设置组件属性及通用样式类。维护一个config 属性名称映射,对节点进行样式相关属性检测及设置,同时根据位置信息判断一些浮动、边距样式等,设置通用className。这种方式有利于布局还原代码可读性,可维护性。
DSL转换
智能识别的数据是一份平面化数据,需要还原为立体、有结构的DSL数据。转换DSL主要通过识别文字的预处理工作,依赖分析、和各个组件的Adapter组成,最终产出一份结构化的schema数据。
预处理:Dumbo的文字识别之后产生的是一个Text节点数据,包含中英文属性,但是文案中可能会存在一些影响最终展示的特殊符号,比如●、丫等,这些符号的误识别会导致最终展示上出现不理想的情况,也有可能会出现长文字被截断成为多个文字节点的情况,需要把这些文字节点进行合并处理等。然后对生成的组件进行国际化处理。
Adapter(以Form组件为例子)
首先,进行节点分割,分割为文字节点和组件节点;
其次,根据Form特性,一般以组件作为FormItem的children,Text作为label属性,优先进行组件节点判断,通过遍历组件节点,并通过相邻节点函数判断,获取到该节点的相邻的Text, 并根据交互稿规范的相邻阀值,进行label判断,由于不确定FormItem的布局情况,可能存在上下/左右2种布局形式,所以会同时判断TopText和LeftText,并分别放入对应的数组中,之后进行比较。
根据Form表单的特性,一般Form的排列形式比较一致,不是上下/左右,很少存在既有上下,又有左右的形式,所以这块直接判断TopText和LeftText的个数来进行布局确认。
在了解布局之后,可以再次遍历没有被命中的文字节点和组件节点,因为已经确定布局类型,所以可以直接根据阀值,来判断是否存在只有文字的FormItem组件,进一步完善组件内容及属性,并且可以把一部分识别不是很准确的RadioGroup等进行合并处理。
最后,进行组件的FormItem组装,输出给一个完成的结构化数据。
依赖分析:识别数据通过Adapter转换之后,获取到的Schema并不包含依赖关系,和集团的规范存在出入,依赖提取的后处理部分,就是通过对Schema的遍历,提取使用到的组件信息,通过对应的模版依赖库,加载对应的依赖关系。
在可视化微调上,基于集团的Low-Code引擎,建立了一套Fusion物料组件,支持识别数据的可视化微调,进一步提升出码准确率。
代码生成
对于代码生成,则主要围绕着集团最新的搭建协议,通过场景的一系列编排,最终完成一个组件的生成。其结构大体可描述为:
在出码处主要处理的内容,是将机器递归遍历给出的字符串,重进编排整合,使其具有维护的能力。主要解决的问题为:代码拆分/整合、状态管理、国际化、样式。
首先,对于代码的拆分和整合。目前主要根据 DSL 中的节点类型进行拆分。对于 BLOCK 、 Component 节点,直接划分为通用的场景,以供其他页面或者模块使用。
其次,是状态管理。目前开发中,dva 已经成为团队统一的状态管理工具,在遍历过程中会对页面的 state 、 effects 进行提取,通过映射,完成组装。
然后,是国际化相关的内容。在集团的搭建协议中,可以看到最新版本的国际化内容已经被替换成如下形式。
整合后的 DSL 中 i18n 的内容会被单独提取出来,对于调用处是一个表达式。而目前团队的国际化方案更多的是自有风格,所以在处理国际化节点时需要做响应的替换。
最后,是样式相关。通过之前的布局分析,通过一系列的计算,最终每个组件节点都被赋予了栅格化的 ClassName 。所以此处只要把布局所需要的基础css 文件作为依赖引入到页面文件中即可。
目前来说,“前端智能化” Dumbo平台已接入众多公有云控制台应用 ,其中新控制台接入页面覆盖率大于50%,研发效率感官提效约30%,在整体识别率、准确率上满足了业务的基本要求,而在场景覆盖、智能化程度、智能交互等方面,也在探索更多的提升空间。
后续,计划进一步收敛场景规范、扩大使用场景覆盖面的同时,不断丰富数据模型能力,从灵活性、识别特征度、模型准确率等多维度考虑,提高“智能化”能力。同时,继续让“智能化”和“低代码”进行结合,让使用者可以通过简单的接口配置,实现页面在线运行。
未来的智能化不止于代码,还在向端云协同方向做更多渗透。