Gjeneroni Embeddings me Transformers Fjali

Shikoni në ai.google.dev Ekzekutoni në Google Colab Vraponi në Kaggle Hapni në Vertex AI Shiko burimin në GitHub

EmbeddingGemma është një model me peshë të lehtë dhe të hapur, i krijuar për rikthim të shpejtë dhe me cilësi të lartë në pajisjet e përditshme si telefonat celularë. Me vetëm 308 milionë parametra, është mjaft efikase për të ekzekutuar teknika të avancuara të AI, të tilla si Retrieval Augmented Generation (RAG), direkt në kompjuterin tuaj lokal, pa kërkuar lidhje interneti.

Konfigurimi

Përpara se të filloni këtë tutorial, plotësoni hapat e mëposhtëm:

  • Merrni akses në Gemma duke u identifikuar në Hugging Face dhe duke zgjedhur Acknowledge License për një model Gemma.
  • Gjeneroni një Token të Qasjes për Hugging Face dhe përdorni atë për t'u identifikuar nga Colab.

Ky fletore do të funksionojë ose në CPU ose GPU.

Instaloni paketat Python

Instaloni bibliotekat e nevojshme për ekzekutimin e modelit EmbeddingGemma dhe gjenerimin e ngulitjeve. Sentence Transformers është një kornizë Python për futjen e tekstit dhe imazhit. Për më shumë informacion, shihni dokumentacionin e Transformuesve të Fjalive .

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

Pasi të keni pranuar licencën, ju nevojitet një shenjë e vlefshme Hugging Face për të hyrë në model.

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

Modeli i ngarkimit

Përdorni bibliotekat sentence-transformers për të krijuar një shembull të një klase modeli me 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

Gjenerimi i Embedding

Një ngulitje është një paraqitje numerike e tekstit, si një fjalë ose fjali, që kap kuptimin e tij semantik. Në thelb, është një listë numrash (një vektor) që lejon kompjuterët të kuptojnë marrëdhëniet dhe kontekstin e fjalëve.

Le të shohim se si EmbeddingGemma do të përpunonte tre fjalë të ndryshme ["apple", "banana", "car"] .

EmbeddingGemma është trajnuar për sasi të mëdha teksti dhe ka mësuar marrëdhëniet midis fjalëve dhe koncepteve.

words = ["apple", "banana", "car"]

# Calculate embeddings by calling model.encode()
embeddings = model.encode(words)

print(embeddings)
for idx, embedding in enumerate(embeddings):
  print(f"Embedding {idx+1} (shape): {embedding.shape}")
[[-0.18476306  0.00167681  0.03773484 ... -0.07996225 -0.02348064
   0.00976741]
 [-0.21189538 -0.02657359  0.02513712 ... -0.08042689 -0.01999852
   0.00512146]
 [-0.18924113 -0.02551468  0.04486253 ... -0.06377774 -0.03699806
   0.03973572]]
Embedding 1: (768,)
Embedding 2: (768,)
Embedding 3: (768,)

Modeli nxjerr një vektor numerik për çdo fjali. Vektorët aktualë janë shumë të gjatë (768), por për thjeshtësi, ata janë paraqitur me disa dimensione.

Çelësi nuk është vetë numrat individualë, por distanca midis vektorëve . Nëse do t'i vizatonim këta vektorë në një hapësirë ​​shumë-dimensionale, vektorët për apple dhe banana do të ishin shumë afër njëri-tjetrit. Dhe vektori për car do të ishte shumë larg nga dy të tjerët.

Përcaktimi i ngjashmërisë

