šŸš€ Coba Zilliz Cloud, Milvus yang sepenuhnya terkelola, secara gratisā€”rasakan performa 10x lebih cepat! Coba Sekarang>>

milvus-logo
LFAI
  • Home
  • Blog
  • Mengoptimalkan Basis Data Vektor, Meningkatkan AI Generatif Berbasis RAG

Mengoptimalkan Basis Data Vektor, Meningkatkan AI Generatif Berbasis RAG

  • Engineering
May 13, 2024
Cathy Zhang, Dr. Malini Bhandaru

Artikel ini awalnya dipublikasikan di Medium Channel Intel dan diposting ulang di sini dengan izin.


Dua metode untuk mengoptimalkan basis data vektor Anda saat menggunakan RAG

Foto oleh Ilya Pavlov di Unsplash

Oleh Cathy Zhang dan Dr: Lin Yang dan Changyan Liu

Model AI Generatif (GenAI), yang mengalami adopsi eksponensial dalam kehidupan kita sehari-hari, ditingkatkan dengan retrieval-augmented generation (RAG), sebuah teknik yang digunakan untuk meningkatkan akurasi dan keandalan respons dengan mengambil fakta-fakta dari sumber eksternal. RAG membantu model bahasa besar (LLM ) biasa untuk memahami konteks dan mengurangi halusinasi dengan memanfaatkan basis data raksasa data tidak terstruktur yang disimpan sebagai vektor - presentasi matematika yang membantu menangkap konteks dan hubungan antar data.

RAG membantu mengambil lebih banyak informasi kontekstual dan dengan demikian menghasilkan respons yang lebih baik, tetapi basis data vektor yang mereka andalkan semakin besar untuk menyediakan konten yang kaya untuk dimanfaatkan. Seperti halnya LLM dengan triliunan parameter yang akan segera hadir, basis data vektor dengan miliaran vektor juga tidak ketinggalan. Sebagai insinyur pengoptimalan, kami ingin tahu apakah kami dapat membuat database vektor lebih berkinerja, memuat data lebih cepat, dan membuat indeks lebih cepat untuk memastikan kecepatan pengambilan bahkan saat data baru ditambahkan. Dengan melakukan hal tersebut, tidak hanya akan mengurangi waktu tunggu pengguna, tetapi juga membuat solusi AI berbasis RAG menjadi lebih berkelanjutan.

Dalam artikel ini, Anda akan mempelajari lebih lanjut tentang database vektor dan kerangka kerja pembandingannya, kumpulan data untuk menangani berbagai aspek, dan alat yang digunakan untuk analisis kinerja - semua yang Anda perlukan untuk mulai mengoptimalkan database vektor. Kami juga akan membagikan pencapaian pengoptimalan kami pada dua solusi database vektor yang populer untuk menginspirasi Anda dalam perjalanan pengoptimalan kinerja dan dampak keberlanjutan.

Memahami Basis Data Vektor

Tidak seperti basis data relasional atau non-relasional tradisional di mana data disimpan secara terstruktur, basis data vektor berisi representasi matematis dari masing-masing item data, yang disebut vektor, yang dibangun menggunakan fungsi penyematan atau transformasi. Vektor biasanya mewakili fitur atau makna semantik dan bisa pendek atau panjang. Basis data vektor melakukan pengambilan vektor dengan pencarian kemiripan menggunakan metrik jarak (di mana semakin dekat berarti hasilnya semakin mirip) seperti Euclidean, dot product, atau kemiripan kosinus.

Untuk mempercepat proses pencarian, data vektor diorganisasikan menggunakan mekanisme pengindeksan. Contoh metode pengorganisasian ini antara lain adalah struktur datar, inverted file (IVF), Hierarchical Navigable Small Worlds (HNSW ), dan locality-sensitive hashing (LSH). Masing-masing metode ini berkontribusi pada efisiensi dan efektivitas pengambilan vektor yang serupa saat dibutuhkan.

