蘋果晶片叢集:大型語言模型實驗
即使連接了四台 Mac Studio,我仍然無法達到綠色的 EXO 狀態。Mac Studio 叢集真不好搞!今天我將進行一些實驗。
記憶體需求與 GPU 的侷限
- 機器學習模型需要大量的記憶體。
- 通常會使用高階 GPU,因為它們在運行並行任務時速度更快,勝過 CPU。
- 但是,Nvidia 的 H100 等專業 GPU 價格非常昂貴、耗電,且記憶體仍然有限。
- 即使是 RTX5090 等消費級 GPU 也很昂貴、耗電,且記憶體更少(最高 32GB),而且還很難找到。
Apple 晶片的優勢
- Apple 晶片機雖然不如 Nvidia GPU 快,但它們更容易取得、超省電,且擁有大量的記憶體,可以與 GPU 共享。
- 這使得能夠輕鬆運行 700 億參數的模型。
- 例如,M4 Max 128GB 機器可以輕鬆運行此模型,使用 65GB 的記憶體。
範例:JavaScript 函數生成
- 以 10 tokens/秒 的速度產生程式碼。
- 儘管速度不是最快的,但可以正常工作。
大型語言模型的需求
- 現今你可以本地運行的開源大型語言模型,參數可以高於 700 億。
- 這些模型需要驚人的記憶體量,例如:
- Llama:4050 億參數
- Deepseek R1:6710 億參數
- 參數越多,模型就越強大。一個擁有 10 億參數的模型可能只會產生亂碼,而 6710 億參數的模型會產生更好的結果。
Mac Studio 的記憶體配置
- Apple 最近推出了 Mac Studio,具備 512GB 的統一記憶體。
- 儘管要價 1 萬美元,但相較於同等級的 Nvidia GPU 仍然更便宜。
- 測試集群中的所有 Mac Studio 均配置了 128GB 的記憶體,並且都使用 M4 Max 晶片。
叢集方式:EXO 與 MLX Distributed
- EXO 是一種進行叢集的方式。
- 另一種方式是 MLX distributed,這是 Apple 對應 Nvidia GPU 上 CUDA 的解決方案。
MLX Distributed 的優勢
- MLX distributed 專門針對 Apple 晶片進行優化,因此速度更快。
- 已載入名為 Deepc Coder V2 light instruct 的模型,並且完全卸載到 GPU。
- 範例:產生 JavaScript 函數。
- 速度非常快,達到 115 tokens/秒。
- 再次測試確認,速度約為 113 tokens/秒。
MLX 效能比較
- 載入相同模型的 MLX 版本,即 dc coderv2 light instruct。
- MLX 的速度更快,達到 168 tokens/秒。
- 再次測試確認,速度約為 163 tokens/秒。
- MLX 經過 Apple 晶片的優化,MLX distributed 允許在 Mac 叢集上運行機器學習模型。
MLX Distributed 設定
- 連結到 AI 開發者撰寫的 MLX 設定教學文章。
- 提供一個更詳細的指南和腳本的儲存庫。
- 腳本假設了一些條件,因此請仔細閱讀說明。
必要條件
- 所有機器都必須啟用 SSH,並且允許在所有機器之間進行無密碼登入。
- 使用 Conda 配置 Python 環境,以隔離 Python 環境。
- 所有機器上必須具有完全相同的 Conda 環境。
- 在單一機器上建立環境,完成所有設定,並確認叢集(單一節點)可以正常工作。
設定步驟
- 在主機檔案中定義一個主機名稱。
- 使用命令和提示字元啟動 MLX 指令。
- 使用 Deep Sea Coder V2 light instruct 4-bit MLX 模型(純 MLX)。
- 速度達到 173 tokens/秒,優於 LM Studio。
- 使用 Mactop 檢測 GPU 使用率是否達到 100%。
環境配置
- 前往主文件夾,找到 minion 文件夾,然後找到 environments 文件夾。
- 將 mlx disc 文件夾複製到所有其他機器上的 environments 文件夾。
- 對專案文件夾執行相同的操作。
專案設定
- 專案文件夾可以從儲存庫複製或自行建立。
-
它需要包含兩個文件:
hosts.json
:描述叢集中的特定主機。- 主機:機器名稱。
- 建立一個本機網路,以便所有機器都可以直接以 10Gbps 的速度互相通訊。
- 所有機器都配備了 10 Gigabit 乙太網路卡。
- 檢查主機名稱並進行重命名:
- 前往系統設定。
- 選擇「一般」。
- 選擇「共享」。
- 啟用遠端登入(SSH)。
- 在下方,可以編輯本機主機名稱。
網路速度測試
- 從一台機器 SSH 到另一台機器,無需密碼。
- 使用
iperf
檢查機器之間的速度。- 將一台機器設定為伺服器。
- 另一台機器使用
iperf -C
命令連接到伺服器。
- 通過乙太網路埠,速度可達 9.4 GB/s。
Thunderbolt 橋接
- 如果未使用乙太網路埠,請拔除它們,然後使用 Thunderbolt 橋接。
- 將機器連接在一起,形成一個 hub-and-spoke 的結構。
- 前往「系統設定」>「網路」>「Thunderbolt 橋接」,然後在 TCP/IP 下的「詳細資訊」中手動配置 IP 位址。
- 在使用 Thunderbolt 5 時,速度明顯更快,達到 65 Gbit/s。
- 但對於 MLX distributed 來說,這並不會帶來明顯的效能提升,因為所有模型的完整檔案都已經儲存在每台機器上。
增加主機到叢集
- 在主機檔案中複製一行,並將主機名稱更改為
ams-2
。 - 再次運行命令。
- 要求總結相對論,速度達到 107 tokens/秒。
- 當使用兩台機器時,速度略有下降。
- GPU 使用率未達到 100%,僅達到約 50% 到 60%。
多節點測試
- 添加所有四台機器。
- 所有四台機器都在工作,顯示 GPU 和記憶體使用率。
- 速度下降到 79 tokens/秒。
- 隨著添加的機器越多,tokens/秒 的速度下降越明顯。
大型模型測試:DeepSeek R1
- 在單一主機上運行 DeepSeek R1 (6710 億參數) 會出現什麼情況?
- 使用 LM Studio 搜尋 Deep Seek 1,然後選擇 MLX 而不是 GGUF。
- 顯示模型過大,無法在機器上運行,因為它需要 420GB 的記憶體。
- 嘗試運行 DeepSeekar1 4bit。
- 記憶體使用量迅速增加,達到 120GB,然後進程終止。
雙節點測試
- 嘗試在兩個主機上運行。
- 如果模型不在其中一台機器上,則需要先下載。
- 更快的解決方案:將模型複製到所有機器上的快取目錄中。
- 在 Home 目錄中,按 Shift + Command + 句號 來顯示隱藏檔案和文件夾。
- 前往快取 > huggingface > hub。
- Deepsear 4-bit 模型的大小為 420GB。
- 使用 Thunderbolt 5 硬碟傳輸模型。
雙節點執行結果
- 在雙節點運行該模型,但似乎沒有任何反應。
- 記憶體使用量增加,達到 70GB(雙機器的記憶體總和為 140GB),然後崩潰。
- 計算表明,兩個 128GB 的機器無法容納該模型。
四節點測試
- 添加其他機器。
- 所有機器上的記憶體使用量都增加。
- 每個機器的 GPU 使用率約為 40%,且開始列印文字。
- 全參數 6710 億模型在叢集上運行,速度為 15 tokens/秒。
M3 Ultra 對比叢集
- M3 Ultra 是否能勝過叢集的 15 tokens/秒?
- 128GB * 4 = 512GB,與這台機器上的 RAM 相符。
- 處理完成後,記憶體使用量會完全降低。
- 每次查詢都需要重新填滿記憶體。
- 可以使用 LM Studio 等工具將資料保存在記憶體中。
MLX 版本比較
- 啟動 Deep Sea Coder Light(小型模型)的 MLX 版本。
- 比較與叢集的速度差異。
- 速度非常快,達到 166 tokens/秒。
M4 Max 對比 M3 Ultra
- M4 Max 的速度很快。
- M3 Ultra 應該更快。
- 但 M3 Ultra 的速度只有 146 tokens/秒,甚至更慢。
- 測試 Llama 3.700 億模型,並將所有圖層卸載到 GPU。
- M4 Max 的速度約為 10 tokens/秒。
- M3 Ultra 的速度約為 13.27 tokens/秒,符合預期。
- Geekbench 多核心結果顯示,M4 Max 的分數約為 25000-26000,而 M3 Ultra 的分數約為 29000,提升幅度不大。
- M3 Ultra 的價格更高,但效能提升並不明顯。
大型模型測試:Deepseek R1(M3 Ultra)
- Deepseek R1 4bit 必須將整個模型讀入記憶體。
- 記憶體使用量達到 407GB,但仍在安全範圍內。
- 能流暢輸出理論,速度達到 19 tokens/秒。
功耗比較
- 叢集:150W
- M3 Ultra:251W
Deepseek V3 測試
- 搜尋 Deepseek R1 的 8-bit 量化版本。
- 找到了 Deepseek V3,它有 8-bit 量化版本,大小約為 750GB。
- MLXLM 工具(GitHub)支援 DeepSseek V3,並且可以動態分配機器之間的負載。
- 即使有 512GB 的機器,仍然會嘗試在每台機器上使用 150GB,這是不可能的。
- 與 Apple 的 Anie 聯繫,他建議修改 pipeline 函數,使其能夠靜態分配給機器,以使 128GB 的機器使用 120GB,而更大的機器處理更多的模型。
實驗結果
- 對 4-bit 模型進行了測試,檢查結果是否正確,減少了等待時間。
- 指定由大型機器處理的層數。
- 512GB 的機器使用了 305GB 的記憶體。
- 小機器使用量約為 73GB。
- 記憶體壓力圖表外觀與小機器完全相同。
- 調整 split 設定,並嘗試改善 tokens/秒 的速度。
DeepS v3 的效能
- 16.482 的 tokens/秒 對於 DeepS v3 來說是不錯的速度。
8-bit 版本測試
- 下載巨型模型需要很長時間。
- 大型模型需要將所有五台機器叢集在一起。
- 最大的挑戰是不均勻分配。
- MLX distributed 使用 MPI(訊息傳遞介面),這是一種用於電腦之間相互通訊和控制的底層介面。
- MPI 不考慮主機檔案中指定的機器順序。
- 即使將 512GB 的機器指定為第一台(索引 0),也不能保證它會獲得 rank 0。
最終配置
- 創建一個 rank 文件,將主機名稱 a5 綁定到 rank 0。
- 修改命令:
bash mlx launch --hostfile hosts MPI --mpi_args map-by rankfile rankfile.txt
- 運行測試。
- 小機器使用量:
- 87 GB
- 92 GB
- 51 GB
- 92 GB
- 大機器使用量正在增加,達到了 400GB。
- 雖然記憶體分割出來了,分配到各節點,但最後還是因為記憶體出錯而停止。
Ivan 的測試結果
- Ivan 使用了兩個 512GB M3 Ultra 機器。
- 8-bit 版本的速度為 12 tokens/秒,這是不錯的。
- 如果使用 MLX distributed 進行叢集,最好使用完全相同的機器。
- 希望有人可以找出如何在不同機器之間分配負載的方法。
總結
- 哪種設定最適合?
- Mac Studio 配備 512GB,無需叢集就能獲得大量記憶體。
- 與購買多個機器以匹配 512GB 機器相比,單一機器可能更划算。
- 可以購買多個 3060 或 3070,它們更便宜,但需要考慮設定成本和營運成本。
Apple 晶片叢集方案
- EXO:簡單且自動,非常適合。
- MLX distributed:另一個不錯的選擇。
- 乙太網路 vs Thunderbolt:
- Thunderbolt:資料傳輸速度更快。
- 乙太網路:設定更容易,更靈活,更穩定。
- 叢集只適用於過大的模型。
- 對於較小的模型(300 億 - 700 億參數),單一 128GB 機器已經足夠。
最終測試
- 五台 Mac Studio 和一台 MacBook Pro 是否能夠運行模型?
- 五個 Mac Studios 和一台 MacBook Pro 成功了!