Në këtë seksion, ne përdorim ngulitje për të përcaktuar se sa të ngjashme janë fjalitë e ndryshme semenisht. Këtu tregojmë shembuj me rezultate të larta, të mesme dhe të ulëta të ngjashmërisë.

  • Ngjashmëri e lartë:

    • Fjalia A: "Kuzhinieri përgatiti një vakt të shijshëm për të ftuarit".
    • Fjalia B: "Një darkë e shijshme u gatua nga shefi i kuzhinës për vizitorët".
    • Arsyetimi: Të dyja fjalitë përshkruajnë të njëjtën ngjarje duke përdorur fjalë dhe struktura të ndryshme gramatikore (zëri aktiv kundrejt pasiv). Ata përcjellin të njëjtin kuptim thelbësor.
  • Ngjashmëri mesatare:

    • Fjalia A: "Ajo është një eksperte në mësimin e makinerive".
    • Fjalia B: "Ai ka një interes të thellë për inteligjencën artificiale".
    • Arsyetimi: Fjalitë janë të lidhura pasi mësimi i makinerive është një nënfushë e inteligjencës artificiale. Megjithatë, ata flasin për njerëz të ndryshëm me nivele të ndryshme angazhimi (ekspert kundrejt interesit).
  • Ngjashmëri e ulët:

    • Fjalia A: "Moti në Tokio është me diell sot".
    • Fjalia B: "Më duhet të blej sende ushqimore për javën".
    • Arsyetimi: Dy fjalitë janë në tema krejtësisht të palidhura dhe nuk kanë asnjë mbivendosje semantike.
# The sentences to encode
sentence_high = [
    "The chef prepared a delicious meal for the guests.",
    "A tasty dinner was cooked by the chef for the visitors."
]
sentence_medium = [
    "She is an expert in machine learning.",
    "He has a deep interest in artificial intelligence."
]
sentence_low = [
    "The weather in Tokyo is sunny today.",
    "I need to buy groceries for the week."
]

for sentence in [sentence_high, sentence_medium, sentence_low]:
  print("🙋‍♂️")
  print(sentence)
  embeddings = model.encode(sentence)
  similarities = model.similarity(embeddings[0], embeddings[1])
  print("`-> 🤖 score: ", similarities.numpy()[0][0])
🙋‍♂️
['The chef prepared a delicious meal for the guests.', 'A tasty dinner was cooked by the chef for the visitors.']
`-> 🤖 score:  0.8002148
🙋‍♂️
['She is an expert in machine learning.', 'He has a deep interest in artificial intelligence.']
`-> 🤖 score:  0.45417833
🙋‍♂️
['The weather in Tokyo is sunny today.', 'I need to buy groceries for the week.']
`-> 🤖 score:  0.22262995

Përdorimi i kërkesave me EmbeddingGemma

Për të gjeneruar futjet më të mira me EmbeddingGemma, duhet të shtoni një "prompt udhëzues" ose "detyrë" në fillim të tekstit tuaj të hyrjes. Këto kërkesa optimizojnë futjet për detyra specifike, të tilla si marrja e dokumenteve ose përgjigjja e pyetjeve, dhe ndihmojnë modelin të dallojë midis llojeve të ndryshme të hyrjes, si një pyetje kërkimi kundrejt një dokumenti.

Si të aplikoni kërkesat

Ju mund të aplikoni një kërkesë gjatë përfundimit në tre mënyra.

  1. Duke përdorur argumentin prompt
    Kaloni vargun e plotë të kërkesës direkt në metodën encode . Kjo ju jep kontroll të saktë.

    embeddings = model.encode(
        sentence,
        prompt="task: sentence similarity | query: "
    )
    
  2. Duke përdorur argumentin prompt_name
    Zgjidhni një kërkesë të paracaktuar me emrin e saj. Këto kërkesa ngarkohen nga konfigurimi i modelit ose gjatë inicializimit të tij.

    embeddings = model.encode(sentence, prompt_name="STS")
    
  3. Duke përdorur Prompt Default
    Nëse nuk specifikoni as prompt as prompt_name , sistemi do të përdorë automatikisht grupin e prompt si default_prompt_name , nëse nuk është caktuar asnjë parazgjedhje, atëherë nuk zbatohet asnjë kërkesë.

    embeddings = model.encode(sentence)
    
print("Available tasks:")
for name, prefix in model.prompts.items():
  print(f" {name}: \"{prefix}\"")
print("-"*80)

for sentence in [sentence_high, sentence_medium, sentence_low]:
  print("🙋‍♂️")
  print(sentence)
  embeddings = model.encode(sentence, prompt_name="STS")
  similarities = model.similarity(embeddings[0], embeddings[1])
  print("`-> 🤖 score: ", similarities.numpy()[0][0])
