在不斷發展的技術世界中,由大語言模型驅動的應用程序,通常被稱為“LLM 應用”,已成為各種行業技術創新背后的驅動力。隨著這些應用程序的普及,用戶需求的大量涌入對底層基礎設施的性能、安全性和可靠性提出了新的挑戰。
Python 和 Docker 一直是構建機器學習應用程序的主流選擇。然而,當涉及到為大型語言模型(LLM)應用程序構建基礎設施時,這種組合的一些缺點變得更加嚴重,例如 Python 的性能問題和 Docker 的冷啟動問題。本演講重點關注為 LLM 生態構建基礎設施的主要場景,并深入探討 Python 和 Docker 組合的問題,更重要的是,為什么 Rust + WebAssembly (WASM) 優于 Python + Docker。最后,我們將演示如何在 flows.network 平臺上構建一個代碼檢查機器人。
現有解決方案:Python + Docker 方法
在機器學習領域,Python 幾乎稱王,主要得益于以下三個特點:
-
易于學習:?Python 是一種高級語言,語法簡單,易于學習和使用。對于 AI 新手或需要快速原型設計和測試想法的開發者,這可能至關重要。
-
龐大的社區:?Python 擁有龐大且活躍的開發者社區,這意味著有許多庫和工具可用于 AI 開發。對于需要快速找到常見問題解決方案的開發者來說,這是個優勢。
-
靈活性:?Python 用途多樣,可用于廣泛的 AI 任務,包括數據分析、機器學習和自然語言處理。對于需要從事多個 AI 項目的開發者而言很有吸引力。
Docker 容器作為當今最流行的容器管理工具之一,為應用部署提供了極大的便利:
-
可移植性:?Docker 容器被設計為可移植的,這意味著它們可以在不同環境之間輕松移動。對于需要將 AI 應用程序部署到多個平臺或云提供商的開發者來說,這可能是一個優勢。
-
隔離:?Docker 容器在應用程序和主機操作系統之間提供了高度的隔離,可以提高安全性和穩定性。對于需要高級別安全性的組織來說,這可能是一個優勢。
-
可擴展性:?Docker 容器可以輕松擴展或縮小以滿足不斷變化的需求,這對于需要大量計算或需要處理大型數據集的 AI 應用程序來說是一個優勢。
對于傳統機器學習應用的開發和部署,Python+Docker 模式展現了其優勢。然而,在 LLM 生態的基礎設施建設中,卻面臨著挑戰。
Python + Docker 的挑戰
Python 和 Docker 的優點自然也帶來了一些缺點。然而,在 LLM 生態基礎設施建設的過程中,這些缺陷變得更加突出,成為關鍵障礙。讓我們先看看 Python 存在的問題。
Python 的缺點
?性能瓶頸
Python 是一種解釋性語言,這意味著它可能比 C++ 或 Rust 等編譯語言慢。當處理需要大量計算的大型數據集或復雜模型時,這可能是一個缺點。
在圖 1 中,前三行分別顯示了用 Python、Java 和 C 編寫的將兩個 4096 x 4096 矩陣相乘的編程性能。從“運行時間(秒)”一欄的統計數據可以看出,(1)Java(作為靜態編程語言)比 Python(作為動態編程語言)快 10 倍;(2) C(作為非 GC 編程語言)比 Python(作為 GC 編程語言)快 50 倍。
圖 1 程序性能工程的加速 將兩個 4096×4096 矩陣相乘。
-
并行性?Python 的全局解釋器鎖 (GIL) 通常被認為是并行執行時的限制。GIL 確保單個進程中一次只有一個線程執行 Python 字節碼,這會阻礙多核處理器的充分利用并影響并行性能。
-
內存管理?Python 的動態類型和垃圾收集會帶來內存管理的開銷。雖然垃圾收集器有助于自動內存管理,但有時會導致效率低下,特別是在實時性能至關重要的情況下。
混合編程:Python + C/C++/Rust
為了改善 Python 語言本身的性能問題,常見的做法是使用 Python 作為負責與用戶交互的前端語言,同時選擇 C/C++/Rust 等高性能編程語言作為后端 語言來處理繁重的計算任務。Python 生態中很多知名庫都采用這種方式來滿足高性能計算的需求,比如 Numpy。然而,這種混合編程方法不可避免地需要額外的工具(或庫)作為“連接”兩種不同編程語言的橋梁。因此,這個過程可能會帶來新的問題。
?維護成本
假設我們想要“綁定” Python 和 C++ API,我們必須使用第三方庫來自動化這個轉換過程,例如 Pybind11。圖 2 中的示例代碼展示了如何使用 Pybind11 “綁定” C++ 和 Python 程序。不難看出,盡管 Pybind11 極大地簡化了轉換過程,但添加或刪除任何 C++ API 都需要對轉換代碼進行相應的更改,并且更改的難度與變更內容密切相關。從成本角度來看,這個過程不僅增加了開發者的學習成本,也增加了項目的開發和維護成本。
圖 2 將 C++ 和 Python“粘合”在一起。
?可移植性問題
-
混合編程可能會帶來可移植性挑戰。由于 Python 與本機庫交互的方式或不同環境中的系統級依賴關系存在差異,在一個平臺上無縫運行的代碼可能會在另一個平臺上遇到問題。
?集成復雜性
-
如圖 2 所示,將 Python 與其他語言綁定通常需要仔細管理數據類型、內存分配和錯誤處理。盡管有第三方庫可以改進綁定任務,例如 Pybind11,但這種“粘合”過程仍然容易出錯,并且需要對 Python 和所使用的其他語言有深入的了解。這會在一定程度上增加開發時間和風險。
Docker 容器的局限性
?冷啟動性能
-
Docker 容器雖然高效,但有時會面臨冷啟動性能的挑戰。“冷啟動”是指容器實例化后開始運行所需的時間。就 Docker 而言,啟動時間通常為秒級。這可能看起來不多,但在快速擴展和響應能力至關重要的環境中,這些時間可能會導致明顯的延遲并降低用戶滿意度。
?磁盤空間消耗
-
Docker 容器有時可能非常龐大,消耗的磁盤空間達到千兆字節 (GB) 的量級。當容器包含所有必要的依賴項和運行時環境時尤其如此。如此大的容器大小可能會導致存儲成本增加、部署時間變慢以及管理和分發容器映像方面的挑戰。
?硬件加速器支持
-
雖然 Docker 容器可以利用硬件加速器來提高性能,但有一個問題。他們通常需要特定版本的軟件來確保兼容性。這意味著組織可能需要維護多個版本的容器或更新其硬件加速器以滿足軟件要求,從而增加了復雜性和管理開銷。
?可移植性問題
-
Docker 的主要賣點之一是它的可移植性。然而,這種可移植性有時取決于 CPU 架構。雖然 Docker 容器被設計為在不同環境中一致運行,但在不同 CPU 架構之間移動時可能會存在差異。這可能會給確保不同部署環境中的一致性能和行為帶來挑戰。
?安全依賴
-
Docker 容器依賴主機操作系統的用戶權限來保證安全。這意味著容器的安全性在一定程度上依賴于底層操作系統的安全配置。如果主機操作系統受到損害或配置錯誤,則可能會使容器面臨安全漏洞。
這些限制凸顯了對替代解決方案的需求,例如 Rust + WebAssembly,它有望解決其中一些痛點,并為部署 LLM 應用程序提供更高效、更安全的環境。
AGI 將是由 Rust 和
WebAssembly 構建
為什么 Rust 和 WebAssembly 可以成為 AGI 的語言?
Rust:AGI 時代的最佳選擇
-
性能。?Rust 是一種編譯語言,以其極快的性能而聞名。當與基于堆棧的虛擬機的二進制指令格式 WebAssembly 結合使用時,這兩個組合有望提供無與倫比的執行速度。
-
內存安全。?Rust 的突出特點之一是它強調內存安全而不犧牲性能。這確保了應用程序既快速又安全。
-
并發性。?Rust 的并發性方法是獨一無二的。它確保在編譯時捕獲數據競爭(并發系統中最常見和最具挑戰性的錯誤之一)。這意味著開發者可以編寫并發代碼,而不必擔心引入難以檢測的運行時錯誤。
-
富有表現力的類型系統。?Rust 擁有強大且富有表現力的類型系統。該系統不僅有助于在編譯時捕獲錯誤,而且還允許開發者以清晰簡潔的方式表達他們的意圖。
-
現代包管理。?Cargo,Rust 的包管理器,簡化了管理依賴項、構建項目甚至發布庫的過程。因其易用性和高效性而受到贊譽的工具。
-
快速增長的生態。?Rust 的生態正在蓬勃發展。像“ndarray”、“llm”、“candle”和“burn”這樣的庫證明了社區積極參與擴展 Rust 的能力。
WASM 容器:更快、更輕、更安全
Shivraj Jadhav 從多個維度比較了 Docker 容器和 WASM。
表 1 WASM 與 Docker
-
可移植性。?WebAssembly 被設計為用于編譯高級語言的可移植目標,允許部署在 Web 和 服務端,跨不同硬件。
-
沙箱機制。?WebAssembly 引入了沙箱機制,提供更安全的生產環境。這可以確保代碼在隔離的環境中運行,從而最大限度地減少潛在風險。
-
保護用戶數據和系統資源。?WebAssembly 的設計考慮了安全性。它確保用戶數據和系統資源免受潛在威脅。
-
字節碼驗證。?在執行之前,WebAssembly 字節碼會經過驗證過程,以防止惡意代碼運行。這增加了額外的安全層。
-
隔離執行環境。?WebAssembly 中的模塊在隔離環境中運行。這意味著即使一個模塊出現問題,也不會影響其他模塊的正常運行。
-
占用空間更小。?使用 Rust 和 WebAssembly,開發者可以事半功倍。編譯后的代碼通常要小得多,從而加快加載時間并提高執行效率。
?WASI-NN 標準
除了上述優點之外,WebAssembly 針對機器學習應用的 WASI-NN 標準也是一個重要因素。
-
主流機器學習推理引擎。?WASI-NN 旨在與流行的機器學習推理引擎(如 TensorFlow、PyTorch 和 OpenVINO)無縫協作。
-
大型語言模型的擴展。?借助“Llama2.c”和“llama.cpp”等工具和庫,WASI-NN 提供為大型模型應用程序量身定制的功能,確保開發者擁有他們需要的的工具,以處理廣泛的數據集和復雜的模型。
最新發布的 WasmEdge 0.13.5 已經支持使用 Rust 和 Wasm 運行 llama2 系列大模型,包括但不限于我們熟知的 Codellama、Mistral、OpenChat、BELLE-Llama2、Yi-34B 等等。詳情請查看 llama-utils。
應用場景:代碼檢查代理(Agent)
在本節中,我們將演示如何使用“flows.network”平臺構建代碼檢查代理。在深入討論具體示例之前,我們首先看一下“Agent”和“flows.network”平臺的概念模型。
Agent 的概念模型
這是 Lilian Weng 提出的基于 LLM 的 AI Agent 的概念框架。
圖 3 LLM 驅動的自治代理系統概述
在這個模型中,LLM 函數扮演了智能體大腦的角色,負責核心推理和決策,但它仍然需要額外的模塊來啟用關鍵能力:規劃、長 / 短期記憶和工具使用。
“flows.network”平臺是基于與 Lilian 提出的模型類似的理念構建的。圖 4 顯示了其主要組件。整個平臺是用 Rust 編寫的,編譯為 wasm 模塊,并在 WasmEdge Runtime 上運行。
圖 4 Flows.network 的主要組件
代碼檢查代理
在“flows.network”平臺上,我們提供了一個代理(一個機器人模版)來幫助 GitHub 上開源項目的維護者審核 PR。將其命名為“代碼檢查機器人”。
代理的抽象設計如圖 5 所示。圖中中心的紅色塊code-review-function
定義了核心代理函數,而紅色塊周圍的每個虛線圓圈與直接連接到圖 3 中“代理”塊的對應部分相匹配。
圖 5 Code Review Bot 抽象設計
圖 6 描述了Code Review Bot的架構。除了 GitHub Service 等外部資源外,代理由 wasm 模塊組成,并在 WasmEdge Runtime 上運行。集成 wasm 模塊負責通過 Web API 將 WebAssembly 函數連接到外部資源。例如,“code-review-function” wasm 模塊將審核中的代碼提取為提示詞,然后“openai-integration” wasm 模塊將提示詞發送到 ChatGPT 服務并等待響應;最后,將評論發送到 code-review-function
wasm 模塊。
圖.6 架構代碼檢查機器人
圖 7 顯示了 Code Review Bot 的 PR 檢查摘要示例。它總結了目標 PR,列出了隱藏的風險和重大改變等。這些信息可以幫助檢查者將注意力集中在關鍵部分,節省時間。
圖 7 代碼檢查機器人 PR 審核總結示例
代碼檢查機器人可以在幾分鐘內完成部署。如果你想在自己的項目中使用它,可參考本指南。
結? ? ?論
在 AI 基礎設施開發領域,雖然 Python 和 Docker 為我們提供了很好的服務,但探索和采用能夠帶來更好性能、安全性和效率的新技術也至關重要。Rust 和 WebAssembly 的結合反映了這種演變,為開發者和組織提供了一個有吸引力的替代方案。
參考資料
flows.network: 驅動 AI 工作負載的低代碼 Serverless 平臺。https://flows.network/
llama-utils: 請訪問 https://github.com/second-state/llama-utils
?作者簡介
Sam Liu, QCon 北京 2023 演講嘉賓,Second State 工程師,CNCF WasmEdge 維護者 & Miley Fu,CNCF 大使,WasmEdge DevRel。
完整幻燈片下載:
https://qcon.infoq.cn/202309/beijing/presentation/5466