वेक्टर डीबी का उपयोग कब (नहीं) करें

Latest Technology, (लेटेस्ट टेक न्यूज़) Gadget (गैजेट्स) …

. वे एक वास्तविक समस्या का समाधान करते हैं, और कई मामलों में, वे आरएजी सिस्टम के लिए सही विकल्प हैं। लेकिन बात यह है: सिर्फ इसलिए कि आप एम्बेडिंग का उपयोग कर रहे हैं इसका मतलब यह नहीं है कि आप ज़रूरत एक वेक्टर डेटाबेस.

हमने एक बढ़ती प्रवृत्ति देखी है जहां प्रत्येक आरएजी कार्यान्वयन एक वेक्टर डीबी में प्लग इन करके शुरू होता है। यह बड़े पैमाने पर, सतत ज्ञान आधारों के लिए समझ में आ सकता है, लेकिन यह हमेशा सबसे कुशल मार्ग नहीं है, खासकर जब आपका उपयोग मामला अधिक गतिशील या समय-संवेदनशील हो।

प्लैंक में, हम एलएलएम-आधारित सिस्टम को बढ़ाने के लिए एम्बेडिंग का उपयोग करते हैं। हालाँकि, हमारे वास्तविक दुनिया के अनुप्रयोगों में से एक में, हमने इसका विकल्प चुना टालना एक वेक्टर डेटाबेस और इसके स्थान पर उपयोग किया गया सरल कुंजी-मूल्य भंडारजो काफी बेहतर फिट साबित हुआ।

इससे पहले कि मैं इसमें उतरूं, आइए अपने परिदृश्य का एक सरल, सामान्यीकृत संस्करण देखें ताकि यह समझाया जा सके कि ऐसा क्यों है।

फू उदाहरण

आइए एक सरल RAG-शैली प्रणाली की कल्पना करें। एक उपयोगकर्ता कुछ टेक्स्ट फ़ाइलें, शायद कुछ रिपोर्ट या मीटिंग नोट्स अपलोड करता है। हम उन फ़ाइलों को टुकड़ों में विभाजित करते हैं, प्रत्येक टुकड़े के लिए एम्बेडिंग उत्पन्न करते हैं, और प्रश्नों के उत्तर देने के लिए उन एम्बेडिंग का उपयोग करते हैं। उपयोगकर्ता अगले कुछ मिनटों में कुछ प्रश्न पूछता है, फिर चला जाता है। उस समय, फ़ाइलें और उनकी एम्बेडिंग दोनों बेकार हैं और उन्हें सुरक्षित रूप से त्याग दिया जा सकता है।

दूसरे शब्दों में, डेटा है अल्पकालिकउपयोगकर्ता केवल एक ही पूछेगा कुछ प्रश्नऔर हम उनका उत्तर देना चाहते हैं जितनी जल्दी हो सके.

अब एक सेकंड के लिए रुकें और अपने आप से पूछें:

मुझे इन एम्बेडिंग्स को कहां संग्रहीत करना चाहिए?


अधिकांश लोगों की प्रवृत्ति है: “मेरे पास एम्बेडिंग है, इसलिए मुझे एक वेक्टर डेटाबेस की आवश्यकता है”, लेकिन एक सेकंड के लिए रुकें और सोचें कि वास्तव में उस अमूर्तता के पीछे क्या हो रहा है। जब आप वेक्टर डीबी में एम्बेडिंग भेजते हैं, तो यह उन्हें सिर्फ “स्टोर” नहीं करता है। यह एक सूचकांक बनाता है जो समानता खोजों को गति देता है। वह अनुक्रमण कार्य वह जगह है जहां से बहुत सारा जादू आता है, और जहां बहुत सारी लागत भी रहती है।

लंबे समय तक चलने वाले, बड़े पैमाने पर ज्ञान के आधार में, यह व्यापार-बंद बिल्कुल सही समझ में आता है: आप एक बार अनुक्रमण लागत का भुगतान करते हैं (या डेटा परिवर्तन के रूप में वृद्धिशील रूप से), और फिर उस लागत को लाखों प्रश्नों में फैलाते हैं। हमारे फू उदाहरण में, ऐसा नहीं हो रहा है। हम इसके विपरीत कर रहे हैं: लगातार एम्बेडिंग के छोटे, एकमुश्त बैच जोड़ रहे हैं, प्रति बैच थोड़ी संख्या में प्रश्नों का उत्तर दे रहे हैं, और फिर सब कुछ फेंक रहे हैं।

तो असली सवाल यह नहीं है कि “क्या मुझे वेक्टर डेटाबेस का उपयोग करना चाहिए?” लेकिन “क्या अनुक्रमणीकरण कार्य इसके लायक है?इसका उत्तर देने के लिए, हम एक साधारण बेंचमार्क देख सकते हैं।

