Карточка модели
Browse files
README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
base_model: sergeyzh/BERTA
|
| 4 |
+
language:
|
| 5 |
+
- ru
|
| 6 |
+
library_name: onnx
|
| 7 |
+
pipeline_tag: feature-extraction
|
| 8 |
+
tags:
|
| 9 |
+
- sentence-similarity
|
| 10 |
+
- feature-extraction
|
| 11 |
+
- onnx
|
| 12 |
+
- russian
|
| 13 |
+
- semantic-search
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
# BERTA-onnx
|
| 17 |
+
|
| 18 |
+
ONNX-сборка [sergeyzh/BERTA](https://huggingface.co/sergeyzh/BERTA) — русскоязычной модели
|
| 19 |
+
эмбеддингов (128M параметров, 768 измерений, до 512 токенов).
|
| 20 |
+
|
| 21 |
+
Веса не менялись: это тот же экспорт `optimum` в fp32, чтобы модель можно было запускать
|
| 22 |
+
одним `onnxruntime`, без PyTorch. Пригодится там, где нужен семантический поиск по русскому
|
| 23 |
+
тексту, а тянуть torch не хочется — например, в локальных инструментах и утилитах.
|
| 24 |
+
|
| 25 |
+
## Что внутри
|
| 26 |
+
|
| 27 |
+
| Файл | Зачем |
|
| 28 |
+
|---|---|
|
| 29 |
+
| `model.onnx` | сама модель, fp32, 490 МБ |
|
| 30 |
+
| `tokenizer.json` | токенизатор |
|
| 31 |
+
| `embed.json` | параметры для рантайма: пулинг, префиксы, размерность |
|
| 32 |
+
| `config.json`, `tokenizer_config.json`, `special_tokens_map.json` | как в оригинале |
|
| 33 |
+
|
| 34 |
+
Пулинг — **mean** по маске внимания, затем L2-нормализация. Префиксы у модели свои:
|
| 35 |
+
`search_query: ` для запроса и `search_document: ` для документа.
|
| 36 |
+
|
| 37 |
+
## Как пользоваться
|
| 38 |
+
|
| 39 |
+
```python
|
| 40 |
+
import json
|
| 41 |
+
import numpy as np
|
| 42 |
+
import onnxruntime as ort
|
| 43 |
+
from tokenizers import Tokenizer
|
| 44 |
+
|
| 45 |
+
cfg = json.load(open("embed.json", encoding="utf-8"))
|
| 46 |
+
tok = Tokenizer.from_file("tokenizer.json")
|
| 47 |
+
tok.enable_truncation(max_length=cfg["max_seq_length"])
|
| 48 |
+
tok.enable_padding()
|
| 49 |
+
sess = ort.InferenceSession("model.onnx", providers=["CPUExecutionProvider"])
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def encode(texts, kind="document"):
|
| 53 |
+
enc = tok.encode_batch([cfg["prefixes"][kind] + t for t in texts])
|
| 54 |
+
ids = np.array([e.ids for e in enc], dtype=np.int64)
|
| 55 |
+
mask = np.array([e.attention_mask for e in enc], dtype=np.int64)
|
| 56 |
+
feed = {"input_ids": ids, "attention_mask": mask}
|
| 57 |
+
names = {i.name for i in sess.get_inputs()}
|
| 58 |
+
if "token_type_ids" in names:
|
| 59 |
+
feed["token_type_ids"] = np.zeros_like(ids)
|
| 60 |
+
out = sess.run(None, {k: v for k, v in feed.items() if k in names})[0]
|
| 61 |
+
m = mask[..., None].astype(np.float32)
|
| 62 |
+
vec = (out * m).sum(1) / np.clip(m.sum(1), 1e-9, None)
|
| 63 |
+
return vec / np.linalg.norm(vec, axis=1, keepdims=True)
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
docs = encode(["Кириллица не рисуется в билде: шрифт без глифов"])
|
| 67 |
+
query = encode(["почему не отображаются русские буквы"], kind="query")
|
| 68 |
+
print(float(query[0] @ docs[0]))
|
| 69 |
+
```
|
| 70 |
+
|
| 71 |
+
## Проверка качества
|
| 72 |
+
|
| 73 |
+
Сборка проверялась на задаче поиска по русским техническим заметкам (карточки задач,
|
| 74 |
+
комментарии разработчиков). Метрика считалась на связях, которые уже были в данных:
|
| 75 |
+
заголовок задачи ищет своё описание, комментарий ищет задачу, к которой написан.
|
| 76 |
+
|
| 77 |
+
| | recall@1 | recall@5 |
|
| 78 |
+
|---|---|---|
|
| 79 |
+
| подстрочный поиск | 52.9% | 75.2% |
|
| 80 |
+
| paraphrase-multilingual-MiniLM-L12-v2 | 42.6% | 68.1% |
|
| 81 |
+
| rubert-tiny-turbo | 53.2% | 77.1% |
|
| 82 |
+
| LaBSE-ru-turbo | 70.6% | 90.6% |
|
| 83 |
+
| **BERTA (эта модель)** | **77.4%** | **90.6%** |
|
| 84 |
+
|
| 85 |
+
Мультиязычные модели на таком материале проигрывали даже обычному поиску по подстроке —
|
| 86 |
+
отсюда и выбор русской модели.
|
| 87 |
+
|
| 88 |
+
**Квантование int8 брать не стоит:** размер падает с 490 до 125 МБ, но recall@1 падает
|
| 89 |
+
с 77.4% до 65.2%, а на поиске по комментариям опускается ниже подстрочного baseline.
|
| 90 |
+
|
| 91 |
+
Экспорт в ONNX качество не меняет: метрики сборки в точности совпали с метриками
|
| 92 |
+
оригинала через `sentence-transformers`.
|
| 93 |
+
|
| 94 |
+
## Лицензия
|
| 95 |
+
|
| 96 |
+
MIT, как у оригинальной модели. Вся заслуга за качество — у авторов
|
| 97 |
+
[sergeyzh/BERTA](https://huggingface.co/sergeyzh/BERTA) и
|
| 98 |
+
[LaBSE-ru-turbo](https://huggingface.co/sergeyzh/LaBSE-ru-turbo), лежащей в её основе.
|