ローリングコンバットピッチなう!

AIとか仮想化とかペーパークラフトとか

Bonsai 8BモデルをUbuntu 22.04で動かす

1.概要

1bitや1.58bit量子化の登場で80億パラメータクラスのLLMが標準的なスペックのPCやスマートフォン上のローカルLLMとして使えそうな雰囲気が出てきました。

家の型落ちPC(第7世代 Core i7 + GeForce GTX1050 、RAM16GB + VRAM 2GB)で動かして見ました。
OSはUbuntu22.04で、Dockerコンテナを使います。

使用したモデルはPrismMLが発表したBonsai 8Bの1bit量子化モデルと1.58bit量子化モデルです。

prismml.com


Bonsaiのモデルはhuggingfaceに公開されているのですが、動作させるにはllama.cppを1bit,1.58bit量子化に対応させたPrismMLによるfork版が必要とのこと。

huggingface.co

huggingface.co


ubuntuにはnvidiaのドライバーとContainer Toolkitが入っているので、これを活用してDockerコンテナ上でllama.cppの1bit,1.58bit量子化対応版をビルドし、GPUのメモリを少しでも活用できる様に実行環境を作ります。

 

2.CUDA開発環境準備

結構ハマったのがここです。Ubuntu上のDockerコンテナにCUDAの開発キットをインストールするのですが、当初はNVIDIAの公式ページからダウンロードして自力で入れてllama.cppのビルドを試みました。

しかし、各種エラー頻発で動かしきれず、結局NVIDIAがdocker hubに公開しているCUDA toolkitインストール済みのイメージを使用することにしました。

hub.docker.com

使用したのはnvidia/cuda:<CUDAバージョン>-devel-ubuntu22.04というタグのついたイメージですがここで重要なのは<CUDAバージョン>の選択。何も考えずに最新バージョンを選ぶと古いモデルのGPUに対応しておらずllama.cppをビルドしても動かないです。(という状況にかなり悩んだ)

ここではまず使用するGPUの「computing capability」という値をNVIDIAの公式ページから確認します。

CUDA GPU Compute Capability | NVIDIA Developer

Legacy CUDA GPU Compute Capability | NVIDIA Developer

2026/5/3時点で最新世代のGPUは12.1や12.0になっていますが、GTX1050は6.1です。この値を覚えておきます。

CUDAのSDKはバージョン毎にサポート対象となるcomputing capabilityが異なるので、使用可能なバージョンを確認します。公式ページでは探しづらかったので、Wikipediaに頼ります。

CUDA - Wikipedia

ここから自分の場合は12.0〜12.6が該当することがわかるのですが、host側でnvidia-smiを実行するとCUDA version 12.2と出てくるので、これに合わせてgithubに登録されているイメージから一番近い12.2.2を選択しました。(実は12.6.2も試しましたがsegmentation faultでllama.cppが起動しませんでした)

host側で以下を実行し、CUDAツールキットの開発環境付きubuntuイメージをpull、GPUを有効化(--gpus allオプション)してdockerを起動します。

$ docker pull nvidia/cuda:12.2.2-devel-ubuntu22.04
$ docker run --gpus all -it nvidia/cuda:12.2.2-devel-ubuntu22.04 /bin/bash

 

3.コンテナ上で必要なパッケージをインストール

dockerコンテナに入ったら、aptコマンドを利用して必要なパッケージをインストールしていきます。


# apt update && apt upgrade -y
# apt install -y git cmake openssl libssl-dev vim
# apt install -y locales
# sed -i -E 's/# (ja_JP.UTF-8)/\\1/' /etc/locale.gen
# locale-gen ja_JP.UTF-8

 

必須はgit,cmakeです。opensslとlibssl-devはllama.cppをHTTPS対応化するために使用しますが、無ければHTTPのみサポートされた状態でビルドされる様です。
vimは無くても良いのですが、コンテナ内で設定ファイルの編集等を行いたくなった場合用です。
locale関連は入れてja_JP.UTF-8ロケールを作っておかないとLLMに対する日本語入力ができなくなるため。

 

