
![]()
模型服務在雲中有效。

MOSEC是用於構建ML模型的後端和微服務的高性能和靈活的模型。它彌合了剛訓練的任何機器學習模型與有效的在線服務API之間的差距。
MOSEC需要Python 3.7或更高。使用:
pip install -U mosec
# or install with conda
conda install conda-forge::mosec要從源代碼構建,請安裝Rust並運行以下命令:
make package您將在dist文件夾中獲得MOSEC車輪文件。
我們演示了MOSEC如何幫助您輕鬆託管預先訓練的穩定擴散模型作為服務。您需要將擴散器和變壓器作為先決條件:
pip install --upgrade diffusers[torch] transformers首先,我們導入庫並設置一個基本的記錄儀,以更好地觀察發生的事情。
from io import BytesIO
from typing import List
import torch # type: ignore
from diffusers import StableDiffusionPipeline # type: ignore
from mosec import Server , Worker , get_logger
from mosec . mixin import MsgpackMixin
logger = get_logger ()然後,我們為客戶構建一個API ,以查詢文本提示,並僅以3個步驟獲得基於穩定的擴散-V1-5模型的圖像。
將您的服務定義為繼承mosec.Worker類。在這裡,我們還繼承了MsgpackMixin ,以採用MSGPACK序列化格式(a) 。
在__init__方法內,初始化模型並將其放在相應的設備上。您可以選擇地分配self.example用一些數據進行熱身(b)模型。請注意,數據應與處理程序的輸入格式兼容,我們接下來會詳細介紹。
覆蓋編寫您的服務處理程序(C) forward方法,並以簽名forward(self, data: Any | List[Any]) -> Any | List[Any] 。接收/返回單個項目或元組取決於是否配置了動態批處理(D) 。
class StableDiffusion ( MsgpackMixin , Worker ):
def __init__ ( self ):
self . pipe = StableDiffusionPipeline . from_pretrained (
"sd-legacy/stable-diffusion-v1-5" , torch_dtype = torch . float16
)
self . pipe . enable_model_cpu_offload ()
self . example = [ "useless example prompt" ] * 4 # warmup (batch_size=4)
def forward ( self , data : List [ str ]) -> List [ memoryview ]:
logger . debug ( "generate images for %s" , data )
res = self . pipe ( data )
logger . debug ( "NSFW: %s" , res [ 1 ])
images = []
for img in res [ 0 ]:
dummy_file = BytesIO ()
img . save ( dummy_file , format = "JPEG" )
images . append ( dummy_file . getbuffer ())
return images[!筆記]
(a)在此示例中,我們以二進制格式返回圖像,而JSON不支持該圖像(除非用base64編碼使有效負載更大的base64)。因此,MSGPACK更適合我們的需求。如果我們不繼承
MsgpackMixin,則默認情況下將使用JSON。換句話說,服務請求/響應的協議可以是MSGPACK,JSON或任何其他格式(檢查我們的Mixins)。(b)熱身通常有助於提前分配GPU記憶。如果指定了熱身示例,則只有在示例通過處理程序轉發後才准備就緒。但是,如果沒有給出示例,則預計第一個請求的延遲將更長。該
example應根據forward期望接收的方式設置為單個項目或元組。此外,如果您想使用多個不同的示例進行熱身,則可以設置multi_examples(此處的演示)。(c)此示例顯示了一個單階段服務,在該服務中,
StableDiffusionWorker直接接收客戶的提示請求並響應圖像。因此,forward可以將其視為完整的服務處理程序。但是,我們還可以在管道中設計多個階段服務(例如,下載圖像,模型推理,後處理)的工人。在這種情況下,整個管道被視為服務處理程序,第一位工人接受了請求,最後一名工人發送了答复。工人之間的數據流是通過過程間通信完成的。(d)由於在此示例中啟用了動態批處理,因此,
forward方法將希望收到字符串的列表,例如['a cute cat playing with a red ball', 'a man sitting in front of a computer', ...],從不同的客戶端匯總進行批處理推斷,改善了系統吞吐量。
最後,我們將工人附加到服務器上以構建單個階段的工作流程(可以輸送多個階段以進一步提高吞吐量,請參見此示例),並指定我們希望其以並行運行的過程數( num=1 ),最大批次大小,最大批次= 4( max_batch_size=4 ),與最大的限制為time time time time tirn interim max_wait_time=10 interime;毫秒,這意味著最長的MOSEC等待,直到將批量發送給工人)。
if __name__ == "__main__" :
server = Server ()
# 1) `num` specifies the number of processes that will be spawned to run in parallel.
# 2) By configuring the `max_batch_size` with the value > 1, the input data in your
# `forward` function will be a list (batch); otherwise, it's a single item.
server . append_worker ( StableDiffusion , num = 1 , max_batch_size = 4 , max_wait_time = 10 )
server . run ()以上片段在我們的示例文件中合併。您可以直接在項目根級別上運行。我們首先查看命令行參數(這裡說明):
python examples/stable_diffusion/server.py --help然後,讓我們從調試日誌開始服務器:
python examples/stable_diffusion/server.py --log-level debug --timeout 30000打開http://127.0.0.1:8000/openapi/swagger/在您的瀏覽器中獲取OpenAPI DOC。
在另一個終端中,對其進行測試:
python examples/stable_diffusion/client.py --prompt " a cute cat playing with a red ball " --output cat.jpg --port 8000您將在當前目錄中獲得名為“ cat.jpg”的圖像。
您可以檢查指標:
curl http://127.0.0.1:8000/metrics就是這樣!您剛剛託管了穩定的擴散模型作為服務!
可以在示例部分中找到更多的現成示例。它包括:
append_worker時,將配置max_batch_size和max_wait_time (millisecond) 。max_batch_size值推斷不會導致GPU中的內存。max_wait_time應小於批處理推理時間。max_batch_size或max_wait_time經過時,它將收集批處理。當流量較高時,該服務將從此功能中受益。mosec的GPU基礎圖像,則可以檢查官方圖像mosecorg/mosec 。對於復雜的用例,請查看Envd。mosec_service_batch_size_bucket顯示批處理大小分佈。mosec_service_batch_duration_second_bucket顯示每個階段中每個連接的動態批次持續時間(從接收第一個任務開始)。mosec_service_process_duration_second_bucket顯示每個階段中每個連接的處理持續時間(包括IPC時間,但不包括mosec_service_batch_duration_second_bucket )。mosec_service_remaining_task顯示當前處理任務的數量。mosec_service_throughput顯示服務吞吐量。SIGINT ( CTRL+C )或SIGTERM ( kill {PID} )停止服務,因為它具有優美的關閉邏輯。 max_batch_size和max_wait_time 。指標將顯示真實批處理大小和批處理持續時間的直方圖。這些是調整這兩個參數的關鍵信息。serialize_ipc/deserialize_ipc方法進行序列化/應對,因此非常大的數據可能會使整個管道慢速。默認情況下,序列化數據將通過RUST傳遞到下一階段,您可以啟用共享內存以減少潛伏期(參考Redisshmipcmixin)。serialize/deserialize方法,該方法用於解碼用戶請求並編碼響應。默認情況下,兩者都使用JSON。但是,JSON並不能很好地支持圖像和嵌入。您可以選擇更快,二進制兼容的MSGPACK(參考穩定擴散)。mosec自V0.8.8以自動適應用戶協議(例如,http/2)。 以下是使用MOSEC的一些公司和個人用戶:
如果您發現此軟件對您的研究有用,請考慮引用
@software{yang2021mosec,
title = {{MOSEC: Model Serving made Efficient in the Cloud}},
author = {Yang, Keming and Liu, Zichen and Cheng, Philip},
url = {https://github.com/mosecorg/mosec},
year = {2021}
}
我們歡迎任何貢獻。請通過提出問題或討論不和諧來給我們反饋。您也可以直接貢獻您的代碼並提取請求!
要開始開發,您可以使用Envd創建一個孤立,清潔的Python&Rust環境。檢查Envd-Docs或build.envd以獲取更多信息。