О СПТАГ
SPTAG — это библиотека приближенного поиска ближайшего соседа, разработанная Microsoft, которую можно использовать для индексации плотного вектора.
Наиболее распространенным является применение поиска изображений, конечно, текстовый поиск также может использоваться для семантического сопоставления.
Установка среды Docker
Поскольку SPTAG в настоящее время не поддерживает версию для Mac, ее можно установить в Docker. Я попробовал официальный dockerfile, чтобы написать немного проблемы, но я не запускал его. Поэтому я планирую создать установку образа докера напрямую.
docker run -it ubuntu:18.04 "/bin/bash"
После входа в докер запустите:
apt update
apt -y install wget build-essential openjdk-8-jdk python3-pip swig
apt -y install software-properties-common git
Установить буст 1.67
add-apt-repository ppa:mhier/libboost-latest
apt update
apt install libboost1.67 libboost1.67-dev
Установите cmake3.15.5
wget https://cmake.org/files/v3.15/cmake-3.15.5.tar.gz
tar zvxf cmake-3.15.5.tar.gz
cd cmake-3.15.5
./bootstrap
make -j2 && make install
Компилировать СПТАГ
git clone https://github.com/microsoft/SPTAG.git
cd SPTAG && mkdir build && cd build
cmake ..
make -j2
Даже если обстановка здесь хорошая. Поместите скомпилированный результат в /app
mkdir /app
mv Release /app
Установите библиотеку python для тестирования
pip3 install numpy rpyc
Сохранение образов Docker
Здесь устанавливается базовая среда, и здесь среда сохраняется.
Сначала проверьте идентификатор контейнера.
docker ps
Я здесь:46b0c72411dc
docker commit -m "create SPTAG env" 46b0c72411dc nladuo/sptag-rpc-server:latest
Взгляните на текущее зеркало еще раз.
написать службу rpc
Поскольку SPTAG не поддерживает Mac, для доступа к нему на Mac здесь можно написать простую демонстрационную службу Rpc, а интерфейс можно немного инкапсулировать.
Этот код находится в:GitHub.com/yourado/sp та…
SPTAG_rpc_demo_server.pyНужно положить его в докер,SPTAG_rpc_demo_client.pyВы можете напрямую импортировать его в свой собственный пакет.
Здесь мы сначала останавливаем предыдущее зеркало, снова открываем контейнер с отображением портов (я использовал порты 8888).
docker run -p 8888:8888 -t -i nladuo/sptag-rpc-server:latest "/bin/bash"
Здесь сначала копируется SPTAG_RPC_DEMO_SERVER.PY в новый контейнер Docker (обратите внимание на изменения в идентификаторе контейнера).
docker cp SPTAG_rpc_demo_server.py 25042d741f07:/app/Release/
Затем запустите его через python:
На этом служба rpc SPTAG завершена, мы можем нажать Ctrl+p, а затем нажать Ctrl+q, чтобы запустить службу в фоновом режиме.
Протестируйте демонстрационный API
добавить проверку индекса
import numpy as np
from SPTAG_rpc_demo_client import SPTAG_RpcDemoClient, DataBean
client = SPTAG_RpcDemoClient("127.0.0.1", "8888")
beans = []
for i in range(5):
vec = i * np.ones((10,), dtype=np.float32)
beans.append(DataBean(_id=f"s{i}", vec=vec))
index_name = "test"
print("Adding Data:", client.add_data(index_name, beans))
Здесь добавлено 5 векторов, 10 0, 10 1, ..., 10 4.
поисковый тест
print("Test Search")
q = DataBean(_id=f"s{0}", vec=0 * np.ones((10,), dtype=np.float32))
print(client.search(index_name, [q], 3))
Затем тестируем поиск, ищем вектор из 10 0s, вы можете видеть, что расстояние возвращенных 10 0s (самих себя) равно 0, а расстояние 10 1s равно=10, расстояние 10 2 с равно=40. нет проблем
удалить тест данных
print("*"*100)
print("Test Delete:", client.delete_data(index_name, [q]))
print("*"*100)
print("Test Search After Deletion")
print(client.search(index_name, [q], 3))
После удаления его уже нет. Третьим ближайшим стало 10 3s,=90
удалить тест индекса
print("*"*100)
print("Test Delete Index:", client.delete_index(index_name))
Наконец, удалите индекс.Вы можете видеть, что возвращаемый результат равен True, и удаление прошло успешно.
Интерфейсы в реальных сценариях
В реальных сценариях
- 1. Файл индекса может быть очень большим, мы не добавляем данные пакетами и не используем передачу данных с большими сетевыми издержками.
- 2. Индекс не будет повторно импортироваться каждый раз при поиске, и тогда поиск будет вызываться снова.
Основываясь на двух вышеупомянутых дефектах, я подумал о следующих решениях:
- 1. Для решения большой проблемы с индексированием используйте инструмент построения индексов, предоставленный SPTAG, для непосредственного построения индекса.
- 2. Для решения проблемы поиска непосредственно напишите специальный интерфейс службы поиска и импортируйте индекс, когда он только запущен. (Индекс может периодически обновляться, если это необходимо, вместо того, чтобы перезагружаться каждый раз)
Индексирование с помощью indexbuilder
Здесь сначала экспортируйте пакет тестовых данных вtest_index_input.txt
середина
import numpy as np
with open("test_index_input.txt", "w") as f:
for i in range(5):
_id = f"s{i}"
vec = i * np.ones((10,), dtype=np.float32)
vec_str = "|".join([str(i) for i in vec.tolist()])
f.write(f"{_id}\t{vec_str}\n")
Затем поместите test_index_input.txt в докер
затем войдите в/app/Release
индексация каталогов
cd /app/Release
./indexbuilder -d 10 -v Float -i ./test_index_input.txt -o data/test_index -a BKT -t 2 Index.DistCalcMethod=L2
Сервис тестового поиска
Затем аналогично демонстрационному API выше, здесь я написал поисковый API. Еще в этом проекте:GitHub.com/yourado/sp та…
SPTAG_rpc_search_server.pyНужно положить его в докер,SPTAG_rpc_search_client.pyВы можете напрямую импортировать его в свой собственный пакет.
Поместите сюда SPTAG_rpc_search_server.py/app/Release
После каталога запустите.
python3 SPTAG_rpc_search_server.py -i test_index
Затем снова протестируйте поисковый клиент.
Как и прежде, без проблем.На этом монтаж и испытания ЗИП завершены.