NGT(高次元ベクトルデータ検索技術)をGolangでごまかして雑なJSON APIにする
類似画像検索システムに組み込むための高次元ベクトルデータ検索技術を探していました。Yahoo! Japanが開発したNGT(高次元ベクトルデータ検索技術)を見つけたので試してみます。
https://www.flickr.com/photos/21001756@N06/2087512650/
表形式をJSON APIに変換する
前回は、NGTをDockerで動かすところまで紹介しました。 tamanobi.hatenablog.com
公式ドキュメントに従って検索コマンドを実行すると、表形式の出力が得られます。 github.com
$ ngt search -n 20 index ./data/sift-query-3.tsv Query No.1 Rank ID Distance 1 3031 239.332 2 4079 240.002 3 3164 244.504 4 3718 246.763 5 157 251.094 6 2422 251.185 7 1313 251.34 8 379 252.446 9 3521 260.158 10 2594 261.132 11 4627 262.381 12 2159 263.471 13 3519 264.909 14 1764 265.136 15 4400 266.156 16 2717 266.914 17 3168 269.637 18 4236 270.673 19 4700 272.725 20 679 272.973 Query Time= 0.000472 (sec), 0.472 (msec)
検索システムとして利用する上では、この表示形式は使いづらいためJSONで返せるようにパッチを当てます。
JSON出力ができるようにパッチを当てる
NGTはC++で書かれているので、STLをJSONにシリアライズするライブラリを探します。今回はヘッダーを読み込むだけで利用できるライブラリを使用しました。 github.com
ngt search
コマンドにjson出力用のオプションを加えました。本家のmasterとの差分は以下のリンクを参照してください。個人向けの雑な修正なので本家にPRは送らない予定です。
Comparing yahoojapan:master...tamanobi:feature/json_output · yahoojapan/NGT · GitHub
差分を取り込んで、buildすればjsonオプションが有効になります。例えば、 ngt search -o j -n 20 index ./data/sift-query-3.tsv
とoオプションにjを渡せば、JSONが出力できます。
ここまでで検索バックエンドの下準備は終わりました。JSONは出力されるものの、HTTP経由でのアクセスに対応していないので何かしらの言語でウェブサーバーを立ててAPIサーバーにします。
GolangでさくっとAPIサーバー
開発速度を鑑みて、それなりに高速でシンプルにJSON APIサーバーかける言語を採用します。今回はGolangにしました。コードはとてもシンプルです。特定のエンドポイントにファイルがPOSTされたらコマンドを実行するだけです。
https://gist.github.com/tamanobi/d10c932eebbd8c4c5ee0ca6f5143f3e9
tsv形式のファイルをいちいち送らないといけないのが、ナンセンスですが今回はよしとします。
Docker
これまでに、2つの変更を行いました。NGTにパッチを当てたこと、GoでのAPIサーバーの作成です。何も考えずに実行できるようにDockerfileを作りました。
リポジトリにDockerfileが入っているので、 docker build -t tamanobi/ngt_webapp .
としてビルドを行ってください。ビルド後に、docker run -it -p 2300:8000 tamanobi/ngt_webapp
とすればウェブサーバーが立ち上がり、ホストOSの2300番ポートにAPIサーバーに転送されるようになります。
まとめ
NGTをHTTPを介して使うために、2つの準備を行いました。
- NGTにパッチを当てて、JSON出力に対応
- GolangでNGTコマンドを発行するウェブサーバーを立てる
次回
次回は、Golangのサーバーに対してリクエストを送ってNGTのデータベース構築や検索を行ってみます。