1.58ビットの壁を破る——三値LLM「BITCOS」が零点スパース性で変える推論の経済学

はじめに:1.58ビットという「当たり前」は本当に最適なのか

三値LLMとは、ニューラルネットワークの重みを −1・0・+1 の3つの値だけで表現するモデルです。−1と+1が正負の符号を、0が「その重みは寄与しない」ことを担います。3つの記号を区別するには理論上 log₂3 ≈ 1.585 ビットあれば足りるため、こうしたモデルは総称して「1.58ビットモデル」と呼ばれてきました。この呼称を広めたのが、三値重みでも大規模モデルがフル精度に匹敵する性能を保てることを示したBitNet b1.58です。以来1.585ビットという数字は、三値LLMの到達点として、ある種の「当たり前」になっています。

しかし、これは理論上の下限であって、実際に配備されている形式の効率ではありません。現在の標準的な保存方法は、5つの三値を1バイトに詰める方式です。3⁵ = 243 ≤ 256 ですから理屈の上では 8 ÷ 5 = 1.6 ビットで収まりますが、実際のモデルは128個などの2の冪のブロック単位で重みを扱うため、ブロックあたり ⌈128 ÷ 5⌉ = 26 バイトが必要となり、実効値は1.625ビットまで切り上がります。さらに重要なのは、この1.625ビットという数字が「−1・0・+1が等しい確率で出現する」という前提の上に成り立っている点です。

Georganas・Heinecke・Dubeyによる研究(arXiv:2609.16338)が問い直したのは、量子化の精度の限界ではありません。保存形式に潜むこの前提と無駄です。著者らは29個の三値LLMモデルで実際の重みの分布を測定し、ゼロが全重みの最大51.5%を占めることを突き止めました。−1と+1に比べてゼロが突出している以上、「3記号が等確率」という仮定は現実と一致していません。ならば分布の偏りを保存形式そのものに織り込めばよい——これがBITCOS(BITmap and COmpacted Signs)という発想につながります。

得られる結論を先に示します。三値テンソルを「プレゼンス・ビットマップ」と「圧縮サイン・ベクトル」の2つに分けて保存すると、コストはゼロ密度 z に対して 2 − z ビット/重みまで下がります。ゼロ密度51.48%のモデルでは1.485ビットに達し、理論上の下限とされてきた1.585ビットを下回ります。実測では重みの読み出し量が2ビット形式比で1.16〜1.32倍削減され、エンドツーエンドのデコードはCPUで最大1.18倍、GPUで最大1.27倍高速化しました。再学習は不要で、出力は元のモデルとビット単位で同一です。

flowchart LR
    A["三値重み<br/>-1 / 0 / +1"] --> B["ゼロの偏りを測定<br/>29モデルで最大51.5%"]
    B --> C["BITCOS形式で保存<br/>プレゼンス・ビットマップ + 圧縮サイン"]
    C --> D["CPU / GPUカーネルで展開<br/>AVX-512 / AVX2 / Xe2"]
    D --> E["推論の高速化<br/>デコード最大1.27倍"]

三値モデルは本当に1.58ビットが限界なのか、低ビット推論を速くする鍵はどこにあるのか。その答えは、量子化の基本と「1.58ビット」という数字の成り立ちをたどり、BITCOSの保存形式とCPU・GPUのカーネル実装、実測された性能と適用限界を確認するなかで見えてきます。

三値LLMとは何か——なぜ重みを3つに絞るのか

量子化とは、学習済みモデルの重みをより少ないビット数で表し直す技術です。一般的なモデルは重みをFP16やBF16の16ビットで保持しますが、推論のたびにこの重みをメモリから読み出す必要があります。量子化の狙いは2つあります。モデルのファイルサイズとメモリ使用量を下げること、そして重みの読み出し量を減らして推論を速くすることです。8B(80億)パラメータのモデルを例にすると、16ビットなら重みだけで約16GB、8ビットなら約8GB、4ビットなら約4GBという関係になります。

三値量子化(ternary quantization)は、この丸めを極限まで進めた方式です。各重みを −1・0・+1 の3値のいずれかに置き換え、その値にグループ単位のスケール係数を掛けたものとして表現します。たとえば128個の重みを1グループとし、グループごとに1つの16ビットのスケール係数を共有する構成では、実際に保存するのは3値の列と128分の1個のスケールだけです。重みが3値に揃うと、行列ベクトル積は「加算・減算・スキップ」だけになり、重みと入力の乗算が消えます。0の重みは入力に何も寄与しないため、計算そのものを省けます。

この方式を現実的な選択肢にしたのがBitNet b1.58(arXiv:2402.17764)です。三値の重みで学習した大規模モデルが、フル精度のモデルに匹敵する性能を維持できることを示しました。3つの記号を区別するには理論上 log₂3 ≈ 1.585 ビットあれば足りるため、こうしたモデルは「1.58ビットモデル」と呼ばれるようになります。

