GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

Polynote 是一个新的多语言笔记本,具有一流的 Scala 支持、Apache Spark 集成,包括 Scala、Python 和 SQL 在内的多语言操作性,以及键入时自动完成等功能。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

最近,Netflix 宣布开源 Polynote ,该笔记本环境给数据科学家和机器学习研究人员提供了一个机会,允许他们自由地无缝整合基于 JVM 的机器学习平台(该平台大量使用 Scala)和 Python 生态系统内的主流机器学习和可视化库。目前,该项目已经得到 Netflix 的个性化及推荐团队的广泛采用,现在正在研究与平台的其他部分进行集成。

功能特性

可重复性

Polynote 的两大指导原则是可重复性和可见性。为了进一步实现这些目标,Netflix 最早的设计决策之一是从头构建 Polynote 的代码解释,而不是像传统笔记本一样依赖 REPL 。Netflix 觉得,尽管 REPL 总体上很好,但是根本不适合笔记本模式。为了理解 REPL 和笔记本的问题,可以看一个典型的笔记本环境设计。

笔记本是有序的单元格集合,每个单元格都可以存放代码或文本。每个单元格的内容可以独立修改和执行。单元格可重新安排、插入及删除,这也取决于笔记本中其他单元的输出。把这个与 REPL 环境进行比较会发现,在 REPL 会话中,用户把表达式一次一个地输入提示符。一旦求完值,表达式和其求值的结果不可变,求值结果被附加到全局状态提供给下个表达式。

不幸的是,这两个模式之间的脱节意味着一个典型的笔记本环境(使用 REPL 会话对单元格代码求值)会随着用户与笔记本的交互而导致隐藏状态的积累。单元格可以按任何顺序执行,从而改变这种全局隐藏状态,进而影响其他单元格的执行。通常情况下,笔记本无法从顶部可靠地重新运行,这使得它们难以重复及与他人共享,该隐藏状态还使得用户难以推断笔记本上发生的事情。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

在其他笔记本中,隐藏状态意味着一个变量在其单元格被删除后仍然可用

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

在 Polynote 笔记本中,没有隐藏状态,被删除的单元格变量不再可用

从头开始编写 Polynote 的代码解释允许消除这种全局、可变的状态。通过跟踪每个单元格中定义的变量,Polynote 基于运行于其上的单元格,为给定的单元格构建输入状态。让单元格的位置在其执行语义中变得重要,加强了最小惊奇原则,允许用户从上到下地阅读笔记本。它通过使笔记本持续地工作,让这更可能确保可重复性。

更好的编辑

面对现实,对于某些习惯使用 IDE 的开发者来说,在笔记本中编写大量代码就像回到了几十年前。我们已经看到更喜欢在 IDE 中编写代码的用户把代码粘贴到笔记本中运行。尽管提供一个成熟的现代 IDE 的所有功能不是 Netflix 的目标,但是,有一些提高生活质量的代码编辑功能对提高可用性很有帮助。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

Polynote 中的代码编辑集成了 Monaco 编辑器以提供交互式自动完成功能

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

Polynote 高亮显示代码中的错误以帮助用户快速找出问题所在

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

Polynote 为文本单元格提供了一个富文本编辑器

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

这个富文本编辑器允许用户轻松插入 LaTeX 方程

可见性

正如之前提到的,可见性是 Polynote 的指导原则之一。Netflix 希望可以轻松查看在任何给定时间,内核在做的事情,而不需要去查看日志。为此,Polynote 提供各种 UI 处理,以让开发者知道在发生的事情。这是某些代码执行过程中,Polynote 的一个屏幕快照。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

只要看一眼 UI,开发者就能得到相当多的信息。首先,很清楚,从笔记本视图和任务列表中都可以看到 Cell 1 正在运行,还可以看到 Cell 2 到 Cell 4 正按顺序排队等待运行。从图片中还可以看到目前正在运行的语句用蓝色高亮显示,这是一个定义“sumOfRandomNumbers”值的命令行。最后,由于对该语句求值启动了一个 Spark 作业,因此,还可在任务列表中看到作业级和阶段级的 Spark 进度信息……

下面是该执行过程的动画,我们可以看到 Polynote 如何使跟踪内核状态变得更加容易。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

执行一个 Polynote 笔记本

符号表提供了对笔记本内部状态的洞见。选择一个单元格后,该符号表显示在黑线上方当前单元格执行产生的值,黑线下方显示单元格可用的值(来自以前的单元格)。在动画的最后,显示了随着依次点击每个单元格而更新的符号表。

最后,内核状态区域提供关于内核执行状态的信息。下面显示了一个特写视图,可以看到内核状态从空闲和已连接状态(绿色)到忙碌状态(黄色)的变化。其他状态包括断开状态(灰色)、死机状态或未启动状态(红色)。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

内核状态从绿色(空闲和已连接状态)到黄色(忙碌状态)的改变

多语言

开发者可能已经注意到,在早先的快照中,每个单元格在其工具栏中有个语言下拉菜单。这是因为 Polynote 真正支持多语言笔记本,其中的每个单元格可以用不同的语言编写。

单元格在运行的时候,内核向单元格的语言解释器提供可用的类型化输入值。反过来,解释器将结果类型化输出值返回给内核。这允许 Polynote 笔记本中的单元格在相同的上下文中操作,并使用相同的共享状态,无论用什么语言定义。因此,用户可为手头的工作选择最佳的工具。

