গুগল ক্লাউডে ওপেন সোর্স এলএলএম গুলি সূক্ষ্মভাবে সুরক্ষিত করুন

1. ভূমিকা

এই ল্যাবে, আপনি Google Kubernetes Engine (GKE) ব্যবহার করে জনপ্রিয় ওপেন-সোর্স ল্যাঙ্গুয়েজ মডেল Llama 2-এর জন্য একটি সম্পূর্ণ, উৎপাদন-গ্রেড ফাইন-টিউনিং পাইপলাইন তৈরি করতে শিখবেন। আপনি স্থাপত্য সিদ্ধান্ত, সাধারণ লেনদেন এবং বাস্তব-বিশ্বের মেশিন লার্নিং অপারেশনস (MLOps) কর্মপ্রবাহকে প্রতিফলিত করে এমন উপাদান সম্পর্কে শিখবেন।

তুমি একটি GKE ক্লাস্টার তৈরি করবে, LoRA (লো-র‍্যাঙ্ক অ্যাডাপ্টেশন) ব্যবহার করে একটি কন্টেইনারাইজড ট্রেনিং পাইপলাইন তৈরি করবে এবং GKE তে তোমার ট্রেনিং কাজ চালাবে।

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

আজ আমরা যা তৈরি করব তা এখানে:

স্থাপত্যে GPU নোড, GCS বাকেট এবং মডেল সার্ভিং সহ GKE ক্লাস্টার দেখানো হচ্ছে

স্থাপত্যের মধ্যে রয়েছে:

  • GKE ক্লাস্টার : আমাদের কম্পিউট রিসোর্স পরিচালনা করে
  • জিপিইউ নোড পুল : প্রশিক্ষণের জন্য ১x এল৪ জিপিইউ ( স্পট )
  • জিসিএস বাকেট : মডেল এবং ডেটাসেট সংরক্ষণ করে
  • কাজের চাপের পরিচয় : K8s এবং GCS এর মধ্যে নিরাপদ প্রবেশাধিকার

তুমি কি শিখবে

  • ML ওয়ার্কলোডের জন্য অপ্টিমাইজ করা বৈশিষ্ট্য সহ একটি GKE ক্লাস্টার তৈরি এবং কনফিগার করুন।
  • ওয়ার্কলোড আইডেন্টিটি ব্যবহার করে GKE থেকে অন্যান্য Google ক্লাউড পরিষেবাগুলিতে নিরাপদ, চাবিহীন অ্যাক্সেস বাস্তবায়ন করুন।
  • ডকার ব্যবহার করে একটি কন্টেইনারাইজড ট্রেনিং পাইপলাইন তৈরি করুন।
  • LoRA-এর সাহায্যে প্যারামিটার-এফিশিয়েন্ট ফাইন-টিউনিং (PEFT) ব্যবহার করে দক্ষতার সাথে একটি ওপেন-সোর্স মডেলকে ফাইন-টিউন করুন।

2. প্রকল্প সেটআপ

গুগল অ্যাকাউন্ট

যদি আপনার ইতিমধ্যেই একটি ব্যক্তিগত Google অ্যাকাউন্ট না থাকে, তাহলে আপনাকে অবশ্যই একটি Google অ্যাকাউন্ট তৈরি করতে হবে।

কর্মক্ষেত্র বা স্কুল অ্যাকাউন্টের পরিবর্তে ব্যক্তিগত অ্যাকাউন্ট ব্যবহার করুন

গুগল ক্লাউড কনসোলে সাইন-ইন করুন

একটি ব্যক্তিগত গুগল অ্যাকাউন্ট ব্যবহার করে গুগল ক্লাউড কনসোলে সাইন-ইন করুন।

একটি প্রকল্প তৈরি করুন (ঐচ্ছিক)

যদি আপনার এই ল্যাবের জন্য ব্যবহার করতে চান এমন কোন বর্তমান প্রকল্প না থাকে, তাহলে এখানে একটি নতুন প্রকল্প তৈরি করুন

৩. ক্লাউড শেল এডিটর খুলুন

  1. সরাসরি ক্লাউড শেল এডিটরে যেতে এই লিঙ্কে ক্লিক করুন।
  2. আজই যদি যেকোনো সময় অনুমোদনের অনুরোধ করা হয়, তাহলে চালিয়ে যেতে অনুমোদন করুন- এ ক্লিক করুন। ক্লাউড শেল অনুমোদন করতে ক্লিক করুন
  3. যদি স্ক্রিনের নীচে টার্মিনালটি না দেখা যায়, তাহলে এটি খুলুন:
    • ভিউ ক্লিক করুন
    • টার্মিনাল ক্লিক করুন ক্লাউড শেল এডিটরে নতুন টার্মিনাল খুলুন
  4. টার্মিনালে, এই কমান্ড দিয়ে আপনার প্রকল্পটি সেট করুন:
    gcloud config set project [PROJECT_ID]
    
    • উদাহরণ:
      gcloud config set project lab-project-id-example
      
    • যদি আপনি আপনার প্রজেক্ট আইডি মনে রাখতে না পারেন, তাহলে আপনি আপনার সমস্ত প্রজেক্ট আইডি তালিকাভুক্ত করতে পারেন:
      gcloud projects list
      
      ক্লাউড শেল এডিটর টার্মিনালে প্রোজেক্ট আইডি সেট করুন
  5. আপনার এই বার্তাটি দেখা উচিত:
    Updated property [core/project].
    

