QCon北京|3天沉浸式学习,跳出信息茧房。 了解详情
写点什么

简化 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:004627

评论

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

润和软件与华秋达成生态共创合作,共同推动物联网硬件创新

华秋电子

软通动力与华秋达成生态共创合作,共同推动物联网硬件创新

华秋电子

向量检索在大模型应用场景的技术和实践

Baidu AICLOUD

向量检索 大模型

点云标注在自动驾驶中的实践应用与挑战

来自四九城儿

2023中国老博会/2023西部养老辅具展会

秋硕展览

LeetCode题解:2618. 检查是否是类的对象实例,迭代和递归

Lee Chen

JavaScript LeetCode

有哪些好用的远程传输大文件的软件

镭速

远程传输大文件

华秋慕尼黑上海电子展圆满收官,数字化赋能智能制造!

华秋电子

aspera替代方案:可靠和高效的企业文件传输工具

镭速

aspera替代方案 企业文件传输工具

开发微信公众号本地调试+-+cpolar内网穿透

程思扬

微信公众号 网络穿透

“芯”有灵“蜥” 融合·创新!龙蜥社区走进 Intel MeetUp 议程硬核剧透来了

OpenAnolis小助手

开源 操作系统 intel Meetup 龙蜥社区

直播预告 | 博睿学院:让Arthas带你玩转jvm

博睿数据

JVM 可观测性 智能运维 博睿数据 博睿学院

国内市场知名的数据可视化工具

2D3D前端可视化开发

数据分析 数据可视化 商业智能 数据可视化工具 可视化大屏

2023年中国(深圳)国际耐火材料产业展会

秋硕展览

Java基础入门——Java语言介绍

java易二三

Java

共筑信创生态!亚信科技AntDB数据库与用友、东方通、星辰天合达成兼容互认

亚信AntDB数据库

数据库 AntDB AntDB数据库

不懂代码也不用怕!10款无代码网站搭建平台

高端章鱼哥

前端 工具 开发工具 设计师

开鸿智谷与华秋达成生态共创合作,共同打造硬件生态

华秋电子

Karmada:让跨集群弹性伸缩FederatedHPA突破新边界

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 7 月 PK 榜

软件测试/测试开发丨Linux常用命令之性能统计

测试人

Python Linux 程序员 性能 软件测试

先楫半导体与华秋达成生态共创合作,共建技术生态社区

华秋电子

应对突发流量,如何快速为自建 K8s 添加云上弹性能力

阿里巴巴云原生

阿里云 Kubernetes 云原生

尝试7分钟内上线一个网站,这个工具太赞了!

互联网工科生

低代码 搭建平台 搭建网站

实现大文件远程传输、备份和共享的小秘诀

镭速

大文件远程传输

深开鸿与华秋达成生态共创合作,共同打造硬件生态

华秋电子

MES1.0.0正式发布|万界星空推出免费的MES系统

万界星空科技

开源 MES系统 制造业生产管理系统

点云标注的未来发展与技术革新

来自四九城儿

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