1. ভূমিকা
এই কোডল্যাবে, আপনি একটি অ্যাপ্লিকেশন তৈরি করবেন যা যোগা ভঙ্গি সুপারিশ করতে ভেক্টর অনুসন্ধান ব্যবহার করে।
কোডল্যাবের মাধ্যমে, আপনি নিম্নলিখিত হিসাবে একটি ধাপে ধাপে পদ্ধতি ব্যবহার করবেন:
- যোগা ভঙ্গি (JSON ফর্ম্যাট) এর একটি বিদ্যমান আলিঙ্গন মুখ ডেটাসেট ব্যবহার করুন।
- একটি অতিরিক্ত ক্ষেত্রের বিবরণ সহ ডেটাসেট উন্নত করুন যা প্রতিটি ভঙ্গির জন্য বর্ণনা তৈরি করতে জেমিনি ব্যবহার করে।
- উত্পন্ন এমবেডিং সহ Firestore সংগ্রহে নথির সংগ্রহ হিসাবে যোগা পোজ ডেটা লোড করুন৷
- ভেক্টর অনুসন্ধানের জন্য Firestore-এ একটি যৌগিক সূচক তৈরি করুন।
- একটি Node.js অ্যাপ্লিকেশনে ভেক্টর অনুসন্ধান ব্যবহার করুন যা নীচে দেখানো হিসাবে সবকিছুকে একত্রিত করে:
আপনি কি করবেন
- যোগা ভঙ্গি সুপারিশ করার জন্য ভেক্টর অনুসন্ধান নিয়োগ করে এমন একটি ওয়েব অ্যাপ্লিকেশন ডিজাইন, তৈরি এবং স্থাপন করুন।
আপনি কি শিখবেন
- টেক্সট বিষয়বস্তু তৈরি করতে এবং এই কোডল্যাবের প্রেক্ষাপটে যোগব্যায়াম ভঙ্গির জন্য বর্ণনা তৈরি করতে কীভাবে জেমিনি ব্যবহার করবেন
- হাগিং ফেস থেকে ফায়ারস্টোরে ভেক্টর এমবেডিং সহ একটি উন্নত ডেটাসেট থেকে রেকর্ডগুলি কীভাবে লোড করবেন
- একটি প্রাকৃতিক ভাষার প্রশ্নের উপর ভিত্তি করে ডেটা অনুসন্ধান করতে Firestore ভেক্টর অনুসন্ধান কীভাবে ব্যবহার করবেন
- অডিও সামগ্রী তৈরি করতে Google ক্লাউড টেক্সট টু স্পিচ API কীভাবে ব্যবহার করবেন
আপনি কি প্রয়োজন হবে
- ক্রোম ওয়েব ব্রাউজার
- একটি জিমেইল অ্যাকাউন্ট
- বিলিং সক্ষম সহ একটি ক্লাউড প্রকল্প৷
এই কোডল্যাব, সমস্ত স্তরের বিকাশকারীদের জন্য ডিজাইন করা হয়েছে (শিশুদের সহ), এটির নমুনা অ্যাপ্লিকেশনটিতে JavaScript এবং Node.js ব্যবহার করে। যাইহোক, উপস্থাপিত ধারণা বোঝার জন্য JavaScript এবং Node.js জ্ঞানের প্রয়োজন নেই।
2. আপনি শুরু করার আগে
একটি প্রকল্প তৈরি করুন
- Google ক্লাউড কনসোলে , প্রকল্প নির্বাচক পৃষ্ঠায়, একটি Google ক্লাউড প্রকল্প নির্বাচন করুন বা তৈরি করুন।
- নিশ্চিত করুন যে আপনার ক্লাউড প্রকল্পের জন্য বিলিং সক্ষম করা আছে৷ একটি প্রকল্পে বিলিং সক্ষম কিনা তা পরীক্ষা করতে শিখুন।
- আপনি ক্লাউড শেল ব্যবহার করবেন, Google ক্লাউডে চলমান একটি কমান্ড-লাইন পরিবেশ যা bq এর সাথে প্রিলোড করা হয়। গুগল ক্লাউড কনসোলের শীর্ষে সক্রিয় ক্লাউড শেল ক্লিক করুন।
- একবার ক্লাউড শেলের সাথে সংযুক্ত হয়ে গেলে, আপনি পরীক্ষা করে দেখুন যে আপনি ইতিমধ্যেই প্রমাণীকৃত হয়েছেন এবং নিম্নলিখিত কমান্ডটি ব্যবহার করে প্রকল্পটি আপনার প্রকল্প আইডিতে সেট করা আছে:
gcloud auth list
- gcloud কমান্ড আপনার প্রকল্প সম্পর্কে জানে তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান।
gcloud config list project
- যদি আপনার প্রজেক্ট সেট করা না থাকে, তাহলে এটি সেট করতে নিম্নলিখিত কমান্ডটি ব্যবহার করুন:
gcloud config set project <YOUR_PROJECT_ID>
- নীচে দেখানো কমান্ডের মাধ্যমে প্রয়োজনীয় API গুলি সক্ষম করুন৷ এটি কয়েক মিনিট সময় নিতে পারে, তাই ধৈর্য ধরুন।
gcloud services enable firestore.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
cloudfunctions.googleapis.com \
aiplatform.googleapis.com \
texttospeech.googleapis.com
কমান্ডের সফল সঞ্চালন হলে, আপনি নীচের দেখানো একটি অনুরূপ একটি বার্তা দেখতে হবে:
Operation "operations/..." finished successfully.
gcloud কমান্ডের বিকল্প হল কনসোলের মাধ্যমে প্রতিটি পণ্য অনুসন্ধান করে বা এই লিঙ্কটি ব্যবহার করে।
যদি কোনো API মিস হয়, আপনি সর্বদা বাস্তবায়নের সময় এটি সক্রিয় করতে পারেন।
জিক্লাউড কমান্ড এবং ব্যবহারের জন্য ডকুমেন্টেশন পড়ুন।
ক্লোন সংগ্রহস্থল এবং সেটআপ পরিবেশ সেটিংস
পরবর্তী ধাপ হল নমুনা সংগ্রহস্থল ক্লোন করা যা আমরা কোডল্যাবের বাকি অংশে উল্লেখ করব। ধরে নিই যে আপনি ক্লাউড শেলে আছেন, আপনার হোম ডিরেক্টরি থেকে নিম্নলিখিত কমান্ড দিন:
git clone https://github.com/rominirani/yoga-poses-recommender-nodejs
সম্পাদক চালু করতে, ক্লাউড শেল উইন্ডোর টুলবারে সম্পাদক খুলুন ক্লিক করুন। উপরের বাম কোণে মেনু বারে ক্লিক করুন এবং নীচে দেখানো হিসাবে ফাইল → ফোল্ডার খুলুন নির্বাচন করুন:
yoga-poses-recommender-nodejs
ফোল্ডারটি নির্বাচন করুন এবং আপনি নীচের চিত্রের মতো নিম্নলিখিত ফাইলগুলির সাথে ফোল্ডারটি খোলা দেখতে পাবেন:
আমাদের এখন পরিবেশের ভেরিয়েবল সেট আপ করতে হবে যা আমরা ব্যবহার করব। env-template
ফাইলটিতে ক্লিক করুন এবং নিচের মত বিষয়বস্তু দেখতে পাবেন:
PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
LOCATION=us-<GOOGLE_CLOUD_REGION_NAME>
GEMINI_MODEL_NAME=<GEMINI_MODEL_NAME>
EMBEDDING_MODEL_NAME=<GEMINI_EMBEDDING_MODEL_NAME>
IMAGE_GENERATION_MODEL_NAME=<IMAGEN_MODEL_NAME>
DATABASE=<FIRESTORE_DATABASE_NAME>
COLLECTION=<FIRESTORE_COLLECTION_NAME>
TEST_COLLECTION=test-poses
TOP_K=3
Google ক্লাউড প্রজেক্ট এবং ফায়ারস্টোর ডেটাবেস অঞ্চল তৈরি করার সময় আপনি যা নির্বাচন করেছেন সেই অনুযায়ী অনুগ্রহ করে PROJECT_ID
এবং LOCATION
এর মানগুলি আপডেট করুন৷ আদর্শভাবে, আমরা Google ক্লাউড প্রকল্প এবং ফায়ারস্টোর ডেটাবেসের জন্য LOCATION
এর মান একই হতে চাই, যেমন us-central1
।
এই কোডল্যাবের উদ্দেশ্যে, আমরা নিম্নলিখিত মানগুলির সাথে যেতে যাচ্ছি (অবশ্যই PROJECT_ID
এবং LOCATION
ব্যতীত, যা আপনাকে আপনার কনফিগারেশন অনুযায়ী সেট করতে হবে৷
PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
LOCATION=us-<GOOGLE_CLOUD_REGION_NAME>
GEMINI_MODEL_NAME=gemini-1.5-flash-002
EMBEDDING_MODEL_NAME=text-embedding-004
IMAGE_GENERATION_MODEL_NAME=imagen-3.0-fast-generate-001
DATABASE=(default)
COLLECTION=poses
TEST_COLLECTION=test-poses
TOP_K=3
অনুগ্রহ করে এই ফাইলটিকে env-template
ফাইলের মতো একই ফোল্ডারে .env
হিসাবে সংরক্ষণ করুন৷
ক্লাউড শেল আইডিই-তে উপরের বামদিকে প্রধান মেনুতে যান এবং তারপরে Terminal → New Terminal
।
আপনি নিম্নলিখিত কমান্ডের মাধ্যমে ক্লোন করা সংগ্রহস্থলের রুট ফোল্ডারে নেভিগেট করুন:
cd yoga-poses-recommender-nodejs
কমান্ডের মাধ্যমে Node.js নির্ভরতা ইনস্টল করুন:
npm install
দারুণ! আমরা এখন Firestore ডাটাবেস সেট আপ করার কাজে এগিয়ে যাওয়ার জন্য প্রস্তুত।
3. ফায়ারস্টোর সেটআপ করুন
ক্লাউড ফায়ারস্টোর হল একটি সম্পূর্ণ-পরিচালিত সার্ভারহীন ডকুমেন্ট ডাটাবেস যা আমরা আমাদের অ্যাপ্লিকেশন ডেটার জন্য ব্যাকএন্ড হিসাবে ব্যবহার করব। ক্লাউড ফায়ারস্টোরের ডেটা নথির সংগ্রহে গঠন করা হয়।
ফায়ারস্টোর ডাটাবেস আরম্ভ
ক্লাউড কনসোলে Firestore পৃষ্ঠায় যান।
আপনি যদি প্রজেক্টে আগে ফায়ারস্টোর ডাটাবেস চালু না করে থাকেন, তাহলে Create Database
-এ ক্লিক করে default
ডাটাবেস তৈরি করুন। ডাটাবেস তৈরি করার সময়, নিম্নলিখিত মানগুলির সাথে যান:
- ফায়ারস্টোর মোড:
Native.
- অবস্থান: ডিফল্ট অবস্থান সেটিংস দিয়ে যান।
- নিরাপত্তা বিধিগুলির জন্য,
Test rules
সাথে যান৷ - ডাটাবেস তৈরি করুন।
পরবর্তী বিভাগে, আমরা আমাদের ডিফল্ট ফায়ারস্টোর ডাটাবেসে poses
নামে একটি সংগ্রহ তৈরি করার ভিত্তি স্থাপন করব। এই সংগ্রহে নমুনা ডেটা (ডকুমেন্ট) বা যোগ পোজ তথ্য থাকবে, যা আমরা আমাদের অ্যাপ্লিকেশনে ব্যবহার করব।
এটি ফায়ারস্টোর ডাটাবেস সেট আপ করার জন্য বিভাগটি সম্পূর্ণ করে।
4. যোগা পোজ ডেটাসেট প্রস্তুত করুন
আমাদের প্রথম কাজ হল যোগা পোজ ডেটাসেট প্রস্তুত করা যা আমরা অ্যাপ্লিকেশনের জন্য ব্যবহার করব। আমরা একটি বিদ্যমান হাগিং ফেস ডেটাসেট দিয়ে শুরু করব এবং তারপরে অতিরিক্ত তথ্য দিয়ে এটিকে উন্নত করব।
যোগা ভঙ্গির জন্য আলিঙ্গন করা মুখের ডেটাসেটটি দেখুন। মনে রাখবেন যে এই কোডল্যাবটি যখন ডেটাসেটগুলির একটি ব্যবহার করে, আপনি আসলে অন্য কোনও ডেটাসেট ব্যবহার করতে পারেন এবং ডেটাসেট উন্নত করতে প্রদর্শিত একই কৌশলগুলি অনুসরণ করতে পারেন৷
আমরা যদি Files and versions
বিভাগে যাই, আমরা সমস্ত ভঙ্গির জন্য JSON ডেটা ফাইল পেতে পারি।
আমরা yoga_poses.json
ডাউনলোড করেছি এবং সেই ফাইলটি আপনাকে প্রদান করেছি। এই ফাইলটির নাম yoga_poses_alldata.json
এবং এটি /data
ফোল্ডারে রয়েছে।
ক্লাউড শেল এডিটরে data/yoga_poses.json
ফাইলটিতে যান এবং JSON অবজেক্টের তালিকাটি দেখুন, যেখানে প্রতিটি JSON অবজেক্ট একটি যোগ পোজ উপস্থাপন করে। আমাদের মোট 3টি রেকর্ড রয়েছে এবং একটি নমুনা রেকর্ড নীচে দেখানো হয়েছে:
{
"name": "Big Toe Pose",
"sanskrit_name": "Padangusthasana",
"photo_url": "https://pocketyoga.com/assets/images/full/ForwardBendBigToe.png",
"expertise_level": "Beginner",
"pose_type": ["Standing", "Forward Bend"]
}
মিথুনের সাথে পরিচয় করিয়ে দেওয়ার এবং কীভাবে আমরা এটির জন্য একটি description
ক্ষেত্র তৈরি করতে ডিফল্ট মডেলটি ব্যবহার করতে পারি তা এখন আমাদের জন্য একটি দুর্দান্ত সুযোগ।
ক্লাউড শেল এডিটরে, generate-descriptions.js
ফাইলে যান। এই ফাইলের বিষয়বস্তু নীচে দেখানো হয়েছে:
import { VertexAI } from "@langchain/google-vertexai";
import fs from 'fs/promises'; // Use fs/promises for async file operations
import dotenv from 'dotenv';
import pRetry from 'p-retry';
import { promisify } from 'util';
const sleep = promisify(setTimeout);
// Load environment variables
dotenv.config();
async function callGemini(poseName, sanskritName, expertiseLevel, poseTypes) {
const prompt = `
Generate a concise description (max 50 words) for the yoga pose: ${poseName}
Also known as: ${sanskritName}
Expertise Level: ${expertiseLevel}
Pose Type: ${poseTypes.join(', ')}
Include key benefits and any important alignment cues.
`;
try {
// Initialize Vertex AI Gemini model
const model = new VertexAI({
model: process.env.GEMINI_MODEL_NAME,
location: process.env.LOCATION,
project: process.env.PROJECT_ID,
});
// Invoke the model
const response = await model.invoke(prompt);
// Return the response
return response;
} catch (error) {
console.error("Error calling Gemini:", error);
throw error; // Re-throw the error for handling in the calling function
}
}
// Configure logging (you can use a library like 'winston' for more advanced logging)
const logger = {
info: (message) => console.log(`INFO - ${new Date().toISOString()} - ${message}`),
error: (message) => console.error(`ERROR - ${new Date().toISOString()} - ${message}`),
};
async function generateDescription(poseName, sanskritName, expertiseLevel, poseTypes) {
const prompt = `
Generate a concise description (max 50 words) for the yoga pose: ${poseName}
Also known as: ${sanskritName}
Expertise Level: ${expertiseLevel}
Pose Type: ${poseTypes.join(', ')}
Include key benefits and any important alignment cues.
`;
const req = {
contents: [{ role: 'user', parts: [{ text: prompt }] }],
};
const runWithRetry = async () => {
const resp = await generativeModel.generateContent(req);
const response = await resp.response;
const text = response.candidates[0].content.parts[0].text;
return text;
};
try {
const text = await pRetry(runWithRetry, {
retries: 5,
onFailedAttempt: (error) => {
logger.info(
`Attempt ${error.attemptNumber} failed. There are ${error.retriesLeft} retries left. Waiting ${error.retryDelay}ms...`
);
},
minTimeout: 4000, // 4 seconds (exponential backoff will adjust this)
factor: 2, // Exponential factor
});
return text;
} catch (error) {
logger.error(`Error generating description for ${poseName}: ${error}`);
return '';
}
}
async function addDescriptionsToJSON(inputFile, outputFile) {
try {
const data = await fs.readFile(inputFile, 'utf-8');
const yogaPoses = JSON.parse(data);
const totalPoses = yogaPoses.length;
let processedCount = 0;
for (const pose of yogaPoses) {
if (pose.name !== ' Pose') {
const startTime = Date.now();
pose.description = await callGemini(
pose.name,
pose.sanskrit_name,
pose.expertise_level,
pose.pose_type
);
const endTime = Date.now();
const timeTaken = (endTime - startTime) / 1000;
processedCount++;
logger.info(`Processed: ${processedCount}/${totalPoses} - ${pose.name} (${timeTaken.toFixed(2)} seconds)`);
} else {
pose.description = '';
processedCount++;
logger.info(`Processed: ${processedCount}/${totalPoses} - ${pose.name} (${timeTaken.toFixed(2)} seconds)`);
}
// Add a delay to avoid rate limit
await sleep(30000); // 30 seconds
}
await fs.writeFile(outputFile, JSON.stringify(yogaPoses, null, 2));
logger.info(`Descriptions added and saved to ${outputFile}`);
} catch (error) {
logger.error(`Error processing JSON file: ${error}`);
}
}
async function main() {
const inputFile = './data/yoga_poses.json';
const outputFile = './data/yoga_poses_with_descriptions.json';
await addDescriptionsToJSON(inputFile, outputFile);
}
main();
এই অ্যাপ্লিকেশনটি প্রতিটি যোগা পোজ JSON রেকর্ডে একটি নতুন description
ক্ষেত্র যোগ করবে। এটি মিথুন মডেলের কাছে একটি কলের মাধ্যমে বিবরণটি পাবে, যেখানে আমরা এটিকে প্রয়োজনীয় প্রম্পট প্রদান করব। ক্ষেত্রটি JSON ফাইলে যোগ করা হয় এবং নতুন ফাইলটি data/yoga_poses_with_descriptions.json
ফাইলে লেখা হয়।
চলুন প্রধান পদক্ষেপের মাধ্যমে যান:
-
main()
ফাংশনে, আপনি দেখতে পাবেন যে এটিadd_descriptions_to_json
ফাংশনকে আহ্বান করে এবং ইনপুট ফাইল এবং প্রত্যাশিত আউটপুট ফাইল সরবরাহ করে। -
add_descriptions_to_json
ফাংশন প্রতিটি JSON রেকর্ডের জন্য নিম্নলিখিত কাজ করে যেমন যোগ পোস্ট তথ্য: - এটি
pose_name
,sanskrit_name
,expertise_level
এবংpose_types
বের করে। - এটি
callGemini
ফাংশনকে আহ্বান করে যা একটি প্রম্পট তৈরি করে এবং তারপরে প্রতিক্রিয়া পাঠ্য পেতে LangchainVertexAI মডেল ক্লাসকে আহ্বান করে। - এই প্রতিক্রিয়া পাঠ্য তারপর JSON অবজেক্ট যোগ করা হয়.
- অবজেক্টের আপডেট করা JSON তালিকা তারপর গন্তব্য ফাইলে লেখা হয়।
আমাদের এই অ্যাপ্লিকেশন চালানো যাক. একটি নতুন টার্মিনাল উইন্ডো চালু করুন (Ctrl+Shift+C) এবং নিম্নলিখিত কমান্ড দিন:
npm run generate-descriptions
যদি আপনাকে কোনো অনুমোদনের জন্য বলা হয়, অনুগ্রহ করে এগিয়ে যান এবং সেটি প্রদান করুন।
আপনি দেখতে পাবেন যে অ্যাপ্লিকেশনটি কার্যকর করা শুরু হয়েছে। নতুন Google ক্লাউড অ্যাকাউন্টে যেকোন হারের সীমা কোটা এড়াতে আমরা রেকর্ডগুলির মধ্যে 30 সেকেন্ডের বিলম্ব যোগ করেছি, তাই অনুগ্রহ করে ধৈর্য ধরুন।
চলমান একটি নমুনা নীচে দেখানো হয়েছে:
একবার জেমিনি কলের সাথে 3টি রেকর্ডের সবকটি উন্নত হয়ে গেলে, একটি ফাইল data/yoga_poses_with_description.json
তৈরি করা হবে। আপনি যে কটাক্ষপাত করতে পারেন.
আমরা এখন আমাদের ডেটা ফাইলের সাথে প্রস্তুত এবং পরবর্তী পদক্ষেপটি হল এম্বেডিং জেনারেশনের সাথে একটি ফায়ারস্টোর ডেটাবেস কীভাবে পপুলেট করা যায় তা বোঝা।
5. ফায়ারস্টোরে ডেটা আমদানি করুন এবং ভেক্টর এমবেডিং তৈরি করুন
আমাদের কাছে data/yoga_poses_with_description.json
ফাইল আছে এবং এখন এটির সাথে Firestore ডেটাবেস তৈরি করতে হবে এবং গুরুত্বপূর্ণভাবে, প্রতিটি রেকর্ডের জন্য ভেক্টর এমবেডিং তৈরি করতে হবে। ভেক্টর এমবেডিংগুলি পরবর্তীতে কাজে লাগবে যখন আমাদের প্রাকৃতিক ভাষায় দেওয়া ব্যবহারকারীর প্রশ্নের সাথে তাদের একটি মিল অনুসন্ধান করতে হবে।
এটি করার পদক্ষেপগুলি নিম্নরূপ হবে:
- আমরা JSON অবজেক্টের তালিকাকে অবজেক্টের তালিকায় রূপান্তর করব। প্রতিটি নথিতে দুটি বৈশিষ্ট্য থাকবে:
content
এবংmetadata
। মেটাডেটা অবজেক্টে পুরো JSON অবজেক্ট থাকবে যার মধ্যেname
,description
,sanskrit_name
, ইত্যাদির মতো বৈশিষ্ট্য রয়েছে৷content
একটি স্ট্রিং পাঠ্য হবে যা কয়েকটি ক্ষেত্রের সংমিশ্রণ হবে৷ - একবার আমাদের কাছে নথিগুলির একটি তালিকা হয়ে গেলে, আমরা বিষয়বস্তু ক্ষেত্রের জন্য এম্বেডিং তৈরি করতে Vertex AI এম্বেডিং ক্লাস ব্যবহার করব। এই এমবেডিংটি প্রতিটি নথির রেকর্ডে যোগ করা হবে এবং তারপর আমরা সংগ্রহে নথি বস্তুর এই তালিকাটি সংরক্ষণ করতে Firestore API ব্যবহার করব (আমরা
TEST_COLLECTION
ভেরিয়েবল ব্যবহার করছি যাtest-poses
তে নির্দেশ করে)।
import-data.js
এর কোড নিচে দেওয়া হল (কোডের অংশগুলি সংক্ষিপ্ততার জন্য কেটে দেওয়া হয়েছে):
import { Firestore,
FieldValue,
} from '@google-cloud/firestore';
import { VertexAIEmbeddings } from "@langchain/google-vertexai";
import * as dotenv from 'dotenv';
import fs from 'fs/promises';
// Load environment variables
dotenv.config();
// Configure logging
const logger = {
info: (message) => console.log(`INFO - ${new Date().toISOString()} - ${message}`),
error: (message) => console.error(`ERROR - ${new Date().toISOString()} - ${message}`),
};
async function loadYogaPosesDataFromLocalFile(filename) {
try {
const data = await fs.readFile(filename, 'utf-8');
const poses = JSON.parse(data);
logger.info(`Loaded ${poses.length} poses.`);
return poses;
} catch (error) {
logger.error(`Error loading dataset: ${error}`);
return null;
}
}
function createFirestoreDocuments(poses) {
const documents = [];
for (const pose of poses) {
// Convert the pose to a string representation for pageContent
const pageContent = `
name: ${pose.name || ''}
description: ${pose.description || ''}
sanskrit_name: ${pose.sanskrit_name || ''}
expertise_level: ${pose.expertise_level || 'N/A'}
pose_type: ${pose.pose_type || 'N/A'}
`.trim();
// The metadata will be the whole pose
const metadata = pose;
documents.push({ pageContent, metadata });
}
logger.info(`Created ${documents.length} Langchain documents.`);
return documents;
}
async function main() {
const allPoses = await loadYogaPosesDataFromLocalFile('./data/yoga_poses_with_descriptions.json');
const documents = createFirestoreDocuments(allPoses);
logger.info(`Successfully created Firestore documents. Total documents: ${documents.length}`);
const embeddings = new VertexAIEmbeddings({
model: process.env.EMBEDDING_MODEL_NAME,
});
// Initialize Firestore
const firestore = new Firestore({
projectId: process.env.PROJECT_ID,
databaseId: process.env.DATABASE,
});
const collectionName = process.env.TEST_COLLECTION;
for (const doc of documents) {
try {
// 1. Generate Embeddings
const singleVector = await embeddings.embedQuery(doc.pageContent);
// 2. Store in Firestore with Embeddings
const firestoreDoc = {
content: doc.pageContent,
metadata: doc.metadata, // Store the original data as metadata
embedding: FieldValue.vector(singleVector), // Add the embedding vector
};
const docRef = firestore.collection(collectionName).doc();
await docRef.set(firestoreDoc);
logger.info(`Document ${docRef.id} added to Firestore with embedding.`);
} catch (error) {
logger.error(`Error processing document: ${error}`);
}
}
logger.info('Finished adding documents to Firestore.');
}
main();
আমাদের এই অ্যাপ্লিকেশন চালানো যাক. একটি নতুন টার্মিনাল উইন্ডো চালু করুন (Ctrl+Shift+C) এবং নিম্নলিখিত কমান্ড দিন:
npm run import-data
সবকিছু ঠিকঠাক থাকলে, আপনি নীচের মত একটি বার্তা দেখতে পাবেন:
INFO - 2025-01-28T07:01:14.463Z - Loaded 3 poses.
INFO - 2025-01-28T07:01:14.464Z - Created 3 Langchain documents.
INFO - 2025-01-28T07:01:14.464Z - Successfully created Firestore documents. Total documents: 3
INFO - 2025-01-28T07:01:17.623Z - Document P46d5F92z9FsIhVVYgkd added to Firestore with embedding.
INFO - 2025-01-28T07:01:18.265Z - Document bjXXISctkXl2ZRSjUYVR added to Firestore with embedding.
INFO - 2025-01-28T07:01:19.285Z - Document GwzZMZyPfTLtiX6qBFFz added to Firestore with embedding.
INFO - 2025-01-28T07:01:19.286Z - Finished adding documents to Firestore.
রেকর্ডগুলি সফলভাবে ঢোকানো হয়েছে এবং এমবেডিংগুলি তৈরি হয়েছে কিনা তা পরীক্ষা করতে, ক্লাউড কনসোলে ফায়ারস্টোর পৃষ্ঠায় যান৷
(ডিফল্ট) ডাটাবেসে ক্লিক করুন, এটি সেই সংগ্রহের অধীনে test-poses
সংগ্রহ এবং একাধিক নথি প্রদর্শন করবে। প্রতিটি নথি একটি যোগ ভঙ্গি.
ক্ষেত্রগুলি তদন্ত করতে যেকোন নথিতে ক্লিক করুন। আমরা যে ক্ষেত্রগুলি আমদানি করেছি তা ছাড়াও, আপনি embedding
ক্ষেত্রটিও পাবেন, যা একটি ভেক্টর ক্ষেত্র, যার মান আমরা text-embedding-004
ভার্টেক্স এআই এমবেডিং মডেলের মাধ্যমে তৈরি করেছি।
এখন যেহেতু আমাদের কাছে ফায়ারস্টোর ডাটাবেসে এম্বেডিং সহ রেকর্ডগুলি আপলোড করা আছে, আমরা পরবর্তী ধাপে যেতে পারি এবং দেখতে পারি কিভাবে ফায়ারস্টোরে ভেক্টরের সাদৃশ্য অনুসন্ধান করা যায়।
6. Firestore ডেটাবেস সংগ্রহে সম্পূর্ণ যোগ পোজ আমদানি করুন
আমরা এখন poses
সংগ্রহ তৈরি করব, যা 160টি যোগ পোজের একটি সম্পূর্ণ তালিকা, যার জন্য আমরা একটি ডাটাবেস আমদানি ফাইল তৈরি করেছি যা আপনি সরাসরি আমদানি করতে পারেন। ল্যাবে সময় বাঁচানোর জন্য এটি করা হয়। বর্ণনা এবং এম্বেডিং ধারণ করে ডেটাবেস তৈরি করার প্রক্রিয়াটি একই যা আমরা আগের বিভাগে দেখেছি।
নীচের ধাপগুলি অনুসরণ করে ডাটাবেস আমদানি করুন:
- নীচে দেওয়া
gsutil
কমান্ড দিয়ে আপনার প্রকল্পে একটি বালতি তৈরি করুন। নিচের কমান্ডে<PROJECT_ID>
ভেরিয়েবলটিকে আপনার Google ক্লাউড প্রজেক্ট আইডি দিয়ে প্রতিস্থাপন করুন।
gsutil mb -l us-central1 gs://<PROJECT_ID>-my-bucket
- এখন যেহেতু বালতি তৈরি হয়েছে, আমরা ফায়ারবেস ডাটাবেসে আমদানি করার আগে আমাদের এই বালতিতে প্রস্তুত করা ডাটাবেস এক্সপোর্ট কপি করতে হবে। নীচে দেওয়া কমান্ড ব্যবহার করুন:
gsutil cp -r gs://yoga-database-firestore-export-bucket/2025-01-27T05:11:02_62615 gs://<PROJECT_ID>-my-bucket
এখন যেহেতু আমাদের কাছে আমদানি করার ডেটা আছে, আমরা যে Firebase ডাটাবেস ( default
) তৈরি করেছি তাতে ডেটা আমদানির চূড়ান্ত ধাপে যেতে পারি।
- নিচে দেওয়া gcloud কমান্ডটি ব্যবহার করুন:
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2025-01-27T05:11:02_62615
আমদানিতে কয়েক সেকেন্ড সময় লাগবে এবং এটি প্রস্তুত হয়ে গেলে, আপনি https://console.cloud.google.com/firestore/databases- এ গিয়ে আপনার Firestore ডাটাবেস এবং সংগ্রহটি যাচাই করতে পারেন, default
ডাটাবেস এবং poses
সংগ্রহটি নীচে দেখানো হিসাবে নির্বাচন করুন:
এটি Firestore সংগ্রহের তৈরি সম্পূর্ণ করে যা আমরা আমাদের অ্যাপ্লিকেশনে ব্যবহার করব।
7. ফায়ারস্টোরে ভেক্টর সাদৃশ্য অনুসন্ধান করুন৷
ভেক্টর সাদৃশ্য অনুসন্ধান করতে, আমরা ব্যবহারকারীর কাছ থেকে প্রশ্ন নেব। এই প্রশ্নের একটি উদাহরণ হতে পারে "Suggest me some exercises to relieve back pain"
।
search-data.js
ফাইলটি একবার দেখুন। দেখতে কী ফাংশন হল search
ফাংশন, যা নীচে দেখানো হয়েছে। একটি উচ্চ স্তরে, এটি একটি এমবেডিং ক্লাস তৈরি করে যা ব্যবহারকারীর প্রশ্নের জন্য এম্বেডিং তৈরি করতে ব্যবহার করা হবে। এটি তারপর ফায়ারস্টোর ডাটাবেস এবং সংগ্রহের সাথে একটি সংযোগ স্থাপন করে। তারপর সংগ্রহে এটি Find Nearest পদ্ধতির আহ্বান করে, যা একটি ভেক্টর সাদৃশ্য অনুসন্ধান করে।
async function search(query) {
try {
const embeddings = new VertexAIEmbeddings({
model: process.env.EMBEDDING_MODEL_NAME,
});
// Initialize Firestore
const firestore = new Firestore({
projectId: process.env.PROJECT_ID,
databaseId: process.env.DATABASE,
});
log.info(`Now executing query: ${query}`);
const singleVector = await embeddings.embedQuery(query);
const collectionRef = firestore.collection(process.env.COLLECTION);
let vectorQuery = collectionRef.findNearest(
"embedding",
FieldValue.vector(singleVector), // a vector with 768 dimensions
{
limit: process.env.TOP_K,
distanceMeasure: "COSINE",
}
);
const vectorQuerySnapshot = await vectorQuery.get();
for (const result of vectorQuerySnapshot.docs) {
console.log(result.data().content);
}
} catch (error) {
log.error(`Error during search: ${error.message}`);
}
}
আপনি কয়েকটি ক্যোয়ারী উদাহরণ সহ এটি চালানোর আগে, আপনাকে প্রথমে একটি Firestore কম্পোজিট সূচক তৈরি করতে হবে, যা আপনার অনুসন্ধান ক্যোয়ারী সফল হওয়ার জন্য প্রয়োজন। আপনি যদি সূচী তৈরি না করেই অ্যাপ্লিকেশনটি চালান, একটি ত্রুটি নির্দেশ করে যে আপনাকে প্রথমে সূচী তৈরি করতে হবে প্রথমে সূচী তৈরি করতে কমান্ডের সাথে প্রদর্শিত হবে।
যৌগিক সূচক তৈরি করার জন্য gcloud
কমান্ডটি নীচে দেখানো হয়েছে:
gcloud firestore indexes composite create --project=<YOUR_PROJECT_ID> --collection-group=poses --query-scope=COLLECTION --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=embedding
সূচকটি সম্পূর্ণ হতে কয়েক মিনিট সময় নেবে যেহেতু ডাটাবেসে উপস্থিত 150+ রেকর্ড রয়েছে৷ এটি সম্পূর্ণ হয়ে গেলে, আপনি নীচে দেখানো কমান্ডের মাধ্যমে সূচকটি দেখতে পারেন:
gcloud firestore indexes composite list
আপনি তালিকায় যে সূচীটি তৈরি করেছেন তা দেখতে হবে।
এখন নিম্নলিখিত কমান্ড ব্যবহার করে দেখুন:
node search-data.js --prompt "Recommend me some exercises for back pain relief"
আপনাকে দেওয়া কয়েকটি সুপারিশ থাকা উচিত। একটি নমুনা রান নীচে দেখানো হয়েছে:
2025-01-28T07:09:05.250Z - INFO - Now executing query: Recommend me some exercises for back pain relief
name: Sphinx Pose
description: A gentle backbend, Sphinx Pose (Salamba Bhujangasana) strengthens the spine and opens the chest. Keep shoulders relaxed, lengthen the tailbone, and engage the core for optimal alignment. Beginner-friendly.
sanskrit_name: Salamba Bhujangasana
expertise_level: Beginner
pose_type: ['Prone']
name: Supine Spinal Twist Pose
description: A gentle supine twist (Supta Matsyendrasana), great for beginners. Releases spinal tension, improves digestion, and calms the nervous system. Keep shoulders flat on the floor and lengthen your spine throughout the twist.
sanskrit_name: Supta Matsyendrasana
expertise_level: Beginner
pose_type: ['Supine', 'Twist']
name: Reverse Corpse Pose
description: Reverse Corpse Pose (Advasana) is a beginner prone pose. Lie on your belly, arms at your sides, relaxing completely. Benefits include stress release and spinal decompression. Ensure your forehead rests comfortably on the mat.
sanskrit_name: Advasana
expertise_level: Beginner
pose_type: ['Prone']
একবার আপনার কাজ হয়ে গেলে, আমরা এখন বুঝতে পেরেছি কিভাবে রেকর্ড আপলোড করতে, এম্বেডিং তৈরি করতে এবং একটি ভেক্টর সাদৃশ্য অনুসন্ধান করতে Firestore ভেক্টর ডেটাবেস কাজ করতে হয়। আমরা এখন একটি ওয়েব অ্যাপ্লিকেশন তৈরি করতে পারি যা একটি ওয়েব ফ্রন্ট-এন্ডে ভেক্টর অনুসন্ধানকে একীভূত করবে।
8. ওয়েব অ্যাপ্লিকেশন
পাইথন ফ্লাস্ক ওয়েব অ্যাপ্লিকেশনটি app.js
ফাইলে পাওয়া যায় এবং ফ্রন্ট-এন্ড HTML ফাইলটি views/index.html.
এটি সুপারিশ করা হয় যে আপনি উভয় ফাইল কটাক্ষপাত করুন. প্রথমে app.js
ফাইল দিয়ে শুরু করুন যেটিতে /search
হ্যান্ডলার রয়েছে, যা ফ্রন্ট-এন্ড HTML index.html
ফাইল থেকে পাস করা প্রম্পট নেয়। এটি তারপর অনুসন্ধান পদ্ধতির আহ্বান করে, যা আমরা পূর্ববর্তী বিভাগে দেখেছি এমন ভেক্টর সাদৃশ্য অনুসন্ধান করে।
তারপর প্রতিক্রিয়াটি সুপারিশের তালিকা সহ index.html
এ ফেরত পাঠানো হয়। তারপর index.html
বিভিন্ন কার্ড হিসাবে সুপারিশগুলি প্রদর্শন করে৷
স্থানীয়ভাবে অ্যাপ্লিকেশন চালান
একটি নতুন টার্মিনাল উইন্ডো (Ctrl+Shift+C) বা বিদ্যমান কোনো টার্মিনাল উইন্ডো চালু করুন এবং নিম্নলিখিত কমান্ড দিন:
npm run start
একটি নমুনা মৃত্যুদন্ড নীচে দেখানো হয়েছে:
...
Server listening on port 8080
একবার চালু হয়ে গেলে, নীচে দেখানো ওয়েব প্রিভিউ বোতামে ক্লিক করে অ্যাপ্লিকেশনটির হোম URL-এ যান:
এটি আপনাকে index.html
ফাইলটি দেখানো উচিত যা নীচে দেখানো হয়েছে:
একটি নমুনা প্রশ্ন প্রদান করুন (উদাহরণ: Provide me some exercises for back pain relief
) এবং Search
বোতামে ক্লিক করুন। এটি ডাটাবেস থেকে কিছু সুপারিশ পুনরুদ্ধার করা উচিত। আপনি একটি Play Audio
বোতামও দেখতে পাবেন, যা বর্ণনার উপর ভিত্তি করে একটি অডিও স্ট্রিম তৈরি করবে, যা আপনি সরাসরি শুনতে পারবেন।
9. (ঐচ্ছিক) গুগল ক্লাউড রানে স্থাপন করা হচ্ছে
আমাদের চূড়ান্ত পদক্ষেপ Google ক্লাউড রানে এই অ্যাপ্লিকেশনটি স্থাপন করা হবে৷ ডিপ্লয়মেন্ট কমান্ডটি নীচে দেখানো হয়েছে, নিশ্চিত করুন যে আপনি এটি স্থাপন করার আগে, আপনি নীচের বোল্ডে দেখানো মানগুলি প্রতিস্থাপন করুন। এই মানগুলি আপনি .env
ফাইল থেকে পুনরুদ্ধার করতে সক্ষম হবেন।
gcloud run deploy yogaposes --source . \
--port=8080 \
--allow-unauthenticated \
--region=<<YOUR_LOCATION>> \
--platform=managed \
--project=<<YOUR_PROJECT_ID>> \
--set-env-vars=PROJECT_ID="<<YOUR_PROJECT_ID>>",LOCATION="<<YOUR_LOCATION>>",EMBEDDING_MODEL_NAME="<<EMBEDDING_MODEL_NAME>>",DATABASE="<<FIRESTORE_DATABASE_NAME>>",COLLECTION="<<FIRESTORE_COLLECTION_NAME>>",TOP_K=<<YOUR_TOP_K_VALUE>>
অ্যাপ্লিকেশনটির রুট ফোল্ডার থেকে উপরের কমান্ডটি চালান। আপনাকে Google ক্লাউড API সক্রিয় করতে বলা হতে পারে, বিভিন্ন অনুমতির জন্য আপনার স্বীকৃতি দিন, অনুগ্রহ করে তা করুন৷
স্থাপনার প্রক্রিয়াটি সম্পূর্ণ হতে প্রায় 5-7 মিনিট সময় লাগবে, তাই অনুগ্রহ করে ধৈর্য ধরুন।
একবার সফলভাবে স্থাপন করা হলে, স্থাপনার আউটপুট ক্লাউড রান পরিষেবা URL প্রদান করবে। এটি ফর্মের হবে:
Service URL: https://yogaposes-<UNIQUEID>.us-central1.run.app
সেই সর্বজনীন URL-এ যান এবং আপনি দেখতে পাবেন একই ওয়েব অ্যাপ্লিকেশন সফলভাবে স্থাপন করা হয়েছে এবং চলছে৷
আপনি Google ক্লাউড কনসোল থেকে ক্লাউড রানেও যেতে পারেন এবং আপনি ক্লাউড রানে পরিষেবার তালিকা দেখতে পাবেন। yogaposes
পরিষেবাটি সেখানে তালিকাভুক্ত পরিষেবাগুলির মধ্যে একটি হওয়া উচিত (যদি একমাত্র না হয়)।
আপনি নির্দিষ্ট পরিষেবার নামের উপর ক্লিক করে ইউআরএল, কনফিগারেশন, লগ এবং আরও অনেক কিছুর মতো পরিষেবার বিশদ বিবরণ দেখতে পারেন (আমাদের ক্ষেত্রে yogaposes
)।
এটি ক্লাউড রানে আমাদের যোগ পোজ সুপারিশকারী ওয়েব অ্যাপ্লিকেশনের বিকাশ এবং স্থাপনা সম্পূর্ণ করে।
10. অভিনন্দন
অভিনন্দন, আপনি সফলভাবে একটি অ্যাপ্লিকেশন তৈরি করেছেন যা Firestore-এ একটি ডেটাসেট আপলোড করে, এম্বেডিং তৈরি করে এবং ব্যবহারকারীদের প্রশ্নের উপর ভিত্তি করে একটি ভেক্টর সাদৃশ্য অনুসন্ধান করে।
রেফারেন্স ডক্স
1. ভূমিকা
এই কোডল্যাবে, আপনি একটি অ্যাপ্লিকেশন তৈরি করবেন যা ভেক্টর অনুসন্ধান ব্যবহার করে যোগা ভঙ্গির সুপারিশ করতে।
কোডল্যাবের মাধ্যমে, আপনি নিম্নলিখিত হিসাবে একটি ধাপে ধাপে পদ্ধতি ব্যবহার করবেন:
- যোগা ভঙ্গি (JSON ফর্ম্যাট) এর একটি বিদ্যমান আলিঙ্গন মুখ ডেটাসেট ব্যবহার করুন।
- একটি অতিরিক্ত ক্ষেত্রের বিবরণ সহ ডেটাসেট উন্নত করুন যা প্রতিটি ভঙ্গির জন্য বর্ণনা তৈরি করতে জেমিনি ব্যবহার করে।
- উত্পন্ন এমবেডিং সহ Firestore সংগ্রহে নথির সংগ্রহ হিসাবে যোগা পোজ ডেটা লোড করুন৷
- ভেক্টর অনুসন্ধানের জন্য Firestore-এ একটি যৌগিক সূচক তৈরি করুন।
- একটি Node.js অ্যাপ্লিকেশনে ভেক্টর অনুসন্ধান ব্যবহার করুন যা নীচে দেখানো হিসাবে সবকিছুকে একত্রিত করে:
আপনি কি করবেন
- যোগা ভঙ্গি সুপারিশ করার জন্য ভেক্টর অনুসন্ধান নিয়োগ করে এমন একটি ওয়েব অ্যাপ্লিকেশন ডিজাইন, তৈরি এবং স্থাপন করুন।
আপনি কি শিখবেন
- টেক্সট বিষয়বস্তু তৈরি করতে এবং এই কোডল্যাবের প্রেক্ষাপটে যোগব্যায়াম ভঙ্গির জন্য বর্ণনা তৈরি করতে কীভাবে জেমিনি ব্যবহার করবেন
- হাগিং ফেস থেকে ফায়ারস্টোরে ভেক্টর এমবেডিং সহ একটি উন্নত ডেটাসেট থেকে রেকর্ডগুলি কীভাবে লোড করবেন
- একটি প্রাকৃতিক ভাষার প্রশ্নের উপর ভিত্তি করে ডেটা অনুসন্ধান করতে Firestore ভেক্টর অনুসন্ধান কীভাবে ব্যবহার করবেন
- অডিও সামগ্রী তৈরি করতে Google ক্লাউড টেক্সট টু স্পিচ API কীভাবে ব্যবহার করবেন
আপনি কি প্রয়োজন হবে
- ক্রোম ওয়েব ব্রাউজার
- একটি জিমেইল অ্যাকাউন্ট
- বিলিং সক্ষম সহ একটি ক্লাউড প্রকল্প৷
এই কোডল্যাব, সমস্ত স্তরের বিকাশকারীদের জন্য ডিজাইন করা হয়েছে (শিশুদের সহ), এটির নমুনা অ্যাপ্লিকেশনটিতে JavaScript এবং Node.js ব্যবহার করে। যাইহোক, উপস্থাপিত ধারণা বোঝার জন্য JavaScript এবং Node.js জ্ঞানের প্রয়োজন নেই।
2. আপনি শুরু করার আগে
একটি প্রকল্প তৈরি করুন
- Google ক্লাউড কনসোলে , প্রকল্প নির্বাচক পৃষ্ঠায়, একটি Google ক্লাউড প্রকল্প নির্বাচন করুন বা তৈরি করুন।
- নিশ্চিত করুন যে আপনার ক্লাউড প্রকল্পের জন্য বিলিং সক্ষম করা আছে৷ একটি প্রকল্পে বিলিং সক্ষম কিনা তা পরীক্ষা করতে শিখুন।
- আপনি ক্লাউড শেল ব্যবহার করবেন, Google ক্লাউডে চলমান একটি কমান্ড-লাইন পরিবেশ যা bq এর সাথে প্রিলোড করা হয়। গুগল ক্লাউড কনসোলের শীর্ষে সক্রিয় ক্লাউড শেল ক্লিক করুন।
- একবার ক্লাউড শেলের সাথে সংযুক্ত হয়ে গেলে, আপনি পরীক্ষা করে দেখুন যে আপনি ইতিমধ্যেই প্রমাণীকৃত হয়েছেন এবং নিম্নলিখিত কমান্ডটি ব্যবহার করে প্রকল্পটি আপনার প্রকল্প আইডিতে সেট করা আছে:
gcloud auth list
- gcloud কমান্ড আপনার প্রকল্প সম্পর্কে জানে তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান।
gcloud config list project
- যদি আপনার প্রজেক্ট সেট করা না থাকে, তাহলে এটি সেট করতে নিম্নলিখিত কমান্ডটি ব্যবহার করুন:
gcloud config set project <YOUR_PROJECT_ID>
- নীচে দেখানো কমান্ডের মাধ্যমে প্রয়োজনীয় API গুলি সক্ষম করুন৷ এটি কয়েক মিনিট সময় নিতে পারে, তাই ধৈর্য ধরুন।
gcloud services enable firestore.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
cloudfunctions.googleapis.com \
aiplatform.googleapis.com \
texttospeech.googleapis.com
কমান্ডের সফল সঞ্চালন হলে, আপনি নীচের দেখানো একটি অনুরূপ একটি বার্তা দেখতে হবে:
Operation "operations/..." finished successfully.
gcloud কমান্ডের বিকল্প হল কনসোলের মাধ্যমে প্রতিটি পণ্য অনুসন্ধান করে বা এই লিঙ্কটি ব্যবহার করে।
যদি কোনো API মিস হয়, আপনি সর্বদা বাস্তবায়নের সময় এটি সক্রিয় করতে পারেন।
জিক্লাউড কমান্ড এবং ব্যবহারের জন্য ডকুমেন্টেশন পড়ুন।
ক্লোন সংগ্রহস্থল এবং সেটআপ পরিবেশ সেটিংস
পরবর্তী ধাপ হল নমুনা সংগ্রহস্থল ক্লোন করা যা আমরা কোডল্যাবের বাকি অংশে উল্লেখ করব। ধরে নিই যে আপনি ক্লাউড শেলে আছেন, আপনার হোম ডিরেক্টরি থেকে নিম্নলিখিত কমান্ড দিন:
git clone https://github.com/rominirani/yoga-poses-recommender-nodejs
সম্পাদক চালু করতে, ক্লাউড শেল উইন্ডোর টুলবারে সম্পাদক খুলুন ক্লিক করুন। উপরের বাম কোণে মেনু বারে ক্লিক করুন এবং নীচে দেখানো হিসাবে ফাইল → ফোল্ডার খুলুন নির্বাচন করুন:
yoga-poses-recommender-nodejs
ফোল্ডারটি নির্বাচন করুন এবং আপনি নীচের চিত্রের মতো নিম্নলিখিত ফাইলগুলির সাথে ফোল্ডারটি খোলা দেখতে পাবেন:
আমাদের এখন পরিবেশের ভেরিয়েবল সেট আপ করতে হবে যা আমরা ব্যবহার করব। env-template
ফাইলটিতে ক্লিক করুন এবং নিচের মত বিষয়বস্তু দেখতে পাবেন:
PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
LOCATION=us-<GOOGLE_CLOUD_REGION_NAME>
GEMINI_MODEL_NAME=<GEMINI_MODEL_NAME>
EMBEDDING_MODEL_NAME=<GEMINI_EMBEDDING_MODEL_NAME>
IMAGE_GENERATION_MODEL_NAME=<IMAGEN_MODEL_NAME>
DATABASE=<FIRESTORE_DATABASE_NAME>
COLLECTION=<FIRESTORE_COLLECTION_NAME>
TEST_COLLECTION=test-poses
TOP_K=3
Google ক্লাউড প্রজেক্ট এবং ফায়ারস্টোর ডেটাবেস অঞ্চল তৈরি করার সময় আপনি যা নির্বাচন করেছেন সেই অনুযায়ী অনুগ্রহ করে PROJECT_ID
এবং LOCATION
এর মানগুলি আপডেট করুন৷ আদর্শভাবে, আমরা Google ক্লাউড প্রকল্প এবং ফায়ারস্টোর ডেটাবেসের জন্য LOCATION
এর মান একই হতে চাই, যেমন us-central1
।
এই কোডল্যাবের উদ্দেশ্যে, আমরা নিম্নলিখিত মানগুলির সাথে যেতে যাচ্ছি (অবশ্যই PROJECT_ID
এবং LOCATION
ব্যতীত, যা আপনাকে আপনার কনফিগারেশন অনুযায়ী সেট করতে হবে৷
PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
LOCATION=us-<GOOGLE_CLOUD_REGION_NAME>
GEMINI_MODEL_NAME=gemini-1.5-flash-002
EMBEDDING_MODEL_NAME=text-embedding-004
IMAGE_GENERATION_MODEL_NAME=imagen-3.0-fast-generate-001
DATABASE=(default)
COLLECTION=poses
TEST_COLLECTION=test-poses
TOP_K=3
অনুগ্রহ করে এই ফাইলটিকে env-template
ফাইলের মতো একই ফোল্ডারে .env
হিসাবে সংরক্ষণ করুন৷
ক্লাউড শেল আইডিই-তে উপরের বামদিকে প্রধান মেনুতে যান এবং তারপরে Terminal → New Terminal
।
আপনি নিম্নলিখিত কমান্ডের মাধ্যমে ক্লোন করা সংগ্রহস্থলের রুট ফোল্ডারে নেভিগেট করুন:
cd yoga-poses-recommender-nodejs
কমান্ডের মাধ্যমে Node.js নির্ভরতা ইনস্টল করুন:
npm install
দারুণ! আমরা এখন Firestore ডাটাবেস সেট আপ করার কাজে এগিয়ে যাওয়ার জন্য প্রস্তুত।
3. ফায়ারস্টোর সেটআপ করুন
ক্লাউড ফায়ারস্টোর হল একটি সম্পূর্ণ-পরিচালিত সার্ভারহীন ডকুমেন্ট ডাটাবেস যা আমরা আমাদের অ্যাপ্লিকেশন ডেটার জন্য ব্যাকএন্ড হিসাবে ব্যবহার করব। ক্লাউড ফায়ারস্টোরের ডেটা নথির সংগ্রহে গঠন করা হয়।
ফায়ারস্টোর ডাটাবেস আরম্ভ
ক্লাউড কনসোলে Firestore পৃষ্ঠায় যান।
আপনি যদি প্রজেক্টে আগে ফায়ারস্টোর ডাটাবেস চালু না করে থাকেন, তাহলে Create Database
-এ ক্লিক করে default
ডাটাবেস তৈরি করুন। ডাটাবেস তৈরি করার সময়, নিম্নলিখিত মানগুলির সাথে যান:
- ফায়ারস্টোর মোড:
Native.
- অবস্থান: ডিফল্ট অবস্থান সেটিংস দিয়ে যান।
- নিরাপত্তা বিধিগুলির জন্য,
Test rules
সাথে যান৷ - ডাটাবেস তৈরি করুন।
পরবর্তী বিভাগে, আমরা আমাদের ডিফল্ট ফায়ারস্টোর ডাটাবেসে poses
নামে একটি সংগ্রহ তৈরি করার ভিত্তি স্থাপন করব। এই সংগ্রহে নমুনা ডেটা (ডকুমেন্ট) বা যোগ পোজ তথ্য থাকবে, যা আমরা আমাদের অ্যাপ্লিকেশনে ব্যবহার করব।
এটি ফায়ারস্টোর ডাটাবেস সেট আপ করার জন্য বিভাগটি সম্পূর্ণ করে।
4. যোগা পোজ ডেটাসেট প্রস্তুত করুন
আমাদের প্রথম কাজ হল যোগা পোজ ডেটাসেট প্রস্তুত করা যা আমরা অ্যাপ্লিকেশনের জন্য ব্যবহার করব। আমরা একটি বিদ্যমান হাগিং ফেস ডেটাসেট দিয়ে শুরু করব এবং তারপরে অতিরিক্ত তথ্য দিয়ে এটিকে উন্নত করব।
যোগা ভঙ্গির জন্য আলিঙ্গন করা মুখের ডেটাসেটটি দেখুন। মনে রাখবেন যে এই কোডল্যাবটি যখন ডেটাসেটগুলির একটি ব্যবহার করে, আপনি আসলে অন্য কোনও ডেটাসেট ব্যবহার করতে পারেন এবং ডেটাসেট উন্নত করতে প্রদর্শিত একই কৌশলগুলি অনুসরণ করতে পারেন৷
আমরা যদি Files and versions
বিভাগে যাই, আমরা সমস্ত ভঙ্গির জন্য JSON ডেটা ফাইল পেতে পারি।
আমরা yoga_poses.json
ডাউনলোড করেছি এবং সেই ফাইলটি আপনাকে প্রদান করেছি। এই ফাইলটির নাম yoga_poses_alldata.json
এবং এটি /data
ফোল্ডারে রয়েছে।
ক্লাউড শেল এডিটরে data/yoga_poses.json
ফাইলটিতে যান এবং JSON অবজেক্টের তালিকাটি দেখুন, যেখানে প্রতিটি JSON অবজেক্ট একটি যোগ পোজ উপস্থাপন করে। আমাদের মোট 3টি রেকর্ড রয়েছে এবং একটি নমুনা রেকর্ড নীচে দেখানো হয়েছে:
{
"name": "Big Toe Pose",
"sanskrit_name": "Padangusthasana",
"photo_url": "https://pocketyoga.com/assets/images/full/ForwardBendBigToe.png",
"expertise_level": "Beginner",
"pose_type": ["Standing", "Forward Bend"]
}
মিথুনের সাথে পরিচয় করিয়ে দেওয়ার এবং কীভাবে আমরা এটির জন্য একটি description
ক্ষেত্র তৈরি করতে ডিফল্ট মডেলটি ব্যবহার করতে পারি তা এখন আমাদের জন্য একটি দুর্দান্ত সুযোগ।
ক্লাউড শেল এডিটরে, generate-descriptions.js
ফাইলে যান। এই ফাইলের বিষয়বস্তু নীচে দেখানো হয়েছে:
import { VertexAI } from "@langchain/google-vertexai";
import fs from 'fs/promises'; // Use fs/promises for async file operations
import dotenv from 'dotenv';
import pRetry from 'p-retry';
import { promisify } from 'util';
const sleep = promisify(setTimeout);
// Load environment variables
dotenv.config();
async function callGemini(poseName, sanskritName, expertiseLevel, poseTypes) {
const prompt = `
Generate a concise description (max 50 words) for the yoga pose: ${poseName}
Also known as: ${sanskritName}
Expertise Level: ${expertiseLevel}
Pose Type: ${poseTypes.join(', ')}
Include key benefits and any important alignment cues.
`;
try {
// Initialize Vertex AI Gemini model
const model = new VertexAI({
model: process.env.GEMINI_MODEL_NAME,
location: process.env.LOCATION,
project: process.env.PROJECT_ID,
});
// Invoke the model
const response = await model.invoke(prompt);
// Return the response
return response;
} catch (error) {
console.error("Error calling Gemini:", error);
throw error; // Re-throw the error for handling in the calling function
}
}
// Configure logging (you can use a library like 'winston' for more advanced logging)
const logger = {
info: (message) => console.log(`INFO - ${new Date().toISOString()} - ${message}`),
error: (message) => console.error(`ERROR - ${new Date().toISOString()} - ${message}`),
};
async function generateDescription(poseName, sanskritName, expertiseLevel, poseTypes) {
const prompt = `
Generate a concise description (max 50 words) for the yoga pose: ${poseName}
Also known as: ${sanskritName}
Expertise Level: ${expertiseLevel}
Pose Type: ${poseTypes.join(', ')}
Include key benefits and any important alignment cues.
`;
const req = {
contents: [{ role: 'user', parts: [{ text: prompt }] }],
};
const runWithRetry = async () => {
const resp = await generativeModel.generateContent(req);
const response = await resp.response;
const text = response.candidates[0].content.parts[0].text;
return text;
};
try {
const text = await pRetry(runWithRetry, {
retries: 5,
onFailedAttempt: (error) => {
logger.info(
`Attempt ${error.attemptNumber} failed. There are ${error.retriesLeft} retries left. Waiting ${error.retryDelay}ms...`
);
},
minTimeout: 4000, // 4 seconds (exponential backoff will adjust this)
factor: 2, // Exponential factor
});
return text;
} catch (error) {
logger.error(`Error generating description for ${poseName}: ${error}`);
return '';
}
}
async function addDescriptionsToJSON(inputFile, outputFile) {
try {
const data = await fs.readFile(inputFile, 'utf-8');
const yogaPoses = JSON.parse(data);
const totalPoses = yogaPoses.length;
let processedCount = 0;
for (const pose of yogaPoses) {
if (pose.name !== ' Pose') {
const startTime = Date.now();
pose.description = await callGemini(
pose.name,
pose.sanskrit_name,
pose.expertise_level,
pose.pose_type
);
const endTime = Date.now();
const timeTaken = (endTime - startTime) / 1000;
processedCount++;
logger.info(`Processed: ${processedCount}/${totalPoses} - ${pose.name} (${timeTaken.toFixed(2)} seconds)`);
} else {
pose.description = '';
processedCount++;
logger.info(`Processed: ${processedCount}/${totalPoses} - ${pose.name} (${timeTaken.toFixed(2)} seconds)`);
}
// Add a delay to avoid rate limit
await sleep(30000); // 30 seconds
}
await fs.writeFile(outputFile, JSON.stringify(yogaPoses, null, 2));
logger.info(`Descriptions added and saved to ${outputFile}`);
} catch (error) {
logger.error(`Error processing JSON file: ${error}`);
}
}
async function main() {
const inputFile = './data/yoga_poses.json';
const outputFile = './data/yoga_poses_with_descriptions.json';
await addDescriptionsToJSON(inputFile, outputFile);
}
main();
এই অ্যাপ্লিকেশনটি প্রতিটি যোগা পোজ JSON রেকর্ডে একটি নতুন description
ক্ষেত্র যোগ করবে। এটি মিথুন মডেলের কাছে একটি কলের মাধ্যমে বিবরণটি পাবে, যেখানে আমরা এটিকে প্রয়োজনীয় প্রম্পট প্রদান করব। ক্ষেত্রটি JSON ফাইলে যোগ করা হয় এবং নতুন ফাইলটি data/yoga_poses_with_descriptions.json
ফাইলে লেখা হয়।
চলুন প্রধান পদক্ষেপের মাধ্যমে যান:
-
main()
ফাংশনে, আপনি দেখতে পাবেন যে এটিadd_descriptions_to_json
ফাংশনকে আহ্বান করে এবং ইনপুট ফাইল এবং প্রত্যাশিত আউটপুট ফাইল সরবরাহ করে। -
add_descriptions_to_json
ফাংশন প্রতিটি JSON রেকর্ডের জন্য নিম্নলিখিত কাজ করে যেমন যোগ পোস্ট তথ্য: - এটি
pose_name
,sanskrit_name
,expertise_level
এবংpose_types
বের করে। - এটি
callGemini
ফাংশনকে আহ্বান করে যা একটি প্রম্পট তৈরি করে এবং তারপরে প্রতিক্রিয়া পাঠ্য পেতে LangchainVertexAI মডেল ক্লাসকে আহ্বান করে। - এই প্রতিক্রিয়া পাঠ্য তারপর JSON অবজেক্ট যোগ করা হয়.
- অবজেক্টের আপডেট করা JSON তালিকা তারপর গন্তব্য ফাইলে লেখা হয়।
আমাদের এই অ্যাপ্লিকেশন চালানো যাক. একটি নতুন টার্মিনাল উইন্ডো চালু করুন (Ctrl+Shift+C) এবং নিম্নলিখিত কমান্ড দিন:
npm run generate-descriptions
যদি আপনাকে কোনো অনুমোদনের জন্য বলা হয়, অনুগ্রহ করে এগিয়ে যান এবং সেটি প্রদান করুন।
আপনি দেখতে পাবেন যে অ্যাপ্লিকেশনটি কার্যকর করা শুরু হয়েছে। নতুন Google ক্লাউড অ্যাকাউন্টে যেকোন হারের সীমা কোটা এড়াতে আমরা রেকর্ডগুলির মধ্যে 30 সেকেন্ডের বিলম্ব যোগ করেছি, তাই অনুগ্রহ করে ধৈর্য ধরুন।
চলমান একটি নমুনা নীচে দেখানো হয়েছে:
একবার জেমিনি কলের সাথে 3টি রেকর্ডের সবকটি উন্নত হয়ে গেলে, একটি ফাইল data/yoga_poses_with_description.json
তৈরি করা হবে। আপনি যে কটাক্ষপাত করতে পারেন.
আমরা এখন আমাদের ডেটা ফাইলের সাথে প্রস্তুত এবং পরবর্তী পদক্ষেপটি হল এম্বেডিং জেনারেশনের সাথে একটি ফায়ারস্টোর ডেটাবেস কীভাবে পপুলেট করা যায় তা বোঝা।
5. ফায়ারস্টোরে ডেটা আমদানি করুন এবং ভেক্টর এমবেডিং তৈরি করুন
আমাদের কাছে data/yoga_poses_with_description.json
ফাইল আছে এবং এখন এটির সাথে Firestore ডেটাবেস তৈরি করতে হবে এবং গুরুত্বপূর্ণভাবে, প্রতিটি রেকর্ডের জন্য ভেক্টর এমবেডিং তৈরি করতে হবে। ভেক্টর এমবেডিংগুলি পরবর্তীতে কাজে লাগবে যখন আমাদের প্রাকৃতিক ভাষায় দেওয়া ব্যবহারকারীর প্রশ্নের সাথে তাদের একটি মিল অনুসন্ধান করতে হবে।
এটি করার পদক্ষেপগুলি নিম্নরূপ হবে:
- আমরা JSON অবজেক্টের তালিকাকে অবজেক্টের তালিকায় রূপান্তর করব। প্রতিটি নথিতে দুটি বৈশিষ্ট্য থাকবে:
content
এবংmetadata
। মেটাডেটা অবজেক্টে পুরো JSON অবজেক্ট থাকবে যার মধ্যেname
,description
,sanskrit_name
, ইত্যাদির মতো বৈশিষ্ট্য রয়েছে৷content
একটি স্ট্রিং পাঠ্য হবে যা কয়েকটি ক্ষেত্রের সংমিশ্রণ হবে৷ - একবার আমাদের কাছে নথিগুলির একটি তালিকা হয়ে গেলে, আমরা বিষয়বস্তু ক্ষেত্রের জন্য এম্বেডিং তৈরি করতে Vertex AI এম্বেডিং ক্লাস ব্যবহার করব। এই এমবেডিংটি প্রতিটি নথির রেকর্ডে যোগ করা হবে এবং তারপর আমরা সংগ্রহে নথি বস্তুর এই তালিকাটি সংরক্ষণ করতে Firestore API ব্যবহার করব (আমরা
TEST_COLLECTION
ভেরিয়েবল ব্যবহার করছি যাtest-poses
তে নির্দেশ করে)।
import-data.js
এর কোড নিচে দেওয়া হল (কোডের অংশগুলি সংক্ষিপ্ততার জন্য কেটে দেওয়া হয়েছে):
import { Firestore,
FieldValue,
} from '@google-cloud/firestore';
import { VertexAIEmbeddings } from "@langchain/google-vertexai";
import * as dotenv from 'dotenv';
import fs from 'fs/promises';
// Load environment variables
dotenv.config();
// Configure logging
const logger = {
info: (message) => console.log(`INFO - ${new Date().toISOString()} - ${message}`),
error: (message) => console.error(`ERROR - ${new Date().toISOString()} - ${message}`),
};
async function loadYogaPosesDataFromLocalFile(filename) {
try {
const data = await fs.readFile(filename, 'utf-8');
const poses = JSON.parse(data);
logger.info(`Loaded ${poses.length} poses.`);
return poses;
} catch (error) {
logger.error(`Error loading dataset: ${error}`);
return null;
}
}
function createFirestoreDocuments(poses) {
const documents = [];
for (const pose of poses) {
// Convert the pose to a string representation for pageContent
const pageContent = `
name: ${pose.name || ''}
description: ${pose.description || ''}
sanskrit_name: ${pose.sanskrit_name || ''}
expertise_level: ${pose.expertise_level || 'N/A'}
pose_type: ${pose.pose_type || 'N/A'}
`.trim();
// The metadata will be the whole pose
const metadata = pose;
documents.push({ pageContent, metadata });
}
logger.info(`Created ${documents.length} Langchain documents.`);
return documents;
}
async function main() {
const allPoses = await loadYogaPosesDataFromLocalFile('./data/yoga_poses_with_descriptions.json');
const documents = createFirestoreDocuments(allPoses);
logger.info(`Successfully created Firestore documents. Total documents: ${documents.length}`);
const embeddings = new VertexAIEmbeddings({
model: process.env.EMBEDDING_MODEL_NAME,
});
// Initialize Firestore
const firestore = new Firestore({
projectId: process.env.PROJECT_ID,
databaseId: process.env.DATABASE,
});
const collectionName = process.env.TEST_COLLECTION;
for (const doc of documents) {
try {
// 1. Generate Embeddings
const singleVector = await embeddings.embedQuery(doc.pageContent);
// 2. Store in Firestore with Embeddings
const firestoreDoc = {
content: doc.pageContent,
metadata: doc.metadata, // Store the original data as metadata
embedding: FieldValue.vector(singleVector), // Add the embedding vector
};
const docRef = firestore.collection(collectionName).doc();
await docRef.set(firestoreDoc);
logger.info(`Document ${docRef.id} added to Firestore with embedding.`);
} catch (error) {
logger.error(`Error processing document: ${error}`);
}
}
logger.info('Finished adding documents to Firestore.');
}
main();
আমাদের এই অ্যাপ্লিকেশন চালানো যাক. একটি নতুন টার্মিনাল উইন্ডো চালু করুন (Ctrl+Shift+C) এবং নিম্নলিখিত কমান্ড দিন:
npm run import-data
সবকিছু ঠিকঠাক থাকলে, আপনি নীচের মত একটি বার্তা দেখতে পাবেন:
INFO - 2025-01-28T07:01:14.463Z - Loaded 3 poses.
INFO - 2025-01-28T07:01:14.464Z - Created 3 Langchain documents.
INFO - 2025-01-28T07:01:14.464Z - Successfully created Firestore documents. Total documents: 3
INFO - 2025-01-28T07:01:17.623Z - Document P46d5F92z9FsIhVVYgkd added to Firestore with embedding.
INFO - 2025-01-28T07:01:18.265Z - Document bjXXISctkXl2ZRSjUYVR added to Firestore with embedding.
INFO - 2025-01-28T07:01:19.285Z - Document GwzZMZyPfTLtiX6qBFFz added to Firestore with embedding.
INFO - 2025-01-28T07:01:19.286Z - Finished adding documents to Firestore.
রেকর্ডগুলি সফলভাবে ঢোকানো হয়েছে এবং এমবেডিংগুলি তৈরি হয়েছে কিনা তা পরীক্ষা করতে, ক্লাউড কনসোলে ফায়ারস্টোর পৃষ্ঠায় যান৷
(ডিফল্ট) ডাটাবেসে ক্লিক করুন, এটি সেই সংগ্রহের অধীনে test-poses
সংগ্রহ এবং একাধিক নথি প্রদর্শন করবে। প্রতিটি নথি একটি যোগ ভঙ্গি.
ক্ষেত্রগুলি তদন্ত করতে যেকোন নথিতে ক্লিক করুন। আমরা যে ক্ষেত্রগুলি আমদানি করেছি তা ছাড়াও, আপনি embedding
ক্ষেত্রটিও পাবেন, যা একটি ভেক্টর ক্ষেত্র, যার মান আমরা text-embedding-004
ভার্টেক্স এআই এমবেডিং মডেলের মাধ্যমে তৈরি করেছি।
এখন যেহেতু আমাদের কাছে ফায়ারস্টোর ডাটাবেসে এম্বেডিং সহ রেকর্ডগুলি আপলোড করা আছে, আমরা পরবর্তী ধাপে যেতে পারি এবং দেখতে পারি কিভাবে ফায়ারস্টোরে ভেক্টরের সাদৃশ্য অনুসন্ধান করা যায়।
6. Firestore ডেটাবেস সংগ্রহে সম্পূর্ণ যোগ পোজ আমদানি করুন
আমরা এখন poses
সংগ্রহ তৈরি করব, যা 160টি যোগ পোজের একটি সম্পূর্ণ তালিকা, যার জন্য আমরা একটি ডাটাবেস আমদানি ফাইল তৈরি করেছি যা আপনি সরাসরি আমদানি করতে পারেন। ল্যাবে সময় বাঁচানোর জন্য এটি করা হয়। বর্ণনা এবং এম্বেডিং ধারণ করে ডেটাবেস তৈরি করার প্রক্রিয়াটি একই যা আমরা আগের বিভাগে দেখেছি।
নীচের ধাপগুলি অনুসরণ করে ডাটাবেস আমদানি করুন:
- নীচে দেওয়া
gsutil
কমান্ড দিয়ে আপনার প্রকল্পে একটি বালতি তৈরি করুন। নিচের কমান্ডে<PROJECT_ID>
ভেরিয়েবলটিকে আপনার Google ক্লাউড প্রজেক্ট আইডি দিয়ে প্রতিস্থাপন করুন।
gsutil mb -l us-central1 gs://<PROJECT_ID>-my-bucket
- এখন যেহেতু বালতি তৈরি হয়েছে, আমরা ফায়ারবেস ডাটাবেসে আমদানি করার আগে আমাদের এই বালতিতে প্রস্তুত করা ডাটাবেস এক্সপোর্ট কপি করতে হবে। নীচে দেওয়া কমান্ড ব্যবহার করুন:
gsutil cp -r gs://yoga-database-firestore-export-bucket/2025-01-27T05:11:02_62615 gs://<PROJECT_ID>-my-bucket
এখন যেহেতু আমাদের কাছে আমদানি করার ডেটা আছে, আমরা যে Firebase ডাটাবেস ( default
) তৈরি করেছি তাতে ডেটা আমদানির চূড়ান্ত ধাপে যেতে পারি।
- নিচে দেওয়া gcloud কমান্ডটি ব্যবহার করুন:
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2025-01-27T05:11:02_62615
আমদানিতে কয়েক সেকেন্ড সময় লাগবে এবং এটি প্রস্তুত হয়ে গেলে, আপনি https://console.cloud.google.com/firestore/databases- এ গিয়ে আপনার Firestore ডাটাবেস এবং সংগ্রহটি যাচাই করতে পারেন, default
ডাটাবেস এবং poses
সংগ্রহটি নীচে দেখানো হিসাবে নির্বাচন করুন:
এটি Firestore সংগ্রহের তৈরি সম্পূর্ণ করে যা আমরা আমাদের অ্যাপ্লিকেশনে ব্যবহার করব।
7. ফায়ারস্টোরে ভেক্টর সাদৃশ্য অনুসন্ধান করুন৷
ভেক্টর সাদৃশ্য অনুসন্ধান করতে, আমরা ব্যবহারকারীর কাছ থেকে প্রশ্ন নেব। এই প্রশ্নের একটি উদাহরণ হতে পারে "Suggest me some exercises to relieve back pain"
।
search-data.js
ফাইলটি একবার দেখুন। দেখতে কী ফাংশন হল search
ফাংশন, যা নীচে দেখানো হয়েছে। একটি উচ্চ স্তরে, এটি একটি এমবেডিং ক্লাস তৈরি করে যা ব্যবহারকারীর প্রশ্নের জন্য এম্বেডিং তৈরি করতে ব্যবহার করা হবে। এটি তারপর ফায়ারস্টোর ডাটাবেস এবং সংগ্রহের সাথে একটি সংযোগ স্থাপন করে। তারপর সংগ্রহে এটি Find Nearest পদ্ধতির আহ্বান করে, যা একটি ভেক্টর সাদৃশ্য অনুসন্ধান করে।
async function search(query) {
try {
const embeddings = new VertexAIEmbeddings({
model: process.env.EMBEDDING_MODEL_NAME,
});
// Initialize Firestore
const firestore = new Firestore({
projectId: process.env.PROJECT_ID,
databaseId: process.env.DATABASE,
});
log.info(`Now executing query: ${query}`);
const singleVector = await embeddings.embedQuery(query);
const collectionRef = firestore.collection(process.env.COLLECTION);
let vectorQuery = collectionRef.findNearest(
"embedding",
FieldValue.vector(singleVector), // a vector with 768 dimensions
{
limit: process.env.TOP_K,
distanceMeasure: "COSINE",
}
);
const vectorQuerySnapshot = await vectorQuery.get();
for (const result of vectorQuerySnapshot.docs) {
console.log(result.data().content);
}
} catch (error) {
log.error(`Error during search: ${error.message}`);
}
}
আপনি কয়েকটি ক্যোয়ারী উদাহরণ সহ এটি চালানোর আগে, আপনাকে প্রথমে একটি Firestore কম্পোজিট সূচক তৈরি করতে হবে, যা আপনার অনুসন্ধান ক্যোয়ারী সফল হওয়ার জন্য প্রয়োজন। আপনি যদি সূচী তৈরি না করেই অ্যাপ্লিকেশনটি চালান, একটি ত্রুটি নির্দেশ করে যে আপনাকে প্রথমে সূচী তৈরি করতে হবে প্রথমে সূচী তৈরি করতে কমান্ডের সাথে প্রদর্শিত হবে।
যৌগিক সূচক তৈরি করার জন্য gcloud
কমান্ডটি নীচে দেখানো হয়েছে:
gcloud firestore indexes composite create --project=<YOUR_PROJECT_ID> --collection-group=poses --query-scope=COLLECTION --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=embedding
সূচকটি সম্পূর্ণ হতে কয়েক মিনিট সময় নেবে যেহেতু ডাটাবেসে উপস্থিত 150+ রেকর্ড রয়েছে৷ এটি সম্পূর্ণ হয়ে গেলে, আপনি নীচে দেখানো কমান্ডের মাধ্যমে সূচকটি দেখতে পারেন:
gcloud firestore indexes composite list
আপনি তালিকায় যে সূচীটি তৈরি করেছেন তা দেখতে হবে।
এখন নিম্নলিখিত কমান্ড ব্যবহার করে দেখুন:
node search-data.js --prompt "Recommend me some exercises for back pain relief"
আপনাকে দেওয়া কয়েকটি সুপারিশ থাকা উচিত। একটি নমুনা রান নীচে দেখানো হয়েছে:
2025-01-28T07:09:05.250Z - INFO - Now executing query: Recommend me some exercises for back pain relief
name: Sphinx Pose
description: A gentle backbend, Sphinx Pose (Salamba Bhujangasana) strengthens the spine and opens the chest. Keep shoulders relaxed, lengthen the tailbone, and engage the core for optimal alignment. Beginner-friendly.
sanskrit_name: Salamba Bhujangasana
expertise_level: Beginner
pose_type: ['Prone']
name: Supine Spinal Twist Pose
description: A gentle supine twist (Supta Matsyendrasana), great for beginners. Releases spinal tension, improves digestion, and calms the nervous system. Keep shoulders flat on the floor and lengthen your spine throughout the twist.
sanskrit_name: Supta Matsyendrasana
expertise_level: Beginner
pose_type: ['Supine', 'Twist']
name: Reverse Corpse Pose
description: Reverse Corpse Pose (Advasana) is a beginner prone pose. Lie on your belly, arms at your sides, relaxing completely. Benefits include stress release and spinal decompression. Ensure your forehead rests comfortably on the mat.
sanskrit_name: Advasana
expertise_level: Beginner
pose_type: ['Prone']
একবার আপনার কাজ হয়ে গেলে, আমরা এখন বুঝতে পেরেছি কিভাবে রেকর্ড আপলোড করতে, এম্বেডিং তৈরি করতে এবং একটি ভেক্টর সাদৃশ্য অনুসন্ধান করতে Firestore ভেক্টর ডেটাবেস কাজ করতে হয়। আমরা এখন একটি ওয়েব অ্যাপ্লিকেশন তৈরি করতে পারি যা একটি ওয়েব ফ্রন্ট-এন্ডে ভেক্টর অনুসন্ধানকে একীভূত করবে।
8. ওয়েব অ্যাপ্লিকেশন
পাইথন ফ্লাস্ক ওয়েব অ্যাপ্লিকেশনটি app.js
ফাইলে পাওয়া যায় এবং ফ্রন্ট-এন্ড HTML ফাইলটি views/index.html.
এটি সুপারিশ করা হয় যে আপনি উভয় ফাইল কটাক্ষপাত করুন. প্রথমে app.js
ফাইল দিয়ে শুরু করুন যেটিতে /search
হ্যান্ডলার রয়েছে, যা ফ্রন্ট-এন্ড HTML index.html
ফাইল থেকে পাস করা প্রম্পট নেয়। এটি তখন অনুসন্ধান পদ্ধতিটি আহ্বান করে, যা ভেক্টর সাদৃশ্য অনুসন্ধান করে যা আমরা পূর্ববর্তী বিভাগে দেখেছি।
এরপরে প্রতিক্রিয়াগুলি সুপারিশগুলির তালিকা সহ index.html
এ ফেরত পাঠানো হয়। index.html
তারপরে সুপারিশগুলি বিভিন্ন কার্ড হিসাবে প্রদর্শন করে।
স্থানীয়ভাবে অ্যাপ্লিকেশন চালান
একটি নতুন টার্মিনাল উইন্ডো (সিটিআরএল+শিফট+সি) বা কোনও বিদ্যমান টার্মিনাল উইন্ডো চালু করুন এবং নিম্নলিখিত কমান্ড দিন:
npm run start
একটি নমুনা মৃত্যুদন্ড নীচে দেখানো হয়েছে:
...
Server listening on port 8080
একবার এবং চলমান হয়ে গেলে, নীচে প্রদর্শিত ওয়েব পূর্বরূপ বোতামটি ক্লিক করে অ্যাপ্লিকেশনটির হোম ইউআরএল দেখুন:
এটি আপনাকে নীচে প্রদর্শিত হিসাবে পরিবেশন করা index.html
ফাইলটি দেখানো উচিত:
একটি নমুনা ক্যোয়ারী সরবরাহ করুন (উদাহরণ: Provide me some exercises for back pain relief
) এবং Search
বোতামে ক্লিক করুন। এটি ডাটাবেস থেকে কিছু সুপারিশ পুনরুদ্ধার করা উচিত। আপনি একটি Play Audio
বোতামও দেখতে পাবেন, যা বর্ণনার ভিত্তিতে একটি অডিও স্ট্রিম তৈরি করবে, যা আপনি সরাসরি শুনতে পারেন।
9। (al চ্ছিক) গুগল ক্লাউড রান মোতায়েন
আমাদের চূড়ান্ত পদক্ষেপটি এই অ্যাপ্লিকেশনটি গুগল ক্লাউড রানে স্থাপন করা হবে। ডিপ্লোয়মেন্ট কমান্ডটি নীচে দেখানো হয়েছে, নিশ্চিত করুন যে আপনি এটি স্থাপনের আগে, আপনি নীচে গা bold ়ভাবে প্রদর্শিত মানগুলি প্রতিস্থাপন করুন। এগুলি এমন মান যা আপনি .env
ফাইল থেকে পুনরুদ্ধার করতে সক্ষম হবেন।
gcloud run deploy yogaposes --source . \
--port=8080 \
--allow-unauthenticated \
--region=<<YOUR_LOCATION>> \
--platform=managed \
--project=<<YOUR_PROJECT_ID>> \
--set-env-vars=PROJECT_ID="<<YOUR_PROJECT_ID>>",LOCATION="<<YOUR_LOCATION>>",EMBEDDING_MODEL_NAME="<<EMBEDDING_MODEL_NAME>>",DATABASE="<<FIRESTORE_DATABASE_NAME>>",COLLECTION="<<FIRESTORE_COLLECTION_NAME>>",TOP_K=<<YOUR_TOP_K_VALUE>>
অ্যাপ্লিকেশনটির মূল ফোল্ডার থেকে উপরের কমান্ডটি কার্যকর করুন। আপনাকে গুগল ক্লাউড এপিআই সক্ষম করতে, বিভিন্ন অনুমতিগুলির জন্য আপনার স্বীকৃতি জানাতেও বলা হতে পারে, দয়া করে এটি করুন।
স্থাপনার প্রক্রিয়াটি সম্পূর্ণ হতে প্রায় 5-7 মিনিট সময় নেবে, তাই দয়া করে ধৈর্য ধরুন।
একবার সফলভাবে মোতায়েন হয়ে গেলে, স্থাপনার আউটপুট ক্লাউড রান পরিষেবা ইউআরএল সরবরাহ করবে। এটি ফর্ম হবে:
Service URL: https://yogaposes-<UNIQUEID>.us-central1.run.app
সেই পাবলিক ইউআরএল দেখুন এবং আপনার একই ওয়েব অ্যাপ্লিকেশনটি মোতায়েন করা এবং সফলভাবে চলমান দেখতে হবে।
আপনি গুগল ক্লাউড কনসোল থেকে ক্লাউড রানও দেখতে পারেন এবং আপনি ক্লাউড রানের পরিষেবাগুলির তালিকা দেখতে পাবেন। yogaposes
পরিষেবাটি সেখানে তালিকাভুক্ত পরিষেবাগুলির মধ্যে একটি হওয়া উচিত (যদি একমাত্র না হয়)।
আপনি নির্দিষ্ট পরিষেবার নাম (আমাদের ক্ষেত্রে yogaposes
) ক্লিক করে ইউআরএল, কনফিগারেশন, লগ এবং আরও অনেক কিছুর মতো পরিষেবার বিশদটি দেখতে পারেন।
এটি ক্লাউড রানে আমাদের যোগব্যায়াম পোজ সুপারিশকারী ওয়েব অ্যাপ্লিকেশনটির বিকাশ এবং স্থাপনা সম্পূর্ণ করে।
10। অভিনন্দন
অভিনন্দন, আপনি সফলভাবে এমন একটি অ্যাপ্লিকেশন তৈরি করেছেন যা ফায়ারস্টোরের জন্য একটি ডেটাসেট আপলোড করে, এম্বেডিংগুলি উত্পন্ন করে এবং ব্যবহারকারীদের ক্যোয়ারির উপর ভিত্তি করে একটি ভেক্টর সাদৃশ্য অনুসন্ধান করে।