写点什么

基于 Spark 的大规模推荐系统特征工程

  • 2020-09-07
  • 本文字数:4492 字

    阅读完需:约 15 分钟

基于Spark的大规模推荐系统特征工程

导读: 特征工程在推荐系统中有着举足轻重的作用,大规模特征工程处理的效率极大的影响了推荐系统线上的性能。第四范式作为国际领先的机器学习和人工智能技术与平台服务提供商,面向大规模特征工程问题开发了下一代离线在线一致性特征抽取引擎 FESQL,针对 AI 场景支持 SQL 接口,兼容 Spark 3.0 同时提供高性能的 Native 执行引擎。本次分享题目为基于 Spark 的大规模推荐系统特征工程及优化,主要内容包括:


  • 大规模推荐系统

  • Spark SQL 应用与 FESQL

  • 基于 LLVM 的 Spark 优化

  • 总结

01 大规模推荐系统

1. 业界推荐系统的应用


众所周知,推荐系统在业界有着许多成功的应用,据统计,亚马逊 40%的销售在推荐系统的作用下产生;Netflix 75%的用户使用推荐系统寻找他们喜爱的视频;30%的用户进行在线购物前会使用关键词搜索他们需要的商品。目前,几乎所有的新闻、搜索、广告、短视频应用都是基于推荐系统建立的。

2. 推荐系统的架构


业界成熟的推荐系统架构一般分为三层:离线层 ( offline layer ),近实时的流式层 ( stream layer ) 和在线层 ( online layer ) 三部分。


离线层: 一般用于大规模的数据预处理、特征抽取与模型训练,通常用 Hadoop HDFS 进行数据存储,使用 Spark,MapReduce 等分布式计算引擎进行特征抽取与计算以及数据管理,再使用离线模型训练框架 TensorFlow、Pytorch、MXNet 等进行离线的模型训练,模型结果可用于线上预测。


近实时的流式层: 主要是为了提升推荐系统的时效性,对于一些时序特征,可以使用消息队列收集近实时的数据,结合流式计算服务如 Flink 对数据进行补全,把结果存入 NoSQL、MySQL 等存储服务中,存储结果供线上服务使用。


在线层: 用户产生的数据可以通过 Flink 生成流式特征,也可以使用 HDFS 进行数据归档。在线预估时从 NoSQL 或 MySQL 中提取流式特征,通过离线训练的模型即可进行线上预估。

3. 大规模推荐系统的特征抽取


大规模推荐系统的数据处理通常分为两类:


  • ETL ( Extract, Transform, Load ):进行数据数据补全、格式转换等;

  • 特征抽取:对原始数据特征进行处理,得到模型易于学习的样本特征,如离散化,embedding 化等方法。


常用工具包括:


  • SQL/Python:针对一般规模的数据,通常可以通过使用 SQL/Python 进行处理;

  • Hadoop/Spark/Flink:针对大规模数据,通常要借助 Hadoop/Spark/Flink 等计算框架。

02 Spark SQL 应用与第四范式自研 FESQL 技术

1. Spark 简介


Spark 是专为大规模数据处理而设计的快速通用的计算引擎,依托强大的分布式计算能力,在 Spark 上可以开发机器学习、流式学习等应用。Spark 提供了 SparkSQL,使其能与 SQL、Hive 兼容,提供 PySpark 接口可以让开发者使用 Python 进行分布式应用开发,提供了 MLlib 包,可以用于机器学习应用的开发。同时 Spark 也提供诸如 Catalyst/Tungsten 等方式的优化。



Spark 的优势就在于:计算速度快,能够处理 PB 级别的数据,分布式计算和自动容错机制,提供便于使用的 SQL/Python/R API,同时,Spark 提供的机器学习库也可以应用于推荐系统,所以在业界,几乎所有公司都会使用 Spark 作为离线层数据处理框架。

2. 大规模推荐系统中的 Spark 应用


以 IBM 的一个推荐系统开源项目来说明 Spark 在推荐系统中的应用。首先是数据加载,使用 read.csv 即可加载本地或 HDFS 数据。使用 select 即可进行特征列选择。