Mari kita lihat bagaimana Anda menggunakan basis data vektor dalam sistem GenAI. Gambar 1 mengilustrasikan pemuatan data ke dalam basis data vektor dan menggunakannya dalam konteks aplikasi GenAI. Ketika Anda memasukkan prompt, prompt akan mengalami proses transformasi yang sama dengan yang digunakan untuk menghasilkan vektor dalam basis data. Prompt vektor yang telah ditransformasi ini kemudian digunakan untuk mengambil vektor yang serupa dari basis data vektor. Item yang diambil ini pada dasarnya berfungsi sebagai memori percakapan, memberikan riwayat kontekstual untuk prompt, mirip dengan cara kerja LLM. Fitur ini terbukti sangat bermanfaat dalam pemrosesan bahasa alami, visi komputer, sistem rekomendasi, dan domain lain yang membutuhkan pemahaman semantik dan pencocokan data. Prompt awal Anda kemudian "digabungkan" dengan elemen yang diambil, menyediakan konteks, dan membantu LLM dalam merumuskan respons berdasarkan konteks yang disediakan daripada hanya mengandalkan data pelatihan aslinya.

Gambar 1. Arsitektur aplikasi RAG.

Vektor disimpan dan diindeks untuk pengambilan yang cepat. Basis data vektor terdiri dari dua jenis, yaitu basis data tradisional yang telah diperluas untuk menyimpan vektor dan basis data vektor yang dibuat khusus. Beberapa contoh basis data tradisional yang menyediakan dukungan vektor adalah Redis, pgvector, Elasticsearch, dan OpenSearch. Contoh basis data vektor yang dibuat khusus meliputi solusi eksklusif Zilliz dan Pinecone, dan proyek sumber terbuka Milvus, Weaviate, Qdrant, Faiss, dan Chroma. Anda dapat mempelajari lebih lanjut tentang basis data vektor di GitHub melalui LangChain dan OpenAI Cookbook.

Kita akan melihat lebih dekat pada satu dari setiap kategori, Milvus dan Redis.

Meningkatkan Kinerja

Sebelum masuk ke dalam pengoptimalan, mari kita tinjau bagaimana database vektor dievaluasi, beberapa kerangka kerja evaluasi, dan alat analisis kinerja yang tersedia.

Metrik Kinerja

Mari kita lihat metrik utama yang dapat membantu Anda mengukur performa basis data vektor.

  • Load latency mengukur waktu yang diperlukan untuk memuat data ke dalam memori database vektor dan membangun indeks. Indeks adalah struktur data yang digunakan untuk mengatur dan mengambil data vektor secara efisien berdasarkan kemiripan atau jaraknya. Jenis-jenis indeks dalam memori termasuk indeks datar, IVF_FLAT, IVF_PQ, HNSW, tetangga terdekat yang dapat diskalakan (ScaNN), dan DiskANN.
  • Recall adalah proporsi kecocokan yang benar, atau item yang relevan, yang ditemukan dalam hasil Top K yang diambil oleh algoritme pencarian. Nilai recall yang lebih tinggi menunjukkan pengambilan item yang relevan dengan lebih baik.
  • Query per detik (QPS ) adalah kecepatan database vektor dalam memproses kueri yang masuk. Nilai QPS yang lebih tinggi menyiratkan kemampuan pemrosesan kueri yang lebih baik dan throughput sistem.

Kerangka Kerja Pembandingan

Gambar 2. Kerangka kerja pembandingan basis data vektor.

Pembandingan database vektor membutuhkan server database vektor dan klien. Dalam pengujian kinerja kami, kami menggunakan dua alat sumber terbuka yang populer.

  • VectorDBBench: Dikembangkan dan bersumber terbuka oleh Zilliz, VectorDBBench membantu menguji database vektor yang berbeda dengan jenis indeks yang berbeda dan menyediakan antarmuka web yang nyaman.
  • vector-db-benchmark: Dikembangkan dan bersumber terbuka oleh Qdrant, vector-db-benchmark membantu menguji beberapa basis data vektor yang umum untuk jenis indeks HNSW. Ia menjalankan pengujian melalui baris perintah dan menyediakan berkas Docker Compose __ untuk menyederhanakan memulai komponen server.

