language:
pipeline_tag: sentence-similarity
tags:
- russian
- pretraining
- embeddings
- tiny
- feature-extraction
- sentence-similarity
- sentence-transformers
- transformers
datasets:
- IlyaGusev/gazeta
- zloelias/lenta-ru
- HuggingFaceFW/fineweb-2
- HuggingFaceFW/fineweb
license: mit
base_model: sergeyzh/rubert-mini-sts
rubert-mini-uncased
ロシア語と英語の文埋め込みを計算するためのモデルは、ai-forever/FRIDAの埋め込みを蒸留することで得られました(埋め込みサイズは1536、レイヤー数は24)。FRIDAの主要な使用モードであるCLSプーリングは、meanプーリングに置き換えられました。埋め込みの変更やフィルタリング、追加モデルの使用など、モデルの動作に他の変更は加えられていません。蒸留は可能な限り広範囲に行われ、ロシア語と英語の文の埋め込み、プレフィックスの動作が再現されています。
このモデルはuncasedタイプであり、テキスト処理時に大文字と小文字を区別しません(例えば「С Новым Годом!」と「С НОВЫМ ГОДОМ!」は同じトークンシーケンスでエンコードされ、同じ埋め込み値を持ちます)。モデルの埋め込みサイズは384、レイヤー数は7です。モデルのコンテキストサイズはFRIDAと同様に512トークンです。
プレフィックス
すべてのプレフィックスはFRIDAから継承されています。
使用されるプレフィックスとそれらがencodechkaのモデル評価に与える影響の一覧:
プレフィックス |
STS |
PI |
NLI |
SA |
TI |
- |
0.817 |
0.734 |
0.448 |
0.799 |
0.971 |
search_query: |
0.828 |
0.752 |
0.463 |
0.794 |
0.973 |
search_document: |
0.794 |
0.730 |
0.446 |
0.797 |
0.971 |
paraphrase: |
0.823 |
0.760 |
0.446 |
0.802 |
0.973 |
categorize: |
0.820 |
0.753 |
0.482 |
0.805 |
0.972 |
categorize_sentiment: |
0.604 |
0.595 |
0.431 |
0.798 |
0.955 |
categorize_topic: |
0.711 |
0.485 |
0.391 |
0.750 |
0.962 |
categorize_entailment: |
0.805 |
0.750 |
0.525 |
0.800 |
0.969 |
タスク:
- 意味的テキスト類似性 (STS)
- 言い換え識別 (PI)
- 自然言語推論 (NLI)
- 感情分析 (SA)
- 有害性識別 (TI)
メトリクス
ruMTEBベンチマークでのモデル評価:
モデル名 |
メトリクス |
Frida |
rubert-mini-uncased |
rubert-mini-frida |
multilingual-e5-large-instruct |
multilingual-e5-large |
CEDRClassification |
精度 |
0.646 |
0.586 |
0.552 |
0.500 |
0.448 |
GeoreviewClassification |
精度 |
0.577 |
0.485 |
0.464 |
0.559 |
0.497 |
GeoreviewClusteringP2P |
V-measure |
0.783 |
0.683 |
0.698 |
0.743 |
0.605 |
HeadlineClassification |
精度 |
0.890 |
0.884 |
0.882 |
0.862 |
0.758 |
InappropriatenessClassification |
精度 |
0.783 |
0.705 |
0.698 |
0.655 |
0.616 |
KinopoiskClassification |
精度 |
0.705 |
0.607 |
0.595 |
0.661 |
0.566 |
RiaNewsRetrieval |
NDCG@10 |
0.868 |
0.791 |
0.721 |
0.824 |
0.807 |
RuBQReranking |
MAP@10 |
0.771 |
0.713 |
0.711 |
0.717 |
0.756 |
RuBQRetrieval |
NDCG@10 |
0.724 |
0.640 |
0.654 |
0.692 |
0.741 |
RuReviewsClassification |
精度 |
0.751 |
0.684 |
0.658 |
0.686 |
0.653 |
RuSTSBenchmarkSTS |
ピアソン相関 |
0.814 |
0.795 |
0.803 |
0.840 |
0.831 |
RuSciBenchGRNTIClassification |
精度 |
0.699 |
0.653 |
0.625 |
0.651 |
0.582 |
RuSciBenchGRNTIClusteringP2P |
V-measure |
0.670 |
0.618 |
0.586 |
0.622 |
0.520 |
RuSciBenchOECDClassification |
精度 |
0.546 |
0.509 |
0.491 |
0.502 |
0.445 |
RuSciBenchOECDClusteringP2P |
V-measure |
0.566 |
0.525 |
0.507 |
0.528 |
0.450 |
SensitiveTopicsClassification |
精度 |
0.398 |
0.365 |
0.373 |
0.323 |
0.257 |
TERRaClassification |
平均適合率 |
0.665 |
0.604 |
0.604 |
0.639 |
0.584 |
モデル名 |
メトリクス |
Frida |
rubert-mini-uncased |
rubert-mini-frida |
multilingual-e5-large-instruct |
multilingual-e5-large |
Classification |
精度 |
0.707 |
0.657 |
0.631 |
0.654 |
0.588 |
Clustering |
V-measure |
0.673 |
0.608 |
0.597 |
0.631 |
0.525 |
MultiLabelClassification |
精度 |
0.522 |
0.476 |
0.463 |
0.412 |
0.353 |
PairClassification |
平均適合率 |
0.665 |
0.604 |
0.604 |
0.639 |
0.584 |
Reranking |
MAP@10 |
0.771 |
0.713 |
0.711 |
0.717 |
0.756 |
Retrieval |
NDCG@10 |
0.796 |
0.715 |
0.687 |
0.758 |
0.774 |
STS |
ピアソン相関 |
0.814 |
0.795 |
0.803 |
0.840 |
0.831 |
Average |
平均 |
0.707 |
0.653 |
0.642 |
0.664 |
0.630 |
transformers
ライブラリを使用したモデルの使用方法:
import torch
import torch.nn.functional as F
from transformers import AutoTokenizer, AutoModel
def pool(hidden_state, mask, pooling_method="mean"):
if pooling_method == "mean":
s = torch.sum(hidden_state * mask.unsqueeze(-1).float(), dim=1)
d = mask.sum(axis=1, keepdim=True).float()
return s / d
elif pooling_method == "cls":
return hidden_state[:, 0]
inputs = [
"paraphrase: ヤロスラヴリ州ではサウナの営業が許可されたが、客は受け入れ不可",
"categorize_entailment: 女性が病院に搬送され、医師が現在彼女の命を救うために奮闘しています。",
"search_query: 電球を交換するのに何人のプログラマーが必要ですか?",
"paraphrase: ヤロスラヴリのサウナは客なしでの営業が許可された",
"categorize_entailment: 女性を医師が救っています。",
"search_document: 電球を交換するには3人のプログラマーが必要です:1人は電球を取り外すプログラムを書き、もう1人は電球を回すプログラムを書き、3人目がテストを行います。"
]
tokenizer = AutoTokenizer.from_pretrained("sergeyzh/rubert-mini-uncased")
model = AutoModel.from_pretrained("sergeyzh/rubert-mini-uncased")
tokenized_inputs = tokenizer(inputs, max_length=512, padding=True, truncation=True, return_tensors="pt")
with torch.no_grad():
outputs = model(**tokenized_inputs)
embeddings = pool(
outputs.last_hidden_state,
tokenized_inputs["attention_mask"],
pooling_method="mean"
)
embeddings = F.normalize(embeddings, p=2, dim=1)
sim_scores = embeddings[:3] @ embeddings[3:].T
print(sim_scores.diag().tolist())
sentence_transformers
を使用する場合(sentence-transformers>=2.4.0):
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("sergeyzh/rubert-mini-uncased")
paraphrase = model.encode(["ヤロスラヴリ州ではサウナの営業が許可されたが、客は受け入れ不可", "ヤロスラヴリのサウナは客なしでの営業が許可された"], prompt="paraphrase: ")
print(paraphrase[0] @ paraphrase[1].T)
categorize_entailment = model.encode(["女性が病院に搬送され、医師が現在彼女の命を救うために奮闘しています。", "女性を医師が救っています。"], prompt="categorize_entailment: ")
print(categorize_entailment[0] @ categorize_entailment[1].T)
query_embedding = model.encode("電球を交換するのに何人のプログラマーが必要ですか?", prompt="search_query: ")
document_embedding = model.encode("電球を交換するには3人のプログラマーが必要です:1人は電球を取り外すプログラムを書き、もう1人は電球を回すプログラムを書き、3人目がテストを行います。", prompt="search_document: ")
print(query_embedding @ document_embedding.T)