MLOps - 烹飪書,第一章

MLOps - 烹飪書,第一章

大家好! 我是 CROC 的履歷開發人員。 我們在 CV 領域實施專案已有 3 年了。 這段時間我們做了很多事情,例如:對司機進行監控,讓他們開車時不喝酒、不抽煙、不打電話、看路、不看夢、不看雲。 ; 我們記錄了在專用車道上行駛並佔用多個停車位的人; 確保工人佩戴頭盔、手套等; 確定一名想要進入該設施的員工; 我們盡可能地計算了一切。

我做這一切是為了什麼?

在實施專案的過程中,我們遇到了坎坷,很多坎坷,有些問題不是你熟悉的,就是以後會熟悉的。

我們來模擬一下狀況

假設我們在一家年輕公司「N」找到了一份工作,該公司的活動與機器學習有關。 我們從事一個 ML(DL、CV)項目,然後由於某種原因我們切換到另一份工作,通常會休息一下,然後回到我們自己或其他人的神經元。

  1. 關鍵時刻到來了,您需要以某種方式記住您停止的位置、您嘗試過的超參數,以及最重要的是它們導致的結果。 對於誰儲存所有啟動的資訊可以有很多選擇:在頭中、配置中、記事本中、在雲端的工作環境中。 當超參數作為註解行儲存在程式碼中時,我碰巧看到了一個選項,一般來說,這是一種幻想。 現在想像一下,您不是返回到您的項目,而是返回到離開公司的人的項目,並且您繼承了一個代碼和一個名為 model_1.pb 的模型。 為了完成圖片並傳達所有痛苦,讓我們假設您也是初學者專家。
  2. 前進。 為了運行程式碼,我們和每個使用它的人都需要創建一個環境。 經常發生的情況是,由於某種原因,他們沒有把他作為我們的遺產留給我們。 這也可能變成一項不平凡的任務。 您不想在這一步上浪費時間,對嗎?
  3. 我們訓練一個模型(例如,汽車偵測器)。 我們已經到了非常好的地步——是時候保存結果了。 我們將其命名為 car_detection_v1.pb。 然後我們訓練另一個 - car_detection_v2.pb。 一段時間後,我們的同事或我們自己使用不同的架構來教導越來越多的內容。 結果,形成了一堆工件,必須煞費苦心地收集有關這些工件的資訊(但我們稍後會這樣做,因為現在我們有更多優先事項)。
  4. 好吧,現在一切都結束了! 我們有模型! 我們可以開始訓練下一個模型,發展一個架構來解決新問題,或者我們可以去喝杯茶嗎? 誰將部署?

發現問題

開發一個專案或產品是很多人的工作。 隨著時間的推移,人們離開又到來,專案越來越多,專案本身也變得更加複雜。 無論如何,上述循環中的情況(並且不僅如此)在某些組合中將在迭代之間發生。 所有這些都會導致時間浪費、混亂、緊張,甚至可能引起客戶不滿,並最終造成金錢損失。 儘管我們通常都遵循同樣的老套路,但我相信沒有人願意一遍又一遍地重溫這些時刻。

MLOps - 烹飪書,第一章

所以,我們經歷了一個開發週期,我們看到有一些問題需要解決。 為此,您需要:

  • 方便儲存工作結果;
  • 讓新進員工參與的過程變得簡單;
  • 簡化部署開發環境的流程;
  • 配置模型版本控制流程;
  • 有一種方便的方法來驗證模型;
  • 找到一個模型狀態管理工具;
  • 找到一種將模型交付生產的方法。

顯然有必要想出一個工作流程來讓您輕鬆方便地管理這個生命週期? 這種做法稱為 MLOps

MLOps(即機器學習的 DevOps)允許資料科學和 IT 團隊透過監視、驗證和治理機器學習模型來協作並加快模型開發和部署的步伐。

你是否可以 榮譽谷歌的人對這一切有何看法? 從文章中可以清楚地看出 MLOps 是一個相當龐大的東西。

MLOps - 烹飪書,第一章

在我的文章中,我將僅描述該過程的一部分。 為了實現,我將使用 MLflow 工具,因為... 這是一個開源項目,需要少量程式碼即可連接,並與流行的機器學習框架整合。 您可以在網路上搜尋其他工具,例如 Kubeflow、SageMaker、Trains 等,也許會找到更適合您需求的工具。

使用 MLFlow 工具的範例「建置」MLOps

MLFlow 是一個用於機器學習模型生命週期管理的開源平台(https://mlflow.org/).

MLflow 包括四個元件:

  • MLflow Tracking - 涵蓋記錄結果和導致此結果的參數的問題;
  • MLflow Project - 允許您打包程式碼並在任何平台上重現它;
  • MLflow Models - 負責將模型部署到生產中;
  • MLflow 註冊表 - 允許您在集中儲存庫中儲存模型並管理其狀態。

MLflow 在兩個實體上運作:

  • 啟動是我們想要註冊的訓練、參數和指標的完整週期;
  • 實驗是一個共同運作的「主題」。

範例的所有步驟均在Ubuntu 18.04作業系統上實現。

1.部署伺服器

為了使我們能夠輕鬆管理我們的專案並接收所有必要的信息,我們將部署一台伺服器。 MLflow 追蹤伺服器有兩個主要元件:

  • 後端儲存 - 負責儲存有關已註冊模型的資訊(支援 4 個 DBMS:mysql、mssql、sqlite 和 postgresql);
  • 工件儲存 - 負責儲存工件(支援 7 種儲存選項:Amazon S3、Azure Blob 儲存、Google 雲端儲存、FTP 伺服器、SFTP 伺服器、NFS、HDFS)。

由於 文物商店 為了簡單起見,我們以 sftp 伺服器為例。

  • 建立一個群組
    $ sudo groupadd sftpg
  • 新增一個用戶並為其設定密碼
    $ sudo useradd -g sftpg mlflowsftp
    $ sudo passwd mlflowsftp 
  • 調整一些訪問設定
    $ sudo mkdir -p /data/mlflowsftp/upload
    $ sudo chown -R root.sftpg /data/mlflowsftp
    $ sudo chown -R mlflowsftp.sftpg /data/mlflowsftp/upload
  • 新增幾行到 /etc/ssh/sshd_config
    Match Group sftpg
     ChrootDirectory /data/%u
     ForceCommand internal-sftp
  • 重新啟動服務
    $ sudo systemctl restart sshd

由於 後端商店 讓我們以 postgresql 為例。

$ sudo apt update
$ sudo apt-get install -y postgresql postgresql-contrib postgresql-server-dev-all
$ sudo apt install gcc
$ pip install psycopg2
$ sudo -u postgres -i
# Create new user: mlflow_user
[postgres@user_name~]$ createuser --interactive -P
Enter name of role to add: mlflow_user
Enter password for new role: mlflow
Enter it again: mlflow
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n
# Create database mlflow_bd owned by mlflow_user
$ createdb -O mlflow_user mlflow_db

要啟動伺服器,您需要安裝以下python套件(我建議建立一個單獨的虛擬環境):

pip install mlflow
pip install pysftp

讓我們啟動我們的伺服器

$ mlflow server  
                 --backend-store-uri postgresql://mlflow_user:mlflow@localhost/mlflow_db 
                 --default-artifact-root sftp://mlflowsftp:mlflow@sftp_host/upload  
                --host server_host 
                --port server_port

2.添加追蹤

為了讓我們訓練的成果不會失去,讓後代的開發者了解發生了什麼,也為了讓老同志和你們能夠冷靜地分析學習過程,我們需要添加追蹤。 追蹤意味著在伺服器上保存參數、指標、工件和有關訓練開始的任何其他資訊。

例如,我創建了一個小 github上的項目 在 Keras 上分割所有內容 COCO資料集。 為了添加跟踪,我創建了一個檔案 mlflow_training.py。

以下是最有趣的事情發生的幾行:

def run(self, epochs, lr, experiment_name):
        # getting the id of the experiment, creating an experiment in its absence
        remote_experiment_id = self.remote_server.get_experiment_id(name=experiment_name)
        # creating a "run" and getting its id
        remote_run_id = self.remote_server.get_run_id(remote_experiment_id)

        # indicate that we want to save the results on a remote server
        mlflow.set_tracking_uri(self.tracking_uri)
        mlflow.set_experiment(experiment_name)

        with mlflow.start_run(run_id=remote_run_id, nested=False):
            mlflow.keras.autolog()
            self.train_pipeline.train(lr=lr, epochs=epochs)

        try:
            self.log_tags_and_params(remote_run_id)
        except mlflow.exceptions.RestException as e:
            print(e)

這裡 self.remote_server 是 mlflow.tracking 方法的小包裝。 MlflowClient(我為了方便而創建它),在它的幫助下我創建了一個實驗並在伺服器上運行它。 接下來,我指示應在何處合併啟動結果 (mlflow.set_tracking_uri(self.tracking_uri))。 我啟用自動日誌記錄 mlflow.keras.autolog()。 目前 MLflow Tracking 支援 TensorFlow、Keras、Gluon XGBoost、LightGBM、Spark 的自動日誌記錄。 如果您還沒有找到您的框架或庫,那麼您始終可以明確記錄。 我們正在開始訓練。 在遠端伺服器上註冊標籤並輸入參數。

只需幾行程式碼,您就可以像其他人一樣存取有關所有發布的信息。 涼爽的?

3.我們制定項目

現在讓我們輕鬆啟動該專案。 為此,請將 MLproject 和 conda.yaml 檔案新增至專案根目錄。
機器學習項目

name: flow_segmentation
conda_env: conda.yaml

entry_points:
  main:
    parameters:
        categories: {help: 'list of categories from coco dataset'}
        epochs: {type: int, help: 'number of epochs in training'}

        lr: {type: float, default: 0.001, help: 'learning rate'}
        batch_size: {type: int, default: 8}
        model_name: {type: str, default: 'Unet', help: 'Unet, PSPNet, Linknet, FPN'}
        backbone_name: {type: str, default: 'resnet18', help: 'exampe resnet18, resnet50, mobilenetv2 ...'}

        tracking_uri: {type: str, help: 'the server address'}
        experiment_name: {type: str, default: 'My_experiment', help: 'remote and local experiment name'}
    command: "python mlflow_training.py 
            --epochs={epochs}
            --categories={categories}
            --lr={lr}
            --tracking_uri={tracking_uri}
            --model_name={model_name}
            --backbone_name={backbone_name}
            --batch_size={batch_size}
            --experiment_name={experiment_name}"

MLflow 項目有幾個屬性:

  • 名稱 - 您的項目名稱;
  • 環境 - 在我的例子中,conda_env表示使用Anaconda來運行,依賴描述在conda.yaml檔案中;
  • 入口點 - 指示我們可以執行哪些檔案和參數(開始訓練時會自動記錄所有參數)

conda.yaml

name: flow_segmentation
channels:
  - defaults
  - anaconda
dependencies:
  - python==3.7
  - pip:
    - mlflow==1.8.0
    - pysftp==0.2.9
    - Cython==0.29.19
    - numpy==1.18.4
    - pycocotools==2.0.0
    - requests==2.23.0
    - matplotlib==3.2.1
    - segmentation-models==1.0.1
    - Keras==2.3.1
    - imgaug==0.4.0
    - tqdm==4.46.0
    - tensorflow-gpu==1.14.0

您可以使用docker作為運行環境,更多詳細資訊請參考 文件.

4. 讓我們開始訓練吧

我們克隆專案並進入專案目錄:

git clone https://github.com/simbakot/mlflow_example.git
cd mlflow_example/

要運行您需要安裝庫

pip install mlflow
pip install pysftp

因為在我使用 conda_env 的範例中,您的電腦上必須安裝 Anaconda(但您可以透過自行安裝所有必要的軟體包並使用啟動參數來解決這個問題)。

所有的準備步驟都完成了,我們可以開始啟動訓練了。 從專案根目錄:

$ mlflow run -P epochs=10 -P categories=cat,dog -P tracking_uri=http://server_host:server_port .

輸入指令後,會自動建立conda環境並開始訓練。
在上面的例子中,我傳遞了訓練的紀元數,我們想要分割的類別(你可以看到完整的列表 這裡)和我們的遠端伺服器的位址。
可以在 MLproject 檔案中找到可能參數的完整清單。

5. 評量學習成果

完成訓練後,我們可以在瀏覽器中存取我們伺服器的位址 http://server_host:server_port

MLOps - 烹飪書,第一章

在這裡,我們看到所有實驗的清單(左上)以及運行資訊(中)。 我們可以查看每次啟動的更詳細資訊(參數、指標、工件和一些附加資訊)。

MLOps - 烹飪書,第一章

對於每個指標,我們可以觀察變化的歷史記錄

MLOps - 烹飪書,第一章

那些。 目前我們可以以「手動」模式分析結果,您也可以使用 MLflow API 設定自動驗證。

6. 註冊模型

在我們分析了我們的模型並確定它已準備好戰鬥後,我們繼續註冊它,為此我們選擇我們需要的發射(如上一段所示)並繼續下去。

MLOps - 烹飪書,第一章

當我們為模型命名後,它就有了一個版本。 如果您儲存了同名的另一個模型,版本將自動升級。

MLOps - 烹飪書,第一章

對於每個模型,我們可以新增描述並選擇三種狀態之一(暫存、生產、存檔);隨後,使用 API,我們可以存取這些狀態,這與版本控制一起提供了額外的靈活性。

MLOps - 烹飪書,第一章

我們還可以輕鬆存取所有型號

MLOps - 烹飪書,第一章

以及他們的版本

MLOps - 烹飪書,第一章

與上一段一樣,所有操作都可以使用 API 完成。

7. 部署模型

在這個階段,我們已經有了一個經過訓練的(keras)模型。 如何使用它的範例:

class SegmentationModel:
    def __init__(self, tracking_uri, model_name):

        self.registry = RemoteRegistry(tracking_uri=tracking_uri)
        self.model_name = model_name
        self.model = self.build_model(model_name)

    def get_latest_model(self, model_name):
        registered_models = self.registry.get_registered_model(model_name)
        last_model = self.registry.get_last_model(registered_models)
        local_path = self.registry.download_artifact(last_model.run_id, 'model', './')
        return local_path

    def build_model(self, model_name):
        local_path = self.get_latest_model(model_name)

        return mlflow.keras.load_model(local_path)

    def predict(self, image):
        image = self.preprocess(image)
        result = self.model.predict(image)
        return self.postprocess(result)

    def preprocess(self, image):
        image = cv2.resize(image, (256, 256))
        image = image / 255.
        image = np.expand_dims(image, 0)
        return image

    def postprocess(self, result):
        return result

為了方便起見,這裡 self.registry 再次是 mlflow.tracking.MlflowClient 的小包裝。 關鍵是我訪問遠端伺服器並在那裡查找具有指定名稱和最新生產版本的模型。 接下來,我將工件本地下載到 ./model 資料夾,並從此目錄 mlflow.keras.load_model(local_path) 建立模型。 現在我們可以使用我們的模型了。 CV(ML)開發人員可以輕鬆改進模型並發布新版本。

總之

我提出了一個系統,它允許:

  • 集中儲存有關機器學習模型、訓練進度和結果的資訊;
  • 快速部署開發環境;
  • 監控和分析模型工作的進展;
  • 方便模型的版本管理和狀態管理;
  • 部署產生的模型很容易。

這個例子是一個玩具,可以作為建立您自己的系統的起點,其中可能包括結果評估和模型註冊的自動化(分別為第5 點和第6 點),或者您將添加資料集的版本控制,或者可能是其他東西? 我想要表達的觀點是,你需要 MLOps 作為一個整體,MLflow 只是達到目的的手段。

寫下你遇到了什麼我沒有顯示的問題?
您會為系統添加什麼內容以滿足您的需求?
您使用什麼工具和方法來解決全部或部分問題?

PS我會留下幾個連結:
github專案- https://github.com/simbakot/mlflow_example
ML流- https://mlflow.org/
我的工作電子郵件用於提問 - [電子郵件保護]

我們公司定期為IT專家舉辦各種活動,例如:莫斯科時間8月19日00:XNUMX將舉辦線上履歷見面會,如果您有興趣,可以參加,報名 這裡 .

來源: www.habr.com

添加評論