新智元報(bào)道
你有沒(méi)有想過(guò)僅用C語(yǔ)言去推理一個(gè)Llama 2的baby模型?
沒(méi)有?現(xiàn)在就能做到了!
就在剛剛過(guò)去的這個(gè)周末,OpenAI科學(xué)家Andrej Karpathy做了一個(gè)非常有趣的項(xiàng)目——llama2.c。
項(xiàng)目靈感正是來(lái)自于之前的明星項(xiàng)目——llama.cpp
首先,在PyTorch中訓(xùn)練一個(gè)較小的Llama 2模型。
然后,用500行代碼在純C環(huán)境下進(jìn)行推理,并且無(wú)需任何依賴項(xiàng)。
最后得到的預(yù)訓(xùn)練模型(基于TinyStories),可以在MacBook Air M1 CPU上用fp32以每秒18個(gè)token的速度生成故事樣本。
llama2.c一經(jīng)發(fā)布,就在GitHub上速攬1.6k星,并且還在快速攀升中。
項(xiàng)目地址:https://github.com/karpathy/llama2.c
順便,Karpathy還表示:「感謝GPT-4對(duì)我生疏的C語(yǔ)言提供幫助!」
英偉達(dá)科學(xué)家Jim Fan稱,GPT-4幫助Karpathy用C語(yǔ)言「養(yǎng)」了一只baby Llama!太了不起了!
網(wǎng)友也表示,使用GPT-4構(gòu)建llama2.c,堪稱是終極跨界。
純C語(yǔ)言推理Llama 2
可能Karpathy沒(méi)想到,這個(gè)llama2.c項(xiàng)目的潛力是如此巨大。
令人驚訝的是,你可以在單線程的CPU上以fp32的交互速率對(duì)這些較?。∣(~10MB))的模型進(jìn)行推理。
不過(guò),我還沒(méi)嘗試過(guò)使用最小的Meta LLama2檢查點(diǎn)(7B),預(yù)計(jì)速度會(huì)很慢。
Karpathy表示,在較窄的領(lǐng)域(比如,故事)中,人們可以使用更小的Transformer來(lái)做有趣的事情。
因此,這個(gè)簡(jiǎn)單的純C語(yǔ)言實(shí)現(xiàn)還是很實(shí)用的,尤其是它還可以進(jìn)行移植。
緊接著,他又使用-O3編譯,將MacBook Air M1上的每秒處理token數(shù)tok/s從18增加到了98。
對(duì)于使用這樣簡(jiǎn)單的方法,并能夠以較高的交互速率運(yùn)行相當(dāng)大小的模型(幾千萬(wàn)參數(shù)),Karpathy表示非常幸興奮——
「看來(lái),我現(xiàn)在必須訓(xùn)練一個(gè)更大的模型了?!?/span>
事實(shí)證明,我原來(lái)的檢查點(diǎn)用編譯-O3在MacBook Air M1上運(yùn)行_way_(100 tok/s)的速度比我預(yù)期的要快,所以我現(xiàn)在正在訓(xùn)練一個(gè)更大的44M模型,它應(yīng)該仍然以交互方式運(yùn)行。也許7B Llama模型觸手可及。
代碼開源
目前,llama2.c的代碼已經(jīng)開源。
利用這段代碼,你可以在PyTorch中從頭開始訓(xùn)練Llama 2 LLM架構(gòu),然后將權(quán)重保存為原始二進(jìn)制文件,并加載到一個(gè)約500行C文件(run. c)中。目前,該文件使用fp32對(duì)模型進(jìn)行推理。
在云Linux開發(fā)環(huán)境中,Karpathy用一個(gè)維度為288、6層、6頭的模型(約1500萬(wàn)參數(shù))在fp32下以約100 tok/s的速度進(jìn)行推理,而這也與M1 MacBook Air上的運(yùn)行情況大致相同。
在C中運(yùn)行一個(gè)baby Llama 2模型前,首先需要一個(gè)模型檢查點(diǎn)。
對(duì)此,你可以下載在TinyStories數(shù)據(jù)集上訓(xùn)練的這個(gè)15M參數(shù)模型(約58MB),并將其放入默認(rèn)檢查點(diǎn)目錄out:
wget https://karpathy.ai/llama2c/model.bin -P out
然后,編譯并運(yùn)行C代碼:
gcc -O3 -o run run.c -lm
./run out/model.bin
可以看到,這只是對(duì)原始token進(jìn)行了流式處理。想要讀取的話,就需要將其轉(zhuǎn)換為文本。
遺憾的是,現(xiàn)在只能通過(guò)一個(gè)簡(jiǎn)單的Python函數(shù)裝飾器來(lái)實(shí)現(xiàn)翻譯(30行代碼):
pip install sentencepiece
python run_wrap.py
在M1 MacBook Air上,它的運(yùn)行速度約為每秒100個(gè)token,對(duì)于超級(jí)簡(jiǎn)單的fp32單線程C代碼來(lái)說(shuō),效果還不錯(cuò)。
示例輸出:
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
從前,有一個(gè)叫Timmy的男孩。Timmy喜歡和他的朋友們一起運(yùn)動(dòng)。他非常擅長(zhǎng)扔球和接球。一天,Timmy的媽媽給了他一件新襯衫,讓他穿去參加一個(gè)聚會(huì)。Timmy覺(jué)得這件襯衫很棒,便問(wèn)媽媽它有沒(méi)有什么特別的用途?!敢r衫就像籃球比賽時(shí)的特殊套裝,」他媽媽說(shuō)。Timmy聽(tīng)了很高興,于是穿上了這件新襯衫。他感覺(jué)自己像個(gè)士兵要去參軍一樣,大聲吶喊。從那天起,每次在聚會(huì)上和朋友們一起運(yùn)動(dòng)時(shí),Timmy都會(huì)穿著這件新襯衫。從前,有一個(gè)叫Lily的小女孩。她喜歡和她的朋友在外面玩。一天,Lily和她的朋友Emma正在玩球。Emma把球扔得太用力了,結(jié)果打到了Lily的臉上。Lily覺(jué)得很尷尬,不想再玩了。Emma問(wèn)Lily怎么了,Lily告訴她她的記憶。Emma告訴Lily,她很尷尬,因?yàn)樗亚蛉拥锰昧α?。Lily覺(jué)得很糟糕。Tok/s:98.746993347843922
理論上應(yīng)該可以加載Meta發(fā)布的權(quán)重,但即使是最小的7B模型,使用這個(gè)簡(jiǎn)單的單線程C程序來(lái)進(jìn)行推理,速度估計(jì)快不了。
所以在這個(gè)repo中,我們專注于更窄的應(yīng)用領(lǐng)域,并從頭開始訓(xùn)練相同的架構(gòu)。
首先,下載并預(yù)分詞一些源數(shù)據(jù)集,例如TinyStories:
python tinystories.py download
python tinystories.py pretokenize
然后,訓(xùn)練模型:
python train.py
更多特殊啟動(dòng)和超參數(shù)覆蓋的信息,請(qǐng)查看train.py腳本。Karpathy預(yù)計(jì)簡(jiǎn)單的超參數(shù)探索應(yīng)該可以得到更好的模型,因此并沒(méi)有對(duì)其進(jìn)行調(diào)整。
如果想跳過(guò)模型訓(xùn)練,只需下載Karpathy的預(yù)訓(xùn)練模型并將其保存到out目錄中,就可以進(jìn)行簡(jiǎn)單的演示了:
wget https://karpathy.ai/llama2c/model.bin -P out
一旦有了model.bin文件,就可以在C中進(jìn)行推理。
首先,編譯C代碼:
gcc -O3 -o run run.c -lm
然后,運(yùn)行:
./run out/model.bin
注意,這里輸出的只是SentencePiece token。要將token解碼為文本,還需利用一個(gè)簡(jiǎn)單的裝飾器來(lái)運(yùn)行這個(gè)腳本:
python run_wrap.py
此外,也可以運(yùn)行PyTorch推理腳本進(jìn)行比較(將model.ckpt添加到/out目錄中):
python sample.py
這將得到相同的結(jié)果。更詳細(xì)的測(cè)試將在test_all.py中進(jìn)行,運(yùn)行方式如下:
$ pytest
目前,你需要兩個(gè)文件來(lái)進(jìn)行測(cè)試或采樣:model.bin文件和之前進(jìn)行PyTorch訓(xùn)練的model.ckpt文件。
(論如何在不下載200MB數(shù)據(jù)的情況下運(yùn)行測(cè)試。)
- 增加更好的測(cè)試來(lái)減少yolo
網(wǎng)友熱議
借著llama2.c熱乎勁兒,網(wǎng)友將llama2編譯成Emscripten,并在網(wǎng)頁(yè)上運(yùn)行。
他使用Emscripten進(jìn)行了編譯,并修改了代碼,以在每次渲染時(shí)預(yù)測(cè)一個(gè)token。網(wǎng)頁(yè)自動(dòng)加載了50MB的模型數(shù)據(jù)。
此外,他還增添了去token化的支持。
還有網(wǎng)友表示,基于llama.cpp的成功,這個(gè)行業(yè)似乎正朝著為每個(gè)發(fā)布的模型提供單獨(dú)源代碼的方向發(fā)展,而不是像pytorch/tenorflow/onnxruntime這樣的通用框架?
llama2.c的意義在何處?
網(wǎng)友舉了一個(gè)生動(dòng)的例子,創(chuàng)建一個(gè)關(guān)于一個(gè)有100人的小島的電腦游戲,每個(gè)人都有意識(shí),llama2. c是他們的大腦。然后你可以模擬一千年的歷史,看看會(huì)發(fā)生什么。
聯(lián)系客服