File size: 8,115 Bytes
3d68cb6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b587ab2
 
3d68cb6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
---
license: apache-2.0
language:
- ru
library_name: sentence-transformers
pipeline_tag: sentence-similarity
base_model: deepvk/USER2-base
tags:
- sentence-transformers
- feature-extraction
- sentence-similarity
- code-retrieval
- 1c
- bsl
- matryoshka
- ru
model-index:
- name: USER2-1C-code
  results:
  - task:
      type: retrieval
      name: Code Retrieval
    dataset:
      type: PruhaNLP/1C-Ebench
      name: 1C-Ebench (forum)
      config: forum
      split: test
    metrics:
    - type: ndcg_at_10
      value: 0.4617
    - type: recall_at_10
      value: 0.6008
    - type: mrr_at_10
      value: 0.4178
  - task:
      type: retrieval
      name: Code Retrieval
    dataset:
      type: PruhaNLP/1C-Ebench
      name: 1C-Ebench (fastcode)
      config: fastcode
      split: test
    metrics:
    - type: ndcg_at_10
      value: 0.7366
    - type: recall_at_10
      value: 0.9208
    - type: mrr_at_10
      value: 0.6774
---

# USER2-1C-code

**Первая открытая эмбеддинг-модель, заточенная под код и язык 1С (1С:Предприятие / BSL).**

`USER2-1C-code` — это би-энкодер для семантического поиска по коду 1С: на вход подаётся вопрос на естественном языке, на выходе — релевантные фрагменты кода/решений. Модель — fine-tune [`deepvk/USER2-base`](https://huggingface.co/deepvk/USER2-base) (ModernBERT, контекст до 8192 токенов) на парах «вопрос → код 1С».


- **Тип:** bi-encoder (sentence-transformers), mean pooling, cosine similarity
- **База:** `deepvk/USER2-base` (ModernBERT, 768d, до 8192 токенов)
- **Языки:** русский + код 1С (BSL)
- **Matryoshka (MRL):** полноценные эмбеддинги на `768 / 512 / 384 / 256 / 128 / 64 / 32`
- **Префиксы:** `search_query` для запросов, `search_document` для кода

## Результаты на 1C-Ebench

Бенчмарк [`PruhaNLP/1C-Ebench`](https://huggingface.co/datasets/PruhaNLP/1C-Ebench): retrieval по двум источникам — `forum` (живые вопросы с тематических площадок) и `fastcode` (готовые сниппеты/шаблоны). Метрика — nDCG@10.

![Leaderboard](assets/leaderboard_gradient.png)

| Модель | avg nDCG@10 |
|---|---|
| **USER2-1C-code (наша)** | **0.599** |
| google/embeddinggemma-300m | 0.540 |
| deepvk/USER2-base | 0.493 |
| deepvk/USER-bge-m3 | 0.491 |
| ibm-granite/granite-embedding-311m-multilingual-r2 | 0.485 |
| microsoft/harrier-oss-v1-270m | 0.480 |
| intfloat/multilingual-e5-base | 0.429 |
| ai-forever/sbert_large_nlu_ru | 0.086 |

Прирост относительно базовой `deepvk/USER2-base` — **+0.106 avg nDCG@10** (0.493 → 0.599).

### Детально по сплитам

![Метрики по сплитам](assets/ours_by_split.png)

| Сплит | nDCG@10 | Recall@10 | MRR@10 |
|---|---|---|---|
| forum | 0.4617 | 0.6008 | 0.4178 |
| fastcode | 0.7366 | 0.9208 | 0.6774 |

## Matryoshka (MRL): обрезаемые эмбеддинги

Модель обучена с `MatryoshkaLoss`, поэтому эмбеддинг можно усекать до меньшей размерности (взять первые `d` компонент и перенормировать) почти без потери качества. Это позволяет экономить память индекса и ускорять поиск.

![MRL degradation](assets/mrl_degradation.png)

| dim | avg nDCG@10 | от полной 768d |
|---|---|---|
| 768 | 0.599 | 100.0% |
| 512 | 0.600 | 100.1% |
| 384 | 0.600 | 100.2% |
| 256 | 0.598 | 99.9% |
| 128 | 0.584 | 97.5% |
| 64 | 0.560 | 93.5% |
| 32 | 0.503 | 83.9% |

До **256d качество практически не падает** — можно смело уменьшать индекс втрое.

## Использование

```python
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("PruhaNLP/USER2-1C-code")

query = "Как программно провести документ в 1С?"
docs = [
    "Документы.РеализацияТоваровУслуг.СоздатьДокумент();",
    "Процедура ПровестиДокумент(Ссылка) Экспорт ... КонецПроцедуры",
]

q_emb = model.encode(query, prompt_name="search_query", normalize_embeddings=True)
d_emb = model.encode(docs, prompt_name="search_document", normalize_embeddings=True)

scores = model.similarity(q_emb, d_emb)
print(scores)
```

Для MRL укажите целевую размерность:

```python
model = SentenceTransformer("PruhaNLP/USER2-1C-code", truncate_dim=256)
```

## Кастомный токенайзер для приватности

При подготовке данных персональные данные в коде/текстах не вырезаются грубо, а заменяются на отдельные **служебные токены**, которые модель видит как единый элемент (а не как ломаную последовательность сабтокенов):

| Сущность | Токен | Токенов после кодирования |
|---|---|---|
| Пути | `[PATH]` | 1 |
| Имена | `[PERSON]` | 1 |
| E-mail | `\|\|\|EMAIL_ADDRESS\|\|\|` | 1 |
| Телефон | `\|\|\|PHONE_NUMBER\|\|\|` | 1 |
| IP | `\|\|\|IP_ADDRESS\|\|\|` | 1 |

Свободные слоты словаря (`[unused0]`/`[unused1]`) переиспользованы под `[PATH]`/`[PERSON]`, а их эмбеддинги инициализированы средним по сабтокенам исходных строк. В результате анонимизация не ломает токенизацию и не плодит шум в последовательности — это аккуратно закрывает персональные данные и держит распределение входа стабильным.

## Детали обучения

- **База:** `deepvk/USER2-base` (ModernBERT)
- **Лосс:** `CachedMultipleNegativesRankingLoss` (scale 20, hard-negatives) внутри `MatryoshkaLoss` по размерностям `[768, 512, 384, 256, 128, 64, 32]`
- **Хард-негативы:** майнинг по FAISS
- **LR-расписание:** трапеция (warmup → stable → cosine decay), peak LR 2e-5
- **Контекст:** до 8192 токенов, fp16
- **Префиксы:** `search_query` / `search_document`

## Код валидации

Eval метод опубликован отдельно:
[`https://github.com/PruhaNLP/1C-RB`](https://github.com/PruhaNLP/1C-RB).

## Правовая информация

«1С», «1С:Предприятие» и связанные обозначения — товарные знаки ООО «1С». Проект является независимым, **не аффилирован с фирмой «1С»** и не одобрен ею. Названия используются исключительно для указания предметной области (номинативное использование). Модель и датасеты предоставляются «как есть», без гарантий. Если вы правообладатель и считаете, что какой-либо материал нарушает ваши права — напишите на контакт ниже, и он будет удалён.

## Контакт для связи

`konstphx@gmail.com`

## Цитирование

```bibtex
@misc{user2_1c_code,
  title  = {USER2-1C-code: эмбеддинг-модель для поиска по коду 1С},
  author = {PruhaNLP},
  year   = {2026},
  url    = {https://huggingface.co/PruhaNLP/USER2-1C-code}
}
```