三値が注目される理由は、精度よりも速度の構造にあります。トークンを1つずつ生成するデコードでは、行列ベクトル積が処理の中心になり、演算量に対して読み出す重みの量が極端に多くなります。計算ユニットは、メモリから重みが届くのを待つ時間が支配的になり、これがメモリ帯域ボトルネックです。重み1つあたりのビット幅を16分の1にすれば、同じ帯域でも単位時間に送り込める重みの数が16倍になり、待ち時間がその分短くなります。

flowchart LR
    A["トークンを1つ生成"] --> B["重み行列をメモリから読み出す<br/>例:8Bパラメータ×16ビット ≒ 16GB"]
    B --> C["行列ベクトル積<br/>演算量は小さい"]
    C --> D["次の重みを読み出す"]
    D --> B
    B -->|読み出し待ちが支配的| E["計算ユニットは待ち状態"]
表現形式 1重みあたりのビット幅 8Bモデルの重みサイズ(概算)
FP16 / BF16 16ビット 約16GB
8ビット 8ビット 約8GB
4ビット 4ビット 約4GB
2ビット 2ビット 約2GB
三値 理論上 約1.585ビット(実際は保存形式に依存) 約1.6GB

ここで注意したいのは、三値モデルの実効的なビット幅が「丸め方」だけで決まるわけではないという点です。−1・0・+1という値の並びを、どのような形式でメモリに詰めて保存するかによって、実際のサイズは変わります。次の節では、1.58ビットという数字がどこから来て、実装のなかでどのように膨らむのかを確認します。

「1.58ビット」のからくり——理論値と実装値のギャップ

三値LLMの重みは、−1・0・+1 の3通りしか取りません。情報理論では、等しい確率で現れる3つの記号を区別するのに必要な情報量は log₂3 ≈ 1.585 ビットです。この値が「1.58ビット」という呼称の由来であり、三値モデルの理論的な下限として長らく受け入れられてきました。ただしこれは、3つの記号が同じ頻度で現れる場合の話です。実際にモデルをメモリ上へどう詰めるかは別の問題で、ここに理論値と実装値のずれが生まれます。

もっとも素直な実装は、5つの三値(trit)を1バイトにまとめる方式です。1バイトは256通りを表現できますが、三値5個の組み合わせは 3⁵ = 243 通りで、ちょうど256に収まります。つまり5つの重みを8ビットで保存でき、単純計算では 8 ÷ 5 = 1.6 ビット/重みになります。理論値の1.585ビットに近い、無駄の少ない詰め方です。

ところが実運用では、ここにもう一段の丸めが入ります。推論カーネルは重みを128個などの2の冪のブロック単位でまとめて処理します。1バイトに5個ずつ詰めると、128個の重みには ⌈128 ÷ 5⌉ = 26 バイトが必要です。5 × 25 = 125 個までしか収まらず、残り3個のために1バイトを追加で確保するためです。これをビット幅に直すと 26 × 8 ÷ 128 = 1.625 ビット/重み。1.585でも1.6でもなく、実際に配備される形式の効率は1.625ビットです。

flowchart LR
    subgraph B1["1バイト = 5つの三値"]
        T["trit ×5<br/>3^5 = 243 ≦ 256"]
    end
    subgraph B2["128重み = 26バイト"]
        A["25バイト<br/>5 × 25 = 125 重み"] --> R["余り 3 重み<br/>→ +1バイトにパディング"]
    end
    B1 -->|"8/5 = 1.6 ビット"| B2
    B2 -->|"26 × 8 / 128"| C["実効 1.625 ビット/重み"]
見積もり方 ビット/重み 前提
情報理論上の下限 log₂3 ≈ 1.585 3記号が等確率
5値パッキング(単純計算) 8 ÷ 5 = 1.600 5三値を1バイトに格納
5値パッキング(ブロック整列後) ⌈128÷5⌉ × 8 ÷ 128 = 1.625 128個単位でブロック処理
2ビットパッキング 2.000 2ビット固定で格納

ここで著者らが指摘するのは、この1.625ビットが成り立つ前提そのものです。5つの三値を1バイトに詰める方式も、ブロック単位で切り上げる方式も、「−1・0・+1が等しい確率で出現する」ことを暗黙に仮定しています。3記号が同じ頻度で現れるなら、どの組み合わせにも同じビット数を割り当てるのが最も効率的だからです。逆に言えば、出現頻度に偏りがあれば、その偏りを保存形式に反映させる余地が残ります。理論限界として語られる1.585ビットと、実際に使われている1.625ビットは別物であり、実装側にはなお改善の伸びしろがある——これが次の節で扱う発想の出発点になります。

BITCOSとは——「ゼロが多い」という事実を設計に活かす

