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埋め込みを量子化するのに、かなり一般的なやり方なのでしょうか、それとも何か見落としている点がありますか?
[link] [comments]