然后是对数据进行预处理以及简单的特征抽取,该项目中使用了 Spark UDF 对字符串进行处理,抽取出其中的年份信息,将年份信息作为特征进行使用。



得到全部特征预处理的结果后即可进行模型训练,可以使用 Spark 内置机器学习 API 进行模型训练。训练完成后,模型即可上线进行线上预估。



线上的预估服务需要提供实时计算的预估接口,但是在实践中,Spark 并不适合直接用于线上预估。原因有三:


  • Driver-exexutor 结构只适合进行批量处理,不适合在线处理

  • Spark 的批处理模式不适合提供长时间运行的在线服务,也不能保证低延时的计算效率(Spark 3.0 的 Hydrogen 可以部分支持)

  • RDD 接口只适合迭代计算,不适合做实时计算


因此,业界的通常做法是使用 Java、C++等后端语言实现在线的预估服务,这就带来了另一个线上特征抽取的一致性问题,由于必须要保证线上线下特征的一致性,所以必须同时开发线上使用的特征处理模块,并人工保证计算结果没有差异。

3. Spark 的优缺点


Spark 支持大规模数据的批处理,提供标准的 SQL 接口的优点使其成为离线层数据处理的不二之选,但是,Spark 不支持线上服务,不能保证线上线下特征一致性,同时在 AI 场景下的性能没有经过优化,所以在 AI 场景下,Spark 仍有许多不足。针对这些不足,第四范式开发了 FESQL 执行引擎。

4. FESQL 线上线下一致性执行引擎


FESQL——保证离线在线特征一致性的 SQL 执行引擎。上图表示传统的上线过程,生成离线模型文件后,由应用开发者开发线上预估服务,将 Spark、SQL 中的特征处理逻辑翻译成后端语言代码,实现线上服务,每新增一个特征,都要开发对应的特征抽取模块,同时需要用户和业务开发者保证特征数据的一致性。下图是使用 FESQL 的上线过程,由于线上线下使用统一的 SQL 服务进行特征抽取,因而保证了特征在线上和线下的一致性。



图中所示为 FESQL 基本框架,左边离线部分和 SparkSQL 的用法基本一致,由数据科学家设计 SQL 语句,基于 Spark 进行离线批处理。橙色框表示第四范式开发的基于 LLVM 优化的 SQL 引擎,性能大大优于原生 Spark,同时能够更好的支持线上服务,尤其对于 SQL 语句进行了拓展,使之能够更好的支持机器学习场景下的线上特征处理。其中 FEDB 是有第四范式开发的全内存数据库,相比于 Spark 读取 HDFS 这种高延时的数据载入方式,FEDB 可以提前载入模型预估所需数据,效果接近开发的线上特征抽取模块,同时支持时序特征。线上线下的数据一致性由同一套的 SQL 执行引擎保证。

5. 性能对比


与兼容 SQL 的全内存数据库 memsql 的方式进行性能对比可以发现,LLVM 优化后的 SQL 之心引擎在读和写的性能上都要更高。



对于机器学习场景下的列聚合 ( 生成时序特征 ) 场景,LLVM 优化后的 SQL 引擎也比 memsql 快很多,耗时基本小于 memsql 的 50%。

03 基于 LLVM 的 Spark 优化

1. Spark Catalyst 和 Tungsten 优化


Spark2.0 之后提供了 Catalyst 和 Tungsten 优化。图为 Catalyst 从 SQL 解析到生成物理计划的流程图,由 SQL 语句或 DataFrame 接口通过编译器技术 ( 语法解析等 ) 生成 Unresolved Logical Plan,Catalyst 通过解析 Catalog 对 Unresolved Logical Plan 处理得到 Logical Plan,在经过 SQL 常用优化方案,得到 Optimized Logical Plan,优化之 Catalyst 后可以生成多个基于 Spark 运行的 Physical Plan,最终选择其中最高效的进行运行。该方式适合于计算节点优化,对于 SQL 的优化也同样效果显著。