4.PrismML版llama.cppをgithubからcloneしビルド


引き続きコンテナ内で以下を実施します。

# git clone https://github.com/PrismML-Eng/llama.cpp
# cd llama.cpp
# cmake -B build -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES="61"
# cmake --build build -j 8

 

ここでのポイント、

  • 1つ目のcmake: -DCMAKE_CUDA_ARCHITECTURES="61"はGPUの「computing capability」に対応しています。GTX1050のcomputing capability 6.1を"61"として指定します。これを指定することでこの世代のGPU専用のllama.cpp実行ファイルがビルドされます。
    CMAKE_CUDA_ARCHITECTURESの代わりに-DGGML_NATIVE=OFFを指定するとそのCUDA Toolkitが対応する全ての世代のGPU向けの実行ファイルがビルドされる様ですがCUDA関係のモジュールのコンパイルに非常に時間がかかります。
  • 2つ目のcmake: -j 8はビルドの並列度を指定しています。これはビルドを実行するマシンのCPUのスレッド数を目安に指定します。huggingfaceのビルドコマンド例ではcmake --build build -jとなっていますが、この指定では大量にスレッドが生成されてメモリに十分な余裕が無いとOOMになります。

上記設定+第7世代Core i7 メモリ16GBで20〜30分程度のビルド時間でした。


5.llama.cppビルド済みのコンテナイメージの保存

ビルド完了後、一旦dockerコンテナをCtrl+P,Ctrl+Q で抜けた後、dockerコマンドにてコンテナイメージのcommitを行います。
docker psで実行中のコンテナのコンテナIDを確認し、commit。イメージに付与するタグは適当決めてください。下記では「bonsai:cuda12.2.2」としています。 

 

$ docker ps
$ docker commit コンテナID bonsai:cuda12.2.2 

 

commit完了後、docker imagesでイメージが保管されていることを確認の後、docker stopでコンテナを一旦止めます。

 

6. コンテナを再度起動して、llama.cppを実行

huggingfaceからBonsaiのggufフォーマットのモデルをダウンロードし、適当なディレクトリに保存しておきます。
必要なモデルはBonsai-8B-Q1_0.ggufとTernary-Bonsai-8B-Q2_0.ggufです。

    • コンテナ起動
$ docker run --gpus all -it -e "LANG=ja_JP.UTF-8" -v ./models:/llama.cpp/models2 -v ./inputs:/llama.cpp/inputs bonsai:cuda12.2.2 /bin/bash

 

日本語を使う場合はここで環境変数LANGをja_JP.UTF-8に指定します。

    • llama.cpp実行(コンテナ内)
# cd llama.cpp
# ./build/bin/llama-cli \
    -m ./models2/Bonsai-8B-Q1_0.gguf \
    -p "Your are my personal assistant.Short answer is prefferable." \
    -t 4 \
    -c 65536 \
    -n 8192 \
    --temp 0.5 \
    --top-p 0.85 \
    --top-k 20 \
    -ngl 5

 

上記でコンテキスト長を64K個、生成トークン長 8192個、GPUに転送するレイヤー数(-ngl)を5層にしています。

VRAM 2GBだと1bit Bonsaiでは-nglは5が限界、1.58bit Bonsai(Ternary-Bonsai)だと4くらいが限界です。コンテキスト長、生成トークン長はPC本体側のメモリ16GBに対して空きが4GB程度残る設定です。

性能ですがCPU 4スレッド割当で1bit Bonsaiで4〜5トークン/secの生成速度、1.5bit残念ながら1トークン/secを下回っています。新しいマシンが欲しい(泣)

英文の要約等をさせると賢さはそこそこです。

 

llama.cpp + 1.5bit Bonsaiの実行画面とhost側でのnvidia-smi実行結果。

7.トークン生成性能

上記のコンテキスト長(-c)、生成トークン長(-n)だとGPUに載るレイヤー数が少ないのでパラメータを変えてテストします。

