はじめに
私は機械知能研究室に所属し,CV分野の研究をしています.
機械知能研究室ではロボットの視覚機能や自立的に行動するための知能システムについて研究に取り組んでいます.(HPはこちらから)
私は,LLMにはあまり詳しくないのですが、自分のPCでAIをローカルで動かして遊んでみたいと思いローカルに実装をしてみました.また,GPUを使わずに超軽量で動くと噂の「1-bit LLM (BitNet)」という面白そうな技術を見つけたので動かしてみることにしました.
そもそも1-bit LLM「BitNet」とは?
通常のAIモデル(ChatGPTなど)は,パラメータ(重み)に16ビットなどの細かい数値を使っているため,ファイルサイズが数十GBにもなり,計算には膨大な「掛け算」が必要になります.そのため,通常は強力なGPUがないと快適に動きません.
一方、Microsoft Researchなどが提唱した「BitNet b1.58」は,この重みを極限まで削り,なんと -1,0, +1 の3つの値だけで表現しています.
値が3つしかないため,AIの中核の計算から重たい「掛け算」が消え去り,「足し算」と「引き算」だけで推論ができるようになります.
結果として,ファイルサイズやメモリ消費量が劇的に小さくなり,GPUを使わずにCPU単体でも爆速で動くという,まさにローカルLLMの常識を覆す次世代のアーキテクチャです.今回はこのBitNetを動かすための公式推論ツールである bitnet.cpp を使用します.
実装
GitHubのREADMEを参考に実装を行なっていきます.
以下に実装環境をまとめておきます.
| 項目 | 使用している環境 |
|---|---|
| 機種 | MacBook Air 13インチ (2025) |
| チップ | Apple M4 |
| メモリ | 16GB |
| OS | macOS Sequoia 15.6.1 |
実装する上で躓いた点
ビルド時のパッケージ依存関係エラー
setup_env.py を実行した際,内部の gguf-py というパッケージのインストールでエラーになって停止してしまいました.
解決策:パッケージの依存関係を無視する --no-deps オプションをつけて手動でインストールすることで回避しました.
macOS Sequoia特有のコンパイルエラー
C++のビルド中に -Welaborated-enum-base という見慣れないエラーが大量発生しました.
調べてみると,Macの最新のシステムファイルと,設定ファイルで指定されている古い「C++11」の文法が衝突しているのが原因でした.
解決策:設定ファイル(CMakeLists.txt)の CXX_STANDARD 11 を 17 に書き換えることで,Mac標準のコンパイラで無事にビルドが通りました.
実行
対話形式でAIが動くか試してみました.
python run_inference.py -m models/BitNet-b1.58-2B-4T/ggml-model-i2_s.gguf -p "You are a helpful assistant." -cnv
終了する場合は Ctrl + C を押す
注意点:日本語には対応していないモデルなので,英語で話しかける必要がある
実行結果
実行した結果,トークン崩壊やワードサラダと呼ばれる現象が起こってしまいました.
> Hello
mon trusted resumeleh simpler dar Clean…
unanimously haven&E Guaranteed acquire VN foll occasionallyethyst/usorta noticingitm ClarenceEinefans fridge metal upliftliquimos take fif ac thin Dept undertAP ab disproportion œReleasePCP withdraw attack tackling
思った回答は得られませんでしたが実際に実行出来ている?ことを確認できました.
次に本命である実行速度について調べました.
速度の検証
BitNetのGitHubで公開されているエンドツーエンドのベンチマークスクリプトを使用し,指定したモデルに対して「プロンプトの読み込み」と「テキスト生成」を実行し,その処理速度を計測するプログラムを実行します.
python utils/e2e_benchmark.py -m /path/to/model -n 200 -p 256 -t 4
それぞれの引数は以下の通りです.
-n 200:テキスト生成時に生成するトークンの数を 200 個に設定します.
-p 256:入力として与えるプロンプトのトークン数を 256 個に設定します.
-t:推論処理に使用するCPUのスレッド数を 4 つに設定します.
検証結果
プロンプト256トークン,生成200トークンで実行してみた結果がこちらです.
| Model | size | pramas | n_batch | test | t/s |
|---|---|---|---|---|---|
| bitnet-b1.58 2B | 1.71 GiB | 2.74 B | 1 | pp256 | 36.81 ± 0.14 |
| bitnet-b1.58 2B | 1.71 GiB | 2.74 B | 1 | tg200 | 35.71 ± 0.33 |
毎秒約35.7トークン(テキスト生成時)人間が文章を読むよりずっと速いスピードでAIが返事をしてくれて,単純に感動しました.(トークン崩壊などが起こっているが...)
好奇心でCPUのスレッド数をいじってみた
実行コマンドの -t(スレッド数)を変更するとどうなるのか気になったので,1,2,4,8と変えてベンチマークを測定してみました.
| スレッド数 | テスト | 生成速度(t/s) |
|---|---|---|
| 1 | tg200 | 13.71 ± 0.03 |
| 2 | tg200 | 23.48 ± 0.06 |
| 4 | tg200 | 35.59 ± 0.30 |
| 8 | tg200 | 37.93 ± 1.22 |
スレッド数を増やせば増やすほど直線的に速くなるかと思いきや,4スレッドから8スレッドに倍増させても,速度は微増(約35.5→37.9)にとどまり,数値のばらつき(±)が大きくなるという面白い結果になりました.
疑問に思い調べたところ,M4チップは「高性能コアが4つ、高効率コアが6つ」という構成のため,4スレッドまでは高性能コアがフル稼働して綺麗に速度が伸びますが,それ以上増やすと処理効率の違う高効率コアが混ざり,コア間の連携コストが足を引っ張ってしまうようです.結果として,私の環境では4スレッドで動かすのが一番効率が良いということが分かりました.ハードウェアの仕組みが結果に直結していて,とても勉強になりました.
[おまけ]普通のLLMも入れて「軽さ」を比べてみた
BitNetがどれくらい軽いのか気になったので,一般的な普通のLLM(Qwen 3.5 4Bの量子化版)を llama.cpp で動かして比較してみました.
実装方法は以下のGitHubリポジトリのREADMEを参考に実装しました.
実装・実行してみたい場合は参考にしてください.
| Model | size | pramas | n_batch | test | t/s |
|---|---|---|---|---|---|
| qwen35 4B Q4_K | 2.54 GiB | 4.21 B | 1 | pp256 | 345.12 ± 2.04 |
| qwen35 4B Q4_K | 2.54 GiB | 4.21 B | 1 | tg200 | 26.75 ± 0.18 |
-
Qwen 3.5 4B (GPUも使用):生成速度 26.75 t/s / メモリサイズ 約2.5GB
-
BitNet 2B (CPUメイン):生成速度 35.71 t/s / メモリサイズ 約1.7GB
結果を見ると非常に面白いことが分かります.最初のプロンプトの読み込み(pp256)こそ,Macの強力なGPUをフル活用できるQwenが約345 t/sと圧倒的です.しかし,いざ文章の生成(tg200)に入ると,ほぼCPUの力だけで動いているBitNet(約35.7 t/s)が,GPUを使っているQwen(約26.7 t/s)の速度を上回るという驚きの結果になりました.
GPUを使わずに既存モデル以上の速度を出しつつ,メモリ消費量も約0.8GB(2.54GB→1.71GB)節約できるのは,かなり優秀だと感じました.メモリ16GBのPCでも重さを気にせずサクサク動くので,ローカルAIを手軽にサクッと楽しみたい人にはピッタリの選択肢だと思います.
おわりに
今回は,GPUを使わずに超軽量で動くと噂の「1-bit LLM (BitNet)」を実装し実際に動かしてみました.結果としては,対話形式はトークン崩壊などが起こってしまい上手くいきませんでしたが,生成速度・軽さの検証では面白い結果を得れたと思います.LLM初心者としては,少しの実装で気軽にLLMを体験することが出来たので良かったと思います.
重いモデルは無理だとローカルAIを諦めている方も,1-bit LLMなら快適に遊べると思うので,ぜひ気軽に試してみてください!
参考文献