পাইপলাইন সহ ভার্টেক্স এমএল মেটাডেটা ব্যবহার করা

১. সংক্ষিপ্ত বিবরণ

এই ল্যাবে, আপনি Vertex ML Metadata ব্যবহার করে আপনার Vertex Pipelines রান থেকে মেটাডেটা বিশ্লেষণ করার পদ্ধতি শিখবেন।

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

আপনি শিখবেন কীভাবে:

  • Kubeflow Pipelines SDK ব্যবহার করে এমন একটি ML পাইপলাইন তৈরি করুন যা Vertex AI-তে একটি ডেটাসেট তৈরি করে এবং সেই ডেটাসেটের উপর একটি কাস্টম Scikit-learn মডেলকে প্রশিক্ষণ ও স্থাপন করে।
  • আর্টিফ্যাক্ট এবং মেটাডেটা তৈরি করে এমন কাস্টম পাইপলাইন কম্পোনেন্ট লিখুন।
  • ক্লাউড কনসোল এবং প্রোগ্রাম্যাটিকভাবে, উভয় ক্ষেত্রেই ভার্টেক্স পাইপলাইন রানগুলোর তুলনা করুন।
  • পাইপলাইন-উৎপাদিত আর্টিফ্যাক্টগুলির বংশধারা সন্ধান করুন
  • আপনার পাইপলাইন রান মেটাডেটা অনুসন্ধান করুন

গুগল ক্লাউডে এই ল্যাবটি চালানোর মোট খরচ প্রায় ২ ডলার

২. ভার্টেক্স এআই-এর পরিচিতি

এই ল্যাবটি গুগল ক্লাউডে উপলব্ধ সর্বাধুনিক এআই প্রোডাক্টটি ব্যবহার করে। ভার্টেক্স এআই গুগল ক্লাউডের এমএল অফারিংগুলোকে একটি নির্বিঘ্ন ডেভেলপমেন্ট অভিজ্ঞতায় একীভূত করে। পূর্বে, অটোএমএল (AutoML) দিয়ে প্রশিক্ষিত মডেল এবং কাস্টম মডেলগুলো আলাদা সার্ভিসের মাধ্যমে অ্যাক্সেস করা যেত। নতুন অফারিংটি অন্যান্য নতুন প্রোডাক্টের সাথে উভয়কে একটি একক এপিআই-তে একত্রিত করেছে। আপনি আপনার বিদ্যমান প্রোজেক্টগুলোও ভার্টেক্স এআই-তে মাইগ্রেট করতে পারেন।

মডেল প্রশিক্ষণ এবং ডেপ্লয়মেন্ট পরিষেবা ছাড়াও, ভার্টেক্স এআই-এর বিভিন্ন ধরনের এমএলওপিএস (MLOps) পণ্য রয়েছে, যার মধ্যে ভার্টেক্স পাইপলাইন, এমএল মেটাডেটা, মডেল মনিটরিং, ফিচার স্টোর এবং আরও অনেক কিছু অন্তর্ভুক্ত। আপনি নিচের ডায়াগ্রামে ভার্টেক্স এআই-এর সমস্ত পণ্য দেখতে পারেন।

ভার্টেক্স পণ্যের সংক্ষিপ্ত বিবরণ

এই ল্যাবে ভার্টেক্স পাইপলাইন এবং ভার্টেক্স এমএল মেটাডেটার উপর আলোকপাত করা হয়েছে।

Vertex AI সম্পর্কে আপনার কোনো মতামত থাকলে, অনুগ্রহ করে সাপোর্ট পেজটি দেখুন।

এমএল পাইপলাইনগুলো কেন দরকারি?

বিস্তারিত আলোচনার আগে, চলুন প্রথমে বুঝে নিই কেন আপনি একটি পাইপলাইন ব্যবহার করতে চাইবেন। কল্পনা করুন, আপনি একটি এমএল (ML) ওয়ার্কফ্লো তৈরি করছেন, যার মধ্যে রয়েছে ডেটা প্রসেসিং, মডেল ট্রেনিং, হাইপারপ্যারামিটার টিউনিং, ইভ্যালুয়েশন এবং মডেল ডেপ্লয়মেন্ট। এই প্রতিটি ধাপের মধ্যে বিভিন্ন নির্ভরশীলতা থাকতে পারে, যা পুরো ওয়ার্কফ্লোটিকে একটি একক সত্তা হিসেবে বিবেচনা করলে নিয়ন্ত্রণ করা কঠিন হয়ে উঠতে পারে। যখন আপনি আপনার এমএল প্রসেসকে বড় পরিসরে নিয়ে যেতে শুরু করবেন, তখন আপনি আপনার টিমের অন্যদের সাথে আপনার এমএল ওয়ার্কফ্লো শেয়ার করতে চাইতে পারেন, যাতে তারা এটি চালাতে পারে এবং কোড দিয়ে অবদান রাখতে পারে। একটি নির্ভরযোগ্য ও পুনরাবৃত্তিযোগ্য প্রসেস ছাড়া এটি কঠিন হয়ে উঠতে পারে। পাইপলাইনের মাধ্যমে, আপনার এমএল প্রসেসের প্রতিটি ধাপই তার নিজস্ব একটি কন্টেইনার হিসেবে কাজ করে। এটি আপনাকে ধাপগুলো স্বাধীনভাবে তৈরি করতে এবং প্রতিটি ধাপের ইনপুট ও আউটপুটকে একটি পুনরাবৃত্তিযোগ্য উপায়ে ট্র্যাক করতে দেয়। এছাড়াও, আপনি আপনার ক্লাউড এনভায়রনমেন্টের অন্যান্য ইভেন্টের উপর ভিত্তি করে আপনার পাইপলাইনের রান শিডিউল করতে বা ট্রিগার করতে পারেন, যেমন নতুন ট্রেনিং ডেটা উপলব্ধ হলে একটি পাইপলাইন রান শুরু করা।

