在过去的十年中,人们对“科学计算”和“数据科学”的兴趣激增:即应用计算来回答问题并分析自然科学和社会科学中的数据。为了满足这些需求,我们看到了编程语言、工具和技术的复兴,这些工具和技术帮助科学家和研究人员探索和理解数据和科学概念,以及传达他们的发现。但迄今为止,很少有工具专注于帮助科学家获得对现代 Web 浏览器全部通信潜力的无过滤访问权限。因此,今天我们很高兴地介绍 碘化物,这是一个实验性的工具,旨在帮助科学家使用 Web 技术编写漂亮的交互式文档,所有这些都在类似于其他科学计算环境的迭代工作流程中进行。
除了只是一个用于在浏览器中创建动态文档的编程环境外,碘化物还试图通过始终将编辑工具与干净易读的文档捆绑在一起,来消除沟通工作流程中的阻碍。这与 IDE 风格的环境不同,IDE 风格的环境输出 .pdf 文件等演示文档(然后与原始代码分离)和混合代码和演示元素的基于单元的笔记本。在碘化物中,您可以获得一个外观如您所愿的文档,以及对底层代码和编辑环境的轻松访问。
碘化物目前还处于 alpha 阶段,但遵循互联网格言 “如果你对产品的第一个版本不感到尴尬,那么你的发布时间就太晚了”,我们决定进行一个非常早期的软发布,希望获得更大社区的反馈。我们有一个演示,您可以 立即试用,但请预期会有很多粗糙的边缘(并且请不要将此 alpha 版本用于关键工作!)。我们希望,尽管存在粗糙的边缘,但如果您眯着眼睛看,您将能够看到该概念的价值,并且您提供的反馈将帮助我们确定下一步的方向。
我们如何获得碘化物
Mozilla 的数据科学
在 Mozilla,我们绝大多数的数据科学工作都集中在沟通方面。尽管我们有时会部署旨在直接改善用户体验的模型,例如帮助用户发现浏览器扩展的推荐引擎,但大多数情况下,我们的数据科学家分析我们的数据以发现和分享见解,这些见解将为产品经理、工程师和高管的决策提供信息。
数据科学工作涉及编写大量代码,但与传统的软件开发不同,我们的目标是回答问题,而不是生产软件。这通常会导致某种报告——文档、一些绘图或可能是交互式数据可视化。与许多数据科学组织一样,我们在 Mozilla 使用诸如 Jupyter 和 R-Studio 等出色的工具来探索我们的数据。但是,当需要分享我们的结果时,我们通常无法将 Jupyter 笔记本或 R 脚本交给决策者,因此我们经常最终做一些事情,例如将关键数据和汇总统计数据复制到 Google 文档中。
我们发现,从在代码中探索数据到创建易于理解的解释并返回的过程并不总是容易。研究表明,许多人都有这种体验。当一名数据科学家阅读另一名数据科学家最终的报告并想查看其背后的代码时,可能会遇到很多阻碍;有时查找代码很容易,有时则不容易。如果他们想尝试实验并扩展代码,事情显然会变得更加困难。另一名数据科学家可能拥有您的代码,但他们的机器可能没有相同的配置,并且设置起来需要时间。