बेंचमार्किंग: नो-इंडेक्स पुनर्प्राप्ति बनाम अनुक्रमित पुनर्प्राप्ति

cars vector db 1
द्वारा तसवीर जूलिया फियानडर पर unsplash

यह अनुभाग अधिक तकनीकी है. हम पायथन कोड को देखेंगे और अंतर्निहित एल्गोरिदम की व्याख्या करेंगे। यदि सटीक कार्यान्वयन विवरण आपके लिए प्रासंगिक नहीं हैं, तो बेझिझक आगे बढ़ें परिणाम अनुभाग।

हम दो प्रणालियों की तुलना करना चाहते हैं:

  1. कोई अनुक्रमण नहीं बिल्कुल, बस मेमोरी में एम्बेडिंग रखता है और उन्हें सीधे स्कैन करता है।
  2. एक वेक्टर डेटाबेसजहां हम प्रत्येक क्वेरी को तेज़ बनाने के लिए अनुक्रमण लागत का अग्रिम भुगतान करते हैं।

सबसे पहले, “नो वेक्टर डीबी” दृष्टिकोण पर विचार करें। जब कोई क्वेरी आती है, तो हम क्वेरी एम्बेडिंग और सभी संग्रहीत एम्बेडिंग के बीच समानता की गणना करते हैं, फिर टॉप-के का चयन करते हैं। बस इतना ही K-निकटतम पड़ोसी बिना किसी सूचकांक के.

import numpy as np

def run_knn(embeddings: np.ndarray, query_embedding: np.ndarray, top_k: int) -> np.ndarray:
    sims = embeddings @ query_embedding
    return sims.argsort()(-top_k:)(::-1)

कोड डॉट उत्पाद को प्रॉक्सी के रूप में उपयोग करता है कोज्या समानता (सामान्यीकृत वैक्टर मानते हुए) और सर्वोत्तम मिलान खोजने के लिए स्कोर को क्रमबद्ध करता है। यह वस्तुतः बस है सभी वैक्टरों को स्कैन करता है और निकटतम को चुनता है।

अब, आइए देखें कि एक वेक्टर DB आम तौर पर क्या करता है। हुड के तहत, अधिकांश वेक्टर डेटाबेस एक पर भरोसा करते हैं अनुमानित निकटतम पड़ोसी (एएनएन) सूचकांक। खोज गति में बड़े पैमाने पर वृद्धि के लिए एएनएन विधियां थोड़ी सटीकता का व्यापार करती हैं, और इसके लिए सबसे व्यापक रूप से उपयोग किए जाने वाले एल्गोरिदम में से एक एचएनएसडब्ल्यू है। हम उपयोग करेंगे hnswlib सूचकांक व्यवहार का अनुकरण करने के लिए पुस्तकालय।

import numpy as np
import hnswlib

def create_hnsw_index(embeddings: np.ndarray, num_dims: int) -> hnswlib.Index:
    index = hnswlib.Index(space='cosine', dim=num_dims)
    index.init_index(max_elements=embeddings.shape(0))
    index.add_items(embeddings)
    return index

def query_hnsw(index: hnswlib.Index, query_embedding: np.ndarray, top_k: int) -> np.ndarray:
    labels, distances = index.knn_query(query_embedding, k=top_k)
    return labels(0)

यह देखने के लिए कि समझौता कहां होता है, हम कुछ यादृच्छिक एम्बेडिंग उत्पन्न कर सकते हैं, उन्हें सामान्य कर सकते हैं, और माप सकते हैं कि प्रत्येक चरण में कितना समय लगता है:

import time
import numpy as np
import hnswlib
from tqdm import tqdm

def run_benchmark(num_embeddings: int, num_dims: int, top_k: int, num_iterations: int) -> None:
    print(f"Benchmarking with {num_embeddings} embeddings of dimension {num_dims}, retrieving top-{top_k} nearest neighbors.")

    knn_times: list(float) = ()
    index_times: list(float) = ()
    hnsw_query_times: list(float) = ()

    for _ in tqdm(range(num_iterations), desc="Running benchmark"):
        embeddings = np.random.rand(num_embeddings, num_dims).astype('float32')
        embeddings = embeddings / np.linalg.norm(embeddings, axis=1, keepdims=True)
        query_embedding = np.random.rand(num_dims).astype('float32')
        query_embedding = query_embedding / np.linalg.norm(query_embedding)

        start_time = time.time()
        run_knn(embeddings, query_embedding, top_k)
        knn_times.append((time.time() - start_time) * 1e3)

        start_time = time.time()
        vector_db_index = create_hnsw_index(embeddings, num_dims)
        index_times.append((time.time() - start_time) * 1e3)

        start_time = time.time()
        query_hnsw(vector_db_index, query_embedding, top_k)
        hnsw_query_times.append((time.time() - start_time) * 1e3)

    print(f"BENCHMARK RESULTS (averaged over {num_iterations} iterations)")
    print(f"(Naive KNN) Average search time without indexing: {np.mean(knn_times):.2f} ms")
    print(f"(HNSW Index) Average index construction time: {np.mean(index_times):.2f} ms")
    print(f"(HNSW Index) Average query time with indexing: {np.mean(hnsw_query_times):.2f} ms")

