Ray
Ray 是 AI 的運算層。它為 ChatGPT 訓練和大規模工作負載提供動力。v3.0(2025)改善了效率,並為代理新增了一個 MCP Server。
使用時機
- 分散式 Python 應用程式:將計算密集的 Python 任務從單一筆記型電腦無縫擴展到大型雲端叢集。
- 使用 Ray Train 的分散式 ML 訓練:協調多節點 PyTorch、XGBoost 和 LightGBM 訓練任務。
- 使用 Ray Serve 的生產模型服務:以動態自動擴展提供 LLM 和多模型微服務管線。
- 使用 Ray Tune 的超參數最佳化:在數百個工作節點上執行貝氏、Optuna 和基於群體訓練的掃描。
快速入門
import ray
ray.init()
# 遠端分散式任務
@ray.remote
def square(x):
return x * x
# 在叢集中並行啟動任務
futures = [square.remote(i) for i in range(10)]
results = ray.get(futures)
print("計算的平方值:", results)
核心概念
#分散式任務與狀態化 Actor
在叢集工作節點間擴展函式與類別:
import ray
import time
# 初始化本地或連接到遠端 Ray 叢集
ray.init(ignore_reinit_error=True)
# 1. 無狀態遠端函式(分散式任務)
@ray.remote
def process_data_chunk(chunk_id: int) -> dict:
time.sleep(0.5) # 模擬 CPU/IO 密集型計算
return {"chunk_id": chunk_id, "processed_items": 1000 * chunk_id}
# 在叢集中並行啟動任務
futures = [process_data_chunk.remote(i) for i in range(8)]
results = ray.get(futures) # 收集結果
print("處理的區塊:", results)
# 2. 有狀態遠端類別(分散式 Actor)
@ray.remote
class GlobalCounter:
def __init__(self):
self.count = 0
def increment(self) -> int:
self.count += 1
return self.count
counter_actor = GlobalCounter.remote()
inc_futures = [counter_actor.increment.remote() for _ in range(5)]
print("最終 Actor 計數:", ray.get(inc_futures[-1]))
#使用 Ray Serve 進行生產模型服務
部署具有動態請求批次處理的可擴展 REST 端點:
from ray import serve
import torch
from transformers import pipeline
@serve.deployment(num_replicas=2, ray_actor_options={"num_cpus": 1, "num_gpus": 0})
class SentimentClassifier:
def __init__(self):
self.classifier = pipeline("sentiment-analysis")
async def __call__(self, request):
json_data = await request.json()
text = json_data.get("text", "")
return self.classifier(text)
app = SentimentClassifier.bind()
# serve.run(app)
#使用 Ray Tune 進行分散式超參數調優
執行並行超參數試驗:
from ray import tune
def training_function(config):
# 模擬的模型訓練
for step in range(10):
intermediate_score = config["alpha"] * step + config["beta"]
tune.report(loss=1.0 / (intermediate_score + 0.1))
search_space = {
"alpha": tune.uniform(0.1, 1.0),
"beta": tune.choice([1, 2, 5])
}
tuner = tune.Tuner(
training_function,
param_space=search_space,
tune_config=tune.TuneConfig(num_samples=10, metric="loss", mode="min")
)
results = tuner.fit()
print("最佳超參數:", results.get_best_result().config)
常見模式
用於模型服務的狀態化分散式 Actor
問題:每次函式呼叫都將大型模型權重重複載入記憶體。
解決方案: 使用 Ray Actors 在請求之間保持記憶體狀態:
@ray.remote(num_gpus=1)
class ModelServer:
def __init__(self):
# 將權重一次性載入 GPU VRAM
self.model = load_large_model()
def predict(self, sample):
return self.model(sample)
server_actor = ModelServer.remote()
prediction = ray.get(server_actor.predict.remote(sample_data))
最佳實踐(2026)
- 務必檢查 Ray Dashboard(埠 8265)以監控節點 CPU/GPU 使用率、Actor 放置和物件儲存記憶體。
- 務必透過 Ray plasma 物件儲存(
ray.put(data))傳遞大型唯讀資料集,以防止重複序列化。 - 務必在裝飾器中明確指定資源需求(
@ray.remote(num_cpus=2, num_gpus=1))。 - 務必使用 Ray Serve 進行內建自動批次處理的生產多模型微服務。
- 切勿在遠端任務內部呼叫
ray.get();將 ObjectRef 直接傳遞給其他遠端任務以保持管線化。 - 切勿建立數百萬個微任務;將細粒度任務批次處理在一起以最小化排程器開銷。
- 切勿在遠端參數中傳遞大型有狀態物件(如資料庫連線或開啟的檔案)。
故障排除
| 錯誤 | 原因 | 解決方案 |
|---|---|---|
RaySystemError: Object store full | 任務產生的資料超過分配的共享記憶體 plasma 儲存空間。 | 使用 ray.get() 消費結果,或將大型陣列儲存到磁碟儲存。 |
Actor died unexpectedly | 工作進程因未處理的例外或 OOM 而崩潰。 | 在 Ray Dashboard(http://localhost:8265)檢查日誌,並增加工作節點 RAM。 |
Task failed to schedule: Unsatisfiable resource request | 請求的 CPU/GPU(num_gpus=2)超過叢集可用資源。 | 透過 ray.cluster_resources() 驗證可用資源。 |