热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

实时数据流上的机器学习——TensorflowonFlink

所有代码开源在:TsingJyujingtf.js-on-flink​github.com前言2019年伊始的时候,给自己定下了一个小目标,不用JNI把TensorFlow撸上Fl

所有代码开源在:

TsingJyujing/tf.js-on-flinkgithub.com《实时数据流上的机器学习——Tensorflow on Flink》

前言

2019年伊始的时候,给自己定下了一个小目标,不用JNI把TensorFlow撸上Flink做实时的预测。把去年放出去的狠话收个尾。

之所以定这个目标,主要是因为在机器学习+流计算的场景有两大诉求:

  1. 如何给流计算赋能机器学习,做一些在线的预测(不是训练)?
  2. 要是能直接利用训练好的Keras或者Tensorflow模型就更好了嘿嘿嘿……
  3. 如何方便的部署?

目前大多的方案还是Flask或者Django写一个Http接口,利用 TensorFlow 原生的 Python API + 某个 Http/RPC Server 作为机器学习中心,然后在流计算中无状态的调用这些接口。

这样做的好处是可以无缝衔接研究者训练好的模型,毕竟大部分的机器学习框架都是Python友好的。但是缺点也很明显: – 网络IO消耗较大 – 为了适配接口编写代码复杂 – 流计算和机器学习服务集群压力不匹配,单方面处理速度过快导致机器学习服务器侧压力太大但是不能背压 – ……

为了解决这样的问题,我们需要把 Tensorflow 直接嵌入到 JVM 中去,这样的话有好几个方案:

  1. 利用原生的 Tensorflow Java API
  2. 把 Python 解释器嵌入JVM
  3. 利用 JNI,调用 C++ API,完成预测(某种程度和1有点像)
  4. 利用 Javascript Engine 运行 Tensorflow.js

本文最终用的是方案4。

先说说几个方案的问题: 1. Java API 官方不保证不稳定是最大的坑,其次部署麻烦,有些glibc不能升级的场景很难部署,更新也很麻烦。 2. 没有找到较好的 Python 解释器的Java库,Jython不能用的,详细原因过长不解释。 3. 依然是glibc等基础库的坑,而且还有在运行中模型不易更新等问题。 4. 也是有坑的,我这一套工具用起来并不是很方便,模型编译出来较大,如果设置不恰当,因为V8引擎的特性,不易使用多核(其实是可以滴)

最后我们的V8依旧是用JNI上的,但是这个库对其他依赖的要求要小很多,基本可以做到是个64位的Linux就可以上(J2V8也支持Windows/Mac/Linux x86/Android等等,但是需要修改POM重新编译)。

Talk is Cheap

1. 用Keras构建一个模型

我这里利用Wine数据集构建了一个简单的模型,详情参见:

TsingJyujing/tf.js-on-flinkgithub.com《实时数据流上的机器学习——Tensorflow on Flink》

这只是一个用于演示的测试模型。

2. 将模型编译为js文件

首先找个网站(自己本机搭建也可以),把你的模型放上去,确保通过http可以访问,像这样:

Index of /tof/models/wine/v1.0.0/fileserver.shinonomelab.com

随后修改src/generate_app.js,把里面的modelPath改成你的模型。

最后编译就好啦:npm run build,如果你要保留一些调试信息可以用npm run build-dev

编译完成以后,你就可以在target文件夹下看到你的 ml.bundle.js 文件,这个就是连库带模型打包到一起的一个文件。

3. 编写合适的 IModel

我这里仅仅实现了输入输出都是稠密矩阵的函数,参见:com.github.tsingjyujing.tof.engine.DenseMatrixModel,因为支持JS的语法,所以你可以把部分的预处理和后处理都放到JS中去,再编写相应的IModel即可。

4. 跑吧~

最简单的方式是使用一个RichMapFunction完成预测任务,我给出的例子里,每来10条数据就输出一下正确率,实际的业务场景还有更多玩法,例如把预测错的样本单独输出,这里就不展开了。

详细代码参看这个类:com.github.tsingjyujing.tof.example.Entry

5. 实时更新

如果你需要在运行中无缝更新你的模型怎么做?可以参考我写的这篇文章。

一般来说,大致就是:

  • 配置更新推送到Kafka,然后connect数据流和模型更新流。
  • 把你的模型文件和文件版本放到文件服务器上,定期检测更新,检测到更新就重新加载V8引擎
  • 或者用配置中心什么的……你们开心就好

最佳实践

  • 为了最大发挥CPU的效能(如果你的计算需要GPU还是老老实实用Python吧),建议将Flink的TaskManager启动时候的Slot数量设置为CPU的核心数量,如果上面还有其他任务,可以酌情减少。
  • 同时,并行化应该配置为全部Slot的个数
  • 不建议直接将JS文件放入Kafka中传输,因为实在太大了,建议使用文件服务器
  • 在切换Model的时候,先静静的等待新的Model加载好了,然后瞬间换掉老的Model即可。
  • 新老Model的切换和使用都必须是同一个Thread!

