【ちょくせきりょうしか】

直積量子化(PQ) とは?

最終更新:
💡 長いベクトルを、部分ごとの「代表番号」に置き換える圧縮術

ベクトルを複数の部分ベクトルに分け、各部分を代表点の番号で置き換えて小さく圧縮する手法。ベクトル検索でメモリを大きく減らしつつ、距離を高速に近似できる。

📌 このページのポイント
部分ごとに代表点の番号へ 128次元を、32次元ずつ4つに分ける例 部分1 代表点 256個 から選ぶ ID 17 部分2 代表点 256個 から選ぶ ID 203 部分3 代表点 256個 から選ぶ ID 5 部分4 代表点 256個 から選ぶ ID 88 float32:512バイト → 符号:4バイト 各番号は8ビット(1バイト) 共有コードブック・索引の容量は別
4つの部分に対応したコードブックから最寄りの代表点を選ぶ例。番号で近似する非可逆圧縮で、4バイトはベクトル1本の符号長。
ひよこ ひよこ
直積量子化(PQ)って何? 学習済みモデルの量子化と同じものなの?
ペンギン先生 ペンギン先生
どちらも少ない表現で近似する量子化の仲間だよ。モデルの量子化では重みなどを少ないビットで表すことが多く、この記事のPQは検索対象のベクトルを部分ごとの代表番号で圧縮する方法なんだ。PQがモデル圧縮に応用されることもあるので、完全に無関係な技術という意味ではないよ。
ひよこ ひよこ
どうやってベクトルを小さくするの?
ペンギン先生 ペンギン先生
まずベクトルをm個の部分ベクトルに分けるよ。たとえば128次元を、32次元ずつ4個に分けるイメージだね。それぞれの部分でk-meansを使って代表点の一覧(コードブック)を作って、各部分ベクトルは「いちばん近い代表点の番号」だけで表すんだ。
ひよこ ひよこ
番号だけで済むなら、すごく小さくなりそうだね!
ペンギン先生 ペンギン先生
そうなんだ。代表点が256個なら、1つの部分は1バイトで表せるよ。128次元のfloat32は512バイトだけど、4個の部分に分ければ4バイトになるんだ。しかも、部分ごとに256通りを選べるから、全体では256の4乗通りの代表点を表せるよ。これが「直積」の名前の由来なんだね。 これはベクトル1本の符号長で、全体で共有するコードブックや索引などの容量は別に必要だよ。
ひよこ ひよこ
圧縮したままで、距離の計算はできるの?
ペンギン先生 ペンギン先生
できるよ。L2距離を使う例なら、クエリの各部分と対応するコードブックの代表点との二乗距離を表にするんだ。データの番号で表を引いて足すと、クエリと復元した近似ベクトルとの二乗距離になる。距離そのものを足すわけではないよ。クエリは元のままでデータ側だけ圧縮するので、ADC(非対称距離計算)と呼ばれるんだ。
ひよこ ひよこ
弱点はないの?
ペンギン先生 ペンギン先生
代表点で置き換えるぶん、元のベクトルには戻らない非可逆圧縮だよ。精度の落ち方はデータや分割数・代表点数によって違うから、再現率などを実測して選ぶんだ。PQで候補を絞ってから元のベクトルで並べ直したり、IVFのような索引と組み合わせたりするよ。Jégouらの論文で検索への利用が説明され、Faissのような大規模なベクトル検索ライブラリでも使われているんだ。
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「直積量子化」って出てきたら「ベクトルを部分ごとに代表番号へ置き換えて小さくする、ベクトル検索用の圧縮」と思えばだいたいOK!
📖 おまけ:英語の意味
「Product Quantization」 = 直積量子化
💬 各部分空間のコードブックを組み合わせた直積(デカルト積)で、全体の代表点を表すから、この名前だよ

参考資料

← 用語集にもどる