譯者 | 布加迪
審校 | 重樓
如今,大多數(shù)使用人工智能(AI)模型的項(xiàng)目都需要大量的計(jì)算資源。幾乎每當(dāng)一個(gè)新模型出現(xiàn),其性能超越之前的模型,它似乎都需要更多的計(jì)算資源才能高效運(yùn)行。很多人會(huì)說(shuō)也有例外,比如DeepSeek模型,但這并非事實(shí)。像DeepSeek這樣的模型不輸給更大的模型,但也并非更勝一籌。至少目前來(lái)看,模型的大小似乎與模型的性能直接相關(guān)。
傳統(tǒng)上,大規(guī)模部署AI意味著管理非常復(fù)雜的基礎(chǔ)架構(gòu),從配置服務(wù)器或集群到編寫部署腳本,甚至管理針對(duì)特定云的服務(wù)。然而,這種開銷不僅成為許多機(jī)器學(xué)習(xí)團(tuán)隊(duì)的一大痛點(diǎn),還成為限制因素,阻礙他們嘗試新模型,并遏制其創(chuàng)造力。為了避免這些限制因素,我們需要調(diào)整方法,而Modal正是讓我們能夠做到這一點(diǎn),這個(gè)統(tǒng)一的云平臺(tái)可用于為數(shù)據(jù)和AI任務(wù)運(yùn)行代碼。
Modal由Modal Labs于2023年推出,這是無(wú)需手動(dòng)設(shè)置基礎(chǔ)架構(gòu)即可運(yùn)行AI工作負(fù)載的平臺(tái)。它允許開發(fā)者完全使用Python定義工作流,在云托管的計(jì)算資源上執(zhí)行代碼。其目的是通過(guò)抽取掉服務(wù)器和集群配置來(lái)簡(jiǎn)化部署。
Modal如何工作?
Modal是一個(gè)云平臺(tái),用于在云端運(yùn)行代碼,無(wú)需關(guān)注基礎(chǔ)架構(gòu)。開發(fā)者通過(guò)Python SDK(軟件開發(fā)工具包)與Modal交互,定義Modal在其基礎(chǔ)架構(gòu)上按需運(yùn)行的所謂的“應(yīng)用程序”和“函數(shù)”。這種比較新穎的方法又可以稱為“函數(shù)即服務(wù)”模式,意味著開發(fā)者拿來(lái)Python函數(shù)后,用簡(jiǎn)單的裝飾器或API調(diào)用即可遠(yuǎn)程執(zhí)行。如果你熟悉云計(jì)算,這可能會(huì)讓你想起AWS Lambda或Google Cloud Functions等服務(wù)。但盡管表面上有一些相似之處,Modal的工作原理截然不同。
與開發(fā)者使用Docker或Kubernetes準(zhǔn)備執(zhí)行代碼所需的一切這種傳統(tǒng)方法不同,Modal則更進(jìn)一步,允許開發(fā)者用Python代碼指定一切。更準(zhǔn)確地說(shuō),在Modal中,我們定義容器。容器就像微型虛擬機(jī),只運(yùn)行你所需的任務(wù),沒有額外的負(fù)擔(dān)。容器由容器引擎管理,容器引擎使用各種技巧讓程序相互隔離。更準(zhǔn)確地說(shuō),Modal使用gVisor容器運(yùn)行時(shí)來(lái)運(yùn)行容器。gVisor容器運(yùn)行時(shí)由谷歌開發(fā),旨在滿足對(duì)沙盒容器的需求,這種容器能夠在主機(jī)操作系統(tǒng)和容器中運(yùn)行的應(yīng)用程序之間提供安全隔離邊界。
Modal將根據(jù)Python代碼中的指令(而不是YAML文件或類似文件中的指令)構(gòu)建這些容器。本質(zhì)上,當(dāng)我們嘗試在Modal上運(yùn)行某任務(wù)時(shí),要做的第一件事就是在代碼中定義image(鏡像),其中需要定義要在其上運(yùn)行代碼的Python版本以及運(yùn)行代碼所需的庫(kù)。以下這個(gè)示例表明了如何定義一個(gè)用于運(yùn)行來(lái)自Hugging Face的Flux模型的鏡像:
import modal
app = modal.App(name="example-dreambooth-flux")
image = modal.Image.debian_slim(python_version="3.10").pip_install(
"accelerate==0.31.0",
"datasets~=2.13.0",
"fastapi[standard]==0.115.4",
"ftfy~=6.1.0",
"gradio~=5.5.0",
"huggingface-hub==0.26.2",
"hf_transfer==0.1.8",
"numpy<2",
"peft==0.11.1",
"pydantic==2.9.2",
"sentencepiece>=0.1.91,!=0.1.92",
"smart_open~=6.4.0",
"starlette==0.41.2",
"transformers~=4.41.2",
"torch~=2.2.0",
"torchvision~=0.16",
"triton~=2.2.0",
"wandb==0.17.6",
如上述代碼所示,一切均由Python處理,無(wú)需任何外部文件。用戶在Python代碼中定義依賴項(xiàng),這些依賴項(xiàng)不會(huì)在本地安裝,而是只會(huì)在Modal的遠(yuǎn)程環(huán)境中安裝。
如上所示,在定義實(shí)際鏡像之前,我們創(chuàng)建了App類的實(shí)例。我們使用這些App對(duì)象來(lái)表示在Modal上運(yùn)行的應(yīng)用程序。我們將創(chuàng)建的所有函數(shù)和類都附加到這個(gè)App對(duì)象上,這樣可以使一切井然有序、易于管理。
以下是用Modal設(shè)計(jì)的簡(jiǎn)單的app:
import io
import modal
from PIL import Image
# Define the App (deployable bundle)
app = modal.App("image-resizer") # groups everything into one deployable unit
# Build a lightweight container with Pillow pre-installed
image = modal.Image.debian_slim().pip_install("Pillow") # container image spec in code
# A real Function: resize any image to a target width, keep aspect ratio
@app.function(image=image, cpu=2) # 2 vCPUs is plenty for Pillow
def resize_image(img_bytes: bytes, width: int = 256) -> bytes:
"""Return a JPEG resized so its shorter side is `width` pixels."""
with Image.open(io.BytesIO(img_bytes)) as im:
ratio = width / min(im.size)
new_size = (round(im.width * ratio), round(im.height * ratio))
im = im.resize(new_size, Image.LANCZOS)
buf = io.BytesIO()
im.save(buf, format="JPEG", quality=90)
return buf.getvalue()
# Local entry-point: run from CLI with `modal run resize.py`
@app.local_entrypoint() # tells Modal *what* to execute locally
def main():
with open("cat.jpg", "rb") as f: # any JPEG in your working dir
out = resize_image.remote(f.read(), width=256) # remote call
with open("cat_resized.jpg", "wb") as g:
g.write(out)
print("Saved cat_resized.jpg")
根據(jù)我們對(duì)創(chuàng)建的App對(duì)象的處理方式,我們最終得到一個(gè)臨時(shí)應(yīng)用程序或已部署的應(yīng)用程序。
當(dāng)你使用app.run()或modal run CLI命令運(yùn)行腳本時(shí),創(chuàng)建一個(gè)臨時(shí)應(yīng)用程序。它是一個(gè)僅在腳本運(yùn)行時(shí)存在的臨時(shí)應(yīng)用程序。另一方面,已部署的應(yīng)用程序無(wú)限期存在,或直到你使用Web UI將其刪除為止。根據(jù)你希望通過(guò)應(yīng)用程序?qū)崿F(xiàn)的目標(biāo),你需要從兩者中選擇一個(gè)。在這里,計(jì)劃如何擴(kuò)展是一個(gè)很重要的因素,因此了解如何使用Modal進(jìn)行擴(kuò)展至關(guān)重要。
無(wú)服務(wù)器GPU加速和擴(kuò)展
大多數(shù)無(wú)服務(wù)器平臺(tái)通常僅限于執(zhí)行CPU密集型任務(wù),或?qū)?/span>GPU提供有限的支持。而Modal允許用戶使用單個(gè)參數(shù)將GPU連接到任何函數(shù)。在我們之前的示例中,這并非必需,在CPU上運(yùn)行代碼會(huì)極其緩慢。比如說(shuō),要將英偉達(dá)的H100 GPU連接到某個(gè)函數(shù),并使其在該GPU上運(yùn)行,我們只需在定義函數(shù)時(shí)聲明希望這么做即可:
import modal
app = modal.App()
image = modal.Image.debian_slim().pip_install("torch")
@app.function(gpu="H100", image=image)
def run():
import torch
print(torch.cuda.is_available())
在底層,Modal將為實(shí)例配置H100,并在上面執(zhí)行容器。該平臺(tái)支持以下GPU類型,從經(jīng)濟(jì)實(shí)惠型到最先進(jìn)型,應(yīng)有盡有:
- 英偉達(dá)T4
- 英偉達(dá)L4
- 英偉達(dá)A10G
- 英偉達(dá)L40S
- 英偉達(dá)A100,40 GB
- 英偉達(dá)A100,80 GB
- 英偉達(dá) H100
這讓用戶可以選擇最符合自身需求的GPU,從而提供對(duì)AI用例至關(guān)重要的靈活性。我們可以將性能較弱的GPU用于小模型或測(cè)試,而將性能更強(qiáng)大的GPU用于推理或訓(xùn)練,這只需在代碼中更改一個(gè)值即可。唯一的區(qū)別當(dāng)然是價(jià)格。計(jì)算按秒計(jì)費(fèi),最便宜的英偉達(dá)T4 價(jià)格為0.000164美元/秒(0.59美元/小時(shí)),最昂貴的英偉達(dá)H100 價(jià)格為0.001097美元/秒(3.95 美元/小時(shí))。
Modal抽取掉這些GPU的配置方式,這意味著用戶無(wú)需了解這些GPU是來(lái)自AWS、GCP還是其他提供商。這使得Modal在資源層面與云無(wú)關(guān),因?yàn)橛脩糁恍柚付ㄒ褂玫?/span>GPU,Modal會(huì)處理其余部分。
除了提供GPU外,Modal還強(qiáng)調(diào)配置GPU的速度和規(guī)模。Modal編寫了基于Rust的容器運(yùn)行時(shí),可在不到一秒的時(shí)間內(nèi)啟動(dòng)容器,使應(yīng)用程序能夠在幾秒鐘內(nèi)擴(kuò)展到數(shù)百個(gè)GPU支持的worker,而通過(guò)云API或Kubernetes集群?jiǎn)?dòng)如此多的GPU實(shí)例可能需要相當(dāng)長(zhǎng)的時(shí)間。這種幾乎即時(shí)擴(kuò)展到數(shù)百個(gè)GPU支持的worker的靈活性不僅在我們想要以分布式方式訓(xùn)練模型時(shí)至關(guān)重要,而且在AI推理工作負(fù)載中也至關(guān)重要,因?yàn)槲覀兘?jīng)常會(huì)遇到請(qǐng)求突然激增的情況,而這些請(qǐng)求有時(shí)很難用標(biāo)準(zhǔn)方法來(lái)處理。
處理大量數(shù)據(jù)
大多數(shù)AI工作流都需要能夠處理大量數(shù)據(jù)。Modal還為此提供了一個(gè)內(nèi)置解決方案:Modal Volumes,這是一個(gè)分布式文件系統(tǒng),用于函數(shù)運(yùn)行過(guò)程中的數(shù)據(jù)持久化和共享。這些卷允許開發(fā)者在運(yùn)行時(shí)將存儲(chǔ)卷掛載到任何函數(shù)的容器中,函數(shù)可以從中讀取文件,也可以像寫入到本地文件系統(tǒng)一樣將文件寫入到其中。關(guān)鍵區(qū)別在于,該卷的持久性超出了單個(gè)函數(shù)執(zhí)行的生命周期,這意味著其他函數(shù)可以訪問這同一個(gè)卷,并在稍后與其交互。
比如說(shuō),用戶可以將大型預(yù)訓(xùn)練模型檢查點(diǎn)下載并存儲(chǔ)到其中一個(gè)卷中。這使得跨多個(gè)容器的多個(gè)推理函數(shù)可以讀取模型的權(quán)重,無(wú)需從外部源下載或傳輸模型。本質(zhì)上,其功能類似將數(shù)據(jù)緩存在特定的Modal環(huán)境中。
雖然這是在Modal中與數(shù)據(jù)交互的首選方式,但它確實(shí)支持其他數(shù)據(jù)訪問模式,允許用戶將外部云存儲(chǔ)容器(比如S3 存儲(chǔ)桶、Google Cloud Storage 等)直接掛載到函數(shù)中。如果你的數(shù)據(jù)已經(jīng)存儲(chǔ)在云數(shù)據(jù)容器中,這非常有用。然而,卷仍然是推薦的方法,因?yàn)檫@是一種性能高得多的解決方案。
對(duì)AI開發(fā)和云應(yīng)用的戰(zhàn)略意義
在AI領(lǐng)域,用戶日益需要更高級(jí)的抽象,以簡(jiǎn)化復(fù)雜工作負(fù)載的部署。雖然許多機(jī)器學(xué)習(xí)工程師在其領(lǐng)域知識(shí)淵博,但并非所有人都精通搭建部署其設(shè)計(jì)的模型所需的基礎(chǔ)架構(gòu)。Modal提供了專為 AI 和數(shù)據(jù)任務(wù)量身定制的、與云無(wú)關(guān)的無(wú)服務(wù)器平臺(tái),儼然是將AI引入各行各業(yè)的最便捷選擇。這對(duì)從業(yè)者和整個(gè)云行業(yè)都具有多重戰(zhàn)略意義。
對(duì)于AI開發(fā)者來(lái)說(shuō),Modal可以顯著提升從創(chuàng)意到生產(chǎn)的速度。它可以幫助開發(fā)者避免AI項(xiàng)目中常見的瓶頸:將模型提供給用戶或集成到產(chǎn)品中所需的工程工作。在很多情況下,這意味著團(tuán)隊(duì)無(wú)需擔(dān)心擴(kuò)展新的機(jī)器學(xué)習(xí)功能,因?yàn)樗璧幕A(chǔ)架構(gòu)不會(huì)成為限制因素。
Modal與云無(wú)關(guān)的方法也迎合了一些公司避免被單一云提供商牢牢束縛的愿望。由于配置的GPU來(lái)自多家不同的提供商,遭遇中斷的可能性會(huì)大大降低。然而這也意味著,如果Modal及其他類似平臺(tái)在該領(lǐng)域變得極其突出,我們可能會(huì)看到權(quán)力從大型云提供商手中轉(zhuǎn)移出去;它們可能會(huì)成為商品化的后端,而不是開發(fā)者直接接觸的界面。然而,這種權(quán)力轉(zhuǎn)移不太可能發(fā)生,因?yàn)椴捎孟?/span>Modal這樣的平臺(tái)也可能被視為一種供應(yīng)商鎖定。唯有時(shí)間才能告訴我們幾年后市場(chǎng)格局會(huì)是什么樣子,因?yàn)?/span>Modal已經(jīng)面臨一些初創(chuàng)公司和開源領(lǐng)域的競(jìng)爭(zhēng),主要的云服務(wù)提供商顯然在努力簡(jiǎn)化其產(chǎn)品。
實(shí)際用例
Modal的多功能性使其成為各行各業(yè)公司的首選平臺(tái)。不妨看兩個(gè)有趣的用例:Modal如何用于大規(guī)模生成式AI推理以及如何用于計(jì)算生物學(xué)。
Suno是一家提供音樂和語(yǔ)音生成服務(wù)的初創(chuàng)公司,它在Modal上運(yùn)行生產(chǎn)級(jí)推理。這使得Suno能夠擴(kuò)展到數(shù)千個(gè)并發(fā)用戶,無(wú)需擴(kuò)建自己的GPU集群。Modal會(huì)根據(jù)需要分配盡可能多的資源:在高峰時(shí)段,它啟動(dòng)新的實(shí)例來(lái)滿足需求;而在非高峰時(shí)段,它會(huì)動(dòng)態(tài)縮減規(guī)模以降低成本。這表明就連非常復(fù)雜和強(qiáng)大的模型也可以快速啟動(dòng),并根據(jù)需求動(dòng)態(tài)調(diào)整。
Sphinx Bio案例表明了Modal如何應(yīng)用于計(jì)算生物學(xué)中。Sphinx Bio代表研究人員運(yùn)行的蛋白質(zhì)折疊模型,類似于谷歌的Alphafold。蛋白質(zhì)折疊是一種計(jì)算密集型的過(guò)程,需要大量GPU才能高效運(yùn)行。通過(guò)使用Modal,Sphinx Bio可以在無(wú)需維護(hù)集群的情況下針對(duì)大型試驗(yàn)進(jìn)行擴(kuò)展,不需要太多的計(jì)算能力時(shí)縮減規(guī)模。此外,由于Modal支持調(diào)度,他們可以輕松地調(diào)度和排隊(duì)多個(gè)獨(dú)立計(jì)算(比如同時(shí)折疊多個(gè)蛋白質(zhì)),并讓Modal可以處理計(jì)算資源的分配。雖然Sphinx Bio代表了這樣一個(gè)用例,但基因組學(xué)、物理模擬甚至金融建模等領(lǐng)域的其他公司也必將紛紛效仿。
以上只是兩個(gè)示例用例,如果你想了解目前有哪些公司在使用Modal,可以在Modal的官方網(wǎng)站上找到更多用例。
結(jié)論
Modal代表了一種新型的云平臺(tái)。它不再要求用戶自行管理基礎(chǔ)架構(gòu),而是提供了一種以函數(shù)為中心的方法,抽取掉大規(guī)模發(fā)布AI應(yīng)用程序的諸多復(fù)雜性。通過(guò)克服AI應(yīng)用程序發(fā)布中的兩大痛點(diǎn):冗長(zhǎng)的部署周期和碎片化的工具,Modal確信在大多數(shù)情況下,用戶會(huì)選擇簡(jiǎn)單、快速和云無(wú)關(guān),而不是低層面控制。
盡管這種無(wú)服務(wù)器方法有效地降低了構(gòu)建復(fù)雜AI服務(wù)的門檻,但在某些情況下,用戶可能會(huì)決定部署基礎(chǔ)架構(gòu),尤其是在對(duì)延遲敏感或需要定制硬件的系統(tǒng)中。這完全沒問題,因?yàn)闆]有適用于所有用例的“最佳”解決方案。話雖如此,Modal無(wú)疑將有關(guān)“理想”的云平臺(tái)應(yīng)該是什么樣子的討論推向新的方向,至少對(duì)于那些開發(fā)AI應(yīng)用程序的人來(lái)說(shuō)是如此。隨著Modal發(fā)展壯大并驗(yàn)證其模式,一大批類似的解決方案可能會(huì)出現(xiàn),從而促使無(wú)服務(wù)器AI功能更緊密地整合到主流云產(chǎn)品中。Modal的成功至少暗示著,我們可以預(yù)期AI基礎(chǔ)架構(gòu)格局將發(fā)生轉(zhuǎn)變,不僅強(qiáng)調(diào)原始性能,還強(qiáng)調(diào)易用性。
原文標(biāo)題:Run Scalable Python Workloads With Modal,作者:Narinder Singh Kharbanda