Ray 提供一個完整機器學習工作流程解決方案,包含分散式訓練、超引數調整與線上推論佈署。Ray Train 簡化分散式訓練流程,並可與 Ray Tune 整合進行超引數最佳化。透過 ScalingConfig 設定,可輕鬆擴充套件訓練規模,並利用 Preprocessor 進行資料預處理。Ray Serve 則專注於線上推論服務的建構,支援多模型整合及業務邏輯的嵌入,並可透過 FastAPI 簡化 HTTP API 開發,提升線上服務的彈性與效率。
分散式訓練與 Ray Train 的整合應用
Ray Train 提供了一個強大的分散式訓練框架,能夠與 Ray Tune 緊密整合,實作高效的超引數調優。透過使用 Ray Train 的 Trainer 和 Ray Tune 的 Tuner,開發者可以輕鬆地擴充套件訓練任務並最佳化模型的超引數。
使用 TorchTrainer 進行分散式訓練
在使用 Ray Train 進行分散式訓練時,使用者需要指定訓練迴圈、資料集和擴充套件組態。ScalingConfig 允許使用者在不撰寫分散式邏輯的情況下擴充套件訓練任務,並宣告式地指定訓練所需的計算資源。
import ray
from ray.air.config import ScalingConfig
from ray.train.xgboost import XGBoostTrainer
ray.init(address="auto")
scaling_config = ScalingConfig(num_workers=200, use_gpu=True)
trainer = XGBoostTrainer(
scaling_config=scaling_config,
# ...
)
內容解密:
ScalingConfig用於組態訓練任務的擴充套件設定,包括工作節點數量和是否使用 GPU。num_workers=200表示啟動 200 個工作節點進行分散式訓練。use_gpu=True表示使用 GPU 加速訓練過程。
資料預處理與 Ray Train
資料預處理是機器學習流程中的重要步驟。Ray Train 提供了 Preprocessor 類別來處理資料預處理任務。常見的預處理操作包括標準化和最小-最大縮放。
from ray.data.preprocessors import StandardScaler, MinMaxScaler
prep_v1 = StandardScaler(columns=["X"])
prep_v2 = MinMaxScaler(columns=["X"])
內容解密:
StandardScaler將指定欄位的資料標準化,使其均值為 0 且標準差為 1。MinMaxScaler將指定欄位的資料縮放到 [0, 1] 範圍內。- 這些前處理器可以被序列化,以便在訓練和服務階段保持一致性。
與 Ray Tune 整合進行超引數調優
Ray Train 與 Ray Tune 的整合使得超引數調優變得簡單。透過定義超引數搜尋空間,可以使用 Tuner 自動進行調優。
from ray import tune
from ray.tune import Tuner
param_space = {
"scaling_config": ScalingConfig(
num_workers=tune.grid_search([2, 4]),
resources_per_worker={
"CPU": 2,
"GPU": 0,
},
),
"preprocessor": tune.grid_search([prep_v1, prep_v2]),
"params": {
"objective": "binary:logistic",
"tree_method": "hist",
"eval_metric": ["logloss", "error"],
"eta": tune.loguniform(1e-4, 1e-1),
"subsample": tune.uniform(0.5, 1.0),
"max_depth": tune.randint(1, 9),
},
}
tuner = Tuner(
trainer,
param_space=param_space,
)
results = tuner.fit()
內容解密:
param_space定義了超引數的搜尋空間,包括擴充套件組態、前處理器選擇和模型引數。tune.grid_search用於對指定的引數進行網格搜尋。tune.loguniform和tune.uniform用於定義引數的隨機搜尋分佈。Tuner使用定義好的搜尋空間對Trainer進行調優。
Ray Train 與 Ray Tune 工作流程
圖表翻譯:
此圖示展示了使用 Ray Train 和 Ray Tune 進行分散式訓練和超引數調優的工作流程。首先定義 ScalingConfig,然後建立 Trainer。接著定義超引數搜尋空間 Param Space,並建立 Tuner。最後,執行 Tuner.fit() 進行調優,並分析結果。
線上推斷與 Ray Serve 簡介
在前面的章節中,我們討論瞭如何使用 Ray 進行資料處理、訓練機器學習模型,並在批次推斷設定中應用它們。然而,許多最令人興奮的機器學習應用案例都涉及線上推斷。在本章中,我們將對 Ray Serve 進行溫和的介紹,Ray Serve 是一個原生的 Ray 函式庫,能夠在 Ray 上建立線上推斷應用。
線上推斷的重要性
線上推斷是指使用機器學習模型來增強使用者直接或間接互動的 API 端點的過程。在許多情況下,延遲是至關重要的,你無法簡單地在後台將模型應用於資料並提供結果。以下是一些線上推斷可以提供巨大價值的真實案例:
- 推薦系統:為產品(例如,線上購物)或內容(例如,社交媒體)提供推薦。雖然可以離線進行,但推薦系統通常需要對使用者的偏好做出即時反應,這需要使用最近的行為作為關鍵特徵進行線上推斷。
- 聊天機器人:線上服務通常具有即時聊天視窗,以從鍵盤上為客戶提供支援。傳統上,這些聊天視窗由客戶支援人員負責,但最近的趨勢是透過機器學習技術來取代他們,以減少勞動成本並提高解決時間。這些聊天機器人需要多種機器學習技術的複雜組合,並且必須能夠即時回應客戶的輸入。
- 預估抵達時間:叫車服務、導航和食品配送服務都依賴於能夠提供準確的抵達時間估計(例如,您的駕駛員、您自己或您的晚餐)。提供準確的估計非常困難,因為它需要考慮現實世界的因素,如交通模式、天氣和事故。估計也會在一次行程中多次重新整理。
線上推斷的挑戰
所有這些應用都分享一個至關重要的要求:延遲。線上上服務的情況下,低延遲對於提供良好的使用者經驗至關重要。對於與現實世界互動的應用(例如,機器人或自動駕駛汽車),更高的延遲可能會對安全或準確性產生更強烈的影響。
機器學習模型是計算密集型的
線上推斷中的許多挑戰都源於一個關鍵特徵:機器學習模型是非常計算密集型的。與傳統的網頁服務相比,請求主要由 I/O 密集型的資料函式庫查詢或其他 API 呼叫處理,大多數機器學習模型歸結為執行許多線性代數運算:提供推薦、估計抵達時間或檢測影像中的物件。
Ray Serve 的架構和核心功能
Ray Serve 是一個 Ray 原生的函式庫,能夠在 Ray 上建立線上推斷應用。本章將首先討論 Ray Serve 所解決的線上推斷挑戰。然後,我們將介紹 Ray Serve 的架構和核心功能。最後,我們將使用 Ray Serve 建立一個由多個自然語言處理模型組成的端對端線上推斷 API。
使用 Ray Serve 的好處
使用 Ray Serve,您可以輕鬆地建立和管理線上推斷應用,並利用 Ray 的分散式計算能力來提高效能和可擴充套件性。Ray Serve 提供了簡單易用的 API,讓您可以專注於建立您的機器學習模型,而無需擔心底層的基礎設施。
建立線上推斷 API
在本章的其餘部分,我們將使用 Ray Serve 建立一個端對端線上推斷 API,該 API 由多個自然語言處理模型組成。您可以按照本章筆記本中的程式碼進行操作。
# 從 ray.serve 匯入必要的模組
from ray import serve
from ray.serve import deployment
# 定義您的機器學習模型
@serve.deployment
class MyModel:
def __init__(self):
# 初始化您的模型
pass
def __call__(self, request):
# 處理請求並傳回結果
pass
# 佈署您的模型
MyModel.deploy()
# 建立一個 HTTP 端點來存取您的模型
@serve.deployment(route_prefix="/predict")
class MyPredictEndpoint:
def __init__(self, model: MyModel):
self.model = model
async def __call__(self, request):
# 處理請求並呼叫您的模型
result = await self.model(request)
return result
# 將您的模型繫結到端點
MyPredictEndpoint.deploy(MyModel)
#### 內容解密:
1. **MyModel類別定義**:這裡定義了一個名為`MyModel`的類別,它將被佈署為一個服務。這個類別包含了模型的初始化和呼叫邏輯。
2. **`__init__`方法**:這個方法用於初始化模型。在這個例子中,它沒有做任何事情,但在實際應用中,您需要在這裡載入您的模型。
3. **`__call__`方法**:這個方法定義了當服務被呼叫時的行為。它接收一個請求作為輸入,並傳回結果。
4. **佈署模型**:`MyModel.deploy()` 用於將模型佈署到 Ray Serve。
5. **定義預測端點**:`MyPredictEndpoint` 類別定義了一個 HTTP 端點,用於接收預測請求並呼叫佈署的模型。
6. **繫結模型到端點**:`MyPredictEndpoint.deploy(MyModel)` 將 `MyModel` 例項繫結到 `MyPredictEndpoint`,這樣當端點接收到請求時,就可以呼叫 `MyModel` 進行預測。
### Ray Serve架構圖
## 線上推理的挑戰與 Ray Serve 簡介
線上推理(Online Inference)是指將訓練好的機器學習模型佈署到生產環境中,以處理實時請求並提供預測結果的過程。這種應用通常需要 24/7 不間斷執行,並且由於模型計算密集,執行線上推理服務可能非常昂貴,需要分配大量的 CPU 和 GPU 資源。
### 線上推理的主要挑戰
線上推理的主要挑戰在於如何在最小化端對端延遲的同時降低成本。為滿足這些需求,線上推理系統需要提供以下關鍵特性:
* 支援 GPU 和 TPU 等專用硬體
* 能夠根據請求負載動態調整模型資源
* 支援請求批次處理,以利用向量化計算
### 機器學習模型不是孤立的
在學術或研究環境中,機器學習的討論通常集中在單個、孤立的任務上,如物件識別或分類別。然而,現實世界的應用通常並不如此清晰和明確。相反,需要結合多個機器學習模型和業務邏輯來解決一個問題。
例如,考慮一個產品推薦的使用案例。雖然我們可以將多種已知的機器學習技術應用於做出推薦的核心問題,但同樣重要的是存在於邊緣的許多挑戰,其中許多將特定於每個使用案例:
* 驗證輸入和輸出,以確保傳回給使用者的結果在語義上是有意義的
* 取得使用者和可用產品的最新資訊,並將其轉換為模型的特徵
* 使用手動規則組合多個模型的結果,例如過濾頂部結果或選擇具有最高置信度的模型
### Ray Serve 簡介
Ray Serve 是構建在 Ray 之上的可擴充套件計算層,用於服務機器學習模型。它是框架無關的,這意味著它不與特定的機器學習函式庫繫結;相反,它將模型視為普通的 Python 程式碼。此外,它允許您靈活地將正常的 Python 業務邏輯與機器學習模型結合起來。
#### Ray Serve 的核心功能
Ray Serve 的核心原語是佈署(deployment),您可以將其視為一組受管理的 Ray 演員(actor),它們可以一起被定址並處理負載平衡的請求。佈署中的每個演員在 Ray Serve 中稱為副本(replica)。通常,佈署將與機器學習模型一一對應,但佈署可以包含任意 Python 程式碼,因此它們也可能包含業務邏輯。
Ray Serve 使得透過 HTTP 暴露佈署以及定義輸入解析和輸出邏輯成為可能。然而,Ray Serve 最重要的功能之一是佈署也可以使用原生的 Python API 直接相互呼叫,這將轉化為副本之間的直接演員呼叫。
#### 使用 Ray Serve 的好處
使用 Ray Serve,您可以構建完整的線上推理服務:一個 Serve 應用程式可以驗證使用者輸入、查詢資料函式庫、在多個機器學習模型上執行可擴充套件的推理,並組合、過濾和驗證輸出——所有這些都在處理單個推理請求的過程中。
### Ray Serve 架構概述
Ray Serve 構建在 Ray 之上,因此它繼承了許多好處,如可擴充套件性、低開銷通訊、適合平行性的 API,以及透過物件儲存利用分享記憶體的能力。
#### 程式碼範例
```python
import ray
from ray import serve
# 初始化 Ray 和 Serve
ray.init()
serve.start()
# 定義一個簡單的佈署
@serve.deployment
def my_deployment(request):
return "Hello, World!"
# 佈署模型
my_deployment.deploy()
# 傳送請求
import requests
response = requests.get("http://localhost:8000/my_deployment")
print(response.text)
# 清理
serve.shutdown()
ray.shutdown()
內容解密:
上述程式碼展示瞭如何使用 Ray Serve 佈署一個簡單的服務。首先,我們初始化 Ray 和 Serve。然後,我們定義了一個簡單的佈署 my_deployment,它傳回 “Hello, World!"。接著,我們佈署這個模型並傳送一個 GET 請求來測試它。最後,我們清理資源,關閉 Serve 和 Ray。
這個例子體現了 Ray Serve 的易用性和靈活性,使得佈署和管理機器學習模型變得更加簡單和高效。
多模型推理圖
Ray Serve 的一個關鍵優勢是能夠組合多個機器學習模型的結果。在後續章節中,我們將探討如何使用 Ray Serve 構建多模型推理圖,以滿足更複雜的線上推理需求。
Ray Serve 基礎與佈署
Ray Serve 是 Ray 生態系統中的一部分,專門用於佈署機器學習模型和應用程式,提供高效能的線上推論服務。本文將介紹如何使用 Ray Serve 佈署簡單的 HTTP 端點,並探討其擴充套件性和資源分配。
Ray Serve 架構概述
Ray Serve 應用程式執行在 Ray 叢集上,多個佈署(deployments)分佈在叢集中。每個佈署由一個或多個副本(replicas)組成,每個副本是一個 Ray 行為者(actor)。輸入的流量透過 HTTP 代理進行負載平衡,將請求分發到各個副本。
Ray Serve 應用程式架構
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Ray分散式訓練與線上推論整合應用
package "機器學習流程" {
package "資料處理" {
component [資料收集] as collect
component [資料清洗] as clean
component [特徵工程] as feature
}
package "模型訓練" {
component [模型選擇] as select
component [超參數調優] as tune
component [交叉驗證] as cv
}
package "評估部署" {
component [模型評估] as eval
component [模型部署] as deploy
component [監控維護] as monitor
}
}
collect --> clean : 原始資料
clean --> feature : 乾淨資料
feature --> select : 特徵向量
select --> tune : 基礎模型
tune --> cv : 最佳參數
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型
note right of feature
特徵工程包含:
- 特徵選擇
- 特徵轉換
- 降維處理
end note
note right of eval
評估指標:
- 準確率/召回率
- F1 Score
- AUC-ROC
end note
@enduml圖表翻譯: 此圖示展示了 Ray Serve 的基本架構,包括 HTTP 代理如何將請求負載平衡到不同的佈署,以及每個佈署如何包含多個副本。
定義基本的 HTTP 端點
本文將介紹如何使用 Ray Serve 定義一個簡單的 HTTP 端點,包裝一個單一的機器學習模型。我們將佈署一個情感分析模型,根據輸入的文字預測其情感是正面還是負面。
程式碼範例:情感分析模型佈署
from ray import serve
from transformers import pipeline
@serve.deployment
class SentimentAnalysis:
def __init__(self):
self._classifier = pipeline("sentiment-analysis")
def __call__(self, request) -> str:
input_text = request.query_params["input_text"]
return self._classifier(input_text)[0]["label"]
basic_deployment = SentimentAnalysis.bind()
內容解密:
__init__方法初始化情感分析模型,該模型可能很大,因此下載和載入可能需要幾分鐘。在 Ray Serve 中,這段程式碼只會在每個副本啟動時執行一次。__call__方法定義了處理請求的邏輯,接受 Starlette HTTP 請求作為輸入,並傳回 JSON 可序列化輸出。- 使用
.bind()方法例項化佈署,並可選地傳遞引數給建構函式。
使用 FastAPI 整合
為了簡化 HTTP API 的編寫,Ray Serve 與 FastAPI 框架整合,允許使用其表達性 API 解析輸入和組態 HTTP 行為。
程式碼範例:使用 FastAPI 的情感分析模型佈署
from fastapi import FastAPI
app = FastAPI()
@serve.deployment
@serve.ingress(app)
class SentimentAnalysis:
def __init__(self):
self._classifier = pipeline("sentiment-analysis")
@app.get("/")
def classify(self, input_text: str) -> str:
return self._classifier(input_text)[0]["label"]
fastapi_deployment = SentimentAnalysis.bind()
內容解密:
- 使用 FastAPI 處理輸入引數的解析,簡化了程式碼。
@serve.ingress(app)裝飾器將 FastAPI 應用程式與 Ray Serve 佈署整合。@app.get("/")定義了 HTTP GET 請求的處理邏輯。
擴充套件性和資源分配
機器學習模型通常需要大量的計算資源,因此正確分配資源對於處理請求負載和最小化成本至關重要。Ray Serve 允許調整佈署的副本數量和資源分配,以滿足不同的需求。