Gambar 3. Contoh perintah vector-db-benchmark yang digunakan untuk menjalankan tes benchmark.

Namun, kerangka kerja benchmark hanyalah sebagian dari persamaan. Kita membutuhkan data yang melatih berbagai aspek dari solusi database vektor itu sendiri, seperti kemampuannya menangani volume data yang besar, berbagai ukuran vektor, dan kecepatan pengambilan data, mari kita lihat beberapa set data publik yang tersedia.

Kumpulan Data Terbuka untuk Melatih Basis Data Vektor

Dataset besar adalah kandidat yang baik untuk menguji latensi pemuatan dan alokasi sumber daya. Beberapa dataset memiliki data berdimensi tinggi dan bagus untuk menguji kecepatan kesamaan komputasi.

Dataset berkisar dari dimensi 25 hingga dimensi 2048. Dataset LAION, sebuah koleksi gambar terbuka, telah digunakan untuk melatih model deep-neural visual dan bahasa yang sangat besar seperti model generatif difusi yang stabil. Dataset OpenAI yang terdiri dari 5 juta vektor, masing-masing dengan dimensi 1536, dibuat oleh VectorDBBench dengan menjalankan OpenAI pada data mentah. Mengingat setiap elemen vektor bertipe FLOAT, untuk menyimpan vektor saja, dibutuhkan sekitar 29 GB (5M * 1536 * 4) memori, ditambah dengan jumlah yang sama untuk menyimpan indeks dan metadata lainnya dengan total 58 GB memori untuk pengujian. Saat menggunakan alat vector-db-benchmark, pastikan penyimpanan disk yang memadai untuk menyimpan hasil.

Untuk menguji latensi pemuatan, kami membutuhkan koleksi vektor yang besar, yang ditawarkan oleh deep-image-96-angular. Untuk menguji performa pembuatan indeks dan komputasi kesamaan, vektor berdimensi tinggi akan memberikan tekanan yang lebih besar. Untuk itu, kami memilih dataset 500 ribu vektor berdimensi 1536.

Alat Bantu Performa

Kita telah membahas cara-cara untuk menekan sistem untuk mengidentifikasi metrik yang diminati, tetapi mari kita periksa apa yang terjadi di tingkat yang lebih rendah: Seberapa sibuk unit komputasi, konsumsi memori, waktu tunggu untuk penguncian, dan banyak lagi? Semua ini memberikan petunjuk tentang perilaku basis data, khususnya berguna dalam mengidentifikasi area masalah.

Utilitas utama Linux menyediakan informasi kinerja sistem. Namun, alat perf di Linux menyediakan wawasan yang lebih dalam. Untuk mempelajari lebih lanjut, kami juga merekomendasikan untuk membaca contoh-contoh perf Linux dan metode analisis mikroarsitektur top-down Intel. Alat lainnya adalah IntelĀ® vTuneā„¢ Profiler, yang berguna untuk mengoptimalkan tidak hanya aplikasi tetapi juga kinerja dan konfigurasi sistem untuk berbagai beban kerja yang mencakup HPC, cloud, IoT, media, penyimpanan, dan lainnya.

Pengoptimalan Basis Data Vektor Milvus

Mari kita lihat beberapa contoh bagaimana kami mencoba meningkatkan kinerja database vektor Milvus.

Mengurangi Overhead Pergerakan Memori dalam Penulisan Buffer Datanode