৪. API গুলি সক্ষম করুন

GKE এবং অন্যান্য পরিষেবা ব্যবহার করার জন্য, আপনার Google ক্লাউড প্রকল্পে প্রয়োজনীয় API গুলি সক্ষম করতে হবে।

  1. টার্মিনালে, API গুলি সক্রিয় করুন:
    gcloud services enable container.googleapis.com \
        artifactregistry.googleapis.com \
        cloudbuild.googleapis.com \
        iam.googleapis.com \
        compute.googleapis.com \
        iamcredentials.googleapis.com \
        storage.googleapis.com
    

API গুলির সাথে পরিচয় করিয়ে দেওয়া হচ্ছে

  • গুগল কুবারনেটস ইঞ্জিন এপিআই ( container.googleapis.com ) আপনাকে আপনার অ্যাপ্লিকেশন চালানোর জন্য GKE ক্লাস্টার তৈরি এবং পরিচালনা করতে দেয়।
  • আর্টিফ্যাক্ট রেজিস্ট্রি API ( artifactregistry.googleapis.com ) আপনার কন্টেইনার ছবি সংরক্ষণের জন্য একটি নিরাপদ, ব্যক্তিগত সংগ্রহস্থল প্রদান করে।
  • ক্লাউড বিল্ড API ( cloudbuild.googleapis.com ) ক্লাউডে আপনার কন্টেইনার ইমেজ তৈরি করতে gcloud builds submit কমান্ড দ্বারা ব্যবহৃত হয়।
  • IAM API ( iam.googleapis.com ) আপনাকে আপনার Google ক্লাউড রিসোর্সের জন্য অ্যাক্সেস নিয়ন্ত্রণ এবং পরিচয় পরিচালনা করতে দেয়।
  • কম্পিউট ইঞ্জিন এপিআই ( compute.googleapis.com ) গুগলের পরিকাঠামোতে চালিত নিরাপদ এবং কাস্টমাইজযোগ্য ভার্চুয়াল মেশিন সরবরাহ করে।
  • IAM সার্ভিস অ্যাকাউন্ট ক্রেডেনশিয়ালস API ( iamcredentials.googleapis.com ) পরিষেবা অ্যাকাউন্টগুলির জন্য স্বল্পস্থায়ী ক্রেডেনশিয়াল তৈরি করার অনুমতি দেয়।
  • ক্লাউড স্টোরেজ API ( storage.googleapis.com ) আপনাকে ক্লাউডে ডেটা সংরক্ষণ এবং পুনরুদ্ধার করতে দেয়, যা এখানে মডেল এবং ডেটাসেট স্টোরেজের জন্য ব্যবহৃত হয়।

৫. প্রকল্পের পরিবেশ সেট আপ করুন

একটি কার্যকরী ডিরেক্টরি তৈরি করুন

  1. টার্মিনালে , আপনার প্রকল্পের জন্য একটি ডিরেক্টরি তৈরি করুন এবং এতে নেভিগেট করুন।
    mkdir llama-finetuning
    cd llama-finetuning
    

পরিবেশ ভেরিয়েবল সেট আপ করুন

  1. টার্মিনালে , আপনার পরিবেশ ভেরিয়েবল সংরক্ষণ করার জন্য env.sh নামে একটি ফাইল তৈরি করুন। এটি নিশ্চিত করে যে আপনার সেশন সংযোগ বিচ্ছিন্ন হলে আপনি সহজেই সেগুলি পুনরায় লোড করতে পারবেন।
    cat <<EOF > env.sh
    export PROJECT_ID=$(gcloud config get-value project)
    export CLUSTER_NAME="ml-gke"
    export GPU_NODE_POOL_NAME="gpu-pool"
    export MACHINE_TYPE="e2-standard-4"
    export GPU_MACHINE_TYPE="g2-standard-16"
    export GPU_TYPE="nvidia-l4"
    export GPU_COUNT=1
    export REGION="asia-southeast1"
    export NODE_LOCATIONS="asia-southeast1-a,asia-southeast1-b"
    EOF
    
  2. আপনার বর্তমান সেশনে ভেরিয়েবল লোড করার জন্য ফাইলটি সোর্স করুন:
    source env.sh
    

