تنظیم دقیق EmbeddingGemma

مشاهده در ai.google.dev اجرا در Google Colab اجرا در Kaggle باز کردن در Vertex AI مشاهده منبع در GitHub

بهینه‌سازی دقیق به کاهش فاصله بین درک عمومی مدل و دقت تخصصی و عملکرد بالای موردنیاز برنامه شما کمک می‌کند. ازآنجایی‌که هیچ مدل واحدی برای همه کارها کامل نیست، تنظیم دقیق آن را با دامنه خاص شما تطبیق می‌دهد.

تصور کنید شرکت شما، «Shibuya Financial»، محصولات مالی پیچیده مختلفی مثل صندوق‌های سرمایه‌گذاری، حساب‌های NISA (حساب پس‌انداز با مزایای مالیاتی)، و وام مسکن ارائه می‌دهد. تیم پشتیبانی مشتری شما از پایگاه دانش داخلی برای یافتن سریع پاسخ سؤالات مشتریان استفاده می‌کند.

راه‌اندازی

قبل‌از شروع این آموزش گام‌به‌گام، مراحل زیر را تکمیل کنید:

  • با ورود به سیستم Hugging Face و انتخاب تصدیق پروانه برای مدل Gemma، به EmbeddingGemma دسترسی پیدا کنید.
  • یک کد دسترسی Hugging Face تولید کنید و از آن برای ورود به سیستم از Colab استفاده کنید.

این دفترچه روی CPU یا GPU اجرا خواهد شد.

نصب بسته‌های Python

کتابخانه‌های موردنیاز برای اجرای مدل EmbeddingGemma و تولید جاسازی‌ها را نصب کنید. ‫Sentence Transformers چارچوب Python برای جاسازی نوشتار و تصویر است. برای اطلاعات بیشتر، به مستندات تبدیل‌کننده‌های جمله مراجعه کنید.

pip install -U sentence-transformers git+https://github.com/huggingface/transformers@v4.56.0-Embedding-Gemma-preview

پس‌از پذیرفتن پروانه، برای دسترسی به مدل به «نشان Hugging Face» معتبری نیاز دارید.

# Login into Hugging Face Hub
from huggingface_hub import login
login()

بار کردن مدل

از کتابخانه‌های sentence-transformers برای ایجاد نمونه‌ای از کلاس مدل با EmbeddingGemma استفاده کنید.

import torch
from sentence_transformers import SentenceTransformer

device = "cuda" if torch.cuda.is_available() else "cpu"

model_id = "google/embeddinggemma-300M"
model = SentenceTransformer(model_id).to(device=device)

print(f"Device: {model.device}")
print(model)
print("Total number of parameters in the model:", sum([p.numel() for _, p in model.named_parameters()]))
Device: cuda:0
SentenceTransformer(
  (0): Transformer({'max_seq_length': 2048, 'do_lower_case': False, 'architecture': 'Gemma3TextModel'})
  (1): Pooling({'word_embedding_dimension': 768, 'pooling_mode_cls_token': False, 'pooling_mode_mean_tokens': True, 'pooling_mode_max_tokens': False, 'pooling_mode_mean_sqrt_len_tokens': False, 'pooling_mode_weightedmean_tokens': False, 'pooling_mode_lasttoken': False, 'include_prompt': True})
  (2): Dense({'in_features': 768, 'out_features': 3072, 'bias': False, 'activation_function': 'torch.nn.modules.linear.Identity'})
  (3): Dense({'in_features': 3072, 'out_features': 768, 'bias': False, 'activation_function': 'torch.nn.modules.linear.Identity'})
  (4): Normalize()
)
Total number of parameters in the model: 307581696

آماده کردن مجموعه داده‌های تنظیم دقیق

این مهم‌ترین بخش است. باید مجموعه داده‌ای بسازید که به مدل آموزش دهد «مشابه» در بافتار خاص شما به چه معنا است. این داده‌ها اغلب به‌صورت سه‌تایی ساختاردهی می‌شوند: (لنگر، مثبت، منفی)

  • لنگر: پرسمان یا جمله اصلی.
  • مثبت: جمله‌ای که ازنظر معنایی بسیار مشابه یا یکسان با جمله اصلی است.
  • منفی: جمله‌ای که درباره موضوعی مرتبط است اما ازنظر معنایی متفاوت است.

در این مثال، ما فقط ۳ سه‌تایی آماده کردیم، اما برای یک برنامه واقعی، برای عملکرد خوب به مجموعه داده بسیار بزرگ‌تری نیاز دارید.

from datasets import Dataset

dataset = [
    ["How do I open a NISA account?", "What is the procedure for starting a new tax-free investment account?", "I want to check the balance of my regular savings account."],
    ["Are there fees for making an early repayment on a home loan?", "If I pay back my house loan early, will there be any costs?", "What is the management fee for this investment trust?"],
    ["What is the coverage for medical insurance?", "Tell me about the benefits of the health insurance plan.", "What is the cancellation policy for my life insurance?"],
]

# Convert the list-based dataset into a list of dictionaries.
data_as_dicts = [ {"anchor": row[0], "positive": row[1], "negative": row[2]} for row in dataset ]

# Create a Hugging Face `Dataset` object from the list of dictionaries.
train_dataset = Dataset.from_list(data_as_dicts)
print(train_dataset)
Dataset({
    features: ['anchor', 'positive', 'negative'],
    num_rows: 3
})

قبل‌از تنظیم دقیق