run_benchmark(num_embeddings=50000, num_dims=1536, top_k=5, num_iterations=20)

परिणाम

इस उदाहरण में, हम 1,536 आयामों (ओपनएआई से मेल खाते हुए) के साथ 50,000 एम्बेडिंग का उपयोग करते हैं text-embedding-3-small) और शीर्ष-5 पड़ोसियों को पुनः प्राप्त करें। अलग-अलग कॉन्फ़िगरेशन के साथ सटीक परिणाम अलग-अलग होंगे, लेकिन जिस पैटर्न की हम परवाह करते हैं वह वही है।

मैं आपको अपने स्वयं के नंबरों के साथ बेंचमार्क चलाने के लिए प्रोत्साहित करता हूं, यह यह देखने का सबसे अच्छा तरीका है कि आपके विशिष्ट उपयोग के मामले में ट्रेड-ऑफ कैसे काम करता है।

औसतन, सहज KNN खोज में प्रति प्रश्न 24.54 मिलीसेकंड लगते हैं। समान एम्बेडिंग के लिए HNSW इंडेक्स बनाने में लगभग 277 सेकंड लगते हैं। एक बार इंडेक्स बन जाने के बाद, प्रत्येक क्वेरी में लगभग 0.47 मिलीसेकंड का समय लगता है।

इससे हम ब्रेक-ईवन पॉइंट का अनुमान लगा सकते हैं। सरल केएनएन और अनुक्रमित क्वेरी के बीच का अंतर 24.07 एमएस प्रति क्वेरी है। इसका मतलब है कि आपको चाहिए प्रत्येक क्वेरी पर बचाए गए समय से पहले 11,510 क्वेरीज़ सूचकांक के निर्माण में लगने वाले समय की भरपाई करती हैं.

total time vs number of queries vector db
बेंचमार्क कोड का उपयोग करके उत्पन्न: अनुभवहीन केएनएन और अनुक्रमित खोज दक्षता की तुलना करने वाला एक ग्राफ

इसके अलावा, एम्बेडिंग और टॉप-के की संख्या के लिए अलग-अलग मूल्यों के साथ भी, ब्रेक-ईवन बिंदु हजारों प्रश्नों में बना रहता है और काफी संकीर्ण सीमा के भीतर रहता है। आपको ऐसा परिदृश्य नहीं मिलता जहां केवल कुछ दर्जन प्रश्नों के बाद अनुक्रमण का लाभ मिलने लगे।

braek even point vector db
बेंचमार्क कोड का उपयोग करके जेनरेट किया गया: विभिन्न एम्बेडिंग गणनाओं और टॉप-के सेटिंग्स के लिए ब्रेक-ईवन पॉइंट दिखाने वाला एक ग्राफ (लेखक द्वारा छवि)

अब इसकी तुलना फू उदाहरण से करें। एक उपयोगकर्ता फ़ाइलों का एक छोटा सा सेट अपलोड करता है और कुछ प्रश्न पूछता है, हजारों नहीं। सिस्टम कभी भी उस बिंदु तक नहीं पहुंचता जहां सूचकांक भुगतान करता है। इसके बजाय, अनुक्रमण चरण बस उस क्षण में देरी करता है जब सिस्टम पहले प्रश्न का उत्तर दे सकता है और परिचालन जटिलता जोड़ता है।

इस तरह के अल्पकालिक, प्रति-उपयोगकर्ता संदर्भ के लिए, सरल इन-मेमोरी KNN दृष्टिकोण न केवल लागू करना और संचालित करना आसान है, बल्कि यह अंत-से-अंत तक तेज़ भी है।

यदि इन-मेमोरी स्टोरेज कोई विकल्प नहीं है, या तो क्योंकि सिस्टम वितरित है या क्योंकि हमें कुछ मिनटों के लिए उपयोगकर्ता की स्थिति को संरक्षित करने की आवश्यकता है, तो हम इसका उपयोग कर सकते हैं कुंजी-मूल्य भंडार पसंद रेडिस. हम उपयोगकर्ता के अनुरोध के लिए एक अद्वितीय पहचानकर्ता को कुंजी के रूप में संग्रहीत कर सकते हैं और सभी एम्बेडिंग को मूल्य के रूप में संग्रहीत कर सकते हैं।