৬. GKE ক্লাস্টারের ব্যবস্থা করুন

  1. টার্মিনালে , একটি ডিফল্ট নোড পুল সহ GKE ক্লাস্টার তৈরি করুন। এতে প্রায় ৫ মিনিট সময় লাগবে।
    gcloud container clusters create $CLUSTER_NAME \
        --project=$PROJECT_ID \
        --region=$REGION \
        --release-channel=rapid \
        --machine-type=$MACHINE_TYPE \
        --workload-pool=${PROJECT_ID}.svc.id.goog \
        --addons=GcsFuseCsiDriver,HttpLoadBalancing \
        --enable-image-streaming \
        --enable-ip-alias \
        --num-nodes=1 \
        --enable-autoscaling \
        --min-nodes=1 \
        --max-nodes=3
    
  2. এরপর, ক্লাস্টারে একটি GPU নোড পুল যোগ করুন। এই নোড পুলটি মডেলটিকে প্রশিক্ষণের জন্য ব্যবহার করা হবে।
    gcloud container node-pools create $GPU_NODE_POOL_NAME \
        --project=$PROJECT_ID \
        --cluster=$CLUSTER_NAME \
        --region=$REGION \
        --machine-type=$GPU_MACHINE_TYPE \
        --accelerator type=$GPU_TYPE,count=$GPU_COUNT,gpu-driver-version=latest \
        --ephemeral-storage-local-ssd=count=1 \
        --enable-autoscaling \
        --enable-image-streaming \
        --num-nodes=0 \
        --min-nodes=0 \
        --max-nodes=1 \
        --location-policy=ANY \
        --node-taints=nvidia.com/gpu=present:NoSchedule \
        --node-locations=$NODE_LOCATIONS \
        --spot
    
  3. অবশেষে, আপনার নতুন ক্লাস্টারের শংসাপত্রগুলি পান এবং যাচাই করুন যে আপনি এটির সাথে সংযোগ করতে পারেন।
    gcloud container clusters get-credentials $CLUSTER_NAME --region=$REGION
    
    kubectl get nodes
    

৭. আলিঙ্গন মুখ অ্যাক্সেস কনফিগার করুন

আপনার পরিকাঠামো প্রস্তুত হওয়ার পর, এখন আপনাকে আপনার মডেল এবং ডেটা অ্যাক্সেস করার জন্য আপনার প্রকল্পের প্রয়োজনীয় শংসাপত্র সরবরাহ করতে হবে। এই কাজে, আপনি প্রথমে একটি Hugging Face টোকেন পাবেন।

একটি আলিঙ্গন মুখের টোকেন পান

  1. যদি আপনার Hugging Face অ্যাকাউন্ট না থাকে, তাহলে একটি নতুন ব্রাউজার ট্যাবে huggingface.co/join এ যান এবং নিবন্ধন প্রক্রিয়াটি সম্পূর্ণ করুন।
  2. নিবন্ধিত এবং লগ-ইন হয়ে গেলে, huggingface.co/meta-llama/Llama-2-7b-hf এ যান।
  3. লাইসেন্সের শর্তাবলী পড়ুন এবং সেগুলি গ্রহণ করতে বোতামে ক্লিক করুন।
  4. huggingface.co/settings/tokens- এ আপনার Hugging Face অ্যাক্সেস টোকেন পৃষ্ঠায় নেভিগেট করুন।
  5. নতুন টোকেন ক্লিক করুন।
  6. ভূমিকার জন্য, পড়ুন নির্বাচন করুন।
  7. Name এর জন্য, একটি বর্ণনামূলক নাম লিখুন (যেমন, ফাইনেটুনিং-ল্যাব)।
  8. একটি টোকেন তৈরি করুন ক্লিক করুন।
  9. জেনারেট করা টোকেনটি আপনার ক্লিপবোর্ডে কপি করুন। পরবর্তী ধাপে আপনার এটির প্রয়োজন হবে।

পরিবেশ ভেরিয়েবল আপডেট করুন

এবার, আপনার env.sh ফাইলে আপনার Hugging Face টোকেন এবং আপনার GCS বাকেটের নাম যোগ করা যাক। [your-hf-token] এর পরিবর্তে আপনার কপি করা টোকেনটি দিন।

  1. টার্মিনালে , নতুন ভেরিয়েবলগুলিকে env.sh এ যুক্ত করুন এবং পুনরায় লোড করুন:
    cat <<EOF >> env.sh
    export HF_TOKEN="[your-hf-token]"
    export BUCKET_NAME="\${PROJECT_ID}-llama-fine-tuning"
    EOF
    
    source env.sh
    

