在機器學習專案中,維護一致的開發環境至關重要。本文將介紹如何結合 Docker 和 Batect 打造高效的機器學習開發流程,確保專案在不同環境下的可重複性,並簡化複雜的命令列操作。透過容器化技術,我們可以有效隔離不同任務的依賴關係,例如模型訓練、API 測試、Jupyter Notebook 等,避免版本衝突和環境設定的困擾。同時,Batect 工具的匯入能進一步簡化 Docker 命令,提升開發效率,並更容易地整合到 CI/CD 流程中,實作自動化構建、測試和佈署。
使用Docker建立一致的執行環境
無論您使用什麼樣的開發環境,Docker都可以幫助您快速建立一致的執行環境。這些環境可以佈署在各種目標環境中,例如雲端工作空間、內網計算例項、嵌入式裝置等,只要Docker執行時環境可用。
雲端機器學習服務通常支援Docker,並提供檔案詳細介紹如何在執行任務或工作時指定Docker映像,無論是公共映像還是自定義映像。
本章中Docker Desktop的使用
與其他容器執行時比較,Docker Desktop在本章中被用於個人使用和教育目的。根據Docker Desktop的授權協定,如果您是一個小型企業(少於250名員工,年收入少於1000萬美元)、個人使用、教育或非商業開源專案,則可以免費使用Docker Desktop。否則,需要購買付費訂閱以進行商業使用。
如果您想在商業環境中使用本章中的依賴管理設定,但沒有Docker許可證,您可以使用免費的Docker daemon,例如colima(適用於Mac和Linux作業系統)。您仍然可以與本章中介紹的所有概念進行互動,只是您將使用colima而不是Docker Engine或Docker Desktop。
要使用colima,您可以參考以下步驟:
- 安裝colima和docker-credential-helper:
brew install colima docker-credential-helper
- 確保Docker組態正確的憑證幫助器。編輯
~/.docker/config.json
並確保它包含以下內容:"credsStore": "osxkeychain"
- 啟動Docker daemon:
colima start
一旦您組態了colima作為Docker daemon,您就可以按照本章中的指導使用Docker建立一致的執行環境。
範例:使用Docker建立一致的執行環境
假設您有一個機器學習模型需要在雲端工作空間中執行,您可以使用Docker建立一致的執行環境。以下是步驟:
# 安裝Docker並組態環境
import os
import docker
# 建立Docker客戶端
client = docker.from_env()
# 下載公共Docker映像
image = client.images.pull("tensorflow/tensorflow:latest")
# 建立Docker容器
container = client.containers.run(image, detach=True)
# 將模型程式碼複製到容器中
client.containers.copy(container.id, "/app/model.py")
# 執行模型
container.exec_run("python /app/model.py")
這個範例展示瞭如何使用Docker建立一致的執行環境,包括下載公共Docker映像、建立Docker容器、複製模型程式碼到容器中和執行模型。
Mermaid圖表:Docker執行流程
graph LR A[下載Docker映像] --> B[建立Docker容器] B --> C[複製模型程式碼到容器] C --> D[執行模型] D --> E[模型執行結果]
圖表翻譯:Docker執行流程
這個Mermaid圖表展示了使用Docker建立一致的執行環境的流程,包括下載Docker映像、建立Docker容器、複製模型程式碼到容器中和執行模型。這個流程可以確保模型在不同的環境中執行一致。
減少Docker移動部分的複雜性
當專案變得更加複雜時,我們可能會遇到越來越多的Docker執行引數和命令列選項,例如卷掛載和要釋出的埠。這些組態引數通常需要在程式碼函式庫的多個地方進行維護。為了簡化這些移動部分,我們可以使用batect,一個命令列工具,允許我們定義開發任務及其相關的組態引數作為單一的真相來源,並將Docker容器執行為batect任務。
使用batect的四個優點
簡單的命令列介面:當使用Docker時,常常會出現很多Docker命令,伴隨著許多呼叫引數,例如環境變數、卷掛載資料夾、要釋出的埠等。這些引數需要在多個地方保持同步。使用batect可以簡化這個過程,將所有的組態引數定義在一個組態檔案中。
簡化多容器之間的通訊:當有多個容器需要相互通訊、按特定順序執行或使用多個Dockerfile時,batect可以幫助簡化這個過程。
提高開發效率:使用batect可以將開發任務及其相關的組態引數定義在一個組態檔案中,從而簡化開發過程,提高開發效率。
簡化CI/CD管線:batect可以幫助簡化CI/CD管線,透過定義開發任務及其相關的組態引數,從而簡化管線的組態和維護。
使用batect的範例
# 定義batect任務
batect train-model
# batect組態檔案
tasks:
train-model:
image: my-image
volumes:
- .:/code
environment:
- STAGING
command: ./scripts/train-model.sh
在這個範例中,batect任務train-model
定義了Docker容器的組態引數,包括映像、卷掛載、環境變數和命令。使用batect可以簡化Docker命令,提高開發效率和簡化CI/CD管線。
內容解密:
在這個範例中,batect組態檔案定義了train-model
任務,該任務使用my-image
映像,掛載當前目錄到容器的/code
目錄,設定環境變數STAGING
,並執行./scripts/train-model.sh
命令。使用batect可以簡化Docker命令,提高開發效率和簡化CI/CD管線。
圖表翻譯:
graph LR A[Docker] -->|使用|> B[batect] B -->|定義任務|> C[組態檔案] C -->|簡化命令|> D[開發效率提高] D -->|簡化管線|> E[CI/CD管線]
在這個圖表中,Docker使用batect定義任務,從而簡化命令和提高開發效率,最終簡化CI/CD管線。
使用 Batect 簡化 Docker 命令
在開發過程中,經常需要重複執行多個 Docker 命令,這些命令可能包含多個引數和選項。這種情況下,維護和更新這些命令可能會變得複雜和容易出錯。Batect 是一個工具,可以幫助我們簡化和統一管理這些 Docker 命令。
Batect 的優點
- 簡化 Docker 命令:Batect 可以將多個 Docker 命令合併成一個簡單的命令,例如
./batect train-model
。 - 統一管理組態:Batect 可以將所有的組態引數存放在一個單一的檔案中,例如
batect.yml
,這樣可以方便地管理和更新組態。 - 簡單的任務組合:Batect 可以簡單地組合多個任務,例如在執行 API 測試之前先執行模型訓練任務。
Batect 的使用
Batect 的使用非常簡單。首先,需要建立一個 batect.yml
檔案,然後定義容器和任務。例如:
containers:
dev:
build_directory: .
volumes:
- local: .
container: /code
tasks:
train-model:
description: Train model
run:
container: dev
command: scripts/train-model.sh
然後,可以使用 ./batect train-model
命令執行模型訓練任務。
案例研究
假設我們需要執行一個模型訓練任務和一個 API 測試任務。沒有 Batect 的話,需要執行兩個 Docker 命令:
$ docker run -it --rm -v $(pwd):/code loan-default-prediction:dev \
./scripts/tests/smoke-test-model-training.sh
$ docker run -it --rm -v $(pwd):/code loan-default-prediction:dev \
./scripts/tests/api-test.sh
使用 Batect 的話,可以簡化為一個命令:
$ ./batect api-test
Batect 會自動執行模型訓練任務和 API 測試任務。
使用 Batect 和 Docker 實作快速且可靠的 CI/CD 流程
在機器學習(ML)專案中,CI/CD 流程的效率和可靠性至關重要。Batect 和 Docker 的結合提供了一種實作快速且可靠的 CI/CD 流程的方法。在本文中,我們將探討如何使用 Batect 和 Docker 實作 CI/CD 流程的自動化和加速。
Batect 的優點
Batect 提供了一種簡單且易於使用的方式來定義和管理 CI/CD 流程。它允許您將複雜的命令和指令碼簡化為簡單的 YAML 檔案。這使得 CI/CD 流程的維護和更新更加容易。
1. 簡化 CI/CD 流程
使用 Batect,您可以簡化 CI/CD 流程並減少手動操作的需要。例如,您可以使用 Batect 來執行模型訓練、API 測試和模型佈署等任務。
name: CI/CD pipeline
on: [push]
jobs:
smoke-test-model-training:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Run model training smoke test
run: ./batect smoke-test-model-training
api-test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Run API tests
run: ./batect api-test
train-model:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Train model
run: ./batect train-model
needs: [smoke-test-model-training, api-test]
2. 加速 Docker 架構
Docker 架構的建置時間可能很長,尤其是當您需要下載和安裝大型 Python 套件、預先訓練的模型和資料集時。Batect 和 Docker 的結合可以幫助您加速 Docker 架構的建置。
FROM python:3.10-slim-bookworm
WORKDIR /code
RUN --mount=type=cache,target=/var/cache/apt \
apt-get update && apt-get -y install gcc
RUN pip install poetry
ADD pyproject.toml /code/
RUN poetry config installer.max-workers 10
RUN --mount=type=cache,target=/root/.cache/pypoetry \
--mount=type=cache,target=/opt/.venv \
poetry install
3. 實作快取機制
Batect 和 Docker 的結合可以實作快取機制,減少不必要的下載和安裝時間。這可以幫助您加速 Docker 架構的建置。
version: '1'
tasks:
smoke-test-model-training:
...
api-test:
...
train-model:
...
dependencies:
- smoke-test-model-training
- api-test
使用Batect最佳化容器化開發流程
在進行機器學習(ML)開發時,容器化技術可以幫助我們更好地管理依賴項和環境。然而,傳統的DockerCompose工具可能並不完全滿足我們的需求。這就是Batect的用武之地。Batect是一個簡單易用的工具,允許我們定義和執行容器化任務,從而提高開發效率。
Batect的優點
Batect提供了多種優點,包括:
- 簡單易用:Batect的組態檔案(
batect.yml
)非常簡單易懂,讓我們可以快速上手。 - 高效的快取機制:Batect可以自動快取依賴項和其他下載的工件,從而減少等待時間。
- 靈活的任務定義:Batect允許我們定義任意的容器化任務,包括執行長期和短期程式。
- 良好的CI/CD整合:Batect可以與常見的CI平臺(如GitHub Actions和CircleCI)無縫整合。
如何使用Batect
要使用Batect,首先需要安裝它。安裝完成後,我們可以建立一個batect.yml
檔案來定義我們的容器化任務。以下是一個簡單的例子:
containers:
dev:
build_directory: .
volumes:
- type: cache
name: python-dependencies
container: /opt/.venv
- type: cache
name: poetry-cache-and-artifacts
container: /root/.cache/pypoetry
- type: cache
name: apt-cache
container: /var/cache/apt
在這個例子中,我們定義了一個名為dev
的容器,該容器使用當前的目錄作為構建目錄。然後,我們定義了三個快取卷:python-dependencies
、poetry-cache-and-artifacts
和apt-cache
。
接下來,我們需要定義一個Dockerfile來指定容器的構建過程。以下是一個簡單的例子:
FROM python:3.10-slim-bookworm
WORKDIR /code
RUN apt-get update && apt-get -y install gcc
RUN pip install poetry
ADD pyproject.toml /code/
RUN poetry config installer.max-workers 10
RUN poetry install
在這個例子中,我們使用Python 3.10作為基礎映象,安裝了GCC和Poetry。然後,我們增加了pyproject.toml
檔案並安裝了依賴項。
Batect的快取機制
Batect的快取機制可以幫助我們減少等待時間。當我們執行一個容器化任務時,Batect會自動快取依賴項和其他下載的工件。如果我們需要清除快取,可以使用以下命令:
./batect --clean
或者,我們可以使用Docker的命令來清除快取:
docker builder prune
實踐有效的依賴管理
在前一章中,我們探討了有效的依賴管理原則和工具。現在,讓我們實踐這些原則和工具,透過一個實際的例子來展示有效的依賴管理。
實踐「簽出並執行」
「簽出並執行」是一個重要的原則,指的是可以快速地簽出程式碼並執行它,而不需要進行複雜的設定和組態。這個原則可以透過使用Docker、batect和Poetry等工具來實作。
使用Docker、batect和Poetry
Docker是一個容器化工具,可以幫助我們建立一致的、可重現的和生產級的執行環境。batect是一個工具,可以簡化Docker命令的定義和呼叫。Poetry是一個工具,可以幫助我們管理依賴和建立一致的執行環境。
自動檢測安全漏洞和更新依賴
除了使用Docker、batect和Poetry等工具外,我們還需要自動檢測安全漏洞和更新依賴。這可以透過使用安全掃描工具和自動化指令碼來實作。
實踐中的例子
在這一章中,我們將透過一個實際的例子來展示如何使用Docker、batect和Poetry等工具來實作有效的依賴管理。這個例子將展示如何建立一致的、可重現的和生產級的執行環境,並如何自動檢測安全漏洞和更新依賴。
步驟1:建立Docker容器
# 建立Docker容器
FROM python:3.9-slim
# 安裝依賴
RUN pip install -r requirements.txt
# 複製程式碼
COPY . /app
# 設定工作目錄
WORKDIR /app
# 執行命令
CMD ["python", "app.py"]
步驟2:使用batect簡化Docker命令
# batect.yml
tasks:
build:
docker:
image: python:3.9-slim
commands:
- pip install -r requirements.txt
- python app.py
步驟3:使用Poetry管理依賴
# pyproject.toml
[tool.poetry]
name = "my-app"
version = "1.0.0"
description = "My App"
[tool.poetry.dependencies]
python = "^3.9"
步驟4:自動檢測安全漏洞和更新依賴
# 安全掃描工具
import safety
# 自動檢測安全漏洞
safety.check_requirements("requirements.txt")
透過這些步驟,我們可以實作有效的依賴管理,建立一致的、可重現的和生產級的執行環境,並自動檢測安全漏洞和更新依賴。這可以幫助我們在機器學習專案中提高效率和安全性。
效果管理和依賴關係
在機器學習(ML)開發中,有效地管理依賴關係和避免依賴地獄是非常重要的。讓我們從實際操作開始,探索如何使用Docker和batect來簡化ML開發流程。
ML開發工作流程
在這一節中,我們將透過以下步驟來訓練和佈署一個預測貸款違約的模型:
- 安裝依賴項:執行一個指令碼來安裝主機機器上的必要依賴項。
- 建立Docker化的本地開發環境:使用Docker建立一個本地開發環境,以便我們可以在一個隔離的環境中開發和測試模型。
- 組態程式碼編輯器:組態程式碼編輯器以瞭解專案的虛擬環境,這樣我們就可以獲得有用的編碼助手。
- 執行常見任務:執行ML開發生命週期中的常見任務,例如訓練模型、執行測試和啟動API。
- 佈署模型:將模型佈署到雲端。
容器化的ML工作流程
在容器化一個ML專案之前,首先需要明確地確定什麼需要被容器化。這一步驟很重要,因為它可以避免混淆和分享狀態。例如,如果我們在開發ML模型和服務ML模型的兩個不同任務中分享同一個映象,我們可能會在生產容器中找到不必要的開發依賴項(例如Jupyter、Pylint),這會不必要地增加容器的大小和攻擊面。
常見的ML任務和過程
在ML開發中,我們通常需要執行多個任務和過程,包括:
- 訓練模型
- 服務模型作為Web API(推理)
- 執行測試
- 啟動API
實踐操作
讓我們透過一個實際的例子來演示如何使用Docker和batect來簡化ML開發流程。以下是簡單的Python程式碼,使用Hugging Face Transformers來訓練和服務一個模型:
# 安裝依賴項
from transformers import pipeline
# 訓練模型
def train_model():
# 載入資料和模型
data = ...
model = ...
# 訓練模型
model.fit(data)
# 服務模型
def serve_model():
# 建立一個Web API
api = ...
# 服務模型
api.predict(...)
# 啟動API
if __name__ == "__main__":
serve_model()
使用Docker和batect
使用Docker和batect可以簡化ML開發流程,以下是簡單的Dockerfile和batect組態檔案:
# Dockerfile
FROM python:3.9-slim
# 安裝依賴項
RUN pip install transformers
# 複製程式碼
COPY . /app
# 設定工作目錄
WORKDIR /app
# 執行命令
CMD ["python", "app.py"]
# batect.yml
tasks:
train:
run: python train.py
serve:
run: python serve.py
容器化的應用場景
在進行機器學習(ML)相關工作時,常需要處理多個不同的任務,例如啟動筆記本伺服器、執行佈署(如ML訓練任務、模型API等)、啟動儀錶板或實驗追蹤服務等。這些任務通常需要不同的依賴項來執行。
容器化的優勢
使用容器化技術可以將不同的依賴項和任務隔離,方便管理和維護。例如,啟動筆記本伺服器可以使用一個容器,執行佈署可以使用另一個容器,如此可以避免不同任務之間的依賴項衝突。
例子:容器化的應用
在本章的例子中,我們已經確定了四個不同的依賴項集,用於執行四個不同的任務(見表4-1)。
表4-1:容器化的元件
Image | 任務例子 | OS級別依賴項 |
---|---|---|
筆記本伺服器 | 啟動筆記本伺服器 | Python、Jupyter |
佈署 | 執行ML訓練任務、模型API | Python、TensorFlow、PyTorch |
儀錶板 | 啟動儀錶板 | Python、Streamlit |
實驗追蹤 | 啟動實驗追蹤服務 | Python、MySQL |
實作容器化
使用Docker等容器化工具,可以輕鬆地建立和管理容器。例如,可以使用以下命令建立一個筆記本伺服器容器:
docker run -p 8888:8888 jupyter/notebook
這個命令會建立一個新的容器,將本地的8888埠對映到容器的8888埠,然後啟動筆記本伺服器。
內容解密:
在上面的例子中,我們使用了Docker的run
命令來建立一個新的容器。-p
選項用於將本地的8888埠對映到容器的8888埠,jupyter/notebook
是容器的映象名稱。這個命令會啟動筆記本伺服器,並將其繫結到本地的8888埠。
圖表翻譯:
graph LR A[啟動筆記本伺服器] -->|建立容器|> B[Docker容器] B -->|對映埠|> C[本地8888埠] C -->|啟動筆記本伺服器|> D[筆記本伺服器]
這個圖表展示了建立筆記本伺服器容器的過程。首先,啟動筆記本伺服器的任務會建立一個新的容器,然後將本地的8888埠對映到容器的8888埠,最後啟動筆記本伺服器。
開發流程概覽
在進行機器學習(ML)開發時,通常會涉及多個步驟,從資料收集、模型訓練到佈署。以下是這個流程的概覽:
1. 資料收集與預處理
首先,需要收集相關的資料。這些資料可能來自各種來源,如資料函式庫、API或是直接從使用者那裡收集。收集到資料後,需要進行預處理,以確保資料的品質和一致性。
2. 特徵工程
特徵工程是指從原始資料中提取出有用的特徵,以便於模型的訓練。這個步驟非常重要,因為它直接影響到模型的效能。
3. 模型訓練
使用收集和預處理好的資料,訓練一個機器學習模型。這個步驟需要選擇合適的演算法和模型架構,並調整模型的引數以獲得最佳的效能。
4. 自動化測試
在模型訓練完成後,需要進行自動化測試,以確保模型的正確性和穩定性。這包括了單元測試、整合測試等。
5. 啟動API伺服器
最後,需要啟動API伺服器,以便於其他應用程式可以存取和使用已經訓練好的模型。
實作細節
以下是每個步驟的實作細節:
資料收集與預處理
import pandas as pd
# 載入資料
data = pd.read_csv('data.csv')
# 預處理資料
data = data.dropna() # 刪除空值
data = data.apply(lambda x: x.astype(str).str.lower()) # 將所有欄位轉換為小寫
特徵工程
from sklearn.feature_extraction.text import TfidfVectorizer
# 建立TF-IDF向量化器
vectorizer = TfidfVectorizer(max_features=5000)
# 將文字資料轉換為TF-IDF向量
X = vectorizer.fit_transform(data['text'])
模型訓練
from sklearn.linear_model import LogisticRegression
# 建立邏輯迴歸模型
model = LogisticRegression(max_iter=1000)
# 訓練模型
model.fit(X, data['label'])
自動化測試
import unittest
class TestModel(unittest.TestCase):
def test_model(self):
# 測試模型的正確性
predictions = model.predict(X)
self.assertEqual(predictions.shape, data['label'].shape)
if __name__ == '__main__':
unittest.main()
啟動API伺服器
from flask import Flask, request, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route('/predict', methods=['POST'])
def predict():
# 接收請求資料
data = request.get_json()
# 預處理資料
data = pd.DataFrame([data])
# 預測結果
prediction = model.predict(vectorizer.transform(data['text']))
# 回傳結果
return jsonify({'prediction': prediction.tolist()})
if __name__ == '__main__':
app.run(debug=True)
這個流程提供了一個基本的框架,從資料收集到模型佈署。每個步驟都可以根據具體需求進行調整和最佳化。
建立高效能的 Jupyter Notebook 伺服器
為了建立一個高效能的 Jupyter Notebook 伺服器,我們需要考慮幾個關鍵因素,包括 Python 版本、編譯器選擇、TensorFlow 模型伺服器的設定,以及生產環境下的依賴管理。
從技術架構視角來看,使用Docker建構一致的機器學習執行環境已成為業界趨勢。本文深入探討瞭如何利用Docker、batect和Poetry等工具簡化依賴管理、最佳化開發流程並提升CI/CD效率。分析顯示,batect有效解決了Docker命令繁瑣、組態分散等痛點,提升了開發效率和可維護性。此外,容器化技術的應用有效隔離了不同任務的依賴,避免了衝突,同時也提升了佈署的可靠性。然而,容器化並非萬靈丹,構建高效能的容器化環境仍需仔細考量映象大小、資源消耗等因素。展望未來,隨著雲原生技術的發展,預期更多工具和最佳實務將湧現,進一步簡化機器學習開發流程,降低容器化技術的門檻。對於追求效率和可靠性的機器學習團隊而言,積極擁抱容器化技術並持續探索最佳實務至關重要。