جستجوی «سرمایه‌گذاری بدون مالیات» ممکن است نتایج زیر را با امتیازهای شباهت ارائه دهد:

  1. سند: افتتاح حساب NISA (امتیاز: ۰٫۵۱)
  2. سند: افتتاح حساب پس‌انداز معمولی (امتیاز: ۰٫۵۰) <- امتیاز مشابه، احتمالاً گیج‌کننده
  3. سند: راهنمای درخواست وام مسکن (امتیاز: ۰٫۴۴)
task_name = "STS"

def get_scores(query, documents):
  # Calculate embeddings by calling model.encode()
  query_embeddings = model.encode(query, prompt_name=task_name)
  doc_embeddings = model.encode(documents, prompt_name=task_name)

  # Calculate the embedding similarities
  similarities = model.similarity(query_embeddings, doc_embeddings)

  for idx, doc in enumerate(documents):
    print("Document: ", doc, "-> 🤖 Score: ", similarities.numpy()[0][idx])

query = "I want to start a tax-free installment investment, what should I do?"
documents = ["Opening a NISA Account", "Opening a Regular Savings Account", "Home Loan Application Guide"]

get_scores(query, documents)
Document:  Opening a NISA Account -> 🤖 Score:  0.51571906
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.5035889
Document:  Home Loan Application Guide -> 🤖 Score:  0.4406476

تربیت

بااستفاده از چارچوبی مثل sentence-transformers در Python، مدل پایه به‌تدریج تمایزهای ظریف در واژگان مالی شما را یاد می‌گیرد.

from sentence_transformers import SentenceTransformerTrainer, SentenceTransformerTrainingArguments
from sentence_transformers.losses import MultipleNegativesRankingLoss
from transformers import TrainerCallback

loss = MultipleNegativesRankingLoss(model)

args = SentenceTransformerTrainingArguments(
    # Required parameter:
    output_dir="my-embedding-gemma",
    # Optional training parameters:
    prompts=model.prompts[task_name],    # use model's prompt to train
    num_train_epochs=5,
    per_device_train_batch_size=1,
    learning_rate=2e-5,
    warmup_ratio=0.1,
    # Optional tracking/debugging parameters:
    logging_steps=train_dataset.num_rows,
    report_to="none",
)

class MyCallback(TrainerCallback):
    "A callback that evaluates the model at the end of eopch"
    def __init__(self, evaluate):
        self.evaluate = evaluate # evaluate function

    def on_log(self, args, state, control, **kwargs):
        # Evaluate the model using text generation
        print(f"Step {state.global_step} finished. Running evaluation:")
        self.evaluate()

def evaluate():
  get_scores(query, documents)

trainer = SentenceTransformerTrainer(
    model=model,
    args=args,
    train_dataset=train_dataset,
    loss=loss,
    callbacks=[MyCallback(evaluate)]
)
trainer.train()
Step 3 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.6459116
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.42690125
Document:  Home Loan Application Guide -> 🤖 Score:  0.40419024
Step 6 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.68530923
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.3611964
Document:  Home Loan Application Guide -> 🤖 Score:  0.40812016
Step 9 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.7168733
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.3449782
Document:  Home Loan Application Guide -> 🤖 Score:  0.44477722
Step 12 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.73008573
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.34124148
Document:  Home Loan Application Guide -> 🤖 Score:  0.4676212
Step 15 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.73378766
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.34055778
Document:  Home Loan Application Guide -> 🤖 Score:  0.47503752
Step 15 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.73378766
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.34055778
Document:  Home Loan Application Guide -> 🤖 Score:  0.47503752
TrainOutput(global_step=15, training_loss=0.009651267528511198, metrics={'train_runtime': 195.3004, 'train_samples_per_second': 0.077, 'train_steps_per_second': 0.077, 'total_flos': 0.0, 'train_loss': 0.009651267528511198, 'epoch': 5.0})

پس‌از ریزتنظیم

همان جستجو اکنون نتایج بسیار واضح‌تری ارائه می‌دهد:

  1. سند: افتتاح حساب NISA (امتیاز: ۰٫۷۳) <- بسیار مطمئن‌تر
  2. سند: افتتاح حساب پس‌انداز معمولی (امتیاز: ۰٫۳۴) <- به‌وضوح نامربوط‌تر
  3. سند: راهنمای درخواست وام مسکن (امتیاز: ۰٫۴۷)
get_scores(query, documents)
Document:  Opening a NISA Account -> 🤖 Score:  0.73378766
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.34055778
Document:  Home Loan Application Guide -> 🤖 Score:  0.47503752

برای بارگذاری مدل خود در Hugging Face Hub، می‌توانید از روش push_to_hub از کتابخانه Sentence Transformers استفاده کنید.

بارگذاری مدل باعث می‌شود که دسترسی به آن برای استنباط مستقیم از «مرکز» آسان شود، بتوانید آن را با دیگران هم‌رسانی کنید، و نسخه کارتان را داشته باشید. پس‌از بارگذاری، هر کسی می‌تواند مدل شما را با یک خط کد بار کند، کافی است به شناسه مدل یکتای آن ارجاع دهد <username>/my-embedding-gemma

# Push to Hub
model.push_to_hub("my-embedding-gemma")

خلاصه و مراحل بعدی

اکنون با نحوه تطبیق دادن مدل EmbeddingGemma برای یک دامنه خاص ازطریق تنظیم دقیق آن با کتابخانه Sentence Transformers آشنا شدید.

ببینید با EmbeddingGemma چه کارهای دیگری می‌توانید انجام دهید: