查看原文
其他

代码解放,一个智能化的「云控制台」如何运转?

Edge Cloud 云布道师 2023-06-18

凌云时刻

本文授权转载自「视频云技术」,作者虚俞,编辑 IMMENSE。

 当谈论“业务智能化”时,我们还能谈论什么?
技术正不断改变企业与组织的业务模式,创造新的增长机遇。随着 AI、5G、云计算、物联网(IoT)、自动化能力的规模及广泛应用,让智能化、数字化、数据化、自动化等概念与企业发展紧密交织,建立全新的成本和效率基准。“智能化”究竟能为业务带来什么?正如“前端智能化”存在的价值和意义,也在被不断拷问。一部分人对“前端智能化”持拥抱态度,认为这是前端领域的一种革命性技术。另一部分人则认为“前端智能化”可行性范围有限,大多是一些 Demo 性产品,对能否真正应用到业务生产持怀疑态度。事实胜于雄辩。其目的,最终还是要将产品和技术能力融入业务体系,释放技术红利,驱动业务增长。在中后台领域,结合阿里云业务场景,“前端智能化”能够降低开发成本,提升研发效能,从而创造更深远的业务价值。让「前端智能化」真正运转起来什么是前端智能化?和垂直的“端智能”方向不同,前端智能化关注的领域更偏向于生产效率的提升。如果更准确的描述,“前端智能化”应该是“前端开发智能化”。通过 AI 与前端业务深入结合,基于 AI 能力提供的丰富预测、推荐信息,结合研发逻辑积累,打造更加人性化、智能化的前端代码。当然,并不是机器能生成 100% 的代码去代替前端开发,出发点是让机器能自动化、智能化,为前端人员减少开发工作量,代替完成可抽象、可复用、UI 编排、国际化等低成本、较为繁琐的工作,最后产出一份可以二次开发、可维护、高质量的源码 Procode。每一套技术方案背后,必然有完整的理论体系和运作机制。

图:Dumbo 平台能力

阿里云在怎样的业务和技术背景下做边缘云 “前端智能化”?
  • 从业务增长上来讲:由于云计算业务整合及调整,增加了大量的控制台、中后台管控等 B 端业务,在人力基本不变的情况下,团队如何快速支撑起这部分业务?
  • 从业务特性上来讲:主要以 ToB 端、中后台为主, 重管控 crud、UI 编排较统一、研发逻辑相似等,云控制台产品的国际化等特性。
前端业务侧基于以上特性沉淀了前端技术框架,研发模式是基于组件化、场景化、模块化的方案。通过这类研发方案,不仅能实现技术成本降低,组件化开发、最佳实践地积累等,还能通过统一的视觉标准规范,减少视觉沟通成本和沟通成本, 从而大大提高开发效率。虽然,基于这种方式的研发方案能带来极大的提效,但在开发过程中也存在一些组件编排复杂、代码重复率高、大量无关核心业务逻辑开发的工作。因此,我们思考如何基于现有研发方案,带来进一步提效?
  • 首先,明确前端的研发成本。主要包括:UI 组件编排、业务逻辑(交互与数据)、文案国际化、工程链路、沟通成本(设计、后端、产品)等。
  • 其次,站在巨人的肩膀上看问题。团队调研了一些现有的提效方案,主要包括:基于可视化搭建平台、基于可视化物料源码开发站、基于AI 能力的效能提升平台等。
在此基础上,结合自身业务场景、现有研发方案、开发模式、学习成本等综合因素考虑,决定打造一个“智能化”的面向阿里云控制台、中后台源码开发平台

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 模型等多个模型用于识别服务。识别过程同时采用了递归识别和组合识别。这是为了提高小组件的识别准确率。同时将识别任务拆分到多个模型中,可降低各个模型的训练难度。

智能出码:一键生成前端代码

通过上述的智能识别,可以了解到 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%,在整体识别率、准确率上满足了业务的基本要求,而在场景覆盖、智能化程度、智能交互等方面,也在探索更多的提升空间。后续,计划进一步收敛场景规范、扩大使用场景覆盖面的同时,不断丰富数据模型能力,从灵活性、识别特征度、模型准确率等多维度考虑,提高“智能化”能力。同时,继续让“智能化”和“低代码”进行结合,让使用者可以通过简单的接口配置,实现页面在线运行。未来的智能化不止于代码,还要向端云协同方向做更多渗透。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存