OpenAI科學家Karpathy周末造出「嬰兒Llama2」!GPT-4輔助寫500行純C代碼,速攬1.6k星
你有沒有想過僅用C語言去推理一個Llama 2的baby模型?
沒有?現在就能做到了!
就在剛剛過去的這個周末,OpenAI科學家Andrej Karpathy做了一個非常有趣的項目——llama2.c。
項目靈感正是來自于之前的明星項目——llama.cpp
首先,在PyTorch中訓練一個較小的Llama 2模型。
然后,用500行代碼在純C環境下進行推理,并且無需任何依賴項。
最后得到的預訓練模型(基于TinyStories),可以在MacBook Air M1 CPU上用fp32以每秒18個token的速度生成故事樣本。
圖片
llama2.c一經發布,就在GitHub上速攬1.6k星,并且還在快速攀升中。
圖片
項目地址:https://github.com/karpathy/llama2.c
順便,Karpathy還表示:「感謝GPT-4對我生疏的C語言提供幫助!」
圖片
英偉達科學家Jim Fan稱,GPT-4幫助Karpathy用C語言「養」了一只baby Llama!太了不起了!
圖片
網友也表示,使用GPT-4構建llama2.c,堪稱是終極跨界。
圖片
純C語言推理Llama 2
可能Karpathy沒想到,這個llama2.c項目的潛力如此巨大。
令人驚訝的是,你可以在單線程的CPU上以fp32的交互速率對這些較小(O(~10MB))的模型進行推理。
不過,我還沒嘗試過使用最小的Meta LLama2檢查點(7B),預計速度會很慢。
圖片
圖片
Karpathy表示,在較窄的領域(比如,故事)中,人們可以使用更小的Transformer來做有趣的事情。
因此,這個簡單的純C語言實現還是很實用的,尤其是它還可以進行移植。
圖片
緊接著,他又使用-O3編譯,將MacBook Air M1上的每秒處理token數tok/s從18增加到了98。
對于使用這樣簡單的方法,并能夠以較高的交互速率運行相當大小的模型(幾千萬參數),Karpathy表示非常幸興奮——
「看來,我現在必須訓練一個更大的模型了。」
圖片
事實證明,我原來的檢查點用編譯-O3在MacBook Air M1上運行_way_(100 tok/s)的速度比我預期的要快,所以我現在正在訓練一個更大的44M模型,它應該仍然以交互方式運行。也許7B Llama模型觸手可及。
代碼開源
目前,llama2.c的代碼已經開源。
利用這段代碼,你可以在PyTorch中從頭開始訓練Llama 2 LLM架構,然后將權重保存為原始二進制文件,并加載到一個約500行C文件(run. c)中。目前,該文件使用fp32對模型進行推理。
在云Linux開發環境中,Karpathy用一個維度為288、6層、6頭的模型(約1500萬參數)在fp32下以約100 tok/s的速度進行推理,而這也與M1 MacBook Air上的運行情況大致相同。
圖片
感受魔力
在C中運行一個baby Llama 2模型前,首先需要一個模型檢查點。
對此,你可以下載在TinyStories數據集上訓練的這個15M參數模型(約58MB),并將其放入默認檢查點目錄out:
wget https://karpathy.ai/llama2c/model.bin -P out
然后,編譯并運行C代碼:
gcc -O3 -o run run.c -lm
./run out/model.bin
可以看到,這只是對原始token進行了流式處理。想要讀取的話,就需要將其轉換為文本。
遺憾的是,現在只能通過一個簡單的Python函數裝飾器來實現翻譯(30行代碼):
pip install sentencepiece
python run_wrap.py
在M1 MacBook Air上,它的運行速度約為每秒100個token,對于超級簡單的fp32單線程C代碼來說,效果還不錯。
示例輸出:
Once upon a time, there was a boy named Timmy. Timmy loved to play sports with his friends. He was very good at throwing and catching balls. One day, Timmy's mom gave him a new shirt to wear to a party. Timmy thought it was impressive and asked his mom to explain what a shirt could be for. "A shirt is like a special suit for a basketball game," his mom said. Timmy was happy to hear that and put on his new shirt. He felt like a soldier going to the army and shouting. From that day on, Timmy wore his new shirt every time he played sports with his friends at the party. Once upon a time, there was a little girl named Lily. She loved to play outside with her friends. One day, Lily and her friend Emma were playing with a ball. Emma threw the ball too hard and it hit Lily's face. Lily felt embarrassed and didn't want to play anymore. Emma asked Lily what was wrong, and Lily told her about her memory. Emma told Lily that she was embarrassed because she had thrown the ball too hard. Lily felt bad achieved tok/s: 98.746993347843922
從前,有一個叫Timmy的男孩。Timmy喜歡和他的朋友們一起運動。他非常擅長扔球和接球。一天,Timmy的媽媽給了他一件新襯衫,讓他穿去參加一個聚會。Timmy覺得這件襯衫很棒,便問媽媽它有沒有什么特別的用途。「襯衫就像籃球比賽時的特殊套裝,」他媽媽說。Timmy聽了很高興,于是穿上了這件新襯衫。他感覺自己像個士兵要去參軍一樣,大聲吶喊。從那天起,每次在聚會上和朋友們一起運動時,Timmy都會穿著這件新襯衫。從前,有一個叫Lily的小女孩。她喜歡和她的朋友在外面玩。一天,Lily和她的朋友Emma正在玩球。Emma把球扔得太用力了,結果打到了Lily的臉上。Lily覺得很尷尬,不想再玩了。Emma問Lily怎么了,Lily告訴她她的記憶。Emma告訴Lily,她很尷尬,因為她把球扔得太用力了。Lily覺得很糟糕。Tok/s:98.746993347843922
使用指南
理論上應該可以加載Meta發布的權重,但即使是最小的7B模型,使用這個簡單的單線程C程序來進行推理,速度估計快不了。
所以在這個repo中,我們專注于更窄的應用領域,并從頭開始訓練相同的架構。
首先,下載并預分詞一些源數據集,例如TinyStories:
python tinystories.py download
python tinystories.py pretokenize
然后,訓練模型:
python train.py
更多特殊啟動和超參數覆蓋的信息,請查看train.py腳本。Karpathy預計簡單的超參數探索應該可以得到更好的模型,因此并沒有對其進行調整。
如果想跳過模型訓練,只需下載Karpathy的預訓練模型并將其保存到out目錄中,就可以進行簡單的演示了:
wget https://karpathy.ai/llama2c/model.bin -P out
一旦有了model.bin文件,就可以在C中進行推理。
首先,編譯C代碼:
gcc -O3 -o run run.c -lm
然后,運行:
./run out/model.bin
注意,這里輸出的只是SentencePiece token。要將token解碼為文本,還需利用一個簡單的裝飾器來運行這個腳本:
python run_wrap.py
此外,也可以運行PyTorch推理腳本進行比較(將model.ckpt添加到/out目錄中):
python sample.py
這將得到相同的結果。更詳細的測試將在test_all.py中進行,運行方式如下:
$ pytest
目前,你需要兩個文件來進行測試或采樣:model.bin文件和之前進行PyTorch訓練的model.ckpt文件。
(論如何在不下載200MB數據的情況下運行測試。)
待辦事項
- 為什么SentencePiece無法正確地迭代解碼?
- 希望能夠刪除run_wrap.py文件,直接使用C代碼轉換為字符串
-是否支持多查詢的功能?對于在CPU上運行的較小模型似乎用處不大?
- 計劃支持超過max_seq_len步數的推理,必須考慮kv緩存的情況
- 為什么在我的A100 40GB GPU上進行訓練時,MFU如此之低(只有約10%)?
- 使用DDP時出現了torch.compile和wandb的奇怪錯誤
- 增加更好的測試來減少yolo
網友熱議
借著llama2.c熱乎勁兒,網友將llama2編譯成Emscripten,并在網頁上運行。
他使用Emscripten進行了編譯,并修改了代碼,以在每次渲染時預測一個token。網頁自動加載了50MB的模型數據。
圖片
圖片
此外,他還增添了去token化的支持。
圖片
還有網友表示,基于llama.cpp的成功,這個行業似乎正朝著為每個發布的模型提供單獨源代碼的方向發展,而不是像pytorch/tenorflow/onnxruntime這樣的通用框架?
圖片
llama2.c的意義在何處?
網友舉了一個生動的例子,創建一個關于一個有100人的小島的電腦游戲,每個人都有意識,llama2. c是他們的大腦。然后你可以模擬一千年的歷史,看看會發生什么。
圖片
參考資料:https://github.com/karpathy/llama2.c