这里是一个使用 scikit-learn(一个 Python 库)来计算用 Scala 生成的数据集的保序回归(isotonic regression)的例子。代码改编自 scikit-learn 网站的保序回归示例。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

Scala 中的数据生成以及 Python 数据分析多语言示例

如本例所示,Polynote 允许开发者在同一个笔记本中流畅地从一种语言切换到另一种语言。

依赖项和配置管理

为了更好地促进可重复性,Polynote 将配置和依赖项信息直接存入笔记本,而不依赖于外部文件或集群 / 服务器级别的配置。我们发现,在笔记本代码中直接管理依赖项很麻烦,可能会让开发者感到困惑。相反,Polynote 提供了一个用户友好的配置部分,用户可在其中为每个笔记本设置依赖项。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

Polynote 的配置 UI,提供了用户友好的、笔记本级别的配置和依赖项管理

借助此配置,Polynote 为该笔记本构建了一个环境。它从本地获取依赖项(使用 Cousier 或 pip 从存储库中获取),并把 Scala 依赖项加载到隔离的 ClassLoader,以降低和 Spark 库发生类冲突的机会。Python 依赖项被加载到隔离的 virtualenv 中。当 Polynote 在 Spark 模式下使用时,它为使用所提供的配置笔记本创建一个 Spark 会话,Python 和 Scala 依赖项会自动添加到这个 Spark 会话中。

数据可视化

笔记本最重要的用例之一是探索和可视化数据的能力。Polynote 集成了两个最流行的开源可视化库: Vega 和 Matplotlib 。尽管 Matplotlib 集成在笔记本中是相当标准的,但是,Polynote 还具有对数据探索的本地支持,其中包括数据模式视图、表检查器、图构造器和 Vega 支持。

我们将使用来自 Kaggle 的 Wine Reviews 数据集,通过上面提到的工具快速分析和探索一些数据。首先,这是一个在 Spark 中加载数据、查看模式、制图并将该图保存到笔记本中的快速示例。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

使用图构造器进行数据探索的示例

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

快速检查器视图,显示数据帧(DataFrame)模式。蓝色箭头指向表视图 (左侧) 和图视图 (右侧) 的快速访问按钮

如果一个单元格的最后一条语句是一个表达式,那么,它将被赋给该单元格的 Out 变量。Polynote 将根据其数据类型决定的方式显示结果的表示形式。如果是类似表的数据类型(比如数据帧或案例类的集合,那么,Polynote 将显示快速检查器,允许开发者一眼就看到模式和类型信息。

快速检查器还提供两个打开完整数据检查器的按钮,左边的按钮打开表视图,右边的按钮打开图构造器。动画展示了图构造器,以及开发者如何拖放度量及维度来创建不同的图。我们还展示了如何将图存到笔记本中作为自己的单元格。因为 Polynote 本身就支持 Vega 规范,所以保存图只需要插入具有生成规范的新 Vega 单元格来实现。与任何其他语言一样,Vega 规范可以利用多语言支持来引用以前单元格中的值。在这种情况下,我们使用 Out 值(一个数据帧),并在其上实施额外的汇总。这样就可以高效绘制图形,而不必向客户端提供数百万数据点。Polynote 的 Vega 规范语言提供了用于汇总和修改类表数据流的 API。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

由图构造器生成的 Vega 单元格,显示其规范

Vega 单元格不需要使用图构造器来创建,任何 Vega 规范都可以放到一个 Vega 单元格中并直接绘制,如下所示。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

在 Polynote 中显示的 Vega 的堆叠面积图示例

除了单元格结果值之外,还可以通过单击检查符号表中的任何变量。

GitHub 标星 2400,Netflix 开源笔记本工具 Polynote

检查符号表中的变量

重塑 Scala 笔记本的体验

Netflix 个性化基础架构团队的工作是通过构建消除痛点并使研究人员专注于研究的工具来加速机器学习创新 。Polynote 源自对现有笔记本工具缺点的不满,尤其是在对 Scala 的支持方面。

比如,Python 开发人员习惯在一个具有相对较少数量依赖项的包管理器构建的环境中工作,而 Scala 开发人员通常在基于项目的环境中工作,并且使用构建工具管理数百个(常常是这样)有冲突的依赖项。借助 Spark,开发人员可以在一个集群计算环境中工作,无论使用哪个节点,分布式代码都必须在一致的环境中运行。最后,Netflix 发现,用户对笔记本内的代码编辑体验感到失望,尤其是那些习惯于使用 IntelliJ IDEA 或 Eclipse 的人。

对于笔记本体验来说,有些问题是独有的。笔记本的执行是一段特定的代码段,在一个特定的时间,运行于特定的环境中的记录。代码、数据及执行结果的组合形成单个文档,使得笔记本很强大,但也难以重复。事实上,科学计算社区已经记录了一些笔记本可重复性问题,还有一些用于可重复笔记本的最佳实践。

最后,对于机器学习领域来说,支持多语言也是一个独有的问题。机器学习研究人员经常在多编程语言环境中工作,比如,研究人员可能使用 Scala 和 Spark 来生成训练数据(清洗、二次采样等),而实际的训练可能使用流行的 Python 机器学习库(如 tensorflow 或 scikit-learn )来进行。

结束语

综上,已经描述了 Polynote 的一些关键功能。如果对这个项目感兴趣,可以通过该项目的网站: http://polynote.org/ ,或者直接访问 Github 的源代码来尝试: https://github.com/polynote/polynote ,Netflix 对该项目的未来非常看好,并且希望向社区学习。

相关推荐