踩过的坑

看上去很简单,但是其实做出这个东西不是一个容易的事情,尤其是前端技术是我的短板的情况下,借助Tensorflow.js就变得尤其痛苦。

放弃了两三次,因为和太多的人吹过水,说能给Flink上TF,所以忍着做完了……

  • Webpack 打包问题
  • babel问题
  • polyfill的兼容性问题
  • Nashorn引擎和V8引擎支持语言版本不同的问题
  • Webpack打包后函数被包裹住,全局内找不到的问题
  • 本地V8不支持访问网络资源的问题
  • global对象的问题
  • JNI的多线程应用问题
  • 还有很多记不清了

推荐阅读
  • 如何利用Apache与Nginx高效实现动静态内容分离
    如何利用Apache与Nginx高效实现动静态内容分离 ... [详细]
  • 内网渗透技术详解:PTH、PTT与PTK在域控环境中的应用及猫盘内网穿透配置
    本文深入探讨了内网渗透技术,特别是PTH、PTT与PTK在域控环境中的应用,并详细介绍了猫盘内网穿透的配置方法。通过这些技术,安全研究人员可以更有效地进行内网渗透测试,解决常见的渗透测试难题。此外,文章还提供了实用的配置示例和操作步骤,帮助读者更好地理解和应用这些技术。 ... [详细]
  • Git命令基础应用指南
    本指南详细介绍了Git命令的基础应用,包括如何使用`git clone`从远程服务器克隆仓库(例如:`git clone [url/path/repository]`)以及如何克隆本地仓库(例如:`git clone [local/path/repository]`)。此外,还提供了常见的Git操作技巧,帮助开发者高效管理代码版本。 ... [详细]
  • 在Windows环境下安装Python的dlib和cv2库时,首先需要安装Boost和CMake。由于CMake依赖于C编译器,因此建议安装Visual Studio,推荐版本为VS2015及以上。此外,确保CMake已正确配置到系统环境变量中,以便顺利编译dlib。安装过程中还需注意Python的版本兼容性,以避免潜在的错误。 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 线程能否先以安全方式获取对象,再进行非安全发布? ... [详细]
  • 本文详细介绍了在Linux系统上编译安装MySQL 5.5源码的步骤。首先,通过Yum安装必要的依赖软件包,如GCC、GCC-C++等,确保编译环境的完备。接着,下载并解压MySQL 5.5的源码包,配置编译选项,进行编译和安装。最后,完成安装后,进行基本的配置和启动测试,确保MySQL服务正常运行。 ... [详细]
  • ButterKnife 是一款用于 Android 开发的注解库,主要用于简化视图和事件绑定。本文详细介绍了 ButterKnife 的基础用法,包括如何通过注解实现字段和方法的绑定,以及在实际项目中的应用示例。此外,文章还提到了截至 2016 年 4 月 29 日,ButterKnife 的最新版本为 8.0.1,为开发者提供了最新的功能和性能优化。 ... [详细]
  • 本文全面解析了 gRPC 的基础知识与高级应用,从 helloworld.proto 文件入手,详细阐述了如何定义服务接口。例如,`Greeter` 服务中的 `SayHello` 方法,该方法在客户端和服务器端的消息交互中起到了关键作用。通过实例代码,读者可以深入了解 gRPC 的工作原理及其在实际项目中的应用。 ... [详细]
  • TypeScript 实战分享:Google 工程师深度解析 TypeScript 开发经验与心得
    TypeScript 实战分享:Google 工程师深度解析 TypeScript 开发经验与心得 ... [详细]
  • Node.js 教程第五讲:深入解析 EventEmitter(事件监听与发射机制)
    本文将深入探讨 Node.js 中的 EventEmitter 模块,详细介绍其在事件监听与发射机制中的应用。内容涵盖事件驱动的基本概念、如何在 Node.js 中注册和触发自定义事件,以及 EventEmitter 的核心 API 和使用方法。通过本教程,读者将能够全面理解并熟练运用 EventEmitter 进行高效的事件处理。 ... [详细]
  • 在之前的系列中,我们探讨了多个关于AI学习的基础知识点。本篇将重点深入解析NumPy这一关键库的核心功能及其广泛应用。即使您对之前提到的例子印象模糊,也无妨,我们将从头开始,详细分析其代码结构与实现逻辑,如`import numpy as np`等基础语句,帮助您全面理解NumPy在数据处理与科学计算中的重要作用。 ... [详细]
  • Windows环境下详细教程:如何搭建Git服务
    Windows环境下详细教程:如何搭建Git服务 ... [详细]
  • 目录RPC是什么RPC的优点RPC的缺点RPC是什么RPC(RemoteProcedureCall)isaprotocolthatoneprogramcanusetorequest ... [详细]
author-avatar
上当受骗的家_908
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有