সারসংক্ষেপ হলো : পাইপলাইন আপনাকে আপনার এমএল ওয়ার্কফ্লো স্বয়ংক্রিয় করতে এবং এর পুনরাবৃত্তি করতে সাহায্য করে।

৩. ক্লাউড পরিবেশ সেটআপ

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

ক্লাউড শেল শুরু করুন

এই ল্যাবে আপনি একটি ক্লাউড শেল সেশনে কাজ করবেন, যা গুগলের ক্লাউডে চলমান একটি ভার্চুয়াল মেশিনে হোস্ট করা একটি কমান্ড ইন্টারপ্রেটার। আপনি চাইলে এই অংশটি আপনার নিজের কম্পিউটারেও চালাতে পারতেন, কিন্তু ক্লাউড শেল ব্যবহার করলে প্রত্যেকেই একটি সামঞ্জস্যপূর্ণ পরিবেশে পুনরায় করার মতো অভিজ্ঞতা লাভ করতে পারে। ল্যাবের পরে, আপনি আপনার নিজের কম্পিউটারে এই অংশটি আবার চেষ্টা করতে পারেন।

ক্লাউড শেল অনুমোদন করুন

ক্লাউড শেল সক্রিয় করুন

ক্লাউড কনসোলের উপরের ডান দিক থেকে, ক্লাউড শেল সক্রিয় করতে নিচের বোতামটিতে ক্লিক করুন:

ক্লাউড শেল সক্রিয় করুন

আপনি যদি আগে কখনো ক্লাউড শেল চালু না করে থাকেন, তাহলে এটি কী তা বর্ণনা করে একটি মধ্যবর্তী স্ক্রিন (নিচে দেওয়া আছে) আপনার সামনে আসবে। যদি তাই হয়, তাহলে 'Continue'-তে ক্লিক করুন (এবং আপনি এটি আর কখনো দেখতে পাবেন না)। একবারের জন্য আসা সেই স্ক্রিনটি দেখতে এইরকম:

ক্লাউড শেল সেটআপ

ক্লাউড শেল প্রস্তুত করতে এবং এর সাথে সংযোগ স্থাপন করতে মাত্র কয়েক মুহূর্ত সময় লাগা উচিত।

ক্লাউড শেল ইনিট

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

ক্লাউড শেলে সংযুক্ত হওয়ার পর আপনি দেখতে পাবেন যে, আপনাকে ইতিমধ্যেই প্রমাণীকৃত করা হয়েছে এবং প্রজেক্টটি আপনার প্রজেক্ট আইডিতে সেট করা আছে।

আপনি প্রমাণীকৃত কিনা তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:

gcloud auth list

কমান্ড আউটপুট

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

gcloud কমান্ডটি আপনার প্রজেক্ট সম্পর্কে জানে কিনা তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:

gcloud config list project

কমান্ড আউটপুট

[core]
project = <PROJECT_ID>

যদি তা না থাকে, তবে আপনি এই কমান্ডটি দিয়ে এটি সেট করতে পারেন:

gcloud config set project <PROJECT_ID>

কমান্ড আউটপুট

Updated property [core/project].

ক্লাউড শেলে কয়েকটি এনভায়রনমেন্ট ভেরিয়েবল আছে, যার মধ্যে GOOGLE_CLOUD_PROJECT অন্যতম, যেটিতে আমাদের বর্তমান ক্লাউড প্রজেক্টের নামটি রয়েছে। এই ল্যাব জুড়ে আমরা বিভিন্ন জায়গায় এটি ব্যবহার করব। নিম্নলিখিত কমান্ডটি চালিয়ে আপনি এটি দেখতে পারেন:

echo $GOOGLE_CLOUD_PROJECT

এপিআই সক্ষম করুন

পরবর্তী ধাপগুলোতে আপনি দেখতে পাবেন এই সার্ভিসগুলো কোথায় (এবং কেন) প্রয়োজন, কিন্তু আপাতত, আপনার প্রোজেক্টকে Compute Engine, Container Registry, এবং Vertex AI সার্ভিসগুলোতে অ্যাক্সেস দেওয়ার জন্য এই কমান্ডটি চালান:

gcloud services enable compute.googleapis.com         \
                       containerregistry.googleapis.com  \
                       aiplatform.googleapis.com

এর ফলে এইটির মতো একটি সফল বার্তা তৈরি হওয়া উচিত:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

একটি ক্লাউড স্টোরেজ বাকেট তৈরি করুন

Vertex AI-তে একটি ট্রেনিং জব চালানোর জন্য, আমাদের সংরক্ষিত মডেল অ্যাসেটগুলো রাখার জন্য একটি স্টোরেজ বাকেট প্রয়োজন হবে। বাকেটটি আঞ্চলিক হতে হবে। আমরা এখানে us-central ব্যবহার করছি, কিন্তু আপনি অন্য কোনো অঞ্চলও ব্যবহার করতে পারেন (শুধু এই ল্যাব জুড়ে সেটি পরিবর্তন করে দেবেন)। আপনার যদি আগে থেকেই একটি বাকেট থাকে, তাহলে আপনি এই ধাপটি বাদ দিতে পারেন।

একটি বাকেট তৈরি করতে আপনার ক্লাউড শেল টার্মিনালে নিম্নলিখিত কমান্ডগুলি চালান:

BUCKET_NAME=gs://$GOOGLE_CLOUD_PROJECT-bucket
gsutil mb -l us-central1 $BUCKET_NAME

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