Jalur penulisan Milvus memproksi penulisan data ke dalam log broker melalui MsgStream. Simpul data kemudian mengkonsumsi data, mengubah dan menyimpannya ke dalam segmen. Segmen akan menggabungkan data yang baru dimasukkan. Logika penggabungan mengalokasikan buffer baru untuk menampung/memindahkan data lama dan data baru yang akan disisipkan dan kemudian mengembalikan buffer baru sebagai data lama untuk penggabungan data berikutnya. Hal ini mengakibatkan data lama menjadi semakin besar, yang pada gilirannya membuat pergerakan data menjadi lebih lambat. Profil Perf menunjukkan overhead yang tinggi untuk logika ini.

Gambar 4. Penggabungan dan pemindahan data dalam basis data vektor menghasilkan overhead performa tinggi.

Kami mengubah logika penggabungan buffer untuk secara langsung menambahkan data baru yang akan disisipkan ke dalam data lama, menghindari pengalokasian buffer baru dan pemindahan data lama yang besar. Profil perf mengonfirmasi bahwa tidak ada overhead pada logika ini. Metrik kode mikro metrik_CPU frekuensi operasi dan metrik_CPU utilisasi menunjukkan peningkatan yang konsisten dengan sistem yang tidak perlu lagi menunggu perpindahan memori yang lama. Load latency meningkat lebih dari 60 persen. Peningkatan ini terekam pada GitHub.

Gambar 5. Dengan lebih sedikit penyalinan, kami melihat peningkatan kinerja lebih dari 50 persen dalam load latency.

Pembuatan Indeks Terbalik dengan Pengurangan Overhead Alokasi Memori

Mesin pencari Milvus, Knowhere, menggunakan algoritma Elkan k-means untuk melatih data klaster untuk membuat indeks inverted file (IVF). Setiap putaran pelatihan data menentukan jumlah iterasi. Semakin besar jumlah iterasi, semakin baik hasil pelatihannya. Namun, hal ini juga menyiratkan bahwa algoritma Elkan akan dipanggil lebih sering.

Algoritma Elkan menangani alokasi dan de-alokasi memori setiap kali dieksekusi. Secara khusus, algoritma ini mengalokasikan memori untuk menyimpan setengah dari ukuran data matriks simetris, tidak termasuk elemen diagonal. Di Knowhere, dimensi matriks simetris yang digunakan oleh algoritma Elkan diatur ke 1024, menghasilkan ukuran memori sekitar 2 MB. Ini berarti untuk setiap putaran pelatihan, Elkan berulang kali mengalokasikan dan mendealokasi memori 2 MB.

Data profil perf mengindikasikan aktivitas alokasi memori yang besar. Bahkan, hal ini memicu alokasi virtual memory area (VMA), alokasi halaman fisik, pengaturan peta halaman, dan pembaruan statistik cgroup memori di kernel. Pola aktivitas alokasi/dealokasi memori yang besar ini, dalam beberapa situasi, juga dapat memperburuk fragmentasi memori. Ini adalah pajak yang signifikan.

Struktur IndexFlatElkan secara khusus didesain dan dibangun untuk mendukung algoritma Elkan. Setiap proses pelatihan data akan memiliki instance IndexFlatElkan yang diinisialisasi. Untuk mengurangi dampak kinerja yang dihasilkan dari alokasi dan de-alokasi memori yang sering terjadi pada algoritma Elkan, kami melakukan refactoring pada logika kode, memindahkan manajemen memori di luar fungsi algoritma Elkan ke dalam proses konstruksi IndexFlatElkan. Hal ini memungkinkan alokasi memori terjadi hanya sekali selama fase inisialisasi sambil melayani semua panggilan fungsi algoritme Elkan berikutnya dari proses pelatihan data saat ini dan membantu meningkatkan latensi pemuatan sekitar 3 persen. Temukan patch Knowhere di sini.

Akselerasi Pencarian Vektor Redis melalui Prefetch Perangkat Lunak

Redis, penyimpan data nilai-kunci dalam memori tradisional yang populer, baru-baru ini mulai mendukung pencarian vektor. Untuk melampaui penyimpanan nilai-kunci pada umumnya, Redis menawarkan modul ekstensibilitas; modul RediSearch memfasilitasi penyimpanan dan pencarian vektor secara langsung di dalam Redis.