Available tasks:
 query: "task: search result | query: "
 document: "title: none | text: "
 BitextMining: "task: search result | query: "
 Clustering: "task: clustering | query: "
 Classification: "task: classification | query: "
 InstructionRetrieval: "task: code retrieval | query: "
 MultilabelClassification: "task: classification | query: "
 PairClassification: "task: sentence similarity | query: "
 Reranking: "task: search result | query: "
 Retrieval: "task: search result | query: "
 Retrieval-query: "task: search result | query: "
 Retrieval-document: "title: none | text: "
 STS: "task: sentence similarity | query: "
 Summarization: "task: summarization | query: "
--------------------------------------------------------------------------------
🙋‍♂️
['The chef prepared a delicious meal for the guests.', 'A tasty dinner was cooked by the chef for the visitors.']
`-> 🤖 score:  0.9363755
🙋‍♂️
['She is an expert in machine learning.', 'He has a deep interest in artificial intelligence.']
`-> 🤖 score:  0.6425841
🙋‍♂️
['The weather in Tokyo is sunny today.', 'I need to buy groceries for the week.']
`-> 🤖 score:  0.38587403

Rasti i përdorimit: Gjenerimi i Shtuar i Rikthimit (RAG)

Për sistemet RAG, përdorni vlerat e mëposhtme prompt_name për të krijuar ngulitje të specializuara për pyetjet dhe dokumentet tuaja:

  • Për pyetjet: Përdorni prompt_name="Retrieval-query" .

    query_embedding = model.encode(
        "How do I use prompts with this model?",
        prompt_name="Retrieval-query"
    )
    
  • Për Dokumentet: Përdorni prompt_name="Retrieval-document" . Për të përmirësuar më tej futjet e dokumenteve, mund të përfshini gjithashtu një titull duke përdorur drejtpërdrejt argumentin prompt :

    • Me titull:
    doc_embedding = model.encode(
        "The document text...",
        prompt="title: Using Prompts in RAG | text: "
    )
    
    • Pa titull:
    doc_embedding = model.encode(
        "The document text...",
        prompt="title: none | text: "
    )
    

Lexim i mëtejshëm

Klasifikimi

Klasifikimi është detyra e caktimit të një pjese teksti në një ose më shumë kategori ose etiketa të paracaktuara. Është një nga detyrat më themelore në Përpunimin e Gjuhës Natyrore (NLP).

Një aplikim praktik i klasifikimit të tekstit është drejtimi i biletave të mbështetjes së klientit. Ky proces drejton automatikisht pyetjet e klientëve në departamentin e duhur, duke kursyer kohë dhe duke zvogëluar punën manuale.

labels = ["Billing Issue", "Technical Support", "Sales Inquiry"]

sentence = [
  "Excuse me, the app freezes on the login screen. It won't work even when I try to reset my password.",
  "I would like to inquire about your enterprise plan pricing and features for a team of 50 people.",
]

# Calculate embeddings by calling model.encode()
label_embeddings = model.encode(labels, prompt_name="Classification")
embeddings = model.encode(sentence, prompt_name="Classification")

# Calculate the embedding similarities
similarities = model.similarity(embeddings, label_embeddings)
print(similarities)

idx = similarities.argmax(1)
print(idx)

for example in sentence:
  print("🙋‍♂️", example, "-> 🤖", labels[idx[sentence.index(example)]])
tensor([[0.4673, 0.5145, 0.3604],
        [0.4191, 0.5010, 0.5966]])
tensor([1, 2])
🙋‍♂️ Excuse me, the app freezes on the login screen. It won't work even when I try to reset my password. -> 🤖 Technical Support
🙋‍♂️ I would like to inquire about your enterprise plan pricing and features for a team of 50 people. -> 🤖 Sales Inquiry

Matryoshka Representation Learning (MRL)

EmbeddingGemma përdor MRL për të siguruar madhësi të shumta të ngulitjes nga një model. Është një metodë e zgjuar trajnimi që krijon një futje të vetme, me cilësi të lartë, ku informacioni më i rëndësishëm përqendrohet në fillim të vektorit.

Kjo do të thotë që ju mund të merrni një futje më të vogël, por gjithsesi shumë të dobishme, thjesht duke marrë dimensionet e para N të futjes së plotë. Përdorimi i futjeve më të vogla dhe të shkurtuara është dukshëm më i lirë për t'u ruajtur dhe më i shpejtë për t'u përpunuar, por ky efikasitet vjen me koston e një cilësie më të ulët të mundshme të futjeve. MRL ju jep fuqinë për të zgjedhur ekuilibrin optimal midis kësaj shpejtësie dhe saktësisë për nevojat specifike të aplikacionit tuaj.

Le të përdorim tre fjalë ["apple", "banana", "car"] dhe të krijojmë futje të thjeshtuara për të parë se si funksionon MRL.

def check_word_similarities():
  # Calculate the embedding similarities
  print("similarity function: ", model.similarity_fn_name)
  similarities = model.similarity(embeddings[0], embeddings[1:])
  print(similarities)

  for idx, word in enumerate(words[1:]):
    print("🙋‍♂️ apple vs.", word, "-> 🤖 score: ", similarities.numpy()[0][idx])

# Calculate embeddings by calling model.encode()
embeddings = model.encode(words, prompt_name="STS")

check_word_similarities()
similarity function:  cosine
tensor([[0.7510, 0.6685]])
🙋‍♂️ apple vs. banana -> 🤖 score:  0.75102395
🙋‍♂️ apple vs. car -> 🤖 score:  0.6684626

Tani, për një aplikim më të shpejtë, nuk keni nevojë për një model të ri. Thjesht shkurtoni futjet e plota në 512 dimensionet e para. Për rezultate optimale, rekomandohet gjithashtu të vendosni normalize_embeddings=True , e cila i shkallëzon vektorët në një gjatësi njësi prej 1.

embeddings = model.encode(words, truncate_dim=512, normalize_embeddings=True)

for idx, embedding in enumerate(embeddings):
  print(f"Embedding {idx+1}: {embedding.shape}")

print("-"*80)
check_word_similarities()
Embedding 1: (512,)
Embedding 2: (512,)
Embedding 3: (512,)
--------------------------------------------------------------------------------
similarity function:  cosine
tensor([[0.7674, 0.7041]])
🙋‍♂️ apple vs. banana -> 🤖 score:  0.767427
🙋‍♂️ apple vs. car -> 🤖 score:  0.7040509

Në mjedise jashtëzakonisht të kufizuara, ju mund t'i shkurtoni më tej futjet në vetëm 256 dimensione . Ju gjithashtu mund të përdorni produktin më efikas të pikave për llogaritjet e ngjashmërisë në vend të ngjashmërisë standarde të kosinusit .

model = SentenceTransformer(model_id, truncate_dim=256, similarity_fn_name="dot").to(device=device)
embeddings = model.encode(words, prompt_name="STS", normalize_embeddings=True)

for idx, embedding in enumerate(embeddings):
  print(f"Embedding {idx+1}: {embedding.shape}")

print("-"*80)
check_word_similarities()
Embedding 1: (256,)
Embedding 2: (256,)
Embedding 3: (256,)
--------------------------------------------------------------------------------
similarity function:  dot
tensor([[0.7855, 0.7382]])
🙋‍♂️ apple vs. banana -> 🤖 score:  0.7854644
🙋‍♂️ apple vs. car -> 🤖 score:  0.7382126

Përmbledhja dhe hapat e mëtejshëm

Tani jeni të pajisur për të gjeneruar ngulitje teksti me cilësi të lartë duke përdorur EmbeddingGemma dhe bibliotekën Sentence Transformers. Zbatoni këto aftësi për të ndërtuar veçori të fuqishme si ngjashmëria semantike, klasifikimi i tekstit dhe sistemet e gjenerimit të shtuar (RAG) dhe vazhdoni të eksploroni se çfarë është e mundur me modelet Gemma.

Shikoni dokumentet e mëposhtme në vijim: