FaissをCentOS7にインストール

###概要：
　Anacondaを導入していない CentOS7 環境に、faissをインストールする方法のメモ。
　Anacondaなら CentOS7 にも問題なくインストールできるかは、私は分かってはいないが… pipではスムーズにインストールできなかったので、インストール可能な手順を記録。

###背景：
　CentOS7環境になぜかインストールできない！
　世界的に見ると、同様の問題にぶち当たっている人は何名かはいるようなのですが、明確に＂コレだぜ！＂といった解決策を見出している情報もなく… 半日以上を費やしてしまった。
　複数の CentOS7 環境で、同様にインストールができないことは確認しているので、CentOS7固有の問題かと思われ、手順を確立しておきたかった。

***
##最初は順調でした…

FaissというFacebook社が公開している、類似性検索（およびクラスタリング）のための高速アルゴリズムを実装したライブラリです。
今、SentenceBERTでベクトル化した値から、SemanticSearchする仕組みを構築しようとしているのですが…
当初は単純に検索したいベクトルと、全検索対象のベクトルのCos類似度を算出・Sortして一番類似性の高いベクトルを取得するような実装でした。
しかしこのSemanticSearchの検索対象が大量になった場合に、算出コストがヤバいことになりそうな気配を感じていました。

ちょっと調べると、この問題に対し、ベクトルをIndex化して（？）低コスト（短時間で）で算出することができる「Faiss」というライブラリが見つかりました。
早速、Google Colab上で試してみました！

```
!pip3 install faiss-cpu
import numpy as np
import faiss

d = max([len(v) for v in sentence_vectors])
index = faiss.IndexFlatL2(d)
index.add(np.array(sentence_vectors).astype('float32'))
closest_n = 1
D, I = index.search(np.array(query_embeddings).astype('float32'), closest_n)
```

###楽勝〜！！

まだ検索対象のベクトルが少数（100以下）のテストなので、劇的な変化は感じませんが…
実際に検索時間は短縮し、類似性検索もCos類似度での抽出結果とも差はないので、実際の仕組みに組み込んでみようと取り組み始めました。

***
##さて… 本題のCentOS7のサーバーにインストールしましょう！！ 当然楽勝でしょう？！

Colabと同様に pip でインストール。
Faiss は Anaconda でのインストールが主流のようですが、私は Anaconda は使っていないので pip です。
pip の場合は faiss-cpu ／ faiss-gpu というモジュール名を指定するようですよね… cpu・gpuを切り替える場合は、uninstallして再度どちらかでインストールし直すみたいです。

https://pypi.org/project/faiss-cpu/
https://pypi.org/project/faiss-gpu/


###しか〜し！ エラーが出てる！  なぜ？！
```
$ sudo pip3 install faiss-cpu
Collecting faiss-cpu
  Downloading https://files.pythonhosted.org/packages/8b/3e/d64ff22504a70fb15457de8fb2f5fd84e35448fdcd9958880ae8d0438a82/faiss-cpu-1.6.4.post2.tar.gz
Building wheels for collected packages: faiss-cpu
  Running setup.py bdist_wheel for faiss-cpu ... error
  Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-i9sic395/faiss-cpu/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/tmp2c2gltlxpip-wheel- --python-tag cp36:
  running bdist_wheel
  running build
  running build_py
  running build_ext
  building 'faiss._swigfaiss' extension
  swigging faiss/faiss/python/swigfaiss.i to faiss/faiss/python/swigfaiss_wrap.cpp
  swig -python -c++ -Doverride= -I/usr/local/include -Ifaiss -DSWIGWORDSIZE64 -o faiss/faiss/python/swigfaiss_wrap.cpp faiss/faiss/python/swigfaiss.i
  unable to execute 'swig': No such file or directory
  error: command 'swig' failed with exit status 1
  
  ----------------------------------------
  Failed building wheel for faiss-cpu
  Running setup.py clean for faiss-cpu
Failed to build faiss-cpu
Installing collected packages: faiss-cpu
  Running setup.py install for faiss-cpu ... error
    Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-i9sic395/faiss-cpu/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-q0l4dufw-record/install-record.txt --single-version-externally-managed --compile:
    running install
    running build
    running build_py
    running build_ext
    building 'faiss._swigfaiss' extension
    swigging faiss/faiss/python/swigfaiss.i to faiss/faiss/python/swigfaiss_wrap.cpp
    swig -python -c++ -Doverride= -I/usr/local/include -Ifaiss -DSWIGWORDSIZE64 -o faiss/faiss/python/swigfaiss_wrap.cpp faiss/faiss/python/swigfaiss.i
    unable to execute 'swig': No such file or directory
    error: command 'swig' failed with exit status 1
    
    ----------------------------------------
Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-i9sic395/faiss-cpu/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-q0l4dufw-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-i9sic395/faiss-cpu/
```

ちなみに、ローカルの Mac で試してみました。Colabだけでうまく行く方法だったのかも？！
いえいえ、ローカルのMacでも何の問題もなく faiss-cpu でインストールが完了します…  これはヤバイ匂いがする！


###迷宮に迷い込みました…
いろいろWeb上で調べてみたのですが、決定打となる対策は見当たりません…
その中でも、faiss-centos という私の現在の悩み事のタネのワードが組み合わされた代物が見つかりました。
これはイケるでしょ！！

https://pypi.org/project/faiss-centos/

ここは気合で！ ほれ！！

```
$ sudo pip3 install faiss-centos
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
Collecting faiss-centos
  Could not find a version that satisfies the requirement faiss-centos (from versions: )
No matching distribution found for faiss-centos
```

##が〜ん…

さらにいろいろWebを彷徨うものの、以下のように解決したんだかどうだか… いまいちわからん。 
https://github.com/facebookresearch/faiss/issues/866

###その後も、いろいろやりました！
その中でも、faiss-centos は wheel ではなくて egg なので、pip のバージョンを8に落として試すとか…
egg ファイルを unzip で伸張してみるとか…
openblas-serial や gmp-devel をインストールしてみるとか…

しかしこちらの苦悩などお構いなしに、_swigfaiss が見つからんとか、何かが足りん！だとか無理難題を言ってきます。 疲れたぁ…

ちょっと一休み…  というか別のことをして気を紛らわせたり、お茶を飲んだり、ボーっとしたり…

***
##あれ〜！？

さて、一休みもしたし、脳みその疲れも取れたし、もうすっかり夜になってるし！
再度 CentOS7 のサーバーにログインして…

```
$ python3
Python 3.6.8 (default, Apr  2 2020, 13:34:55) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import faiss
>>> 
```
###エラーが出てない！！
休憩前は、エラーだったのに…　とうとう私の元にも7人のコビトさん達がやってきてくれたのかぁ？？

だって…  pipでインストールされた形跡もない！？  どゆこと？？

```
$ pip3 freeze | grep faiss
$ 
```

なので目的のフォルダーに移動し、もう一度…  エラーだ。
またルートに戻って、もう一度…　　イケる！　　何の違い？？

なにやら、「 https://pypi.org/project/faiss-centos/ 」からダウンロードした、faiss_centos-1.5.2-py3.6.egg をunzip した、faiss/ フォルダを直下にして、import するとOKのようなのです。
一筋の光が… 

だとしたら…  この faiss/ フォルダを、site-packages/ にコピーしたら？？？


***
##結論
その後、追加でインストールが必要なライブラリなどを特定し、CentOS7でも faiss をインストールできる手順を特定しました。

分かってしまえば、コレだけでしたぁ… 

```
$ wget https://files.pythonhosted.org/packages/f6/8b/ab69a201ea1b8be759ba16f172f92d1fb935a8f4a94f02fe52c7d8ec579f/faiss_centos-1.5.2-py3.6.egg
$ unzip faiss_centos-1.5.2-py3.6.egg
$ sudo cp -r ./faiss /usr/local/lib/python3.6/site-packages
 （もしくは…  $ sudo cp -r ./faiss /usr/lib/python3.6/site-packages　環境に合わせて…）

$ sudo yum install openblas-serial
$ sudo yum install gmp gmp-devel

$ python3
Python 3.6.8 (default, Apr 2 2020, 13:34:55) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import faiss
>>>
```


もし、同じような問題にぶち当たっている人がいたら、参考にしてもらえると嬉しいですね。