作者 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 語言編寫的。
大規模部署模型不同於編寫調用 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:
我們希望 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