爲何我們用 Go 而非 Python 來部署機器學習模型?

作者 Caleb Kaiser 此前曾撰寫過《爲何我們用 Go 而非 Python 編寫機器學習基礎設施平臺?》,InfoQ 中文站曾經翻譯並分享。今天,我們帶來了作者的新作《爲何我們用 Go 而非 Python 來部署機器學習模型》,在這篇文章中,Cortex Labs 介紹了團隊爲何用 Go 而非 Python 部署機器學習模型。

本文最初發表在 Towards Data Science,經原作者 Caleb Kaiser 授權,InfoQ 中文站翻譯並分享。

Python 是當下最流行的機器學習語言,對這一點大家應該沒有什麼異議。不過很多機器學習框架進行實際計算使用的是 CUDA C/C++ 等語言,只是它們都提供了 Python 接口。因此,大多數機器學習從業者都是直接使用 Python 工作的。

我們的機器學習基礎設施 Cortex 也是如此,它 88.3% 的代碼是由 Go 語言編寫的。

來源:Cortex GitHub

大規模部署模型不同於編寫調用 PyTorch 和 TensorFlow 函數的 Python 腳本。要實際大規模地運行一個生產機器學習 API,我們需要基礎設施來做如下事情:

  • 自動伸縮:這樣流量波動發生時就不會中斷我們的 API(且我們的 AWS 仍然保持可控)。
  • API 管理:處理多個部署。
  • 滾動更新:這樣我們就可以在更新模型的同時還可以爲請求提供服務。

我們構建了 Cortex 來提供這一功能。我們之所以決定用 Go 語言來編寫,是出於以下幾個原因:

1.Go 語言已爲基礎設施社區所接受

就背景而言,我們是軟件工程師,而不是數據科學家。我們進入機器學習領域是因爲我們想構建像 Gmail 的 Smart Compose 這樣的功能,而不是因爲我們對反向傳播着迷(儘管它確實很酷)。我們想要這樣的一個簡單工具,它將採用經過訓練的模型,並自動實現所需的所有基礎設施功能,如可複製的部署、可擴展的請求處理、自動監控等,以便將其部署爲 API。

雖然這種從模型到微服務的一體化平臺還不存在,但我們之前已經在普通軟件中實現了這些功能。我們知道什麼樣的工具適合這項工作,並且還知道它們是用什麼語言編寫的。

構建 Kubernetes、Docker 和 Terraform 等工具的團隊使用 Go 語言是有原因的。Go 語言的速度很快,能很好地處理併發,可以編譯成單一的二進制文件。這樣一來,選擇 Go 語言對我們來說,風險相對較低。其他團隊已經用 Go 語言解決了類似的挑戰。

此外,對於基礎設施工程師來說,使用 Go 語言編寫更容易做出貢獻,因爲他們可能已經熟悉了這門語言。

2. Go 語言解決了與併發性和調度相關的問題

管理一個部署需要許多服務同時運行,並按照精確的時間表進行。值得慶幸的是,Gorountine、channel(通道)和 Go 內置的 timer 和 ticker 爲併發性和調度提供了一個優雅的解決方案。

在較高的級別上,Goroutine 是指 Go 語言通過在一個虛擬獨立線程上執行一個原本正常的函數,使其併發運行。一個操作系統線程可以容納多個 Goroutine。channel 允許 Goroutine 共享數據,而 timer 和 ticker 允許我們調度 Goroutine。

我們在需要的時候使用 Goroutine 來實現併發性,比如 Cortex 需要將多個文件上傳到 S3,並行運行這些文件可以節省時間;或者是爲了保持一個潛在的、長期運行的功能,比如 CloudWatch 的流日誌,以免阻塞主線程。

此外,我們在 Goroutine 中使用 timer 和 ticker 來運行 Cortex 的 autoscaler。我已經寫過一份關於如何在 Cortex 中實現副本級自動擴展的的完整版報告,該報告的中心思想是,Cortex 計算排隊和進行中的請求數量,計算每個副本應該處理多少併發請求,並進行適當的擴展。

爲了做到這一點,Cortex 的監控功能需要以一致的時間間隔執行。Go 的調度器確保在應該進行監視的時候進行監視,而 Goroutine 允許每個監視函數併發地、獨立地執行每個 API。

要在 Python 中實現所有這些功能,也許可以使用 asyncio 這樣的工具來實現,但 Go 讓它變得如此簡單,這對我們來說不啻爲一個福音。

3. 在 Go 中構建跨平臺 CLI 更容易

我們的 CLI 部署模型並管理 API:

來源:Cortex GitHub

我們希望 CLI 在 Linux 和 Mac 上都可以用。最初,我們嘗試用 Python 語言來編寫 CLI,但用戶一直很難讓它在不同的環境中使用。當我們在 Go 中重新構建 CLI 時,能夠將它編譯成單一的二進制文件,這樣一來,我們就可以跨平臺分發 CLI,而不需要做太多額外的工程計劃。

編譯後的 Go 二進制代碼與解釋性編程語言相比,性能上的優勢也很明顯。根據計算機基準測試的結果來看,Go 的速度明顯比 Python 要快得多

無獨有偶,許多其他基礎設施的 CLI,如 eksctl、kops 和 Helm 客戶端等,都是用 Go 語言編寫的。

4. Go 有助於構建可靠的基礎設施

最後一點,Go 有助於 Cortex 最重要的特性:可靠性。

在所有軟件中,可靠性顯然很重要,但對於推理基礎設施來說,可靠性絕對是最關鍵的。Cortex 中的一個 bug 可能會讓推理費用嚴重增加。如果存在嚴重的 bug,那麼很有可能在編譯過程中被發現。對於一個小團隊來說,這是非常有用的。

與 Python 相比,Go 的高冷性質可能會使得它上手變得更痛苦一些,但這些內部的“防護欄”爲我們提供了第一道防線,幫助我們避免犯下愚蠢的類型錯誤。

小結:Python 用於腳本,Go 用於基礎設施

我們仍然喜歡 Python,它在 Cortex 中佔有一席之地,特別是在模型推理方面。

Cortex 支持 Python 作爲模型服務腳本。我們編寫 Python,將模型加載到內存中,進行推理前後處理,併爲請求提供服務。然而,即使是 Python 代碼也被打包到 Docker 容器中,這些容器也是由 Go 語言編寫的代碼進行編排的。

對於數據科學和機器學習工程來說,Python 將(並且應該)仍然是最流行的語言。但是,當涉及到機器學習基礎設施時,我們對 Go 很滿意。

作者介紹:

Caleb Kaiser,Cortex Lab 創始團隊成員,曾在 AngelList 工作,最初在 Cadillac 供職。

原文鏈接:

https://towardsdatascience.com/why-we-deploy-machine-learning-models-with-go-not-python-a4e35ec16deb

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章