feat: интеграция LLAIM Legal NER как третьей ступени распознавания

- Подключение ru-legal-ner (ONNX) для юридических реквизитов: ИНН, ОГРН,
  СНИЛС, паспорт, телефон, email, банковский счёт, дата.
- Отдельный проход LEGAL_CANDIDATE, чтобы не вытеснять кандидатов имён и адресов.
- coversAny(policy) в Pipeline вместо проверки только FIO.
- Нормализация цифровых ПД (ИНН/СНИЛС/карта/ОГРН) в свободной форме.
- Фикс ложного срабатывания ФИО на аббревиатуре «ИНН» (PD_MARKERS).
- Рефакторинг конструкторов NameCascade через record EngineConfig (Sonar S107).
This commit is contained in:
dakocha3
2026-09-23 21:40:53 +03:00
parent c209c4a366
commit 685ec977de
12 changed files with 384 additions and 14 deletions
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env python3
"""Конвертация LLAIMlegal/ru-legal-ner в ONNX для RuBertRecogniser.
Модель — BertForTokenClassification. Экспортируем в ONNX с динамической
длиной входа, чтобы RuBertRecogniser мог подавать куски разной длины.
"""
import torch
from transformers import AutoTokenizer, AutoModelForTokenClassification
from pathlib import Path
SRC = "LLAIMlegal/ru-legal-ner"
OUT = Path("models/ru-legal-ner")
tokenizer = AutoTokenizer.from_pretrained(SRC)
model = AutoModelForTokenClassification.from_pretrained(SRC)
model.eval()
# Динамическая длина: batch=1, seq=dynamic
dummy = torch.zeros(1, 8, dtype=torch.long)
torch.onnx.export(
model,
(dummy, dummy, dummy),
str(OUT / "model.onnx"),
input_names=["input_ids", "attention_mask", "token_type_ids"],
output_names=["logits"],
dynamic_shapes=[
{0: "batch", 1: "seq"},
{0: "batch", 1: "seq"},
{0: "batch", 1: "seq"},
],
opset_version=14,
)
print("ONNX exported to", OUT / "model.onnx")
+16 -1
View File
@@ -40,6 +40,21 @@ fetch "https://huggingface.co/onnx-community/bert-base-NER-Russian-ONNX/resolve/
mv -f models/rubert-ner/onnx/model_int8.onnx models/rubert-ner/model.onnx 2>/dev/null || true
rmdir models/rubert-ner/onnx 2>/dev/null || true
# LLAIM Legal NER (LLAIMlegal/ru-legal-ner, MIT) — юридические реквизиты и
# документы: ИНН, ОГРН, СНИЛС, паспорт, телефон, email, банковский счёт, дата.
# Готового ONNX нет — скачиваем веса и конвертируем скриптом (нужны torch,
# transformers, optimum, onnx).
fetch "https://huggingface.co/LLAIMlegal/ru-legal-ner/resolve/main" \
models/ru-legal-ner model.safetensors \
config.json tokenizer.json tokenizer_config.json
if command -v python3 >/dev/null 2>&1; then
python3 tools/convert_ru_legal_ner.py || echo "Не удалось сконвертировать ru-legal-ner в ONNX"
else
echo "python3 не найден: ru-legal-ner не сконвертирован в ONNX"
fi
echo "Готово. Включить:"
echo " pdguard.ner.name-engine=wikineural, pdguard.ner.name-model=models/wikineural-ner"
echo " pdguard.ner.address-engine=rubert, pdguard.ner.address-model=models/rubert-ner"
echo " pdguard.ner.address-engine=rubert, pdguard.ner.address-model=models/rubert-ner"
echo " pdguard.ner.legal-engine=ru-legal-ner, pdguard.ner.legal-model=models/ru-legal-ner"