写点什么

简化 TensorFlow 和 Spark 互操作性问题:LinkedIn 开源 Spark-TFRecord

  • 2020-06-09
  • 本文字数:4121 字

    阅读完需:约 14 分钟

简化TensorFlow和Spark互操作性问题:LinkedIn开源Spark-TFRecord

TensorFlow 和 Apache Spark 的互操作问题是现实世界机器学习场景中常见的挑战。可以说,TensorFlow 是市场上最流行的深度学习框架,而 Apache Spark 仍然是被广泛采用的数据计算平台之一,从大型企业到初创公司都能见到它们的身影。很自然会有公司尝试将这两者结合起来。虽然有一些框架能够让 TensorFlow 适应 Spark,但互操作性挑战的根源性往往在于数据级别上。TFRecord 是 TensorFlow 的原生数据结构,在 Apache Spark 中并不完全受支持。最近,LinkedIn 工程师开源了 Spark-TFRecord,这是一个基于 TensorFlow TFRecord 的 Spark 新的原生数据源。


LinkedIn 决定着手解决这一问题,并不令人感到惊讶。这家互联网巨头长期以来一直是 Spark 技术的广泛采用者,并且也一直是 TensorFlow 和机器学习开源社区的积极贡献者。在内部,LinkedIn 工程团队经常尝试在 TensorFlow 的原生 TFRecord 格式和 Spark 的内部格式(如 Avro 或 Parquet)之间实现转换。Spark-TFRecord 项目的目标就是在 Spark 管道中提供 TFRecord 结构的原生功能。

先前的尝试

Spark-TFRecord 并非第一个尝试解决 Spark 和 TensorFlow 之间的数据互操作性挑战的项目。这一方面最受欢迎的项目是 Spark 的创建者 Databricks 推广的 Spark-Tensorflow-Connector。我们已经多次使用过 Spark-TensorFlow-Connector,并取得了不同程度的成功。从架构上讲,连接器是 TFRecord 格式到 Spark SQL DataFrames 的一种改编。了解了这一点,Spark-TensorFlow-Connector 在关系数据访问场景中工作非常有效,但在其他用例中却仍然非常有限,也就不足为奇了。


如果你仔细想想,TensorFlow 工作流的一个重要部分与磁盘 I/O 操作相关,而不是与数据库访问相关。在这些场景中,开发人员在使用 Spark-TensorFlow-Connector 时仍然需要编写相当多的代码。此外,当前版本的 Spark-TensorFlow-Connector 仍然缺少一些重要的功能,比如在 TensorFlow 计算中经常用到的 PartitionBy。最后,这个连接器更像是处理 Spark SQL Data Frames 中的 TensorFlow 记录的桥梁,而不是原生文件格式。


考虑到这些限制,LinkedIn 工程团队决定从一个略微不同的角度来解决 Spark-TensorFlow 的互操作性挑战。

Spark-TFRecord

Spark-TFRecord 是 Apache Spark 的原生 TensorFlow TFRecord。具体来说,Spark-TFRecord 提供了从 Apache Spark 读取 TFRecord 数据或向 Apache Spark 写入 TFRecord 数据的例程。与构建连接器来处理 TFRecord 结构不同的是,Spark-TFRecord 构建为原生 Spark 数据集,就像 Avro、JSON 或者 Parquet 一样。这意味着在 Spark-TFRecord 中,Spark 所有的 DataSet 和 DataFrame I/O 例程都是自动可用的。


一个值得探讨的明显问题是,为什么要构建一个新的数据结构,而不是简单地对开源 Spark-TensorFlow-Connector 进行版本控制呢?嗯,看起来,要使连接器适应磁盘 I/O 操作,需要从根本上进行重新设计。


LinkedIn 工程团队没有遵循这条路线,而是决定实现一个新的 Spark FileFormat 接口,该接口从根本上来说,是为了支持磁盘 I/O 操作而设计的。新街口将使 TFRecord 原生操作适应任何 Spark DataFrame。从架构上看,Spark-TFRecord 由一系列基本构建块组成,这些构建块抽象出了读/写和序列化/反序列化例程:


  • Schema Inferencer:这是离 Spark-TensorFlow-Connector 最近的组件。

  • TFRecord Reader:该组件读取 TFRecord 结构并将其传递给 TFRecord Deserializer。

  • TFRecord Writer:该组件从 TFRecord Serializer 接收 TFRecord 结构并将其写入磁盘。

  • TFRecord Deserializer:该组件将 TFRecord 转换为 Spark InternalRow 结构。



使用 LinkedIn 的 Spark-TFRecord 与其他 Spark 远程数据集并没有什么不同。开发人员只需包含 spark-tfrecord jar 库,并使用传统的 DataFrame API 读写 TFRecord 即可,如下代码所示:


