做者:George Novack翻譯:Bach(才雲)python
校對:星空下的文仔(才雲)、bot(才雲)git
K8sMeetupgithub
爲何要使用機器學習流水線框架
如今,機器學習流水線(Machine Learning Pipeline)被你們給予了極大的關注,它旨在自動化和協調訓練機器學習模型所涉及的各個步驟,可是,不少人也不清楚將機器學習工做流程建模爲自動流水線到底有什麼好處。機器學習
當訓練新的 ML 模型時,大多數據科學家和 ML 工程師會開發一些新的 Python 腳本或 interactive notebook,以進行數據提取和預處理,來構建用於訓練模型的數據集;而後建立幾個其餘腳本或 notebook 來嘗試不一樣類型的模型或機器學習框架;最後收集、調試指標,評估每一個模型在測試數據集上的運行狀況,來肯定要部署到生產中的模型。模塊化
手動機器學習工做流程函數
顯然,這是對真正機器學習工做流程的過分簡化,並且這種通用方法須要大量的人工參與,而且除了最初開發該方法的工程師以外,其餘人都沒法輕易重複使用。工具
由此,咱們使用機器學習流水線來解決這些問題。與其將數據準備、模型訓練、模型驗證和模型部署視爲特定模型中的單一代碼庫,不如將其視爲一系列獨立的模塊化步驟,讓每一個步驟都專一於具體任務。學習
機器學習流水線測試
將機器學習工做流程建模爲機器學習流水線有不少好處:
K8sMeetup
什麼是 Kubeflow
Kubeflow 是一個基於 Kubernetes 的開源平臺,旨在簡化機器學習系統的開發和部署。Kubeflow 在官方文檔中被稱爲 「Kubernetes 機器學習工具包」,它由幾個組件(component)組成,這些組件跨越了機器學習開發生命週期的各個步驟,包括了 notebook developent environment、超參數調試、功能管理、模型服務以及 ML Pipelines。
Kubeflow 中央儀表板
在本文中,咱們只關注 Kubeflow 的 Pipelines 組件。
K8sMeetup
環境
本文選擇在裸機上運行的 Kubernetes 集羣,但實際上咱們能夠在安裝 Kubeflow 的任何 Kubernetes 集羣上運行示例代碼。
本地惟一須要的依賴項是 Kubeflow Pipelines SDK,咱們可使用 pip 安裝 SDK:pip install kfp 。
K8sMeetup
Kubeflow Pipelines
Kubeflow 中的流水線由一個或多個組件(component)組成,它們表明流水線中的各個步驟。每一個組件都在其本身的 Docker 容器中運行,這意味着流水線中的每一個步驟都具備本身的一組依賴關係,與其餘組件無關。
對於開發的每一個組件,咱們建立一個單獨的 Docker 鏡像,該鏡像會接收輸入、執行操做、進行輸出。另外,咱們要有一個單獨的 Python 腳本,pipeline.py 腳本會從每一個 Docker 鏡像建立 Pipelines 組件,而後使用這些組件構造流水線(Pipeline)。咱們總共建立四個組件:
sklearn.datasets
中加載 Boston Housing
數據集,而後將其拆分爲訓練集和測試集。
ML 流水線視圖
K8sMeetup
Preprocess Data 組件
第一個 Pipelines 組件用 sklearn.datasets
加載 Boston Housing
數據集。咱們使用 Sci-kit Learn
的 train_test_split
函數將此數據集分爲訓練集和測試集,而後用 np.save
將數據集保存到磁盤,以便之後的組件重複使用。
到目前爲止,咱們只有一個簡單的 Python 腳本。如今,咱們須要建立一個執行該腳本的 Docker 鏡像,這裏編寫一個 Dockerfile 來建立鏡像:
從 python:3.7-slim
基礎鏡像開始,咱們使用 pip
安裝必需的軟件包,將預處理的 Python 腳本從本地計算機複製到容器,而後將 preprocess.py
腳本指定爲容器 Entrypoint,這樣在容器啓動時,腳本就會執行。
K8sMeetup
構建流水線
如今,咱們着手構建流水線,首先要確保能夠從 Kubernetes 集羣訪問上文構建的 Docker 鏡像。本文使用 GitHub Actions 構建鏡像並將其推送到 Docker Hub。
如今定義一個組件,每一個組件都要定義爲一個返回 ContainerOp 類型的對象(object)。此類型來自咱們先前安裝的 kfp
SDK。這是流水線中第一個組件的組件定義:
請注意,對於 image
參數,咱們傳遞了上文 Dockerfile 定義的 Docker 鏡像的名稱,對於 file_outputs
參數,指定了 Python 腳本組件保存到磁盤的四個 .npy
文件的文件路徑。經過將這四個文件指定爲「File Output」,咱們能夠將它們用於流水線中的其餘組件。
注意:在組件中對文件路徑進行硬編碼不是一個很好的作法,就如上面的代碼中那樣,這要求建立組件定義的人員要了解有關組件實現的特定細節。這會讓組件接受文件路徑做爲命令行參數更加乾淨,定義組件的人員也能夠徹底控制輸出文件的位置。
定義了第一個組件後,咱們建立一個使用 preprocess-data 組件的流水線:
流水線由一個註解 @dsl.pipeline
修飾的 Python 函數定義。在函數內,咱們能夠像使用其餘任何函數同樣使用組件。爲了運行流水線,咱們建立一個 kfp.Client
對象,再調用 create_run_from_pipeline_func
函數,並傳入定義流水線的函數。
若是執行該腳本,而後導航到 Kubeflow 中央儀表板流水線部分的「Experiment」視圖,咱們就能看到流水線的執行狀況。在流水線的圖形視圖中單擊該組件,咱們還能夠看到來自 preprocess-data 組件的四個文件輸出。
Kubeflow 流水線用戶界面
所以,咱們能夠運行流水線並在 GUI 中進行可視化,可是隻有一個步驟的流水線並沒什麼意思,下面咱們來建立其他的組件。
K8sMeetup
其他組件
對於 train-model
組件,咱們建立一個簡單的 Python 腳本,該腳本使用 Sci-kit Learn 來訓練迴歸模型。這相似於預處理器組件的 Python 腳本,其中最大的區別是,這裏用 argparse
來接受訓練數據的文件路徑以做爲命令行參數。
這個 Dockerfile 與咱們用於第一個組件的很是類似,從基礎鏡像開始,安裝必要的軟件包,將 Python 腳本複製到容器中,而後執行腳本。
其餘兩個組件 test-model 和 deploy-model 遵循着相同的模式。實際上,它們與咱們已經實現的兩個組件很是像,這裏就再也不贅述。若是你們有興趣,能夠在如下 GitHub 存儲庫中找到該流水線的全部代碼:https : //github.com/gnovack/kubeflow-pipelines
就像以前的 preprocess-data 組件同樣,咱們將從這三個組件中構建 Docker 鏡像並將其推送到 Docker Hub:
K8sMeetup
完整的流水線
如今是時候建立完整的機器學習流水線了。首先,咱們爲 train-model、test-model 和 deploy-model 組件建立組件定義。
該 train-model 組件的定義與以前的 preprocess-data 組件的定義之間的惟一主要區別是, train-model 接受兩個參數,x_train
和 y_train
,其將做爲命令行參數傳遞給容器並進行解析,這會在使用 argparse
模塊的組件實現中。
這裏 test-model 和 deploy-model 組件定義爲:
定義了四個 Pipelines 組件後,咱們如今從新訪問 boston_pipeline
函數,並將全部組件一塊兒使用。
這裏有幾點要注意:
preprocess_op()
函數時,將函數的輸出存儲在名爲 _preprocess_op
的變量中。要訪問 preprocess-data 組件的輸出,咱們使用 _preprocess_op.outputs['NAME_OF_OUTPUT']
。file_outputs
時,咱們獲取的是文件內容而不是文件路徑。在本文中,因爲這些不是純文本文件,所以咱們不能僅將文件內容做爲命令行參數傳遞到 Docker 容器組件中。要訪問文件路徑,咱們須要使用 dsl.InputArgumentPath()
並傳入組件輸出。如今,若是咱們運行建立的流水線並導航到 Kubeflow 中央儀表板中的「Pipelines UI」,咱們能夠看到流水線圖中顯示的全部四個組件。
K8sMeetup
結論
在本文中,咱們建立了一個很是簡單的機器學習流水線,該流水線能夠加載一些數據、訓練模型、在保留數據集上對其進行評估、對其進行「deploy」。經過使用 Kubeflow Pipelines,咱們可以將該工做流中的每一個步驟封裝到 Pipelines 組件中,每一個組件都在各自獨立的 Docker 容器環境中運行。這種封裝促進了機器學習工做流程中各步驟之間的鬆散耦合,併爲未來流水線中組件的重複使用提供了可能性。
本文簡單介紹了 Kubeflow Pipelines 的功能,但願可以幫助你們瞭解組件(component)的基礎知識,以及如何使用它們建立和運行流水線。