কোডল্যাব - ফায়ারস্টোর, ভেক্টর অনুসন্ধান, ল্যাংচেইন এবং জেমিনি (পাইথন সংস্করণ) সহ একটি প্রাসঙ্গিক যোগ পোজ সুপারিশকারী অ্যাপ তৈরি করুন

১. ভূমিকা

এই কোডল্যাবে, আপনি এমন একটি অ্যাপ্লিকেশন তৈরি করবেন যা ভেক্টর সার্চ ব্যবহার করে যোগাসন সুপারিশ করে।

কোডল্যাবের মাধ্যমে, আপনি নিম্নলিখিত ধাপে ধাপে পদ্ধতিটি অনুসরণ করবেন:

  1. যোগাসনের একটি বিদ্যমান আলিঙ্গনরত মুখের ডেটাসেট (JSON ফরম্যাট) ব্যবহার করুন।
  2. একটি অতিরিক্ত ফিল্ড বিবরণ যোগ করে ডেটাসেটটিকে আরও উন্নত করুন, যা জেমিনি ব্যবহার করে প্রতিটি পোজের জন্য বিবরণ তৈরি করবে।
  3. ডকুমেন্ট তৈরি করতে ল্যাংচেইন ব্যবহার করুন, এবং ফায়ারস্টোরে কালেকশন ও এমবেডিং তৈরি করতে ফায়ারস্টোর ল্যাংচেইন ইন্টিগ্রেশন ব্যবহার করুন।
  4. ভেক্টর সার্চ সক্ষম করার জন্য ফায়ারস্টোরে একটি কম্পোজিট ইনডেক্স তৈরি করুন।
  5. একটি ফ্লাস্ক অ্যাপ্লিকেশনে ভেক্টর সার্চ ব্যবহার করুন যা নিচে দেখানো অনুযায়ী সবকিছুকে একত্রিত করে:

84e1cbf29cbaeedc.png

আপনি যা করবেন

  • এমন একটি ওয়েব অ্যাপ্লিকেশন ডিজাইন, বিল্ড এবং ডেপ্লয় করুন যা ভেক্টর সার্চ ব্যবহার করে যোগাসন সুপারিশ করে।

আপনি যা শিখবেন

  • কীভাবে জেমিনি ব্যবহার করে টেক্সট কন্টেন্ট তৈরি করা যায় এবং এই কোডল্যাবের প্রেক্ষাপটে, যোগাসনের জন্য বর্ণনা তৈরি করা যায়।
  • ভেক্টর এমবেডিংস সহ হাগিং ফেস-এর একটি উন্নত ডেটাসেট থেকে রেকর্ড লোড করতে ল্যাংচেইন ডকুমেন্ট লোডার ফর ফায়ারস্টোর কীভাবে ব্যবহার করবেন
  • স্বাভাবিক ভাষার কোয়েরির উপর ভিত্তি করে ডেটা অনুসন্ধান করতে ফায়ারস্টোরের জন্য ল্যাংচেইন ভেক্টর স্টোর কীভাবে ব্যবহার করবেন
  • গুগল ক্লাউড টেক্সট টু স্পিচ এপিআই ব্যবহার করে কীভাবে অডিও কন্টেন্ট তৈরি করা যায়

আপনার যা যা লাগবে

  • ক্রোম ওয়েব ব্রাউজার
  • একটি জিমেইল অ্যাকাউন্ট
  • বিলিং সক্ষম একটি ক্লাউড প্রজেক্ট

সকল স্তরের (শিক্ষানবিশ সহ) ডেভেলপারদের জন্য ডিজাইন করা এই কোডল্যাবটির নমুনা অ্যাপ্লিকেশনে পাইথন ব্যবহার করা হয়েছে। তবে, এখানে উপস্থাপিত ধারণাগুলো বোঝার জন্য পাইথন জ্ঞানের প্রয়োজন নেই।

২. শুরু করার আগে

একটি প্রকল্প তৈরি করুন

  1. গুগল ক্লাউড কনসোলের প্রজেক্ট সিলেক্টর পেজে, একটি গুগল ক্লাউড প্রজেক্ট নির্বাচন করুন বা তৈরি করুন।
  2. আপনার ক্লাউড প্রোজেক্টের জন্য বিলিং চালু আছে কিনা তা নিশ্চিত করুন। কোনো প্রোজেক্টে বিলিং চালু আছে কিনা তা কীভাবে পরীক্ষা করবেন, তা জেনে নিন।
  3. আপনি ক্লাউড শেল ব্যবহার করবেন, যা গুগল ক্লাউডে চলমান একটি কমান্ড-লাইন পরিবেশ এবং এটি bq-এর সাথে আগে থেকেই লোড করা থাকে। গুগল ক্লাউড কনসোলের শীর্ষে থাকা ‘Activate Cloud Shell’-এ ক্লিক করুন।

ক্লাউড শেল সক্রিয় করুন বোতামের ছবি

  1. ক্লাউড শেলে সংযুক্ত হওয়ার পর, আপনি নিম্নলিখিত কমান্ডটি ব্যবহার করে যাচাই করে নিন যে আপনি ইতিমধ্যেই প্রমাণীকৃত এবং প্রজেক্টটি আপনার প্রজেক্ট আইডিতে সেট করা আছে:
gcloud auth list
  1. gcloud কমান্ডটি আপনার প্রজেক্ট সম্পর্কে অবগত আছে কিনা, তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান।
gcloud config list project
  1. আপনার প্রজেক্টটি সেট করা না থাকলে, এটি সেট করতে নিম্নলিখিত কমান্ডটি ব্যবহার করুন:
gcloud config set project <YOUR_PROJECT_ID>
  1. নিচে দেখানো কমান্ডের মাধ্যমে প্রয়োজনীয় 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 বাদ পড়ে যায়, তাহলে আপনি বাস্তবায়ন চলাকালীন সময়েই তা সক্রিয় করে নিতে পারেন।

gcloud কমান্ড এবং এর ব্যবহার সম্পর্কে জানতে ডকুমেন্টেশন দেখুন।

রিপোজিটরি ক্লোন করুন এবং পরিবেশ সেটিংস সেটআপ করুন

পরবর্তী ধাপ হলো স্যাম্পল রিপোজিটরিটি ক্লোন করা, যা আমরা কোডল্যাবের বাকি অংশে রেফারেন্স হিসেবে ব্যবহার করব। ধরে নিন আপনি ক্লাউড শেলে আছেন, আপনার হোম ডিরেক্টরি থেকে নিম্নলিখিত কমান্ডটি দিন:

git clone https://github.com/rominirani/yoga-poses-recommender-python

এডিটর চালু করতে, ক্লাউড শেল উইন্ডোর টুলবারে থাকা ‘ওপেন এডিটর’-এ ক্লিক করুন। উপরের বাম কোণার মেনু বারে ক্লিক করুন এবং নিচে দেখানো অনুযায়ী ‘ফাইল → ওপেন ফোল্ডার’ নির্বাচন করুন:

66221fd0d0e5202f.png

yoga-poses-recommender-python ফোল্ডারটি নির্বাচন করুন এবং আপনি দেখবেন যে নিচে দেখানো ফাইলগুলি সহ ফোল্ডারটি খুলে গেছে:

44699efc7fb1b911.png

এখন আমাদের ব্যবহারযোগ্য এনভায়রনমেন্ট ভেরিয়েবলগুলো সেট করতে হবে। config.template.yaml ফাইলটিতে ক্লিক করুন এবং আপনি নীচে দেখানো বিষয়বস্তুর মতো কিছু দেখতে পাবেন:

project_id: your-project-id
location: us-central1
gemini_model_name: gemini-1.5-flash-002
embedding_model_name: text-embedding-004
image_generation_model_name: imagen-3.0-fast-generate-002
database: (default)
collection: poses
test_collection: test-poses
top_k: "3"

গুগল ক্লাউড প্রজেক্ট এবং ফায়ারস্টোর ডেটাবেস রিজিয়ন তৈরি করার সময় আপনি যা নির্বাচন করেছেন, সেই অনুযায়ী project_id এবং location এর মান আপডেট করুন। আদর্শগতভাবে, আমরা চাই গুগল ক্লাউড প্রজেক্ট এবং ফায়ারস্টোর ডেটাবেস উভয়ের জন্যই location এর মান একই হোক, যেমন us-central1

এই কোডল্যাবের জন্য, আমরা আগে থেকে কনফিগার করা মানগুলোই ব্যবহার করব (অবশ্যই project_id এবং location বাদে, যেগুলো আপনাকে আপনার কনফিগারেশন অনুযায়ী সেট করতে হবে)।

অনুগ্রহ করে এই ফাইলটি config.yaml ফাইলের সাথে একই ফোল্ডারে config.template.yaml নামে সংরক্ষণ করুন।

এখন শেষ ধাপ হলো একটি পাইথন এনভায়রনমেন্ট তৈরি করা, যা আমরা স্থানীয়ভাবে ব্যবহার করব এবং যেখানে আমাদের জন্য সমস্ত পাইথন ডিপেন্ডেন্সি সেট আপ করা থাকবে। pyproject.toml ফাইলটি দেখুন, যেখানে এর বিস্তারিত বিবরণ রয়েছে, যার বিষয়বস্তু নিচে দেখানো হলো:

dependencies = [
    "datasets>=3.2.0",
    "flask>=3.1.0",
    "google-cloud-aiplatform>=1.78.0",
    "google-cloud-texttospeech>=2.24.0",
    "langchain-community>=0.3.15",
    "langchain-core>=0.3.31",
    "langchain-google-community>=2.0.4",
    "langchain-google-firestore>=0.5.0",
    "langchain-google-vertexai>=2.0.7",
    "pydantic-settings>=2.7.1",
    "pyyaml>=6.0.2",
    "tenacity>=9.0.0",
]

এই ডিপেন্ডেন্সিগুলো requirements.txt ফাইলে আগে থেকেই ভার্সন লক করা আছে . সংক্ষেপে, আমাদের requirements.txt ফাইলে থাকা পাইথন প্যাকেজ ডিপেন্ডেন্সিগুলো সহ একটি ভার্চুয়াল পাইথন এনভায়রনমেন্ট তৈরি করতে হবে, যা ভার্চুয়াল এনভায়রনমেন্টে ইনস্টল করা হবে। এটি করার জন্য, Cloud Shell IDE-এর Command Palette (Ctrl+Shift+P)-এ যান এবং Python: Create Environment টাইপ করুন। একটি Virtual Environment(venv) , Python 3.x interpreter এবং requirements.txt ফাইলটি নির্বাচন করার জন্য পরবর্তী কয়েকটি ধাপ অনুসরণ করুন।

