2026年9月7日 月曜日
AI時短ラボ
検証· 約13

手元のメモリを99.998%まで使い切る量子化ツール「shoehorn」──プリセットGGUFをやめる発想

OSSツールshoehornは、Hugging Faceのモデルを「今使える実メモリ」から逆算してテンソルごとに混合精度を割り当て、量子化する。公式サイトの実行例では519.2MiBの予算に対し519.2MiBちょうど(余白13KB、使用率99.998%)まで詰め込んだ数字が示されている。

手元のメモリを99.998%まで使い切る量子化ツール「shoehorn」──プリセットGGUFをやめる発想
執筆・編集:
目次

3行まとめ

  1. shoehornは、プリセット量子化(Q4_K_Mなど固定の刻み)ではなく「今使える実メモリ量」から逆算してテンソルごとの精度を割り当てる、ローカルLLM向けの量子化ツール。
  2. 公式サイトの実行例では、519.2MiBの予算に対し519.2MiBちょうど(使用率99.998%、余白13KB)まで使い切ったと示されている。
  3. MITライセンス、Rustでゼロから実装(llama.cppのコードは一切リンクしていない)、出力は標準的なGGUF v3形式で、下流のllama.cpp系ツールでそのまま読める。

プリセット量子化の何が問題なのか

ローカルLLMを動かす時、多くの人はHugging Face上で配布されているQ4_K_MやQ5_K_Sといった「プリセットの量子化レベル」からファイルを選ぶ。公式サイトはこの方式の問題点を「手元のハードウェアを無視している」と表現する。予算に収まるものを選べば数百MBの品質の余地を無駄にし、逆に載ると思って選んだファイルがロード時に載らないことに気づく——という両方向のミスマッチが起きる、という指摘だ。

shoehornはこれを反転させる。まず手元で実際に使えるメモリ量を起点にし、そこから推論そのものが必要とする分を差し引き、残りの予算にぴったり収まるようテンソルごとの混合精度割り当てを解く。公式サイトが示す実行例は次の通りだ。

$ shoehorn fit unsloth/Qwen3-4B-GGUF --serve
weights: 519.2 MiB of 519.2 MiB budget (99.998% used, 13 KB slack)

519.2MiBの予算に対し519.2MiBちょうど、使用率99.998%・余白13KBまで詰め込んだ、という数字がそのままサイトに掲載されている。

ブラウザで「自分のマシンに何が載るか」を調べられる

サイトにはダウンロード前に使える診断ツールが埋め込まれている。手持ちのハードウェア(Mac 8GB〜128GB、GPU VRAM 8GB〜32GB、またはカスタム値)と、想定する会話の長さ(4k〜32kトークン)を選ぶと、Hugging Faceでダウンロード数の多いモデル群の中から、その予算に収まるものを品質順にランキングして表示する仕組みで、この処理はすべてブラウザ内で完結すると説明されている。

導入と仕組み

shoehornはllama.cppをPATH上に持つことを前提にした推論バックエンドで、インストールは次のコマンドで完結する(llama.cppもHomebrew経由で一緒に入る)。

brew install notactuallytreyanastasio/shoehorn/shoehorn

インストール後はshoehorn uiでローカルアプリが開き、モデルを選んでボタンを押すとチャットが始まる、という導線になっている。ローカルWebアプリは手元のマシンを計測し、予算に対するフィット具合を「メジャー(ものさし)」のように可視化し、その量子化がどれだけパープレキシティ(品質の目安)を犠牲にしたかを数値で示した上で、チャットボタンに至る、とサイトは説明している。

技術的な特徴として、量子化器自体はRustでゼロから実装されており、llama.cppのコードは一切リンクしていない。それでいて出力は標準的なGGUF v3形式で、llama.cpp系の他のツールでそのまま読み込める。macOS Apple Silicon、Linux x86-64(NVIDIA/AMD)、Windows x86-64(NVIDIA)向けのバイナリが配布されており、ソースからはcargo install --path .でもビルドできる。ライセンスはMIT。GitHub APIで確認したリポジトリメタデータによれば、star数86・fork数6・open issues 1(本記事執筆時点のスナップショット)で、created_atは2026-08-13T19:05:59Z、直近のpush(pushed_at)は2026-08-19T17:41:52Z。

リリース一覧APIで確認したところ、タグは3つ公開されている。リポジトリ作成(8月13日)からわずか4日後の8月17日にv0.1.0を公開し、同日中にv0.2.0へ更新、2日後の8月19日にv0.3.0(現時点の最新)を出している。

バージョン 公開日時(UTC)
v0.1.0 2026-08-17T03:59:19Z
v0.2.0 2026-08-17T22:51:41Z
v0.3.0(最新) 2026-08-19T00:17:41Z

各リリースのnotesはFull Changelogへのcompareリンクのみで、変更点を要約した本文は付いていなかった。リポジトリ作成から3回のバージョンを出し切るまでのペースの速さは、個人開発者によるツールらしい立ち上がりの早さを示している。

設計文書(DESIGN.md)が明かす「厳密フィット」の解き方

公式サイトだけでは分からない設計判断の詳細が、リポジトリ内のDESIGN.mdに記録されている。冒頭には、このツールの出発点になったユーザーの依頼文がそのまま引用されている。

"LLM runtime that takes in a BF16 model file and an imatrix and quantizes it to fit exactly into your available VRAM. Can you make that?"