यह हमें एक हल्का, कम जटिलता वाला समाधान देता है जो हमारे उपयोग के मामले में उपयुक्त है अल्पकालिक, कम-प्रश्न वाले संदर्भ.

वास्तविक दुनिया का उदाहरण: हमने एक कुंजी-मूल्य वाला स्टोर क्यों चुना

real world example vector db
द्वारा तसवीर गेविन एलनवुड पर unsplash

पर प्लांकहम व्यवसायों के बारे में बीमा से संबंधित सवालों के जवाब देते हैं। एक सामान्य अनुरोध व्यवसाय के नाम और पते से शुरू होता है, और फिर हम पुनः प्राप्त करते हैं वास्तविक समय डेटा उस विशिष्ट व्यवसाय के बारे में, जिसमें उसकी ऑनलाइन उपस्थिति, पंजीकरण और अन्य सार्वजनिक रिकॉर्ड शामिल हैं। यह डेटा हमारा संदर्भ बन जाता है, और हम इसके आधार पर प्रश्नों के उत्तर देने के लिए एलएलएम और एल्गोरिदम का उपयोग करते हैं।

महत्वपूर्ण बात यह है कि जब भी हमें कोई अनुरोध मिलता है, हम उसे तैयार करते हैं एक ताजा संदर्भ. हम मौजूदा डेटा का पुन: उपयोग नहीं कर रहे हैं, यह मांग पर प्राप्त किया जाता है और इसके लिए प्रासंगिक बना रहता है ज़्यादा से ज़्यादा कुछ मिनट.

यदि आप पहले के बेंचमार्क के बारे में सोचते हैं, तो यह पैटर्न पहले से ही आपके “यह वेक्टर डीबी उपयोग केस नहीं है” सेंसर को ट्रिगर कर रहा होगा।

हर बार जब हमें कोई अनुरोध प्राप्त होता है, तो हम अल्पकालिक डेटा के लिए नई एम्बेडिंग तैयार करते हैं, जिसे हम संभवतः केवल कुछ सौ बार ही क्वेरी करेंगे। वेक्टर DB में उन एम्बेडिंग को अनुक्रमित करने से अनावश्यक विलंबता जुड़ जाती है। इसके विपरीत, रेडिस के साथ, हम कर सकते हैं एंबेडिंग्स को तुरंत स्टोर करें और एप्लिकेशन कोड में त्वरित समानता खोज चलाएँ अनुक्रमणन में लगभग कोई देरी नहीं।

इसलिए हमने चुना रेडिस वेक्टर डेटाबेस के बजाय. जबकि वेक्टर डीबी बड़ी मात्रा में एम्बेडिंग को संभालने और तेजी से निकटतम-पड़ोसी प्रश्नों का समर्थन करने में उत्कृष्ट हैं, वे परिचय देते हैं ओवरहेड अनुक्रमणऔर हमारे मामले में, वह ओवरहेड इसके लायक नहीं है।

निष्कर्ष के तौर पर

यदि आपको लाखों एम्बेडिंग संग्रहीत करने और साझा कॉर्पस में उच्च-क्वेरी वर्कलोड का समर्थन करने की आवश्यकता है, तो एक वेक्टर डीबी बेहतर फिट होगा। और हाँ, वहाँ निश्चित रूप से ऐसे उपयोग के मामले हैं जिनकी वास्तव में वेक्टर डीबी से आवश्यकता और लाभ है।

लेकिन सिर्फ इसलिए कि आप एम्बेडिंग का उपयोग कर रहे हैं या RAG सिस्टम बनाने का मतलब यह नहीं है कि आपको वेक्टर DB पर डिफ़ॉल्ट होना चाहिए।

प्रत्येक डेटाबेस तकनीक की अपनी ताकत और फायदे हैं। सबसे अच्छा विकल्प आपके डेटा और उपयोग के मामले की गहरी समझ से शुरू होता है, बिना सोचे-समझे चलन का अनुसरण करने के बजाय।

तो, अगली बार जब आपको कोई डेटाबेस चुनने की आवश्यकता हो, तो एक पल के लिए रुकें और पूछें: क्या मैं वस्तुनिष्ठ ट्रेड-ऑफ के आधार पर सही डेटाबेस चुन रहा हूं, या क्या मैं सिर्फ सबसे आधुनिक, सबसे चमकदार विकल्प के साथ जा रहा हूं?

(टैग्सटूट्रांसलेट)एडिटर्स पिक(टी)एम्बेडिंग्स(टी)एलएलएम एप्लीकेशन(टी)रैग(टी)वेक्टर डेटाबेस
Latest Technology, (लेटेस्ट टेक न्यूज़) Gadget (गैजेट्स) …

Source link

Leave a Reply

Your email address will not be published. Required fields are marked *