Hitung penyematan klip dengan mudah dan buat sistem clip retrieval dengannya. 100 juta teks+gambar yang disematkan dapat diproses dalam 20 jam menggunakan 3080.
Hal ini memungkinkan untuk membangun sistem pencarian semantik yang sederhana. Tertarik mempelajari pencarian semantik secara umum? Anda dapat membaca posting media saya tentang topik ini.
Lihat juga laion5B dan penelusuran semantik dalam skala miliaran untuk membaca selengkapnya tentang cara membuat skala ini menjadi miliaran sampel.
Jika Anda yakin untuk membuat alat yang dapat digunakan kembali agar data mudah digunakan untuk ML dan Anda ingin berkontribusi, silakan bergabung dalam obrolan DataToML.
pip install pengambilan klip
Jika Anda tertarik untuk menjalankan indeks laion5B, lihat dokumen ini
ClipClient
memungkinkan kueri jarak jauh dari backend pengambilan klip melalui python.
Lihat ClipClient
- Memulai Notebook untuk contoh notebook jupyter.
Selama inisialisasi Anda dapat menentukan beberapa parameter:
backend_url
: url backend. (diperlukan)indice_name
: tentukan nama indeks yang ingin Anda gunakan. (diperlukan)aesthetic_score
: skor estetika yang dinilai oleh prediktor estetika. Standarnya adalah 9
.use_mclip
: apakah akan menggunakan CLIP versi multibahasa. Standarnya adalah False
.aesthetic_weight
: bobot skor estetika. Standarnya adalah 0.5
modality
: menelusuri gambar atau teks dalam indeks, salah satu Multimodal.IMAGE
atau Multimodal.TEXT
. Standarnya adalah Multimodal.IMAGE
.num_images
: jumlah gambar yang akan dikembalikan dari API. Standarnya adalah 40
.deduplicate
: Apakah akan menghapus duplikat hasil dengan menyematkan gambar. Standarnya benar.use_safety_model
: Apakah akan menghapus gambar yang tidak aman. Standarnya benar.use_violence_detector
: Apakah akan menghapus gambar yang mengandung kekerasan. Standarnya benar.Misalnya, untuk menanyakan backend yang dihosting untuk Laion5B dengan parameter default:
from clip_retrieval . clip_client import ClipClient , Modality
client = ClipClient ( url = "https://knn.laion.ai/knn-service" , indice_name = "laion5B-L-14" )
Anda dapat menemukan gambar dengan teks yang mirip dengan teks yang Anda berikan.
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 }
Anda juga dapat menemukan gambar dengan teks yang mirip dengan gambar yang Anda berikan. Gambar dapat diteruskan melalui jalur atau url lokal.
cat_results = client . query ( image = "cat.jpg" )
dog_results = client . query ( image = "https://example.com/dog.jpg" )
Anda juga dapat menemukan gambar dengan teks yang mirip dengan penyematan klip yang Anda berikan.
cat_results = client . query ( embedding_input = cat_embedding )
Untuk menyempurnakan kumpulan data yang ada dengan pasangan teks/gambar yang serupa, Anda dapat mengkueri direktori gambar dan menggabungkan hasilnya.
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 )
Anda dapat membuat kumpulan data menggunakan hasil json yang disimpan dan alat img2dataset
.
img2dataset " search-results.json "
--input_format= " json "
--output_folder= " knn_search_dataset "
--caption_col= " caption "
Pertama-tama pilih kumpulan data url gambar dan keterangan (contoh) lalu jalankan:
Anda mungkin ingin menjalankan export CUDA_VISIBLE_DEVICES=
untuk menghindari penggunaan GPU jika VRAM tidak cukup.
wget https://github.com/rom1504/img2dataset/raw/main/tests/test_files/test_1000.parquet
clip-retrieval end2end test_1000.parquet /tmp/my_output
Lalu pergi ke http://localhost:1234 dan nikmati pencarian di antara gambar-gambar Anda
Gunakan --run_back False
jika Anda tidak ingin menjalankan backend
Dapatkan beberapa gambar dalam example_folder
, misalnya dengan melakukan:
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
Anda juga dapat meletakkan file teks dengan nama yang sama dengan gambar di folder tersebut, untuk mendapatkan penyematan teks.
Kemudian jalankan clip-retrieval inference --input_dataset image_folder --output_folder embeddings_folder
Folder keluaran akan berisi:
Skala ini mencapai jutaan sampel. Pada 1400 sampel/dtk dari 3080, 10 juta sampel dapat diproses dalam 2 jam.
clip_inference mengubah kumpulan teks+gambar menjadi penyematan klip
"open_clip:ViT-B-32/laion2b_s34b_b79k"
untuk menggunakan open_clip atau "hf_clip:patrickjohncyh/fashion-clip"
untuk menggunakan model klip wajah berpelukan. DeepSparse adalah runtime inferensi untuk inferensi model sparse yang cepat pada CPU. Ada backend yang tersedia dalam pengambilan klip dengan menginstalnya dengan pip install deepsparse-nightly[clip]
, dan menentukan clip_model
dengan awalan "nm:"
, seperti "nm:neuralmagic/CLIP-ViT-B-32-256x256-DataComp-s34B-b86K-quant-ds"
atau "nm:mgoin/CLIP-ViT-B-32-laion2b_s34b_b79k-ds"
.
Jika Anda ingin memiliki kontrol lebih besar atas cara inferensi dijalankan, Anda dapat membuat dan memanggil pekerja secara langsung menggunakan clip-retrieval inference.worker
Contoh Penggunaan:
clip-retrieval inference.worker
--tasks= " [0] "
--input_dataset= " input/folder/{000000..000100}.tar "
--output_folder= " example/path "
--input_format= " webdataset "
--output_partition_count= " 1 "
Melakukan hal ini akan memanggil satu pekerja yang dapat diinstruksikan untuk fokus pada subset tertentu dari input_dataset
. Pekerja tersebut akan memproses tasks
yang diberikan kepadanya secara berurutan. Di sini, tasks
adalah daftar partition_id
yang akan menjadi tanggung jawab pekerja ini.
Untuk menghitung jumlah tugas secara manual, gunakan rumus berikut: number_samples / wds_number_file_per_input_file
.
API ini sangat mirip dengan clip-retrieval inference
dengan beberapa perubahan kecil:
partition_id
yang menjadi tanggung jawab pekerja ini untuk melakukan komputasi. ( diperlukan )"open_clip:ViT-B-32-quickgelu"
untuk menggunakan open_clip atau "hf_clip:patrickjohncyh/fashion-clip"
untuk menggunakan model klip wajah berpelukan.Catatan : Pekerja tidak menerima argumen berikut
- write_batch_size Tulis ukuran batch (default 10**6 )
- distribution_strategy pilih cara mendistribusikan pekerjaan, lihat bagian distribusi untuk detailnya ( urutan default)
- wds_number_file_per_input_file estimasi jumlah sampel per tar jika menggunakan wds dan tidak menentukan output_partition_count (default 10000 )
- salah satu argumen SLURM
Contoh kueri hdfs menggunakan format webdataset: `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
Untuk menjalankan ini di banyak node (dan banyak GPU), lihat tutorial di docs/distributed_clip_inference.md
Indeks klip mengambil masukan dari keluaran inferensi klip dan membuat indeks darinya menggunakan autofaiss
clip-retrieval index --embeddings_folder embeddings_folder --index_folder index_folder
--max_index_memory_usage "16G"
memungkinkan konfigurasi jumlah ram yang akan dikonsumsi indeks. Lebih banyak ram, recall knn lebih baik (Default 4G
).--current_memory_available 24G
memungkinkan pengontrolan berapa banyak ram yang digunakan selama proses pembuatan (Default 16G
).--image_subfolder "img_emb"
memungkinkan untuk menentukan subfolder untuk penyematan gambar yang digabungkan ke opsi --embeddings_folder
(Default img_emb
).--text_subfolder "text_emb"
memungkinkan untuk menentukan subfolder untuk penyematan teks yang digabungkan ke opsi --embeddings_folder
(Default text_emb
).--copy_metadata True
memungkinkan untuk memilih apakah akan menyalin metadata atau tidak di akhir proses (Default True
).--nb_cores 8
memungkinkan pengontrolan jumlah thread (Default None
, yang akan menggunakan semua core).Outputnya adalah folder yang berisi:
Berkat autofaiss dan faiss, skala ini mencapai ratusan juta sampel dalam beberapa jam.
Anda mungkin ingin hati-hati memilih berapa banyak memori yang akan digunakan untuk indeks Anda untuk memaksimalkan ingatan knn. Kolab pemilihan indeks autofaiss dapat membantu bersama dengan perintah autofaiss score_index
untuk memeriksa penarikan kembali indeks Anda. Secara umum, indeks yang menggunakan lebih banyak memori akan memperoleh daya ingat yang lebih baik sehingga mendekati knn yang naif (lambat).
Setelah penyematan dihitung, Anda mungkin ingin memfilter data berdasarkan kueri tertentu. Untuk itu Anda dapat menjalankan clip-retrieval filter --query "cat" --output_folder "cat/" --indice_folder "indice_folder"
Ini akan menyalin 100 gambar terbaik untuk kueri ini di folder output. Menggunakan --num_results
atau --threshold
mungkin berguna untuk menyempurnakan filter
Berkat indeks knn yang cepat, ini dapat berjalan secara real time (<10ms) untuk nilai K yang besar (100000), dan dalam hitungan menit untuk nilai K yang sangat besar.
Skrip ini berfungsi untuk kumpulan data kecil. Untuk yang lebih besar, silakan periksa [notebook/simple_filter.ipynb].
Clip back adalah backend layanan knn sederhana. Jika menggunakan pemetaan memori hdf5 dan faiss, hanya menggunakan memori yang digunakan oleh klip yaitu 4GB.
Jalankan (output_folder adalah output dari indeks klip)
echo ' {"example_index": "output_folder"} ' > indices_paths.json
clip-retrieval back --port 1234 --indices-paths indices_paths.json
Pilihan:
--use_jit True
menggunakan jit untuk model klip--clip_model "ViT-B/32"
memungkinkan pemilihan model klip yang akan digunakan. Awali dengan "open_clip:"
untuk menggunakan model open_clip.--enable_mclip_option True
memuat model mclip, sehingga memungkinkan pencarian dalam bahasa apa pun.--columns_to_return='["url", "image_path", "caption", "NSFW"]
memungkinkan Anda menentukan kolom mana yang harus diambil dari metadata dan dikembalikan oleh backend. Sangat berguna untuk menentukan less dalam kasus caching hdf5 untuk mempercepat kueri.--enable_faiss_memory_mapping=True
dapat diberikan untuk menggunakan indeks dengan pemetaan memori. Itu mengurangi penggunaan memori menjadi nol.--enable_hdf5 True
dapat diteruskan untuk mengaktifkan caching hdf5 untuk metadata. Caching HDF5 memungkinkan penggunaan metadata hampir tanpa penggunaan memori.--use_arrow True
memungkinkan penggunaan panah alih-alih hdf5. Harus digunakan bersama dengan clip_back_prepro untuk kumpulan data yang sangat besar (miliar)--reorder_metadata_by_ivf_index True
memanfaatkan properti lokalitas data dari hasil indeks knn ivf: opsi ini mengurutkan pengumpulan metadata dalam urutan kluster IVF. Hal ini memungkinkan pengambilan metadata lebih cepat karena pembacaan kemudian mengakses beberapa bagian metadata yang sebagian besar berurutan, bukan banyak bagian yang tidak berurutan. Dalam praktiknya, itu berarti dapat mengambil 1 juta item dalam 1 detik, sedangkan hanya 1000 item yang dapat diambil dalam 1 detik tanpa metode ini. Ini akan mengurutkan metadata menggunakan indeks gambar pertama.--provide_safety_model True
akan secara otomatis mengunduh dan memuat model keamanan. Anda perlu pip install autokeras
ketergantungan opsional agar ini berfungsi.--provide_violence_detector True
akan memuat detektor kekerasan, kertas--provide_aesthetic_embeddings True
akan memuat penyematan estetika dan memungkinkan pengguna membuat kueri berpindah ke titik yang lebih bagus di ruang klipOpsi ini juga dapat disediakan di file konfigurasi agar memiliki opsi berbeda untuk setiap indeks. Contoh:
{
"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 atau cache panah adalah ide bagus untuk digunakan jika:
Pada titik ini Anda memiliki server flask sederhana yang berjalan pada port 1234 dan dapat menjawab pertanyaan berikut:
/indices-list
-> mengembalikan daftar indeks/knn-service
yang diambil sebagai masukan: {
"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
}
teks, gambar, dan image_url saling eksklusif dan menghasilkan:
[
{
"image" : "base 64 of an image" ,
"text" : "some result text" ,
"id" : 543
} ,
{
"image" : "base 64 of an image" ,
"text" : "some result text" ,
"id" : 782
}
]
Setiap objek juga dapat berisi bidang url jika metadata menyediakannya.
Id adalah posisi item dalam indeks. Ini dapat digunakan untuk menanyakan metadata dengan titik akhir /metadata:
{
"indice_name" : "example_index" ,
"ids" : [ 543 , 782 ]
}
yang mengembalikan:
{
"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
}
Argumen num_result_ids
dari /knn-service
dan /metadata
dapat digunakan bersama untuk melakukan kueri knn besar dan kemudian mengambil metadata hanya jika diperlukan. Masuk akal untuk melakukan hal itu karena pencarian knn bisa sangat efisien berkat lokalitas referensi yang kuat dari indeks knn IVF yang membuatnya cepat untuk melakukan knn dengan K yang besar, sedangkan implementasi metadata pada disk saat ini (hdf5) tidak memilikinya. properti dan karenanya tidak dapat menangani pengambilan item acak dalam jumlah besar dengan cepat. Secara khusus ini dapat digunakan untuk mengimplementasikan pengguliran tak terbatas di ujung depan.
Secara default, backend juga akan menampilkan front end. Front end tersebut secara default akan mengenai backend ini, namun Anda mungkin perlu menentukan apakah ini terjadi melalui http atau https, dalam hal ini gunakan opsi --default_backend
untuk menentukan url backend. --url_column
memungkinkan menentukan nama kolom url untuk bagian depan
Backend ini memiliki latensi 50 md jika menggunakan indeks dan metadata yang dipetakan memori. Throughputnya sekitar 20 kueri/dtk. Untuk throughput yang tinggi, diperlukan penggunaan server grpc serta GPU untuk inferensi klip yang cepat, mematikan opsi pemetaan memori juga dapat mempercepat permintaan, dengan mengorbankan penggunaan ram yang tinggi.
Backend ini juga memperlihatkan titik akhir prometheus /metrics
serta ringkasan yang dapat dibaca manusia di /metrics-summary
. Ini (opsional) dapat digunakan untuk menyiapkan dasbor grafana untuk pemantauan:
Dapat dilihat di dasbor ini bahwa bagian paling lambat dari setiap panggilan adalah mengambil gambar berdasarkan urlnya jika terjadi pencarian url gambar, yang memakan waktu hingga 300 md. Untuk kueri teks atau kueri gambar, latensinya sekitar 50 ms. Berikut adalah contoh keluaran dalam ringkasan metrik:
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 adalah UI sederhana yang terhubung ke clip back dan menampilkan hasilnya. Anda dapat menggunakannya di ui pengambilan klip
Atau Anda dapat menjalankannya sendiri dengan:
npm install -g clip-retrieval-front
clip-retrieval-front 3005
Anda juga dapat menjalankannya dengan clip-retrieval front
atau belakang dari paket python.
Untuk pengembangannya, lanjutkan ke depan dan jalankan npm install
lalu npm start
.
Baik secara lokal, atau di gitpod (lakukan export PIP_USER=false
di sana)
Siapkan virtualenv:
python3 -m venv .env
source .env/bin/activate
pip install -e .
untuk menjalankan tes:
pip install -r requirements-test.txt
Kemudian
make lint
make test
Anda dapat menggunakan make black
untuk memformat ulang kode
python -m pytest -x -s -v tests -k "test_runner"
untuk menjalankan tes tertentu
Jika Anda ingin menggunakan front melalui backend atau frontend python, jalankan
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}}
}