Untuk pencarian kemiripan vektor, Redis mendukung dua algoritme, yaitu brute force dan HNSW. Algoritme HNSW secara khusus dibuat untuk menemukan perkiraan tetangga terdekat secara efisien dalam ruang dimensi tinggi. Algoritme ini menggunakan antrean prioritas bernama candidate_set untuk mengelola semua kandidat vektor untuk komputasi jarak.

Setiap kandidat vektor mencakup metadata yang substansial selain data vektor. Akibatnya, ketika memuat kandidat dari memori, hal ini dapat menyebabkan kesalahan cache data, yang menyebabkan penundaan pemrosesan. Pengoptimalan kami memperkenalkan pengambilan awal perangkat lunak untuk memuat kandidat berikutnya secara proaktif sambil memproses kandidat yang sekarang. Peningkatan ini telah menghasilkan peningkatan throughput sebesar 2 hingga 3 persen untuk pencarian kemiripan vektor dalam satu kali penyiapan Redis. Patch ini sedang dalam proses untuk di-upstream.

Perubahan Perilaku Default GCC untuk Mencegah Penalti Kode Perakitan Campuran

Untuk mendorong performa maksimum, bagian kode yang sering digunakan sering kali ditulis secara manual dalam perakitan. Namun, ketika segmen kode yang berbeda ditulis oleh orang yang berbeda atau pada titik waktu yang berbeda, instruksi yang digunakan mungkin berasal dari set instruksi perakitan yang tidak kompatibel seperti IntelĀ® Advanced Vector Extensions 512 (IntelĀ® AVX-512 ) dan Streaming SIMD Extensions (SSE). Jika tidak dikompilasi dengan benar, kode campuran akan menghasilkan penalti kinerja. Pelajari lebih lanjut tentang pencampuran instruksi Intel AVX dan SSE di sini.

Anda dapat dengan mudah menentukan apakah Anda menggunakan kode perakitan mode campuran dan belum mengompilasi kode dengan VZEROUPPER, sehingga menimbulkan penalti kinerja. Hal ini dapat diamati melalui perintah perf seperti sudo perf stat -e 'assists.sse_avx_mix/event/event=0xc1,umask=0x10/' <beban kerja>. Jika OS Anda tidak memiliki dukungan untuk event tersebut, gunakan cpu/event=0xc1,umask=0x10,name=assists_sse_avx_mix/.

Kompiler Clang secara default menyisipkan VZEROUPPER, untuk menghindari penalti mode campuran. Tetapi kompiler GCC hanya memasukkan VZEROUPPER ketika flag kompiler -O2 atau -O3 ditentukan. Kami menghubungi tim GCC dan menjelaskan masalah ini dan mereka sekarang, secara default, menangani kode perakitan mode campuran dengan benar.

Mulai Mengoptimalkan Basis Data Vektor Anda

Basis data vektor memainkan peran integral dalam GenAI, dan basis data vektor terus berkembang untuk menghasilkan respons yang lebih berkualitas. Sehubungan dengan pengoptimalan, aplikasi AI tidak berbeda dengan aplikasi perangkat lunak lain yang mengungkapkan rahasianya ketika seseorang menggunakan alat analisis kinerja standar bersama dengan kerangka kerja tolok ukur dan input stres.

Dengan menggunakan alat bantu ini, kami menemukan jebakan kinerja yang berkaitan dengan alokasi memori yang tidak perlu, kegagalan untuk mengambil instruksi, dan menggunakan opsi kompiler yang salah. Berdasarkan temuan kami, kami meningkatkan peningkatan pada Milvus, Knowhere, Redis, dan kompiler GCC untuk membantu membuat AI menjadi lebih berkinerja dan berkelanjutan. Basis data vektor adalah kelas aplikasi penting yang layak untuk upaya pengoptimalan Anda. Kami harap artikel ini dapat membantu Anda untuk memulai.

Like the article? Spread the word

Terus Baca