|  ai.google.dev에서 보기 |  Google Colab에서 실행 |  Kaggle에서 실행 |  |  GitHub에서 소스 보기 | 
EmbeddingGemma는 휴대전화와 같은 일상적인 기기에서 빠르고 고품질 검색을 위해 설계된 경량의 오픈 임베딩 모델입니다. 파라미터가 3억 8백만 개에 불과하므로 인터넷 연결 없이 로컬 머신에서 직접 검색 증강 생성 (RAG)과 같은 고급 AI 기술을 실행할 수 있을 만큼 효율적입니다.
설정
이 튜토리얼을 시작하기 전에 다음 단계를 완료하세요.
- Hugging Face에 로그인하고 Gemma 모델에 대해 라이선스 확인을 선택하여 Gemma에 액세스합니다.
- Hugging Face 액세스 토큰을 생성하고 이를 사용하여 Colab에서 로그인합니다.
이 노트북은 CPU 또는 GPU에서 실행됩니다.
Python 패키지 설치
EmbeddingGemma 모델을 실행하고 임베딩을 생성하는 데 필요한 라이브러리를 설치합니다. Sentence Transformers는 텍스트 및 이미지 임베딩을 위한 Python 프레임워크입니다. 자세한 내용은 Sentence 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()
모델 로드
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
임베딩 생성
임베딩은 단어나 문장과 같은 텍스트의 수치 표현으로, 시맨틱 의미를 포착합니다. 기본적으로 컴퓨터가 단어의 관계와 맥락을 이해할 수 있도록 하는 숫자 목록 (벡터)입니다.
EmbeddingGemma가 세 가지 단어를 어떻게 처리하는지 살펴보겠습니다 ["apple", "banana", "car"].
EmbeddingGemma는 방대한 양의 텍스트를 학습했으며 단어와 개념 간의 관계를 학습했습니다.
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,)
모델은 각 문장에 대한 숫자 벡터를 출력합니다. 실제 벡터는 매우 길지만 (768) 간단하게 몇 가지 차원으로 표시됩니다.
키는 개별 숫자가 아니라 벡터 간의 거리입니다. 다차원 공간에 이러한 벡터를 표시하면 apple 및 banana의 벡터가 서로 매우 가까워집니다. car의 벡터는 다른 두 벡터와 멀리 떨어져 있습니다.
유사성 판단
이 섹션에서는 임베딩을 사용하여 서로 다른 문장이 의미적으로 얼마나 유사한지 확인합니다. 여기에서는 유사성 점수가 높음, 중간, 낮음인 예를 보여줍니다.
- 유사성이 높음: - 문장 A: '요리사가 손님을 위해 맛있는 식사를 준비했습니다.'
- 문장 B: '방문객을 위해 요리사가 맛있는 저녁 식사를 요리했습니다.'
- 이유: 두 문장 모두 서로 다른 단어와 문법 구조 (능동태 vs. 수동태)를 사용하여 동일한 이벤트를 설명합니다. 핵심 의미는 동일합니다.
 
- 중간 유사성: - 문장 A: '그녀는 머신러닝 전문가입니다.'
- 문장 B: '그는 인공지능에 깊은 관심을 가지고 있습니다.'
- 이유: 머신러닝은 인공지능의 하위 분야이므로 두 문장이 관련이 있습니다. 하지만 참여 수준이 다른 사람 (전문가와 관심 있는 사람)에 대해 이야기합니다.
 
- 유사성이 낮음: - 문장 A: '오늘 도쿄 날씨는 맑아.'
- 문장 B: '이번 주 식료품을 사야 해.'
- 이유: 두 문장은 완전히 관련이 없는 주제에 관한 내용이며 의미상 중복되는 부분이 없습니다.
 
# 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
EmbeddingGemma로 프롬프트 사용
EmbeddingGemma로 최적의 임베딩을 생성하려면 입력 텍스트의 시작 부분에 '안내 프롬프트' 또는 '작업'을 추가해야 합니다. 이러한 프롬프트는 문서 검색 또는 질문 답변과 같은 특정 작업에 맞게 임베딩을 최적화하고 모델이 검색어와 문서와 같은 다양한 입력 유형을 구분하는 데 도움이 됩니다.
프롬프트 적용 방법
추론 중에 프롬프트를 적용하는 방법은 세 가지입니다.
- prompt인수 사용
 전체 프롬프트 문자열을- encode메서드에 직접 전달합니다. 이를 통해 정확하게 제어할 수 있습니다.- embeddings = model.encode( sentence, prompt="task: sentence similarity | query: " )
