|
|
Запустить в Google Colab
|
|
|
Посмотреть исходный код на GitHub
|
EmbeddingGemma – это легкая открытая модель для создания встраиваемых объектов, предназначенная для быстрого и качественного поиска на обычных устройствах, таких как мобильные телефоны. Модель содержит всего 308 миллионов параметров, поэтому она достаточно эффективна для использования передовых методов ИИ, таких как генерация с расширенным поиском (RAG), непосредственно на вашем локальном устройстве без подключения к интернету.
Настройка
Прежде чем начать работу с этим руководством, выполните следующие действия:
- Чтобы получить доступ к Gemma, войдите в аккаунт Hugging Face и выберите Acknowledge license (Принять лицензию) для модели Gemma.
- Сгенерируйте токен доступа Hugging Face и используйте его для входа в Colab.
Этот блокнот будет выполняться на центральном или графическом процессоре.
Как установить пакеты 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 будет далеко от двух других.
Как определить сходство
В этом разделе мы используем встраивание, чтобы определить, насколько семантически похожи разные предложения. Ниже приведены примеры с высоким, средним и низким показателями сходства.
Высокое сходство:
- Предложение А: "Шеф-повар приготовил для гостей вкусное блюдо".
- Предложение Б: "Шеф-повар приготовил для посетителей вкусный ужин".
- Обоснование. В обоих предложениях описывается одно и то же событие, но разными словами и грамматическими конструкциями (активный и пассивный залог). Они передают один и тот же основной смысл.
Среднее сходство:
- Предложение А: "Она эксперт в области машинного обучения".
- Предложение Б: "Он очень интересуется искусственным интеллектом".
- Обоснование: предложения связаны, поскольку машинное обучение – это область искусственного интеллекта. Однако в них говорится о разных людях с разным уровнем вовлеченности (эксперт и заинтересованный пользователь).
Низкое сходство:
- Предложение А: "Сегодня в Токио солнечная погода".
- Предложение Б: "Мне нужно купить продукты на неделю".
- Обоснование. В этих двух предложениях речь идет о совершенно разных вещах, и они не связаны между собой по смыслу.
# 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 можно найти в простом примере RAG в кулинарной книге Gemma.
Классификация
Классификация – это задача по отнесению фрагмента текста к одной или нескольким заранее определенным категориям или ярлыкам. Это одна из основных задач в области обработки естественного языка (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 Representation Learning (MRL)
Встраивание Gemma использует MRL, чтобы предоставлять несколько размеров встраивания из одной модели. Это эффективный метод обучения, который позволяет создать одно высококачественное встраивание, в котором наиболее важная информация сосредоточена в начале вектора.
Это означает, что вы можете получить меньший, но все ещё очень полезный вектор, просто взяв первые N измерений полного вектора. Хранить и обрабатывать усеченные встраивания значительно дешевле и быстрее, но это может привести к снижению качества. MRL позволяет выбрать оптимальный баланс между скоростью и точностью в зависимости от потребностей вашего приложения.
Давайте рассмотрим, как работает MRL, на примере трех слов ["apple", "banana", "car"] и упрощенных встраиваний.
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 измерений. Для достижения оптимальных результатов также рекомендуется задать значение normalize_embeddings=True, которое масштабирует векторы до единичной длины 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
В условиях очень ограниченных ресурсов можно сократить количество измерений до 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
- Простой пример RAG в книге рецептов Gemma
Запустить в Google Colab
Посмотреть исходный код на GitHub