এই পৃষ্ঠাটি আপনাকে দেখায় কিভাবে Cloud Firestore ব্যবহার করে নিম্নলিখিত কৌশলগুলি ব্যবহার করে K-নিকটতম প্রতিবেশী (KNN) ভেক্টর অনুসন্ধান করতে হয়:
- ভেক্টর মান সংরক্ষণ করুন
- KNN ভেক্টর ইনডেক্স তৈরি এবং পরিচালনা করুন
- সমর্থিত ভেক্টর দূরত্ব পরিমাপের একটি ব্যবহার করে একটি K-নিকটতম-প্রতিবেশী (KNN) কোয়েরি তৈরি করুন।
শুরু করার আগে
Cloud Firestore এম্বেডিং সংরক্ষণ করার আগে, আপনাকে ভেক্টর এম্বেডিং তৈরি করতে হবে। Cloud Firestore এম্বেডিং তৈরি করে না। আপনি ভেক্টর মান তৈরি করতে Vertex AI এর মতো একটি পরিষেবা ব্যবহার করতে পারেন, উদাহরণস্বরূপ, আপনার Cloud Firestore ডেটা থেকে টেক্সট এম্বেডিং । এরপর আপনি এই এম্বেডিংগুলি Cloud Firestore ডকুমেন্টে আবার সংরক্ষণ করতে পারেন।
এম্বেডিং সম্পর্কে আরও জানতে, এম্বেডিং কী? দেখুন।
Vertex AI দিয়ে টেক্সট এম্বেডিং কীভাবে পাবেন তা জানতে, টেক্সট এম্বেডিং পান দেখুন।
ভেক্টর এম্বেডিং সংরক্ষণ করুন
নিম্নলিখিত উদাহরণগুলি Cloud Firestore ভেক্টর এম্বেডিং কীভাবে সংরক্ষণ করতে হয় তা প্রদর্শন করে।
ভেক্টর এম্বেডিং ব্যবহার করে লেখার অপারেশন
নিচের উদাহরণটি দেখায় কিভাবে একটি Cloud Firestore ডকুমেন্টে একটি ভেক্টর এম্বেডিং সংরক্ষণ করতে হয়:
পাইথন
নোড.জেএস
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]) });
যাও
জাভা
import com.google.cloud.firestore.CollectionReference; import com.google.cloud.firestore.DocumentReference; import com.google.cloud.firestore.FieldValue; import com.google.cloud.firestore.VectorQuery; CollectionReference coll = firestore.collection("coffee-beans"); Map<String, Object> docData = new HashMap<>(); docData.put("name", "Kahawa coffee beans"); docData.put("description", "Information about the Kahawa coffee beans."); docData.put("embedding_field", FieldValue.vector(new double[] {1.0, 2.0, 3.0})); ApiFuture<DocumentReference> future = coll.add(docData); DocumentReference documentReference = future.get();
ক্লাউড ফাংশন ব্যবহার করে ভেক্টর এম্বেডিং গণনা করুন
যখনই কোনও ডকুমেন্ট আপডেট বা তৈরি করা হয় তখন ভেক্টর এম্বেডিং গণনা এবং সংরক্ষণ করতে, আপনি একটি ক্লাউড ফাংশন সেট আপ করতে পারেন:
পাইথন
@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)
নোড.জেএস
/** * 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, }); }
যাও
// Not yet supported in the Go client library
জাভা
// Not yet supported in the Java client library
ভেক্টর ইনডেক্স তৈরি এবং পরিচালনা করুন
আপনার ভেক্টর এম্বেডিং ব্যবহার করে নিকটতম প্রতিবেশী অনুসন্ধান করার আগে, আপনাকে অবশ্যই একটি সংশ্লিষ্ট সূচক তৈরি করতে হবে। নিম্নলিখিত উদাহরণগুলি Google Cloud CLI ব্যবহার করে ভেক্টর সূচকগুলি কীভাবে তৈরি এবং পরিচালনা করতে হয় তা প্রদর্শন করে। Firebase CLI এবং Terraform ব্যবহার করেও ভেক্টর সূচকগুলি পরিচালনা করা যেতে পারে।
একটি ভেক্টর সূচক তৈরি করুন
ভেক্টর ইনডেক্স তৈরি করার আগে, Google Cloud CLI এর সর্বশেষ সংস্করণে আপগ্রেড করুন:
gcloud components update
একটি ভেক্টর সূচক তৈরি করতে, gcloud firestore indexes composite create ব্যবহার করুন:
জিক্লাউড
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২০৪৮ পর্যন্ত একটি পূর্ণসংখ্যা। ইনডেক্স টাইপটি অবশ্যইflatহতে হবে। ইনডেক্স কনফিগারেশনটি নিম্নরূপে ফর্ম্যাট করুন:{"dimension":" DIMENSION ", "flat": "{}"}.
নিচের উদাহরণটি একটি কম্পোজিট ইনডেক্স তৈরি করে, যার মধ্যে ফিল্ড vector-field জন্য একটি ভেক্টর ইনডেক্স এবং ফিল্ড color জন্য একটি আরোহী ইনডেক্স অন্তর্ভুক্ত থাকে। নিকটতম প্রতিবেশী অনুসন্ধানের আগে আপনি এই ধরণের ইনডেক্স ব্যবহার করে ডেটা প্রি-ফিল্টার করতে পারেন।
জিক্লাউড
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 firestore indexes composite list --database=database-id
database-id ডাটাবেসের আইডি দিয়ে প্রতিস্থাপন করুন।
একটি ভেক্টর সূচক মুছুন
জিক্লাউড
gcloud firestore indexes composite delete index-id --database=database-id
কোথায়:
- index-id হল মুছে ফেলার জন্য index এর ID। index ID পুনরুদ্ধার করতে
indexes composite listব্যবহার করুন। - database-id হলো ডাটাবেসের আইডি।
একটি ভেক্টর সূচক বর্ণনা কর।
জিক্লাউড
gcloud firestore indexes composite describe index-id --database=database-id
কোথায়:
- index-id হল সেই index এর ID যা বর্ণনা করতে হবে। index ID পুনরুদ্ধার করতে
indexes composite list। - database-id হলো ডাটাবেসের আইডি।
একটি নিকটতম-প্রতিবেশীর প্রশ্ন করুন
ভেক্টর এম্বেডিংয়ের নিকটতম প্রতিবেশী খুঁজে পেতে আপনি একটি সাদৃশ্য অনুসন্ধান করতে পারেন। সাদৃশ্য অনুসন্ধানের জন্য ভেক্টর ইনডেক্স প্রয়োজন। যদি কোনও সূচক বিদ্যমান না থাকে, তাহলে Cloud Firestore gcloud CLI ব্যবহার করে একটি সূচক তৈরি করার পরামর্শ দেয়।
নিম্নলিখিত উদাহরণটি কোয়েরি ভেক্টরের ১০টি নিকটতম প্রতিবেশী খুঁজে বের করে।
পাইথন
নোড.জেএস
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();
যাও
জাভা
import com.google.cloud.firestore.VectorQuery; import com.google.cloud.firestore.VectorQuerySnapshot; VectorQuery vectorQuery = coll.findNearest( "embedding_field", new double[] {3.0, 1.0, 2.0}, /* limit */ 10, VectorQuery.DistanceMeasure.EUCLIDEAN); ApiFuture<VectorQuerySnapshot> future = vectorQuery.get(); VectorQuerySnapshot vectorQuerySnapshot = future.get();
ভেক্টর দূরত্ব
নিকটতম-প্রতিবেশী প্রশ্নগুলি ভেক্টর দূরত্বের জন্য নিম্নলিখিত বিকল্পগুলিকে সমর্থন করে:
-
EUCLIDEAN: ভেক্টরগুলির মধ্যে EUCLIDEAN দূরত্ব পরিমাপ করে। আরও জানতে, ইউক্লিডীয় দেখুন। -
COSINE: ভেক্টরগুলির মধ্যে কোণের উপর ভিত্তি করে তুলনা করে যা আপনাকে ভেক্টরের মাত্রার উপর ভিত্তি করে নয় এমন সাদৃশ্য পরিমাপ করতে দেয়। আমরা COSINE দূরত্বের পরিবর্তে ইউনিট নরমালাইজড ভেক্টর সহDOT_PRODUCTব্যবহার করার পরামর্শ দিচ্ছি, যা গাণিতিকভাবে সমতুল্য এবং উন্নত কর্মক্ষমতা প্রদান করে। আরও জানতে কোসাইন সাদৃশ্য দেখুন। -
DOT_PRODUCT:COSINEএর অনুরূপ কিন্তু ভেক্টরের মান দ্বারা প্রভাবিত হয়। আরও জানতে, Dot পণ্য দেখুন।
দূরত্ব পরিমাপ নির্বাচন করুন
আপনার সমস্ত ভেক্টর এম্বেডিং স্বাভাবিক করা হয়েছে কিনা তার উপর নির্ভর করে, দূরত্ব পরিমাপ খুঁজে পেতে কোন দূরত্ব পরিমাপ ব্যবহার করবেন তা আপনি নির্ধারণ করতে পারেন। একটি স্বাভাবিক ভেক্টর এম্বেডিংয়ের মাত্রা (দৈর্ঘ্য) ঠিক 1.0।
এছাড়াও, যদি আপনি জানেন যে আপনার মডেলটি কোন দূরত্ব পরিমাপের সাথে প্রশিক্ষিত ছিল, তাহলে আপনার ভেক্টর এম্বেডিংয়ের মধ্যে দূরত্ব গণনা করতে সেই দূরত্ব পরিমাপটি ব্যবহার করুন।
স্বাভাবিক তথ্য
যদি আপনার এমন একটি ডেটাসেট থাকে যেখানে সমস্ত ভেক্টর এম্বেডিং স্বাভাবিক করা হয়, তাহলে তিনটি দূরত্ব পরিমাপ একই শব্দার্থিক অনুসন্ধান ফলাফল প্রদান করে। মূলত, যদিও প্রতিটি দূরত্ব পরিমাপ একটি ভিন্ন মান প্রদান করে, সেই মানগুলি একইভাবে সাজানো হয়। যখন এম্বেডিংগুলি স্বাভাবিক করা হয়, তখন DOT_PRODUCT সাধারণত গণনার দিক থেকে সবচেয়ে দক্ষ হয়, তবে বেশিরভাগ ক্ষেত্রেই পার্থক্যটি নগণ্য। তবে, যদি আপনার অ্যাপ্লিকেশনটি অত্যন্ত কর্মক্ষমতা সংবেদনশীল হয়, তাহলে DOT_PRODUCT কর্মক্ষমতা টিউনিংয়ে সাহায্য করতে পারে।
অ-স্বাভাবিক তথ্য
যদি আপনার এমন একটি ডেটাসেট থাকে যেখানে ভেক্টর এম্বেডিং স্বাভাবিক করা হয় না, তাহলে দূরত্ব পরিমাপ হিসেবে DOT_PRODUCT ব্যবহার করা গাণিতিকভাবে সঠিক নয় কারণ ডট পণ্য দূরত্ব পরিমাপ করে না। এম্বেডিংগুলি কীভাবে তৈরি করা হয়েছিল এবং কোন ধরণের অনুসন্ধান পছন্দ করা হয় তার উপর নির্ভর করে, COSINE বা EUCLIDEAN দূরত্ব পরিমাপ এমন অনুসন্ধান ফলাফল তৈরি করে যা অন্যান্য দূরত্ব পরিমাপের তুলনায় বিষয়গতভাবে ভাল। আপনার ব্যবহারের ক্ষেত্রে কোনটি সবচেয়ে ভালো তা নির্ধারণ করতে COSINE বা EUCLIDEAN সাথে পরীক্ষা-নিরীক্ষার প্রয়োজন হতে পারে।
ডেটা স্বাভাবিক করা হয়েছে নাকি স্বাভাবিক করা হয়নি তা নিশ্চিত নই
যদি আপনি নিশ্চিত না হন যে আপনার ডেটা স্বাভাবিক করা হয়েছে কিনা এবং আপনি DOT_PRODUCT ব্যবহার করতে চান, তাহলে আমরা আপনাকে COSINE ব্যবহার করার পরামর্শ দিচ্ছি। COSINE হল DOT_PRODUCT এর মতো যার স্বাভাবিককরণ অন্তর্নির্মিত। COSINE ব্যবহার করে পরিমাপ করা দূরত্ব 0 থেকে 2 পর্যন্ত। 0 এর কাছাকাছি ফলাফল নির্দেশ করে যে ভেক্টরগুলি খুব একই রকম।
ডকুমেন্টগুলি প্রি-ফিল্টার করুন
নিকটতম প্রতিবেশী খুঁজে বের করার আগে ডকুমেন্টগুলিকে প্রি-ফিল্টার করার জন্য, আপনি অন্যান্য কোয়েরি অপারেটরের সাথে একটি সাদৃশ্য অনুসন্ধান একত্রিত করতে পারেন। and এবং or কম্পোজিট ফিল্টারগুলি সমর্থিত। সমর্থিত ফিল্ড ফিল্টার সম্পর্কে আরও তথ্যের জন্য, কোয়েরি অপারেটরগুলি দেখুন।
পাইথন
নোড.জেএস
// 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();
যাও
জাভা
import com.google.cloud.firestore.VectorQuery; import com.google.cloud.firestore.VectorQuerySnapshot; VectorQuery preFilteredVectorQuery = coll .whereEqualTo("color", "red") .findNearest( "embedding_field", new double[] {3.0, 1.0, 2.0}, /* limit */ 10, VectorQuery.DistanceMeasure.EUCLIDEAN); ApiFuture<VectorQuerySnapshot> future = preFilteredVectorQuery.get(); VectorQuerySnapshot vectorQuerySnapshot = future.get();
গণনা করা ভেক্টর দূরত্ব পুনরুদ্ধার করুন
নিম্নলিখিত উদাহরণে দেখানো FindNearest কোয়েরিতে একটি distance_result_field আউটপুট প্রোপার্টি নাম বরাদ্দ করে আপনি গণনা করা ভেক্টর দূরত্ব পুনরুদ্ধার করতে পারেন:
পাইথন
নোড.জেএস
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')); });
যাও
জাভা
import com.google.cloud.firestore.VectorQuery; import com.google.cloud.firestore.VectorQueryOptions; import com.google.cloud.firestore.VectorQuerySnapshot; VectorQuery vectorQuery = coll.findNearest( "embedding_field", new double[] {3.0, 1.0, 2.0}, /* limit */ 10, VectorQuery.DistanceMeasure.EUCLIDEAN, VectorQueryOptions.newBuilder().setDistanceResultField("vector_distance").build()); ApiFuture<VectorQuerySnapshot> future = vectorQuery.get(); VectorQuerySnapshot vectorQuerySnapshot = future.get(); for (DocumentSnapshot document : vectorQuerySnapshot.getDocuments()) { System.out.println(document.getId() + " Distance: " + document.get("vector_distance")); }
যদি আপনি একটি ফিল্ড মাস্ক ব্যবহার করে একটি ডকুমেন্ট ফিল্ডের একটি উপসেট এবং একটি distanceResultField ফেরত দিতে চান, তাহলে আপনাকে অবশ্যই ফিল্ড মাস্কে distanceResultField এর মান অন্তর্ভুক্ত করতে হবে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
পাইথন
নোড.জেএস
const vectorQuery: VectorQuery = coll .select('name', 'description', 'vector_distance') .findNearest({ vectorField: 'embedding_field', queryVector: [3.0, 1.0, 2.0], limit: 10, distanceMeasure: 'EUCLIDEAN', distanceResultField: 'vector_distance' });
যাও
জাভা
import com.google.cloud.firestore.VectorQuery; import com.google.cloud.firestore.VectorQueryOptions; import com.google.cloud.firestore.VectorQuerySnapshot; VectorQuery vectorQuery = coll .select("name", "description", "vector_distance") .findNearest( "embedding_field", new double[] {3.0, 1.0, 2.0}, /* limit */ 10, VectorQuery.DistanceMeasure.EUCLIDEAN, VectorQueryOptions.newBuilder() .setDistanceResultField("vector_distance") .build()); ApiFuture<VectorQuerySnapshot> future = vectorQuery.get(); VectorQuerySnapshot vectorQuerySnapshot = future.get(); for (DocumentSnapshot document : vectorQuerySnapshot.getDocuments()) { System.out.println(document.getId() + " Distance: " + document.get("vector_distance")); }
দূরত্বের সীমা নির্দিষ্ট করুন
আপনি একটি সাদৃশ্য থ্রেশহোল্ড নির্দিষ্ট করতে পারেন যা শুধুমাত্র থ্রেশহোল্ডের মধ্যে থাকা নথিগুলি ফেরত দেয়। থ্রেশহোল্ড ক্ষেত্রের আচরণ আপনার চয়ন করা দূরত্ব পরিমাপের উপর নির্ভর করে:
-
EUCLIDEANএবংCOSINEদূরত্বগুলি সেই নথিগুলিতে থ্রেশহোল্ড সীমাবদ্ধ করে যেখানে দূরত্ব নির্দিষ্ট থ্রেশহোল্ডের চেয়ে কম বা সমান। ভেক্টরগুলি আরও অনুরূপ হওয়ার সাথে সাথে এই দূরত্বের পরিমাপ হ্রাস পায়। -
DOT_PRODUCTদূরত্ব সেই ডকুমেন্টগুলিতে থ্রেশহোল্ড সীমাবদ্ধ করে যেখানে দূরত্ব নির্দিষ্ট থ্রেশহোল্ডের চেয়ে বেশি বা সমান। ভেক্টরগুলি আরও অনুরূপ হওয়ার সাথে সাথে ডট পণ্যের দূরত্ব বৃদ্ধি পায়।
নিম্নলিখিত উদাহরণে EUCLIDEAN দূরত্ব মেট্রিক ব্যবহার করে সর্বাধিক ৪.৫ ইউনিট দূরে থাকা ১০টি নিকটতম নথি ফেরত দেওয়ার জন্য একটি দূরত্বের থ্রেশহোল্ড কীভাবে নির্দিষ্ট করতে হয় তা দেখানো হয়েছে:
পাইথন
নোড.জেএস
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); });
যাও
জাভা
import com.google.cloud.firestore.VectorQuery; import com.google.cloud.firestore.VectorQueryOptions; import com.google.cloud.firestore.VectorQuerySnapshot; VectorQuery vectorQuery = coll.findNearest( "embedding_field", new double[] {3.0, 1.0, 2.0}, /* limit */ 10, VectorQuery.DistanceMeasure.EUCLIDEAN, VectorQueryOptions.newBuilder() .setDistanceThreshold(4.5) .build()); ApiFuture<VectorQuerySnapshot> future = vectorQuery.get(); VectorQuerySnapshot vectorQuerySnapshot = future.get(); for (DocumentSnapshot document : vectorQuerySnapshot.getDocuments()) { System.out.println(document.getId()); }
সীমাবদ্ধতা
ভেক্টর এম্বেডিং নিয়ে কাজ করার সময়, নিম্নলিখিত সীমাবদ্ধতাগুলি লক্ষ্য করুন:
- সর্বাধিক সমর্থিত এম্বেডিং ডাইমেনশন হল 2048। বৃহত্তর সূচক সংরক্ষণ করতে, ডাইমেনশন্যালিটি রিডাকশন ব্যবহার করুন।
- নিকটতম-প্রতিবেশীর জিজ্ঞাসা থেকে সর্বাধিক ১০০০টি নথি ফেরত পাঠানো যেতে পারে।
- ভেক্টর অনুসন্ধান রিয়েল-টাইম স্ন্যাপশট শ্রোতাদের সমর্থন করে না।
- শুধুমাত্র Python, Node.js, Go, এবং Java ক্লায়েন্ট লাইব্রেরিগুলি ভেক্টর অনুসন্ধান সমর্থন করে।
এরপর কি?
- Cloud Firestore জন্য সেরা অনুশীলন সম্পর্কে পড়ুন।
- স্কেলে পড়া এবং লেখা বুঝুন।