Latar Belakang
alam artikel ini, kita akan membahas bagaimana Milvus menjadwalkan tugas-tugas kueri. Kita juga akan membahas masalah, solusi, dan orientasi masa depan untuk mengimplementasikan penjadwalan Milvus.
Latar Belakang
Kita tahu dari Mengelola Data dalam Mesin Pencari Vektor Berskala Besar bahwa pencarian kemiripan vektor diimplementasikan dengan jarak antara dua vektor dalam ruang dimensi tinggi. Tujuan dari pencarian vektor adalah untuk menemukan K vektor yang paling dekat dengan vektor target.
Ada banyak cara untuk mengukur jarak vektor, seperti jarak Euclidean:
1-euclidean-distance.png
di mana x dan y adalah dua vektor. n adalah dimensi vektor.
Untuk menemukan K vektor terdekat dalam kumpulan data, jarak Euclidean perlu dihitung antara vektor target dan semua vektor dalam kumpulan data yang akan dicari. Kemudian, vektor diurutkan berdasarkan jarak untuk mendapatkan K vektor terdekat. Pekerjaan komputasi berbanding lurus dengan ukuran set data. Semakin besar dataset, semakin banyak pekerjaan komputasi yang dibutuhkan kueri. GPU, yang dikhususkan untuk pemrosesan grafik, memiliki banyak core untuk menyediakan daya komputasi yang dibutuhkan. Oleh karena itu, dukungan multi-GPU juga menjadi pertimbangan dalam implementasi Milvus.
Konsep dasar
Blok data (TabelFile)
Untuk meningkatkan dukungan pencarian data berskala masif, kami mengoptimalkan penyimpanan data Milvus. Milvus membagi data dalam tabel berdasarkan ukurannya menjadi beberapa blok data. Selama pencarian vektor, Milvus mencari vektor di setiap blok data dan menggabungkan hasilnya. Satu operasi pencarian vektor terdiri dari N operasi pencarian vektor independen (N adalah jumlah blok data) dan N-1 operasi penggabungan hasil.
Antrian tugas (Tabel Tugas)
Setiap Sumber Daya memiliki larik tugas, yang mencatat tugas-tugas milik Sumber Daya. Setiap tugas memiliki status yang berbeda, termasuk Mulai, Memuat, Dimuat, Dieksekusi, dan Dieksekusi. Pemuat dan Eksekutor dalam perangkat komputasi berbagi antrean tugas yang sama.
Penjadwalan kueri
Penjadwalan 2-query.png
- Ketika server Milvus dimulai, Milvus meluncurkan GpuResource yang sesuai melalui parameter
gpu_resource_config
dalam file konfigurasiserver_config.yaml
. DiskResource dan CpuResource masih belum dapat diedit diserver_config.yaml
. GpuResource adalah kombinasi darisearch_resources
danbuild_index_resources
dan disebut sebagai{gpu0, gpu1}
dalam contoh berikut:
3-contoh-kode.png
3-contoh.png
- Milvus menerima sebuah permintaan. Metadata tabel disimpan dalam basis data eksternal, yaitu SQLite atau MySQl untuk host tunggal dan MySQL untuk terdistribusi. Setelah menerima permintaan pencarian, Milvus memvalidasi apakah tabel tersebut ada dan dimensinya konsisten. Kemudian, Milvus membaca daftar TableFile dari tabel tersebut.
4-milvus-membaca-daftar-tablefile-list.png
- Milvus membuat sebuah SearchTask. Karena komputasi setiap TableFile dilakukan secara independen, Milvus membuat SearchTask untuk setiap TableFile. Sebagai unit dasar penjadwalan tugas, SearchTask berisi vektor target, parameter pencarian, dan nama-nama file dari TableFile.
5-daftar-file-file-daftar-tugas-pembuat.png
- Milvus memilih perangkat komputasi. Perangkat yang digunakan SearchTask untuk melakukan komputasi tergantung pada perkiraan waktu penyelesaian untuk setiap perangkat. Perkiraan waktu penyelesaian menentukan perkiraan interval antara waktu saat ini dan perkiraan waktu ketika komputasi selesai.
Misalnya, saat blok data SearchTask dimuat ke memori CPU, SearchTask berikutnya menunggu di antrean tugas komputasi CPU dan antrean tugas komputasi GPU menganggur. Perkiraan waktu penyelesaian untuk CPU sama dengan jumlah perkiraan biaya waktu SearchTask sebelumnya dan SearchTask saat ini. Perkiraan waktu penyelesaian untuk GPU sama dengan jumlah waktu blok data yang akan dimuat ke GPU dan perkiraan biaya waktu SearchTask saat ini. Perkiraan waktu penyelesaian untuk sebuah SearchTask dalam sebuah Sumber Daya sama dengan waktu eksekusi rata-rata semua SearchTask dalam Sumber Daya tersebut. Milvus kemudian memilih perangkat dengan estimasi waktu penyelesaian yang paling sedikit dan menetapkan SearchTask ke perangkat tersebut.
Di sini kami mengasumsikan bahwa estimasi waktu penyelesaian untuk GPU1 lebih pendek.
6-GPU1-estimasi-waktu-penyelesaian-lebih-pendek.png
Milvus menambahkan SearchTask ke antrean tugas DiskResource.
Milvus memindahkan SearchTask ke antrean tugas CpuResource. Thread pemuatan di CpuResource memuat setiap tugas dari antrean tugas secara berurutan. CpuResource membaca blok data yang sesuai ke memori CPU.
Milvus memindahkan SearchTask ke GpuResource. Thread pemuatan di GpuResource menyalin data dari memori CPU ke memori GPU. GpuResource membaca blok data yang sesuai ke memori GPU.
Milvus mengeksekusi SearchTask di GpuResource. Karena hasil dari SearchTask relatif kecil, hasilnya langsung dikembalikan ke memori CPU.
7-penjadwal.png
- Milvus menggabungkan hasil dari SearchTask ke seluruh hasil pencarian.
8-milvus-menggabungkan-hasil-pencarian.png
Setelah semua SearchTask selesai, Milvus mengembalikan seluruh hasil pencarian ke klien.
Pembuatan indeks
Pembuatan indeks pada dasarnya sama dengan proses pencarian tanpa proses penggabungan. Kami tidak akan membahas hal ini secara detail.
Pengoptimalan kinerja
Cache
Seperti yang telah disebutkan sebelumnya, blok data perlu dimuat ke perangkat penyimpanan yang sesuai seperti memori CPU atau memori GPU sebelum komputasi. Untuk menghindari pemuatan data yang berulang-ulang, Milvus memperkenalkan cache LRU (Least Recently Used). Ketika cache penuh, blok data baru akan menyingkirkan blok data lama. Anda dapat menyesuaikan ukuran cache dengan file konfigurasi berdasarkan ukuran memori saat ini. Cache yang besar untuk menyimpan data pencarian disarankan untuk menghemat waktu pemuatan data secara efektif dan meningkatkan kinerja pencarian.
Tumpang tindih pemuatan data dan komputasi
Cache tidak dapat memenuhi kebutuhan kita akan kinerja pencarian yang lebih baik. Data perlu dimuat ulang ketika memori tidak mencukupi atau ukuran kumpulan data terlalu besar. Kita perlu mengurangi efek pemuatan data pada kinerja pencarian. Pemuatan data, baik dari disk ke memori CPU atau dari memori CPU ke memori GPU, termasuk dalam operasi IO dan hampir tidak memerlukan pekerjaan komputasi dari prosesor. Jadi, kami mempertimbangkan untuk melakukan pemuatan data dan komputasi secara paralel untuk penggunaan sumber daya yang lebih baik.
Kami membagi komputasi pada blok data menjadi 3 tahap (pemuatan dari disk ke memori CPU, komputasi CPU, penggabungan hasil) atau 4 tahap (pemuatan dari disk ke memori CPU, pemuatan dari memori CPU ke memori GPU, komputasi GPU dan pengambilan hasil, dan penggabungan hasil). Ambil komputasi 3 tahap sebagai contoh, kita dapat menjalankan 3 thread yang bertanggung jawab atas 3 tahap untuk berfungsi sebagai pipelining instruksi. Karena set hasil sebagian besar kecil, penggabungan hasil tidak membutuhkan banyak waktu. Dalam beberapa kasus, tumpang tindih pemuatan data dan komputasi dapat mengurangi waktu pencarian hingga 1/2.
9-urutan-tumpang tindih-memuat-milvus.png
Masalah dan solusi
Kecepatan transmisi yang berbeda
Sebelumnya, Milvus menggunakan strategi Round Robin untuk penjadwalan tugas multi-GPU. Strategi ini bekerja dengan sempurna di server 4-GPU kami dan performa pencarian 4 kali lebih baik. Namun, untuk host 2-GPU kami, kinerjanya tidak 2 kali lebih baik. Kami melakukan beberapa percobaan dan menemukan bahwa kecepatan penyalinan data untuk sebuah GPU adalah 11 GB/s. Namun, untuk GPU lainnya, kecepatannya adalah 3 GB/s. Setelah mengacu pada dokumentasi mainboard, kami mengonfirmasi bahwa mainboard tersebut terhubung ke satu GPU melalui PCIe x16 dan GPU lainnya melalui PCIe x4. Dengan kata lain, GPU ini memiliki kecepatan penyalinan yang berbeda. Kemudian, kami menambahkan waktu penyalinan untuk mengukur perangkat yang optimal untuk setiap SearchTask.
Pekerjaan di masa mendatang
Lingkungan perangkat keras dengan peningkatan kompleksitas
Dalam kondisi nyata, lingkungan perangkat keras mungkin lebih rumit. Untuk lingkungan perangkat keras dengan banyak CPU, memori dengan arsitektur NUMA, NVLink, dan NVSwitch, komunikasi antar CPU/GPU membawa banyak peluang untuk pengoptimalan.
Pengoptimalan kueri
Selama eksperimen, kami menemukan beberapa peluang untuk peningkatan performa. Misalnya, ketika server menerima beberapa kueri untuk tabel yang sama, kueri dapat digabungkan dalam beberapa kondisi. Dengan menggunakan lokalitas data, kami dapat meningkatkan kinerja. Pengoptimalan ini akan diimplementasikan dalam pengembangan kami di masa depan. Sekarang kita sudah mengetahui bagaimana query dijadwalkan dan dilakukan untuk skenario single-host, multi-GPU. Kami akan terus memperkenalkan lebih banyak mekanisme dalam untuk Milvus di artikel-artikel mendatang.
- Konsep dasar
- Pembuatan indeks
- Pengoptimalan kinerja
- Masalah dan solusi
- Pekerjaan di masa mendatang
On This Page
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word