数据和 AI 正在成为很多公司的重要资产。其中,数据代表了公司在特定领域的积累,也是公司的护城河,AI 能力输出则代表了公司对数据资产的利用深度。二者密不可分,光有数据没有 AI,就好比你只有原材料,却无法加工产生价值;光有 AI 没有数据,就好比你光有屠龙术,但是却没有龙给你屠。只有将二者作为一个整体,才能给一个公司带来最大的价值。
大数据和 AI 融合存在的问题
数据和 AI 本身存在上下游关系,以及由于历史发展而存在先后顺序,这导致它们最终成为了两个相对独立的体系,带来了两个很大的问题:
大数据和 AI 的技术栈不同
大数据在语言层面以 Java/Scala/SQL 为主导,其中 SQL 是交互语言,Java/Scala 则是大数据体系的构建语言。AI 则是以 Python/C++ 为主导,其中 Python 为交互语言,C++ 为算法体系的构建语言。在面向的人群上,Java/Scala 面向数据研发,SQL 面向分析师、运营、产品。但是随着 SQL 进一步发展,现在越来越多数据研发也开始直接使用 SQL 去解决自己的问题。Python 则更多面向算法。当然,分析师通常也会一些 Python,而会 Python 的自然也会一些 SQL。
从交互的复杂度而言:
C++ > Java/Scala > Python > SQL
自然而然的,越是简单的编程语言,就越容易变得流行,毕竟流行的本质就是使用人群扩大。只有门槛低的语言,才能提高使用人群的比例。所以 SQL 和 Python 慢慢分别发展成了大数据和算法的标准交互语言。实际上这些语言存在已久,只是因为各自的特点以及简单性使得它们在新的时代得到了新的应用。
平台是隔离的
在很多公司,数据平台和 AI 平台通常是两个平台,而且有时候连维护也是由两个不同的团队负责。这种平台之间的隔离造成了很大的互通问题,其中最大的问题就是数据互通。
完成一次对数据价值的开发,首先要对数据进行处理,处理后进一步交给 AI 去学习。而技术栈以及平台的不同,导致 AI 获取数据的成本被提高了。用户可能需要先去数据平台写个数据处理脚本(譬如基于 Spark 等)提取数据,然后转存到 AI 平台或者一个能被 AI 和数据平台共享的存储上,然后再去 AI 平台写 Python 或者调库完成对数据的训练。当然,随着分工越来越细,其实用户自己无法完成所有这些事情,他往往需要把这些步骤拆解然后下发到各个小的支持团队里去,然后各个小团队进行排期,最终完成一整个链条的工作。无论对大公司还是小公司,这都会极大地消耗成本。
构建数据和 AI 平台依然困难
即使到今天,对很多公司来说,构建数据和 AI 平台依然很困难:需要了解无数的组件,需要有大量经验且分别懂 SQL、Java、Scala、Python 的开发、分析师、算法,或者需要了解各种云产品并做组合以达到自己想要的效果。所有这些困难堆叠起来就会导致极其高昂的开发成本。同时,由于 IT 特有的属性,即使做了这些投入,可能依然满地是坑。面对底层无数存储,如何做一个有效的权限控制就已经让很多开发挠头了。
而且,数据和 AI 应该是普惠的。在笔者看来,数据和 AI 不应该仅仅局限在数据科学家手里(包括分析师和算法),任何一个产品、运营,甚至任何一个有权访问数据的人,都应该可以对这些数据进行价值开发。这种开发小到只是查看,或者导出成一个 Excel,或者对外提供一个查询接口,大到提供一个精准的推荐系统,都应该能比较容易地完成。
我们需要一个面向大数据和 AI 的新语言
前面说了这么多,无非是想告诉大家:
1、大数据和 AI 需要融合成一个平台;
2、构建这个平台的成本应该要降下来;
3、数据和 AI 的使用门槛要降下来,人人都应该能够利用数据给公司创造价值。
那怎么才能实现上面这三个诉求呢?单单从平台层面很难解决这个问题,这个时候我们就需要从语言层面着手了。我们需要一个能够更好地融合大数据和 AI 的编程语言,它必须具备以下特点:
1、语言要足够简单,产品和运营也能很容易学会;
2、能够同时完美满足大数据和算法的需求,打通两者互通的数据管道;
3、语言的执行引擎要是分布式的,并具备强大的硬件资源管理能力,能够满足海量数据计算需求;
4、必须保护现有的投资,包括能够复用现有的大数据生态和 AI 生态。
Python 对大多数人还是有一定难度,而且无法很好地整合大数据生态。SQL 简单,但是无法满足算法的复杂需求且难以利用 AI 领域大量生态。
我们希望用一个语言完成大数据批流处理以及 AI 的训练和预测。我们希望在语言层面内建数据安全机制,解决无数底层存储的访问控制问题,让开发不再挠头。我们还希望这个语言内置的功能易于扩展,且能够充分利用大数据和 AI 的构建语言 Java/Scala/C++ 做扩展,因此这个语言的执行引擎应该具有强大的插件化能力。
目前正在朝着这个目标努力的编程语言有 SQLFlow 和 MLSQL。
SQLFlow
SQLFlow 的初衷是为了解决成千上万分析师既要操作数据又要使用 AI,往往需要在两个系统甚至更多系统之间切换导致工作效率低的窘境。
SQLFlow 对 SQL 做了部分语法扩展,用户可以在 SQL 中加入算法的描述。
一个典型的语法如下:
-- SQL 部分
SELECT * FROM 20newsgroups.train
-- 算法描述部分
TO TRAIN DNNClassifer
WITH hidden_units = [10, 10], n_classes = 3, EPOCHS = 10
COLUMN sepal_length, sepal_width, petal_length, petal_width
LABEL class
INTO sqlflow_models.my_dnn_model;
其基本逻辑是提供了一个基于 Go 开发的 Service,用于接收发往后端存储的 SQL,然后对 SQL 进行解析并提取出数据描述部分和算法描述部分。
SQLFlow 会将数据描述部分(SQL)发送给后端存储引擎,并把后端返回的数据喂给算法部分做训练;同时根据算法描述自动生成 Python 代码,然后提交给特定的算法引擎来完成训练,最后将结果保存回存储引擎。目前后端支持 MySQL、Hive、MaxCompute 等,算法引擎支持 TensorFlow、PyTorch。
不过笔者个人认为,SQLFlow 需要研发去适配众多存储后端,同时还要针对各个算法引擎做支持,并且语法扩展部分目前还不够灵活,只能使用 SQLFlow 已经实现好的一些算法,缩小了 SQLFlow 的覆盖人群,譬如专业的算法工程师应该不大会去使用它。
MLSQL
MLSQL 一开始的出发点也是为了解决算法的普惠性,希望不仅仅是 AI 人才能用上算法,工程师、分析师和产品运营都应该能用起来。
和 SQLFlow 只是简单扩展 SQL 不同的是,MLSQL 是基于 SQL 语法设计的全新的编程语言。
对于工程师或分析师来说,可以完全使用类 SQL 语法来实现训练和预测,这一点上 MLSQL 和 SQLFlow 是相同的:
select * from 20newsgroups as 20newsgroups;
train 20newsgroups
as RandomForest.`/ai_model/rf`
where keepVersion="true"
and evaluateTable="tfTable_test"
and `fitParam.0.featuresCol`="value"
and `fitParam.0.labelCol`="label_num"
and `fitParam.0.maxDepth`=“2";
系统会自动生成 Spark/Python 代码完成训练。
而对于专业的算法工程师,MLSQL 支持使用内嵌 Python 进行训练(这一点目前在 SQLFlow 官方文档中没有体现):
!python env "PYTHON_ENV=source activate dev";
!python conf "schema=st(field(count_vect,binary),field(tfidf_transformer,binary),field(nb,binary))";
load delta.`ai_data.20newsgroups` as 20newsgroups;
-- 提取数据中的分类,因为隐含在 url 里。
select *, split(file,"/")[4] as label from 20newsgroups as 20newsgroups;
-- 我们可视化下数据分布
select label,value from 20newsgroups as 20newsgroups;
!ray on 20newsgroups '''
import pandas as pd
import plotly.express as px
from plotly.io import to_html
from vega_datasets import data
from pyjava.api.mlsql import PythonContext,RayContext
ray_context = RayContext.connect(globals(),None)
data = list(ray_context.collect())
df = pd.DataFrame(data, columns=data[0].keys())
from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer()
X_train_counts = count_vect.fit_transform(df.value)
from sklearn.feature_extraction.text import TfidfTransformer
tfidf_transformer = TfidfTransformer()
X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts)
from sklearn.naive_bayes import MultinomialNB
print("这是进行训练的过程")
clf = MultinomialNB().fit(X_train_tfidf, df.label)
docs_new = ['God is love', 'OpenGL on the GPU is fast']
X_new_counts = count_vect.transform(docs_new)
X_new_tfidf = tfidf_transformer.transform(X_new_counts)
print("这是进行预测的过程。")
predicted = clf.predict(X_new_tfidf)
for doc, category in zip(docs_new, predicted):
print('%r => %s' % (doc, category))
# 最好是能讲数据序列化后上传到模型仓库
# 不过我们这里就先保存成表
import pickle
context.build_result([{"count_vect":pickle.dumps(count_vect),"tfidf_transformer":pickle.dumps(tfidf_transformer),"nb":pickle.dumps(clf)}])
''' named model_data;
-- 把三个模型保存到数据湖
save overwrite model_data as delta.`ai_model.20newsgroups` where overwriteSchema="true";
上述代码从数据湖中提取数据,使用 SQL 进行简单处理,然后使用 Python 做了一个文本分类训练,最后把模型保存回数据湖中。
从语言层面来讲,MLSQL 有点三不像:
1、有命令行的东西
2、有类 SQL 的东西
3、有 Python
我们相信部分任务仅仅用类似命令行就能解决,大部分仅仅用 SQL 就能解决,只有非常少的一部分才需要动手写 Python。因此 MLSQL 将 SQL 作为一等公民,命令行是 SQL 的一个语法糖,Python 作为内嵌语言,也是为了尽可能让语言的使用更简单。
MLSQL 底层脚本执行引擎采用的是 Spark,这意味着 MLSQL 可以充分利用现有的大数据生态,目前已经支持市面上大部分存储,包括数仓、关系型数据库、数据湖、分布式文件系统等,并且可以利用 Spark 自身强大的算力完成混算。而基于 MLSQL 另外一个子项目 PyJava 开发的 Python 执行引擎,则使得用户可以充分利用 Python 的生态体系。另外,MLSQL 也对分布式机器学习框架 Ray 做了深度的集成,并且支持插拔使用。
MLSQL 底层架构如下图所示,使用者可以用 MLSQL 同时完成批处理、AdHoc 计算、流式计算、机器学习等诸多任务。
不要被架构图的复杂度吓到,MLSQL 执行引擎的部署和一个普通的 Spark 应用没有任何区别。
除此之外,MLSQL 还有诸多特性,譬如:
1、在语言层面内置了到列级别的权限访问控制;
2、插件化内核,核心功能均采用内置插件完成,现在也有不少官方插件;
3、支持在脚本中使用 Java/Scala 语言书写 UDF/UDAF;
4、支持 include 语法,强化了 SQL 工程和复用能力。
以上两个项目的开源地址如下:
结语
当下编程语言越来越趋向领域化,最终都是要让合适的语言为合适的领域助力。我们相信,大数据和 AI 的蓬勃发展,必然需要一个更加为之量身定制的语言。以 SQLFlow、MLSQL 为代表的这类语言的诞生正是顺应了这个趋势。
本文转自 公众号:AI前线 ,作者祝威廉,点击阅读原文