वेक्टर एम्बेडिंग की मदद से खोजें

इस पेज पर, K-निकट वैल्यू की परफ़ॉर्मेंस देने के लिए, Cloud Firestore का इस्तेमाल करने का तरीका बताया गया है नेबर (KNN) वेक्टर इन तकनीकों का इस्तेमाल करके खोज करता है:

  • वेक्टर की वैल्यू सेव करें
  • KNN वेक्टर इंडेक्स बनाएं और मैनेज करें
  • समर्थित वेक्टर में से किसी एक का इस्तेमाल करके K-निकटतम-पड़ोसी (KNN) क्वेरी करें दूरी की माप

वेक्टर एम्बेडिंग स्टोर करें

आपके पास अपने कंप्यूटर से, टेक्स्ट एम्बेड करने जैसी वेक्टर वैल्यू बनाने का विकल्प होता है Cloud Firestore डेटा को सेव कर सकता है और उन्हें Cloud Firestore दस्तावेज़ों में सेव कर सकता है.

वेक्टर एम्बेडिंग के साथ ऑपरेशन लिखें

नीचे दिया उदाहरण दिखाता है कि किसी Cloud Firestore दस्तावेज़:

Python
from google.cloud import firestore
from google.cloud.firestore_v1.vector import Vector

firestore_client = firestore.Client()
collection = firestore_client.collection("coffee-beans")
doc = {
    "name": "Kahawa coffee beans",
    "description": "Information about the Kahawa coffee beans.",
    "embedding_field": Vector([1.0, 2.0, 3.0]),
}

collection.add(doc)
Node.js
import {
  Firestore,
  FieldValue,
} from "@google-cloud/firestore";

const db = new Firestore();
const coll = db.collection('coffee-beans');
await coll.add({
  name: "Kahawa coffee beans",
  description: "Information about the Kahawa coffee beans.",
  embedding_field: FieldValue.vector([1.0 , 2.0, 3.0])
});

Cloud फ़ंक्शन की मदद से वेक्टर एम्बेड करना कम करें

जब भी कोई दस्तावेज़ अपडेट किया जाता है, तब वेक्टर एम्बेड करने का हिसाब लगाने और उसे सेव करने के लिए या बनाई गई है, तो आप क्लाउड फ़ंक्शन सेट अप कर सकते हैं:

Python
@functions_framework.cloud_event
def store_embedding(cloud_event) -> None:
  """Triggers by a change to a Firestore document.
  """
  firestore_payload = firestore.DocumentEventData()
  payload = firestore_payload._pb.ParseFromString(cloud_event.data)

  collection_id, doc_id = from_payload(payload)
  # Call a function to calculate the embedding
  embedding = calculate_embedding(payload)
  # Update the document
  doc = firestore_client.collection(collection_id).document(doc_id)
  doc.set({"embedding_field": embedding}, merge=True)
Node.js
/**
 * A vector embedding will be computed from the
 * value of the `content` field. The vector value
 * will be stored in the `embedding` field. The
 * field names `content` and `embedding` are arbitrary
 * field names chosen for this example.
 */
async function storeEmbedding(event: FirestoreEvent<any>): Promise<void> {
  // Get the previous value of the document's `content` field.
  const previousDocumentSnapshot = event.data.before as QueryDocumentSnapshot;
  const previousContent = previousDocumentSnapshot.get("content");

  // Get the current value of the document's `content` field.
  const currentDocumentSnapshot = event.data.after as QueryDocumentSnapshot;
  const currentContent = currentDocumentSnapshot.get("content");

  // Don't update the embedding if the content field did not change
  if (previousContent === currentContent) {
    return;
  }

  // Call a function to calculate the embedding for the value
  // of the `content` field.
  const embeddingVector = calculateEmbedding(currentContent);

  // Update the `embedding` field on the document.
  await currentDocumentSnapshot.ref.update({
    embedding: embeddingVector,
  });
}

वेक्टर इंडेक्स बनाएं और मैनेज करें

वेक्टर एम्बेड करके आस-पास के नतीजे खोजने से पहले, आपको मिलता-जुलता इंडेक्स बनाना होगा. ये उदाहरण दिखाते हैं कि वेक्टर इंडेक्स बनाने और उन्हें मैनेज करने का तरीका जानें.

वेक्टर इंडेक्स बनाना

वेक्टर इंडेक्स बनाने से पहले, Google Cloud CLI के सबसे नए वर्शन में अपग्रेड करें:

gcloud components update

वेक्टर इंडेक्स बनाने के लिए, gcloud firestore indexes composite create का इस्तेमाल करें:

gcloud
gcloud firestore indexes composite create \
--collection-group=collection-group \
--query-scope=COLLECTION \
--field-config field-path=vector-field,vector-config='vector-configuration' \
--database=database-id

कहां:

  • collection-group, कलेक्शन ग्रुप का आईडी है.
  • vector-field उस फ़ील्ड का नाम है जिसमें वेक्टर एम्बेड करने की सुविधा होती है.
  • database-id, डेटाबेस का आईडी है.
  • vector-configuration में वेक्टर dimension और इंडेक्स टाइप शामिल होता है. dimension, 2048 तक का पूर्णांक होता है. इंडेक्स टाइप flat होना चाहिए. इंडेक्स कॉन्फ़िगरेशन को इस तरह फ़ॉर्मैट करें: {"dimension":"DIMENSION", "flat": "{}"}.

नीचे दिया गया उदाहरण एक कंपोज़िट इंडेक्स बनाता है, जिसमें vector-field फ़ील्ड के लिए वेक्टर इंडेक्स शामिल है और color फ़ील्ड के लिए बढ़ते क्रम वाला इंडेक्स. प्री-फ़िल्टर करने के लिए, इस तरह के इंडेक्स का इस्तेमाल किया जा सकता है डेटा को आस-पास के पड़ोसी की खोज से पहले.

gcloud
gcloud firestore indexes composite create \
--collection-group=collection-group \
--query-scope=COLLECTION \
--field-config=order=ASCENDING,field-path="color" \
--field-config field-path=vector-field,vector-config='{"dimension":"1024", "flat": "{}"}' \
--database=database-id

सभी सदिश इंडेक्स की सूची बनाएं

gcloud
gcloud firestore indexes composite list --database=database-id

database-id को डेटाबेस के आईडी से बदलें.

वेक्टर इंडेक्स मिटाना

gcloud
gcloud firestore indexes composite delete index-id --database=database-id

कहां:

  • index-id, मिटाए जाने वाले इंडेक्स का आईडी है. इंडेक्स आईडी को फिर से पाने के लिए, indexes composite list का इस्तेमाल करें.
  • database-id, डेटाबेस का आईडी है.

सदिश सूचकांक के बारे में बताना

gcloud
gcloud firestore indexes composite describe index-id --database=database-id

कहां:

  • index-id, इंडेक्स करने के लिए इस्तेमाल किया जाने वाला आईडी है. इसका इस्तेमाल करें या indexes composite list का इस्तेमाल करके इंडेक्स आईडी को फिर से पाएं.
  • database-id, डेटाबेस का आईडी है.

आस-पड़ोस की कोई क्वेरी करें

आप इसके निकटतम पड़ोसियों को खोजने के लिए समानता खोज कर सकते हैं वेक्टर एम्बेड करना. समानता खोजने के लिए वेक्टर इंडेक्स की ज़रूरत होती है. अगर इंडेक्स मौजूद नहीं है, तो Cloud Firestore उसे बनाने के लिए इंडेक्स का सुझाव देता है gcloud CLI का इस्तेमाल करके.

नीचे दिए गए उदाहरण में, क्वेरी वेक्टर के 10 सबसे नज़दीक मौजूद हैं.

Python
from google.cloud.firestore_v1.base_vector_query import DistanceMeasure
from google.cloud.firestore_v1.vector import Vector

collection = db.collection("coffee-beans")

# Requires a single-field vector index
vector_query = collection.find_nearest(
    vector_field="embedding_field",
    query_vector=Vector([3.0, 1.0, 2.0]),
    distance_measure=DistanceMeasure.EUCLIDEAN,
    limit=5,
)
Node.js
import {
  Firestore,
  FieldValue,
  VectorQuery,
  VectorQuerySnapshot,
} from "@google-cloud/firestore";

// Requires a single-field vector index
const vectorQuery: VectorQuery = coll.findNearest({
  vectorField: 'embedding_field',
  queryVector: [3.0, 1.0, 2.0],
  limit: 10,
  distanceMeasure: 'EUCLIDEAN'
});

const vectorQuerySnapshot: VectorQuerySnapshot = await vectorQuery.get();

वेक्टर डिस्टेंस

आस-पास की जगहों की क्वेरी में, वेक्टर की दूरी के लिए ये विकल्प इस्तेमाल किए जा सकते हैं:

  • EUCLIDEAN: वेक्टर के बीच EUCLIDEAN की दूरी मापता है. इस बारे में ज़्यादा जानने के लिए, यह देखें यूक्लिडीन.
  • COSINE: वेक्टर के बीच के ऐंगल के आधार पर उनकी तुलना करता है, ताकि आप वह समानता मापे जो वेक्टर की तीव्रता पर आधारित नहीं है. हमारा सुझाव है कि इसके बजाय DOT_PRODUCT को यूनिट नॉर्मलाइज़्ड वेक्टर के साथ इस्तेमाल करें COSINE की दूरी, जो गणितीय रूप से बेहतर परफ़ॉर्मेंस. ज़्यादा जानने के लिए देखें कोसाइन के बीच समानता सीखें वगैरह को कॉपी करने का विकल्प है.
  • DOT_PRODUCT: यह COSINE की तरह ही होता है, लेकिन इस पर असर पड़ता है वेक्टर. इस बारे में ज़्यादा जानने के लिए, यह देखें डॉट प्रॉडक्ट.

दूरी की माप चुनें

आपके सभी वेक्टर एम्बेडिंग नॉर्मलाइज़ किए गए हैं या नहीं, इसके आधार पर तय करें कि दूरी की माप का पता लगाने के लिए किस दूरी की माप का इस्तेमाल करना है. नॉर्मलाइज़ किया गया वेक्टर एम्बेडिंग का मैग्निट्यूड (लंबाई) 1.0 होता है.

इसके अलावा, अगर आपको यह पता हो कि दूरी को मापने के लिए आपके मॉडल को किस दूरी की मदद से ट्रेनिंग दी गई है, अपने सदिश (वेक्टर) के बीच की दूरी की गणना करने के लिए, उस दूरी की माप का इस्तेमाल करें एम्बेड करना.

नॉर्मलाइज़्ड डेटा

अगर आपके पास एक ऐसा डेटासेट है जिसमें सभी वेक्टर एम्बेडिंग नॉर्मलाइज़ की जाती हैं, तो सभी तीनों दूरी की मापों से एक जैसे खोज परिणाम मिलते हैं. कम शब्दों में कहें, तो हर दूरी की माप एक अलग मान दिखाती है, वे मान एक जैसे क्रम में लगाए जाते हैं. टास्क कब शुरू होगा एम्बेडिंग को नॉर्मलाइज़ किया जाता है. आम तौर पर, DOT_PRODUCT हैं, लेकिन ज़्यादातर मामलों में अंतर बहुत कम होता है. हालांकि, अगर आपके ऐप्लिकेशन प्रदर्शन के लिए बहुत ज़्यादा संवेदनशील है, DOT_PRODUCT से इसमें सहायता मिल सकती है परफ़ॉर्मेंस ट्यूनिंग.

ऐसा डेटा जो सामान्य नहीं है

अगर आपके पास कोई ऐसा डेटासेट है जिसमें वेक्टर एम्बेड करने की प्रोसेस नॉर्मलाइज़ की गई है, तो दूरी के रूप में DOT_PRODUCT का इस्तेमाल करना गणितीय रूप से सही नहीं है मापें, क्योंकि डॉट प्रॉडक्ट दूरी को नहीं मापता. निर्भर करता है एम्बेड करने की प्रोसेस कैसे जनरेट की गई थी और किस तरह की खोज को प्राथमिकता दी जाएगी, दूरी की माप COSINE या EUCLIDEAN में से किसी को भी बनाया जा सकता है खोज के ऐसे नतीजे जो दूरी की अन्य मापों से बेहतर हैं. COSINE या EUCLIDEAN के साथ प्रयोग करने पर यह आ सकता है होना ज़रूरी है.

पक्का नहीं पता कि डेटा नॉर्मलाइज़ किया हुआ है या नहीं

अगर आपको नहीं पता कि आपका डेटा नॉर्मलाइज़ किया गया है या नहीं और आपको DOT_PRODUCT, हमारा सुझाव है कि आप इसके बजाय COSINE का इस्तेमाल करें. COSINE, DOT_PRODUCT की तरह है, जिसमें नॉर्मलाइज़ेशन पहले से मौजूद होता है. COSINE का इस्तेमाल करके मापी गई दूरी, 0 से 2 तक है. एक नतीजा जो 0 के करीब है, यह बताता है कि वेक्टर बहुत मिलते-जुलते हैं.

दस्तावेज़ों को पहले से फ़िल्टर करना

आस-पास के लोगों को ढूंढने से पहले, दस्तावेज़ों को प्री-फ़िल्टर करने के लिए, अन्य क्वेरी ऑपरेटर के साथ समानता खोज. and और or कंपोज़िट फ़िल्टर का इस्तेमाल किया जा सकता है. काम करने वाले फ़ील्ड फ़िल्टर के बारे में ज़्यादा जानकारी के लिए, क्वेरी ऑपरेटर देखें.

Python
from google.cloud.firestore_v1.base_vector_query import DistanceMeasure
from google.cloud.firestore_v1.vector import Vector

collection = db.collection("coffee-beans")

# Similarity search with pre-filter
# Requires a composite vector index
vector_query = collection.where("color", "==", "red").find_nearest(
    vector_field="embedding_field",
    query_vector=Vector([3.0, 1.0, 2.0]),
    distance_measure=DistanceMeasure.EUCLIDEAN,
    limit=5,
)
Node.js
// Similarity search with pre-filter
// Requires composite vector index
const preFilteredVectorQuery: VectorQuery = coll
    .where("color", "==", "red")
    .findNearest({
      vectorField: "embedding_field",
      queryVector: [3.0, 1.0, 2.0],
      limit: 5,
      distanceMeasure: "EUCLIDEAN",
    });

const vectorQueryResults = await preFilteredVectorQuery.get();

परिकलित सदिश दूरी का पता लगाएं

वेक्टर की दूरी ज्ञात करने के लिए, FindNearest क्वेरी पर distance_result_field आउटपुट प्रॉपर्टी का नाम, इस तौर पर नीचे दिए गए उदाहरण में दिखाया गया है:

Python
from google.cloud.firestore_v1.base_vector_query import DistanceMeasure
from google.cloud.firestore_v1.vector import Vector

collection = db.collection("coffee-beans")

vector_query = collection.find_nearest(
    vector_field="embedding_field",
    query_vector=Vector([3.0, 1.0, 2.0]),
    distance_measure=DistanceMeasure.EUCLIDEAN,
    limit=10,
    distance_result_field="vector_distance",
)

docs = vector_query.stream()

for doc in docs:
    print(f"{doc.id}, Distance: {doc.get('vector_distance')}")
Node.js
const vectorQuery: VectorQuery = coll.findNearest(
    {
      vectorField: 'embedding_field',
      queryVector: [3.0, 1.0, 2.0],
      limit: 10,
      distanceMeasure: 'EUCLIDEAN',
      distanceResultField: 'vector_distance'
    });

const snapshot: VectorQuerySnapshot = await vectorQuery.get();

snapshot.forEach((doc) => {
  console.log(doc.id, ' Distance: ', doc.get('vector_distance'));
});

