拿20年前的蘋果“古董”筆記本跑模型推理:九分之一現代CPU速度,但成功了!

 整理 | 華衛、核子可樂
眾所周知,大語言模型(LLM)往往對硬體要求很高。近日,軟體工程師 Andrew Rossignol 成功在一臺“古董”老筆記本 PowerBook G4 上運行了生成式 AI。
據瞭解,這檯筆記本已有 20 年曆史,僅配備 1.5 GHz PowerPC G4 處理器和 1 GB 記憶體,但仍然順利跑起了 Meta 的 Llama 2 大模型推理任務。此番實驗移植了開源 llama2.c 專案,而後使用名為 AltiVec 的 PowerPC 向量擴充套件提升效能表現。
在 PowerBook G4 上執行 TinyStories 110M Llama 2 大模型推理任務。
Rossignol 在一篇部落格裡,完整介紹了關於此專案的所有過程和更多技術細節。以下是經不改變原意的翻譯和整理後的部落格原文:
1 另闢蹊徑,慢慢思考:在 PowerPC Mac 上執行大模型
為舊硬體注入新生命永遠是件令人心曠神怡的好事,也是我本人的愛好之一。讓現代軟體在幾十年前設計的系統上執行起來,對我總有種難以抗拒的吸引力。而在近年深入研究大語言模型(LLM)的過程中,這種衝動也一直縈繞在我的腦海:能不能把 AI 的前沿技術引入自己那臺代表舊日榮光的 2005 款 PowerBook G4 中?藉助一塊 1.5 GHz 處理器、整整 1 GB 的記憶體和 32 位定址空間,我開始了實驗並最終取得了成功。而透過在蘋果經典筆記型電腦上跑起大模型推理,我們證明即使是陳舊的硬體也完全可以牽手代表未來的 AI 新成果。
我首先選擇了 Andrej Karpathy 的 llama2.c 專案——這個出色的專案僅使用一個 C 檔案就實現了 Llama 2 大模型推理。其中沒有使用到任何加速器,效能完全靠專案的簡單性實現,也讓我找到了實現推理的基本思路。
我將其核心實現分叉成了名叫 ullm 的新專案。核心演算法保持不變,但我花了一些時間對程式碼做出改進,增強了其穩健性。
2 程式碼改進
我從最基礎的改進著手,陸續添加了系統函式的打包器,例如檔案 I/O 和記憶體分配機制,藉此降低程式檢測難度。
  • 引入狀態返回,刪除所有 exit 呼叫。
  • 抽象檔案訪問以簡化狀態處理。
  • 抽象 malloc/free 以進行簡單的除錯 / 分析。
  • 將 512 位元組靜態 LUT 替換為單字串。
  • 修復了使用 -Wall 編譯時的一些警告提示。
3 從庫入手
我把程式碼組織成庫以便於大規模修復,這套庫具有由標頭公開的公共 API,因此可以進行單元測試、確保進一步重構不致破壞其推理功能。
該庫需要兩條輸入:其一為 const config,負責提供模型路徑、rng seed 與 token 輸出回撥等細節資訊;其二則是 state,負責跟蹤載入權重、臨時緩衝區和 tokenizer 狀態等。
生成的 API 測試起來非常簡單,並可輕鬆為其構建命令列介面工具。
4 基於回撥的輸出與測試
由於遷移至公共 API,因此我們可以輕鬆使用回撥替換掉基於 printf 的輸出,這樣就能讓推理引擎持續生成 token。這也是後續實現端到端推理管道整合測試所必需的最後一條變更。
5 內部結構
除了公共 API 之外,我還重新組織了其內部結構。在改進之後,程式碼變得相對優雅,同時刪除了所有 exit 呼叫,以便在初始化或推理過程中失敗時進行狀態傳播。
6 移植到 PPC
為了適應執行 gcc 4.x(大家沒看錯)工具鏈的 PowerPC Mac,我還做了額外的調整。最核心的問題就是 PowerPC 7447B CPU 為大端處理器,而如今釋出的模型檢查點和標記器則預設使用小端處理器。在首次測試時 malloc 達到 2 GB,明顯是出了問題。從種種跡象來看,模型明顯是在從檔案中讀取小端值。
  • 大小端:將模型檢查點 / 標記器從小端轉換為大端。
  • 對齊,16 位元組:將權重複制到記憶體中,而非進行記憶體對映。
  • 效能:AltiVec。
