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 對該項目的未來非常看好,並且希望向社區學習。


分享到:


相關文章: