ArcFace埋め込みを16ビットに量子化してpgvectorで保存するのはHALFVEC?[D]

Reddit r/MachineLearning / 2026/4/12

💬 オピニオンDeveloper Stack & InfrastructureIdeas & Deep AnalysisTools & Practical Usage

要点

  • 本投稿では、pgvectorに512次元の顔埋め込みを32ビット浮動小数として格納すると、PostgreSQLのTOASTのインライン閾値を超える可能性があり、その結果アウト・オブ・ライン格納によって追加のI/Oが発生しうると論じています。
  • HALFVEC(16ビット量子化)を使うことで保存容量を半分にでき、TOASTではなくインラインに埋め込みを保持することで読み取り効率が改善する可能性があると提案しています。
  • 著者は、ArcFaceの埋め込みに32ビット精度が本当に必要なのか疑問を投げかけています。埋め込み空間では学習時の損失によってアイデンティティがしばしば大きく分離される点を指摘しています。
  • 本投稿は、16ビット量子化は顔の類似度品質に与える影響が小さい可能性がある一方で、影響があるとしても非常に小さな小数点レベルの違いにとどまるかもしれない、という含意を示しつつ、その前提が正しいかどうかを問いかけています。
  • 最後に、ArcFaceに対する16ビットpgvector量子化が標準的な実践なのか、それとも精度や距離(メトリック)への影響といった重要な見落としがないかを、確認するよう求めています。

32ビット浮動小数点としての512次元フェイス埋め込みは2048バイトで、さらに4〜8バイトのヘッダが加わるため、PostgreSQLのTOASTしきい値(2040バイト)をほんの少しだけ超えます。そのためデフォルトでは、postgresqlはそれらを行内に保持せず常にTOASTテーブルにダンプします(結果:データポインタを引き当てて別の読み取りを行う必要があるため、I/Oが倍になる)。

もちろんHNSWならこの問題は完全に回避できますが、ArcFace埋め込みに対して32ビット精度がそもそも意味を持つのか気になっています。これらのモデルが学習に用いる損失関数は、同一人物の顔と別人物の顔を空間上でかなり大きく離すように働く傾向があります。ですので、これらを16ビットに量子化しても大丈夫でしょう。私の数学が正しければですが、現実世界の状況では差は出ないはずです(それを正規化した0.0〜100.0の「顔の類似度」に翻訳すると、議論しているのは小数第3位あたりの差で、つまり0.001くらいです)。

HALFVECなら、ストレージが1/2になり、さらにI/Oオペレーションも1/2になります。なぜならTOASTに溢れ出さずにインラインで格納され、同じページ読み取りで回収されるからです。

この理解は合っていますか? ArcFace埋め込みを量子化するのに、かなり一般的なやり方なのでしょうか、それとも何か見落としている点がありますか?

投稿者 /u/dangerousdotnet
[link] [comments]