数据科学工作的良性循环。
为什么科学领域中几乎没有 Web?
在 Mozilla 这些数据科学工作流程的背景下,我在 2017 年底进行了一个需要交互式数据可视化的项目。今天,您可以使用 Python、R 和 Julia 的出色库来创建交互式可视化,但对于我想完成的事情,我需要降级到 Javascript。这意味着要离开我喜欢的 data science 环境。现代 Web 开发工具非常强大,但也极其复杂。我真的不想弄清楚如何将带有热模块重新加载的完整 Javascript 构建工具链运行起来,但除此之外,我没有找到太多针对在实时迭代工作流程中创建干净、可读的 Web 文档的工具,这种工作流程我比较熟悉。
我开始思考为什么这种工具不存在——为什么没有用于构建交互式 Web 文档的 Jupyter——并且很快扩展到思考为什么几乎没有人将 Javascript 用于科学计算。三个主要原因显而易见
- Javascript 本身在科学家中的声誉褒贬不一,因为其速度缓慢且笨拙;
- 在浏览器中运行或与 Javascript 配合使用的科学计算库并不多;以及
- 正如我所发现的,很少有科学编码工具能够实现快速迭代循环,并且还能无过滤地访问浏览器中的演示功能。
这些都是非常大的挑战。但当我进一步思考时,我开始认为,在浏览器中工作对于我们在 Mozilla 所进行的那种沟通型数据科学来说可能有一些真正的好处。当然,最大的优势是,浏览器可以说是地球上最先进且支持最广泛的演示技术集合,从 DOM 到 WebGL 到 Canvas 再到 WebVR。
思考上面提到的工作流程阻碍,我突然意识到另一个潜在的优势:在浏览器中,最终文档不必与创建它的工具分开。我想要一个旨在帮助科学家迭代 Web 文档(基本上是用于解释想法的单用途 Web 应用)的工具……而我们正在使用的许多工具本身基本上就是 Web 应用。对于编写这些小型 Web 应用文档的用例,为什么不将文档与用于编写它的工具捆绑在一起呢?
通过这样做,非技术读者可以看到我漂亮的文档,但其他数据科学家可以立即回到原始代码。此外,由于计算内核将是浏览器的 JS 引擎,他们将能够立即开始扩展和实验分析代码。而且他们可以在不连接到远程计算资源或安装任何软件的情况下完成所有这些操作。
走向碘化物
我开始与同事讨论在浏览器中进行科学计算的潜在优缺点,在我们讨论的过程中,我们注意到了一些其他有趣的趋势。
在 Mozilla 内部,我们看到了很多展示 WebAssembly 的有趣演示,WebAssembly 是一种让浏览器运行用 Javascript 以外的语言编写的代码的新方法。WebAssembly 允许程序以惊人的速度运行,在某些情况下接近本地二进制文件。我们看到了将诸如 整个 3D 游戏引擎 等计算量大的进程在浏览器中无障碍运行的示例。展望未来,可以将一流的 C 和 C++ 数值计算库编译为 WebAssembly,并将它们封装在符合人体工程学的 JS API 中,就像 SciPy 项目针对 Python 所做的那样。实际上,项目已经开始 进行 此类操作 操作 操作。
WebAssembly 使得能够在浏览器中以接近本机的速度运行代码。
我们还注意到 Javascript 社区愿意在这样做有助于人们 更有效地解决问题 的情况下引入 新的语法。也许可以模仿 MATLAB、Julia 和 Python 中使数值编程更易于理解和流畅的一些关键语法元素——矩阵乘法、多维切片、广播数组运算等等。同样,我们发现其他人 也有类似的想法。
随着这些思路的汇聚,我们开始思考,网络平台是否即将成为科学计算的理想家园。至少,它似乎正在发展,可以满足我们在 Mozilla(以及许多其他行业和学术界人士)遇到的某些沟通工作流程的需求。随着 Javascript 核心不断改进以及添加数值编程语法扩展的可能性,也许 JS 本身可以对科学家更有吸引力。WebAssembly 似乎为伟大的科学库提供了一条途径。这三者的基石将是为网络创建数据科学文档的环境。我们决定将最初的实验重点放在最后一个元素上,这让我们找到了 Iodide。
Iodide 的解剖结构
Iodide 是一款旨在为科学家提供熟悉的工作流程,以利用网络平台的全部功能创建精美互动文档的工具。为了实现这一目标,我们提供了“报告”——基本上是一个网页,您可以用内容填充它——以及一些用于迭代探索数据和修改报告以创建您准备分享的内容的工具。准备就绪后,您可以直接发送最终报告的链接。如果您的同事和合作者想要查看您的代码并从中学习,他们可以一键返回探索模式。如果他们想要尝试代码并将其用作自己工作的基础,只需再点击一次,他们就可以将其分叉并开始处理自己的版本。
继续阅读,进一步了解我们正在尝试的一些想法,以使此工作流程感觉流畅。
探索和报告视图
Iodide 旨在缩短探索、解释和协作之间的循环。其中最重要的是能够在美观且易于阅读的文档和用于迭代计算探索的实用环境之间来回切换。
当您首次创建一个新的 Iodide 笔记本时,您将从“探索视图”开始。这提供了一组窗格,包括一个用于编写代码的编辑器、一个用于查看评估代码输出的控制台、一个用于检查会话期间创建的变量的工作区查看器以及一个“报告预览”窗格,您可以在其中看到报告的预览。

在 Iodide 的探索视图中编辑 Markdown 代码块。
通过点击右上角的“报告”按钮,您的报告预览内容将展开以填充整个窗口,使您可以将要讲述的故事置于最显眼的位置。不会编写代码或对技术细节不感兴趣的读者可以专注于您试图传达的信息,而不必阅读代码。当读者访问报告视图的链接时,您的代码将自动运行。如果他们想要查看您的代码,只需点击右上角的“探索”按钮即可将其带回探索视图。从那里,他们可以复制笔记本以进行自己的探索。

