整理 | 王子彧 責編 | 張紅月
說起 Chris Lattner,大家一定不陌生。這位編譯器大神,曾經領導了眾多大型技術項目。他不僅是 LLVM 項目的主要發起人,還是 Clang 編譯器的創作者。同時,他是蘋果公司編譯器開發團隊的首席架構師和蘋果新程式語言 Swift 創造者。此外,Chris Lattner 還為 Google Brain 和 TensorFlow 建立和管理了一系列與 AI 相關的編譯器、運行時和程式語言團隊。
2022 年 1 月,Chris Lattner 和 AI 領域專家 Tim Davis 共同建立了 Modular AI,旨在重建全球 ML 基礎設施。
而在近日,編譯器的大神 Chris Lattner 在社群網路上官宣了一種全新的程式語言:Mojo!
(n h) s d’, h=self.nheads)’],[20,’\n’,’24:\’NmMJ\’|36:177|direction:\’ltr\”],[20,’ q,k,v = torch.chunk(x, 3, dim=-1)’],[20,’\n’,’24:\’8xN8\’|36:177|direction:\’ltr\”],[20,’ s = (q@k.transpose(1,2))/self.scale’],[20,’\n’,’24:\’uUzu\’|36:177|direction:\’ltr\”],[20,’ x = s.softmax(dim=-1)@v’],[20,’\n’,’24:\’tmUp\’|36:177|direction:\’ltr\”],[20,’ x = rearrange(x, ‘(n h) s d -> n s (h d)’, h=self.nheads)’],[20,’\n’,’24:\’MLpH\’|36:177|direction:\’ltr\”],[20,’ return self.proj(x)’],[20,’\n’,’24:\’dLJW\’|36:177|direction:\’ltr\”],[20,’\n’,’24:\’Ffnr\’|direction:\’ltr\”],[20,’但實際上,這些操作很複雜。例如,在 ‘],[20,’CUDA C’,’16:\’https%3A%2F%2Fgithub.com%2FHazyResearch%2Fflash-attention%2Ftree%2Fmain%2Fcsrc%2Fflash_attn%2Fsrc\”],[20,’ 中進行記憶體最佳化的「快閃記憶體注意」實現。它還掩蓋了這些構建模型的通用方法留下了大量的性能的事實。例如,「塊稀疏」方法可以顯著提高速度和記憶體使用。研究人員正在對常見架構的每個部分進行調整,並提出新的架構(以及 SGD 最佳化器,資料增強方法等)——我們甚至還沒有一個每個人都會永久使用的整齊包裝的系統。’],[20,’\n’,’24:\’2m79\’|direction:\’ltr\”],[20,’\n’,’24:\’DDgE\’|direction:\’ltr\”],[20,’在實踐中,許多用於語言模型的最快程式碼都是用 C 和 C++ 編寫的。例如,Fabrice Bellard 的 TextSynth 和 Georgi Gerganov 的 ggml 都使用 C 語言,因此能夠充分利用完全編譯語言的性能優勢。’],[20,’\n’,’24:\’36PE\’|direction:\’ltr\”],[20,’\n’,’24:\’DN1g\’|32:1|direction:\’ltr\”],[20,’「MLIR 的語法糖」:Mojo’],[20,’\n’,’24:\’8fvq\’|32:1|direction:\’ltr\”],[20,’\n’,’24:\’qZNr\’|direction:\’ltr\”],[20,’Chris Lattner 開發的 LLVM,從根本上改變了編譯器的創建方式,也為世界上許多廣泛使用的語言生態系統打下了堅實的基礎。’],[20,’\n’,’24:\’2qgn\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Hgan\’|7:3|direction:\’ltr\”],[20,’之後,他推出了一個建立在 LLVM 之上的 C 和 C++ 編譯器 Clang,並被廣泛使用。LLVM 包括「中間表示」(IR),這是一種為機器讀寫(而不是人)設計的特殊語言,它使一個龐大的軟體社區能夠協同合作,為更廣泛的硬體提供更好的程式語言功能。’],[20,’\n’,’24:\’D0CZ\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Q2nA\’|7:3′],[20,’Chris Lattner 認為 C 和 C++ 並沒有完全充分利用 LLVM 的威力,因此他在蘋果工作時,設計了一種名為「Swift」的新語言,他將其描述為「LLVM 的語法糖」。如今,Swift 已經成為世界上使用最廣泛的程式語言之一,特別是它創建了 iPhone、iPad、MacOS 和 Apple TV 創建 iOS 應用程序的主要方式。’],[20,’\n’,’24:\’zbPx\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’3O23\’|7:3′],[20,’不幸的是,蘋果對 Swift 的控制導致它還沒有真正在技術領域大放異彩。Chris Lattner 曾在 Google 試圖將 Swift 從蘋果的舒適區移出來,成為 AI 模型開發中 Python 的替代品。但遺憾的是,它沒有得到蘋果或 Google 的支持,最終沒有成功。’],[20,’\n’,’24:\’nlZ9\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’LYql\’|7:3|direction:\’ltr\”],[20,’話雖如此,在 Google 期間,Chris 開發了另一個非常成功的項目:MLIR。MLIR 是 LLVM IR 的替代品,適用於現代多核計算和 AI 工作負載。這對於充分利用 GPU、TPU 等硬體的強大功能以及越來越多地添加到伺服器級 CPU 中的向量單元至關重要。’],[20,’\n’,’24:\’OfP0\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’7f3L\’|7:3|direction:\’ltr\”],[20,’那麼,如果 Swift 是「LLVM 的語法糖」,那麼「MLIR 的語法糖」是什麼?答案是:Mojo!Mojo 是一種全新的語言,旨在充分利用 MLIR。並且,Mojo 也是 Python。’],[20,’\n’,’24:\’TrBA\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’h70y\’|7:3|direction:\’ltr\”],[20,’也許說 Mojo 是 Python++ 更為恰當。它將(完成後)是 Python 語言的嚴格超集。但它也有附加功能,因此,開發者可以編寫利用現代加速器的高性能程式碼。’],[20,’\n’,’24:\’FLR3\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’L0bn\’|7:3|direction:\’ltr\”],[20,’在 Jeremy Howard 看來,Mojo 似乎比 Swift 更實用。雖然 Swift 是一種包含了基於程式語言設計最新研究的各種炫酷功能的全新語言,但 Mojo 的核心是 Python。因為 Python 已經被數百萬程式設計師廣泛使用,並且經過幾十年的使用,它的功能和侷限性已經得到了充分完善。’],[20,’\n’,’24:\’OiOW\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’ARV7\’|7:3|direction:\’ltr\”],[20,’用最新的程式語言進行研究很酷,但它可能具有潛在危險。就 Jeremy Howard 個人而言,他經常被 Swift 強大但古怪的類型系統搞糊塗,有時甚至成功地被 Swift 編譯器混淆並且完全崩潰!’],[20,’\n’,’24:\’OLt6\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’LtSx\’|7:3|direction:\’ltr\”],[20,’Mojo 的一個關鍵技巧是,作為開發人員,您可以隨時選擇加入更快的「模式」。通過使用「fn」而不是「def」來創建函數。在這種模式下,您必須準確確定每個變數的類型,Mojo 可以創建最佳化的機器程式碼來實現您的函數。此外,如果使用「struct」而不是「class」,您的屬性將被打包到記憶體中,這樣它們可以在資料結構中使用,而無需追蹤指針。這些特性使得像 C 這樣的語言變得很快,而現在 Python 程式設計師只需學習一點點新語法即可使用。’],[20,’\n’,’24:\’JP1E\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’f8xX\”],[20,’Mojo 如何做到的?’],[20,’\n’,’24:\’Mmlv\’|32:1|direction:\’ltr\”],[20,’\n’,’24:\’WmBa\’|direction:\’ltr\”],[20,’幾十年來,為了創建簡潔、靈活、快速、實用和易於使用的程式語言,開發者們進行了數百次嘗試。但並沒有取得太大成效。而 Mojo 似乎做到了。我們可以得出一些假設:’],[20,’\n’,’24:\’qIMh\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’LMX0\’|7:3′],[20,’1.Mojo 實際上並沒有實現這些目標,精彩的演示掩蓋了令人失望的現實表現。’],[20,’\n’,’24:\’qalr\’|7:3|direction:\’ltr\”],[20,’2.Modular 是一家擁有數百名開發人員的大型公司,公司為實現未曾實現過的目標付出了多年的努力。’],[20,’\n’,’24:\’OTD4\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Soar\’|7:3|direction:\’ltr\”],[20,’事實上,這兩個假設都不成立。我們舉兩個例子,(matmul 和 mandelbrot)並不是在嘗試了數十種方法後才精心選擇的唯一有效方法;相反,它們是我們為演示而嘗試的一種方法,並且第一次就成功了!雖然在這個早期階段,還是有很多功能的缺失(除了線上「playground」之外,Mojo 還沒有發佈給公眾),但您在演示中看到的確實是它的工作方式。事實上,您現在可以在 playground 中自己運行它。’],[20,’\n’,’24:\’505e\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’KmFt\’|7:3|direction:\’ltr\”],[20,’Modulal 是一家僅成立一年的小初創公司。一個小團隊是如何在短時間內做到這樣的呢?’],[20,’\n’,’24:\’ooEj\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’pDdJ\’|7:3|direction:\’ltr\”],[20,’關鍵一:基礎強大’,’8:1′],[20,’\n’,’24:\’OspC\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’AdWm\’|7:3|direction:\’ltr\”],[20,’關鍵在於 Mojo 是建立在一些非常強大的基礎之上的。Jeremy Howard 表示,很少見到有軟體項目願意花費時間來打好堅實的基礎,並且往往會因此積累大量的技術債務。隨著時間的推移,添加功能和修復錯誤變得越來越困難。然而,在 Mojo 這樣一個設計良好的系統中,每個功能都比上一個更容易添加,速度也更快,出錯率低,每個功能所構建的基礎都越來越好。’],[20,’\n’,’24:\’2Ivi\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’aLN2\’|7:3|direction:\’ltr\”],[20,’其核心是最初是由 Chris Lattner 在 Google 開發的並且使用多年的 MLIR。Chris Lattner 已經意識到「AI 時代程式語言」的核心基礎將需要什麼,並專注於構建它們。MLIR 就是其中的一個關鍵部分。就像 LLVM 在過去十年中極大地簡化了強大的新程式語言的開發一樣(如 Rust、Julia 和Swift,它們都基於 LLVM),MLIR 為建立在其上的語言提供了更強大的核心。’],[20,’\n’,’24:\’RTSF\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’8wMK\’|7:3|direction:\’ltr\”],[20,’關鍵二:使用 Python 作為語法’,’8:1′],[20,’\n’,’24:\’Gi3v\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’wV0d\’|7:3|direction:\’ltr\”],[20,’Mojo 快速發展的另一個關鍵因素是決定使用 Python 作為語法。開發和迭代語法是語言開發中最容易出錯、最複雜和最有爭議的一部分。通過簡單地將其外包給現有的語言,整個部分就會消失!因此,需要少量地在 Python 之上添加的新語法部分來自然適應。’],[20,’\n’,’24:\’7YD5\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’0LoR\’|7:3|direction:\’ltr\”],[20,’接下來是創建一個最小的 Pythonic 方法直接調用 MLIR。這並不是一個大項目,但它需要在此基礎上創建所有 Mojo 所需的全部內容,並直接在 Mojo 中處理其他所有工作。這意味著 Mojo 開發人員從一開始就能「dog-food」 Mojo。當他們在開發 Mojo 時發現某些東西不太好用時,他們可以為 Mojo 本身添加所需的功能,以便更容易開發下一個 Mojo 部分!’],[20,’\n’,’24:\’VPBX\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’xcXW\’|7:3′],[20,’這一點和 Julia 很像。Julia 是在’],[20,’最小的類LISP核心’,’16:\’https%3A%2F%2Fgithub.com%2FJeffBezanson%2Ffemtolisp\”],[20,’上開發的,該核心提供 Julia 語言元素,然後將其綁定到基本的 LLVM 操作。Julia 中的幾乎所有內容都是建立在它之上的。’],[20,’\n’,’24:\’nkPR\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Q7Nr\’|7:3|direction:\’ltr\”],[20,’Modular 團隊內部宣佈,決定通過一個視訊(包括演示)推出 Mojo,並且他們將時間定在了未來幾周之內。那時 Mojo 只是最基本的語言,沒有可用的筆記本核心,幾乎沒有實現任何 Python 語法,也沒有進行任何最佳化。’],[20,’\n’,’24:\’vJt8\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’tuVp\’|7:3|direction:\’ltr\”],[20,’起初,Jeremy Howard 並不理解這個行為。但這段時間,Mojo 的表現讓他歎為觀止。每隔一兩天,就有全新的語言功能被實現。一旦有足夠的語言功能來嘗試運行演算法,它們就能夠立即達到或接近最先進的性能水平!Jeremy Howard 突然意識到 Mojo 所有的基礎都已經建立好了,並且它們被明確設計用於構建現在正在開發的東西。因此,一切都很順利,而且運作良好也就不足為奇了。’],[20,’\n’,’24:\’dsta\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’wNnB\’|7:3′],[20,’這是 Jeremy Howard 對 Mojo 未來持樂觀態度的理由。雖然這個項目還處於早期階段,但根據 Jeremy Howard 在過去幾週中觀察到的情況,他的猜測是它將比大多數人預期的發展得更快、更遠……’],[20,’\n’,’24:\’bQvK\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’vaEI\’|direction:\’ltr\”],[20,’Mojo 關鍵優勢:易於部署’],[20,’\n’,’24:\’kS4U\’|32:1|direction:\’ltr\”],[20,’\n’,’24:\’LIXL\’|direction:\’ltr\”],[20,’這是很關鍵的一點。如果你想把你酷炫的 Python 程序給朋友,你需要讓他們’],[20,’\n’,’24:\’5wq6\’|7:3|direction:\’ltr\”],[20,’先安裝 Python!或者,你可以給他們一個包含 Python 和你使用的所有庫的巨大檔案。’],[20,’\n’,’24:\’osAj\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Fz2s\’|7:3|direction:\’ltr\”],[20,’由於 Python 是一種解釋型語言,所以你的程序的行為將取決於安裝的 python 的確切版本、存在的庫的版本以及它們的配置方式。為了避免維護問題,Python 社區已經確定了幾種選項來安裝 Python 應用程序:環境,每個程序都有一個單獨的Python 安裝;或容器,為每個應用程序設置一整個作業系統。但這兩種方法都會在開發和部署Python 應用程序時產生許多混亂和開銷。’],[20,’\n’,’24:\’JFrx\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Wkh2\’|7:3|direction:\’ltr\”],[20,’將其與部署靜態編譯的 C 應用程序進行比較:您只需將編譯的程序直接下載即可。它的大小可能只有 100k 左右,可以快速啟動和運行。’],[20,’\n’,’24:\’h5K2\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’vM8Z\’|7:3|direction:\’ltr\”],[20,’還有一種 Go 採用的方法,它不能生成像 C 這樣的小型應用程序,而是將「運行時」集成到每個打包的應用程序中。這種方法是 Python 和 C 之間的折中,仍需要數十兆位元組的二進位制檔案,但比 Python 更容易部署。’],[20,’\n’,’24:\’pct9\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’vlLo\’|7:3′],[20,’作為一種編譯語言,Mojo 的部署方式與 C 基本相同。例如,一個包含從頭開始編寫的 matmul 版本的程序大約是 100 k。’],[20,’\n’,’24:\’UeeQ\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’WKFl\’|7:3′],[20,’這意味著 Mojo 不僅僅是面向 AI/ML 應用程序的語言。它實際上是 Python 一種版本,可以幫助我們編寫快速、小巧、易於部署的應用程序,利用所有可用的核心和加速器!’],[20,’\n’,’24:\’U1qT\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’tRxS\’|direction:\’ltr\”],[20,’\n’,’24:\’7k8z\’|direction:\’ltr\”],[20,’Mojo 的替代品’],[20,’\n’,’24:\’Xpfd\’|32:1|direction:\’ltr\”],[20,’\n’,’24:\’eXV2\’|direction:\’ltr\”],[20,’Mojo 並不是解決 Python 性能和部署問題的唯一辦法。在語言方面,Julia 可能是目前最強的替代品。它具有 Mojo 的許多優點,並且構建出了很多優秀的項目。但在 Jeremy Howard 看來,Julia 也並不完美:’],[20,’\n’,’24:\’HloO\’|direction:\’ltr\”],[20,’\n’,’24:\’HevC\’|direction:\’ltr\”],[20,’Julia 面臨的最大挑戰源於其大型運行時,決定在該語言中使用垃圾回收。此外,Julia 中使用的多排程方法雖然打開了很多用語言做很酷的事情的大門,但也會讓開發人員的工作變得非常複雜。’],[20,’\n’,’24:\’uFW1\’|direction:\’ltr\”],[20,’\n’,’24:\’YVMU\’|7:3′],[20,’在 Python 中,目前最好的解決方案可能是 ‘],[20,’Jax’,’16:\’https%3A%2F%2Fjax.readthedocs.io%2Fen%2Flatest%2F\”],[20,’,它有效地使用 Python 創建了一個特定領域的語言(DSL)。這種語言的輸出是 XLA,它是一個早於MLIR的機器學習編譯器(我相信它正在逐漸轉移到MLIR上)。Jax 繼承了 Python(例如,該語言無法表示結構,或直接分配記憶體或創建快速循環)和 XLA(主要針對 TPU,很大程度上限制在機器學習特定的概念上)的限制,但具有巨大的優勢,即不需要新的語言或新的編譯器。’],[20,’\n’,’24:\’mtFh\’|7:3|direction:\’ltr\”],[20,’ ‘],[20,’\n’,’24:\’6g0O\’|7:3|direction:\’ltr\”],[20,’如前所述,還有新的 PyTorch 編譯器,Tensorflow 也能夠生成 XLA 程式碼。就 Jeremy Howard個人而言,這種方式使用 Python 最終並不令人滿意。Jeremy Howard 實際上並沒有使用 Python 的所有功能,但必須使用與其所針對的後端兼容的子集。Jeremy Howard 不能輕鬆地調試和分析編譯後的程式碼,因為很多不確定性,甚至很難知道最終執行的內容。’],[20,’\n’,’24:\’KE2z\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Pote\’|7:3|direction:\’ltr\”],[20,’Jeremy Howard 甚至無法得到一個獨立的二進位制檔案,而必須使用特殊的運行時並處理複雜的 API。’],[20,’\n’,’24:\’AbgL\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Kq5J\’|7:3|direction:\’ltr\”],[20,’Python 的另一個有趣的方向是 ‘],[20,’Numba’,’16:\’https%3A%2F%2Fnumba.pydata.org%2F\”],[20,’ 和 ‘],[20,’Cython’,’16:\’https%3A%2F%2Fcython.org%2F\”],[20,’。Numba 使用一個特殊的裝飾器,使 Python 函數被編譯成使用LLVM最佳化的機器程式碼。Cython 類似,但還提供了一個類似於 Python 的語言,具有 Mojo 的一些特性,並將這個 Python 方言轉換成 C,然後進行編譯。這些語言都沒有解決部署問題,但它們可以幫助解決性能問題。’],[20,’\n’,’24:\’CRzC\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’mMs8\’|7:3′],[20,’兩者都無法針對具有通用跨平臺程式碼的一系列加速器,儘管 Numba 確實提供了一種非常有用的方法來編寫 CUDA 程式碼(因此可以針對 NVIDIA GPU)。Jeremy Howard 對於 Numba 和 Cython 的存在表示感激,並且認為從它們中獲得了很多。但它們完全不同於使用完整的語言和編譯器生成獨立的二進位制檔案。它們只是Python性能問題的臨時解決方案,對於僅需要解決性能問題的情況是可行的’],[20,’\n’,’24:\’bnE2\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’MRYz\’|7:3′],[20,’但 Jeremy Howard 更喜歡使用一種既像 Python 一樣,又像 C 一樣快的語言,能夠允許其使用一個語言來編寫從應用程序伺服器到模型架構以及安裝程序的所有內容,並且能在編寫程式碼的語言中直接調試和分析其的程式碼。’],[20,’\n’,’24:\’qqu3\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’BrEH\’|7:3′],[20,’你喜歡這樣的語言嗎?歡迎在評論區留言討論。’],[20,’\n’,’24:\’yzdJ\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’0SAI\’|direction:\’ltr\”],[20,’\n’,’24:\’hxif\’|direction:\’ltr\”],[20,’參考連結:’],[20,’\n’,’24:\’4Ko2\’|direction:\’ltr\”],[20,’https://www.fast.ai/posts/2023-05-03-mojo-launch.html’,’0:\’rgb(65%2C%2070%2C%2075)\’|16:\’https%3A%2F%2Fwww.fast.ai%2Fposts%2F2023-05-03-mojo-launch.html\’|1:\’rgb(255%2C%20255%2C%20255)\’|27:\’9\’|31:2′],[20,’\n’,’24:\’INNX\’|direction:\’ltr\”],[20,’https://www.modular.com/mojo’,’0:\’rgb(65%2C%2070%2C%2075)\’|16:\’https%3A%2F%2Fwww.modular.com%2Fmojo\’|1:\’rgb(255%2C%20255%2C%20255)\’|27:\’9\’|31:2′]]” data-copy-origin=”https://shimo.im” style=”visibility: visible;”>

Enlitic 創始人 Jeremy Howard 在試用 Mojo 後表示:「Mojo 是幾十年來最大的程式設計進步」。

Jeremy Howard 直言:
回顧我第一次使用 Visual Basic v1.0 的情景。彼時,它還只是一個針對 DOS 的程序。在此之前,編寫程序非常複雜。因此,我除了掌握最基本的玩具應用程序之外,其他方面沒有取得太大進展。然而,當我在 VB 螢幕上畫了一個按鈕,輸入了一行程式碼就得到一個完整的可運行應用程序時,我覺得很驚奇。這種感覺令我難以忘懷。我人生中第二次有這種感覺,是用 Modular1 推出的新程式語言 Mojo 編寫程式碼。

比 Python 快 35000 倍的 Mojo 有何神奇之處?
Mojo 將 Python 的易用性與 C 的性能相結合,釋放了 AI 硬體強大的可程式設計性和 AI 模型的可擴 (n h) s d’, h=self.nheads)’],[20,’\n’,’24:\’NmMJ\’|36:177|direction:\’ltr\”],[20,’ q,k,v = torch.chunk(x, 3, dim=-1)’],[20,’\n’,’24:\’8xN8\’|36:177|direction:\’ltr\”],[20,’ s = (q@k.transpose(1,2))/self.scale’],[20,’\n’,’24:\’uUzu\’|36:177|direction:\’ltr\”],[20,’ x = s.softmax(dim=-1)@v’],[20,’\n’,’24:\’tmUp\’|36:177|direction:\’ltr\”],[20,’ x = rearrange(x, ‘(n h) s d -> n s (h d)’, h=self.nheads)’],[20,’\n’,’24:\’MLpH\’|36:177|direction:\’ltr\”],[20,’ return self.proj(x)’],[20,’\n’,’24:\’dLJW\’|36:177|direction:\’ltr\”],[20,’\n’,’24:\’Ffnr\’|direction:\’ltr\”],[20,’但實際上,這些操作很複雜。例如,在 ‘],[20,’CUDA C’,’16:\’https%3A%2F%2Fgithub.com%2FHazyResearch%2Fflash-attention%2Ftree%2Fmain%2Fcsrc%2Fflash_attn%2Fsrc\”],[20,’ 中進行記憶體最佳化的「快閃記憶體注意」實現。它還掩蓋了這些構建模型的通用方法留下了大量的性能的事實。例如,「塊稀疏」方法可以顯著提高速度和記憶體使用。研究人員正在對常見架構的每個部分進行調整,並提出新的架構(以及 SGD 最佳化器,資料增強方法等)——我們甚至還沒有一個每個人都會永久使用的整齊包裝的系統。’],[20,’\n’,’24:\’2m79\’|direction:\’ltr\”],[20,’\n’,’24:\’DDgE\’|direction:\’ltr\”],[20,’在實踐中,許多用於語言模型的最快程式碼都是用 C 和 C++ 編寫的。例如,Fabrice Bellard 的 TextSynth 和 Georgi Gerganov 的 ggml 都使用 C 語言,因此能夠充分利用完全編譯語言的性能優勢。’],[20,’\n’,’24:\’36PE\’|direction:\’ltr\”],[20,’\n’,’24:\’DN1g\’|32:1|direction:\’ltr\”],[20,’「MLIR 的語法糖」:Mojo’],[20,’\n’,’24:\’8fvq\’|32:1|direction:\’ltr\”],[20,’\n’,’24:\’qZNr\’|direction:\’ltr\”],[20,’Chris Lattner 開發的 LLVM,從根本上改變了編譯器的創建方式,也為世界上許多廣泛使用的語言生態系統打下了堅實的基礎。’],[20,’\n’,’24:\’2qgn\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Hgan\’|7:3|direction:\’ltr\”],[20,’之後,他推出了一個建立在 LLVM 之上的 C 和 C++ 編譯器 Clang,並被廣泛使用。LLVM 包括「中間表示」(IR),這是一種為機器讀寫(而不是人)設計的特殊語言,它使一個龐大的軟體社區能夠協同合作,為更廣泛的硬體提供更好的程式語言功能。’],[20,’\n’,’24:\’D0CZ\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Q2nA\’|7:3′],[20,’Chris Lattner 認為 C 和 C++ 並沒有完全充分利用 LLVM 的威力,因此他在蘋果工作時,設計了一種名為「Swift」的新語言,他將其描述為「LLVM 的語法糖」。如今,Swift 已經成為世界上使用最廣泛的程式語言之一,特別是它創建了 iPhone、iPad、MacOS 和 Apple TV 創建 iOS 應用程序的主要方式。’],[20,’\n’,’24:\’zbPx\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’3O23\’|7:3′],[20,’不幸的是,蘋果對 Swift 的控制導致它還沒有真正在技術領域大放異彩。Chris Lattner 曾在 Google 試圖將 Swift 從蘋果的舒適區移出來,成為 AI 模型開發中 Python 的替代品。但遺憾的是,它沒有得到蘋果或 Google 的支持,最終沒有成功。’],[20,’\n’,’24:\’nlZ9\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’LYql\’|7:3|direction:\’ltr\”],[20,’話雖如此,在 Google 期間,Chris 開發了另一個非常成功的項目:MLIR。MLIR 是 LLVM IR 的替代品,適用於現代多核計算和 AI 工作負載。這對於充分利用 GPU、TPU 等硬體的強大功能以及越來越多地添加到伺服器級 CPU 中的向量單元至關重要。’],[20,’\n’,’24:\’OfP0\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’7f3L\’|7:3|direction:\’ltr\”],[20,’那麼,如果 Swift 是「LLVM 的語法糖」,那麼「MLIR 的語法糖」是什麼?答案是:Mojo!Mojo 是一種全新的語言,旨在充分利用 MLIR。並且,Mojo 也是 Python。’],[20,’\n’,’24:\’TrBA\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’h70y\’|7:3|direction:\’ltr\”],[20,’也許說 Mojo 是 Python++ 更為恰當。它將(完成後)是 Python 語言的嚴格超集。但它也有附加功能,因此,開發者可以編寫利用現代加速器的高性能程式碼。’],[20,’\n’,’24:\’FLR3\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’L0bn\’|7:3|direction:\’ltr\”],[20,’在 Jeremy Howard 看來,Mojo 似乎比 Swift 更實用。雖然 Swift 是一種包含了基於程式語言設計最新研究的各種炫酷功能的全新語言,但 Mojo 的核心是 Python。因為 Python 已經被數百萬程式設計師廣泛使用,並且經過幾十年的使用,它的功能和侷限性已經得到了充分完善。’],[20,’\n’,’24:\’OiOW\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’ARV7\’|7:3|direction:\’ltr\”],[20,’用最新的程式語言進行研究很酷,但它可能具有潛在危險。就 Jeremy Howard 個人而言,他經常被 Swift 強大但古怪的類型系統搞糊塗,有時甚至成功地被 Swift 編譯器混淆並且完全崩潰!’],[20,’\n’,’24:\’OLt6\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’LtSx\’|7:3|direction:\’ltr\”],[20,’Mojo 的一個關鍵技巧是,作為開發人員,您可以隨時選擇加入更快的「模式」。通過使用「fn」而不是「def」來創建函數。在這種模式下,您必須準確確定每個變數的類型,Mojo 可以創建最佳化的機器程式碼來實現您的函數。此外,如果使用「struct」而不是「class」,您的屬性將被打包到記憶體中,這樣它們可以在資料結構中使用,而無需追蹤指針。這些特性使得像 C 這樣的語言變得很快,而現在 Python 程式設計師只需學習一點點新語法即可使用。’],[20,’\n’,’24:\’JP1E\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’f8xX\”],[20,’Mojo 如何做到的?’],[20,’\n’,’24:\’Mmlv\’|32:1|direction:\’ltr\”],[20,’\n’,’24:\’WmBa\’|direction:\’ltr\”],[20,’幾十年來,為了創建簡潔、靈活、快速、實用和易於使用的程式語言,開發者們進行了數百次嘗試。但並沒有取得太大成效。而 Mojo 似乎做到了。我們可以得出一些假設:’],[20,’\n’,’24:\’qIMh\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’LMX0\’|7:3′],[20,’1.Mojo 實際上並沒有實現這些目標,精彩的演示掩蓋了令人失望的現實表現。’],[20,’\n’,’24:\’qalr\’|7:3|direction:\’ltr\”],[20,’2.Modular 是一家擁有數百名開發人員的大型公司,公司為實現未曾實現過的目標付出了多年的努力。’],[20,’\n’,’24:\’OTD4\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Soar\’|7:3|direction:\’ltr\”],[20,’事實上,這兩個假設都不成立。我們舉兩個例子,(matmul 和 mandelbrot)並不是在嘗試了數十種方法後才精心選擇的唯一有效方法;相反,它們是我們為演示而嘗試的一種方法,並且第一次就成功了!雖然在這個早期階段,還是有很多功能的缺失(除了線上「playground」之外,Mojo 還沒有發佈給公眾),但您在演示中看到的確實是它的工作方式。事實上,您現在可以在 playground 中自己運行它。’],[20,’\n’,’24:\’505e\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’KmFt\’|7:3|direction:\’ltr\”],[20,’Modulal 是一家僅成立一年的小初創公司。一個小團隊是如何在短時間內做到這樣的呢?’],[20,’\n’,’24:\’ooEj\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’pDdJ\’|7:3|direction:\’ltr\”],[20,’關鍵一:基礎強大’,’8:1′],[20,’\n’,’24:\’OspC\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’AdWm\’|7:3|direction:\’ltr\”],[20,’關鍵在於 Mojo 是建立在一些非常強大的基礎之上的。Jeremy Howard 表示,很少見到有軟體項目願意花費時間來打好堅實的基礎,並且往往會因此積累大量的技術債務。隨著時間的推移,添加功能和修復錯誤變得越來越困難。然而,在 Mojo 這樣一個設計良好的系統中,每個功能都比上一個更容易添加,速度也更快,出錯率低,每個功能所構建的基礎都越來越好。’],[20,’\n’,’24:\’2Ivi\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’aLN2\’|7:3|direction:\’ltr\”],[20,’其核心是最初是由 Chris Lattner 在 Google 開發的並且使用多年的 MLIR。Chris Lattner 已經意識到「AI 時代程式語言」的核心基礎將需要什麼,並專注於構建它們。MLIR 就是其中的一個關鍵部分。就像 LLVM 在過去十年中極大地簡化了強大的新程式語言的開發一樣(如 Rust、Julia 和Swift,它們都基於 LLVM),MLIR 為建立在其上的語言提供了更強大的核心。’],[20,’\n’,’24:\’RTSF\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’8wMK\’|7:3|direction:\’ltr\”],[20,’關鍵二:使用 Python 作為語法’,’8:1′],[20,’\n’,’24:\’Gi3v\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’wV0d\’|7:3|direction:\’ltr\”],[20,’Mojo 快速發展的另一個關鍵因素是決定使用 Python 作為語法。開發和迭代語法是語言開發中最容易出錯、最複雜和最有爭議的一部分。通過簡單地將其外包給現有的語言,整個部分就會消失!因此,需要少量地在 Python 之上添加的新語法部分來自然適應。’],[20,’\n’,’24:\’7YD5\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’0LoR\’|7:3|direction:\’ltr\”],[20,’接下來是創建一個最小的 Pythonic 方法直接調用 MLIR。這並不是一個大項目,但它需要在此基礎上創建所有 Mojo 所需的全部內容,並直接在 Mojo 中處理其他所有工作。這意味著 Mojo 開發人員從一開始就能「dog-food」 Mojo。當他們在開發 Mojo 時發現某些東西不太好用時,他們可以為 Mojo 本身添加所需的功能,以便更容易開發下一個 Mojo 部分!’],[20,’\n’,’24:\’VPBX\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’xcXW\’|7:3′],[20,’這一點和 Julia 很像。Julia 是在’],[20,’最小的類LISP核心’,’16:\’https%3A%2F%2Fgithub.com%2FJeffBezanson%2Ffemtolisp\”],[20,’上開發的,該核心提供 Julia 語言元素,然後將其綁定到基本的 LLVM 操作。Julia 中的幾乎所有內容都是建立在它之上的。’],[20,’\n’,’24:\’nkPR\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Q7Nr\’|7:3|direction:\’ltr\”],[20,’Modular 團隊內部宣佈,決定通過一個視訊(包括演示)推出 Mojo,並且他們將時間定在了未來幾周之內。那時 Mojo 只是最基本的語言,沒有可用的筆記本核心,幾乎沒有實現任何 Python 語法,也沒有進行任何最佳化。’],[20,’\n’,’24:\’vJt8\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’tuVp\’|7:3|direction:\’ltr\”],[20,’起初,Jeremy Howard 並不理解這個行為。但這段時間,Mojo 的表現讓他歎為觀止。每隔一兩天,就有全新的語言功能被實現。一旦有足夠的語言功能來嘗試運行演算法,它們就能夠立即達到或接近最先進的性能水平!Jeremy Howard 突然意識到 Mojo 所有的基礎都已經建立好了,並且它們被明確設計用於構建現在正在開發的東西。因此,一切都很順利,而且運作良好也就不足為奇了。’],[20,’\n’,’24:\’dsta\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’wNnB\’|7:3′],[20,’這是 Jeremy Howard 對 Mojo 未來持樂觀態度的理由。雖然這個項目還處於早期階段,但根據 Jeremy Howard 在過去幾週中觀察到的情況,他的猜測是它將比大多數人預期的發展得更快、更遠……’],[20,’\n’,’24:\’bQvK\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’vaEI\’|direction:\’ltr\”],[20,’Mojo 關鍵優勢:易於部署’],[20,’\n’,’24:\’kS4U\’|32:1|direction:\’ltr\”],[20,’\n’,’24:\’LIXL\’|direction:\’ltr\”],[20,’這是很關鍵的一點。如果你想把你酷炫的 Python 程序給朋友,你需要讓他們’],[20,’\n’,’24:\’5wq6\’|7:3|direction:\’ltr\”],[20,’先安裝 Python!或者,你可以給他們一個包含 Python 和你使用的所有庫的巨大檔案。’],[20,’\n’,’24:\’osAj\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Fz2s\’|7:3|direction:\’ltr\”],[20,’由於 Python 是一種解釋型語言,所以你的程序的行為將取決於安裝的 python 的確切版本、存在的庫的版本以及它們的配置方式。為了避免維護問題,Python 社區已經確定了幾種選項來安裝 Python 應用程序:環境,每個程序都有一個單獨的Python 安裝;或容器,為每個應用程序設置一整個作業系統。但這兩種方法都會在開發和部署Python 應用程序時產生許多混亂和開銷。’],[20,’\n’,’24:\’JFrx\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Wkh2\’|7:3|direction:\’ltr\”],[20,’將其與部署靜態編譯的 C 應用程序進行比較:您只需將編譯的程序直接下載即可。它的大小可能只有 100k 左右,可以快速啟動和運行。’],[20,’\n’,’24:\’h5K2\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’vM8Z\’|7:3|direction:\’ltr\”],[20,’還有一種 Go 採用的方法,它不能生成像 C 這樣的小型應用程序,而是將「運行時」集成到每個打包的應用程序中。這種方法是 Python 和 C 之間的折中,仍需要數十兆位元組的二進位制檔案,但比 Python 更容易部署。’],[20,’\n’,’24:\’pct9\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’vlLo\’|7:3′],[20,’作為一種編譯語言,Mojo 的部署方式與 C 基本相同。例如,一個包含從頭開始編寫的 matmul 版本的程序大約是 100 k。’],[20,’\n’,’24:\’UeeQ\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’WKFl\’|7:3′],[20,’這意味著 Mojo 不僅僅是面向 AI/ML 應用程序的語言。它實際上是 Python 一種版本,可以幫助我們編寫快速、小巧、易於部署的應用程序,利用所有可用的核心和加速器!’],[20,’\n’,’24:\’U1qT\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’tRxS\’|direction:\’ltr\”],[20,’\n’,’24:\’7k8z\’|direction:\’ltr\”],[20,’Mojo 的替代品’],[20,’\n’,’24:\’Xpfd\’|32:1|direction:\’ltr\”],[20,’\n’,’24:\’eXV2\’|direction:\’ltr\”],[20,’Mojo 並不是解決 Python 性能和部署問題的唯一辦法。在語言方面,Julia 可能是目前最強的替代品。它具有 Mojo 的許多優點,並且構建出了很多優秀的項目。但在 Jeremy Howard 看來,Julia 也並不完美:’],[20,’\n’,’24:\’HloO\’|direction:\’ltr\”],[20,’\n’,’24:\’HevC\’|direction:\’ltr\”],[20,’Julia 面臨的最大挑戰源於其大型運行時,決定在該語言中使用垃圾回收。此外,Julia 中使用的多排程方法雖然打開了很多用語言做很酷的事情的大門,但也會讓開發人員的工作變得非常複雜。’],[20,’\n’,’24:\’uFW1\’|direction:\’ltr\”],[20,’\n’,’24:\’YVMU\’|7:3′],[20,’在 Python 中,目前最好的解決方案可能是 ‘],[20,’Jax’,’16:\’https%3A%2F%2Fjax.readthedocs.io%2Fen%2Flatest%2F\”],[20,’,它有效地使用 Python 創建了一個特定領域的語言(DSL)。這種語言的輸出是 XLA,它是一個早於MLIR的機器學習編譯器(我相信它正在逐漸轉移到MLIR上)。Jax 繼承了 Python(例如,該語言無法表示結構,或直接分配記憶體或創建快速循環)和 XLA(主要針對 TPU,很大程度上限制在機器學習特定的概念上)的限制,但具有巨大的優勢,即不需要新的語言或新的編譯器。’],[20,’\n’,’24:\’mtFh\’|7:3|direction:\’ltr\”],[20,’ ‘],[20,’\n’,’24:\’6g0O\’|7:3|direction:\’ltr\”],[20,’如前所述,還有新的 PyTorch 編譯器,Tensorflow 也能夠生成 XLA 程式碼。就 Jeremy Howard個人而言,這種方式使用 Python 最終並不令人滿意。Jeremy Howard 實際上並沒有使用 Python 的所有功能,但必須使用與其所針對的後端兼容的子集。Jeremy Howard 不能輕鬆地調試和分析編譯後的程式碼,因為很多不確定性,甚至很難知道最終執行的內容。’],[20,’\n’,’24:\’KE2z\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Pote\’|7:3|direction:\’ltr\”],[20,’Jeremy Howard 甚至無法得到一個獨立的二進位制檔案,而必須使用特殊的運行時並處理複雜的 API。’],[20,’\n’,’24:\’AbgL\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’Kq5J\’|7:3|direction:\’ltr\”],[20,’Python 的另一個有趣的方向是 ‘],[20,’Numba’,’16:\’https%3A%2F%2Fnumba.pydata.org%2F\”],[20,’ 和 ‘],[20,’Cython’,’16:\’https%3A%2F%2Fcython.org%2F\”],[20,’。Numba 使用一個特殊的裝飾器,使 Python 函數被編譯成使用LLVM最佳化的機器程式碼。Cython 類似,但還提供了一個類似於 Python 的語言,具有 Mojo 的一些特性,並將這個 Python 方言轉換成 C,然後進行編譯。這些語言都沒有解決部署問題,但它們可以幫助解決性能問題。’],[20,’\n’,’24:\’CRzC\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’mMs8\’|7:3′],[20,’兩者都無法針對具有通用跨平臺程式碼的一系列加速器,儘管 Numba 確實提供了一種非常有用的方法來編寫 CUDA 程式碼(因此可以針對 NVIDIA GPU)。Jeremy Howard 對於 Numba 和 Cython 的存在表示感激,並且認為從它們中獲得了很多。但它們完全不同於使用完整的語言和編譯器生成獨立的二進位制檔案。它們只是Python性能問題的臨時解決方案,對於僅需要解決性能問題的情況是可行的’],[20,’\n’,’24:\’bnE2\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’MRYz\’|7:3′],[20,’但 Jeremy Howard 更喜歡使用一種既像 Python 一樣,又像 C 一樣快的語言,能夠允許其使用一個語言來編寫從應用程序伺服器到模型架構以及安裝程序的所有內容,並且能在編寫程式碼的語言中直接調試和分析其的程式碼。’],[20,’\n’,’24:\’qqu3\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’BrEH\’|7:3′],[20,’你喜歡這樣的語言嗎?歡迎在評論區留言討論。’],[20,’\n’,’24:\’yzdJ\’|7:3|direction:\’ltr\”],[20,’\n’,’24:\’0SAI\’|direction:\’ltr\”],[20,’\n’,’24:\’hxif\’|direction:\’ltr\”],[20,’參考連結:’],[20,’\n’,’24:\’4Ko2\’|direction:\’ltr\”],[20,’https://www.fast.ai/posts/2023-05-03-mojo-launch.html’,’0:\’rgb(65%2C%2070%2C%2075)\’|16:\’https%3A%2F%2Fwww.fast.ai%2Fposts%2F2023-05-03-mojo-launch.html\’|1:\’rgb(255%2C%20255%2C%20255)\’|27:\’9\’|31:2′],[20,’\n’,’24:\’INNX\’|direction:\’ltr\”],[20,’https://www.modular.com/mojo’,’0:\’rgb(65%2C%2070%2C%2075)\’|16:\’https%3A%2F%2Fwww.modular.com%2Fmojo\’|1:\’rgb(255%2C%20255%2C%20255)\’|27:\’9\’|31:2′]]” data-copy-origin=”https://shimo.im” style=”outline: 0px; font-size: 15px; color: rgba(0, 0, 0, 0.9); font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, ‘Helvetica Neue’, ‘PingFang SC’, ‘Hiragino Sans GB’, ‘Microsoft YaHei UI’, ‘Microsoft YaHei’, Arial, sans-serif; visibility: visible;”>展性。使用 Mojo 可以編寫比 C 更快、可移植的程式碼,並與 Python 生態系統無縫互動。最重要的是,Mojo 具備了使用 Python 庫整個生態系統的能力。
一、可用性和可程式設計性
Mojo 能夠對大量低級 AI 硬體進行程式設計,無需 C++ 或 CUDA。
二、性能
在用最先進的編譯器和異構運行時,Mojo 能夠利用硬體的全部功能,包括多核、向量單元和加速器單元,在不復雜的前提下,實現與 C++ 和 CUDA 相當的性能。
除此之外,根據官網測試結果,Mojo 比 Python 快 35000 倍。

三、互操作性
Mojo 可以訪問 Numpy 和 Matplotlib 等任意庫以及所有使用者自定義程式碼。
四、可擴展性
Mojo 可以通過預處理和後處理操作輕鬆擴展模型,或將操作替換為自定義操作。並且能夠利用核心融合、圖形重寫、形狀函數等。
目前,Mojo 仍在不斷完善中,但開發者可以在 Modular AI 基於 JupyterHub 的 Playground 進行試用。使用者可以通過閱讀教程編寫自己的 Mojo 程式碼。
試用地址:https://docs.modular.com/mojo/get-started.html
Mojo 的官宣在網上引起了不小的討論,Jeremy Howard 體驗後更是髮長文向大家安利了 Mojo。在他看來,Mojo 是 Python++ 更為恰當,並且比 Swift 更實用。他直言自己更喜歡使用一種既像 Python 優雅,又像 C 一樣快的語言,能夠允許其使用一個語言來編寫從應用程序伺服器到模型架構以及安裝程序的所有內容,並且能在編寫程式碼的語言中直接調試和分析其程式碼。

為什麼不直接使用 Python ?
缺點一:性能缺陷
Python 有幾乎完美的核心,它可以做任何事情。但它也有一個缺點:性能。Python 比像 C++ 這樣的語言慢幾千倍。因此,將 Python 用於程式碼性能的關鍵部分不切實際。
但 Python 有一個絕招:它可以調用快速語言編寫的程式碼。因此,Python程式設計師不用 Python 來實現性能關鍵部分的程式碼。比如 Numpy 和 PyTorch 這樣的庫為高性能程式碼提供了「pythonic」接口,讓 Python 程式設計師有種賓至如歸的感覺。
缺點二:「雙語言”問題
如今,幾乎所有的 AI 模型都是用 Python 開發,這要歸功於其靈活、完美的程式語言、高效的工具和生態系統,以及高性能的編譯庫。
但這種「雙語言」方法有嚴重的缺點。例如,AI 模型通常必須用 Python 轉換為更快的實現,如 ONNX 或 torchscript。但這些部署方法不能支持 Python 的所有功能,因此 Python 程式設計師必須學會使用與其部署目標匹配的語言子集。並且,很難對部署版本的程式碼進行分析或調試,也不能保證它能夠和 Python 版本完全相同地運行。
這種雙語言問題妨礙了學習,使得開發者無法在程式碼運行時執行演算法的實現,或者跳轉到感興趣的方法定義,而是陷入 C 庫和二進位制檔案的細節中。對於 AI 領域的快速發展,開發者們都需要學習。但無論是經驗豐富的開發者還是入門的學生,仍面臨很多困難。
當嘗試調試程式碼或查找和解決性能問題時,同樣會出現這個問題。雙語言問題意味著,一旦我們進入後端實現語言,Python 程式設計師熟悉的工具就不再適用。
即使使用最快的編譯實現語言來編寫庫,也會出現無法避免的性能問題。一個主要問題是缺乏「融合」——也就是說,連續調用一堆編譯函數會帶來大量的開銷,因為資料被轉換為 Python 格式和從 Python 格式轉換,並且必須重複從 Python 到 C 的切換成本。
因此,我們必須編寫常見函陣列合的特殊「融合」版本,並從 Python 調用這些融合版本。這意味著需要實現和記憶更多的庫函數,稍有差錯,就很難有一個合適的融合版本。
我們還必須處理 Python 中缺乏有效並行處理的問題。如今,我們都有具備多個核心的計算機,但 Python 通常只會一次使用一個核心。有一些笨重的方法可以編寫使用多個核的並行程式碼,但它們要麼必須在完全分離的記憶體上工作(並且啟動開銷大),要麼必須交替訪問記憶體(可怕的「全局直譯器鎖定」通常使並行程式碼比單執行緒程式碼實際上更慢!)
像 PyTorch 這樣的庫一直在開發越來越巧妙的方法來處理這些性能問題,新發布的 PyTorch 2 甚至包括一個 compile() 函數,該函數使用複雜的編譯後端來創建 Python 程式碼的高性能實現。然而,這樣的功能不能發揮魔力:基於語言本身的設計,Python 的可能性存在根本性限制。
除此之外,它們總體上都是非常基本的演算法,例如,transformer 模型幾乎完全由多層感知器(MLP)和注意力實現,只需幾行 Python 和 PyTorch 即可實現。以下是 MLP 的實現:
nn.Sequential(nn.Linear(ni,nh), nn.GELU(), nn.LayerNorm(nh), nn.Linear(nh,ni))
這是一個自我注意層:
def forward(self, x):
x = self.qkv(self.norm(x))
x = rearrange(x, 'n s (h d) -> (n h) s d', h=self.nheads)
q,k,v = torch.chunk(x, 3, dim=-1)
s = (q@k.transpose(1,2))/self.scale
x = s.softmax(dim=-1)@v
x = rearrange(x, '(n h) s d -> n s (h d)', h=self.nheads)
return self.proj(x)
但實際上,這些操作很複雜。例如,在 CUDA C 中進行記憶體最佳化的「快閃記憶體注意」實現。它還掩蓋了這些構建模型通用方法所留下的大量性能事實。例如,「塊稀疏」方法可以顯著提高速度和記憶體使用。研究人員正在對常見架構的每個部分進行調整,並提出新的架構(以及 SGD 最佳化器,資料增強方法等)——我們甚至還沒有適合每個人都會永久使用的整齊包裝系統。
在實踐中,許多用於語言模型的最快程式碼都是用 C 和 C++ 編寫的。例如,Fabrice Bellard 的 TextSynth 和 Georgi Gerganov 的 ggml 都使用 C 語言,因此能夠充分利用完全編譯語言的性能優勢。

「MLIR 的語法糖」:Mojo
Chris Lattner 開發的 LLVM,從根本上改變了編譯器的創建方式,也為世界上許多廣泛使用的語言生態系統打下了堅實的基礎。
之後,他推出了一個建立在 LLVM 之上的 C 和 C++ 編譯器 Clang,並被廣泛使用。LLVM 包括「中間表示」(IR),這是一種為機器讀寫(而不是人)設計的特殊語言,它使一個龐大的軟體社區能夠協同合作,為更廣泛的硬體提供更好的程式語言功能。
Chris Lattner 認為 C 和 C++ 並沒有完全充分利用 LLVM 的威力,因此他在蘋果工作時,設計了一種名為「Swift」的新語言,他將其描述為「LLVM 的語法糖」。如今,Swift 已經成為世界上使用最廣泛的程式語言之一,它是 iPhone、iPad、MacOS 和 Apple TV 創建 iOS 應用程序的主要方式。
不幸的是,蘋果對 Swift 的控制導致它還沒有真正在技術領域大放異彩。Chris Lattner 曾在 Google 試圖將 Swift 從蘋果的舒適區移出來,成為 AI 模型開發中 Python 的替代品。但遺憾的是,它沒有得到蘋果或 Google 的支持,最終沒有成功。
話雖如此,在 Google 期間,Chris 開發了另一個非常成功的項目:MLIR。MLIR 是 LLVM IR 的替代品,適用於現代多核計算和 AI 工作負載。這對於充分利用 GPU、TPU 等硬體的強大功能以及越來越多地添加到伺服器級 CPU 中的向量單元至關重要。
那麼,如果 Swift 是「LLVM 的語法糖」,那麼「MLIR 的語法糖」是什麼?答案是:Mojo!Mojo 是一種全新的語言,旨在充分利用 MLIR。並且,Mojo 也是 Python。
也許說 Mojo 是 Python++ 更為恰當。它將(完成後)是 Python 語言的嚴格超集。但它還會有額外的功能,因此,開發者可以編寫利用現代加速器的高性能程式碼。
在 Jeremy Howard 看來,Mojo 似乎比 Swift 更實用。雖然 Swift 是一種包含了基於程式語言設計最新研究的各種炫酷功能的全新語言,但 Mojo 的核心是 Python。因為 Python 已經被數百萬程式設計師廣泛使用,並且經過幾十年的使用,它的功能和侷限性已經得到了充分完善。
用最新的程式語言進行研究很酷,但它可能具有潛在危險。就 Jeremy Howard 個人而言,他經常被 Swift 強大但古怪的類型系統搞糊塗,有時甚至成功地被 Swift 編譯器混淆並且完全崩潰!
Mojo 的一個關鍵技巧是,作為開發人員,您可以隨時選擇加入更快的「模式」。通過使用「fn」而不是「def」來創建函數。在這種模式下,您必須準確確定每個變數的類型,Mojo 可以創建最佳化的機器程式碼來實現函數。此外,如果使用「struct」而不是「class」,您的屬性將被打包到記憶體中,這樣它們可以在資料結構中使用,而無需追蹤指針。這些特性使得像 C 這樣的語言變得很快,而現在 Python 程式設計師只需學習一點點新語法即可使用。

Mojo 如何做到的?
幾十年來,為了創建簡潔、靈活、快速、實用和易於使用的程式語言,開發者們進行了數百次嘗試。但並沒有取得太大成效。而 Mojo 似乎做到了。我們可以得出一些假設:
1.Mojo 實際上並沒有實現這些目標,精彩的演示掩蓋了令人失望的現實表現;
2.Modular 是一家擁有數百名開發人員的大型公司,公司為實現未曾實現過的目標付出了多年的努力。
事實上,這兩個假設都不成立。我們舉兩個例子,(matmul 和 mandelbrot)並不是在嘗試了數十種方法後才精心選擇的唯一有效方法;相反,它們是我們為演示而嘗試的一種方法,並且第一次就成功了!雖然在早期階段還有很多功能的缺失(除了線上「playground」之外,Mojo 還沒有發佈給公眾),但在演示中看到的確實是它的工作方式。事實上,您現在可以在 playground 中自己運行它。
Modulal 是一家僅成立一年的小初創公司。一個小團隊是如何在短時間內做到這樣的呢?
關鍵一:基礎強大
關鍵在於 Mojo 是建立在一些非常強大的基礎之上的。Jeremy Howard 表示,很少見到有軟體項目願意花費時間來打好堅實的基礎,並且往往會因此積累大量的技術債務。隨著時間的推移,添加功能和修復錯誤變得越來越困難。然而,在 Mojo 這樣一個設計良好的系統中,每個功能都比上一個更容易添加,速度也更快,出錯率低,每個功能所構建的基礎都越來越好。
其核心是最初是由 Chris Lattner 在 Google 開發的並且使用多年的 MLIR。Chris Lattner 已經意識到「AI 時代程式語言」的核心基礎將需要什麼,並專注於構建它們。MLIR 就是其中的一個關鍵部分。就像 LLVM 在過去十年中極大地簡化了強大的新程式語言的開發一樣(如 Rust、Julia 和Swift,它們都基於 LLVM),MLIR 為建立在其上的語言提供了更強大的核心。
關鍵二:使用 Python 作為語法
Mojo 快速發展的另一個關鍵因素是使用 Python 作為語法。開發和迭代語法是語言開發中最容易出錯、最複雜和最有爭議的一部分。通過簡單地將其外包給現有的語言,整個部分就會消失!因此,需要少量地在 Python 之上添加的新語法部分來自然適應。
接下來是創建一個最小的 Pythonic 方法直接調用 MLIR。這並不是一個大項目,但它需要在此基礎上創建所有 Mojo 所需的全部內容,並直接在 Mojo 中處理其他所有工作。這意味著 Mojo 開發人員從一開始就能「dog-food」 Mojo。當他們在開發 Mojo 並發現某些東西不太好用時,他們可以為 Mojo 本身添加所需的功能,以便更容易開發下一個 Mojo 部分!
這一點和 Julia 很像。Julia 是在最小類 LISP 核心上開發的,該核心提供 Julia 語言元素,然後將其綁定到基本的 LLVM 操作。Julia 中的幾乎所有內容都是建立在它之上。
Modular 團隊決定通過視訊(包括演示)推出 Mojo,並且他們將時間定在了未來幾周之內。那時 Mojo 只是最基本的語言,沒有可用的筆記本核心,幾乎沒有實現任何 Python 語法,也沒有進行任何最佳化。
起初,Jeremy Howard 並不理解這個行為。但這段時間,Mojo 的表現讓他歎為觀止。每隔一兩天,就有全新的語言功能被實現。一旦有足夠的語言功能來嘗試運行演算法,它們就能夠立即達到或接近最先進的性能水平!Jeremy Howard 突然意識到 Mojo 所有的基礎都已經建好了,並且它們被明確設計用於構建現在正在開發的東西。因此,一切都很順利,而且運作良好。
這是 Jeremy Howard 對 Mojo 未來持樂觀態度的理由。雖然這個項目還處於早期階段,但根據 Jeremy Howard 在過去幾週中觀察到的情況,他的猜測是它將比大多數人預期的發展得更快、更遠……

Mojo 關鍵優勢:易於部署
這是很關鍵的一點。如果你想把你酷炫的 Python 程序給朋友,你需要讓他們先安裝 Python!或者,你可以給他們一個包含 Python 和你使用的所有庫的巨大檔案。
由於 Python 是一種解釋型語言,所以程序的執行將取決於所安裝 Python 的確切版本、存在的庫的版本以及它們的配置方式。為了避免維護問題,Python 社區已經確定了幾種選項來安裝 Python 應用程序:環境,每個程序都有一個單獨的 Python 安裝或容器,為每個應用程序設置一整個作業系統。但這兩種方法都會在開發和部署 Python 應用程序時產生許多混亂和開銷。
將其與部署靜態編譯的 C 應用程序進行比較:您只需將編譯的程序直接下載即可。它的大小可能只有 100k 左右,可以快速啟動和運行。
還有一種 Go 採用的方法,它不能生成像 C 這樣的小型應用程序,而是將「運行時」集成到每個打包的應用程序中。這種方法是 Python 和 C 之間的折中,仍需要數十兆位元組的二進位制檔案,但比 Python 更容易部署。
作為一種編譯語言,Mojo 的部署方式與 C 基本相同。例如,一個包含從頭開始編寫的 matmul 版本的程序大約是 100 k。
這意味著Mojo不僅僅是用於AI/ML應用的語言。它實際上是Python的一個版本,允許開發者編寫快速、小巧、易於部署的應用程序,並利用所有可用的核心和加速器!

Mojo 的替代品
Mojo 並不是解決 Python 性能和部署問題的唯一辦法。在語言方面,Julia 可能是目前最強的替代品。它具有 Mojo 的許多優點,並且構建出了很多優秀的項目。但在 Jeremy Howard 看來,Julia 也並不完美。
Julia 面臨的最大挑戰源於其大型運行時,決定在該語言中使用垃圾回收。此外,Julia 中使用的多排程方法雖然打開了很多用語言做很酷的事情的大門,但也會讓開發人員的工作變得非常複雜。
在 Python 中,目前最好的解決方案可能是 Jax,它有效地使用 Python 創建了一個特定領域的語言(DSL)。這種語言的輸出是 XLA,它是一個早於 MLIR 的機器學習編譯器。Jax 繼承了 Python(例如,該語言無法表示結構,或直接分配記憶體或創建快速循環)和 XLA(主要針對 TPU,很大程度上限制在機器學習特定的概念上)的限制,但具有巨大的優勢,即不需要新的語言或新的編譯器。
如前所述,還有新的 PyTorch 編譯器,Tensorflow 也能夠生成 XLA 程式碼。就 Jeremy Howard 個人而言,這種方式使用 Python 最終並不令人滿意。Jeremy Howard 實際上並沒有使用 Python 的所有功能,但必須使用與其所針對的後端兼容的子集。Jeremy Howard 不能輕鬆地調試和分析編譯後的程式碼,因為很多不確定性,甚至很難知道最終執行的內容。
Jeremy Howard 甚至無法得到一個獨立的二進位制檔案,而必須使用特殊的運行時並處理複雜的 API。
Python 的另一個有趣的方向是 Numba 和 Cython。Numba 使用一個特殊的裝飾器,使 Python 函數被編譯成使用 LLVM 最佳化的機器程式碼。Cython 類似,但還提供了一個類似於 Python 的語言,具有 Mojo 的一些特性,並將這個 Python 方言轉換成 C,然後進行編譯。這些語言都沒有解決部署問題,但它們可以幫助解決性能問題。
兩者都無法針對具有通用跨平臺程式碼的一系列加速器,儘管 Numba 確實提供了一種非常有用的方法來編寫 CUDA 程式碼(因此可以針對 NVIDIA GPU)。Jeremy Howard 對於 Numba 和 Cython 的存在表示感激,並從中受益匪淺。然而,它們並不像使用完整語言和編譯器生成獨立二進位制檔案一樣。它們只是 Python 性能問題的臨時解決方案,在僅需要這些功能的情況下可以使用。
Jeremy Howard 最後表示,他更喜歡使用一種既優雅如 Python,又快速如專業編寫的 C 語言,允許他使用同一種語言編寫應用程序伺服器、模型架構以及安裝程序,並可以直接在自己編寫程式碼的語言中進行調試和分析。
你喜歡這樣的語言嗎?歡迎在評論區留言討論。
參考連結:
https://www.fast.ai/posts/2023-05-03-mojo-launch.html
https://www.modular.com/mojo