Tungsten 是另外一种优化方案。主要的优化点在于:


  • 内存管理与堆外存储避免了多余的内存使用,同时减少了 GC;

  • 引入 code generation 技术,通过 JIT 编译运行,Spark 动态生成 Java 字节码来计算这些表达式,而不是为逐行解析执行,减少了原始数据类型的装箱操作,更重要的是避免了 Overhead 较大的虚函数调用。



以一个经典实例来介绍 Tungsten 的原理。左侧的 SQL 命令可以翻译成在 Spark 上运行的 Logical Plan,由下往上分为 4 个计算节点,传统的 SQL 执行引擎中,四个节点分别由四个迭代器实现 ( 可以理解为四个循环 ),循环没有合并优化以及节点的虚函数调用对于 CPU Cache 非常不优化,导致传统的 SQL 引擎计算性能比较差。右侧为 Tungsten 优化后的结果,使用了 whole staged code generation,对多节点的循环进行了合并,性能有着明显的提升。

2. Catalyst/Tungsten 的不足


Catalyst/Tungsten 给 Spark 带来了明显的性能能提升,但 Catalyst/Tungsten 的优化仍然是基于 Java 进行的,如果能使用更底层的指令集,如汇编、二进制码效果会更好;JVM 难以支持循环展开等优化方式;而且并非所有的节点都支持 code generation,例如图中的 WindowExec 节点就不支持 code generation。

3. FESQL


鉴于以原因,Catalyst/Tungsten 的优化仍有不足,第四范式基于 LLVM 技术进一步优化得到 FESQL。SparkSQL 架构如黄色部分所示,FESQL 架构如蓝色框所示,根据 SparkSQL 语句生成 FESQL Logical Plan,再由 LLVM JIT 生成平台二进制码直接执行,相比于 Spark 少了 JVM 一层,性能也会有明显提升。

4. LLVM 简介


LLVM 项目是一个模块化的、可重用的编译器和工具链集合,可以方便的实现编译器和代码生成的工作。提供了许多有用的工具,如 Clang、LLDB、MLIR、TVM 等,能够实现多种编程语言的编译器。



JIT ( Just-In-Time Compiler ) 编译,可以一边运行程序一边编译二进制代码,右图为使用 JIT 编译的 Add 函数,这部分代码可以在运行时被翻译成底层代码,与直接使用 C++来实现效率接近,同时 JIT 能够适应不同的 CPU 生成优化的二进制码。

5. FESQL 的优化点


目前已经能使用循环展开、常数折叠、向量化和一些基于 CPU 本身的优化;未来,基于 PTX 后端还可以尝试生成 CUDA 代码,利用 GPU 进行计算的加速。

6. 性能比较


FESQL 与 Databrick 内部的 Photon 非常相似 ( Photon 内部由 C++实现 ),因而进行对两者进行比较。Photon 是 Databrick 的企业产品,仅能在 Databrick 的平台上使用,且不支持 PTX/CUDA。对比由 C++和由 JVM 实现的处理引擎的性能,发现 C++实现的处理引擎性能非常优越。

7. FESQL 的节点优化


FESQL 使用了节点优化,使用 SimpleProject 对 Project 节点进行合并优化,对窗口节点使用 code generate 进行优化。下图说明了对于节点的优化可以明显减少执行的流程。

8. FESQL 的表达式优化


FESQL 也实现了非常多表达式优化,保证在不同 SQL 场景都比传统数据库有着更好的性能表现。

9. 性能


对比 Spark 3.0 和 FESQL on Spark 可以发现,FESQL 的执行效率明显高于 Spark 3.0,多窗口的情况下效果更明显,有着接近 6 倍的性能提升。



通过对比两者生成的逻辑计划图,可以发现 FESQL 的计划图明显更简单,通过对比两者的火焰图,底层 RDD 计算基本一致,FESQL 取样的样本数更少,执行时间更短,因此 FESQL 的执行效率更高。

10. 展望


未来第四范式计划推出 LLVM-enabled Spark Distribution,使开发者可以通过设置 SPARK_HOME 便利的实现性能加速;为开发者提供 Docker、Notebook、Jar、Whl 包,便于开发;提供类似 Python 的保证一致性的 DSL 语言用于 UDF 和 UDFA 实现;还有提供对 CUDA 和 GPU 的支持。

