(这是第一篇开篇,成长之路序列会包含多篇,笔者作为这个平台的架构兼技术经理,充分讲述其中的迭代心酸之路以及中间遇到的问题和解决方案)
声明:文章不涉及公司内部技术资料的外泄,涉及的图片都是重画的简易架构图,主要通过架构的演进,讲述分享技术的迭代之路和过程,进行技术交流和探讨。
人工智能-智能创意平台架构成长之路(三)--机器学习算法工程服务化
人工智能-智能创意平台架构成长之路(四)-丰富多彩的banner图生成解密第一部分(对标阿里鹿班的设计)
笔者所在的公司从很早就开始了探索人工智能,而2018年公司专门成立了独立的人工智能研发中心,标志着开始了大规模的人工智能产品研发,也体现出对人工智能发展的重视,从2018年下半年开始在规划一个类似京东玲珑和阿里鹿班的一个Banner图的合成平台项目,初期产品设计的是一个sass化的产品,可以对内也可以对外服务,初期规划时,只有如下几个模块。
最终会通过算法自动生成类似这样的banner图
1、 服务:主要是对外提供统一的restful api服务,服务包括离线服务和实时服务。
2、 工作台:指的是一个用户操作合成banner界面,供用户做操作,在鹿班和玲珑中都有。
智能合成,指的是用户可以选择风格标签后,然后平台依靠人工智能自动生成banner图。
手动合成:指的是人可以手工干预合成,比如可以自己选择素材和上传素材(比如banner图的背景,装饰图等)
3、 后台管理指的一个供管理用的界面。
总体的应用架构设计如下:
由于一期在规划时,先实现工作台和后台管理两部分,服务一开始不实现,所以初期的系统技术架构设计如下:
设计的思路如下:
1、 考虑到系统的高可拓展性以及未来平台可能会增加很多其它的服务,并且可能会朝着智能创意来发展,所以在web 框架选型时,我这边选是springcloud+springboot。虽然一开始模块很少,使用springcloud会有点大材小用,但是这个是一个长期不断迭代的项目,所以系统的扩展性在前期一定要先准备好。
2、 由于服务一开始我们并不实现,所以我们其实只有一个模块,就是iwogh-web这个模块。
3、 我们所有的请求还是使用springcloud中的Zuul模块来做理由控制。Eureka来负责服务注册中心。
4、 数据库使用的Mysql数据库,因为一开始数据并不大,关心型的mysql可以满足要求,并不需要一开始就去考虑大数据的方案。
5、 由于算法基本都是python来实现的,所以我们会把python实现的算法包装一个http的服务,包装的时候我们开始选择的是python中的flask框架。
6、 算法的集群实现,我们使用的是nginx来做反向代理转发,一个nginx集群,可以控制很多个不同的算法集群(比如每个不同类型的算法构建一个集群),因为我们可以利用nginx中的location
location的语法:
location [=|~|~*|^~] patt { } //中括号中为修饰符,可以不写任何参数,此时称为一般匹配,也可以写参数
因此,大类型可以分为三种:
location = patt {} [精准匹配]
location patt{} [普通匹配]
location ~ patt{} [正则匹配]
server {
listen 80;
server_name localhost;
location =/text.html { #精准匹配,浏览器输入IP地址/text.html,定位到服务器/var/www/html/text.html文件
root /var/www/html;
index text.html;
}
location / { #普通匹配,浏览器输入IP地址,定位到服务器/usr/local/nginx/html/default.html文件
root html;
index default.html;
}
location ~ image { #正则匹配,浏览器输入IP/image..地址会被命中,定位到/var/www/image/index.html
root /var/www/image;
index index.html;
}
}
当然还有一种思路,就是通过sidecar组件,把算法服务也注册到springcloud中作为一个服务,然后调用算法服务采用spingcloud内部服务的方式来实现。
不过最终经过一些考虑,否决了这种想法,
1) 、算法更偏底层,不太适合在应用层的服务中管理,在架构设计时,本来也会给算法设计一层算法工程化服务层,结构大致会这样,算法服务只专注于算法的处理,不会涉及任何的处理逻辑。
2) 、算法一般是python来实现的,所以工程化的封装一般也是会使用python来包装服务,纳入到以java为主的springcloud服务中来管理,在持续集成发布时,不是非常方便管理。
1、 redis主要用来做分布式的会话session,而且我们还使用session做了另一个设计,由于banner合成时一次是批量合成5张图出来,但是算法底层由于是深度机器学习框架,所以算法处理的速度并不会很快,如果用户在工作台中等待5张图全部合成完,用户的体验会很差,因为等待的时间会很长,所以我们采用了轮询 按照一张一张来加载,并不是等5张banner图全部出来后再一次加载出来,而是出来一张就加载一张。
如下图,在第一步调用算法服务处理完后,生成了banner图后会先存入到图片存储中,然后写入时,会往redis和mysql中同时写入,redis中会有一定的实效时间,因为用户有不可能会在页面一直等,总归是会超时的,实效时间一般设定在了5-10分钟左右。此时页面会轮询