৮. ওয়ার্কলোড আইডেন্টিটি কনফিগার করুন

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

  1. প্রথমে, একটি Google পরিষেবা অ্যাকাউন্ট (GSA) তৈরি করুন। টার্মিনালে , চালান:
    cat <<EOF >> env.sh
    export GSA_NAME="llama-fine-tuning"
    EOF
    source env.sh
    
    gcloud iam service-accounts create $GSA_NAME \
      --display-name="Llama Fine-tuning Service Account"
    
  2. এরপর, GCS বাকেট তৈরি করুন এবং GSA কে এটি অ্যাক্সেস করার অনুমতি দিন:
    gcloud storage buckets create gs://$BUCKET_NAME --project=$PROJECT_ID --location=$REGION
    gcloud storage buckets add-iam-policy-binding gs://$BUCKET_NAME \
        --member=serviceAccount:${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com \
        --role=roles/storage.admin
    
  3. এখন, একটি Kubernetes পরিষেবা অ্যাকাউন্ট (KSA) তৈরি করুন:
    cat <<EOF >> env.sh
    export KSA_NAME="llama-workload-sa"
    export NAMESPACE="ml-workloads"
    EOF
    source env.sh
    
    kubectl create namespace $NAMESPACE
    kubectl create serviceaccount $KSA_NAME --namespace $NAMESPACE
    
  4. অবশেষে, GSA এবং KSA-এর মধ্যে IAM নীতি বাঁধাই তৈরি করুন:
    gcloud iam service-accounts add-iam-policy-binding ${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:${PROJECT_ID}.svc.id.goog[${NAMESPACE}/${KSA_NAME}]"
    
    kubectl annotate serviceaccount $KSA_NAME --namespace $NAMESPACE \
        iam.gke.io/gcp-service-account=${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
    

৯. বেস মডেলটি মঞ্চস্থ করুন

উৎপাদন ML পাইপলাইনে, Llama 2 (~13 GB) এর মতো বৃহৎ মডেলগুলি সাধারণত প্রশিক্ষণের সময় ডাউনলোড করার পরিবর্তে ক্লাউড স্টোরেজে আগে থেকে স্টেজ করা থাকে। এই পদ্ধতিটি আরও ভাল নির্ভরযোগ্যতা, দ্রুত অ্যাক্সেস প্রদান করে এবং নেটওয়ার্ক সমস্যা এড়ায়। Google Cloud জনসাধারণের GCS বাকেটগুলিতে জনপ্রিয় মডেলগুলির আগে থেকে ডাউনলোড করা সংস্করণ সরবরাহ করে, যা আপনি এই ল্যাবের জন্য ব্যবহার করবেন।

  1. প্রথমে, যাচাই করা যাক যে আপনি গুগল-প্রদত্ত লামা 2 মডেলটি অ্যাক্সেস করতে পারেন:
    gcloud storage ls gs://vertex-model-garden-public-us-central1/llama2/llama2-7b-hf/
    
  2. gcloud storage কমান্ড ব্যবহার করে এই পাবলিক বাকেট থেকে আপনার নিজস্ব প্রজেক্টের বাকেটের Llama 2 মডেলটি কপি করুন। এই স্থানান্তরটি Google এর উচ্চ-গতির অভ্যন্তরীণ নেটওয়ার্ক ব্যবহার করে এবং মাত্র এক বা দুই মিনিট সময় নেয়।
    gcloud storage cp -r gs://vertex-model-garden-public-us-central1/llama2/llama2-7b-hf \
      gs://${BUCKET_NAME}/llama2-7b/
    
  3. আপনার বাকেটের বিষয়বস্তু তালিকাভুক্ত করে মডেল ফাইলগুলি সঠিকভাবে অনুলিপি করা হয়েছে কিনা তা যাচাই করুন।
    gcloud storage ls --recursive --long gs://${BUCKET_NAME}/llama2-7b/llama2-7b-hf/
    

১০. প্রশিক্ষণ কোড প্রস্তুত করুন

এখন তুমি একটি কন্টেইনারাইজড অ্যাপ্লিকেশন তৈরি করবে যা মডেলটিকে সূক্ষ্ম-সুরক্ষিত করবে। এই কাজটি LoRA (লো-র‍্যাঙ্ক অ্যাডাপ্টেশন) ব্যবহার করে, একটি প্যারামিটার-দক্ষ ফাইন-সুরক্ষিত (PEFT) কৌশল যা সম্পূর্ণ মডেলের পরিবর্তে শুধুমাত্র ছোট "অ্যাডাপ্টার" স্তরগুলিকে প্রশিক্ষণ দিয়ে মেমরির প্রয়োজনীয়তা নাটকীয়ভাবে হ্রাস করে।

এখন, প্রশিক্ষণ পাইপলাইনের জন্য পাইথন স্ক্রিপ্ট তৈরি করুন।

  1. টার্মিনালে , train.py ফাইলটি খুলতে নিম্নলিখিত কমান্ডটি চালান:
    cloudshell edit train.py
    
  2. নিম্নলিখিত কোডটি train.py ফাইলে পেস্ট করুন:
#!/usr/bin/env python3
"""Fine-tune Llama 2 with LoRA on American Stories dataset """

import os
import torch
import logging

from pathlib import Path
from datasets import load_dataset, concatenate_datasets
from transformers import (
    AutoTokenizer,
    AutoModelForCausalLM,
    Trainer,
    TrainingArguments,
    DataCollatorForLanguageModeling
)
from peft import get_peft_model, LoraConfig

os.environ["TOKENIZERS_PARALLELISM"] = "false"
os.environ["NCCL_DEBUG"] = "INFO"

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class SimpleTextDataset(torch.utils.data.Dataset):
    def __init__(self, input_ids, attention_mask):
        self.input_ids = input_ids
        self.attention_mask = attention_mask
    
    def __len__(self):
        return len(self.input_ids)
    
    def __getitem__(self, idx):
        return {
            'input_ids': self.input_ids[idx],
            'attention_mask': self.attention_mask[idx],
            'labels': self.input_ids[idx].clone()
        }

def get_lora_config():
    config = {
       "r": 16,
       "lora_alpha": 32,
       "target_modules": [
          "q_proj", "k_proj", "v_proj", "o_proj",
          "gate_proj", "up_proj", "down_proj"
       ],
       "lora_dropout": 0.05,
       "task_type": "CAUSAL_LM",
    }
    return LoraConfig(**config)

def load_model_and_tokenizer(model_path):
    logger.info("Loading tokenizer...")
    tokenizer = AutoTokenizer.from_pretrained(model_path)
    
    if tokenizer.pad_token is None:
        tokenizer.pad_token = tokenizer.eos_token
    tokenizer.padding_side = "left"
    
    logger.info("Loading model...")

    model = AutoModelForCausalLM.from_pretrained(
        model_path,
        torch_dtype=torch.float16,
        device_map="auto",
        trust_remote_code=True,
        use_cache=False
    )
    
    return model, tokenizer

def prepare_dataset(tokenizer, max_length=512):
    logger.info("Loading American Stories dataset...")
     We recommend using o
    dataset = load_dataset(
        "dell-research-harvard/AmericanStories",
        "subset_years",
        year_list=["1809", "1810", "1811", "1812", "1813", "1814", "1815"],
        trust_remote_code=True
    )
    
    all_articles = []
    for year_data in dataset.values():
        all_articles.extend(year_data["article"])
    
    logger.info(f"Total articles collected: {len(all_articles)}")
    
    batch_size = 1000
    all_input_ids = []
    all_attention_masks = []
    
    for i in range(0, len(all_articles), batch_size):
        batch_articles = all_articles[i:i+batch_size]
        logger.info(f"Processing batch {i//batch_size + 1}/{(len(all_articles) + batch_size - 1)//batch_size}")
        
        encodings = tokenizer(
            batch_articles,
            padding="max_length",
            truncation=True,
            max_length=max_length,
            return_tensors="pt"
        )
        
        all_input_ids.append(encodings['input_ids'])
        all_attention_masks.append(encodings['attention_mask'])
    
    # Concatenate all batches
    input_ids = torch.cat(all_input_ids, dim=0)
    attention_mask = torch.cat(all_attention_masks, dim=0)
    
    logger.info(f"Total tokenized examples: {len(input_ids)}")
    
    # Create simple dataset
    dataset = SimpleTextDataset(input_ids, attention_mask)
    
    return dataset

def train_model(model, tokenizer, train_dataset, output_dir):
    logger.info(f"Train dataset size: {len(train_dataset)}")
    
    n_gpus = torch.cuda.device_count()
    logger.info(f"Available GPUs: {n_gpus}")
    
    # For multi-GPU, we can increase batch size
    per_device_batch_size = 2 if n_gpus > 1 else 1
    gradient_accumulation_steps = 2 if n_gpus > 1 else 4
    
    # Training for 250 steps
    max_steps = 250
    
    training_args = TrainingArguments(
        output_dir=output_dir,
        max_steps=max_steps,
        per_device_train_batch_size=per_device_batch_size,
        gradient_accumulation_steps=gradient_accumulation_steps,
        learning_rate=2e-4,
        warmup_steps=20,
        fp16=True,
        gradient_checkpointing=True,
        logging_steps=10,
        evaluation_strategy="no",
        save_strategy="no",
        optim="adamw_torch",
        ddp_find_unused_parameters=False,
        dataloader_num_workers=0,
        remove_unused_columns=False,
        report_to=[],
        disable_tqdm=False,
        logging_first_step=True,
    )
    
    # Create trainer
    trainer = Trainer(
        model=model,
        args=training_args,
        train_dataset=train_dataset,
        tokenizer=tokenizer,
        data_collator=DataCollatorForLanguageModeling(
            tokenizer=tokenizer,
            mlm=False,
            pad_to_multiple_of=8
        )
    )
    
    # Train
    logger.info(f"Starting training on {n_gpus} GPU(s)...")
    logger.info(f"Training for {max_steps} steps - approximately {(max_steps * 2.5 / 60):.1f} minutes")
    
    try:
        trainer.train()
        logger.info("Training completed successfully!")
    except Exception as e:
        logger.error(f"Training error: {e}")
        logger.info("Attempting to save model despite error...")
    
    logger.info("Saving model...")
    try:
        trainer.save_model(output_dir)
        tokenizer.save_pretrained(output_dir)
        logger.info(f"Model saved successfully to {output_dir}!")

        if not output_dir.startswith("/gcs-mount"):
            logger.info("Copying artifacts to GCS bucket...")
            gcs_target = "/gcs-mount/llama2-7b-american-stories"
            os.makedirs(gcs_target, exist_ok=True)
            return_code = os.system(f"cp -r {output_dir}/* {gcs_target}/")
            if return_code != 0:
                raise RuntimeError(f"Failed to copy model to GCS: cp command returned {return_code}")
            logger.info(f"Copied to {gcs_target}")

    except Exception as e:
        logger.error(f"Error saving model or copying to GCS: {e}")
        raise

def run_inference(model, tokenizer):
    logger.info("Running inference test...")
    
    prompt = "The year was 1812, and the"
    
    inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
    
    model.eval()
    
    with torch.no_grad():
        outputs = model.generate(
            **inputs, 
            max_new_tokens=50, 
            do_sample=True, 
            temperature=0.7,
            pad_token_id=tokenizer.pad_token_id
        )
    
    generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
    logger.info("-" * 50)
    logger.info(f"Input Prompt: {prompt}")
    logger.info(f"Generated Text: {generated_text}")
    logger.info("-" * 50)

def main():
    if torch.cuda.is_available():
        for i in range(torch.cuda.device_count()):
            logger.info(f"GPU {i}: {torch.cuda.get_device_name(i)}")
    
    model_path = os.getenv('MODEL_PATH', '/gcs-mount/llama2-7b/llama2-7b-hf')
    output_path = os.getenv('OUTPUT_PATH', '/gcs-mount/llama2-7b-american-stories')
    
    # Load model and tokenizer
    model, tokenizer = load_model_and_tokenizer(model_path)
    model.enable_input_require_grads()

    # Apply LoRA
    logger.info("Applying LoRA configuration...")
    lora_config = get_lora_config()
    model = get_peft_model(model, lora_config)
    model.train()
    
    # Prepare dataset
    train_dataset = prepare_dataset(tokenizer)
    
    # Train
    train_model(model, tokenizer, train_dataset, output_path)
    
    # Run Inference
    run_inference(model, tokenizer)
    
    logger.info("Training and inference complete!")

if __name__ == "__main__":
    main()

১১. প্রশিক্ষণ কোডটি বুঝুন

train.py স্ক্রিপ্টটি সূক্ষ্ম-সুরকরণ প্রক্রিয়াটি পরিচালনা করে। আসুন এর মূল উপাদানগুলি ভেঙে ফেলা যাক।

কনফিগারেশন

স্ক্রিপ্টটি LoraConfig ব্যবহার করে নিম্ন-র‍্যাঙ্ক অভিযোজন সেটিংস সংজ্ঞায়িত করে। LoRA প্রশিক্ষণযোগ্য প্যারামিটারের সংখ্যা উল্লেখযোগ্যভাবে হ্রাস করে, যা আপনাকে ছোট GPU-তে বড় মডেলগুলিকে সূক্ষ্ম-টিউন করার অনুমতি দেয়।

def get_lora_config():
    config = {
       "r": 16,
       "lora_alpha": 32,
       "target_modules": ["q_proj", "k_proj", "v_proj", "o_proj", ...],
       "lora_dropout": 0.05,
       "task_type": "CAUSAL_LM",
    }
    return LoraConfig(**config)

ডেটাসেট প্রস্তুত করুন

prepare_dataset ফাংশনটি "American Stories" ডেটাসেট লোড করে এবং টোকেনাইজড অংশগুলিতে প্রক্রিয়া করে। এটি ইনপুট টেনসরগুলিকে দক্ষতার সাথে পরিচালনা করার জন্য একটি কাস্টম SimpleTextDataset ব্যবহার করে।

def prepare_dataset(tokenizer, max_length=512):
    dataset = load_dataset("dell-research-harvard/AmericanStories", ...)
    # ... tokenization logic ...
    return SimpleTextDataset(input_ids, attention_mask)

ট্রেন

train_model ফাংশনটি এই কাজের জন্য অপ্টিমাইজ করা নির্দিষ্ট আর্গুমেন্ট সহ Trainer সেট আপ করে। মূল পরামিতিগুলির মধ্যে রয়েছে:

  • gradient_accumulation_steps : মেমোরির ব্যবহার না বাড়িয়ে একটি বৃহত্তর ব্যাচের আকার অনুকরণ করতে সাহায্য করে।
  • fp16=True : স্মৃতিশক্তি কমাতে এবং গতি বাড়াতে মিশ্র নির্ভুল প্রশিক্ষণ ব্যবহার করে।
  • gradient_checkpointing=True : ব্যাকওয়ার্ড পাসের সময় অ্যাক্টিভেশনগুলিকে সংরক্ষণ করার পরিবর্তে পুনরায় গণনা করে মেমরি সংরক্ষণ করে।
  • optim="adamw_torch" : PyTorch থেকে স্ট্যান্ডার্ড AdamW অপ্টিমাইজার বাস্তবায়ন ব্যবহার করে।
training_args = TrainingArguments(
    per_device_train_batch_size=per_device_batch_size,
    gradient_accumulation_steps=gradient_accumulation_steps,
    fp16=True,
    gradient_checkpointing=True,
    optim="adamw_torch",
)

অনুমান

run_inference ফাংশনটি একটি নমুনা প্রম্পট ব্যবহার করে সূক্ষ্ম-সুরযুক্ত মডেলের দ্রুত পরীক্ষা করে। এটি নিশ্চিত করে যে মডেলটি মূল্যায়ন মোডে রয়েছে এবং অ্যাডাপ্টারগুলি সঠিকভাবে কাজ করছে কিনা তা যাচাই করার জন্য পাঠ্য তৈরি করে।

def run_inference(model, tokenizer):
    prompt = "The year was 1812, and the"
    # ... generation logic ...
    logger.info(f"Generated Text: {generated_text}")

১২. অ্যাপ্লিকেশনটি কনটেইনারাইজ করুন

এখন, ডকার ব্যবহার করে প্রশিক্ষণ কন্টেইনার চিত্রটি তৈরি করুন এবং এটিকে Google Artifact Registry এ পুশ করুন।

  1. টার্মিনালে , Dockerfile ফাইলটি খুলতে নিম্নলিখিত কমান্ডটি চালান:
    cloudshell edit Dockerfile
    
  2. নিম্নলিখিত কোডটি Dockerfile ফাইলে পেস্ট করুন:
FROM pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime

WORKDIR /app

# Install required packages
RUN pip install --no-cache-dir \
    transformers==4.46.0 \
    datasets==3.1.0 \
    pyarrow==15.0.0 \
    peft==0.13.2 \
    accelerate==1.1.0 \
    tensorboard==2.18.0 \
    nvidia-ml-py==12.535.161 \
    scipy==1.13.1

# Copy training scripts
COPY train.py /app/

# Run training
CMD ["python", "train.py"]

পাত্রটি তৈরি করুন এবং ধাক্কা দিন

  1. আর্টিফ্যাক্ট রেজিস্ট্রি সংগ্রহস্থল তৈরি করুন:
    gcloud artifacts repositories create gke-finetune \
        --repository-format=docker \
        --location=$REGION \
        --description="Docker repository for Llama fine-tuning"
    
  2. ক্লাউড বিল্ড ব্যবহার করে ছবি তৈরি করুন এবং পুশ করুন:
    gcloud builds submit --tag ${REGION}-docker.pkg.dev/${PROJECT_ID}/gke-finetune/llama-trainer:latest .
    

১৩. ফাইন-টিউনিং কাজটি স্থাপন করুন

  1. ফাইন-টিউনিং কাজ শুরু করতে Kubernetes জব ম্যানিফেস্ট তৈরি করুন। টার্মিনালে , চালান:
    cloudshell edit training_job.yaml
    
  2. নিম্নলিখিত কোডটি training_job.yaml ফাইলে পেস্ট করুন:
apiVersion: batch/v1
kind: Job
metadata:
  name: llama-fine-tuning
  namespace: ml-workloads
spec:
  template:
    metadata:
      annotations:
        gke-gcsfuse/volumes: "true"
        gke-gcsfuse/memory-limit: "4Gi"
    spec:
      serviceAccountName: llama-workload-sa
      restartPolicy: OnFailure
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
        - key: cloud.google.com/gke-spot
          operator: Exists
          effect: NoSchedule
      nodeSelector:
        cloud.google.com/gke-accelerator: nvidia-l4

      containers:
        - name: training
          image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/gke-finetune/llama-trainer:latest
          env:
            - name: MODEL_PATH
              value: "/gcs-mount/llama2-7b/llama2-7b-hf"
            - name: OUTPUT_PATH
              value: "/tmp/llama2-7b-american-stories"
            - name: NCCL_DEBUG
              value: "INFO"
          resources:
            requests:
              nvidia.com/gpu: 1
              cpu: "8"
              memory: "32Gi"
            limits:
              nvidia.com/gpu: 1

          volumeMounts:
            - name: gcs-fuse
              mountPath: /gcs-mount
            - name: shm
              mountPath: /dev/shm
      volumes:
        - name: gcs-fuse
          csi:
            driver: gcsfuse.csi.storage.gke.io
            volumeAttributes:
              bucketName: ${BUCKET_NAME}
              mountOptions: "implicit-dirs"
        - name: shm
          emptyDir:
            medium: Memory
            sizeLimit: 32Gi
  1. অবশেষে, আপনার GKE ক্লাস্টারে ফাইন-টিউনিং কাজ শুরু করতে Kubernetes জব ম্যানিফেস্ট প্রয়োগ করুন।
    envsubst < training_job.yaml | kubectl apply -f -
    

১৪. প্রশিক্ষণের কাজ পর্যবেক্ষণ করুন

আপনি গুগল ক্লাউড কনসোলে আপনার প্রশিক্ষণ কাজের অগ্রগতি পর্যবেক্ষণ করতে পারেন।

  1. Kubernetes Engine > Workloads পৃষ্ঠায় যান।
    GKE কাজের চাপ দেখুন
  2. llama-fine-tuning কাজের বিস্তারিত দেখতে তার উপর ক্লিক করুন।
  3. ডিফল্টরূপে "বিস্তারিত" ট্যাবটি প্রদর্শিত হয়। আপনি " সম্পদ" বিভাগে GPU ব্যবহারের মেট্রিক্স দেখতে পারেন। GPU ব্যবহারের মেট্রিক্স
  4. প্রশিক্ষণ লগ দেখতে লগ ট্যাবে ক্লিক করুন। আপনি প্রশিক্ষণের অগ্রগতি দেখতে পাবেন, যার মধ্যে ক্ষতি এবং শেখার হারও অন্তর্ভুক্ত। প্রশিক্ষণ লগগুলি ক্ষতি এবং শেখার হার দেখায়

১৫. পরিষ্কার করা

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

GKE ক্লাস্টার মুছে ফেলুন

gcloud container clusters delete $CLUSTER_NAME --region $REGION --quiet

আর্টিফ্যাক্ট রেজিস্ট্রি সংগ্রহস্থল মুছে ফেলুন

gcloud artifacts repositories delete gke-finetune --location $REGION --quiet

GCS বাকেটটি মুছে ফেলুন

gcloud storage rm -r gs://${BUCKET_NAME}

১৬. অভিনন্দন!

আপনি GKE তে একটি ওপেন-সোর্স LLM সফলভাবে উন্নত করেছেন!

সংক্ষিপ্তসার

এই ল্যাবে, আপনি:

  • GPU ত্বরণ সহ একটি GKE ক্লাস্টার সরবরাহ করা হয়েছে।
  • গুগল ক্লাউড পরিষেবাগুলিতে নিরাপদ অ্যাক্সেসের জন্য কনফিগার করা ওয়ার্কলোড আইডেন্টিটি।
  • ডকার এবং আর্টিফ্যাক্ট রেজিস্ট্রি ব্যবহার করে একটি পাইটর্চ প্রশিক্ষণ কাজ কনটেইনারাইজ করা হয়েছে।
  • Llama 2 কে একটি নতুন ডেটাসেটে অভিযোজিত করার জন্য LoRA ব্যবহার করে একটি সূক্ষ্ম-টিউনিং কাজ স্থাপন করা হয়েছে।

এরপর কি?

গুগল ক্লাউড লার্নিং পাথ

এই ল্যাবটি গুগল ক্লাউড লার্নিং পাথ সহ প্রোডাকশন-রেডি এআই- এর অংশ। প্রোটোটাইপ থেকে প্রোডাকশন পর্যন্ত ব্যবধান পূরণ করতে সম্পূর্ণ পাঠ্যক্রমটি অন্বেষণ করুন

#ProductionReadyAI হ্যাশট্যাগ ব্যবহার করে আপনার অগ্রগতি শেয়ার করুন।