三値LLMの重みは −1・0・+1 の3種類ですが、実際のモデルでこの3つが同じ割合で現れるわけではありません。29個の最先端三値モデルの重み分布を実測したところ、ゼロが全体の最大51.5%を占めていました。−1と+1はほぼ半分ずつを分け合い、ゼロだけが突出して多いという偏りです。従来の保存形式は「3記号が等確率で出現する」ことを前提にビット幅を決めていたため、この偏りは完全に無視されていました。

BITCOS(BITmap and COmpacted Signs)は、この偏りを保存形式そのものに反映させたレイアウトです。三値テンソルを次の2つの要素に分けて保存します。

  1. プレゼンス・ビットマップ:重み1つにつき1ビットを持ち、その重みが非ゼロなら1、ゼロなら0とする。テンソル全体と同じ長さになる。
  2. 圧縮サイン・ベクトル:非ゼロの重みにだけ1ビットを割り当て、+1 か −1 かをテンソルの順序で並べる。長さはビットマップの1の個数(popcount)と一致する。
flowchart LR
    A["三値テンソル<br/>−1 / 0 / +1"] --> B["プレゼンス・ビットマップ<br/>重みごとに1ビット<br/>非ゼロ=1"]
    A --> C["圧縮サイン・ベクトル<br/>非ゼロの重みにだけ1ビット<br/>+1 / −1"]
    B --> D["ビットコスト = 1ビット/重み"]
    C --> E["ビットコスト = (1−z) ビット/重み"]
    D --> F["合計 = 2 − z ビット/重み"]
    E --> F

この構造の要点は、ゼロがビットマップの1ビットしか消費せず、符号ビットを持たないことです。ゼロ密度を z とすると、重みあたりのコストは次式で表されます。

コスト = 1(ビットマップ)+ (1 − z)(符号)= 2 − z ビット/重み

ゼロが増えるほど符号ベクトルが短くなるため、コストは右下がりに下がります。8×8(64重み)のテンソルで30個がゼロ(z = 0.469)の場合、プレゼンス64ビット+符号34ビットで合計98ビット、つまり1.531ビット/重みとなり、三値の理論下限 log₂3 ≈ 1.585ビットを下回ります。

損益分岐点と実測モデルでの効果

比較対象は2つあります。5値パッキング(実効1.625ビット)と2ビット固定パッキング(2.000ビット)です。前者とBITCOSが逆転するのは 2 − z < 1.625、すなわち z > 0.375 のとき。実測した29モデルのうち26モデルがこの条件を満たしました。一方、2ビット固定パッキングに対しては 2 − z < 2 が z > 0 で常に成り立つため、すべてのゼロ密度でBITCOSが有利です(削減率1.16〜1.32倍)。

モデル ゼロ密度 z BITCOS(2 − z) 2ビット比 5値パッキング比
CAT-Q Qwen3-1.7B 51.48% 1.485 ビット 1.32× 1.09×
CAT-Q Qwen3-32B 47.11% 1.529 ビット 1.28× 1.06×
BitNet b1.58 2B4T 42.19% 1.578 ビット 1.27× 1.03×
Maple 20B-A1B 40.67% 1.593 ビット 1.25× 1.02×
Bonsai 27B 29.66% 1.703 ビット 1.16× 0.96×

ゼロ密度のレンジは29.7%(Bonsai 27B)から51.5%(CAT-Q Qwen3-1.7B)にわたり、最良のモデルでは1.485ビット/重みまで低減します。16ビットのグループスケール係数のオーバーヘッドまで含めると、BITCOSの優位はさらに広がります。

測定対象となったモデル群

検証には、作り方の異なる複数のファミリが使われています。BitNet(量子化認識学習による三値事前学習の代表格)、Bonsai(1.7B〜27B)、CAT-Q(Qwen3系を学習後量子化したモデルで、最大235BのMoE構成を含む)、ParetoQ(125M〜1.5B)、TriLM/Spectra(99M〜3.9B)、Maple(20B-A1BのMoE)、BitCPM-CANNです。モデルの規模・学習手法・アーキテクチャがばらついているにもかかわらず、いずれもゼロが突出して多いという共通の性質が確認されています。つまりゼロの偏りは特定モデルの癖ではなく、三値量子化そのものに備わった構造的な特徴だと言えます。

flowchart TD
    S["三値重みの分布を測る"] --> Z{"ゼロ密度 z"}
    Z -->|"z > 0.375"| W["5値パッキングより小さい<br/>26 / 29 モデル"]
    Z -->|"z > 0"| V["2ビット固定より常に小さい<br/>29 / 29 モデル"]
    W --> R["最小 1.485 ビット/重み<br/>理論下限 1.585 ビットを下回る"]
    V --> R

BITCOSはどう展開されるのか——CPUとGPUの実装

「保存形式を小さくしても、取り出しに時間がかかれば速くならない」——ここがBITCOSの実装で最初に立ちはだかる壁です。BITCOSは重みをプレゼンス・ビットマップと圧縮サイン・ベクトルに分けて保持するため、行列ベクトル積の計算に入る前に、圧縮されたビット列から元の三値(−1・0・+1)を復元する展開(アンパック)が必要になります。この展開が重ければ、メモリで節約した分は相殺されてしまいます。データ形式と展開カーネルは切り離せない一組であり、x86 CPU向けに2種類、Intel Xe2 GPU向けに1種類の命令列が用意されています。

AVX-512版——マスクをそのまま述語レジスタに使う

AVX-512対応のx86 CPUでは、プレゼンス・ビットマップの32ビットをそのまま述語レジスタ k1 に読み込めます。展開の中心は pdep(parallel bit deposit) です。pdepは、ソースの下位ビットをマスクの1が立っている位置へ順番に落とす命令で、圧縮サイン・ストリームの次の32ビットを、非ゼロの重みが並ぶ位置へ「散らす」役割を担います。この散布操作が、そのまま圧縮解除になります。

その後の復元は2回のマスク付き移動だけです。まずk1でグループスケール(+s)をゼロマスク移動し、続いて負の値を示すマスクで −s を上書きします。32行分を処理するのに17命令、うち展開に相当するのはpdep 1命令とマスク付き移動2命令の計3命令で、残りはロード・アドレス計算・プリフェッチ・popcnt・FMAといった定型処理です。展開の負担が非常に軽いことが、CPUで効果が出る理由です。

AVX2版——int8で再構成し内積を取る

クライアント向けx86 CPU(AVX2、AVX-VNNI-INT8)にはマスクレジスタもFP16演算もありません。プレゼンスをバイト単位のマスクに実体化するだけで5命令(ブロードキャスト、シャッフル、比較)かかります。重みはint8として組み立て直し、w = p − 2n(p=存在ビット、n=負ビット)という式で −1・0・+1 を復元します。具体的には N を 0xFE とANDして −2n を作り、そこから P を減算します。活性化も128重みごとにint8へ量子化し、内積はAVX-VNNI-INT8でint32に累積、グループスケールは最後に1回だけ適用されます。

Xe2 GPU版——ルックアップテーブルで代替する

Xe2 GPUにはpdepに相当する命令がないため、256エントリの参照表(LUT)を共有ローカルメモリに置きます。各エントリは4つのfp16定数を持ち、テーブル全体で2KBです。鍵は8ビットで、4行分の存在ビット4つと符号ビット4つを連結して作ります。1回のルックアップで4つの三値、たとえば (+1, −1, 0, −1) がそのまま得られます。

グループを4行にしたのは設計上の必然です。8行にするとテーブルが2¹⁶エントリ必要になり実用的ではありません。256エントリに収まる行数であり、かつDPAS/XMXのVNNI2オペランド配置(連続4行=2つのdword)と一致するのが4行なのです。符号の読み出し位置は列ごとにカーソルで管理し、各グループが消費するビット数はpopcount(m) なので、読み出し窓をレジスタに保持してその分だけ右へシフトします。16レーンが16出力列に対応し、1回のルックアップで4行×16列=64個の重みを埋められます。

実装 対象 プレゼンスの扱い 展開の鍵となる操作 内積の演算
AVX-512版 x86サーバーCPU 32ビットを述語レジスタ k1 に直接ロード pdepで符号を散布+マスク付き移動2回 FP16
AVX2版 x86クライアントCPU バイトマスクへ展開(5命令) w = p − 2n でint8再構成 AVX-VNNI-INT8
Xe2 GPU版 統合・ディスクリートGPU 4行分を8ビットの鍵にまとめる 256エントリLUT(2KB)の参照 DPAS/XMX
flowchart TB
    A["BITCOSの圧縮データ<br/>プレゼンス・ビットマップ+圧縮サイン"] --> B{"対象ハードウェア"}
    B -->|"AVX-512"| C["32ビットのプレゼンスを k1 へ<br/>pdep で符号を非ゼロ位置に散布<br/>マスク付き移動で +s / −s を復元"]
    B -->|"AVX2"| D["プレゼンスをバイトマスク化<br/>w = p − 2n で int8 を再構成"]
    B -->|"Xe2 GPU"| E["4行を8ビット鍵に連結<br/>256エントリLUTを1回参照<br/>4つのfp16を取得"]
    C --> F["三値 × 活性化の内積"]
    D --> F
    E --> F
    F --> G["グループスケールを適用して出力"]

これらBITCOSカーネルは、2ビットの最先端カーネル(LIBXSMM/XeTLA)と並べて比較され、vLLM のCPUバックエンドとXPUバックエンドに統合したうえで評価されています。同じランタイム・同じモデルで保存形式だけを差し替える構成になっているため、差が出ればそれはカーネルと形式の実装力の差だと言えます。

性能評価——実測されたスピードアップ

