Сервис выделения сущностей из поискового запроса клиента в мобильном приложении торговой сети «Пятерочка»
Задача: извлечение из текстовых описаний товаров следующих сущностей:
Проект включает несколько подходов к решению задачи NER с различными архитектурами и оптимизациями, а также готовые API для развертывания на сервере.
| Папка | Архитектура | Ключевые особенности | F1-Score |
|---|---|---|---|
src_base | BERT | Стандартный fine-tuning с classification head | 0.896 |
src_base_v1 | BERT + Weighted Loss | Добавлена взвешенная функция потерь для балансировки классов | 0.9205 |
src_bilstm | LLM → BiLSTM → CRF | Frozen LLM embeddings + двунаправленный LSTM + CRF | 0.781 |
src_crf | BERT → CRF | BERT encoder + CRF слой для структурного предсказания последовательности | 0.9302 |
src_crf_v1 | BERT → CRF + Features | Расширенная версия src_crf с доп. признаками (язык слова, длина токена) | 0.9306 |
Tokens → BERT Encoder → Dropout → Linear(hidden_size → num_labels) → Softmax
Особенности:
AutoModelForTokenClassification из TransformersTokens → BERT Encoder → Dropout → Linear → Softmax + WeightedCrossEntropyLoss
Особенности:
Text → LLM Tokenizer → Frozen LLM
→ Word Embeddings → BiLSTM(2 layers, hidden=256)
→ Dropout(0.5) → Linear → CRF
Особенности:
Tokens → BERT Encoder → Dropout(0.1)
→ Linear(hidden_size → num_labels)
→ CRF(emissions + transitions) → Viterbi Decoding
Особенности:
BertCrfForTokenClassification с CRF слоем из библиотеки torchcrfTokens → BERT Encoder → Dropout(0.1)
→ [BERT_hidden ⊕ Lang_Embedding(3→8) ⊕ Length(1)]
→ Linear(hidden_size+9 → num_labels) → CRF → Viterbi
Особенности:
src_crf, но с расширенным входом в Linear слойLang Type Embedding(3→8): кодирование типа символов (0=латиница, 1=кириллица, 2=цифры)Word Length [0,1]: нормализованная длина токена как дополнительный признакhidden_size + 8 + 1 = hidden_size + 9Xak_5_NER/
├── src_base/ # Базовая BERT модель
│ ├── train_base.py
│ ├── inference_base.py
│ └── NER_model_train_base_pipline.ipynb
├── src_base_v1/ # Базовая BERT модель (v1)
│ ├── train_v1.py
│ ├── inference_base.py
│ └── NER_model_train.ipynb
├── src_bilstm/ # BERT + BiLSTM
│ ├── train_bilstm.py
│ ├── inference_bilstm.py
│ └── NER_model_train_v2_BiLSTM.ipynb
├── src_crf/ # BERT + CRF
│ ├── train crf.py
│ ├── inference_crf.py
│ └── NER_model_train_v1_crf.ipynb
├── src_crf_v1/ # BERT + CRF (v1)
│ ├── train.py
│ ├── inference.py
│ └── NER_model_train_v3_crf_add.ipynb
├── data/ # Датасеты
│ ├── train_balanced.csv
│ ├── train_v1.csv
│ ├── train_extended.csv
│ └── dataset_generation.ipynb
│ └── balance_dataset.py
├── API/ # API для базовой модели
│ └── SRC/
│ ├── app.py
│ ├── inference.py
│ ├── Dockerfile
│ └── model_finetuned/ # ⚠️ Модель загружается отдельно
└── API_crf/ # API для CRF модели
└── SRC/
├── app.py
├── inference.py
├── Dockerfile
└── model_finetuned/ # ⚠️ Модель загружается отдельно
Папки API/ и API_crf/ содержат готовые к развертыванию FastAPI приложения с оптимизацией для production:
Важно! Перед развертыванием необходимо загрузить обученную модель с Hugging Face Hub:
P0ve1/NER_X5_bertP0ve1/NER_X5_bert-crfAPI/SRC/model_finetuned/API_crf/SRC/model_finetuned/Требуемые файлы модели:
model_finetuned/
├── config.json
├── pytorch_model.bin (или model.safetensors)
├── tokenizer_config.json
├── tokenizer.json
├── vocab.txt
└── special_tokens_map.json
# Для базовой модели
cd API
docker-compose up -d --build
# Для CRF модели
cd API_crf
docker-compose up -d --build
# Health check
curl http://localhost:80/health
# Предсказание (базовая модель)
curl -X POST "http://localhost:80/api/predict" \
-H "Content-Type: application/json" \
-d '{"input": "молоко сгущенное 500ml"}'
# Production endpoint (пример)
curl -X POST "http://51.250.30.54:8000/api/predict" \
-H "Content-Type: application/json" \
-d '{"input": "молоко сгущенное 500ml"}'
Ответ:
[
{"start_index": 0, "end_index": 6, "entity": "B-TYPE"},
{"start_index": 7, "end_index": 17, "entity": "B-BRAND"},
{"start_index": 18, "end_index": 23, "entity": "B-VOLUME"}
]
Подробные инструкции по настройке, оптимизации и мониторингу см. в файлах:
API/README.md - полная документация для базовой моделиAPI/instruction.md - пошаговая инструкция по развертываниюAPI_crf/README.md - документация для CRF моделиAPI_crf/instruction.md - инструкция для CRF версииДокументация включает:
Папка data/ содержит:
train_v1.csv - исходный датасетtrain_balanced.csv - сбалансированный датасет для обученияtrain_extended (3).csv - расширенный датасетbalance_dataset.py - скрипт для балансировки данныхДатасет представлен в CSV формате со следующими колонками:
sample - текст описания товара (токенизированный по пробелам)annotation - список аннотаций в формате [(token, label), ...]Пример:
sample,annotation
"молоко сгущенное 500ml","[('молоко', 'B-TYPE'), ('сгущенное', 'I-TYPE'), ('500ml', 'B-VOLUME')]"
Используется схема BIO (Begin, Inside, Outside):
B-VOLUME / I-VOLUME - объем/весB-TYPE / I-TYPE - тип продуктаB-PERCENT / I-PERCENT - процентное содержаниеB-BRAND / I-BRAND - брендO - не является сущностьюРезультаты старых экспериментов на выборке 5000 примеров:
| Модель | F1-Score |
|---|---|
| dslim/bert-base-NER | 0.7146 |
| DeepPavlov/rubert-base-cased | 0.8292 |
| FacebookAI/xlm-roberta-large-finetuned-conll03-english | 0.6459 |
| Babelscape/wikineural-multilingual-ner | 0.5169 |
| cointegrated/rubert-tiny2 | 0.4858 |
| Модель | F1-Score |
|---|---|
| DeepPavlov/rubert-base-cased | 0.8530 |
Каждая папка src_* содержит:
train*.py - скрипт для обучения моделиinference*.py - скрипт для предсказаний*.ipynb - Jupyter notebook с полным pipelineDataPreprocessor - загрузка и предобработка данныхalign_labels_with_tokens - выравнивание меток с токенамиcompute_metrics - вычисление F1-score и accuracyBertCrfForTokenClassification - кастомная модель BERT+CRFLLMEmbeddingExtractor - извлечение эмбеддингов для BiLSTM1 commits
Jupyter Notebook
85.7%
Python
14.2%
Сервис выделения сущностей из поискового запроса клиента в мобильном приложении торговой сети «Пятерочка»
Задача: извлечение из текстовых описаний товаров следующих сущностей:
Проект включает несколько подходов к решению задачи NER с различными архитектурами и оптимизациями, а также готовые API для развертывания на сервере.
| Папка | Архитектура | Ключевые особенности | F1-Score |
|---|---|---|---|
src_base | BERT | Стандартный fine-tuning с classification head | 0.896 |
src_base_v1 | BERT + Weighted Loss | Добавлена взвешенная функция потерь для балансировки классов | 0.9205 |
src_bilstm | LLM → BiLSTM → CRF | Frozen LLM embeddings + двунаправленный LSTM + CRF | 0.781 |
src_crf | BERT → CRF | BERT encoder + CRF слой для структурного предсказания последовательности | 0.9302 |
src_crf_v1 | BERT → CRF + Features | Расширенная версия src_crf с доп. признаками (язык слова, длина токена) | 0.9306 |
Tokens → BERT Encoder → Dropout → Linear(hidden_size → num_labels) → Softmax
Особенности:
AutoModelForTokenClassification из TransformersTokens → BERT Encoder → Dropout → Linear → Softmax + WeightedCrossEntropyLoss
Особенности:
Text → LLM Tokenizer → Frozen LLM
→ Word Embeddings → BiLSTM(2 layers, hidden=256)
→ Dropout(0.5) → Linear → CRF
Особенности:
Tokens → BERT Encoder → Dropout(0.1)
→ Linear(hidden_size → num_labels)
→ CRF(emissions + transitions) → Viterbi Decoding
Особенности:
BertCrfForTokenClassification с CRF слоем из библиотеки torchcrfTokens → BERT Encoder → Dropout(0.1)
→ [BERT_hidden ⊕ Lang_Embedding(3→8) ⊕ Length(1)]
→ Linear(hidden_size+9 → num_labels) → CRF → Viterbi
Особенности:
src_crf, но с расширенным входом в Linear слойLang Type Embedding(3→8): кодирование типа символов (0=латиница, 1=кириллица, 2=цифры)Word Length [0,1]: нормализованная длина токена как дополнительный признакhidden_size + 8 + 1 = hidden_size + 9Xak_5_NER/
├── src_base/ # Базовая BERT модель
│ ├── train_base.py
│ ├── inference_base.py
│ └── NER_model_train_base_pipline.ipynb
├── src_base_v1/ # Базовая BERT модель (v1)
│ ├── train_v1.py
│ ├── inference_base.py
│ └── NER_model_train.ipynb
├── src_bilstm/ # BERT + BiLSTM
│ ├── train_bilstm.py
│ ├── inference_bilstm.py
│ └── NER_model_train_v2_BiLSTM.ipynb
├── src_crf/ # BERT + CRF
│ ├── train crf.py
│ ├── inference_crf.py
│ └── NER_model_train_v1_crf.ipynb
├── src_crf_v1/ # BERT + CRF (v1)
│ ├── train.py
│ ├── inference.py
│ └── NER_model_train_v3_crf_add.ipynb
├── data/ # Датасеты
│ ├── train_balanced.csv
│ ├── train_v1.csv
│ ├── train_extended.csv
│ └── dataset_generation.ipynb
│ └── balance_dataset.py
├── API/ # API для базовой модели
│ └── SRC/
│ ├── app.py
│ ├── inference.py
│ ├── Dockerfile
│ └── model_finetuned/ # ⚠️ Модель загружается отдельно
└── API_crf/ # API для CRF модели
└── SRC/
├── app.py
├── inference.py
├── Dockerfile
└── model_finetuned/ # ⚠️ Модель загружается отдельно
Папки API/ и API_crf/ содержат готовые к развертыванию FastAPI приложения с оптимизацией для production:
Важно! Перед развертыванием необходимо загрузить обученную модель с Hugging Face Hub:
P0ve1/NER_X5_bertP0ve1/NER_X5_bert-crfAPI/SRC/model_finetuned/API_crf/SRC/model_finetuned/Требуемые файлы модели:
model_finetuned/
├── config.json
├── pytorch_model.bin (или model.safetensors)
├── tokenizer_config.json
├── tokenizer.json
├── vocab.txt
└── special_tokens_map.json
# Для базовой модели
cd API
docker-compose up -d --build
# Для CRF модели
cd API_crf
docker-compose up -d --build
# Health check
curl http://localhost:80/health
# Предсказание (базовая модель)
curl -X POST "http://localhost:80/api/predict" \
-H "Content-Type: application/json" \
-d '{"input": "молоко сгущенное 500ml"}'
# Production endpoint (пример)
curl -X POST "http://51.250.30.54:8000/api/predict" \
-H "Content-Type: application/json" \
-d '{"input": "молоко сгущенное 500ml"}'
Ответ:
[
{"start_index": 0, "end_index": 6, "entity": "B-TYPE"},
{"start_index": 7, "end_index": 17, "entity": "B-BRAND"},
{"start_index": 18, "end_index": 23, "entity": "B-VOLUME"}
]
Подробные инструкции по настройке, оптимизации и мониторингу см. в файлах:
API/README.md - полная документация для базовой моделиAPI/instruction.md - пошаговая инструкция по развертываниюAPI_crf/README.md - документация для CRF моделиAPI_crf/instruction.md - инструкция для CRF версииДокументация включает:
Папка data/ содержит:
train_v1.csv - исходный датасетtrain_balanced.csv - сбалансированный датасет для обученияtrain_extended (3).csv - расширенный датасетbalance_dataset.py - скрипт для балансировки данныхДатасет представлен в CSV формате со следующими колонками:
sample - текст описания товара (токенизированный по пробелам)annotation - список аннотаций в формате [(token, label), ...]Пример:
sample,annotation
"молоко сгущенное 500ml","[('молоко', 'B-TYPE'), ('сгущенное', 'I-TYPE'), ('500ml', 'B-VOLUME')]"
Используется схема BIO (Begin, Inside, Outside):
B-VOLUME / I-VOLUME - объем/весB-TYPE / I-TYPE - тип продуктаB-PERCENT / I-PERCENT - процентное содержаниеB-BRAND / I-BRAND - брендO - не является сущностьюРезультаты старых экспериментов на выборке 5000 примеров:
| Модель | F1-Score |
|---|---|
| dslim/bert-base-NER | 0.7146 |
| DeepPavlov/rubert-base-cased | 0.8292 |
| FacebookAI/xlm-roberta-large-finetuned-conll03-english | 0.6459 |
| Babelscape/wikineural-multilingual-ner | 0.5169 |
| cointegrated/rubert-tiny2 | 0.4858 |
| Модель | F1-Score |
|---|---|
| DeepPavlov/rubert-base-cased | 0.8530 |
Каждая папка src_* содержит:
train*.py - скрипт для обучения моделиinference*.py - скрипт для предсказаний*.ipynb - Jupyter notebook с полным pipelineDataPreprocessor - загрузка и предобработка данныхalign_labels_with_tokens - выравнивание меток с токенамиcompute_metrics - вычисление F1-score и accuracyBertCrfForTokenClassification - кастомная модель BERT+CRFLLMEmbeddingExtractor - извлечение эмбеддингов для BiLSTM1 commits
Jupyter Notebook
85.7%
Python
14.2%