在解決了錯誤並完成上述結構變更後,我使用 x86 Dell PowerEdge T440 主力機實現了輸出奇偶校驗。
以下是我編寫的,用於切換模型檢查點的粗略程式碼:
7 模型
Llama2.c 專案推薦使用 TinyStories 模型,而且理由非常充分。這些小模型無需任何專門的硬體加速,即可生成特定形式的輸出。
在實驗中,我使用 15M 模型變體進行了大部分測試,之後又切換到保真度最高的 110M 模型。這已經是上限了,更大的模型要麼 32 位定址空間裝不下,要麼在現有硬體的 CPU 和可用記憶體頻寬上執行速度太慢。
好訊息是,這些模型確實能創作出不少異想天開的兒童故事,讀起來那是相當有趣。而由於體量相對較小,它們也讓我在除錯架構難題時感受相對輕鬆。
8 效能
為了在蘋果與戴爾硬體間直觀比較效能,我選擇啟用編譯器最佳化(-O2)的單執行緒推理選項。
在單一英特爾至強 Silver 4216 3.2 GHz 核心上執行推理時,其基準效能結果如下:
I ullm.llama2: Complete: 6.91 token/s
real    0m26.511s
user    0m26.019s
sys     0m0.472s
可以看到,戴爾的成績是總用時 26.5 秒,每秒平均生成 6.91 個 token(劇透:蘋果遠遠達不到這個水平)。其中 Inference seed 並非隨機,所以生成的輸出結果在每輪執行中均恆定不變,這就保證了多次執行下的效能間可以直接比較。
好了,使用相同的程式碼在 1.5 GHz PowerPC 7447B 處理器上執行,PowerBook G4 到底取得了怎樣的成績?
I ullm.llama2: Complete: 0.77 token/s
real    4m0.099s
user    3m51.387s
sys     0m5.533s
雖然速度慢得多,但它仍然成功了!在與擁有更高記憶體頻寬的現代 CPU 相比,PowerPC 的速度大約是其九分之一。老實講,居然能跟 15 年後的年輕計算機保持在同一性能數量級內,這真的令人印象深刻。
下面我們來看看耗費時間最長的函式:matmul。控制結構的核心在於巢狀迴圈與乘法 / 求和。
那還能不能做得更好?我記得 PowerPC 處理器支援所謂 AltiVec 向量擴充套件,雖然早期版本的處理器擴充套件比較有限,但確實包含一項可以加快速度的關鍵運算:融合乘加。使用融合乘加運算,處理器能夠執行 4 倍的並行浮點乘法與加法,依靠 SIMD(單指令多資料)語義實現加速。
以下是使用 AltiVec SIMD 擴充套件重寫的同一函式。請注意,這是我第一次編寫 AltiVec 程式碼。在修復了 16 位元組對齊問題之後,此程式碼能夠與原始 C 語言版本生成同樣的輸出。
可以看到,這裡實際上有 4 個並行求和,之後我在核心乘法求和迴圈結束時進行了手動求和。
如今網路上幾乎找不到多少關於這個古老擴充套件集的資料,好在 Gemini 給了我不少幫助。另外,官方提供的 PowerPC 文件也還不錯,只是與舊版本的 ISA 並不完全匹配。
I ullm.llama2: Complete: 0.88 token/s
real    3m32.098s
user    3m23.535s
sys     0m5.368s
好極了!AltiVec 將推理過程縮短了約 30 秒,讓實現速度從戴爾的九分之一變成了八分之一,每秒生成的 token 數量則增加了 10%。爽!
9 後續探索
Llama2.c 專案還討論瞭如何使用相同程式碼執行具備數十億引數的模型。雖然頗具吸引力,但遺憾的是 G4 PowerPC 系統是 32 位的,因此最大可定址記憶體只有區區 4 GB,執行模型體量的上限也就是這個 110M TinyStories 了。量化技術雖然有肥皂劇幫助,但模型檢查點仍然高達 7 GB(不量化則約為 26 GB),還是塞不進可用地址空間。
所以我認為這個專案可以到此結束了。在此過程中,我熟悉了大模型的性質及其操作方式,也深切意識到矩陣乘法正是制約每秒輸出 token 數量的最大瓶頸。
所以還是讓我的老爺機做它該做的吧:一邊聽歌一邊碼字,今天確實辛苦它了。
參考連結:
https://www.macrumors.com/2025/03/24/powerbook-g4-generative-ai/
http://www.theresistornetwork.com/2025/03/thinking-different-thinking-slowly-llms.html
今日好文推薦
“我已經過時了!”83歲圖靈獎大師、龍書作者在大模型時代的技術焦慮:新技術越來越難以適應
3人2個月日夜開發奠定微軟基石!微軟50週年蓋茨公開歷史性原始碼,“圓謊”成就的程式碼傳奇
“付費刪資料,否則全網叫賣!”十年未更新系統,Oracle雲曝出前所未有的重大生產事故,全球14萬企業資料遭暗網“清倉大促”
平替Navicat ?開源12年,這個最初僅2人的專案斬獲42.5k star,如今年收入過億

相關文章