|  Visualizza su ai.google.dev |  Esegui in Google Colab |  Esegui in Kaggle |  |  Visualizza il codice sorgente su GitHub | 
EmbeddingGemma è un modello di embedding open source e leggero progettato per un recupero rapido e di alta qualità su dispositivi di uso quotidiano come i cellulari. Con soli 308 milioni di parametri, è abbastanza efficiente da eseguire tecniche di AI avanzate, come la generazione aumentata dal recupero (RAG), direttamente sulla tua macchina locale senza richiedere una connessione a internet.
Configurazione
Prima di iniziare questo tutorial, completa i seguenti passaggi:
- Accedi a Gemma effettuando l'accesso a Hugging Face e selezionando Accetta licenza per un modello Gemma.
- Genera un token di accesso Hugging Face e utilizzalo per accedere da Colab.
Questo notebook verrà eseguito su CPU o GPU.
Installa i pacchetti Python
Installa le librerie necessarie per eseguire il modello EmbeddingGemma e generare gli embedding. Sentence Transformers è un framework Python per gli incorporamenti di testo e immagini. Per saperne di più, consulta la documentazione di Sentence Transformers.
pip install -U sentence-transformers git+https://github.com/huggingface/transformers@v4.56.0-Embedding-Gemma-previewDopo aver accettato la licenza, per accedere al modello è necessario un token Hugging Face valido.
# Login into Hugging Face Hub
from huggingface_hub import login
login()
Carica modello
Utilizza le librerie sentence-transformers per creare un'istanza di una classe di modello con 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
Generazione dell'incorporamento
Un embedding è una rappresentazione numerica di un testo, ad esempio una parola o una frase, che ne acquisisce il significato semantico. In sostanza, si tratta di un elenco di numeri (un vettore) che consente ai computer di comprendere le relazioni e il contesto delle parole.
Vediamo come EmbeddingGemma elaborerebbe tre parole diverse ["apple", "banana", "car"].
EmbeddingGemma è stato addestrato su grandi quantità di testo e ha appreso le relazioni tra parole e concetti.
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,)
Il modello restituisce un vettore numerico per ogni frase. I vettori effettivi sono molto lunghi (768), ma per semplicità vengono presentati con poche dimensioni.
La chiave non sono i singoli numeri, ma la distanza tra i vettori. Se dovessimo tracciare questi vettori in uno spazio multidimensionale, i vettori per apple e banana sarebbero molto vicini tra loro. Il vettore per car sarebbe lontano dagli altri due.
Determinare la somiglianza
In questa sezione utilizziamo gli incorporamenti per determinare il grado di somiglianza semantica tra diverse frasi. Di seguito mostriamo esempi con punteggi di somiglianza alti, medi e bassi.
- Similarità elevata: - Frase A: "Lo chef ha preparato un pasto delizioso per gli ospiti".
- Frase B: "Lo chef ha preparato una cena gustosa per i visitatori".
- Motivazione: entrambe le frasi descrivono lo stesso evento utilizzando parole e strutture grammaticali diverse (forma attiva e passiva). Trasmettono lo stesso significato di base.
 
- Somiglianza media: - Frase A: "È un'esperta di machine learning".
- Frase B: "Ha un profondo interesse per l'intelligenza artificiale".
- Motivazione: le frasi sono correlate perché il machine learning è una branca secondaria dell'intelligenza artificiale. Tuttavia, parlano di persone diverse con livelli di coinvolgimento diversi (esperto e interesse).
 
- Somiglianza bassa: - Frase A: "Oggi a Tokyo c'è il sole."
- Frase B: "Devo comprare la spesa per la settimana".
- Motivazione: le due frasi riguardano argomenti completamente non correlati e non condividono alcuna sovrapposizione semantica.
 
# 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
Utilizzo dei prompt con EmbeddingGemma
Per generare gli incorporamenti migliori con EmbeddingGemma, devi aggiungere un "prompt didattico" o un "task" all'inizio del testo di input. Questi prompt ottimizzano gli incorporamenti per attività specifiche, come il recupero di documenti o la risposta alle domande, e aiutano il modello a distinguere tra diversi tipi di input, ad esempio una query di ricerca e un documento.
Come applicare i prompt
Puoi applicare un prompt durante l'inferenza in tre modi.
- Utilizzo dell'argomento - prompt
 Passa la stringa di prompt completa direttamente al metodo- encode. In questo modo hai un controllo preciso.- embeddings = model.encode( sentence, prompt="task: sentence similarity | query: " )