从探索视图切换到报告视图。
无论何时与他人共享 Iodide 笔记本的链接,您的合作者始终可以访问这两个视图。简洁、易读的文档永远不会与底层的可运行代码和实时编辑环境分离。
具有网络平台功能的实时互动文档
Iodide 文档驻留在浏览器中,这意味着计算引擎始终可用。无论何时共享您的工作,您都将共享一个具有运行代码的实时互动报告。此外,由于计算发生在浏览器中,与演示并行,因此无需在另一个进程中调用语言后端。这意味着互动文档会实时更新,为无缝 3D 可视化开辟了可能性,即使对于VR 所需的低延迟和高帧速率也是如此。
共享、协作和可重复性
在网络中构建 Iodide 简化了我们在其他工具中遇到的许多工作流程摩擦元素。共享变得更加简单,因为文档和代码在同一个 URL 中可用,而不是,例如,将脚本的链接粘贴到 Google 文档的脚注中。协作变得更加简单,因为计算内核就是浏览器,库可以通过 HTTP 请求加载,就像网页加载脚本一样——不需要安装任何额外的语言、库或工具。而且由于浏览器提供了一个兼容性层,因此您不必担心笔记本行为在不同计算机和操作系统上的可重复性。
为了支持协作工作流程,我们构建了一个非常简单的服务器,用于保存和共享笔记本。在iodide.io 上有一个公共实例,您可以在其中尝试使用 Iodide 并公开共享您的工作。还可以将自己的实例设置在防火墙后面(实际上,我们在 Mozilla 的某些内部工作中已经这样做了)。但重要的是,笔记本本身并不与 Iodide 服务器的单个实例深度绑定。如果需要,应该很容易将您的工作迁移到另一个服务器,或者将您的笔记本导出为捆绑包,以在其他服务(如 Netlify 或 Github Pages)上共享(有关导出捆绑包的更多信息,请参见下面的“下一步?”)。将计算保留在客户端使我们能够专注于构建一个非常棒的共享和协作环境,而无需在云中构建计算资源。
Pyodide:浏览器中的 Python 科学堆栈
当我们开始思考如何让网络对科学家更友善时,我们专注于如何让 Javascript 更易于使用,例如将现有的科学库编译为 WebAssembly 并将其封装在易于使用的 JS API 中。当我们将此建议提交给Mozilla 的 WebAssembly 专家时,他们提出了一个更大胆的想法:如果许多科学家更喜欢 Python,那就去他们喜欢的地方,将 Python 科学堆栈编译成在 WebAssembly 中运行。
我们认为这听起来很吓人——这将是一个巨大的项目,并且永远无法提供令人满意的性能……但两个星期后Mike Droettboom 就已经实现了在 Iodide 笔记本中运行 Python 的工作实现。在接下来的几个月里,我们添加了 Numpy、Pandas 和 Matplotlib,它们是迄今为止 Python 科学生态系统中使用最广泛的模块。在Nexedi 的贡献者 Kirill Smelkov 和 Roman Yurchak 的帮助下,我们实现了对 Scipy 和 scikit-learn 的支持。从那时起,我们一直在逐步添加其他库。
在 Javascript 虚拟机中运行 Python 解释器会带来性能损失,但这种损失实际上非常小——在我们的基准测试中,比 Firefox 上的原生性能慢约 1x-12x,比 Chrome 上的原生性能慢约 1x-16x。经验表明,这对互动探索来说非常有用。