পরিবেশটি তৈরি হয়ে গেলে, নিম্নলিখিত কমান্ডের সাহায্যে সেটিকে সক্রিয় করতে হবে।

source .venv/bin/activate

আপনার কনসোলে (.venv) দেখতে পাবেন। যেমন -> (.venv) yourusername@cloudshell:

চমৎকার! আমরা এখন ফায়ারস্টোর ডাটাবেস সেটআপ করার কাজে এগিয়ে যাওয়ার জন্য পুরোপুরি প্রস্তুত।

৩. ফায়ারস্টোর সেটআপ করুন

ক্লাউড ফায়ারস্টোর হলো একটি সম্পূর্ণভাবে পরিচালিত সার্ভারবিহীন ডকুমেন্ট ডেটাবেস, যা আমরা আমাদের অ্যাপ্লিকেশন ডেটার ব্যাকএন্ড হিসেবে ব্যবহার করব। ক্লাউড ফায়ারস্টোরের ডেটা ডকুমেন্টের কালেকশন আকারে বিন্যস্ত থাকে।

ফায়ারস্টোর ডেটাবেস প্রারম্ভিককরণ

ক্লাউড কনসোলে ফায়ারস্টোর পৃষ্ঠাটি পরিদর্শন করুন।

যদি আপনি প্রজেক্টে আগে কোনো ফায়ারস্টোর ডাটাবেস তৈরি না করে থাকেন, তাহলে Create Database এ ক্লিক করে default ডাটাবেসটি তৈরি করুন। ডাটাবেস তৈরির সময়, নিম্নলিখিত মানগুলি ব্যবহার করুন:

  • ফায়ারস্টোর মোড: Native.
  • অবস্থানের ধরণ হিসেবে Region নির্বাচন করুন এবং অঞ্চলের জন্য us-central1 অবস্থানটি নির্বাচন করুন।
  • নিরাপত্তা বিধির জন্য Test rules অনুসরণ করুন।
  • ডাটাবেসটি তৈরি করুন।

61d0277510803c8d.png

পরবর্তী অংশে, আমরা আমাদের ডিফল্ট ফায়ারস্টোর ডেটাবেসে ' poses নামের একটি কালেকশন তৈরির ভিত্তি স্থাপন করব। এই কালেকশনটিতে নমুনা ডেটা (ডকুমেন্ট) বা যোগাসনের তথ্য থাকবে, যা আমরা পরবর্তীতে আমাদের অ্যাপ্লিকেশনে ব্যবহার করব।

এর মাধ্যমে ফায়ারস্টোর ডাটাবেস সেটআপ করার পর্বটি সম্পন্ন হলো।

৪. যোগাসনের ডেটাসেট প্রস্তুত করুন।

আমাদের প্রথম কাজ হলো অ্যাপ্লিকেশনটির জন্য ব্যবহৃত যোগাসনের ডেটাসেটটি প্রস্তুত করা। আমরা একটি বিদ্যমান হাগিং ফেস ডেটাসেট দিয়ে শুরু করব এবং তারপর অতিরিক্ত তথ্য দিয়ে এটিকে সমৃদ্ধ করব।

যোগাসনের জন্য হাগিং ফেস ডেটাসেটটি দেখুন। উল্লেখ্য যে, যদিও এই কোডল্যাবটি ডেটাসেটগুলোর মধ্যে একটি ব্যবহার করে, আপনি চাইলে অন্য যেকোনো ডেটাসেটও ব্যবহার করতে পারেন এবং ডেটাসেটটিকে উন্নত করার জন্য প্রদর্শিত একই কৌশলগুলো অনুসরণ করতে পারেন।

298cfae7f23e4bef.png

আমরা যদি Files and versions বিভাগে যাই, তাহলে সমস্ত পোজের জন্য JSON ডেটা ফাইলটি পেতে পারি।

3fe6e55abdc032ec.png

আমরা yoga_poses.json ফাইলটি ডাউনলোড করে আপনাকে দিয়েছি। এই ফাইলটির নাম yoga_poses_alldata.json এবং এটি /data ফোল্ডারে রয়েছে।

ক্লাউড শেল এডিটরে থাকা data/yoga_poses.json ফাইলটিতে যান এবং JSON অবজেক্টগুলোর তালিকাটি দেখুন, যেখানে প্রতিটি JSON অবজেক্ট একটি যোগাসনকে নির্দেশ করে। এখানে মোট ৩টি রেকর্ড রয়েছে এবং নিচে একটি নমুনা রেকর্ড দেখানো হলো:

{
   "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.py ফাইলটিতে যান। এই ফাইলটির বিষয়বস্তু নিচে দেখানো হলো:

import json
import time
import logging
import vertexai
from langchain_google_vertexai import VertexAI
from tenacity import retry, stop_after_attempt, wait_exponential
from settings import get_settings

settings = get_settings()
logging.basicConfig(
    level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)
# Initialize Vertex AI SDK
vertexai.init(project=settings.project_id, location=settings.location)
logging.info("Done Initializing Vertex AI SDK")


@retry(
    stop=stop_after_attempt(5),
    wait=wait_exponential(multiplier=1, min=4, max=10),
)
def generate_description(pose_name, sanskrit_name, expertise_level, pose_types):
    """Generates a description for a yoga pose using the Gemini API."""

    prompt = f"""
    Generate a concise description (max 50 words) for the yoga pose: {pose_name}
    Also known as: {sanskrit_name}
    Expertise Level: {expertise_level}
    Pose Type: {", ".join(pose_types)}

    Include key benefits and any important alignment cues.
    """
    try:
        model = VertexAI(model_name=settings.gemini_model_name, verbose=True)
        response = model.invoke(prompt)
        return response
    except Exception as e:
        logging.info(f"Error generating description for {pose_name}: {e}")
        return ""


def add_descriptions_to_json(input_file, output_file):
    """Loads JSON data, adds descriptions, and saves the updated data."""

    with open(input_file, "r") as f:
        yoga_poses = json.load(f)

    total_poses = len(yoga_poses)
    processed_count = 0

    for pose in yoga_poses:
        if pose["name"] != " Pose":
            start_time = time.time()  # Record start time
            pose["description"] = generate_description(
                pose["name"],
                pose["sanskrit_name"],
                pose["expertise_level"],
                pose["pose_type"],
            )
            end_time = time.time()  # Record end time

            processed_count += 1
            end_time = time.time()  # Record end time
            time_taken = end_time - start_time
            logging.info(
                f"Processed: {processed_count}/{total_poses} - {pose['name']} ({time_taken:.2f} seconds)"
            )

        else:
            pose["description"] = ""
            processed_count += 1
            logging.info(
                f"Processed: {processed_count}/{total_poses} - {pose['name']} ({time_taken:.2f} seconds)"
            )
        # Adding a delay to avoid rate limit
        time.sleep(30)

    with open(output_file, "w") as f:
        json.dump(yoga_poses, f, indent=2)


def main():
    # File paths
    input_file = "./data/yoga_poses.json"
    output_file = "./data/yoga_poses_with_descriptions.json"

    # Add descriptions and save the updated JSON
    add_descriptions_to_json(input_file, output_file)


if __name__ == "__main__":
    main()

এই অ্যাপ্লিকেশনটি প্রতিটি যোগাসনের JSON রেকর্ডে একটি নতুন description ক্ষেত্র যোগ করবে। এটি জেমিনি মডেলে একটি কলের মাধ্যমে বিবরণটি সংগ্রহ করবে, যেখানে আমরা এটিকে প্রয়োজনীয় প্রম্পট সরবরাহ করব। ক্ষেত্রটি JSON ফাইলে যোগ করা হয় এবং নতুন ফাইলটি data/yoga_poses_with_descriptions.json ফাইলে লেখা হয়।

চলুন প্রধান ধাপগুলো দেখে নেওয়া যাক:

  1. main() ফাংশনের ভেতরে আপনি দেখতে পাবেন যে, এটি add_descriptions_to_json ফাংশনটিকে কল করে এবং প্রত্যাশিত ইনপুট ও আউটপুট ফাইল সরবরাহ করে।
  2. add_descriptions_to_json ফাংশনটি প্রতিটি JSON রেকর্ডের জন্য, অর্থাৎ যোগা পোস্টের তথ্যের জন্য, নিম্নলিখিত কাজগুলো করে থাকে:
  3. এটি pose_name , sanskrit_name , expertise_level এবং pose_types বের করে আনে।
  4. এটি `generate_description` ফাংশনটিকে কল করে, যা একটি প্রম্পট তৈরি করে এবং তারপরে প্রতিক্রিয়ার টেক্সটটি পাওয়ার জন্য `Langchain VertexAI` মডেল ক্লাসটিকে কল করে।
  5. এরপর এই প্রতিক্রিয়া টেক্সটটি JSON অবজেক্টে যোগ করা হয়।
  6. এরপর অবজেক্টগুলোর হালনাগাদকৃত JSON তালিকাটি গন্তব্য ফাইলে লেখা হয়।

চলুন এই অ্যাপ্লিকেশনটি চালানো যাক। একটি নতুন টার্মিনাল উইন্ডো খুলুন (Ctrl+Shift+C) এবং নিম্নলিখিত কমান্ডটি দিন:

python generate-descriptions.py

যদি আপনার কাছে কোনো অনুমতি চাওয়া হয়, তবে অনুগ্রহ করে তা প্রদান করুন।

আপনি দেখবেন যে অ্যাপ্লিকেশনটি চালু হতে শুরু করেছে। নতুন গুগল ক্লাউড অ্যাকাউন্টগুলিতে থাকতে পারে এমন কোনো রেট লিমিট কোটা এড়ানোর জন্য আমরা রেকর্ডগুলির মধ্যে ৩০ সেকেন্ডের একটি বিলম্ব যোগ করেছি, তাই অনুগ্রহ করে ধৈর্য ধরুন।

চলমান একটি নমুনা রান নিচে দেখানো হলো:

8e830d9ea9b6c60.png

একবার জেমিনি কলের মাধ্যমে তিনটি রেকর্ডই উন্নত করা হয়ে গেলে, data/yoga_poses_with_description.json নামের একটি ফাইল তৈরি হবে। আপনি সেটি দেখে নিতে পারেন।

আমাদের ডেটা ফাইল এখন প্রস্তুত এবং পরবর্তী ধাপ হলো এমবেডিং জেনারেশন সহ, কীভাবে এটি দিয়ে একটি ফায়ারস্টোর ডেটাবেস পূরণ করতে হয় তা বোঝা।

৫. ফায়ারস্টোরে ডেটা ইম্পোর্ট করুন এবং ভেক্টর এমবেডিং তৈরি করুন

আমাদের কাছে data/yoga_poses_with_description.json ফাইলটি আছে এবং এখন আমাদের এটি দিয়ে ফায়ারস্টোর ডেটাবেসটি পূরণ করতে হবে এবং সবচেয়ে গুরুত্বপূর্ণভাবে, প্রতিটি রেকর্ডের জন্য ভেক্টর এমবেডিং তৈরি করতে হবে। এই ভেক্টর এমবেডিংগুলো পরবর্তীতে কাজে আসবে, যখন আমাদের ব্যবহারকারীর স্বাভাবিক ভাষায় দেওয়া কোয়েরির সাথে এগুলোর সাদৃশ্য অনুসন্ধান করতে হবে।

উপরোক্ত প্রক্রিয়াটি বাস্তবায়নের জন্য আমরা ল্যাংচেইন ফায়ারস্টোর কম্পোনেন্টগুলো ব্যবহার করব।

তা করার ধাপগুলো নিম্নরূপ হবে:

  1. আমরা JSON অবজেক্টের তালিকাটিকে Langchain ডকুমেন্ট অবজেক্টের একটি তালিকায় রূপান্তর করব। প্রতিটি ডকুমেন্টের দুটি অ্যাট্রিবিউট থাকবে: page_content এবং metadata । metadata অবজেক্টটিতে সম্পূর্ণ JSON অবজেক্টটি থাকবে, যেটিতে name , description , sanskrit_name ইত্যাদির মতো অ্যাট্রিবিউটগুলো রয়েছে। page_content হবে একটি স্ট্রিং টেক্সট, যা কয়েকটি ফিল্ডের সংযোগে গঠিত হবে।
  2. একবার আমাদের কাছে Document অবজেক্টের একটি তালিকা চলে এলে, আমরা এই ডকুমেন্টের তালিকা, একটি কালেকশনের নাম (আমরা TEST_COLLECTION ভেরিয়েবলটি ব্যবহার করছি যা test-poses কে নির্দেশ করে), একটি Vertex AI Embedding ক্লাস এবং FirestoreVectorStore সংযোগের বিবরণ ( PROJECT_ID এবং from_documents DATABASE নাম) সহ FirestoreVectorStore Langchain ক্লাস এবং বিশেষত from_documents মেথডটি ব্যবহার করব। এটি কালেকশনটি তৈরি করবে এবং প্রতিটি অ্যাট্রিবিউটের জন্য একটি করে embedding ফিল্ডও তৈরি করবে।

import-data.py এর কোড নিচে দেওয়া হলো (সংক্ষিপ্ততার জন্য কোডের কিছু অংশ ছেঁটে ফেলা হয়েছে):

... 

def create_langchain_documents(poses):
   """Creates a list of Langchain Documents from a list of poses."""
   documents = []
   for pose in poses:
       # Convert the pose to a string representation for page_content
       page_content = (
           f"name: {pose.get('name', '')}\n"
           f"description: {pose.get('description', '')}\n"
           f"sanskrit_name: {pose.get('sanskrit_name', '')}\n"
           f"expertise_level: {pose.get('expertise_level', 'N/A')}\n"
           f"pose_type: {pose.get('pose_type', 'N/A')}\n"
       ).strip()
       # The metadata will be the whole pose
       metadata = pose

       document = Document(page_content=page_content, metadata=metadata)
       documents.append(document)
   logging.info(f"Created {len(documents)} Langchain documents.")
   return documents

def main():
    all_poses = load_yoga_poses_data_from_local_file(
        "./data/yoga_poses_with_descriptions.json"
    )
    documents = create_langchain_documents(all_poses)
    logging.info(
        f"Successfully created langchain documents. Total documents: {len(documents)}"
    )

    embedding = VertexAIEmbeddings(
        model_name=settings.embedding_model_name,
        project=settings.project_id,
        location=settings.location,
    )

    client = firestore.Client(project=settings.project_id, database=settings.database)

    vector_store = FirestoreVectorStore.from_documents(
        client=client,
        collection=settings.test_collection,
        documents=documents,
        embedding=embedding,
    )
    logging.info("Added documents to the vector store.")


if __name__ == "__main__":
    main()

চলুন এই অ্যাপ্লিকেশনটি চালানো যাক। একটি নতুন টার্মিনাল উইন্ডো খুলুন (Ctrl+Shift+C) এবং নিম্নলিখিত কমান্ডটি দিন:

python import-data.py

সবকিছু ঠিকঠাক থাকলে, আপনি নিচেরটির মতো একটি বার্তা দেখতে পাবেন:

2025-01-21 14:50:06,479 - INFO - Added documents to the vector store.

রেকর্ডগুলি সফলভাবে সন্নিবেশিত হয়েছে কিনা এবং এমবেডিংগুলি তৈরি হয়েছে কিনা তা পরীক্ষা করতে, ক্লাউড কনসোলে ফায়ারস্টোর পৃষ্ঠাটি দেখুন।

504cabdb99a222a5.png

(ডিফল্ট) ডেটাবেসে ক্লিক করুন, এতে ' test-poses কালেকশন এবং তার অধীনে একাধিক ডকুমেন্ট দেখা যাবে। প্রতিটি ডকুমেন্ট হলো একটি যোগাসন।

d0708499e403aebc.png

ফিল্ডগুলো খতিয়ে দেখতে যেকোনো একটি ডকুমেন্টে ক্লিক করুন। আমাদের ইম্পোর্ট করা ফিল্ডগুলো ছাড়াও আপনি embedding ফিল্ডটিও পাবেন, যেটি একটি ভেক্টর ফিল্ড এবং আমাদের ব্যবহৃত Langchain VertexAIEmbeddings ক্লাসের মাধ্যমে আপনার জন্য স্বয়ংক্রিয়ভাবে তৈরি করা হয়েছে, যেখানে আমরা text-embedding-004 Vertex AI Embedding মডেলটি সরবরাহ করেছি।

d67113e2dc63cd6b.png

এখন যেহেতু আমরা এমবেডিং সহ রেকর্ডগুলো ফায়ারস্টোর ডেটাবেসে আপলোড করে ফেলেছি, আমরা পরবর্তী ধাপে যেতে পারি এবং দেখতে পারি ফায়ারস্টোরে কীভাবে ভেক্টর সিমিলারিটি সার্চ করতে হয়।

৬. ফায়ারস্টোর ডেটাবেস সংগ্রহে সম্পূর্ণ যোগাসনগুলো ইম্পোর্ট করুন।

আমরা এখন poses কালেকশনটি তৈরি করব, যা হলো ১৬০টি যোগাসনের একটি সম্পূর্ণ তালিকা। এর জন্য আমরা একটি ডাটাবেস ইম্পোর্ট ফাইল তৈরি করেছি যা আপনি সরাসরি ইম্পোর্ট করতে পারবেন। ল্যাবে সময় বাঁচানোর জন্যই এটি করা হয়। যে ডাটাবেসে বর্ণনা এবং এমবেডিংগুলো থাকে, তা তৈরি করার প্রক্রিয়াটি আগের অংশে দেখা পদ্ধতির মতোই।

নিচে দেওয়া ধাপগুলো অনুসরণ করে ডাটাবেস ইম্পোর্ট করুন:

  1. নিচে দেওয়া gsutil কমান্ডটি ব্যবহার করে আপনার প্রজেক্টে একটি বাকেট তৈরি করুন। নিচের কমান্ডে থাকা <PROJECT_ID> ভেরিয়েবলটির জায়গায় আপনার গুগল ক্লাউড প্রজেক্ট আইডি বসান।
gsutil mb -l us-central1 gs://<PROJECT_ID>-my-bucket
  1. বাকেটটি তৈরি হয়ে গেলে, ফায়ারবেস ডেটাবেসে ইম্পোর্ট করার আগে, আমাদের প্রস্তুত করা ডেটাবেস এক্সপোর্টটি এই বাকেটে কপি করতে হবে। নিচে দেওয়া কমান্ডটি ব্যবহার করুন:
gsutil cp -r gs://yoga-database-firestore-export-bucket/2025-01-27T05:11:02_62615  gs://<PROJECT_ID>-my-bucket

এখন যেহেতু আমাদের কাছে ইম্পোর্ট করার জন্য ডেটা আছে, আমরা আমাদের তৈরি করা ফায়ারবেস ডেটাবেসে ( default ) ডেটা ইম্পোর্ট করার চূড়ান্ত ধাপে যেতে পারি।

  1. নিচে দেওয়া gcloud কমান্ডটি ব্যবহার করুন:
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2025-01-27T05:11:02_62615

ইম্পোর্ট হতে কয়েক সেকেন্ড সময় লাগবে এবং এটি প্রস্তুত হয়ে গেলে, আপনি https://console.cloud.google.com/firestore/databases- এ গিয়ে আপনার ফায়ারস্টোর ডেটাবেস এবং কালেকশনটি যাচাই করতে পারবেন, এবং নিচে দেখানো অনুযায়ী default ডেটাবেস ও poses কালেকশনটি নির্বাচন করুন:

a8f5a6ba69bec69b.png

এর মাধ্যমে আমাদের অ্যাপ্লিকেশনে ব্যবহৃত ফায়ারস্টোর কালেকশনটি তৈরি সম্পন্ন হলো।

৭. ফায়ারস্টোরে ভেক্টর সাদৃশ্য অনুসন্ধান সম্পাদন করুন

ভেক্টর সিমিলারিটি সার্চ করার জন্য, আমরা ব্যবহারকারীর কাছ থেকে কোয়েরিটি নেব। এই কোয়েরির একটি উদাহরণ হতে পারে "Suggest me some exercises to relieve back pain"

search-data.py ফাইলটি দেখুন। এখানে দেখার মতো মূল ফাংশনটি হলো search ফাংশন, যা নিচে দেখানো হলো। সহজ ভাষায় বলতে গেলে, এটি একটি embedding ক্লাস তৈরি করে যা ব্যবহারকারীর কোয়েরির জন্য embedding তৈরি করতে ব্যবহৃত হবে। এরপর এটি FirestoreVectorStore ক্লাস ব্যবহার করে এর similarity_search ফাংশনটিকে কল করে।

def search(query: str):
    """Executes Firestore Vector Similarity Search"""
    embedding = VertexAIEmbeddings(
        model_name=settings.embedding_model_name,
        project=settings.project_id,
        location=settings.location,
    )

    client = firestore.Client(project=settings.project_id, database=settings.database)

    vector_store = FirestoreVectorStore(
        client=client, collection=settings.collection, embedding_service=embedding
    )

    logging.info(f"Now executing query: {query}")
    results: list[Document] = vector_store.similarity_search(
        query=query, k=int(settings.top_k), include_metadata=True
    )
    for result in results:
        print(result.page_content)

কয়েকটি কোয়েরি উদাহরণ দিয়ে এটি চালানোর আগে, আপনাকে প্রথমে একটি ফায়ারস্টোর কম্পোজিট ইনডেক্স তৈরি করতে হবে, যা আপনার সার্চ কোয়েরিগুলো সফল হওয়ার জন্য প্রয়োজন। ইনডেক্স তৈরি না করে অ্যাপ্লিকেশনটি চালালে, প্রথমে ইনডেক্স তৈরি করার কমান্ডসহ একটি এরর প্রদর্শিত হবে, যা নির্দেশ করবে যে আপনাকে প্রথমে ইনডেক্সটি তৈরি করতে হবে।

কম্পোজিট ইনডেক্স তৈরি করার জন্য 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

ডাটাবেসে ১৫০টিরও বেশি রেকর্ড থাকায় ইনডেক্সটি সম্পূর্ণ হতে কয়েক মিনিট সময় লাগবে। এটি সম্পূর্ণ হয়ে গেলে, আপনি নিচে দেখানো কমান্ডটির মাধ্যমে ইনডেক্সটি দেখতে পারবেন:

gcloud firestore indexes composite list

আপনি এইমাত্র তৈরি করা ইনডেক্সটি তালিকায় দেখতে পাবেন।

এখন নিম্নলিখিত কমান্ডটি ব্যবহার করে দেখুন:

python search-data.py --prompt "Recommend me some exercises for back pain relief"

আপনাকে কয়েকটি সুপারিশ প্রদান করা হবে। নিচে একটি নমুনা রান দেখানো হলো:

2025-01-21 15:48:51,282 - INFO - Now executing query: Recommend me some exercises for back pain relief
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 the spine.

sanskrit_name: Supta Matsyendrasana
expertise_level: Beginner
pose_type: ['Supine', 'Twist']
name: Cow Pose
description: Cow Pose (Bitilasana) is a gentle backbend, stretching the chest, shoulders, and abdomen.  Maintain a neutral spine, lengthen the tailbone, and avoid hyperextension.  Benefits include improved posture and stress relief.

sanskrit_name: Bitilasana
expertise_level: Beginner
pose_type: ['Arm Leg Support', 'Back Bend']
name: Locust I Pose
description: Locust Pose I (Shalabhasana A) strengthens the back, glutes, and shoulders.  Lie prone, lift chest and legs simultaneously, engaging back muscles.  Keep hips grounded and gaze slightly forward.

sanskrit_name: Shalabhasana A
expertise_level: Intermediate
pose_type: ['Prone', 'Back Bend']

একবার এটি চালু হয়ে গেলে, আমরা এখন বুঝে গেছি কীভাবে ফায়ারস্টোর ভেক্টর ডেটাবেস ব্যবহার করে রেকর্ড আপলোড করতে, এমবেডিং তৈরি করতে এবং ভেক্টর সিমিলারিটি সার্চ করতে হয়। আমরা এখন একটি ওয়েব অ্যাপ্লিকেশন তৈরি করতে পারি যা এই ভেক্টর সার্চটিকে একটি ওয়েব ফ্রন্ট-এন্ডের সাথে একীভূত করবে।

৮. ওয়েব অ্যাপ্লিকেশন

পাইথন ফ্লাস্ক ওয়েব অ্যাপ্লিকেশনটি main.py ফাইলে এবং ফ্রন্ট-এন্ড HTML ফাইলটি templates/index.html.

উভয় ফাইলই দেখে নেওয়ার পরামর্শ দেওয়া হচ্ছে। প্রথমে main.py ফাইলটি দিয়ে শুরু করুন, যেটিতে /search হ্যান্ডলারটি রয়েছে। এই হ্যান্ডলারটি ফ্রন্ট-এন্ড HTML index.html ফাইল থেকে পাঠানো প্রম্পটটি গ্রহণ করে। এরপর এটি search মেথডটিকে কল করে, যা ভেক্টর সিমিলারিটি সার্চটি সম্পন্ন করে, যা আমরা পূর্ববর্তী অংশে আলোচনা করেছি।

এরপর সুপারিশগুলোর তালিকা সহ প্রতিক্রিয়াটি index.html এ ফেরত পাঠানো হয়। তারপর index.html সুপারিশগুলোকে আলাদা আলাদা কার্ড হিসেবে প্রদর্শন করে।

অ্যাপ্লিকেশনটি স্থানীয়ভাবে চালান

একটি নতুন টার্মিনাল উইন্ডো (Ctrl+Shift+C) অথবা যেকোনো বিদ্যমান টার্মিনাল উইন্ডো চালু করুন এবং নিম্নলিখিত কমান্ডটি দিন:

python main.py

নিচে একটি নমুনা কার্যসম্পাদন দেখানো হলো:

 * Serving Flask app 'main'
 * Debug mode: on
2025-01-21 16:02:37,473 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:8080
 * Running on http://10.88.0.4:8080
2025-01-21 16:02:37,473 - INFO - Press CTRL+C to quit
2025-01-21 16:02:37,474 - INFO -  * Restarting with stat
2025-01-21 16:02:41,462 - WARNING -  * Debugger is active!
2025-01-21 16:02:41,484 - INFO -  * Debugger PIN: 440-653-555

একবার চালু হয়ে গেলে, নিচে দেখানো ওয়েব প্রিভিউ বোতামটিতে ক্লিক করে অ্যাপ্লিকেশনটির হোম ইউআরএল-এ যান:

de297d4cee10e0bf.png

এটি আপনাকে index.html ফাইলটি নিচে দেখানো অনুযায়ী পরিবেশন করবে:

20240a0e885ac17b.png

একটি নমুনা কোয়েরি দিন (উদাহরণ: Provide me some exercises for back pain relief ) এবং Search বাটনে ক্লিক করুন। এটি ডাটাবেস থেকে কিছু সুপারিশ নিয়ে আসবে। আপনি একটি Play Audio বাটনও দেখতে পাবেন, যা বর্ণনার উপর ভিত্তি করে একটি অডিও স্ট্রিম তৈরি করবে, যা আপনি সরাসরি শুনতে পারবেন।

789b4277dc40e2be.png

৯. (ঐচ্ছিক) গুগল ক্লাউড রান-এ ডেপ্লয় করা

আমাদের চূড়ান্ত ধাপ হবে এই অ্যাপ্লিকেশনটি গুগল ক্লাউড রান-এ ডেপ্লয় করা। ডেপ্লয়মেন্ট কমান্ডটি নিচে দেখানো হলো, ডেপ্লয় করার আগে নিশ্চিত করুন যে আপনি ভেরিয়েবলের (<<YOUR_PROJECT_ID>>) মানগুলো আপনার প্রোজেক্টের নির্দিষ্ট মান দিয়ে প্রতিস্থাপন করেছেন। এই মানগুলো আপনি config.yaml ফাইল থেকে সংগ্রহ করতে পারবেন।

gcloud run deploy yogaposes --source . \
  --port=8080 \
  --allow-unauthenticated \
  --region=us-central1 \
  --platform=managed  \
  --project=<<YOUR_PROJECT_ID>> \
  --env-vars-file=config.yaml

অ্যাপ্লিকেশনটির রুট ফোল্ডার থেকে উপরের কমান্ডটি চালান। আপনাকে গুগল ক্লাউড এপিআই (Google Cloud APIs) সক্রিয় করতেও বলা হতে পারে এবং বিভিন্ন অনুমতির জন্য আপনার সম্মতি জানাতে বলা হলে, অনুগ্রহ করে তা করুন।

স্থাপন প্রক্রিয়াটি সম্পন্ন হতে প্রায় ৫-৭ মিনিট সময় লাগবে, তাই অনুগ্রহ করে ধৈর্য ধরুন।

3a6d86fd32e4a5e.png

সফলভাবে ডেপ্লয়মেন্ট সম্পন্ন হলে, ডেপ্লয়মেন্ট আউটপুটে ক্লাউড রান সার্ভিস ইউআরএলটি দেওয়া হবে। এটি দেখতে এইরকম হবে:

Service URL: https://yogaposes-<<UNIQUEID>.us-central1.run.app

ওই পাবলিক ইউআরএল-টি ভিজিট করলে আপনি দেখবেন যে একই ওয়েব অ্যাপ্লিকেশনটি সফলভাবে ডেপ্লয় হয়ে চলছে।

84e1cbf29cbaeedc.png

আপনি গুগল ক্লাউড কনসোল থেকেও ক্লাউড রান-এ যেতে পারেন এবং সেখানে সার্ভিসগুলোর তালিকা দেখতে পাবেন। সেখানে তালিকাভুক্ত সার্ভিসগুলোর মধ্যে yogaposes সার্ভিসটি একটি হওয়া উচিত (যদি একমাত্রটি না-ও হয়)।

f2b34a8c9011be4c.png

নির্দিষ্ট সার্ভিসের নামে (আমাদের ক্ষেত্রে yogaposes ) ক্লিক করে আপনি সার্ভিসটির ইউআরএল, কনফিগারেশন, লগ এবং আরও অনেক কিছুর বিস্তারিত তথ্য দেখতে পারেন।

faaa5e0c02fe0423.png

এর মাধ্যমে ক্লাউড রান-এ আমাদের যোগাসন সুপারিশকারী ওয়েব অ্যাপ্লিকেশনটির উন্নয়ন এবং স্থাপন সম্পন্ন হলো।

১০. অভিনন্দন

অভিনন্দন, আপনি সফলভাবে এমন একটি অ্যাপ্লিকেশন তৈরি করেছেন যা ফায়ারস্টোরে একটি ডেটাসেট আপলোড করে, এমবেডিং তৈরি করে এবং ব্যবহারকারীর কোয়েরির উপর ভিত্তি করে ভেক্টর সিমিলারিটি সার্চ করে।

রেফারেন্স নথি