gcloud projects describe $GOOGLE_CLOUD_PROJECT > project-info.txt
PROJECT_NUM=$(cat project-info.txt | sed -nre 's:.*projectNumber\: (.*):\1:p')
SVC_ACCOUNT="${PROJECT_NUM//\'/}-compute@developer.gserviceaccount.com"
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT --member serviceAccount:$SVC_ACCOUNT --role roles/storage.objectAdmin

একটি ভার্টেক্স এআই ওয়ার্কবেঞ্চ ইনস্ট্যান্স তৈরি করুন

আপনার ক্লাউড কনসোলের Vertex AI সেকশন থেকে Workbench-এ ক্লিক করুন:

ভার্টেক্স এআই মেনু

সেখান থেকে, ব্যবহারকারী-পরিচালিত নোটবুকগুলোর মধ্যে, নতুন নোটবুক-এ ক্লিক করুন:

নতুন নোটবুক তৈরি করুন

তারপর GPU ছাড়া TensorFlow Enterprise 2.3 (LTS সহ) ইনস্ট্যান্স টাইপটি নির্বাচন করুন:

TFE উদাহরণ

ডিফল্ট অপশনগুলো ব্যবহার করুন এবং তারপর তৈরি করুন-এ ক্লিক করুন।

আপনার নোটবুকটি খুলুন

ইনস্ট্যান্সটি তৈরি হয়ে গেলে, Open JupyterLab নির্বাচন করুন:

খোলা নোটবুক

৪. ভার্টেক্স পাইপলাইন সেটআপ

ভার্টেক্স পাইপলাইন ব্যবহার করার জন্য আমাদের আরও কয়েকটি লাইব্রেরি ইনস্টল করতে হবে:

  • কুবেফ্লো পাইপলাইনস : এটি সেই এসডিকে যা আমরা আমাদের পাইপলাইন তৈরি করতে ব্যবহার করব। ভার্টেক্স পাইপলাইনস কুবেফ্লো পাইপলাইনস বা টিএফএক্স উভয় দিয়েই তৈরি পাইপলাইন চালানো সমর্থন করে।
  • ভার্টেক্স এআই এসডিকে : এই এসডিকে ভার্টেক্স এআই এপিআই কল করার অভিজ্ঞতাকে অপ্টিমাইজ করে। আমরা ভার্টেক্স এআই-তে আমাদের পাইপলাইন চালানোর জন্য এটি ব্যবহার করব।

পাইথন নোটবুক তৈরি করুন এবং লাইব্রেরি ইনস্টল করুন

প্রথমে, আপনার নোটবুক ইনস্ট্যান্সের লঞ্চার মেনু থেকে পাইথন ৩ নির্বাচন করে একটি নোটবুক তৈরি করুন:

পাইথন৩ নোটবুক তৈরি করুন

এই ল্যাবে আমরা যে দুটি সার্ভিস ব্যবহার করব তা ইনস্টল করার জন্য, প্রথমে একটি নোটবুক সেলে ইউজার ফ্ল্যাগটি সেট করুন:

USER_FLAG = "--user"

তারপর আপনার নোটবুক থেকে নিম্নলিখিতটি চালান:

!pip3 install {USER_FLAG} google-cloud-aiplatform==1.7.0
!pip3 install {USER_FLAG} kfp==1.8.9

এই প্যাকেজগুলো ইনস্টল করার পর আপনাকে কার্নেলটি পুনরায় চালু করতে হবে:

import os

if not os.getenv("IS_TESTING"):
    # Automatically restart kernel after installs
    import IPython

    app = IPython.Application.instance()
    app.kernel.do_shutdown(True)

এরপর, যাচাই করুন যে আপনি KFP SDK সংস্করণটি সঠিকভাবে ইনস্টল করেছেন। এটি অবশ্যই >=1.8 হতে হবে:

!python3 -c "import kfp; print('KFP SDK version: {}'.format(kfp.__version__))"

এরপর নিশ্চিত করুন যে আপনার Vertex AI SDK ভার্সনটি 1.6.2 বা তার চেয়ে বড়।

!pip list | grep aiplatform

আপনার প্রজেক্ট আইডি এবং বাকেট সেট করুন

এই ল্যাব জুড়ে আপনি আপনার ক্লাউড প্রজেক্ট আইডি এবং পূর্বে তৈরি করা বাকেটটি ব্যবহার করবেন। এরপর আমরা সেগুলোর প্রত্যেকটির জন্য ভ্যারিয়েবল তৈরি করব।

আপনি যদি আপনার প্রজেক্ট আইডি না জানেন, তাহলে নিম্নলিখিত কমান্ডটি চালিয়ে তা পেতে পারেন:

import os
PROJECT_ID = ""

# Get your Google Cloud project ID from gcloud
if not os.getenv("IS_TESTING"):
    shell_output=!gcloud config list --format 'value(core.project)' 2>/dev/null
    PROJECT_ID = shell_output[0]
    print("Project ID: ", PROJECT_ID)

অন্যথায়, এটি এখানে সেট করুন:

if PROJECT_ID == "" or PROJECT_ID is None:
    PROJECT_ID = "your-project-id"  # @param {type:"string"}

এরপর আপনার বাকেটের নাম সংরক্ষণের জন্য একটি ভ্যারিয়েবল তৈরি করুন। যদি আপনি এই ল্যাবে এটি তৈরি করে থাকেন, তাহলে নিম্নলিখিতটি কাজ করবে। অন্যথায়, আপনাকে এটি ম্যানুয়ালি সেট করতে হবে:

BUCKET_NAME="gs://" + PROJECT_ID + "-bucket"

লাইব্রেরি আমদানি করুন

এই কোডল্যাব জুড়ে আমরা যে লাইব্রেরিগুলো ব্যবহার করব, সেগুলো ইম্পোর্ট করতে নিম্নলিখিতগুলো যোগ করুন:

import matplotlib.pyplot as plt
import pandas as pd

