We develop custom named entity recognition (NER) systems for business domains such as finance, medicine, and law. Our solutions extract domain-specific entities with high accuracy through fine-tuning pre-trained models on your data. For a comprehensive overview, see the Wikipedia article on NER. Standard models (CoNLL-2003) only recognize persons, organizations, locations — clearly insufficient for domain-specific vocabulary. Typical business tasks: extracting financial indicators from reports, identifying drugs in prescriptions, recognizing legal entities in contracts. Each requires a tailored approach. Our fine-tuning NER pipeline using ruBERT NER or spaCy NER achieves high Entity F1 scores by employing proper BIO tagging.
We implement NER end-to-end: from architecture selection to deployment in your infrastructure. Let's break down how to set up entity recognition in Russian, compare tools, and show why fine-tuning pays off.
Standard entity types and their extension
The basic set (CoNLL-2003): PER (persons), ORG (organizations), LOC (locations), MISC (other). This is often insufficient for business. Typical custom types:
- Finance: MONEY, PERCENT, DATE, TICKER, FINANCIAL_INSTRUMENT
- Medicine: DISEASE, DRUG, DOSAGE, PROCEDURE, ANATOMY
- Law: LAW, COURT, CASE_NUMBER, LEGAL_ENTITY
- Logistics: ADDRESS, POSTAL_CODE, VEHICLE_ID, CARGO
How to choose a tool for NER in Russian?
natasha — optimal for a quick start:
from natasha import Segmenter, MorphVocab, NewsEmbedding, NewsNERTagger, Doc
segmenter = Segmenter()
emb = NewsEmbedding()
ner_tagger = NewsNERTagger(emb)
doc = Doc("Газпром подписал контракт с немецкой компанией Wintershall в Берлине.")
doc.segment(segmenter)
doc.tag_ner(ner_tagger)
# [(Газпром, ORG), (Wintershall, ORG), (Берлине, LOC)]
spaCy (ru_core_news_lg): balance of speed and quality, easily integrates into production pipelines.
BERT-based (DeepPavlov, HuggingFace): maximum accuracy on complex texts, but higher latency.
Compare tools in the table:
| Tool | Accuracy (F1) | Speed (ms/sentence) | Custom entities |
|---|---|---|---|
| natasha | 85–90% | ~2 ms | no (only basic) |
| spaCy | 88–93% | ~5 ms | fine-tuning via prodigy |
| ruBERT | 92–97% | ~30 ms (CPU) | fine-tuning via HF |
Why fine-tuning improves accuracy?
Fine-tuning on your corpus removes homonymy and lifts F1 by 10–15%. A pre-trained model confuses 'Apple' (fruit) and 'Apple' (company). After fine-tuning, the model considers context, which is critical for domain-specific vocabulary. The process includes annotation, IOB2 formatting, and training via HuggingFace.
| Scenario | F1 before fine-tuning | F1 after fine-tuning |
|---|---|---|
| Medical terms | 75% | 91% |
| Legal entities | 68% | 88% |
Fine-tuning for custom entities
Process:
- Annotation: using Prodigy or Label Studio. Minimum 200–500 examples per entity type.
- Format: IOB2 (BIO-tagging) — standard for NER.
- Training: HuggingFace TokenClassification with pre-trained RuBERT.
from transformers import AutoModelForTokenClassification, TrainingArguments
model = AutoModelForTokenClassification.from_pretrained(
"DeepPavlov/rubert-base-cased",
num_labels=len(label_list),
id2label=id2label,
label2id=label2id
)
NER quality evaluation
Entity-level F1 (strict) — the main metric. 'Strict' means correct type AND correct span boundaries. Partial match is considered an error.
Typical scores on Russian texts:
- PER: F1 95–97% (easily recognizable patterns)
- ORG: F1 88–93% (many abbreviations)
- LOC: F1 90–95%
- Custom domain entities: 80–90% after fine-tuning on 1K+ examples
How we implement NER for your domain?
Our approach is engineering-driven, no black boxes. Work stages:
- Data analysis: study your texts, define target entities, assess complexity (nesting, homonymy, discontiguous entities).
- Annotation and augmentation: prepare corpus in IOB2, control quality via cross-validation of annotators.
- Architecture selection: compare natasha/spaCy/BERT on your corpus, choose by F1 and latency.
- Fine-tuning and testing: train model, achieve F1 > 90% on target types.
- Deployment: package into ONNX (CPU) or TorchServe (GPU), latency from 5 to 30 ms per sentence.
- Handover: documentation, pipeline code, model access, training for your team.
What is included in our work
You receive:
- Trained model with custom entities
- Inference code (Python, Docker image)
- Instructions for retraining on new data
- 3-month warranty support
For each project, we prepare a guideline for annotators, conduct a test round with quality control (inter-annotator agreement > 0.9). After scheme approval, we start full annotation.
Complex cases
- Nested entities: 'Министерство финансов России' — ORG + LOC. Most models do not support nesting; we use Span-BERT or biaffine NER.
- Discontiguous entities: 'ООО… (далее — Компания)' — requires a coreference module.
- Homonymy: resolved by context (transformers handle better than CRF).
Deployment and reliability
We guarantee stable model operation under load. With over 5 years of experience in NLP and more than 50 successful projects, we are a trusted partner for custom NER development. Our team includes certified PyTorch engineers, ensuring reliable deployment.
Deliverables
Our deliverables include:
- Comprehensive documentation of the model architecture and training process
- Access to the trained model and inference pipeline
- Retraining scripts and guidelines for updating the model with new data
- 3 months of post-deployment support and troubleshooting
- Option for ongoing annotation and model maintenance
The cost of a typical NER project starts from $5,000 for a single entity type and scales up to $15,000 for comprehensive multi-entity systems. This investment often yields 80% reduction in manual data processing costs.
Contact us to discuss your task and get a work plan and timeline (from 2 to 6 weeks depending on annotation volume).
Order development of a custom NER system for your domain. Get a consultation on tool selection and required data volume. For a preliminary assessment of your case, write to us — we will prepare a detailed work plan.







