EmbeddingGemma را به خوبی تنظیم کنید

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

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

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

راه اندازی

قبل از شروع این آموزش، مراحل زیر را انجام دهید:

  • با ورود به Hugging Face و انتخاب مجوز Acknowledge برای مدل Gemma به EmbeddingGemma دسترسی پیدا کنید.
  • یک نشانه دسترسی به چهره در آغوش گرفته و از آن برای ورود از Colab استفاده کنید.

این نوت بوک بر روی CPU یا GPU کار می کند.

بسته های پایتون را نصب کنید

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

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()

مدل بارگذاری

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

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

Fine-Tuning Dataset را آماده کنید

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

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

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

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 (امتیاز: 0.45)
  2. سند: باز کردن یک حساب پس انداز معمولی (امتیاز: 0.48) <- امتیاز مشابه، بالقوه گیج کننده
  3. سند: راهنمای درخواست وام مسکن (امتیاز: 0.42)
task_name = "STS"

def get_scores(query, documents):
  # Calculate embeddings by calling model.encode()
  query_embeddings = model.encode(query, prompt=task_name)
  doc_embeddings = model.encode(documents, prompt=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.45698774
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.48092696
Document:  Home Loan Application Guide -> 🤖 Score:  0.42127067

آموزش

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

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.6449194
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.44123
Document:  Home Loan Application Guide -> 🤖 Score:  0.46752414
Step 6 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.68873787
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.34069622
Document:  Home Loan Application Guide -> 🤖 Score:  0.50065553
Step 9 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.7148906
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.30480516
Document:  Home Loan Application Guide -> 🤖 Score:  0.52454984
Step 12 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.72614634
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.29255486
Document:  Home Loan Application Guide -> 🤖 Score:  0.5370023
Step 15 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.7294032
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.2893038
Document:  Home Loan Application Guide -> 🤖 Score:  0.54087913
Step 15 finished. Running evaluation:
Document:  Opening a NISA Account -> 🤖 Score:  0.7294032
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.2893038
Document:  Home Loan Application Guide -> 🤖 Score:  0.54087913
TrainOutput(global_step=15, training_loss=0.009651281436261646, metrics={'train_runtime': 63.2486, 'train_samples_per_second': 0.237, 'train_steps_per_second': 0.237, 'total_flos': 0.0, 'train_loss': 0.009651281436261646, 'epoch': 5.0})

پس از تنظیم دقیق

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

  1. سند: افتتاح حساب NISA (امتیاز: 0.72) <- بسیار مطمئن تر
  2. سند: باز کردن یک حساب پس انداز معمولی (امتیاز: 0.28) <- به وضوح کمتر مرتبط است
  3. سند: راهنمای درخواست وام مسکن (امتیاز: 0.54)
get_scores(query, documents)
Document:  Opening a NISA Account -> 🤖 Score:  0.7294032
Document:  Opening a Regular Savings Account -> 🤖 Score:  0.2893038
Document:  Home Loan Application Guide -> 🤖 Score:  0.54087913

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

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

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

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

اکنون یاد گرفته‌اید که چگونه یک مدل EmbeddingGemma را برای یک دامنه خاص با تنظیم دقیق آن با کتابخانه Sentence Transformers تطبیق دهید.

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