अगर आपको distanceResultField के साथ दस्तावेज़ फ़ील्ड का सबसेट दिखाने के लिए, फ़ील्ड मास्क का इस्तेमाल करना है, तो आपको फ़ील्ड मास्क में distanceResultField की वैल्यू भी शामिल करनी होगी, जैसा कि इस उदाहरण में दिखाया गया है:

Python
vector_query = collection.select(["color", "vector_distance"]).find_nearest(
    vector_field="embedding_field",
    query_vector=Vector([3.0, 1.0, 2.0]),
    distance_measure=DistanceMeasure.EUCLIDEAN,
    limit=10,
    distance_result_field="vector_distance",
)
Node.js
const vectorQuery: VectorQuery = coll
    .select('color', 'vector_distance')
    .findNearest({
      vectorField: 'embedding_field',
      queryVector: [3.0, 1.0, 2.0],
      limit: 10,
      distanceMeasure: 'EUCLIDEAN',
      distanceResultField: 'vector_distance'
    });

दूरी की सीमा तय करें

आप एक समान थ्रेशोल्ड तय कर सकते हैं, जो थ्रेशोल्ड. थ्रेशोल्ड फ़ील्ड का व्यवहार, दूरी की माप पर निर्भर करता है ये विकल्प चुने जा सकते हैं:

  • EUCLIDEAN और COSINE की दूरी, थ्रेशोल्ड को उन दस्तावेज़ों तक सीमित करती है जहां दूरी, तय किए गए थ्रेशोल्ड से कम या उसके बराबर है. यह दूरी सदिशों के एक जैसे होने से उनकी माप घटती जाती है.
  • DOT_PRODUCT की दूरी, थ्रेशोल्ड को उन दस्तावेज़ों तक सीमित करती है जिनमें दूरी है तय सीमा से ज़्यादा या उसके बराबर होना चाहिए. डॉट प्रॉडक्ट की दूरी जैसे-जैसे वेक्टर ज़्यादा एक जैसा होता जाता है.

इस उदाहरण में बताया गया है कि EUCLIDEAN की दूरी की मेट्रिक का इस्तेमाल करके, सबसे नज़दीकी 10 दस्तावेज़ दिखाने के लिए, दूरी की सीमा तय करने का तरीका क्या है. ये दस्तावेज़ ज़्यादा से ज़्यादा 4.5 यूनिट से दूर होते हैं:

Python
from google.cloud.firestore_v1.base_vector_query import DistanceMeasure
from google.cloud.firestore_v1.vector import Vector

collection = db.collection("coffee-beans")

vector_query = collection.find_nearest(
    vector_field="embedding_field",
    query_vector=Vector([3.0, 1.0, 2.0]),
    distance_measure=DistanceMeasure.EUCLIDEAN,
    limit=10,
    distance_threshold=4.5,
)

docs = vector_query.stream()

for doc in docs:
    print(f"{doc.id}")
Node.js
const vectorQuery: VectorQuery = coll.findNearest({
  vectorField: 'embedding_field',
  queryVector: [3.0, 1.0, 2.0],
  limit: 10,
  distanceMeasure: 'EUCLIDEAN',
  distanceThreshold: 4.5
});

const snapshot: VectorQuerySnapshot = await vectorQuery.get();

snapshot.forEach((doc) => {
  console.log(doc.id);
});

सीमाएं

वेक्टर एम्बेड करने की सुविधा का इस्तेमाल करते समय, इन सीमाओं का ध्यान रखें:

  • एम्बेड करने के लिए, ज़्यादा से ज़्यादा 2048 डाइमेंशन का इस्तेमाल किया जा सकता है. बड़े इंडेक्स सेव करने के लिए, डाइमेंशन में कमी.
  • निकटतम आस-पड़ोस की क्वेरी से दिए जाने वाले दस्तावेज़ों की अधिकतम संख्या 1000 है.
  • वेक्टर खोज रीयल-टाइम स्नैपशॉट लिसनर का समर्थन नहीं करती.
  • वेक्टर सर्च की सुविधा सिर्फ़ Python और Node.js क्लाइंट लाइब्रेरी पर काम करती है.

आगे क्या करना है