譯者? | 朱先忠
審校 | 孫淑娟
簡介
ML模型生命周期開發每個階段的基本活動之一是協作。從ML模型的概念到部署,需要構建模型所涉及的不同角色之間的參與和交互。此外,ML模型開發的本質涉及實驗、工件(artifacts)和指標的跟蹤、模型版本管理等,所有這些都需要通過一種有效的組織來正確維護ML模型生命周期。
幸運的是,目前已經出現類似于MLflow這樣的開發和維護模型生命周期的工具。在本文中,我們將詳細剖析MLflow,包括其主要組件及特性等內容的分析。此外,我們還將提供示例來說明MLflow在實踐中是如何工作的。
什么是MLflow?
MLflow是一個開源工具,用于在ML模型生命周期的每個階段進行開發、維護和協作。此外,MLflow是一個與框架無關的工具;因此,任何ML/DL(機器學習/深度學習)框架都可以快速適應MLflow提出的生態系統。
MLflow是作為一個平臺的形式出現的,其中提供了跟蹤指標、工件和元數據等的一系列工具。此外,它還提供了打包、分發以及部署模型和項目等的標準格式支持。
MLflow還提供了管理模型版本的工具。這些工具分別封裝在下面四個主要組件中:
- MLflow跟蹤(Tracking)
- MLflow模型(Models)
- MLflow項目(Projects)
- MLflow注冊表(Registry)
MLflow跟蹤
MLflow跟蹤是一種基于API的工具,用于記錄指標、參數、模型版本、代碼版本和文件。MLflow跟蹤與一個UI集成到一起,用于可視化和管理工件、模型、文件等。
其中,每個MLflow跟蹤會話都是在運行(run)的概念下組織和管理的。運行是指代碼的執行;其中,工件日志部分是被顯式執行的。
MLflow跟蹤允許您通過MLflow提供的Python、R、Java等語言以及REST形式的API等方式來生成運行。默認情況下,運行是存儲在執行代碼會話的目錄中。然而,MLflow還允許在本地或遠程服務器上存儲工件。
MLflow模型
MLflow模型允許將機器學習模型打包成標準格式,以便通過REST API、Microsoft Azure ML、Amazon SageMaker或Apache Spark等不同服務直接使用。MLflow模型協定的優點之一是包裝是多語言或多風味(flavor)支持的。
[譯者注]MLflow中經常遇到“flavor”一詞,其主要是指對于多種語言、多種類型組件及庫的廣泛支持,通過下面展示的配置文件容易看出這一點。在此,本文統一直接翻譯為“風味”。
在打包方面,MLflow生成一個包含兩個文件的目錄,一個是模型,另一個是指定模型打包和加載細節的文件。例如,下面的代碼片段顯示了一個MLmodel文件的內容,其中指定了風味加載器(flavor loader)以及定義環境的“conda.yaml”文件。
artifact_path: model
flavors:
python_function:
env: conda.yaml
loader_module: MLflow.sklearn
model_path: model.pkl
python_version: 3.8.2
sklearn:
pickled_model: model.pkl
serialization_format: cloudpickle
sklearn_version: 0.24.2
run_id: 39c46969dc7b4154b8408a8f5d0a97e9
utc_time_created: '2021-05-29 23:24:21.753565'
MLflow項目
MLflow項目提供了打包、共享和重用機器學習項目的標準格式。每個項目可以是遠程存儲庫或本地目錄。與MLflow模型不同,MLflow項目旨在實現機器學習項目的可移植性和分布性。
MLflow項目由名為“MLProject”的一個YAML聲明文件來定義,其中公開了相應項目的一系列規范內容。
模型實現的關鍵特征在MLProject文件中指定,這些特征包括:
- 模型接收的輸入參數
- 參數的數據類型
- 用于執行所述模型的命令,以及
- 項目運行的環境
下面的代碼片段顯示了一個MLProject文件的示例,其中要實現的模型是一棵決策樹形式,其唯一的參數對應樹的深度,默認值為2。
name: example-decision-tree
conda_env: conda.yaml
entry_points:
main:
parameters:
tree_depth: {type: int, default: 2}
command: "python main.py {tree_depth}"
同樣,MLflow提供了一個CLI(command-lineinterface,命令行界面)來運行位于本地服務器或遠程存儲庫上的項目。以下代碼片段顯示了如何從本地服務器或遠程存儲庫運行項目的示例:
$ mlflow run model/example-decision-tree -P tree_depth=3
$ mlflow run git@github.com:FernandoLpz/MLflow-example.git -P tree_depth=3
在這兩個示例中,環境是基于MLProject文件規范生成的。觸發模型的命令將在命令行上傳遞的參數下執行。由于模型允許輸入參數,因此這些參數可以通過`-P'標志指定。在這兩個示例中,模型參數都是指決策樹的最大深度。
默認情況下,如示例中所示的運行將把工件存儲在一個名字為“.mlruns”的目錄。
如何在MLflow服務器中存儲工件?
實現MLflow時最常見的用例之一是使用MLflow服務器記錄指標和工件。MLflow服務器負責管理MLflow客戶端生成的工件和文件。這些工件可以存儲在從文件目錄到遠程數據庫等不同存儲形式的方案中。例如,要在本地運行MLflow服務器,我們可以鍵入如下命令:
$ mlflow server
上述命令將通過IP地址http://127.0.0.1:5000/啟動MLflow服務。為了存儲工件和指標,在客戶端會話中定義服務器的跟蹤URI。
在下面的代碼片段中,我們將看到MLflow服務器中工件存儲的基本實現:
import MLflow
remote_server_uri = "http://127.0.0.1:5000"
MLflow.set_tracking_uri(remote_server_uri)
with MLflow.start_run():
MLflow.log_param("test-param", 1)
MLflow.log_metric("test-metric", 2)
其中,命令“MLflow.set_tracking_uri()”負責設置服務器的位置。
如何在MLflow服務器中執行身份驗證?
在沒有身份驗證的情況下暴露服務器可能會有風險。因此,添加身份驗證非常必要,當然也非常方便。身份驗證將取決于您將在其中部署服務器的生態系統:
- 在本地服務器上,添加基于用戶和密碼的基本身份驗證就足夠了
- 在遠程服務器上,必須與相應的代理一起調整憑據數據
為了說明這些,讓我們看一個使用基本身份驗證(用戶名和密碼)部署的MLflow服務器的示例。此外,我們還將看到如何通過配置客戶端方式來使用此服務器。
示例:MLflow服務器身份驗證
在本例中,我們通過Nginx反向代理將基本用戶和密碼身份驗證應用于MLflow服務器。
讓我們從Nginx的安裝開始,我們可以通過以下方式完成:
# For darwin based OS
$ brew install nginx
# For debian based OS
$ apt-get install nginx
# For redhat based OS
$ yum install nginx
對于Windows操作系統,您必須使用本機Win32 API。您可以按照鏈接(https://nginx.org/en/docs/windows.html)處的詳細說明進行這些操作,在此省略有關介紹。
安裝結束后,我們將繼續使用“htpasswd”命令生成具有相應密碼的用戶,如下所示:
sudo htpasswd -c /usr/local/etc/nginx/.htpasswdMLflow-user
上述命令為nginx服務的“.htpasswd”文件中指定的名字為“mlflow-user”的用戶生成憑據。稍后,要在創建的用戶憑據下定義代理,請使用配置文件“/usr/local/etc/nginx/nginx.conf”進行定義,默認情況下具有以下內容:
server {
listen 8080;
server_name localhost;
# charset koi8-r;
# access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
它必須看起來像這樣:
server {
# listen 8080;
# server_name localhost;
# charset koi8-r;
# access_log logs/host.access.log main;
location / {
proxy_pass http://localhost:5000;
auth_basic "Restricted Content";
auth_basic_user_file /usr/local/etc/nginx/.htpasswd;
}
在這里,我們通過端口5000為本地主機定義身份驗證代理。這是默認情況下部署MLflow服務器的IP地址和端口號。請注意,在使用云端類型的提供程序時,您必須配置實現所需的憑據和代理。接下來,開始初始化MLflow服務器,如以下代碼段所示:
$ MLflow server --host localhost
嘗試在瀏覽器中訪問http://localhost時,需要通過創建的用戶名和密碼請求身份驗證。
圖1:登錄界面
輸入憑據后,您將被導航到MLflow服務器用戶界面中,如圖2所示。
圖2:MLflow服務器UI
要從客戶端將數據存儲在MLflow服務器中,您必須:
- 定義包含訪問服務器的憑據的環境變量
- 設置存儲工件的URI
對于憑證,我們將導出以下環境變量:
$ export MLflow_TRACKING_USERNAME=MLflow-user
$ export MLflow_TRACKING_PASSWORD=MLflow-password
一旦定義了環境變量,就只需要為工件存儲定義服務器URI。
import MLflow
# Define MLflow Server URI
remote_server_uri = "http://localhost"
MLflow.set_tracking_uri(remote_server_uri)
with MLflow.start_run():
MLflow.log_param("test-param", 2332)
MLflow.log_metric("test-metric", 1144)
當執行上面的代碼片段時,我們可以看到測試指標和參數反映在服務器上。
圖3:從服務器上具有身份驗證的客戶端服務存儲的指標和參數
如何注冊MLflow模型?
開發機器學習模型時的一個日常需求是維護模型版本中的順序。為此,MLflow提供了MLflow注冊表。
MLflow注冊表是一個擴展,有助于:
- 管理每個MLModel的版本,以及
- 記錄每個模型在三個不同階段的發展進程:歸檔(archive)、模擬環境(staging)和生產(production)。它非常類似于Git中的版本系統。
注冊模型有四種選擇:
- 通過UI
- 作為“MLflow.<flavor>.log_model()”的參數方式
- 使用“MLflow.register_model()”方法或
- 使用“create_registered_model()”客戶端API。
在以下示例中,使用“MLflow.<flavor>.log_model()”方法注冊模型:
with MLflow.start_run():
model = DecisionTreeModel(max_depth=max_depth)
model.load_data()
model.train()
model.evaluate()
MLflow.log_param("tree_depth", max_depth)
MLflow.log_metric("precision", model.precision)
MLflow.log_metric("recall", model.recall)
MLflow.log_metric("accuracy", model.accuracy)
# Register the model
MLflow.sklearn.log_model(model.tree, "MyModel-dt", registered_model_name="Decision Tree")
如果是新模型,MLFlow將其初始化為版本1。如果模型已進行版本控制,則將其初始化成版本2(或后續版本)。
默認情況下,注冊模型時,分配的狀態為“無”。要將狀態分配給已注冊模型,我們可以通過以下方式執行:
client = MLflowClient()
client.transition_model_version_stage(
name="Decision Tree",
version=2,
stage="Staging"
)
在上面的代碼片段中,決策樹模型的版本2被分配給模擬環境(staging)。在服務器UI中,我們可以看到如圖4所示的狀態:
圖4:注冊模型
為了實現模型服務,我們可以使用MLflowCLI。為此,我們只需要服務器URI、模型名稱和模型狀態這些信息即可,如下所示:
$ export MLflow_TRACKING_URI=http://localhost
$ mlflow models serve -m "models:/MyModel-dt/Production"
模型服務和POST請求
$ curl http://localhost/invocations -H 'Content-Type: application/json' -d '{"inputs": [[0.39797844703998664, 0.6739875109527594, 0.9455601866618499, 0.8668404460733665, 0.1589125298570211]}'
[1]%
在上面的代碼片段中,向模型提供服務的地址發出POST請求。在請求中傳遞了一個包含五個元素的數組,這是模型期望作為推理的輸入數據。在這種情況下,預測結果是1。
需要指出的是,MLFlow允許定義數據結構,以便通過實現簽名在“MLmodel”文件中進行推斷。同樣,通過請求傳遞的數據可以是不同類型的,可以在鏈接(https://www.mlflow.org/docs/latest/_modules/mlflow/models/signature.html)處查閱。
前面示例的完整實現可以在下面的鏈接處找到:
https://github.com/FernandoLpz/MLFlow-example
MLflow插件
由于MLflow的框架不可知性,導致了MLflow插件的出現。該插件的主要功能是以自適應方式將MLflow的功能擴展到不同的框架。
MLflow插件允許為特定平臺定制和調整工件的部署和存儲。
例如,下面這些是用于平臺特定部署的插件:
- MLflow-redisai:它允許從MLflow中創建和管理的模型創建部署到RedisAI(https://oss.redislabs.com/redisai/)
- MLflow-torchserve:使PyTorch模型能夠直接部署到torchserve(https://github.com/pytorch/serve)
- MLflow-algorithmia:允許將使用MLflow創建和管理的模型部署到Algorithmia(https://algorithmia.com/)基礎設施
- MLflow-ray-serve:支持將MLflow模型部署到Ray(https://docs.ray.io/en/master/serve/)基礎設施上
另一方面,為了管理MLflow項目,我們還提供了MLflow-yarn,這是一個在Hadoop/Yarn支持下管理MLProject的插件。對于MLflow跟蹤的定制,我們有MLflow-elasticsearchstore,它允許在Elasticsearch環境下管理MLflow追蹤擴展。
同樣,也提供了特定的插件以支持部署到AWS和Azure等平臺,它們是:
- MLflow.sagemaker和
- MLflow.azureml
必須提到的是,MLflow提供了根據需要創建和定制插件的能力。
MLflow與Kubeflow的比較
由于對開發和維護機器學習模型生命周期的工具的需求不斷增加,出現了不同的管理方案,例如MLflow和KubeFlow等。
正如我們在本文中已經看到的,MLflow是一種工具,它允許在開發機器學習模型的生命周期中進行協作,主要關注跟蹤工件(MLflow跟蹤)、協作、維護和項目版本控制。
另一方面,還有一個類似的工具是Kubeflow,它與MLflow一樣,是一種開發具有特定差異的機器學習模型的工具。
Kubeflow是一個在Kubernetes集群上工作的平臺;也就是說,Kubeflow利用了Kubernetes的集裝箱化特性。此外,Kubeflow還提供了Kubeflow管道線等工具,旨在通過SDK擴展生成和自動化管道(DAGs)。
此外,Kubeflow還提供??Katib??,這是一種大規模優化超參數的工具,并提供Jupyter筆記本的管理和協作服務。
具體而言,MLflow是一個專注于機器學習項目開發的管理和協作工具。另一方面,Kubeflow是一個專注于通過Kubernetes集群和使用容器開發、訓練和部署模型的平臺。
這兩個平臺都具有各自顯著的優勢,都是開發、維護和部署機器學習模型的可選擇方案。然而,在開發團隊中使用、實現和集成這些技術時,必須考慮相應的技術壁壘。
由于Kubeflow需要連接到Kubernetes集群才能達到實現和集成目的,因此建議由一名專家來管理該技術。同樣,開發和配置管道自動化也是一項挑戰,需要學習曲線,在特定情況下可能對公司不利。
總之,MLflow和Kubeflow都是專注于機器學習模型生命周期特定階段的平臺。MLflow是一種面向協作的工具,而Kubeflow更傾向于利用Kubernetes集群來生成機器學習任務。然而,Kubeflow需要MLOps部分的經驗。您需要了解Kubernetes中的服務部署,這可能是嘗試接近Kubeflow時需要考慮的問題。
譯者介紹
朱先忠,51CTO社區編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。早期專注各種微軟技術(編著成ASP.NET AJX、Cocos 2d-X相關三本技術圖書),近十多年投身于開源世界(熟悉流行全棧Web開發技術),了解基于OneNet/AliOS+Arduino/ESP32/樹莓派等物聯網開發技術與Scala+Hadoop+Spark+Flink等大數據開發技術。
原文標題:??How toPackage and Distribute Machine Learning Models with MLFlow???,作者:Fernando López?