BITCOSが理論上2 − z ビット/重みまで小さくなることは、そのまま推論が速くなることを意味しません。圧縮ビット列を展開する命令のコストが上回れば、メモリで節約した分は消えます。そこで著者らは5つの実行プラットフォームで、マイクロベンチマークとエンドツーエンド推論の両方を実測しています。比較対象は、CPU側がLIBXSMM、GPU側がXeTLAによる最先端の2ビットカーネルです。

略称 実機 コア数 メモリ帯域
サーバーCPU Intel Xeon Platinum 8592+ 64 約245GB/s
クライアントCPU Intel Core Ultra 9 285K 24(P8+E16) 約98GB/s
省電力CPU Intel Core Ultra 7 258V 8(P4+E4) 約108GB/s
統合GPU Arc 140V 8 Xe2コア 約108GB/s
ディスクリートGPU Arc Pro B70 32 Xe2コア 約500GB/s

マイクロベンチマーク——GEMVで測る土台の速さ

GEMV(行列ベクトル積)はデコード時の計算のほぼ全体を占めるため、重みをどれだけ速く読めるかがそのまま速度になります。32768×16384の重み行列、グループサイズ128という条件で、実際に配備されている三値モデルのゼロ密度域 z ∈ [0.297, 0.515] を対象に測定されました。2ビット最先端カーネルに対する速度比は、サーバーCPUで1.14〜1.28倍、クライアントCPUで1.13〜1.27倍、統合GPUで1.04〜1.14倍、ディスクリートGPUで1.01〜1.12倍です。

エンドツーエンドのデコード

マイクロベンチマークの利得が実推論に残るかを確かめるため、vLLM上で7つの三値モデルを動かし、バッチ1・256トークン生成のデコードスループットが測定されています。アテンションやKVキャッシュ管理が混ざるぶん利得は緩やかになり、2ビット最先端カーネル比でサーバーCPU 1.10〜1.18倍、クライアントCPU 1.02〜1.15倍、統合GPU 1.09〜1.22倍、ディスクリートGPU 1.02〜1.27倍でした。llama.cppのTQ1_0形式(5値パッキング)に対しては、サーバーCPUで1.13〜1.48倍、クライアントCPUで1.46〜1.74倍です。

公平に見ておくべき事実もあります。比較対象の2ビット最先端カーネル自体が、TQ1_0より最大1.78倍速いのです。BITCOSは「弱い相手に勝った」のではなく、すでに十分強いベースラインの上でさらに上積みしています。

削減率と速度向上率のギャップ

BITCOSの重みトラフィック削減は2ビット形式比で1.16〜1.32倍ですが、実測のGEMV速度向上は最大1.28倍、エンドツーエンドでは最大1.27倍にとどまります。削減率がそのまま速度にならないのは、ビットマップとスケール係数の読み出し、popcountやカーソル更新といった展開まわりの処理が固定費として残るためです。この固定費が相対的に重くなる環境では利得が消えることもあり、効果の有無はプラットフォームの律速要因に左右されます。

flowchart LR
    A["BITCOSの重み<br/>1.485〜1.703ビット/重み"] --> B["重みトラフィック<br/>2ビット比 1.16〜1.32倍削減"]
    B --> C["GEMV速度<br/>最大1.28倍"]
    B --> D["展開の固定費<br/>ビットマップ読み出し・popcount・スケール"]
    C --> E["エンドツーエンド・デコード<br/>CPU最大1.18倍 / GPU最大1.27倍"]
    D --> E

効くところと効かないところ——ルーフライン分析

BITCOSはゼロ密度 z に対して 2 − z ビット/重みまで重みを小さくできますが、「ペイロードが小さいほど速い」という関係は常に成り立つわけではありません。展開命令のコストが相対的に大きくなると、メモリで稼いだ時間が命令の時間に置き換わり、節約が速度に結びつかなくなります。この境界を事前に予測するために、著者らは2項のルーフライン・モデルを用意しました。

ルーフライン・モデルとは、ハードウェアが持つ「帯域の上限」と「処理(ここでは展開)の上限」という2つの制約を並べ、実際の速度をどちらが決めているかを判定する枠組みです。BITCOSでは32個の重みを1回処理するあたりの読み出しバイト数を、ゼロ密度 z の関数として次のように定式化しています。

B(z) = 4(ビットマップ)+ 4(1 − z)(圧縮サイン)+ 0.5(グループスケール)= 8.5 − 4z

32重みあたりのビットマップは32ビット=4バイト、スケール係数は16ビット=0.5バイト、符号ベクトルは非ゼロの重みの数だけ伸びるので 4(1 − z) バイトになります。このとき1回の反復時間は T = max(B(z)/β, γ)、実効帯域は min(β, B(z)/γ) で近似されます。β はコアあたりの読み出し帯域(バイト/サイクル)、γ は重みがキャッシュに常駐した状態での1反復あたりの展開コスト(サイクル)です。B(z)/γ が β を上回ればメモリ律速、下回れば命令律速という判定になります。