DESIGN.mdによれば、shoehornは「量子化カーネル自体は自前実装、推論エンジンはllama.cppを再利用する」という設計判断を明示的に選んでいる。理由として「Metal推論エンジンを書くのは数ヶ月がかりの、大部分がコモディティな作業になる。新規性があるのは『厳密フィットのソルバー』とimatrix重み付きエンコーダの部分だ」と説明されている。対応する量子化フォーマットは、32要素ブロックのQ4_0・Q4_1・Q5_0・Q5_1・Q8_0と、256要素スーパーブロックのQ4_K・Q5_K・Q6_K、それにF16/BF16/F32のパススルーで、ビット幅にしておよそ4.5〜16 bits/weightの範囲をカバーする。IQ2/IQ3/IQ4系のフォーマットはv1では見送られており、「コードブック探索が1桁多くのコードを要し、主に4 bpw未満で効いてくる」として将来の拡張候補に位置づけられている。DESIGN.mdの記述をもとに対応フォーマットを整理すると次の通り。

分類 フォーマット ブロック単位
レガシー32ブロック(K-quant非対応行長のフォールバック) Q4_0・Q4_1・Q5_0・Q5_1・Q8_0 32要素
K-quant(品質/ビットのワークホース、imatrix対応) Q4_K・Q5_K・Q6_K 256要素
パススルー(正規化層・バイアスなど数値的にセンシティブな1次元テンソル向け) F16・BF16・F32
未実装(v1では見送り、将来拡張候補) IQ2・IQ3・IQ4

「厳密フィット」を解く核心部分は、D6「Exact-fit solving」というセクションに説明がある。各テンソルについて候補となる量子化タイプを1つ選び、バイト数の合計が予算以下という制約のもとで重み付き誤差の合計を最小化する、という「複数選択ナップサック問題」として定式化し、(1)ラグランジュ乗数λを二分探索しながら各テンソルでargmin(誤差 + λ×バイト数)を選ぶ処理を30回程度反復、(2)残った余白に対して「バイトあたりの誤差改善が最も大きいテンソル単位のアップグレード」を貪欲に繰り返す、という2段階のアルゴリズムだと説明されている。バイト単位の動的計画法は数GB規模の予算では計算量的に非現実的なため、この緩和法を採用したとDESIGN.mdは述べている。

メモリ予算自体の計算式(D7)は次の通りだ。

model_budget = usable_vram − kv_cache − compute_buffer − reserve

usable_vramはApple SiliconのMetal APIが返すrecommendedMaxWorkingSetSize(統合メモリのおよそ75%)を既定値とし、--budgetで上書きできる。kv_cacheはモデル自身のGGUFハイパーパラメータと--ctxからn_layer×ctx×n_kv_heads×(key_len+value_len)×2バイトという厳密な計算式で求め、compute_bufferはロジットとアクティベーションのスクラッチ領域を粗く見積もり、既定512MiBの--reserveマージンで見積もり誤差を吸収する設計だとDESIGN.mdは説明している。

開発時のテストモデルにはQwen3-0.6B(unslothのGGUFビルド)を使い、imatrixは約1,000行のプローズ+コードの較正テキストに対しllama-imatrixで自前生成したという。誤差計測は全行を測るとテンソルあたり候補数×行数で計算量が5倍に膨らむため、テンソルあたり最大128行を均等サンプリングして合計値をスケールする方式(--exact-errorsで無効化可能)を採り、Qwen3-0.6Bでのプラン作成+ソルバー実行は実測0.7秒だったと記載されている。

「99.998%」が他の環境でも再現するかは確認していない

本記事はshoehorn公式サイト(notactuallytreyanastasio.github.io/shoehorn)、リポジトリ内のDESIGN.md、GitHub APIのリポジトリメタデータ・リリース一覧をcurlで取得した内容にもとづく。掲載されている「99.998%」という数字は公式サイトに示された1つの実行例であり、モデルや予算の組み合わせによってこの数値がどこまで安定するかは確認できていない。llama.cppを別途インストールした上で実際にshoehornを動かし、量子化やパープレキシティの数値を自分の手元で再現するところまでは今回行っていない。DESIGN.mdに書かれているアルゴリズム(ラグランジュ緩和・貪欲な上積み・誤差サンプリング)の説明も、実装コード自体(Rustのソースファイル)を読んで裏取りしたわけではなく、設計文書の記述をそのまま紹介している。開発者名(GitHubアカウントnotactuallytreyanastasio)以外の運営主体情報も公式サイト・DESIGN.md・リポジトリページからは読み取れなかった。

メモリ予算から逆算する量子化の紹介は見当たらない

Zenn・Qiitaともに実質的な言及はゼロだった。ローカルLLMの量子化を扱う日本語記事はGGUF形式の解説やLM Studio・Ollamaの使い方が中心で、「メモリ予算から逆算して量子化レベルを最適化する」というアプローチそのものはまだ紹介されていない。

関連記事

シェア: ポスト はてブ

出典・参照資料

AIニュースの解説を動画でも

YouTubeでは注目ニュースの背景を解説し、Xでは新着記事をお知らせしています。

コメント

まだコメントはありません。最初のコメントを書いてみませんか?

AIについて聞きたいことはありますか?

質問箱で無料で受け付けています。回答は公開され、他の方の参考にもなります。

質問箱を見る →

新しい記事をメールで受け取る

AIの新しい発表を、出典付きで整理して届けます。

関連記事