指示内容は以下2文をそれぞれ実行。

1. C言語でHello Worldのサンプルソースを作成。Hello World改行有り、10回繰り返し
2. SpaceXの会社概要を10行程度で要約せよ

 

モデル コンテキスト長(-c) 生成トークン長
(-n)
HOST
メモリ使用量(MiB)
GPU

Hello Word(C言語)
ソース生成
SpaceX説明
レイヤ数 メモリ使用量(MiB) Prompt
(t/s)
Generation
(t/s)
Prompt
(t/s)
Generation
(t/s)
Bonsai 8B 1bit 81920 10240 11674 4 1764 90.9 9.4 101.0 8.8
65536 8192 9248 5 1742 97.9 10.1 100.5 8.9
32768 4096 4318 10 1822 100.8 10.0 106.4 8.9
8192 2048 316 26 1916 124.5 11.2 122.4 10.6
4096 1024 107 99 1944 144.4 15.9 133.5 15.5
Bonsai 8B 1.58bit 65536 8192 10058 5 1908 77.7 1.0 85.5 0.9
8192 2048 1726 18 1884 99.5 1.7 102.0 1.6
4096 1024 1154 22 1874 101.8 2.1 107.4 1.9

GPUに載せるレイヤー数は、モデルロード時にsegmentation faultが発生しないところを狙って、トライ&エラーで求めています。
1bit量子化の場合、コンテキスト長4096,生成トークン長上限1024だと2GBのVRAMでもほぼ全てもレイヤーがGPUに載っている様です。
この状態だとトークンの生成速度は十分に速いです。ただしコンテキスト長4096では出来ることが少ないですね。ちょっと長い文章を読み込ませるとコンテキストバッファ不足に陥ります。

1bit量子化と1.58bit量子化の間に「賢さ」の差異はさほど大きくは感じられませんでした。1bit量子化だとGPU使わずフルCPUでもトークン生成速度がさほど落ちないので1bit量子化のほうが使いやすそうです。とはいえ、Claude Opus 4.6等とは賢さ、速度ともに比べ様が無いです。8Bくらいのパラメータ数だと課金気にせずローカルで使えるオモチャですね。

PC本体のメモリが16GBだと、1bit量子化でコンテキスト長80Kか64Kあたりなら軽作業の補助には使えそうな気がします。

 

上記の様な簡単なプロンプトでは1bit量子化の場合で9〜10トークン/秒で生成していますが、100〜300行程度のテキストファイル(pythonスクリプトだったり、とある企業のIR Reportの簡易版だったり)の要約をさせると、4トークン/秒くらいの生成速度でした。


GPU,CPUそれぞれのメモリフットプリントはllama.cppからExitした際に以下のように表示されます。

llama_memory_breakdown_print: | memory breakdown [MiB] | total   free    self   model   context   compute    unaccounted |
llama_memory_breakdown_print: |   - CUDA0 (GTX 1050)   |  1998 =  113 + (1824 =  1184 +     336 +     304) +          60 |
llama_memory_breakdown_print: |   - Host               |                 1154 =   890 +     240 +      24                |

 

8. 参考

NVIDIAContainerToolkitのインストール方法docs.nvidia.com

 

9. 追記

gemma4のE4B-ITモデル試したら、そちらのほうが圧倒的に良かったです。

ペルソナ設定したらちゃんと守ってくれる。

 

宮島サービスエリアピクミンテラス

あけましておめでとうございます。

1月4日に山陽自動車道下り線、宮島サービスエリアにあるピクミンテラスに行ってきました。1月2日夜の雪が少し残って、氷ピクミンがいい感じに凍ってました。

NEXCO西日本×ピクミン ピクミンテラスin宮島SA 特設サイト | NEXCO 西日本の高速道路・交通情報 渋滞・通行止め情報
朝9時40分くらいに到着。10時オープンの特設ショップの整理券は7番目でほぼ開店と同時に入れました。息子に原生生物コレクションとか色々買わされました。