在浏览器中运行 Matplotlib 使其互动功能成为可能,而这些功能在静态环境中是不可用的
将 Python 引入浏览器创造了一些神奇的工作流程。例如,您可以在 Python 中导入和清理数据,然后从 Javascript 中访问生成的 Python 对象(在大多数情况下,转换会自动进行),以便可以使用 JS 库(如d3)显示它们。更神奇的是,您可以从 Python 代码访问浏览器 API,使您能够执行诸如无需接触 Javascript 即可操作 DOM之类的操作。
当然,关于Pyodide 的内容还有很多,它值得单独撰写一篇文章——我们将在下个月的后续文章中详细介绍。
JSMD(JavaScript MarkDown)
就像在 Jupyter 和 R 的 R-Markdown 模式中一样,在 Iodide 中,您可以根据需要交织代码和文档,将您的代码分成“代码块”,您可以修改并将其作为独立的单元运行。我们对此想法的实现与 R Markdown 和 MATLAB 的“单元模式”相似:我们不是使用显式的基于单元的界面,而是 Iodide 笔记本的内容只是一个文本文档,它使用特殊的语法来区分特定类型的单元。我们称这种文本格式为“JSMD”。
遵循 MATLAB 的做法,代码块由以%%
开头的行定义,后面跟着一个字符串,指示下面代码块的语言。我们目前支持包含 Javascript、CSS、Markdown(和 HTML)、Python、一个用于简化资源加载的特殊“fetch”代码块以及一个插件代码块,该代码块允许您通过添加新的单元类型来扩展 Iodide 的功能。
我们发现这种格式非常方便。它可以轻松地使用文本导向工具,例如 diff 查看器和您喜欢的文本编辑器,并且您可以在不学习单元管理快捷键的情况下执行标准文本操作,如剪切/复制/粘贴。有关更多详细信息,您可以在我们的文档中阅读有关 JSMD 的内容。
下一步?
值得重复的是,我们仍处于 alpha 阶段,因此我们将继续改进整体抛光和消除错误。但除此之外,我们还考虑了一些功能,准备在下一次实验中进行尝试。如果这些想法中有任何特别有用,请告诉我们!更重要的是,如果您想帮助我们构建它们,请告诉我们!
增强的协作功能
如上所述,到目前为止,我们已经构建了一个非常简单的后端,允许您在线保存您的工作,查看其他人完成的工作,以及快速分叉和扩展其他用户创建的现有笔记本,但这仅仅是有效协作工作流程的初始步骤。
我们正在考虑添加的下一个三个主要协作功能是
- 类似 Google Docs 的评论线程
- 通过类似于 Github pull 请求的分叉/合并工作流程,向其他用户的笔记本建议更改的功能
- 像 Google Docs 一样的同步笔记本编辑。
目前,我们的大致优先顺序是按此顺序,但如果您想以不同的顺序进行处理,或者您有其他建议,请告诉我们!
更多语言!
我们已经与来自 R 和 Julia 社区的人员讨论了将这些语言编译为 WebAssembly,这将使它们能够在 Iodide 和其他基于浏览器的项目中使用。我们初步调查表明,这应该是可行的,但实现这些语言可能比 Python 更具挑战性。与 Python 一样,如果能够,例如,在 R 中拟合统计模型,或者在 Julia 中求解微分方程,然后使用浏览器 API 显示结果,那么一些酷炫的工作流程就会出现。如果您对将这些语言带到网络感兴趣,请联系我们——特别是,我们希望获得 FORTRAN 和 LLVM 专家的大力支持。
导出笔记本存档
碘化物的早期版本是自包含的可运行 HTML 文件,其中包含分析中使用的 JSMD 代码和运行碘化物本身的 JS 代码,但我们已经从这种架构中移除了。后来的实验使我们确信,拥有碘化物服务器的协作优势 outweighs 在本地系统上管理文件的优势。尽管如此,这些实验表明我们可以通过将碘化物代码与笔记本使用的任何数据和库一起嵌入到一个大的 HTML 文件中,来获取可运行的碘化物笔记本快照。这可能最终会比你希望为普通用户提供的文件更大,但它可以证明对分析的完全可重复和可存档的快照很有用。
碘化物到文本编辑器浏览器扩展
虽然许多科学家已经习惯了在基于浏览器的编程环境中工作,但我们知道有些人永远不会在他们最喜欢的文本编辑器之外编辑代码。我们真的希望碘化物能满足人们的现有需求,包括那些喜欢在其他编辑器中键入代码但想要使用碘化物提供的交互式和迭代功能的人。为了满足这一需求,我们开始考虑创建一个轻量级浏览器扩展和一些简单的 API,让碘化物与客户端编辑器对话。
欢迎反馈和协作!
我们并没有试图解决数据科学和科学计算的所有问题,我们知道碘化物不会是每个人的最爱。如果你需要在 GPU 集群上处理 TB 级数据,碘化物可能无法提供太多帮助。如果你正在发表期刊文章,你只需要撰写一个 LaTeX 文档,那么有更适合你需求的工具。如果将所有事物都引入浏览器这一趋势让你有点反感,没问题——还有很多很棒的工具可以用来做科学研究,我们对此表示感谢!我们不想改变任何人的工作方式,对许多科学家来说,以 Web 为中心的交流无关紧要。太棒了!享受你的精彩人生!
但是对于那些确实为 Web 制作内容的科学家,以及那些如果拥有为你的工作方式设计的工具,可能会这样做的人:我们非常希望收到你的反馈!
请访问 iodide.io,试用一下,并给我们反馈(但请记住:这个项目处于 alpha 阶段——请不要将其用于任何关键工作,并请注意,在 alpha 阶段,所有内容都可能发生变化)。你可以填写我们的快速调查,Github 问题和错误报告也非常受欢迎。功能请求和对总体方向的想法可以通过我们的Google 论坛或Gitter分享。
如果你想参与帮助我们构建碘化物,我们在 Github 上开源。碘化物涉及各种各样的软件学科,从现代前端开发到科学计算,再到编译和转译,因此有很多有趣的事情要做!如果有任何让你感兴趣的事情,请联系我们!
非常感谢 Hamilton Ulmer、 William Lachance 和 Mike Droettboom 对碘化物做出的杰出贡献,并感谢他们审阅了这篇文章。
18 条评论