- Mozillaと共同で作られたオープンソース llamafile をシェルツールのように使い、ローカルLLMを単一の実行ファイルとして動かし、画像・Webページ・API・チャット・コード・メール処理を Bash ワンライナーでこなす
- LLaVA ベースの
.llamafile は、--image とプロンプトだけで 画像説明 を標準出力に出力し、OSごとに Xcode、binfmt_misc、.exe 拡張子のような準備が必要な場合がある
- 自動化に組み込む際は、BNF 文法制約、
--temp 0、-n トークン制限で出力を絞る必要があり、ファイル名生成では予測不能な出力や ENAMETOOLONG エラーを避けることが重要
- URL要約は、
links で HTML をテキスト化してから Mistral 7B llamafile にパイプする方式で、例では 3,774語のWebページが 129語の要約に短縮される
- OpenAI 互換のローカル API、ターミナルチャットボット、コード補完、メール作成まで可能だが、コーディング用 LLM は数学や検証に限界があるため、未知のテーマを探索する補助ツールとして見るのが安全
llamafile をローカル LLM のシェルツールとして使う
- llamafile は Mozilla と共同で進められたオープンソースプロジェクトで、LLM をユーザーのコンピュータ上で直接実行できるようにする
- プロジェクトは GitHub で 8.3k stars、Hacker News で 1073 upvotes を獲得し、Hackaday でも取り上げられた
- 例で使われているリリースは 0.8.12 で、記事はこのバージョンで何ができるかを示している
- 開始方法は、Hugging Face から事前ビルド済みの
.llamafile をダウンロードし、実行権限を与えるというもの
- 使用モデルはマルチモーダル視覚モデル LLaVA 用の
llava-v1.5-7b-q4.llamafile
- MacOS、Linux、Windows、BSD で実行可能
- 問題があれば README の Gotchas を確認する必要があり、MacOS では Xcode、Linux では
binfmt_misc インタープリタ、Windows では .exe 拡張子が必要な場合がある
画像要約: LLaVA を標準出力に呼び出す
llava-v1.5-7b-q4.llamafile はデフォルトで マルチモーダル視覚モデル を使用し、--mmproj '' を渡すとこの動作が変わる
- 画像は
--image GRAPHIC フラグで渡し、jpeg、png、tga、bmp、psd、gif、hdr、pic、pnm ファイルを受け取れる
- 質問は
--silent-prompt -p PROMPT の形で渡し、回答は標準出力に出る
- 例のワンライナーは
lemurs.jpg に対して What do you see? と尋ね、--temp 0 で決定的な出力を使う
- GPU オフロードには
-ngl 999 が必要
- 同じ画像要約コマンドでも、ハードウェアによって実行時間は大きく異なる
- Mac Studio: 4秒、価格 $8,300、M2 Ultra、800 GB/s メモリ帯域幅、60 GPU cores
- Windows PC: 10秒、4年前の NVIDIA GeForce RTX 2080 Ti、当時の Amazon 価格 $500〜$1,000
- Hewlett Packard ProDesk 600 G5: 45秒、$1,653、Intel Core i9-9900、2667 MT/s または 19.8 GB/s メモリ帯域幅、GPU なし
- 出力例は、母親のキツネザルが3匹の子どものうち2匹を抱え、緑豊かな環境の中で保護とぬくもりを与えている、といった説明
安全なファイル名生成: 文法制約とトークン制限
- LLaVA で画像ファイル名を作る際の核心的なリスクは、LLM の出力が一般に 予測不能 であること
--grammar は Backus-Naur Form によって出力可能なトークンを制限する
- 例:
root ::= "yes" | "no" は、出力を "yes\n" または "no\n" のみに強制する
- ファイル名の例では、小文字の単語と空白だけを出すようにしてから、
sed で空白をアンダースコアに置き換え、.jpg を付ける
- ファイル名生成のワンライナーでは、
--grammar 'root ::= [a-z]+ (" " [a-z]+)+' と -n 16 を併用する
-n 16 で最大生成トークン数を制限しないと、LLM が長すぎるテキストを生成して ENAMETOOLONG エラーが起こりうる
- 文法は、モデルが本来生成しようとする方式とある程度整合している必要がある
- LLaVA はアンダースコア入りの文を生成するよう訓練されていないため、BNF にアンダースコアを直接入れると一貫しない出力になることがある
- 小文字出力は LLaVA の守備範囲内だった
- JSON のように Web 上で大量に収集された形式は、文法制約によって幻覚した JSON の構文エラーを減らすガードレールになりうる
- より完成された形として
rename-pictures.sh スクリプトがあり、~/Pictures を対象に実行する例が示されている
URL要約: links と Mistral 7B の組み合わせ
- Mistral 7B instruct llamafile は、
links コマンドの出力をパイプして HTML URL の要約に使える
links はコマンドラインWebブラウザで、MacOS では通常 brew install links でインストールできる
- パッケージマネージャがない場合に使える事前ビルド済みの APE バイナリも提供されている
links v2.29、7.7MB
- AMD64+ARM64、Linux+Windows+FreeBSD+NetBSD+OpenBSD 向け
- URL要約ワンライナーは次の流れで動く
- まず
[INST]Summarize the following text: を出力
links -codepage utf-8 -force-html -width 500 -dump URL でWebページをテキスト化
sed 's/*/ /g' で一部の文字を整える
[/INST] を付けた後、Mistral llamafile に -f /dev/stdin で渡す
- 例の対象である “Real Programmers Don’t Use Pascal” のページは、3,774語から129語の要約に短縮される
- 同じ方法で、テキストに対する任意の質問も可能
- 例では、筆者が精神的に不安定に見えるかを尋ね、Mistral は誇張や大げさな表現はあるものの、1983年の風刺的な文章である点を踏まえて答える
--grammar 'root ::= "yes" | "no"' を使えば、スクリプトで扱いやすい YES/NO 形式に制限できる
- 重要な制約は、Mistral v0.2 の 32k トークンコンテキストサイズ を超えないこと
-width 500 は段落の再配置を避けるのに役立ち、不要な改行を減らせる
sed 's/ */ /g' で連続する空白を減らせる
dd bs=1 count=80000 で長いWebページを大まかに切り詰め、最後の防衛線として使える
ローカル OpenAI 互換 API
- “server” llamafile はローカルで OpenAI API 互換エンドポイント を提供する
- 例では Mixtral 8x7B を使っており、30 gibibyte のモデルを動かせる強力な GPU が必要
- サーバーは
mixtral-8x7b-instruct-v0.1.Q5_K_M-server.llamafile --nobrowser で起動する
- 別のターミナルから
curl で http://localhost:8080/v1/chat/completions にリクエストを送り、Python で返却 JSON を見やすく出力する
- リクエスト JSON は、
model の値に gpt-3.5-turbo を入れ、system・user メッセージ配列を送る OpenAI Chat Completions 形式に従う
- 例の応答には、再帰の概念を詩で説明した
assistant メッセージと、completion_tokens、prompt_tokens、total_tokens の使用量が含まれる
ターミナルチャットボット: Digital Athena プロンプト
- llamafile は、リリースページの圧縮済みバイナリを入手するか、ソースからビルドして、標準的な UNIX コマンドラインツールのように使える
git clone, make -j8, sudo make install, man llamafile という流れが示されている
- この方式により、Hugging Face の GGUF weights と組み合わせて使いやすくなる
- チャットボットの例では、Facebook が研究目的で公開した元の LLaMA モデルを使う
- プロンプトは、モデルを擬人化せず、学術的な口調で話させるよう構成することが重要
- 名前は知恵と知識のギリシャの女神 Athena に由来する Digital Athena
Researcher と Digital Athena の対話形式で始まる
- 対話実行には
--interactive, --color, --ctx_size 4096, --reverse-prompt 'Researcher:' のようなオプションが使われる
--temp 0 は、出力を決定的かつ再現可能にする設定
- これを使わない場合、llamafile は 0.8.12 のランダム性レベルを使い、毎回固有の回答を返す
- 擬人化されたチャットボットを望むなら、元の LLaMA モデルはユーザーを Reddit 上の見知らぬ相手のように見るデフォルト傾向があるため、扱いが難しいことがある
コード補完: Wizard Coder を使う
- Wizard Coder llamafile をダウンロードすれば、Emacs や Vim で現在行の自動補完に使える
- 例のモデルは Python 中心にファインチューニングされているが、C の
memcpy() 実装を生成する
- プロンプトには、英語の説明を入れず、Markdown コードブロックの開始と関数シグネチャだけを含める
- 英語を書かないことで、モデルが長いコード説明を付ける可能性を減らせる
- Markdown コードブロックを使うと、
-r で指定した reverse prompt トークンが出て、適切な時点で停止する可能性が高まる
- さらに確実に止めたいなら、
-n 100 で応答を100トークンに制限できる
- 出力例は、
for ループで src から dst へ size ぶんコピーし、dst を返す memcpy() 実装
- コーディング用 LLM には明確な限界がある
- 人間の言語理解は得意だが、数学には弱い
- もっともらしく見えるコードを書くが、レビューに耐えるとは限らない
- 複数言語で Stack Overflow の回答を反復するツールのように考えると役立つ
- 良い体験を得るには、未知のテーマの探索を助けてもらうくらいの期待値が必要
メール作成: 小型モデルで返信を生成
- メール作成の例は、$50 の Raspberry Pi が会社のメールに返信し、製品販売を支援するという状況
- Rocket 3B は少し異なるプロンプト文法を使い、このケースでは temperature が即興性をまねるのに役立つ場合がある
- 例では、PHP サーバーがサポートリクエストをプロンプトに注入し、出力を
sendmail にパイプする構成を想定している
- システムプロンプトは、ユーザーを助けつつ、会話をピクルス購入へ導くよう指示する
- Long Island Sound で強風に遭って救助が必要だとユーザーが述べる例に対し、モデルは共感の一文の後に Bill Pickle’s Gourmet Dill Pickles を勧める返信を生成する
- 最後の例はユーモアを意図したものであり、Mozilla が特定のモデル・ライセンス・データセット・慣行を推奨または保証していると解釈してはならない
1件のコメント
Hacker Newsの意見
ここ数か月、LLMとCLIユーティリティの組み合わせを楽しく探っているが、この2つは本当に相性がいい
Unix哲学の、パイプで複数のツールをつなぎ合わせるやり方は、LLMの動作方式ともよく合う
主に https://llm.datasette.io/ のCLIツールで実験していて、https://github.com/simonw/blip-caption や https://github.com/simonw/ospeak のような単発ツールもある
LLM+CLI の領域をもっと多くの人が大きく掘り下げていないのが不思議なくらい面白い
これまで見てきた技術分野の探索の中でいちばん騒がしく、もっと聞くどころか、むしろ少なくてもいいくらい
プロンプトテンプレートをコマンドラインの動詞のように公開し、複数の「リポジトリ」から読み込める
作業中の各リポジトリごとにプロンプトセットを維持し、動的なプロンプト文脈を生成するカスタムの「prompto」https://github.com/go-go-golems/prompto スクリプトも一緒に置いている
サードパーティライブラリ向けのものもかなり作っていて、https://github.com/go-go-golems/promptos にある
公開プロンプトの一部は https://github.com/go-go-golems/geppetto/tree/main/cmd/pinoc... で見られ、今は宣言型エージェントフレームワークを作っている
最近は httrack + w3m dump + sgpt images + GPT Vision で27.8万トークン規模の特定知識ベースを作り、知識の概略構造を保つカスタムPerlハックでRAGを構成した
入力処理とローカルRAGについて、Unix哲学とうまく合うツールを見たことがあるか気になる
付け加えると、元記事の作者はすでに関連作業をかなりやっていて、https://simonwillison.net/2023/Oct/23/embeddings/ にまとまっている
今詰まっているのは、埋め込みを作るコンテンツをチャンク化するツールチェーンだ。原文で「2.1 Failover」や「Chapter 8: The dream」のような位置の文脈を検出し、80文字幅ソースの改行をほどき、段落を保った賢い分割などをしてくれるとよい
主な原因はVS Codeだと思うし、私がサポートしている開発者たちも、ターミナルやCLIよりポイント&クリックを望んでいる
最近の関連記事
Llamafile – The easiest way to run LLMs locally on your Mac - https://news.ycombinator.com/item?id=38522636 - 2023年12月、コメント17件
Llamafile is the new best way to run a LLM on your own computer - https://news.ycombinator.com/item?id=38489533 - 2023年12月、コメント47件
Llamafile lets you distribute and run LLMs with a single file - https://news.ycombinator.com/item?id=38464057 - 2023年11月、コメント287件
本当に素晴らしい。LLMで画像ファイル名を説明的なものに変える例が特に気に入った
WindowsデスクトップのNVIDIA GeForce RTX 3080 Tiで動かしてみたが、動作させるまでにいくつかつまずきがあった
WSLはワンライナー内で
/dev/nullに隠されるerror: APE is running on WIN32 inside WSL. You need to run: sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop'というエラーを出すその次にzshでは
zsh: exec format error: ./llava-v1.5-7b-q4-main.llamafileが出たので、bashで実行する必要があった。タイトルにbashとあるとはいえ、zshで動かないのは変に見えるGPUオフロードがサポートされていないという警告も出るが、おそらくWSLのせいだろう。このWindowsマシンではGPUプログラミングはしていない
shを付ければ解決する:sh ./llava-v1.5-7b-q4-main.llamafilezshとAPEの独特な挙動で、https://justine.lol/ape.html に関連する内容がある
CPUだけを使った場合、テストがかなり遅かったのか気になる
Hugging Faceでざっと検索してみると、TinyLlamaの約1B級Llamafileがいくつか見つかる
もともとあった3つのllamafileを加えると合計6つだが、ほかにも野に出回っているllamafileがあるのか気になる
HNがllamafileとmodelfile(https://github.com/jmorganca/ollama/blob/main/docs/modelfile...)をどう見ているのか気になる
どちらもDockerfileのような体験を思い起こさせる。ModelfileはまさにDockerfileのように見えるが、llamafileは書くのがより難しそうで、実際の形がすぐにはピンと来ない。ターミナルで実行するコマンド列なのか気になる
理論的には、なぜ単にDockerfileを使わないのかも気になる
--grammarオプションで、LLM出力のロジットを制限し、さまざまな自然言語処理の分類タスクを行うbashスクリプトに非常に向いているそれ以外では、ローカルLLMが必要ならollamaを使い、GPUサーバーを借りるときはvllmを使い、単に最高のモデルが必要ならOpenAI APIを使う
llamafileをダウンロードして
chmod +xし、./runで実行すればよいただしDocker + llamafileの組み合わせも可能。https://github.com/ajbouh/cosmosにかなり良いDockerfile設定がある
元記事で使われているllamafileとollamaの長所・短所が気になる
そのため、最小限の手間であらゆる設定ノブを使える。特に“server” llamafileをダウンロードすれば、ブラウザタブでローカルLLMを立ち上げる最速の方法になる
https://huggingface.co/jartine/llava-v1.5-7B-GGUF/tree/main
llamafileでもコマンドラインチャットボットはできるが、その用途ではollamaのほうがはるかにすっきりして洗練された体験を提供する
自分の理解が合っているか確認したい。シェルスクリプトでllamafileを実行し、ディレクトリ内のファイル名を変更するように使う場合、新しいファイル名が渡ってくるたびに実行ファイルを開いてロードしなければならない、ということで合っているのか?
だとすると、そのメモリは毎回ロード・アンロードされるのか、それとも自分が知らないすごいキャッシュがあるのか気になる
画像キャプションの例をM1 Proで初めて実行したときは13秒、2回目は8秒で、その後の実行もずっと同じくらいの時間がかかる
大量のファイルを処理するなら、重みを一度だけロードし、プロセスがループしている間保持する方式が本当に必要になりそう
それでもなお、とても有用で興味深い
そのRAMをほかのものが要求しない限り、そのページ群はコマンド呼び出しの間もメモリにキャッシュされたまま残る
128GBのワークステーションでは、CPUで複数の7Bモデルを使ってもすべてキャッシュに残っている
8GB VRAMのモデルで数行の補完なら、おおよそ6秒対2秒くらいで、3090と96GB RAMでは推論はすべてGPUで回している
本当にバッチ処理をするなら、補完の間もモデルを保持し続けるほうが確実に良い
一方で、serverとしてロードしたモデルに縛られるという欠点がある。必要なたびにロードすればモデルを差し替えられる
これはマルチモーダルな画像問い合わせでは重要。ほかのモデルは投影された画像トークンを理解できないためである
インストール手順に次のコマンドがあるが、これが安全なのか気になる
Windows 10でllamafileを実行するには何かする必要があるのか気になる
llava-v1.5-7b-q4-server.llamafileをgit bashで実行すると“Segmentation fault”ですぐ落ち、cmdでは何の出力もないllamafileとモデルを別々にダウンロードして
llamafile.exe -m llava-v1.5-7b-Q4_K.ggufも試したが、同じ問題が残る似た問題を見つけられず、自分にはアンチウイルスの問題でもなさそうに見える
cmd.exeやPowerShellで実行してみたのか気になる--strace、または可能なら--ftraceフラグを渡して、何が起きているのか確認できる.llamafileの名前を.exeに変更する必要がある.llamafileを.exeにリネームする必要がある