大数据和AI两者最核心的部分都是数据。大数据的主要工作是对数据进行各种转换和存储。而AI的主要工作是学习数据并且得出模型。 AI天然需要大数据的基础,因为AI需要各种形态的数据,而我们得到这些形态的数据,必然离不开大数据。就此而言,他们两个合在一起,才是一个完整的工作流。
所以大数据平台要和AI进行整合,有两个核心点:
- 数据的交换
- 统一的语言
无论进程内还是进程间,数据交换最高效的方式是通过 Apache Arrow。那么数据交换的问题算是有了一个标准。
统一的语言呢?大部分大数据基础软件都是Java/Scala,而AI则是Python based on C /C的。大部分公司最后会选择Python作为一个大一统语言。尽管Python比较简单,但是学习成本依然不低,而且对于数据的操作,他其实不是最优的。对数据操作最优的是SQL。对算法而言,则是Python。尽管如此,我们可以将SQL内嵌到Python里。
然而在实际的工业实践中,获得一个算法模型,大概率70-80%的人工时间都是在数据处理上。然后大概率70-80%的机器时间都是在模型训练上。这意味着,本来用户应该70%-80%的时间只要使用SQL就能搞定自己的问题,剩下的时间开发模型以及调整模型参数。
就此而言,最好的模式是SQL包含Python,因为无论从人员的时间上,还是代码量上,数据处理都是最大的,这意味着我们应该尽可能让数据处理用起来更简单。
所以我们有了MLSQL 这么一个新语言:
A Programming Language Designed For Big Data and AI
MLSQL 是一个SQL形态的语言,保留了SQL的大部分特性,同时对除了查询以外的语法做了必要的简化,同时内嵌python支持。MLSQL可以单机或者分布式运行。配合MLSQL Console 系统,我们基本可以覆盖AI同学工作的大部分时间。
假设用户希望使用python对一张表里的每条数据进行处理,那么会写如下的代码:
代码语言:javascript复制import ray
from pyjava.api.mlsql import RayContext
import numpy as np;
ray_context = RayContext.connect(globals(),"192.168.217.155:49860")
is_in_mlsql = ray_context.is_in_mlsql
ray_context.mock_data = [{"content":"jack"},{"content":"jack3"}]
def echo(row):
row["content"]="jackm"
return row
buffer = ray_context.foreach(echo)
if not is_in_mlsql:
for item in buffer:
print(item)
这里我们连接了Ray 去执行实际的业务逻辑。
echo 只是简单的对所有的数据的content字段进行填充。mock_data提供了mock数据。执行结果如下:
测试代码没问题了,现在我们希望真实加载HIve里的数据做处理。
代码语言:javascript复制!pyInclude python-example.test2.py named wow1;
load hive.`mock.mock_data` as orginal_text_corpus;
select id,content,label from orginal_text_corpus as orginal_text_corpus1;
-- ray 配置
!python env "PYTHON_ENV=export PYTHONIOENCODING=utf8 && source activate dev";
!python conf "schema=st(field(id,long),field(content,string),field(label,double))";
!python conf "pythonMode=ray";
!python conf "runIn=executor";
!python conf "dataMode=data";
-- ray处理数据代码
!ray on orginal_text_corpus1 py.wow1 named mlsql_temp_table2;
--结果
select * from mlsql_temp_table2 as output;
得到结果如下:
上面的脚本可以直接将python include到MLSQL脚本里,并且通过!ray命令在指定的数据集上运行对应的python脚本,并且可以是分布式的,也可以在单个节点上运行python,但是你可以再提交到ray集群上运行。
Console支持单个python脚本的调试和开发。正如上面的示例,你可以给脚本设置mock数据,如果他运行在MLSQL中,则会使用实际SQL提供的数据,如果他是自己单独运行,则会使用mock数据。一旦我们调试完成后,就可以引入到真实的数据环境里,而从上面的例子来看,这个成本非常的低。
通常而言,MLSQL 一般内嵌一个Python代码。如果python代码足以构成一个复杂的项目,用户也可以直接在MLSQL Console完成编写:
在Console中调试完成之后,然后发布到Pip 私仓。之后在MLSQL 脚本的的Python脚本里引用这个库。
看似简单的交互,里面涉及到了很多的细节问题:
- 在分布式系统中,如何让worker节点的日志信息输出到driver并且实时回显到控制台。
- 底层Python和SQL引擎如何交互等
- 如何解决python调试的问题。
- 用户应当可以指定python运行在worker节点还是driver节点。
- 如何管理python环境问题等等。
这些问题部分在下面的文章里得到解答:
祝威廉:Spark整合Ray思路漫谈(2)
总结一下,MLSQL Console提供了对Python单脚本,Python项目的支持,同时MLSQL 支持通过!pyInclude 或者直接在MLSQL脚本中写python从而可以对任何表的数据进行处理或者以其作为训练数据进行模型训练。对于内嵌的python脚本,MLSQL 使用
https://github.com/allwefantasy/pyjava
pyjava项目中的python API对用户提供支持。
对于预测服务,我们提供了一个解决方案:
祝威廉:在Java应用中写Python提供预测服务实战
如果你不追求响应时间,MLSQL也可以直接将模型注册为SQL 中的UDF函数。后续我们会进一步介绍。