from kfp.v2 import compiler, dsl
from kfp.v2.dsl import pipeline, component, Artifact, Dataset, Input, Metrics, Model, Output, InputPath, OutputPath

from google.cloud import aiplatform

# We'll use this namespace for metadata querying
from google.cloud import aiplatform_v1

ধ্রুবক সংজ্ঞায়িত করুন

আমাদের পাইপলাইন তৈরি করার আগে শেষ যে কাজটি করতে হবে তা হলো কিছু ধ্রুবক ভেরিয়েবল নির্ধারণ করা। PIPELINE_ROOT হলো ক্লাউড স্টোরেজের সেই পাথ, যেখানে আমাদের পাইপলাইন দ্বারা তৈরি আর্টিফ্যাক্টগুলো লেখা হবে। আমরা এখানে অঞ্চল হিসেবে us-central1 ব্যবহার করছি, কিন্তু আপনি যদি আপনার বাকেট তৈরি করার সময় অন্য কোনো অঞ্চল ব্যবহার করে থাকেন, তাহলে নিচের কোডে REGION ভেরিয়েবলটি আপডেট করুন:

PATH=%env PATH
%env PATH={PATH}:/home/jupyter/.local/bin
REGION="us-central1"

PIPELINE_ROOT = f"{BUCKET_NAME}/pipeline_root/"
PIPELINE_ROOT

উপরের কোডটি চালানোর পর, আপনার পাইপলাইনের রুট ডিরেক্টরিটি প্রিন্ট হতে দেখবেন। এটি হলো ক্লাউড স্টোরেজের সেই অবস্থান যেখানে আপনার পাইপলাইনের আর্টিফ্যাক্টগুলো লেখা হবে। এটি gs://YOUR-BUCKET-NAME/pipeline_root/ ফরম্যাটে থাকবে।

৫. কাস্টম উপাদান ব্যবহার করে একটি ৩-ধাপের পাইপলাইন তৈরি করা

এই ল্যাবের মূল উদ্দেশ্য হলো পাইপলাইন রান থেকে মেটাডেটা বোঝা। তা করার জন্য, আমাদের ভার্টেক্স পাইপলাইনে চালানোর মতো একটি পাইপলাইন প্রয়োজন হবে, এবং আমরা সেখান থেকেই শুরু করব। এখানে আমরা নিম্নলিখিত কাস্টম কম্পোনেন্টগুলো সহ একটি ৩-ধাপের পাইপলাইন সংজ্ঞায়িত করব:

  • get_dataframe : BigQuery টেবিল থেকে ডেটা নিয়ে তাকে Pandas DataFrame-এ রূপান্তর করুন।
  • train_sklearn_model : কিছু মেট্রিক্স সহ একটি Scikit Learn মডেলকে প্রশিক্ষণ দিতে এবং রপ্তানি করতে Pandas DataFrame ব্যবহার করুন।
  • deploy_model : এক্সপোর্ট করা Scikit Learn মডেলটিকে Vertex AI-এর একটি এন্ডপয়েন্টে ডিপ্লয় করুন।

এই পাইপলাইনে, আমরা KOKLU, M. এবং OZKAN, IA, (2020), "Multiclass Classification of Dry Beans Using Computer Vision and Machine Learning Techniques." In Computers and Electronics in Agriculture, 174, 105507. DOI থেকে প্রাপ্ত UCI মেশিন লার্নিং শুকনো শিম ডেটাসেটটি ব্যবহার করব।

এটি একটি সারণীভিত্তিক ডেটাসেট, এবং আমাদের পাইপলাইনে আমরা এই ডেটাসেটটি ব্যবহার করে একটি স্কিকিট-লার্ন মডেলকে প্রশিক্ষণ, মূল্যায়ন এবং স্থাপন করব, যা শিমের বৈশিষ্ট্যের উপর ভিত্তি করে সেগুলোকে ৭টি প্রকারের মধ্যে যেকোনো একটিতে শ্রেণীবদ্ধ করবে। চলুন কোডিং শুরু করা যাক!

পাইথন ফাংশন ভিত্তিক উপাদান তৈরি করুন

কেএফপি এসডিকে ব্যবহার করে আমরা পাইথন ফাংশনের ওপর ভিত্তি করে কম্পোনেন্ট তৈরি করতে পারি। এই পাইপলাইনের ৩টি কম্পোনেন্টের জন্য আমরা সেটিই ব্যবহার করব।

BigQuery ডেটা ডাউনলোড করুন এবং CSV তে রূপান্তর করুন

প্রথমে, আমরা get_dataframe কম্পোনেন্টটি তৈরি করব:

@component(
    packages_to_install=["google-cloud-bigquery", "pandas", "pyarrow", "db-dtypes"],
    base_image="python:3.9",
    output_component_file="create_dataset.yaml"
)
def get_dataframe(
    bq_table: str,
    output_data_path: OutputPath("Dataset")
):
    from google.cloud import bigquery
    import pandas as pd
    import os

    project_number = os.environ["CLOUD_ML_PROJECT_ID"]
    bqclient = bigquery.Client(project=project_number)
    table = bigquery.TableReference.from_string(
        bq_table
    )
    rows = bqclient.list_rows(
        table
    )
    dataframe = rows.to_dataframe(
        create_bqstorage_client=True,
    )
    dataframe = dataframe.sample(frac=1, random_state=2)
    dataframe.to_csv(output_data_path)

চলুন এই কম্পোনেন্টটিতে কী ঘটছে তা আরও ভালোভাবে খতিয়ে দেখি:

  • @component ডেকোরেটরটি পাইপলাইন রান করার সময় এই ফাংশনটিকে একটি কম্পোনেন্টে কম্পাইল করে। আপনি যখনই কোনো কাস্টম কম্পোনেন্ট লিখবেন, তখনই এটি ব্যবহার করবেন।
  • base_image প্যারামিটারটি নির্দিষ্ট করে যে এই কম্পোনেন্টটি কোন কন্টেইনার ইমেজ ব্যবহার করবে।
  • এই কম্পোনেন্টটি কয়েকটি পাইথন লাইব্রেরি ব্যবহার করবে, যেগুলো আমরা packages_to_install প্যারামিটারের মাধ্যমে নির্দিষ্ট করে দিই।
  • output_component_file প্যারামিটারটি ঐচ্ছিক, এবং এটি সেই yaml ফাইলটি নির্দিষ্ট করে যেখানে কম্পাইল করা কম্পোনেন্টটি লেখা হবে। সেলটি রান করার পর আপনি আপনার নোটবুক ইনস্ট্যান্সে ফাইলটি লেখা দেখতে পাবেন। আপনি যদি এই কম্পোনেন্টটি কারও সাথে শেয়ার করতে চান, তাহলে আপনি তাদের তৈরি করা yaml ফাইলটি পাঠাতে পারেন এবং নিম্নলিখিত কমান্ড ব্যবহার করে তাদের এটি লোড করতে বলতে পারেন:
# This is optional, it shows how to load a component from a yaml file
# dataset_component = kfp.components.load_component_from_file('./create_dataset.yaml')
  • এরপরে, এই কম্পোনেন্টটি BigQuery পাইথন ক্লায়েন্ট লাইব্রেরি ব্যবহার করে BigQuery থেকে আমাদের ডেটা একটি Pandas DataFrame-এ ডাউনলোড করে এবং তারপর সেই ডেটা থেকে একটি CSV ফাইল হিসেবে আউটপুট তৈরি করে। এটি আমাদের পরবর্তী কম্পোনেন্টে ইনপুট হিসেবে পাঠানো হবে।

একটি স্কিকিট-লার্ন মডেল প্রশিক্ষণের জন্য একটি কম্পোনেন্ট তৈরি করুন।

এই অংশে আমরা পূর্বে তৈরি করা CSV ফাইলটি ব্যবহার করে একটি Scikit-learn ডিসিশন ট্রি মডেলকে প্রশিক্ষণ দেব। এই অংশটি ফলাফলস্বরূপ প্রাপ্ত Scikit মডেলটিকে এক্সপোর্ট করে, সাথে একটি Metrics আর্টিফ্যাক্টও পাঠায়, যাতে আমাদের মডেলের অ্যাকুরেসি, ফ্রেমওয়ার্ক এবং এটিকে প্রশিক্ষণ দিতে ব্যবহৃত ডেটাসেটের আকার অন্তর্ভুক্ত থাকে।

@component(
    packages_to_install=["sklearn", "pandas", "joblib", "db-dtypes"],
    base_image="python:3.9",
    output_component_file="beans_model_component.yaml",
)
def sklearn_train(
    dataset: Input[Dataset],
    metrics: Output[Metrics],
    model: Output[Model]
):
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.metrics import roc_curve
    from sklearn.model_selection import train_test_split
    from joblib import dump

    import pandas as pd
    df = pd.read_csv(dataset.path)
    labels = df.pop("Class").tolist()
    data = df.values.tolist()
    x_train, x_test, y_train, y_test = train_test_split(data, labels)

    skmodel = DecisionTreeClassifier()
    skmodel.fit(x_train,y_train)
    score = skmodel.score(x_test,y_test)
    print('accuracy is:',score)

    metrics.log_metric("accuracy",(score * 100.0))
    metrics.log_metric("framework", "Scikit Learn")
    metrics.log_metric("dataset_size", len(df))
    dump(skmodel, model.path + ".joblib")

Vertex AI-তে মডেলটি আপলোড ও ডেপ্লয় করার জন্য একটি কম্পোনেন্ট নির্ধারণ করুন।

অবশেষে, আমাদের শেষ অংশটি পূর্ববর্তী ধাপ থেকে প্রশিক্ষিত মডেলটি নেবে, সেটিকে Vertex AI-তে আপলোড করবে এবং একটি এন্ডপয়েন্টে স্থাপন করবে:

@component(
    packages_to_install=["google-cloud-aiplatform"],
    base_image="python:3.9",
    output_component_file="beans_deploy_component.yaml",
)
def deploy_model(
    model: Input[Model],
    project: str,
    region: str,
    vertex_endpoint: Output[Artifact],
    vertex_model: Output[Model]
):
    from google.cloud import aiplatform

    aiplatform.init(project=project, location=region)

    deployed_model = aiplatform.Model.upload(
        display_name="beans-model-pipeline",
        artifact_uri = model.uri.replace("model", ""),
        serving_container_image_uri="us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.0-24:latest"
    )
    endpoint = deployed_model.deploy(machine_type="n1-standard-4")

    # Save data to the output params
    vertex_endpoint.uri = endpoint.resource_name
    vertex_model.uri = deployed_model.resource_name

এখানে আমরা প্রেডিকশনের জন্য একটি প্রি-বিল্ট কন্টেইনার ব্যবহার করে মডেলটি আপলোড করতে ভার্টেক্স এআই এসডিকে (Vertex AI SDK) ব্যবহার করছি। এরপর এটি মডেলটিকে একটি এন্ডপয়েন্টে ডেপ্লয় করে এবং মডেল ও এন্ডপয়েন্ট রিসোর্স উভয়ের ইউআরআই (URI) ফেরত দেয়। এই কোডল্যাবের পরবর্তী অংশে, এই ডেটাকে আর্টিফ্যাক্ট হিসেবে ফেরত দেওয়ার অর্থ কী, সে সম্পর্কে আপনি আরও জানতে পারবেন।

পাইপলাইনটি সংজ্ঞায়িত এবং সংকলন করুন