- prompt_name인수 사용
 이름으로 사전 정의된 프롬프트를 선택합니다. 이러한 프롬프트는 모델의 구성에서 또는 초기화 중에 로드됩니다.- embeddings = model.encode(sentence, prompt_name="STS")
- 기본 프롬프트 사용 
 - prompt또는- prompt_name을 지정하지 않으면 시스템에서- default_prompt_name으로 설정된 프롬프트를 자동으로 사용합니다. 기본값이 설정되지 않은 경우 프롬프트가 적용되지 않습니다.- 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
사용 사례: 검색 증강 생성 (RAG)
RAG 시스템의 경우 다음 prompt_name 값을 사용하여 쿼리 및 문서에 대한 전문 임베딩을 만드세요.
- 쿼리: - prompt_name="Retrieval-query"를 사용합니다.- query_embedding = model.encode( "How do I use prompts with this model?", prompt_name="Retrieval-query" )
- 문서: - prompt_name="Retrieval-document"를 사용합니다. 문서 임베딩을 더욱 개선하려면- prompt인수를 직접 사용하여 제목을 포함할 수도 있습니다.- 제목이 있는 경우:
 - doc_embedding = model.encode( "The document text...", prompt="title: Using Prompts in RAG | text: " )- 제목이 없는 경우:
 - doc_embedding = model.encode( "The document text...", prompt="title: none | text: " )
- 제목이 있는 경우:
추가 자료
- 사용 가능한 모든 EmbeddingGemma 프롬프트에 대한 자세한 내용은 모델 카드를 참고하세요.
- 프롬프트 템플릿에 대한 일반 정보는 Sentence Transformer 문서를 참고하세요.
- RAG 데모는 Gemma Cookbook의 Simple RAG example을 참고하세요.
분류
분류는 텍스트 조각을 하나 이상의 사전 정의된 카테고리 또는 라벨에 할당하는 작업입니다. 이는 자연어 처리 (NLP)에서 가장 기본적인 작업 중 하나입니다.
텍스트 분류의 실제 적용 사례는 고객 지원 티켓 라우팅입니다. 이 프로세스는 고객 문의를 올바른 부서로 자동 전달하여 시간을 절약하고 수동 작업을 줄여줍니다.
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 표현 학습 (MRL)
EmbeddingGemma는 MRL을 활용하여 하나의 모델에서 여러 임베딩 크기를 제공합니다. 가장 중요한 정보가 벡터의 시작 부분에 집중된 단일 고품질 임베딩을 생성하는 영리한 학습 방법입니다.
즉, 전체 임베딩의 첫 번째 N 차원을 가져오기만 하면 작지만 매우 유용한 임베딩을 얻을 수 있습니다. 더 작고 잘린 삽입을 사용하면 저장 비용이 훨씬 저렴하고 처리 속도가 빠르지만 삽입의 품질이 낮아질 수 있습니다. MRL을 사용하면 애플리케이션의 특정 요구사항에 맞게 이 속도와 정확도 간의 최적의 균형을 선택할 수 있습니다.
["apple", "banana", "car"]라는 세 단어를 사용하여 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
이제 더 빠른 애플리케이션을 위해 새 모델이 필요하지 않습니다. 전체 임베딩을 처음 512차원으로 잘라내기만 하면 됩니다. 최적의 결과를 얻으려면 벡터를 단위 길이 1로 조정하는 normalize_embeddings=True도 설정하는 것이 좋습니다.
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
매우 제한된 환경에서는 256차원으로만 삽입을 추가로 단축할 수 있습니다. 표준 코사인 유사성 대신 더 효율적인 내적을 유사성 계산에 사용할 수도 있습니다.
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
요약 및 다음 단계
이제 EmbeddingGemma와 Sentence Transformers 라이브러리를 사용하여 고품질 텍스트 임베딩을 생성할 수 있습니다. 이러한 기술을 적용하여 시맨틱 유사성, 텍스트 분류, 검색 증강 생성 (RAG) 시스템과 같은 강력한 기능을 구축하고 Gemma 모델로 할 수 있는 작업을 계속 탐색하세요.
다음 문서를 확인하세요.
- EmbeddingGemma 미세 조정
- Gemma Cookbook의 간단한 RAG 예시