所有代码开源在:
TsingJyujing/tf.js-on-flink
2019年伊始的时候,给自己定下了一个小目标,不用JNI把TensorFlow撸上Flink做实时的预测。把去年放出去的狠话收个尾。
之所以定这个目标,主要是因为在机器学习+流计算的场景有两大诉求:
目前大多的方案还是Flask或者Django写一个Http接口,利用 TensorFlow 原生的 Python API + 某个 Http/RPC Server 作为机器学习中心,然后在流计算中无状态的调用这些接口。
这样做的好处是可以无缝衔接研究者训练好的模型,毕竟大部分的机器学习框架都是Python友好的。但是缺点也很明显: - 网络IO消耗较大 - 为了适配接口编写代码复杂 - 流计算和机器学习服务集群压力不匹配,单方面处理速度过快导致机器学习服务器侧压力太大但是不能背压 - ……
为了解决这样的问题,我们需要把 Tensorflow 直接嵌入到 JVM 中去,这样的话有好几个方案:
本文最终用的是方案4。
先说说几个方案的问题: 1. Java API 官方不保证不稳定是最大的坑,其次部署麻烦,有些glibc不能升级的场景很难部署,更新也很麻烦。 2. 没有找到较好的 Python 解释器的Java库,Jython不能用的,详细原因过长不解释。 3. 依然是glibc等基础库的坑,而且还有在运行中模型不易更新等问题。 4. 也是有坑的,我这一套工具用起来并不是很方便,模型编译出来较大,如果设置不恰当,因为V8引擎的特性,不易使用多核(其实是可以滴)
最后我们的V8依旧是用JNI上的,但是这个库对其他依赖的要求要小很多,基本可以做到是个64位的Linux就可以上(J2V8也支持Windows/Mac/Linux x86/Android等等,但是需要修改POM重新编译)。
我这里利用Wine数据集构建了一个简单的模型,详情参见:
TsingJyujing/tf.js-on-flink
这只是一个用于演示的测试模型。
首先找个网站(自己本机搭建也可以),把你的模型放上去,确保通过http可以访问,像这样:
Index of /tof/models/wine/v1.0.0/随后修改src/generate_app.js,把里面的modelPath改成你的模型。
最后编译就好啦:npm run build,如果你要保留一些调试信息可以用npm run build-dev。
编译完成以后,你就可以在target文件夹下看到你的 ml.bundle.js 文件,这个就是连库带模型打包到一起的一个文件。
IModel
我这里仅仅实现了输入输出都是稠密矩阵的函数,参见:com.github.tsingjyujing.tof.engine.DenseMatrixModel,因为支持JS的语法,所以你可以把部分的预处理和后处理都放到JS中去,再编写相应的IModel即可。
最简单的方式是使用一个RichMapFunction完成预测任务,我给出的例子里,每来10条数据就输出一下正确率,实际的业务场景还有更多玩法,例如把预测错的样本单独输出,这里就不展开了。
详细代码参看这个类:com.github.tsingjyujing.tof.example.Entry
如果你需要在运行中无缝更新你的模型怎么做?可以参考我写的这篇文章。
一般来说,大致就是:
看上去很简单,但是其实做出这个东西不是一个容易的事情,尤其是前端技术是我的短板的情况下,借助Tensorflow.js就变得尤其痛苦。
放弃了两三次,因为和太多的人吹过水,说能给Flink上TF,所以忍着做完了……
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69918097/viewspace-3158565/ ,如需转载,请注明出处,否则将追究法律责任。