এখন যেহেতু আমরা আমাদের তিনটি উপাদান সংজ্ঞায়িত করেছি, এরপর আমরা আমাদের পাইপলাইন সংজ্ঞা তৈরি করব। এটি বর্ণনা করে যে কীভাবে ইনপুট এবং আউটপুট আর্টিফ্যাক্টগুলো বিভিন্ন ধাপের মধ্যে প্রবাহিত হয়:

@pipeline(
    # Default pipeline root. You can override it when submitting the pipeline.
    pipeline_root=PIPELINE_ROOT,
    # A name for the pipeline.
    name="mlmd-pipeline",
)
def pipeline(
    bq_table: str = "",
    output_data_path: str = "data.csv",
    project: str = PROJECT_ID,
    region: str = REGION
):
    dataset_task = get_dataframe(bq_table)

    model_task = sklearn_train(
        dataset_task.output
    )

    deploy_task = deploy_model(
        model=model_task.outputs["model"],
        project=project,
        region=region
    )

নিম্নলিখিতটি একটি JSON ফাইল তৈরি করবে যা আপনি পাইপলাইনটি চালানোর জন্য ব্যবহার করবেন:

compiler.Compiler().compile(
    pipeline_func=pipeline, package_path="mlmd_pipeline.json"
)

দুটি পাইপলাইন রান শুরু করুন

এরপর আমরা আমাদের পাইপলাইনের দুটি রান চালু করব। প্রথমে, আমাদের পাইপলাইন জব আইডিগুলোর জন্য একটি টাইমস্ট্যাম্প নির্ধারণ করা যাক:

from datetime import datetime

TIMESTAMP = datetime.now().strftime("%Y%m%d%H%M%S")

মনে রাখবেন যে, আমাদের পাইপলাইনটি চালানোর সময় একটি প্যারামিটার গ্রহণ করে: সেটি হলো bq_table যা আমরা ট্রেনিং ডেটা হিসেবে ব্যবহার করতে চাই। এই পাইপলাইন রানটি beans ডেটাসেটের একটি ছোট সংস্করণ ব্যবহার করবে:

run1 = aiplatform.PipelineJob(
    display_name="mlmd-pipeline",
    template_path="mlmd_pipeline.json",
    job_id="mlmd-pipeline-small-{0}".format(TIMESTAMP),
    parameter_values={"bq_table": "sara-vertex-demos.beans_demo.small_dataset"},
    enable_caching=True,
)

এরপরে, একই ডেটাসেটের একটি বৃহত্তর সংস্করণ ব্যবহার করে আরেকটি পাইপলাইন রান তৈরি করুন।

run2 = aiplatform.PipelineJob(
    display_name="mlmd-pipeline",
    template_path="mlmd_pipeline.json",
    job_id="mlmd-pipeline-large-{0}".format(TIMESTAMP),
    parameter_values={"bq_table": "sara-vertex-demos.beans_demo.large_dataset"},
    enable_caching=True,
)

অবশেষে, উভয় রানের জন্য পাইপলাইন এক্সিকিউশন চালু করুন। এটি দুটি আলাদা নোটবুক সেলে করাই শ্রেয়, যাতে আপনি প্রতিটি রানের আউটপুট দেখতে পারেন।

run1.submit()

তারপর, দ্বিতীয় রান শুরু করুন:

run2.submit()

এই সেলটি রান করার পর, আপনি ভার্টেক্স এআই কনসোলে প্রতিটি পাইপলাইন দেখার জন্য একটি লিঙ্ক দেখতে পাবেন। আপনার পাইপলাইন সম্পর্কে আরও বিস্তারিত জানতে সেই লিঙ্কটি খুলুন:

পাইপলাইন রান ইউআরএল

এটি সম্পূর্ণ হলে (এই পাইপলাইনটি প্রতিবার চলতে প্রায় ১০-১৫ মিনিট সময় নেয়), আপনি এইরকম কিছু দেখতে পাবেন:

sklearn পাইপলাইন সম্পন্ন হয়েছে

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

৬. পাইপলাইন আর্টিফ্যাক্ট এবং লিনিয়েজ বোঝা

আপনার পাইপলাইন গ্রাফে, আপনি প্রতিটি ধাপের পরে ছোট ছোট বাক্স দেখতে পাবেন। এগুলো হলো আর্টিফ্যাক্ট , বা পাইপলাইনের কোনো ধাপ থেকে তৈরি হওয়া আউটপুট। আর্টিফ্যাক্ট অনেক ধরনের হয়। এই নির্দিষ্ট পাইপলাইনটিতে আমাদের ডেটাসেট, মেট্রিক্স, মডেল এবং এন্ডপয়েন্ট আর্টিফ্যাক্ট রয়েছে। প্রতিটি সম্পর্কে আরও বিস্তারিত দেখতে UI-এর উপরের দিকে থাকা 'Expand Artifacts' স্লাইডারটিতে ক্লিক করুন:

আর্টিফ্যাক্ট প্রসারিত করুন

কোনো আর্টিফ্যাক্টে ক্লিক করলে আপনি সেটির URI সহ আরও বিস্তারিত তথ্য দেখতে পাবেন। উদাহরণস্বরূপ, vertex_endpoint আর্টিফ্যাক্টটিতে ক্লিক করলে আপনাকে সেই URI দেখানো হবে, যেখানে আপনি আপনার Vertex AI কনসোলে সেই ডেপ্লয় করা এন্ডপয়েন্টটি খুঁজে পাবেন:

এন্ডপয়েন্ট আর্টিফ্যাক্টের বিবরণ