- Utilizzo dell'argomento - prompt_name
 Seleziona un prompt predefinito in base al nome. Questi prompt vengono caricati dalla configurazione del modello o durante l'inizializzazione.- embeddings = model.encode(sentence, prompt_name="STS")
- Utilizzo del prompt predefinito 
 Se non specifichi- prompto- prompt_name, il sistema utilizzerà automaticamente il prompt impostato come- default_prompt_name. Se non è impostato alcun valore predefinito, non viene applicato alcun prompt.- 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
Caso d'uso: Retrieval-Augmented Generation (RAG)
Per i sistemi RAG, utilizza i seguenti valori di prompt_name per creare incorporamenti specializzati per le query e i documenti:
- Per le query:utilizza - prompt_name="Retrieval-query".- query_embedding = model.encode( "How do I use prompts with this model?", prompt_name="Retrieval-query" )
- Per Documenti:utilizza - prompt_name="Retrieval-document". Per migliorare ulteriormente gli incorporamenti dei documenti, puoi anche includere un titolo utilizzando direttamente l'argomento- prompt:- Con un titolo:
 - doc_embedding = model.encode( "The document text...", prompt="title: Using Prompts in RAG | text: " )- Senza titolo:
 - doc_embedding = model.encode( "The document text...", prompt="title: none | text: " )
- Con un titolo:
Per approfondire
- Per informazioni dettagliate su tutti i prompt EmbeddingGemma disponibili, consulta la scheda del modello.
- Per informazioni generali sui modelli di prompt, consulta la documentazione di Sentence Transformer.
- Per una demo di RAG, consulta l'esempio semplice di RAG in Gemma Cookbook.
Classificazione
La classificazione è l'attività di assegnazione di un testo a una o più categorie o etichette predefinite. È una delle attività più fondamentali nell'elaborazione del linguaggio naturale (NLP).
Un'applicazione pratica della classificazione del testo è l'instradamento dei ticket di assistenza clienti. Questo processo indirizza automaticamente le query dei clienti al reparto corretto, risparmiando tempo e riducendo il lavoro 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 utilizza MRL per fornire più dimensioni di incorporamento da un unico modello. Si tratta di un metodo di addestramento intelligente che crea un unico embedding di alta qualità in cui le informazioni più importanti sono concentrate all'inizio del vettore.
Ciò significa che puoi ottenere un embedding più piccolo, ma comunque molto utile, prendendo semplicemente le prime N dimensioni dell'embedding completo. L'utilizzo di incorporamenti più piccoli e troncati è molto più economico da archiviare e più veloce da elaborare, ma questa efficienza ha un costo: la potenziale qualità inferiore degli incorporamenti. MRL ti consente di scegliere l'equilibrio ottimale tra velocità e precisione per le esigenze specifiche della tua applicazione.
Utilizziamo tre parole ["apple", "banana", "car"] e creiamo incorporamenti semplificati per vedere come funziona 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
Ora, per un'applicazione più veloce, non è necessario un nuovo modello. Basta troncare gli incorporamenti completi alle prime 512 dimensioni. Per ottenere risultati ottimali, è consigliabile impostare anche normalize_embeddings=True, che ridimensiona i vettori a una lunghezza unitaria di 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
In ambienti estremamente vincolati, puoi ridurre ulteriormente gli incorporamenti a sole 256 dimensioni. Puoi anche utilizzare il prodotto scalare, più efficiente, per i calcoli di similarità anziché la similarità coseno standard.
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
Riepilogo e passaggi successivi
Ora hai gli strumenti per generare incorporamenti di testo di alta qualità utilizzando EmbeddingGemma e la libreria Sentence Transformers. Applica queste competenze per creare funzionalità potenti come la similarità semantica, la classificazione del testo e i sistemi RAG (Retrieval-Augmented Generation) e continua a esplorare le possibilità offerte dai modelli Gemma.
Consulta i seguenti documenti:
- Perfezionare EmbeddingGemma
- Esempio semplice di RAG nel cookbook di Gemma