Легко вычисляйте встраивания клипов и создавайте с их помощью систему clip retrieval . 100 миллионов вложений текста и изображений могут быть обработаны за 20 часов с использованием 3080.
В комплексе это позволяет построить простую систему семантического поиска. Хотите узнать о семантическом поиске в целом? Вы можете прочитать мой средний пост на эту тему.
Также см. laion5B и семантический поиск в масштабе миллиардов, чтобы узнать больше о том, как масштабировать этот масштаб до миллиардов выборок.
Если вы верите в создание многоразовых инструментов, упрощающих использование данных для машинного обучения, и хотите внести свой вклад, присоединяйтесь к чату DataToML.
pip install клип-извлечение
Если вас интересует запуск индекса laion5B, см. этот документ.
ClipClient
позволяет удаленно запрашивать серверную часть поиска клипов через Python.
Пример блокнота Jupyter см. в разделе ClipClient
— Блокнот для начала работы.
Во время инициализации вы можете указать несколько параметров:
backend_url
: URL-адрес бэкэнда. (необходимый)indice_name
: укажите имя индекса, который вы хотите использовать. (необходимый)aesthetic_score
: эстетическая оценка по рейтингу эстетики-предсказателя. По умолчанию — 9
.use_mclip
: использовать ли многоязычную версию CLIP. По умолчанию — False
.aesthetic_weight
: вес эстетической оценки. По умолчанию – 0.5
modality
: поиск по изображению или тексту в индексе, один из Multimodal.IMAGE
или Multimodal.TEXT
. По умолчанию используется Multimodal.IMAGE
.num_images
: количество изображений, возвращаемых API. По умолчанию — 40
.deduplicate
: следует ли дедуплицировать результат путем встраивания изображения. По умолчанию верно.use_safety_model
: удалять ли небезопасные изображения. По умолчанию верно.use_violence_detector
: удалять ли изображения с насилием. По умолчанию верно.Например, чтобы запросить размещенный бэкэнд для Laion5B с параметрами по умолчанию:
from clip_retrieval . clip_client import ClipClient , Modality
client = ClipClient ( url = "https://knn.laion.ai/knn-service" , indice_name = "laion5B-L-14" )
Вы можете найти изображения с подписями, похожие на предоставленный вами текст.
results = client . query ( text = "an image of a cat" )
results [ 0 ]
> { 'url' : 'https://example.com/kitten.jpg' , 'caption' : 'an image of a kitten' , 'id' : 14 , 'similarity' : 0.2367108941078186 }
Вы также можете найти изображения с подписями, похожие на предоставленное вами изображение. Изображения можно передавать по локальному пути или URL-адресу.
cat_results = client . query ( image = "cat.jpg" )
dog_results = client . query ( image = "https://example.com/dog.jpg" )
Вы также можете найти изображения с подписями, похожие на предоставленный вами клип.
cat_results = client . query ( embedding_input = cat_embedding )
Чтобы дополнить существующий набор данных похожими парами текст/изображение, вы можете запросить каталог изображений и объединить результаты.
all_results = [ result for result in [ client . query ( image = image ) for image in os . listdir ( "my-images" )]]
with open ( "search-results.json" , "w" ) as f :
json . dump ( all_results , f )
Вы можете создать набор данных, используя сохраненные результаты json и инструмент img2dataset
.
img2dataset " search-results.json "
--input_format= " json "
--output_folder= " knn_search_dataset "
--caption_col= " caption "
Сначала выберите набор данных URL-адресов изображений и подписей (примеры), затем запустите:
Возможно, вы захотите запустить export CUDA_VISIBLE_DEVICES=
чтобы не использовать графический процессор, если у него недостаточно видеопамяти.
wget https://github.com/rom1504/img2dataset/raw/main/tests/test_files/test_1000.parquet
clip-retrieval end2end test_1000.parquet /tmp/my_output
Затем перейдите по адресу http://localhost:1234 и наслаждайтесь поиском среди своих фотографий.
Используйте --run_back False
если вы не хотите запускать серверную часть
Получите несколько изображений в папке example_folder
, например, выполнив:
pip install img2dataset
echo 'https://placekitten.com/200/305' >> myimglist.txt
echo 'https://placekitten.com/200/304' >> myimglist.txt
echo 'https://placekitten.com/200/303' >> myimglist.txt
img2dataset --url_list=myimglist.txt --output_folder=image_folder --thread_count=64 --image_size=256
Вы также можете поместить в эту папку текстовые файлы с теми же именами, что и изображения, чтобы получить встраивание текста.
Затем запустите clip-retrieval inference --input_dataset image_folder --output_folder embeddings_folder
Выходная папка будет содержать:
Это масштабируется до миллионов образцов. При скорости 1400 выборок в секунду из 3080 10 миллионов выборок могут быть обработаны за 2 часа.
clip_inference превращает набор текста+изображения во встраивания клипов
"open_clip:ViT-B-32/laion2b_s34b_b79k"
, чтобы использовать open_clip, или "hf_clip:patrickjohncyh/fashion-clip"
, чтобы использовать модель обнимающего лица. DeepSparse — это среда выполнения для быстрого вывода разреженных моделей на процессорах. В рамках извлечения клипов доступен бэкэнд, установив его с помощью pip install deepsparse-nightly[clip]
и указав clip_model
с добавленным "nm:"
, например "nm:neuralmagic/CLIP-ViT-B-32-256x256-DataComp-s34B-b86K-quant-ds"
». "nm:neuralmagic/CLIP-ViT-B-32-256x256-DataComp-s34B-b86K-quant-ds"
или "nm:mgoin/CLIP-ViT-B-32-laion2b_s34b_b79k-ds"
.
Если вы хотите иметь больший контроль над тем, как выполняется вывод, вы можете создавать и вызывать рабочие процессы напрямую, используя clip-retrieval inference.worker
Пример использования:
clip-retrieval inference.worker
--tasks= " [0] "
--input_dataset= " input/folder/{000000..000100}.tar "
--output_folder= " example/path "
--input_format= " webdataset "
--output_partition_count= " 1 "
Это приведет к вызову одного работника, которому можно поручить сосредоточиться на определенном подмножестве input_dataset
. Этот работник будет последовательно обрабатывать переданные ему tasks
. Здесь tasks
— это списки partition_id
, за которые будет отвечать этот работник.
Чтобы вручную вычислить количество задач, используйте следующую формулу: number_samples / wds_number_file_per_input_file
.
API очень похож на clip-retrieval inference
с некоторыми небольшими изменениями:
partition_id
, за вычисление которого отвечает этот исполнитель. ( необходимый )"open_clip:ViT-B-32-quickgelu"
, чтобы использовать open_clip, или "hf_clip:patrickjohncyh/fashion-clip"
чтобы использовать модель обнимающего лица.Примечание . Рабочий не принимает следующие аргументы.
- write_batch_size Размер пакета записи (по умолчанию 10**6 )
- Distribution_strategy выбирает, как распределить задание, подробности см. в разделе «Распределение» ( последовательное по умолчанию).
- wds_number_file_per_input_file оценка количества выборок на каждый tar, если используется wds и не указан выходной_partition_count (по умолчанию 10000 )
- любой из аргументов SLURM
Пример запроса hdfs с использованием формата набора веб-данных: `clip_inference --input_dataset "pipe:hdfs dfs -cat /myfolder/webdataset/{00000..00010}.tar" --output_folder "hdfs://myfolder/embeddings" --input_format webdataset
`clip_inference --input_dataset "pipe:aws s3 cp --quiet s3://myfolder/webdataset/{00000..00010}.tar -" --output_folder "s3://myfolder/embeddings" --input_format webdataset
Чтобы запустить это на нескольких узлах (и нескольких графических процессорах), см. Учебное пособие по адресу docs/distributed_clip_inference.md.
Индекс клипа принимает в качестве входных данных результат вывода клипа и создает из него индекс с помощью autofaiss.
clip-retrieval index --embeddings_folder embeddings_folder --index_folder index_folder
--max_index_memory_usage "16G"
позволяет настроить объем оперативной памяти, который будет потреблять индекс. Чем больше оперативной памяти, тем лучше память (по умолчанию 4G
).--current_memory_available 24G
позволяет контролировать, сколько оперативной памяти используется в процессе создания (по умолчанию 16G
).--image_subfolder "img_emb"
позволяет указать подпапку для встраивания изображений, которая объединяется с опцией --embeddings_folder
(по умолчанию img_emb
).--text_subfolder "text_emb"
позволяет указать подпапку для встраивания текста, которая объединяется с опцией --embeddings_folder
( text_emb
по умолчанию).--copy_metadata True
позволяет выбрать, копировать метаданные или нет в конце процесса (по умолчанию True
).--nb_cores 8
позволяет контролировать количество потоков (по умолчанию None
, при этом будут использоваться все ядра).Результатом является папка, содержащая:
Благодаря autofaiss и faiss это масштабируется до сотен миллионов образцов за несколько часов.
Возможно, вы захотите тщательно выбрать, какой объем памяти использовать для вашего индекса, чтобы максимизировать загрузку knn. Colab по выбору индекса autofaiss вместе с командой autofaiss score_index
может помочь проверить отзыв вашего индекса. В целом индексы, использующие больше памяти, лучше запоминаются и, следовательно, ближе к наивному (медленному) KNN.
После того, как вложения вычислены, вы можете отфильтровать данные по конкретному запросу. Для этого вы можете запустить clip-retrieval filter --query "cat" --output_folder "cat/" --indice_folder "indice_folder"
Он скопирует 100 лучших изображений для этого запроса в выходную папку. Использование --num_results
или --threshold
может быть полезно для уточнения фильтра.
Благодаря быстрому индексу KNN это может выполняться в реальном времени (<10 мс) для больших значений K (100 000) и за считанные минуты для очень больших значений K.
Эти сценарии работают для небольших наборов данных. Для более крупных файлов проверьте [notebook/simple_filter.ipynb].
Clip back — это простой бэкэнд службы KNN. При использовании одновременного отображения памяти hdf5 и faiss используется только память, используемая клипом, которая составляет 4 ГБ.
Запустить (output_folder — это результат индекса клипа)
echo ' {"example_index": "output_folder"} ' > indices_paths.json
clip-retrieval back --port 1234 --indices-paths indices_paths.json
Параметры:
--use_jit True
использует jit для модели клипа--clip_model "ViT-B/32"
позволяет выбрать модель клипа. Префикс "open_clip:"
для использования модели open_clip.--enable_mclip_option True
загружает модель mclip, позволяя выполнять поиск на любом языке.--columns_to_return='["url", "image_path", "caption", "NSFW"]
позволяет указать, какие столбцы должны быть получены из метаданных и возвращены серверной частью. Полезно указать меньше в случае кэширования hdf5, чтобы ускорить запросы.--enable_faiss_memory_mapping=True
может быть передана для использования индекса с отображением памяти. Это уменьшает использование памяти до нуля.--enable_hdf5 True
может быть передана для включения кэширования метаданных hdf5. Кэширование HDF5 позволяет использовать метаданные практически без использования памяти.--use_arrow True
позволяет использовать стрелку вместо hdf5. Следует использовать вместе с clip_back_prepro для очень больших наборов данных (миллиарды).--reorder_metadata_by_ivf_index True
использует свойство локальности данных результатов индексов knn ivf: она упорядочивает сбор метаданных в порядке кластеров IVF. Это позволяет гораздо быстрее извлекать метаданные, поскольку операции чтения затем получают доступ к нескольким, в основном последовательным, частям метаданных, а не к множеству непоследовательных частей. На практике это означает возможность получить 1 млн элементов за 1 с, тогда как без этого метода за 1 с можно получить только 1000 элементов. Это упорядочит метаданные, используя первый индекс изображения.--provide_safety_model True
автоматически загрузит и загрузит модель безопасности. Чтобы это работало, вам нужно pip install autokeras
.--provide_violence_detector True
загрузит детектор насилия, бумажный--provide_aesthetic_embeddings True
загрузит эстетические внедрения и позволит пользователям перемещать запрос к более удобной точке пространства клипа.Эти параметры также можно указать в файле конфигурации, чтобы иметь разные параметры для каждого индекса. Пример:
{
"laion5B" : {
"indice_folder" : " /mnt/laion5B/prepared_data " ,
"provide_safety_model" : true ,
"enable_faiss_memory_mapping" : true ,
"use_arrow" : true ,
"enable_hdf5" : false ,
"reorder_metadata_by_ivf_index" : false ,
"columns_to_return" : [ " url " , " caption " ],
"clip_model" : " ViT-L/14 " ,
"enable_mclip_option" : false
},
"laion_400m" : {
"indice_folder" : " /mnt/laion400M/index100 " ,
"provide_safety_model" : true ,
"enable_faiss_memory_mapping" : true ,
"enable_hdf5" : true ,
"use_arrow" : false ,
"reorder_metadata_by_ivf_index" : true ,
"enable_mclip_option" : true ,
"clip_model" : " ViT-B/32 "
}
}
hdf5 или кэширование стрелок рекомендуется использовать, если:
На данный момент у вас есть простой сервер Flask, работающий на порту 1234 и способный отвечать на следующие запросы:
/indices-list
-> вернуть список индексов/knn-service
, который принимает на вход: {
"text" : "a text query" ,
"image" : "a base64 image" ,
"image_url" : "http://some-url.com/a.jpg" ,
"modality" : "image" , // image or text index to use
"num_images" : 4 , // number of output images
"indice_name" : "example_index" ,
"num_result_ids" : 4 // optional, if specified fetch this number of results in total but only num_images with metadata
}
text, image и image_url являются взаимоисключающими и возвращают:
[
{
"image" : "base 64 of an image" ,
"text" : "some result text" ,
"id" : 543
} ,
{
"image" : "base 64 of an image" ,
"text" : "some result text" ,
"id" : 782
}
]
Каждый объект также может содержать поле URL-адреса, если оно предусмотрено метаданными.
Идентификатор — это позиция элемента в индексе. Его можно использовать для запроса метаданных с помощью конечной точки /metadata:
{
"indice_name" : "example_index" ,
"ids" : [ 543 , 782 ]
}
который возвращает:
{
"image" : "base 64 of an image" ,
"text" : "some result text"
// any other key available in the metadata and specified in columns_to_return cli option
}
Аргумент num_result_ids
/knn-service
и /metadata
можно использовать вместе для выполнения больших запросов KNN, а затем получать метаданные только при необходимости. Это имеет смысл, поскольку поиск knn может быть очень эффективным благодаря сильной локальности ссылки индекса knn IVF, что позволяет быстро выполнять knn с большим K, тогда как текущая реализация метаданных на диске (hdf5) не имеет этого свойство и, следовательно, не может быстро получить большое количество случайных элементов. В частности, это можно использовать для реализации бесконечной прокрутки во внешнем интерфейсе.
По умолчанию серверная часть также предоставляет внешний интерфейс. Этот внешний интерфейс по умолчанию будет обращаться к этому серверному интерфейсу, однако вам может потребоваться указать, происходит ли это через http или https. В этом случае используйте опцию --default_backend
, чтобы указать URL-адрес внутреннего интерфейса. --url_column
позволяет указать имя URL-адреса столбца для передней части
Этот сервер имеет задержку 50 мс при использовании индексов и метаданных, отображенных в памяти. Пропускная способность составляет около 20 запросов/с. Для высокой пропускной способности требуется использование сервера grpc, а также графического процессора для быстрого вывода клипов. Отключение параметров сопоставления памяти также может ускорить запросы за счет большого использования оперативной памяти.
Этот бэкэнд также предоставляет конечную точку Prometheus /metrics
, а также удобочитаемую сводку в /metrics-summary
. Это можно (опционально) использовать для настройки панели управления Grafana для мониторинга:
На этой панели видно, что самой медленной частью любого вызова является получение изображения по его URL-адресу в случае поиска URL-адреса изображения, что занимает до 300 мс. Для текстовых запросов или запросов изображений задержка составляет около 50 мс. Вот пример вывода в сводке метрик:
Among 20.0 calls to the knn end point with an average latency of 0.1889s per request, the step costs are (in order):
name description calls average proportion
0 download_time Time spent downloading an url 6 0.3215s 170.2%
1 metadata_get_time Time spent retrieving metadata 20 0.0415s 21.9%
2 knn_index_time Time spent doing a knn on the index 20 0.0267s 14.1%
3 image_clip_inference_time Time spent doing a image clip inference 6 0.0206s 10.9%
4 text_clip_inference_time Time spent doing a text clip inference 14 0.0186s 9.8%
5 image_prepro_time Time spent doing the image preprocessing 6 0.0097s 5.2%
6 text_prepro_time Time spent doing the text preprocessing 14 0.0020s 1.0%
Clip front — это простой пользовательский интерфейс, который подключается к клипу назад и отображает результаты. Вы можете использовать его в пользовательском интерфейсе поиска клипов.
Или вы можете запустить его самостоятельно с помощью:
npm install -g clip-retrieval-front
clip-retrieval-front 3005
Вы также можете запустить его с clip-retrieval front
или сзади из пакета Python.
Для разработки перейдите вперед и запустите npm install
затем npm start
.
Либо локально, либо в gitpod ( export PIP_USER=false
)
Настройте виртуальную среду:
python3 -m venv .env
source .env/bin/activate
pip install -e .
для запуска тестов:
pip install -r requirements-test.txt
затем
make lint
make test
Вы можете использовать make black
для переформатирования кода.
python -m pytest -x -s -v tests -k "test_runner"
для запуска определенного теста
Если вы хотите использовать фронтальную часть через бэкэнд или интерфейс Python, запустите
cd front
npm install
npm run build
cd ..
pip install -e .
@misc{beaumont-2022-clip-retrieval,
author = {Romain Beaumont},
title = { clip retrieval : Easily compute clip embeddings and build a clip retrieval system with them},
year = {2022},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {url{https://github.com/rom1504/clip-retrieval}}
}