একটি Metrics আর্টিফ্যাক্ট আপনাকে নির্দিষ্ট পাইপলাইন স্টেপের সাথে যুক্ত কাস্টম মেট্রিক্স পাস করার সুযোগ দেয়। আমাদের পাইপলাইনের sklearn_train কম্পোনেন্টে, আমরা আমাদের মডেলের অ্যাকুরেসি, ফ্রেমওয়ার্ক এবং ডেটাসেট সাইজের মেট্রিক্স লগ করেছি। সেই বিবরণগুলো দেখতে মেট্রিক্স আর্টিফ্যাক্টটিতে ক্লিক করুন:

মডেল মেট্রিক্স

প্রতিটি আর্টিফ্যাক্টের একটি বংশধারা (Lineage) থাকে, যা এর সাথে সংযুক্ত অন্যান্য আর্টিফ্যাক্টগুলোর বর্ণনা দেয়। আপনার পাইপলাইনের vertex_endpoint আর্টিফ্যাক্টটিতে আবার ক্লিক করুন, এবং তারপর 'View Lineage' বোতামটিতে ক্লিক করুন:

বংশধারা দেখান

এটি একটি নতুন ট্যাব খুলবে যেখানে আপনি আপনার নির্বাচিতটির সাথে সংযুক্ত সমস্ত নিদর্শন দেখতে পাবেন। আপনার বংশবৃত্তান্ত গ্রাফটি দেখতে অনেকটা এইরকম হবে:

এন্ডপয়েন্ট লিনিয়েজ গ্রাফ

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

৭. পাইপলাইন রানের তুলনা

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

পাইপলাইন UI-তে রানগুলির তুলনা

ক্লাউড কনসোলে, আপনার পাইপলাইন ড্যাশবোর্ডে যান। এটি আপনার চালানো প্রতিটি পাইপলাইন রানের একটি সার্বিক চিত্র প্রদান করে। শেষ দুটি রান যাচাই করুন এবং তারপর উপরে থাকা ' Compare ' বোতামটিতে ক্লিক করুন:

রানগুলির তুলনা করুন

এটি আমাদেরকে এমন একটি পৃষ্ঠায় নিয়ে যায় যেখানে আমরা নির্বাচিত প্রতিটি রানের জন্য ইনপুট প্যারামিটার এবং মেট্রিক্স তুলনা করতে পারি। এই দুটি রানের ক্ষেত্রে, ভিন্ন BigQuery টেবিল, ডেটাসেটের আকার এবং অ্যাকুরেসি মানগুলো লক্ষ্য করুন:

তুলনা মেট্রিক্স

আপনি এই UI কার্যকারিতা ব্যবহার করে দুইয়ের অধিক রান, এমনকি ভিন্ন ভিন্ন পাইপলাইনের রানও তুলনা করতে পারেন।

Vertex AI SDK ব্যবহার করে রানগুলোর তুলনা

অনেক পাইপলাইন এক্সিকিউশনের ক্ষেত্রে, মেট্রিক্সের বিশদ বিবরণে আরও গভীরে যেতে এবং ভিজ্যুয়ালাইজেশন তৈরি করতে আপনার এই তুলনামূলক মেট্রিক্সগুলো প্রোগ্রাম্যাটিকভাবে পাওয়ার একটি উপায় প্রয়োজন হতে পারে।

আপনি রান মেটাডেটা অ্যাক্সেস করতে aiplatform.get_pipeline_df() মেথডটি ব্যবহার করতে পারেন। এখানে, আমরা একই পাইপলাইনের শেষ দুটি রানের মেটাডেটা সংগ্রহ করে একটি Pandas DataFrame-এ লোড করব। এখানকার pipeline প্যারামিটারটি আমাদের পাইপলাইন ডেফিনিশনে দেওয়া নামটি নির্দেশ করে:

df = aiplatform.get_pipeline_df(pipeline="mlmd-pipeline")
df

যখন আপনি ডেটাফ্রেমটি প্রিন্ট করবেন, তখন এইরকম কিছু দেখতে পাবেন:

পাইপলাইন মেট্রিক্স ডেটাফ্রেম

আমরা এখানে আমাদের পাইপলাইনটি মাত্র দুইবার চালিয়েছি, কিন্তু আপনি কল্পনা করতে পারেন যে আরও বেশিবার চালালে আপনি কতগুলো মেট্রিক পেতেন। এরপর, আমাদের মডেলের নির্ভুলতা এবং প্রশিক্ষণের জন্য ব্যবহৃত ডেটার পরিমাণের মধ্যে সম্পর্ক দেখার জন্য আমরা ম্যাটপ্লটলিব (matplotlib) দিয়ে একটি কাস্টম ভিজ্যুয়ালাইজেশন তৈরি করব।

একটি নতুন নোটবুক সেলে নিম্নলিখিতটি চালান:

plt.plot(df["metric.dataset_size"], df["metric.accuracy"],label="Accuracy")
plt.title("Accuracy and dataset size")
plt.legend(loc=4)
plt.show()

আপনার এইরকম কিছু দেখা উচিত:

ম্যাটপ্লটলিব মেটাডেটা গ্রাফ

৮. পাইপলাইন মেট্রিক্স অনুসন্ধান করা

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

সমস্ত মডেল আর্টিফ্যাক্ট পাওয়া

এইভাবে আর্টিফ্যাক্ট কোয়েরি করার জন্য, আমরা একটি MetadataServiceClient তৈরি করব:

API_ENDPOINT = "{}-aiplatform.googleapis.com".format(REGION)
metadata_client = aiplatform_v1.MetadataServiceClient(
  client_options={
      "api_endpoint": API_ENDPOINT
  }
)

এরপরে, আমরা ওই এন্ডপয়েন্টে একটি list_artifacts রিকোয়েস্ট পাঠাবো এবং একটি ফিল্টার পাস করবো, যা নির্দেশ করবে যে আমরা আমাদের রেসপন্সে কোন আর্টিফ্যাক্টগুলো পেতে চাই। প্রথমে, চলুন আমাদের প্রোজেক্টের সমস্ত মডেল আর্টিফ্যাক্টগুলো সংগ্রহ করি। তা করতে, আপনার নোটবুকে নিম্নলিখিত কমান্ডটি চালান:

MODEL_FILTER="schema_title = \"system.Model\""
artifact_request = aiplatform_v1.ListArtifactsRequest(
    parent="projects/{0}/locations/{1}/metadataStores/default".format(PROJECT_ID, REGION),
    filter=MODEL_FILTER
)
model_artifacts = metadata_client.list_artifacts(artifact_request)

ফলস্বরূপ প্রাপ্ত model_artifacts রেসপন্সটিতে আপনার প্রোজেক্টের প্রতিটি মডেল আর্টিফ্যাক্টের জন্য একটি ইটারেবল অবজেক্ট থাকে, সাথে প্রতিটি মডেলের সংশ্লিষ্ট মেটাডেটাও থাকে।

ডেটাফ্রেমে অবজেক্ট ফিল্টার করা এবং প্রদর্শন করা

ফলাফলস্বরূপ আর্টিফ্যাক্ট কোয়েরিটি যদি আরও সহজে দেখা যেত, তবে সুবিধা হতো। এরপর, চলুন ১০ই আগস্ট, ২০২১-এর পরে তৈরি হওয়া এবং LIVE অবস্থায় থাকা সমস্ত আর্টিফ্যাক্ট সংগ্রহ করি। এই অনুরোধটি চালানোর পর, আমরা ফলাফলগুলো একটি Pandas DataFrame-এ প্রদর্শন করব। প্রথমে, অনুরোধটি চালান:

LIVE_FILTER = "create_time > \"2021-08-10T00:00:00-00:00\" AND state = LIVE"
artifact_req = {
    "parent": "projects/{0}/locations/{1}/metadataStores/default".format(PROJECT_ID, REGION),
    "filter": LIVE_FILTER
}
live_artifacts = metadata_client.list_artifacts(artifact_req)

তারপর, ফলাফলগুলো একটি ডেটাফ্রেমে প্রদর্শন করুন:

data = {'uri': [], 'createTime': [], 'type': []}

for i in live_artifacts:
    data['uri'].append(i.uri)
    data['createTime'].append(i.create_time)
    data['type'].append(i.schema_title)

df = pd.DataFrame.from_dict(data)
df

আপনি এইরকম কিছু দেখতে পাবেন:

ফিল্টার করা আর্টিফ্যাক্ট ডেটাফ্রেম

আপনি এখানে যা যা চেষ্টা করেছেন, তার পাশাপাশি অন্যান্য মানদণ্ডের উপর ভিত্তি করেও আর্টিফ্যাক্টগুলো ফিল্টার করতে পারেন।

এর সাথেই, আপনার ল্যাব শেষ হলো!

🎉 অভিনন্দন! 🎉

আপনি শিখেছেন কীভাবে ভার্টেক্স এআই ব্যবহার করে:

  • Kubeflow Pipelines SDK ব্যবহার করে এমন একটি ML পাইপলাইন তৈরি করুন যা Vertex AI-তে একটি ডেটাসেট তৈরি করে এবং সেই ডেটাসেটের উপর একটি কাস্টম Scikit-learn মডেলকে প্রশিক্ষণ ও স্থাপন করে।
  • আর্টিফ্যাক্ট এবং মেটাডেটা তৈরি করে এমন কাস্টম পাইপলাইন কম্পোনেন্ট লিখুন।
  • ক্লাউড কনসোল এবং প্রোগ্রাম্যাটিকভাবে, উভয় ক্ষেত্রেই ভার্টেক্স পাইপলাইন রানগুলোর তুলনা করুন।
  • পাইপলাইন-উৎপাদিত আর্টিফ্যাক্টগুলির বংশধারা সন্ধান করুন
  • আপনার পাইপলাইন রান মেটাডেটা অনুসন্ধান করুন

Vertex-এর বিভিন্ন অংশ সম্পর্কে আরও জানতে ডকুমেন্টেশন দেখুন।

৯. পরিচ্ছন্নতা

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

আপনার নোটবুক ইনস্ট্যান্সটি বন্ধ করুন বা মুছে ফেলুন

আপনি যদি এই ল্যাবে তৈরি করা নোটবুকটি ব্যবহার করা চালিয়ে যেতে চান, তবে ব্যবহার না করার সময় এটি বন্ধ করে রাখার পরামর্শ দেওয়া হচ্ছে। আপনার ক্লাউড কনসোলের নোটবুকস UI থেকে, নোটবুকটি নির্বাচন করুন এবং তারপরে স্টপ (Stop) নির্বাচন করুন। আপনি যদি ইনস্ট্যান্সটি সম্পূর্ণরূপে মুছে ফেলতে চান, তাহলে ডিলিট (Delete ) নির্বাচন করুন।

স্টপ ইনস্ট্যান্স

আপনার Vertex AI এন্ডপয়েন্টগুলি মুছে ফেলুন

আপনার স্থাপন করা এন্ডপয়েন্টটি মুছে ফেলতে, আপনার Vertex AI কনসোলের এন্ডপয়েন্টস বিভাগে যান এবং ডিলিট আইকনে ক্লিক করুন:

এন্ডপয়েন্ট মুছুন

আপনার ক্লাউড স্টোরেজ বাকেট মুছে ফেলুন

স্টোরেজ বাকেটটি ডিলিট করতে, আপনার ক্লাউড কনসোলের নেভিগেশন মেনু ব্যবহার করে স্টোরেজ-এ যান, আপনার বাকেটটি সিলেক্ট করুন এবং ডিলিট-এ ক্লিক করুন:

স্টোরেজ মুছে ফেলুন