--- 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} } ```