import org.apache.commons.io.FileUtilsimport org.apache.spark.sql.{ DataFrame, Row }import org.apache.spark.sql.catalyst.expressions.GenericRowimport org.apache.spark.sql.types._val path = "test-output.tfrecord"val testRows: Array[Row] = Array(new GenericRow(Array[](11, 1, 23L, 10.0F, 14.0, List(1.0, 2.0), "r1")),new GenericRow(Array[](21, 2, 24L, 12.0F, 15.0, List(2.0, 2.0), "r2")))val schema = StructType(List(StructField("id", IntegerType),                             StructField("IntegerCol", IntegerType),                             StructField("LongCol", LongType),                             StructField("FloatCol", FloatType),                             StructField("DoubleCol", DoubleType),                             StructField("VectorCol", ArrayType(DoubleType, true)),                             StructField("StringCol", StringType)))val rdd = spark.sparkContext.parallelize(testRows)//Save DataFrame as TFRecordsval df: DataFrame = spark.createDataFrame(rdd, schema)df.write.format("tfrecord").option("recordType", "Example").save(path)//Read TFRecords into DataFrame.//The DataFrame schema is inferred from the TFRecords if no custom schema is provided.val importedDf1: DataFrame = spark.read.format("tfrecord").option("recordType", "Example").load(path)importedDf1.show()//Read TFRecords into DataFrame using custom schemaval importedDf2: DataFrame = spark.read.format("tfrecord").schema(schema).load(path)importedDf2.show()
复制代码


对大多数组织来说,Spark 和 TensorFlow 这样的深度学习框架之间的互操作性可能仍然是一个具有挑战性的领域。然而,像 LinkedIn 的 Spark-TFRecord 这样经过大规模测试的项目,无疑有助于简化这两种技术之间的桥梁,而这两种技术对现代机器学习架构来说都是必不可少的。


作者介绍:


Jesus Rodriguez,Invector Labs 首席科学家、执行合伙人,在 IntoTheBlock 任 CTO。同时也是天使投资人、作家、多家软件公司董事会成员。


原文链接:


https://towardsdatascience.com/linkedin-open-sources-a-small-component-to-simplify-the-tensorflow-spark-interoperability-fbf0b65ae113


2020-06-09 09:004656

评论

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

iOS自动化测试驱动工具探索

字节跳动终端技术

ios 字节跳动 自动化测试 测试工具 火山引擎MARS

上云采购季丨云服务器1核2G 低至35元/年,老用户续费6.5折起

阿里云弹性计算

阿里云 云服务器 ECS 采购季

网络安全kali渗透学习 web渗透入门 Metasploit---基于tcp协议收集主机信息

学神来啦

网络安全 信息安全 kali kali Linux

Linux之ping命令

入门小站

Linux

简单说明一下数据库审计能带来的价值

行云管家

数据库 数据安全 数据库审计

什么是云效?通过云效体验一站式研发,实现10 倍效能提升

阿里云云效

阿里云 DevOps 云原生 研发效能 云效

【C语言】野指针

謓泽

C语言 3月月更 野指针

ImageView变灰、倒影、圆角、加水印

逆锋起笔

android 图片处理 3月月更 imageView

网易智企发布“易+”开源计划,网易会议组件正式开源

网易云信

音视频 开发

当渲染遇上边缘计算,打造视频交互新模式

火山引擎边缘云

云原生 边缘计算 实时渲染

Web 键盘输入法应用开发指南 (4) —— 组合键

天择

JavaScript 键盘 输入法 3月月更

web前端培训:2022前端基础面试题

@零度

CSS JavaScript 前端开发

大规模异构数据的线索列表进化之路

百度Geek说

后端

语音顶会 ICASSP 2022 成果分享:基于时频感知域模型的单通道语音增强算法

阿里云CloudImagine

阿里云 音频 论文 视频云 智能降噪

无依赖单机尝鲜 Nebula Exchange 的 SST 导入

NebulaGraph

数据库 大数据 图数据库

【等级保护】等级保护共分为几级?保护对象是指什么?

行云管家

网络安全 等保 等级保护 等保2.0

大数据培训:Spark 性能调优详解

@零度

spark 大数据培训

面向体验,助推超视频时代新增长

字节跳动视频云技术团队

音视频开发

2022年2月国产数据库大事记

墨天轮

数据库 opengauss TiDB 国产数据库 polarDB

老牌软件厂商亚信科技加入,携手龙蜥社区共建开源生态

OpenAnolis小助手

开源 亚信科技 互联网社区

深入浅出特征工程 -- 基于 OpenMLDB 的实践指南(下)

第四范式开发者社区

数据库 sql 人工智能「 特征 特征平台

为什么在数据驱动的路上,AB实验值得信赖?

字节跳动数据平台

字节跳动 数据分析 AB testing实战 ab测试

应对EAST 5.0新挑战!索信达推出灵矩全景式监管合规平台

索信达控股

数据治理 金融 监管平台 数智化 合规性

2022年中国个人云盘行业发展年度分析

易观分析

个人云盘

大数据时代下,App数据隐私安全你真的了解么?

移动研发平台EMAS

阿里云 开发者工具 数据安全 #EMAS

selenium相对定位器

红毛丹

3月程序媛福利 3月月更

java培训:JVM的体系结构

@零度

JVM JAVA开发

WorkPlus数据中台:企业降本增效新引擎

BeeWorks

恒源云(Gpushare)_【活动专区】已上线,没有最优只有更优

恒源云

人工智能 算法 服务器

谁能在第四代算力革命中脱颖而出?CPU?GPU?算法?数据?

GPU算力

在线HTML转PUG工具

入门小站

工具

简化TensorFlow和Spark互操作性问题:LinkedIn开源Spark-TFRecord_AICon_Jesus Rodriguez_InfoQ精选文章