![見出し画像](https://assets.st-note.com/production/uploads/images/111546249/rectangle_large_type_2_2be39da27a89e90543ef192b14186ea5.jpeg?width=1200)
【llama2.c】15Mに満たない言語モデルで小さな物語を紡ぐ
OpenAIのAndrej Karpathy氏による「llama2.c」が話題になっていた。
CPU環境で「Llama 2 アーキテクチャをゼロから学習させ、重みを生のバイナリファイルに保存し、シンプルなCファイルにロードしてモデルを推論する」という一連の流れが体験できるという。
My fun weekend hack: llama2.c 🦙🤠https://t.co/CUoF0l07oX
— Andrej Karpathy (@karpathy) July 23, 2023
Lets you train a baby Llama 2 model in PyTorch, then inference it with one 500-line file with no dependencies, in pure C. My pretrained model (on TinyStories) samples stories in fp32 at 18 tok/s on my MacBook Air M1 CPU. pic.twitter.com/aBvKCf1t2u
「llama.cpp」に影響を受けた週末プロジェクトだそうで、「シンプルなアプローチで、それなりの大きさのモデル(数千万パラメータ)がとてもインタラクティブな速度で動くことに嬉しい驚きを覚える」と述べている。
例によって中身はほとんど理解できないが、面白そうなので手元のPC(Windows 11)でひとまず試してみた。
Windowsで「llama2.c」を試す
Cに触れたことはないので、まず実行環境の用意から。「MinGW」というコンパイラ管理ソフトがあればCが実行できるらしい。こちらの記事を参考に導入した。
インストール後、環境変数 Pathの登録に失敗したので「C:\MinGW\bin」フォルダに、ダウンロードした「llama2.c」のファイルを直接放り込み、このフォルダ上で実行(無知)。
「llama2.c」はモデルのトレーニングから始められるが、Karpathy氏が学習済みのモデルもアップしているので、それを動かしてみる。この場合の手順(和訳)は以下の通り。
CでLlama 2の赤ちゃんモデルを動かしてみよう。TinyStoriesデータセットで学習させた15Mパラメータモデル(~58MB)をダウンロードし、デフォルトのチェックポイントディレクトリに置く:
wget https://karpathy.ai/llama2c/model.bin -P out
Cコードをコンパイルして実行する:
gcc -O3 -o run run.c -lm
./run out/model.bin
ただし、これは生のトークンをストリームしているだけ。トークンをテキストに翻訳する必要がある。悲しいかな、このCコードを翻訳用の簡単なラッパーに通さないといけない:
pip install sentencepiece
python run_wrap.py
これでテキストがストリーム表示されるだろう。私のM1 MacBook Airでは、〜100トークン/秒で実行される。超素朴なfp32シングルスレッドCコードとしては悪くない。
私(無知)の場合は、モデル(https://karpathy.ai/llama2c/model.bin)を手動で「C:\MinGW\bin\out」にダウンロード。モデルサイズはわずか58MBと可愛らしいサイズ。コマンドプロンプトを起動して以下のコマンドを順に実行。
cd C:\MinGW\bin
gcc -O3 -o run run.c -lm
run out/model.bin
pip install sentencepiece
python run_wrap.py
モデルを走らせると、以下のように勢いよく生のトークンが数値で出力され、ラッパーでテキストに変換される。CPUに大した負荷はかからない。
Windowsで「llama2.c」を試す pic.twitter.com/aFJ5gVn6Cv
— Baku (@bk_sakurai) July 24, 2023
このモデルはChatGPTで生成した「小さな物語(TinyStories)データセット」で学習していて、「Once upon a time(昔々)」で始まるささやかな物語が出力される。
出力例(和訳)
昔々、リリーという小さな女の子がいた。彼女は公園に行ってアヒルに餌をやるのが大好きだった。ある日、彼女は頭に輝く王冠をかぶった大きくて太いアヒルを見つけた。彼女はアヒルに向かって走り、餌を取ろうとしたが、アヒルは餌を欲しがらなかった。しかしリリーはあきらめなかった。アヒルを捕まえようとし続け、ついに「ollipopvoiceアヒルより遅い」と書かれた看板にたどり着いた。リリーはアイスクリーム屋さんに、ごちそうをもらいに来るように注文した。アイスクリーム屋さんは大喜びで、リリーに大きなバニラアイスクリームをくれた。彼女はアイスクリーム屋さんとアイスクリーム屋さんにお礼を言いながら、車を走らせた。リリーはアヒルの家族に手を振って別れを告げ、満面の笑みで家路についた。
昔々、小さな赤い車がいた。その車はスピードを出すのが大好きだった。満面の笑みを浮かべながら、その車は通りを疾走した。ある日…
感想
言語モデルが生のトークンを吐き出すのを眺めるのは新鮮。モデルは言葉を数値として処理していて、それをわざわざトークナイザーでテキストにデコードしているのだということを感覚的に理解する。
通常のLlamaなどのLLMのファイルサイズは巨大で、量子化した7Bパラメータのモデルでも数GBのサイズはある。もっと小さい3.6Bモデルとかのモデルだと、まともな文章の生成は難しいのだと思っていたが、実際は15M足らずのモデル(60MB以下)でも、学習次第で意味のある文章が生成できるものらしい。
このデータセットの作成に関する論文(「小さな物語:言語モデルはどこまで小さくても首尾一貫した英語を話すことができるのか?」)は以下。
論文の読後メモと抄訳は下記。