Модель для расчетов эмбеддингов предложений на русском и английском языках получена методом дистилляции эмбеддингов
ai-forever/FRIDA (размер эмбеддингов - 1536, слоёв - 24). Основной режим использования FRIDA - CLS pooling заменен на mean pooling. Каких-либо других изменений поведения модели (модификации или фильтрации эмбеддингов, использования дополнительной модели) не производилось. Дистиляция выполнена в максимально возможном объеме - эмбеддинги русских и английских предложений, работа префиксов.
Модель принадлежит к виду uncased - не различает при обработке текста буквы, написанные в верхнем и нижнем регистре (фразы, например, "С Новым Годом!" и "С НОВЫМ ГОДОМ!" кодируются одинаковой последовательностью токенов и имеют равные значения эмбеддингов). Размер эмбеддингов модели - 384, слоёв - 7. Размер контекста модели соответствует FRIDA - 512 токенов.
Все префиксы унаследованы от FRIDA.
Перечень используемых префиксов и их влияние на оценки модели в
encodechka:
Оценки модели на бенчмарке
ruMTEB:
1import torch
2import torch.nn.functional as F
3from transformers import AutoTokenizer, AutoModel
4
5
6def pool(hidden_state, mask, pooling_method="mean"):
7 if pooling_method == "mean":
8 s = torch.sum(hidden_state * mask.unsqueeze(-1).float(), dim=1)
9 d = mask.sum(axis=1, keepdim=True).float()
10 return s / d
11 elif pooling_method == "cls":
12 return hidden_state[:, 0]
13
14inputs = [
15 #
16 "paraphrase: В Ярославской области разрешили работу бань, но без посетителей",
17 "categorize_entailment: Женщину доставили в больницу, за ее жизнь сейчас борются врачи.",
18 "search_query: Сколько программистов нужно, чтобы вкрутить лампочку?",
19 #
20 "paraphrase: Ярославским баням разрешили работать без посетителей",
21 "categorize_entailment: Женщину спасают врачи.",
22 "search_document: Чтобы вкрутить лампочку, требуется три программиста: один напишет программу извлечения лампочки, другой — вкручивания лампочки, а третий проведет тестирование."
23]
24
25tokenizer = AutoTokenizer.from_pretrained("sergeyzh/rubert-mini-uncased")
26model = AutoModel.from_pretrained("sergeyzh/rubert-mini-uncased")
27
28tokenized_inputs = tokenizer(inputs, max_length=512, padding=True, truncation=True, return_tensors="pt")
29
30with torch.no_grad():
31 outputs = model(**tokenized_inputs)
32
33embeddings = pool(
34 outputs.last_hidden_state,
35 tokenized_inputs["attention_mask"],
36 pooling_method="mean"
37)
38
39embeddings = F.normalize(embeddings, p=2, dim=1)
40sim_scores = embeddings[:3] @ embeddings[3:].T
41print(sim_scores.diag().tolist())
42# [0.9366128444671631, 0.8030662536621094, 0.6826460957527161]
43# [0.9360030293464661, 0.8591322302818298, 0.728583037853241] - FRIDA
1from sentence_transformers import SentenceTransformer
2
3# loads model with mean pooling
4model = SentenceTransformer("sergeyzh/rubert-mini-uncased")
5
6paraphrase = model.encode(["В Ярославской области разрешили работу бань, но без посетителей", "Ярославским баням разрешили работать без посетителей"], prompt="paraphrase: ")
7print(paraphrase[0] @ paraphrase[1].T)
8
9# 0.9366129
10# 0.9360032 - FRIDA
11
12categorize_entailment = model.encode(["Женщину доставили в больницу, за ее жизнь сейчас борются врачи.", "Женщину спасают врачи."], prompt="categorize_entailment: ")
13print(categorize_entailment[0] @ categorize_entailment[1].T)
14# 0.80306643
15# 0.8591322 - FRIDA
16
17query_embedding = model.encode("Сколько программистов нужно, чтобы вкрутить лампочку?", prompt="search_query: ")
18document_embedding = model.encode("Чтобы вкрутить лампочку, требуется три программиста: один напишет программу извлечения лампочки, другой — вкручивания лампочки, а третий проведет тестирование.", prompt="search_document: ")
19print(query_embedding @ document_embedding.T)
20# 0.68264616
21# 0.7285831 - FRIDA