클립 임베딩을 쉽게 계산하고 이를 통해 clip retrieval 시스템을 구축할 수 있습니다. 3080을 사용하면 1억 개의 텍스트+이미지 임베딩을 20시간 안에 처리할 수 있습니다.
이를 통해 엔드 투 엔드(End to End)를 통해 간단한 의미 검색 시스템을 구축할 수 있습니다. 일반적인 의미 검색에 대해 배우고 싶으십니까? 주제에 대한 내 중간 게시물을 읽을 수 있습니다.
또한 이 규모를 수십억 개의 샘플로 만드는 방법에 대한 자세한 내용은 laion5B 및 수십억 규모의 의미 검색을 참조하세요.
ML에 데이터를 쉽게 사용할 수 있도록 재사용 가능한 도구를 만들고 기여하고 싶다면 DataToML 채팅에 참여하세요.
pip 설치 클립 검색
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
: 이미지 삽입을 통해 결과를 중복 제거할지 여부입니다. 기본값은 true입니다.use_safety_model
: 안전하지 않은 이미지를 제거할지 여부입니다. 기본값은 true입니다.use_violence_detector
: 폭력적인 이미지를 삭제할지 여부입니다. 기본값은 true입니다.예를 들어, 기본 매개변수를 사용하여 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과 캡션(예)의 데이터세트를 선택한 후 다음을 실행하세요.
VRAM이 충분하지 않은 경우 GPU 사용을 피하기 위해 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
실행합니다.
출력 폴더에는 다음이 포함됩니다.
이는 수백만 개의 샘플로 확장됩니다. 3080의 초당 1400개 샘플에서는 10M 샘플을 2시간 안에 처리할 수 있습니다.
Clip_inference는 텍스트+이미지 세트를 클립 임베딩으로 전환합니다.
"open_clip:ViT-B-32/laion2b_s34b_b79k"
로 지정하고, 포옹 얼굴 클립 모델을 사용하려면 "hf_clip:patrickjohncyh/fashion-clip"
으로 지정합니다. DeepSparse는 CPU에서 빠른 희소 모델 추론을 위한 추론 런타임입니다. pip install deepsparse-nightly[clip]
을 사용하여 설치하고 "nm:" 앞에 "nm:"
을 추가하여 clip_model
지정하여 클립 검색 내에서 사용할 수 있는 백엔드가 있습니다(예: "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
사용하여 워커를 직접 만들고 호출할 수 있습니다.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"
로 지정하고 포옹 얼굴 클립 모델을 사용하려면 "hf_clip:patrickjohncyh/fashion-clip"
으로 지정합니다.참고 : 작업자는 다음 인수를 허용하지 않습니다.
- write_batch_size 쓰기 배치 크기(기본값 10**6 )
- distribution_strategy 작업 배포 방법을 선택합니다. 자세한 내용은 배포 섹션을 참조하세요. (기본값 순차 )
- wds_number_file_per_input_file wds를 사용하고 output_partition_count를 지정하지 않은 경우 tar당 샘플 수 추정(기본값 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
여러 노드(및 여러 GPU)에서 이를 실행하려면 docs/distributed_clip_inference.md의 튜토리얼을 참조하세요.
클립 인덱스는 클립 추론의 출력을 입력으로 사용하고 autofaiss를 사용하여 인덱스를 만듭니다.
clip-retrieval index --embeddings_folder embeddings_folder --index_folder index_folder
--max_index_memory_usage "16G"
옵션을 사용하면 인덱스가 소비할 RAM의 양을 구성할 수 있습니다. RAM이 많을수록 knn 리콜이 향상됩니다(기본값 4G
).--current_memory_available 24G
하면 생성 프로세스 중에 사용되는 RAM의 양을 제어할 수 있습니다(기본값 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 재현율을 최대화하기 위해 인덱스에 사용할 메모리 양을 신중하게 선택할 수 있습니다. autofaiss index Selection colab은 autofaiss score_index
명령과 함께 색인 회수를 확인하는 데 도움이 될 수 있습니다. 일반적으로 더 많은 메모리를 사용하는 인덱스는 더 나은 리콜을 얻으므로 순진한(느린) knn에 더 가깝습니다.
임베딩이 계산되면 특정 쿼리로 데이터를 필터링할 수 있습니다. 이를 위해 clip-retrieval filter --query "cat" --output_folder "cat/" --indice_folder "indice_folder"
실행할 수 있습니다. 그러면 출력 폴더에 이 쿼리에 대한 최상의 이미지 100개가 복사됩니다. --num_results
또는 --threshold
사용하면 필터를 구체화하는 데 도움이 될 수 있습니다.
빠른 knn 인덱스 덕분에 이는 큰 K 값(100000)의 경우 실시간(<10ms)으로 실행되고 매우 큰 K 값의 경우 몇 분 안에 실행될 수 있습니다.
이 스크립트는 소규모 데이터세트에 작동합니다. 더 큰 파일은 [notebook/simple_filter.ipynb]를 확인하세요.
클립백은 간단한 knn 서비스 백엔드입니다. hdf5와 faiss 메모리 매핑을 모두 사용하는 경우 클립에서 사용하는 메모리인 4GB만 사용합니다.
실행(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 캐싱의 경우 less를 지정하는 것이 유용합니다.--enable_faiss_memory_mapping=True
옵션을 전달하면 메모리 매핑과 함께 인덱스를 사용할 수 있습니다. 그러면 메모리 사용량이 0으로 줄어듭니다.--enable_hdf5 True
옵션을 전달하여 메타데이터에 대한 hdf5 캐싱을 활성화할 수 있습니다. HDF5 캐싱을 사용하면 메모리를 거의 사용하지 않고 메타데이터를 사용할 수 있습니다.--use_arrow True
이면 hdf5 대신 화살표를 사용할 수 있습니다. 매우 큰 데이터 세트(수십억)의 경우 Clip_back_prepro와 함께 사용해야 합니다.--reorder_metadata_by_ivf_index True
옵션은 knn ivf 인덱스 결과의 데이터 지역성 속성을 활용합니다. 즉, IVF 클러스터 순서로 메타데이터 컬렉션을 정렬합니다. 그러면 읽기가 많은 비순차적 부분 대신 메타데이터의 대부분 순차 부분에 액세스하므로 훨씬 더 빠른 메타데이터 검색이 가능해집니다. 실제로 이는 1초에 100만 개의 항목을 검색할 수 있는 반면, 이 방법을 사용하지 않으면 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 또는 화살표 캐싱은 다음과 같은 경우에 사용하는 것이 좋습니다.
이제 포트 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 필드가 포함될 수도 있습니다.
id는 인덱스에서 항목의 위치입니다. /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
}
/knn-service
및 /metadata
의 num_result_ids
인수를 함께 사용하여 대규모 knn 쿼리를 수행한 다음 필요할 때만 메타데이터를 가져올 수 있습니다. knn 검색은 knn IVF 인덱스 참조의 강력한 지역성 덕분에 매우 효율적일 수 있으므로 큰 K로 knn을 빠르게 수행할 수 있는 반면 현재의 디스크상 메타데이터 구현(hdf5)에는 그런 기능이 없습니다. 따라서 대량의 임의 항목을 빠르게 검색하는 것을 처리할 수 없습니다. 특히 이는 프런트 엔드에서 무한 스크롤을 구현하는 데 사용될 수 있습니다.
기본적으로 백엔드는 프런트 엔드도 노출합니다. 해당 프런트 엔드는 기본적으로 이 백엔드에 도달하지만 이것이 http 또는 https를 통해 발생하는지 지정해야 할 수도 있습니다. 이 경우 --default_backend
옵션을 사용하여 백엔드 URL을 지정합니다. --url_column
사용하면 전면에 대한 열 URL 이름을 지정할 수 있습니다.
메모리 매핑된 인덱스와 메타데이터를 사용하는 경우 이 백엔드의 지연 시간은 50ms입니다. 처리량은 약 20 쿼리/초입니다. 높은 처리량을 위해서는 grpc 서버를 사용해야 하고 빠른 클립 추론을 위한 GPU도 필요합니다. 메모리 매핑 옵션을 끄면 RAM 사용량이 많아지는 대신 요청 속도가 빨라질 수도 있습니다.
또한 이 백엔드는 prometheus /metrics
엔드포인트와 사람이 읽을 수 있는 /metrics-summary
요약을 노출합니다. 이는 (선택적으로) 모니터링을 위해 grafana 대시보드를 설정하는 데 사용될 수 있습니다.
이 대시보드에서는 이미지 URL 검색의 경우 호출에서 가장 느린 부분이 URL을 통해 이미지를 가져오는 데 최대 300ms가 소요되는 것을 볼 수 있습니다. 텍스트 쿼리 또는 이미지 쿼리의 경우 지연 시간은 약 50ms입니다. 다음은 측정항목 요약의 출력 예입니다.
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)는 클립 백에 연결하여 결과를 표시하는 간단한 UI입니다. 클립 검색 UI에서 사용할 수 있습니다.
또는 다음을 사용하여 직접 실행할 수도 있습니다.
npm install -g clip-retrieval-front
clip-retrieval-front 3005
Python 패키지에서 앞뒤로 clip-retrieval front
사용하여 실행할 수도 있습니다.
개발을 위해 전면으로 이동하여 npm install
실행한 다음 npm start
실행하세요.
로컬로 또는 gitpod에서(여기서 export PIP_USER=false
)
virtualenv를 설정합니다:
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}}
}