ゼロ密度 z = 0.40(B = 6.9バイト)での各プラットフォームの位置は次のとおりです。

プラットフォーム コア種別 展開コスト γ(サイクル) 帯域 β(バイト/サイクル) B/γ 判定
サーバーCPU 高性能 4.60 1.321 1.502 メモリ律速
クライアントCPU 高性能 5.00 0.756 1.381 メモリ律速
クライアントCPU 高効率 7.95 0.903 0.868 命令律速(境界付近)
省電力CPU 高性能 5.00 3.224 1.381 命令律速
省電力CPU 高効率 7.95 3.663 0.868 命令律速

表の意味は明快です。サーバーCPUとクライアントCPUの高性能コアはメモリ律速にあり、BITCOSが減らしたペイロードがそのまま時間短縮に変換されます。一方、省電力CPUはコア数が8と少ないのに約108GB/sという帯域を共有しており、コアあたりの帯域が過剰になっています。ここでは展開コストが上限を決めてしまうため、BITCOSは2ビット形式より全密度で遅くなり、展開が安い2ビット形式が勝ちます。同じ傾向はクライアントCPUの高効率コアにも表れ、B/γ が β をわずかに下回る境界付近に位置しています。

実務的な指針はこうなります。メモリ帯域が豊富でコア数が少ないクライアント環境こそがBITCOSの適用限界であり、採用前に対象ハードウェアがどちらの律速にあるかを確認する必要があります。極端な例としてゼロ密度 z = 0.95 では展開命令列が完全にボトルネックとなり、実効帯域は約190GB/sに制限されました。「ゼロが多いほど有利」という直感にも、命令側から上限がかかるということです。

flowchart TD
    A["ゼロ密度 z を測定<br/>B(z) = 8.5 − 4z バイト / 32重み"] --> B{"B(z)/γ > β ?"}
    B -->|"上回る"| C["メモリ律速<br/>ペイロード削減が速度に直結<br/>サーバーCPU・高性能コア"]
    B -->|"下回る"| D["命令律速<br/>展開コストが上限を決める<br/>省電力CPU(8コア・約108GB/s)"]
    C --> E["BITCOSが有利"]
    D --> F["2ビット固定形式が有利"]

先行研究のなかでBITCOSは何を変えたのか

三値LLMの研究は、大きく2つの系統に分かれます。1つは量子化認識学習(QAT:学習の過程で三値制約をかけてモデルそのものを作り込む方式)で、BitNet b1.58やParetoQ、Spectra/TriLM、Bonsai、Mapleなどが該当します。もう1つは学習後量子化(PTQ:すでに学習済みのモデルを事後的に三値へ丸める方式)で、CAT-QやTWLAが代表例です。BITCOSはこのどちらでもありません。「高品質な三値モデルをどう作るか」ではなく、「できあがった三値モデルをどう保存し、どう展開するか」に貢献する技術であり、既存のQAT・PTQモデルの上にそのまま重ねられます。

三値モデルのスパース性を活かす先行研究も存在します。三値CSC形式は非ゼロ重みのインデックスだけを保存し、三値の乗算を加減算に置き換える方式です。計算が律速するプリフィル(入力全体をまとめて処理する段階)では有効ですが、バッチ1の逐次デコードはメモリ律速のためかえって遅くなり、cuBLASをレイヤ単位で上回るには75〜88%という高いスパース性が必要でした。大半の三値モデルのゼロ密度は29.7〜51.5%にとどまるため、この条件は現実的ではありません。

学習段階でスパース性を仕込む系統もあります。Sparse-BitNetは学習全体を通じてN:Mマスク(M個の重みのうちN個を残すパターン)を動的に適用し、Sherryは4重みごとに1つのゼロを強制して1.25ビット/重みを達成しました。いずれも「学習のやり直し」が前提で、Sparse-BitNetの6:8構成では困惑度が0.17〜0.32悪化し、下流タスク精度も0.8〜3.8ポイント低下しています。

BITCOSの違いは、既存チェックポイントにすでに含まれている非構造化ゼロをそのまま使う点にあります。再学習は不要、専用のスパースハードウェアも不要で、三値値をビット単位で元のモデルと同一に復元します。加えてBITCOSは位置情報を持つ密なビットマップを順に読むためアクセスがシーケンシャルで、ベクトル化しやすいという設計上の利点があります。インデックス方式が非ゼロ位置への不規則なギャザーを伴うのとは対照的です。