04 总结


大规模推荐系统中可以使用 Spark、Flink、ES、FESQL 实现大规模的数据处理,其中 Spark 更适合离线的批处理,而不适合线上处理,FESQL 能同时进行线上线下服务因为能够保证特征一致性,同时 LLVM JIT 实现的 FESQL 拥有比 Spark 3.0 更好的性能。


作者介绍


陈迪豪,第四范式架构师


第四范式先知平台架构师,负责深度学习框架产品化以及下一代特征引擎开发工作。积极参与了开源社区 TensorFlow、Kubernetes、TVM 等项目开发,对分布式系统和深度学习平台有一定了解,目前专注于离线在线一致性的特征引擎开发。


本文来自 DataFunTalk


原文链接


基于Spark的大规模推荐系统特征工程


2020-09-07 10:083436

评论

发布
暂无评论
发现更多内容

NodeJs中Buffer与Stream理解

小风以北

stream 原理 Node buffer

云图说|将源端MongoDB业务搬迁至华为云DDS的几种方式

华为云开发者联盟

mongodb 数据迁移 华为云文档数据库服务 DDS 文档数据库

Java面试过了京东五面之后,发现掌握了这些技术也没有那么难

钟奕礼

Java 编程 程序员 架构 面试

tensorflow实现cifar10彩色图像多类别分类

AI_robot

iOS开发:git上传代码到开源中国的步骤,以及pod的更新方法

花花

ios

这可能是全网关于Camera慢动作录像(SlowMotion)介绍最全的文章了

小驰笔记

android 音视频 camera 引航计划

最全Java架构师技能树:Java编程+网络+设计模式+数据库+分布式

钟奕礼

Java 编程 程序员 架构 面试

tensorflow实现两种图像风格融合 即神经风格迁移

AI_robot

tensorflow实现像素级图像分割算法

AI_robot

深入分析小程序运行环境框架原理

小风以北

小程序 编译原理 框架 工作原理

tensorflow实现CNN模型垃圾分类算法

AI_robot

区块链底层Baas平台搭建,区块链政务底层平台开发

tensorflow实现低分辨率灰度图像分类算法

AI_robot

tensorflow实现深度卷积生成对抗网络(DCGAN)生成手写数字图片

AI_robot

UUID不失精度,长度改进

waitmoon

Java uuid

NodeJs 介绍

小风以北

nodejs 新特性

Tensorflow实现Transformer模型将葡萄牙语翻译成英语

AI_robot

【译】ECMAScript 2021: 最终功能集确定

清秋

JavaScript ecmascript 翻译 ES6 新闻

寻找音乐API接入正版音乐曲库?了解HIFIVE音乐开放平台!

HIFIVE音加加

音乐api 正版曲库 音乐sdk

一个数组通过配置随机抽取组成小数组

waitmoon

Java

推荐16款强大的Twitter视频下载器(2021精选)

科技猫

twitter 软件 网站 分享 视频下载

民国最出名的女作家,为什么是她?

了了Vita

最新阿里蚂蚁金服四面(已拿offer)Java技术面经总结

钟奕礼

Java 编程 程序员 架构 面试

看完这篇文章,你起码对分析视频卡顿有点思路了

小驰笔记

android 音视频 camera 引航计划

如何在游戏中快速集成聊天功能

LeanCloud

游戏开发 即时通讯 聊天室 sdk

Android 高通Camx架构学习 - 第1章

小驰笔记

android 音视频 camera 引航计划

阿里天猫3面(Java研发):GC回收+Redis Hash算法+架构部署+秒杀等

钟奕礼

Java 编程 程序员 架构 面试

《月亮与六便士》:给你500万,你会用它买套房子还是周游世界?

了了Vita

专访孙立坚:印度经济发展实力几何 ?

了了Vita

随机数环设想

waitmoon

Java

在项目启动时(无request)获取Tomcat端口号

waitmoon

Java

基于Spark的大规模推荐系统特征工程_数据库_DataFunTalk_InfoQ精选文章