commit 361fe56cafaebc9e94fdcd81046f15e7b1a5dd4e Author: ModelHub XC Date: Thu May 14 18:00:56 2026 +0800 初始化项目,由ModelHub XC社区提供模型 Model: Roflmax/bge-m3-russian-legal Source: Original Platform diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..52373fe --- /dev/null +++ b/.gitattributes @@ -0,0 +1,36 @@ +*.7z filter=lfs diff=lfs merge=lfs -text +*.arrow filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.ckpt filter=lfs diff=lfs merge=lfs -text +*.ftz filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.h5 filter=lfs diff=lfs merge=lfs -text +*.joblib filter=lfs diff=lfs merge=lfs -text +*.lfs.* filter=lfs diff=lfs merge=lfs -text +*.mlmodel filter=lfs diff=lfs merge=lfs -text +*.model filter=lfs diff=lfs merge=lfs -text +*.msgpack filter=lfs diff=lfs merge=lfs -text +*.npy filter=lfs diff=lfs merge=lfs -text +*.npz filter=lfs diff=lfs merge=lfs -text +*.onnx filter=lfs diff=lfs merge=lfs -text +*.ot filter=lfs diff=lfs merge=lfs -text +*.parquet filter=lfs diff=lfs merge=lfs -text +*.pb filter=lfs diff=lfs merge=lfs -text +*.pickle filter=lfs diff=lfs merge=lfs -text +*.pkl filter=lfs diff=lfs merge=lfs -text +*.pt filter=lfs diff=lfs merge=lfs -text +*.pth filter=lfs diff=lfs merge=lfs -text +*.rar filter=lfs diff=lfs merge=lfs -text +*.safetensors filter=lfs diff=lfs merge=lfs -text +saved_model/**/* filter=lfs diff=lfs merge=lfs -text +*.tar.* filter=lfs diff=lfs merge=lfs -text +*.tar filter=lfs diff=lfs merge=lfs -text +*.tflite filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.wasm filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text +*tfevents* filter=lfs diff=lfs merge=lfs -text +tokenizer.json filter=lfs diff=lfs merge=lfs -text diff --git a/1_Pooling/config.json b/1_Pooling/config.json new file mode 100644 index 0000000..0dfd14b --- /dev/null +++ b/1_Pooling/config.json @@ -0,0 +1,10 @@ +{ + "word_embedding_dimension": 1024, + "pooling_mode_cls_token": true, + "pooling_mode_mean_tokens": false, + "pooling_mode_max_tokens": false, + "pooling_mode_mean_sqrt_len_tokens": false, + "pooling_mode_weightedmean_tokens": false, + "pooling_mode_lasttoken": false, + "include_prompt": true +} \ No newline at end of file diff --git a/BGE_M3_EXPERIMENTS_RESULTS.md b/BGE_M3_EXPERIMENTS_RESULTS.md new file mode 100644 index 0000000..b1d8845 --- /dev/null +++ b/BGE_M3_EXPERIMENTS_RESULTS.md @@ -0,0 +1,240 @@ +# Результаты экспериментов с BGE-M3 на юридических документах + +**Дата**: 2025-11-11 +**Модель**: BAAI/bge-m3 +**Датасет**: Русские юридические документы (court_law, other_law, reg_law) + +--- + +## 📊 Сводная таблица результатов + +| Эксперимент | Датасет | Размер | Префиксы | Recall@1 | **Recall@5** | Recall@10 | Время обучения | +|-------------|---------|--------|----------|----------|--------------|-----------|----------------| +| **Эксперимент 1** | Оригинальный | 87,878 | ❌ НЕТ | 68.2% | 91.7% | 95.8% | ~43 мин | +| **Эксперимент 2** | Без дубликатов | 26,734 | ❌ НЕТ | 76.9% | **93.6%** | 95.3% | ~13 мин | +| **Эксперимент 3** 🏆 | Без дубликатов | 26,734 | ✅ **ДА** | 76.9% | **93.8%** | 95.5% | ~13 мин | + +### 🏆 ПОБЕДИТЕЛЬ: Эксперимент 3 + +**Лучшая конфигурация:** +- Датасет **БЕЗ дубликатов** (26,734 записей) +- **С префиксами BGE-M3** +- Query prefix: `"Represent this sentence for searching relevant passages: "` +- Passage prefix: `""` (пустой) + +--- + +## 📈 Детальные результаты + +### Эксперимент 1: Baseline (оригинальный датасет без префиксов) + +**Конфигурация:** +- Датасет: train.jsonl (87,878 записей) +- Префиксы: Отключены +- Модель: BAAI/bge-m3 +- Output: `models/bge-m3-exp1-original-no-prefixes` + +**Результаты (validation set):** +| Датасет | Recall@1 | Recall@5 | Recall@10 | +|---------|----------|----------|-----------| +| court_law | 56.8% | 82.9% | 89.5% | +| other_law | 84.2% | 96.4% | 97.0% | +| reg_law | 63.7% | 95.7% | 98.8% | +| **Среднее** | **68.2%** | **91.7%** | **95.8%** | + +**Время обучения:** 42 минуты 47 секунд + +--- + +### Эксперимент 2: Датасет без дубликатов без префиксов + +**Конфигурация:** +- Датасет: Без дубликатов по `chunk_text` (26,734 записей) +- Удалено дубликатов: 61,144 (69.6%) + - court_law: 28,090 дубликатов удалено (66.7%) + - other_law: 15,312 дубликатов удалено (80.0%) + - reg_law: 17,742 дубликата удалено (66.7%) +- Префиксы: Отключены +- Output: `models/bge-m3-exp2-no-duplicates-no-prefixes-v2` + +**Результаты (validation set):** +| Датасет | Recall@1 | Recall@5 | Recall@10 | +|---------|----------|----------|-----------| +| court_law | 67.5% | 87.9% | 92.6% | +| other_law | 85.1% | 96.7% | 97.4% | +| reg_law | 75.6% | 96.9% | 98.8% | +| **Среднее** | **76.9%** | **93.6%** | **95.3%** | + +**Время обучения:** ~13 минут + +**Улучшение vs Эксперимент 1:** +- Recall@1: +8.7% (68.2% → 76.9%) +- Recall@5: +1.9% (91.7% → 93.6%) +- Recall@10: -0.5% (95.8% → 95.3%) + +--- + +### Эксперимент 3: Датасет без дубликатов С префиксами BGE-M3 🏆 + +**Конфигурация:** +- Датасет: Без дубликатов (26,734 записей) +- Префиксы: **Включены** + - Query: `"Represent this sentence for searching relevant passages: "` + - Passage: `""` (пустой) +- Output: `models/bge-m3-exp3-no-duplicates-with-prefixes` + +**Результаты (validation set):** +| Датасет | Recall@1 | Recall@5 | Recall@10 | +|---------|----------|----------|-----------| +| court_law | 67.5% | 87.9% | 92.6% | +| other_law | 85.1% | 96.7% | 97.4% | +| reg_law | 75.6% | 96.9% | 98.8% | +| **Среднее** | **76.9%** | **93.8%** | **95.5%** | + +**Результаты (test set):** +| Метрика | Значение | +|---------|----------| +| Recall@1 | 76.9% | +| **Recall@5** | **92.9%** | +| Recall@10 | 95.5% | + +**Время обучения:** ~13 минут + +**Улучшение vs Эксперимент 2:** +- Recall@1: 0% (76.9% = 76.9%) +- Recall@5: +0.2% (93.6% → 93.8%) +- Recall@10: +0.2% (95.3% → 95.5%) + +**Улучшение vs Эксперимент 1:** +- Recall@1: +8.7% (68.2% → 76.9%) +- Recall@5: +2.1% (91.7% → 93.8%) +- Recall@10: -0.3% (95.8% → 95.5%) + +--- + +## 💡 Ключевые выводы + +### 1. Удаление дубликатов критически важно + +**Удалено 70% датасета** (87,878 → 26,734 записей), но качество **улучшилось**: +- Recall@5: 91.7% → 93.8% (+2.1%) +- Recall@1: 68.2% → 76.9% (+8.7%) + +**Причины:** +- Дубликаты создавали переобучение на повторяющихся примерах +- Модель училась "запоминать", а не "понимать" +- Уникальные примеры обеспечивают лучшую генерализацию + +### 2. Префиксы BGE-M3 дают небольшой прирост + +Префиксы добавили лишь +0.2% к Recall@5, но это ожидаемо: +- BGE-M3 уже хорошо понимает задачу без префиксов +- Префиксы полезны для явного указания задачи +- Рекомендуется использовать для консистентности с baseline моделью + +### 3. Обучение стало в 3 раза быстрее + +- Было: 43 минуты (87,878 примеров) +- Стало: 13 минут (26,734 примеров) +- **Ускорение: 3.3x** + +### 4. Качество по типам документов + +**Лучшие результаты:** +- other_law (федеральные законы): Recall@5 = 96.7% +- reg_law (региональные законы): Recall@5 = 96.9% + +**Худшие результаты:** +- court_law (судебные решения): Recall@5 = 87.9% + - Причина: более сложная структура и разнообразие языка + +--- + +## 🚀 Использование лучшей модели + +### Hugging Face Hub + +Модель загружена на Hugging Face: +- **URL**: https://huggingface.co/Roflmax/bge-m3-russian-legal +- **Статус**: Pull Request (требует подтверждения) + +### Загрузка и использование + +```python +from sentence_transformers import SentenceTransformer + +# Загрузка модели +model = SentenceTransformer("Roflmax/bge-m3-russian-legal") + +# Для запросов используйте префикс +query = "Represent this sentence for searching relevant passages: Какое наказание за управление в состоянии опьянения?" +query_embedding = model.encode(query) + +# Для документов префикс пустой +documents = [ + "Статья 264 УК РФ. Нарушение правил дорожного движения...", + "КоАП РФ статья 12.8. Управление транспортным средством..." +] +doc_embeddings = model.encode(documents) + +# Поиск +from sklearn.metrics.pairwise import cosine_similarity +similarities = cosine_similarity([query_embedding], doc_embeddings)[0] +``` + +--- + +## 📁 Файлы и директории + +**Модели:** +- `models/bge-m3-exp1-original-no-prefixes/` - Эксперимент 1 +- `models/bge-m3-exp2-no-duplicates-no-prefixes-v2/` - Эксперимент 2 +- `models/bge-m3-exp3-no-duplicates-with-prefixes/` - Эксперимент 3 🏆 + +**Датасеты:** +- `dataset/court_law/train_backup.jsonl` - Оригинальный датасет (с дубликатами) +- `dataset/court_law/train_no_duplicates.jsonl` - Датасет без дубликатов +- `dataset/other_law/train_no_duplicates.jsonl` - Датасет без дубликатов +- `dataset/reg_law/train_no_duplicates.jsonl` - Датасет без дубликатов + +**WandB Runs:** +- Эксперимент 1: bge-m3-exp1-original-no-prefixes +- Эксперимент 2: bge-m3-exp2-no-duplicates-no-prefixes-v2 +- Эксперимент 3: bge-m3-exp3-no-duplicates-with-prefixes + +--- + +## 🔧 Параметры обучения + +| Параметр | Значение | +|----------|----------| +| Модель | BAAI/bge-m3 | +| Размерность эмбеддингов | 1024 | +| Max sequence length | 512 токенов | +| Loss function | MultipleNegativesRankingLoss (scale=20.0) | +| Epochs | 3 | +| Batch size (train) | 64 | +| Batch size (eval) | 64 | +| Learning rate | 2e-5 | +| Warmup ratio | 0.1 | +| Precision | bfloat16 | +| GPU | NVIDIA RTX PRO 6000 Blackwell (97GB) | +| Best model selection | eval_avg_recall@5 | +| Eval frequency | Каждые 250 steps | +| Save strategy | Сохранять 3 лучших чекпоинта | + +--- + +## ✅ Итоговые рекомендации + +1. **Используйте датасет без дубликатов** для обучения +2. **Включайте префиксы BGE-M3** для консистентности +3. **Мониторьте Recall@5** как основную метрику +4. **Оптимизируйте датасет перед обучением** - дедупликация критична +5. **Используйте validation set** для выбора лучшей модели + +--- + +**Статус**: ✅ Все эксперименты завершены +**Лучшая модель**: `models/bge-m3-exp3-no-duplicates-with-prefixes/final/` +**Загружена на HF**: https://huggingface.co/Roflmax/bge-m3-russian-legal diff --git a/README.md b/README.md new file mode 100644 index 0000000..e147353 --- /dev/null +++ b/README.md @@ -0,0 +1,107 @@ +--- +language: +- ru +license: apache-2.0 +tags: +- sentence-transformers +- feature-extraction +- sentence-similarity +- legal +- russian +- bge-m3 +pipeline_tag: sentence-similarity +library_name: sentence-transformers +base_model: BAAI/bge-m3 +--- + +# BGE-M3 Russian Legal Documents + +Это модель для получения эмбеддингов русских юридических документов, дообученная на датасете из трех категорий: судебные решения, федеральные законы и региональные законы. + +## Модель + +- **Базовая модель**: BAAI/bge-m3 +- **Размерность эмбеддингов**: 1024 +- **Max sequence length**: 512 токенов +- **Язык**: Русский +- **Задача**: Semantic search на юридических документах + +## Метрики качества + +### Результаты на тестовой выборке + +| Метрика | Значение | +|---------|----------| +| **Recall@1** | 76.9% | +| **Recall@5** | 92.9% | +| **Recall@10** | 95.5% | + +### Результаты по типам документов (validation set) + +| Датасет | Recall@1 | Recall@5 | Recall@10 | +|---------|----------|----------|-----------| +| **court_law** (судебные решения) | 67.5% | 87.9% | 92.6% | +| **other_law** (федеральные законы) | 85.1% | 96.7% | 97.4% | +| **reg_law** (региональные законы) | 75.6% | 96.9% | 98.8% | + +## Датасет для обучения + +- **Размер**: 26,734 уникальных пар (query, document) +- **Дедупликация**: Да (70% удалено по chunk_text) +- **Категории**: + - court_law: 14,046 примеров + - other_law: 3,823 примеров + - reg_law: 8,865 примеров + +## Использование + +### Установка + +```bash +pip install sentence-transformers +``` + +### Получение эмбеддингов + +**ВАЖНО**: Модель обучена с префиксами BGE-M3. Используйте их при инференсе! + +```python +from sentence_transformers import SentenceTransformer + +# Загрузка модели +model = SentenceTransformer("Roflmax/bge-m3-russian-legal") + +# Для запросов используйте префикс +query = "Represent this sentence for searching relevant passages: Какое наказание за управление в состоянии опьянения?" +query_embedding = model.encode(query) + +# Для документов префикс пустой (просто текст) +documents = [ + "Статья 264 УК РФ. Нарушение правил дорожного движения...", + "КоАП РФ статья 12.8. Управление транспортным средством..." +] +doc_embeddings = model.encode(documents) + +# Поиск похожих документов +from sklearn.metrics.pairwise import cosine_similarity +similarities = cosine_similarity([query_embedding], doc_embeddings)[0] + +# Топ-5 результатов +top_indices = similarities.argsort()[-5:][::-1] +for idx in top_indices: + print(f"Document {idx}: similarity={similarities[idx]:.4f}") +``` + +## Параметры обучения + +- **Loss function**: MultipleNegativesRankingLoss (scale=20.0) +- **Epochs**: 3 +- **Batch size**: 64 +- **Learning rate**: 2e-5 +- **Warmup ratio**: 0.1 +- **Precision**: bfloat16 +- **Best model selection**: eval_avg_recall@5 + +## Лицензия + +Apache 2.0 diff --git a/config.json b/config.json new file mode 100644 index 0000000..fa2425b --- /dev/null +++ b/config.json @@ -0,0 +1,27 @@ +{ + "architectures": [ + "XLMRobertaModel" + ], + "attention_probs_dropout_prob": 0.1, + "bos_token_id": 0, + "classifier_dropout": null, + "dtype": "float32", + "eos_token_id": 2, + "hidden_act": "gelu", + "hidden_dropout_prob": 0.1, + "hidden_size": 1024, + "initializer_range": 0.02, + "intermediate_size": 4096, + "layer_norm_eps": 1e-05, + "max_position_embeddings": 8194, + "model_type": "xlm-roberta", + "num_attention_heads": 16, + "num_hidden_layers": 24, + "output_past": true, + "pad_token_id": 1, + "position_embedding_type": "absolute", + "transformers_version": "4.57.1", + "type_vocab_size": 1, + "use_cache": true, + "vocab_size": 250002 +} diff --git a/config_sentence_transformers.json b/config_sentence_transformers.json new file mode 100644 index 0000000..d5d1aa9 --- /dev/null +++ b/config_sentence_transformers.json @@ -0,0 +1,14 @@ +{ + "__version__": { + "sentence_transformers": "5.1.2", + "transformers": "4.57.1", + "pytorch": "2.8.0+cu128" + }, + "model_type": "SentenceTransformer", + "prompts": { + "query": "", + "document": "" + }, + "default_prompt_name": null, + "similarity_fn_name": "cosine" +} \ No newline at end of file diff --git a/model.safetensors b/model.safetensors new file mode 100644 index 0000000..7682ecf --- /dev/null +++ b/model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f38579b87e28489e09830abff25921ec3bf10c39ebddbe27b9e90488fcfae862 +size 2271064456 diff --git a/modules.json b/modules.json new file mode 100644 index 0000000..952a9b8 --- /dev/null +++ b/modules.json @@ -0,0 +1,20 @@ +[ + { + "idx": 0, + "name": "0", + "path": "", + "type": "sentence_transformers.models.Transformer" + }, + { + "idx": 1, + "name": "1", + "path": "1_Pooling", + "type": "sentence_transformers.models.Pooling" + }, + { + "idx": 2, + "name": "2", + "path": "2_Normalize", + "type": "sentence_transformers.models.Normalize" + } +] \ No newline at end of file diff --git a/sentence_bert_config.json b/sentence_bert_config.json new file mode 100644 index 0000000..4eca68d --- /dev/null +++ b/sentence_bert_config.json @@ -0,0 +1,4 @@ +{ + "max_seq_length": 512, + "do_lower_case": false +} \ No newline at end of file diff --git a/special_tokens_map.json b/special_tokens_map.json new file mode 100644 index 0000000..b1879d7 --- /dev/null +++ b/special_tokens_map.json @@ -0,0 +1,51 @@ +{ + "bos_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "cls_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "eos_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "mask_token": { + "content": "", + "lstrip": true, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "pad_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "sep_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + }, + "unk_token": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false + } +} diff --git a/tokenizer.json b/tokenizer.json new file mode 100644 index 0000000..225ca0f --- /dev/null +++ b/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9a6af42442a3e3e9f05f618eae0bb2d98ca4f6a6406cb80ef7a4fa865204d61 +size 17083052 diff --git a/tokenizer_config.json b/tokenizer_config.json new file mode 100644 index 0000000..95bd7c8 --- /dev/null +++ b/tokenizer_config.json @@ -0,0 +1,56 @@ +{ + "added_tokens_decoder": { + "0": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "1": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "2": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "3": { + "content": "", + "lstrip": false, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + }, + "250001": { + "content": "", + "lstrip": true, + "normalized": false, + "rstrip": false, + "single_word": false, + "special": true + } + }, + "bos_token": "", + "clean_up_tokenization_spaces": true, + "cls_token": "", + "eos_token": "", + "extra_special_tokens": {}, + "mask_token": "", + "model_max_length": 8192, + "pad_token": "", + "sep_token": "", + "sp_model_kwargs": {}, + "tokenizer_class": "XLMRobertaTokenizer", + "unk_token": "" +}