手法 再学習 必要なスパース性 データアクセス 精度への影響
三値CSC形式 不要 75〜88%(デコードで有利になる条件) 不規則なギャザー なし(表現は同一)
Sparse-BitNet 必要 学習時にN:Mマスクを強制 構造化スパース 困惑度0.17〜0.32悪化
Sherry 必要 ゼロ密度25%を固定 構造化スパース 量子化に伴う劣化あり
BITCOS 不要 既存のゼロをそのまま利用 密なビットマップで順次読み出し ビット単位で同一(bit-exact)
flowchart TD
    A["三値LLMの研究"] --> B["作り方<br/>QAT・PTQ"]
    A --> C["保存と展開のしかた"]
    B --> D["高品質な三値モデルを生成"]
    C --> E["三値CSC形式<br/>インデックス保存・再学習不要"]
    C --> F["Sparse-BitNet / Sherry<br/>学習時にゼロを強制"]
    C --> G["BITCOS<br/>既存のゼロをそのまま使う"]
    D --> G
    E --> H["計算律速のプリフィル向け"]
    F --> I["再学習と精度劣化を伴う"]
    G --> J["再学習不要・bit-exact・シーケンシャルアクセス"]

この技術が実務にもたらすもの

BITCOSの実務上の価値は、第一に「すでに手元にある三値モデルを、そのまま小さく・速くできる」点にあります。三値LLMの配布ファイルサイズは重みのビット幅にほぼ比例するため、2ビット形式から1.485〜1.7ビットへ移行できれば、ダウンロード量とディスク占有が1.16〜1.32倍減ります。さらに、デコード時に読み出す重みの総量そのものが減るため、メモリ帯域が足を引っ張る環境では待ち時間の短縮に直結します。再学習もモデル再変換も不要で、出力はビット単位で元モデルと一致するため、既存の推論スタックに保存形式とカーネルを差し替えるだけで導入できます。

とくに効果が大きいのは、オンデバイスやエージェント用途です。これらはバッチ1の逐次デコードが中心で、計算量よりも重み読み出しの帯域が性能を決める典型的なメモリ律速のワークロードです。1台の端末でモデルを常駐させながら対話やツール呼び出しを回す構成では、重みトラフィックの削減率がほぼそのまま応答速度の改善として現れます。実測でも、統合GPUで最大1.22倍、ディスクリートGPUで最大1.27倍のデコードスループット改善が報告されています。

用途・環境 主な律速要因 BITCOSの効き方
サーバーCPUでのバッチ1デコード メモリ帯域 ペイロード削減が速度に直結(最大1.18倍)
統合GPU・ディスクリートGPU メモリ帯域 帯域集約型のため効果が安定(最大1.22〜1.27倍)
高性能コア中心のクライアントCPU メモリ帯域 展開コストを吸収できる範囲で有効(最大1.15倍)
帯域が過剰でコア数が少ない端末 展開命令 2ビット形式のほうが速くなる場合がある

一方で、どのハードウェアでも一律に速くなるわけではありません。メモリ帯域が豊富でコア数が少ない端末では、展開命令のコストが相対的に重くなり命令律速へ転じます。この場合、展開が軽い2ビット形式のほうが有利になります。導入判断では、次の流れで自環境の律速要因を確認するのが実務的です。

flowchart TD
    A["対象ワークロードを確認"] --> B{"バッチ1の逐次デコードか"}
    B -- "いいえ(大バッチ・プリフィル中心)" --> C["メモリ削減の効果は限定的<br/>計算律速の最適化を優先"]
    B -- "はい" --> D{"コアあたりメモリ帯域が逼迫しているか"}
    D -- "はい(メモリ律速)" --> E["BITCOSを採用<br/>重みトラフィック削減が速度に反映"]
    D -- "いいえ(命令律速)" --> F["2ビット形式を維持<br/>展開の安さを優先"]
    E --> G["既存チェックポイントをそのまま変換し<br/>出力の一致を検証"]

今後はCPUとGPU以外のアーキテクチャへの展開が課題として残されており、データ形式とカーネル実装を同時に設計するという考え方自体が、他の低ビット形式にも広がる可能性があります。採用を検討する際は、「あなたの環境はメモリ律速か、命令律速か」を最初に測ることが、最短で効果を得るための判断基準になります。

よくある質問

BITCOSを使うにはモデルを再学習する必要がありますか?

不要です。BITCOSは、既存の三値チェックポイントにすでに含まれているゼロをそのまま利用する保存形式であり、再学習もスパース化の強制も行いません。重みの値そのものには一切手を加えず、元のモデルと同じ三値値をビット単位で復元できるため、出力は変化しません。学習済みモデルを差し替えるだけで導入できる点が、学習時にスパース構造を課す手法との大きな違いです。

「1.58ビット」より小さい値になるのはなぜですか?

1.585ビット(log₂3)は、−1・0・+1という3つの記号が等しい確率で出現するという前提のもとでの情報理論上の下限です。しかし実際の三値モデルを29個測定すると、ゼロが重み全体の29.7%〜51.5%を占めており、この前提は成り立っていません。ゼロをビットマップの1ビットだけで表し符号ビットを持たせないBITCOSでは、ゼロ密度を z とすると 2 − z ビットまで下がり、ゼロ密度51.48%のCAT-Q Qwen3-1.7Bでは1.485ビット/重みを達成しています。

どのくらい速くなりますか?

実運用に近いゼロ密度域(z ∈ [0.297, 0.515])では、最先端の2ビットカーネルと比べてエンドツーエンドのデコードがサーバーCPUで最大1.18倍、統合GPUで最大1.22倍、ディスクリートGPUで最大1.27倍になります。行列ベクトル積のマイクロベンチマークでは、サーバーCPUで最大1.28倍のゲインが報告されています。ただし速度向上の幅はプラットフォームの律速要因に依存し、メモリ帯域に律速される環境ほど効果が大きくなる点には注意が必要です。

どんな環境では効果がない、あるいは遅くなりますか?

メモリ帯域が豊富でコア数が少ないクライアントCPU、たとえば8コアで毎秒約108GBを共有する構成では、展開命令のコストが相対的に大きくなって命令律速に転じ、展開の安い2ビット形式のほうが速くなります。実際にCore Ultra 7 258Vでは、BITCOSはすべてのゼロ密度で2ビット版に敗れています。導入前に対象ハードウェアがメモリ律速か命令律速かを見極めることが、採用判断の分かれ目になります。

特別なハードウェアは必要ですか?

不要です。BITCOSはAVX-512、AVX2(AVX-VNNI-INT8)、Intel Xe2 GPUといった標準的な命令セットだけで実装され、汎用のCPUおよびGPU上で動作します。専用のスパース演算ユニットや特殊アクセラレータを前提としていないため、既存の推論基盤に組み込みやすい設計です。実際にvLLMのCPUバックエンドとXPUバックエンドへ統合した状態で性能評価が行われています。

まとめ

三値LLMの重みは {−1, 0, +1} の3値しか取らないため、その保存コストは長らく log₂3 ≈ 1.585 ビット/重みという情報理論上の下限を基準に語られてきました。しかし実際に配備されている5値パッキング(1バイトに5つの三値を詰める方式)は、2の冪のブロックサイズを使う実務上の制約から実効1.625ビット/重みに切り上がっており、この数字は「3つの記号が等確率で出現する」という暗黙の仮定に依存しています。29個の三値モデルを実測すると、ゼロは全重みの29.7%〜51.5%を占めており、−1と+1はゼロほど多くありません。つまり前提そのものが現実とずれていたのです。

BITCOSはこの偏りを保存形式に反映させました。非ゼロかどうかを示すプレゼンス・ビットマップと、非ゼロの重みにだけ符号を与える圧縮サイン・ベクトルの2本立てにすることで、ゼロ密度 z に対して 2 − z ビット/重み を実現します。ゼロはビットマップの1ビットだけを消費し、符号ビットを持ちません。その結果、29モデル中26モデルが5値パッキングより小さくなり、最小では1.485ビット/重みまで下がります。2ビット固定形式に対してはすべてのモデルで有利であり、重みトラフィックは1.16〜1.32倍削減されます。

項目 値
保存コスト 2 − z ビット/重み
5値パッキングとの損益分岐 z > 0.375
5値パッキングより有利なモデル 29中26
2ビット形式より有利なモデル 29中29(1.16〜1.32倍削減)
最小ビット幅 1.485ビット/重み(ゼロ密度51.48%)

導入しやすさもこの方式の特徴です。既存チェックポイントに含まれるゼロをそのまま使うため再学習は不要で、元のモデルとビット単位で同一の三値値に戻ります。専用ハードウェアも要らず、標準的なCPU命令とGPU命令だけで展開カーネルを構成できます。実測ではエンドツーエンドのデコードがサーバーCPUで最大1.18倍、ディスクリートGPUで最大1.27倍高速化しました。

flowchart LR
  A["三値重み<br/>ゼロが最大51.5%"] --> B["BITCOSで保存<br/>2−z ビット/重み"]
  B --> C["展開カーネル<br/>CPU / GPU"]
  C --> D{"律速要因は?"}
  D -->|"メモリ律速"| E["ペイロード削減が<br/>そのまま高速化"]
  D -->|"命令律速"| F["展開コストが支配し<br/>効果なし"]

ただし効果はプラットフォーム次第です。メモリ帯域が乏しくコアあたりの展開余力がある環境では、小さくなったペイロードがそのまま時間短縮に変換されます。一方、帯域が豊富でコア数の少ないクライアントCPUでは展開命令がボトルネックとなり、展開の安い2ビット形式に軍配が上がります。採用を検討する際は、まず自分の環境がメモリ律速か命令律速かを見極めることが出発点になります。データ形式とカーネル実装を一体で設計するというこの考え方は、他のアーキテクチャへも広がりうる余地を残しています。

参考資料

関連記事