File size: 4,650 Bytes
81e8ada
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
---
license: apache-2.0
language:
- ru
library_name: transformers
pipeline_tag: text-classification
tags:
- customer-support
- hierarchical-classification
- mps
- minilm
base_model: sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2
---

# Классификаторы тикетов

Базовый encoder:
`sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2`.

Архитектура каждой модели:

```text
MiniLM encoder → masked mean pooling → Dropout(0.2) → Linear(384, N)
```

Обучены четыре независимые версии:

| Папка | Классы | Назначение |
|---|---:|---|
| `handler` | 3 | `human`, `llm`, `auto` |
| `human` | 22 | Категории обязательной ручной обработки |
| `llm` | 20 | Категории ответа/черновика LLM |
| `auto` | 18 | Категории безопасного автоответа |

## Данные

Использован `encoder_dataset.json`:

- 3000 уникальных запросов;
- 60 категорий;
- 50 запросов на категорию;
- 10 независимых смысловых формулировок на категорию;
- пять стилевых вариантов каждой формулировки.

Train/validation/test разделены по смысловым формулировкам в пропорции
80/10/10. Стилевые варианты одной исходной фразы всегда находятся в одном
split.

## Результаты

| Модель | Test accuracy | Test macro-F1 |
|---|---:|---:|
| `handler` | 0.817 | 0.817 |
| `human` | 0.745 | 0.690 |
| `llm` | 0.800 | 0.755 |
| `auto` | 0.778 | 0.713 |

В test router допустил 2 ошибки `human → auto` на 110 human-примерах.
Поэтому в MVP автоматическую отправку нужно дополнительно ограничивать
confidence threshold, allowlist и risk-правилами.

На Apple M1 Pro один уже загруженный `handler` выполняет batch-1 inference
примерно за 7.8 мс median и 8.7 мс p95. Время запуска CLI и загрузки весов в этот
замер не входит.

## Запуск

Каскадный прогноз:

```bash
.venv/bin/python predict.py \
  "С меня два раза сняли деньги за одну покупку"
```

Прогноз конкретной головой:

```bash
.venv/bin/python predict.py \
  "Где выключить рекламные уведомления?" \
  --task auto
```

Повторное обучение:

```bash
.venv/bin/python train_encoder_heads.py
```

## Загрузка с Hugging Face при старте сервиса

Публичный репозиторий не требует токена:

```python
from hub_runtime import HubTicketClassifier

classifier = HubTicketClassifier(
    repo_id="ZenMan67/support-ticket-classifiers-minilm"
)
result = classifier.predict(
    "С меня два раза сняли деньги за одну покупку"
)
```

При создании `HubTicketClassifier` вызывается `snapshot_download`. Router
загружается сразу, а соответствующая category-head — при первом обращении к
ней. Если нужны все четыре модели в памяти, передайте `preload_all=True`.

В каждой папке модели:

- `model.safetensors` — encoder и линейная голова в FP16;
- `config.json` — base model, pooling и порядок labels;
- `metrics.json` — split, история обучения и ошибки test.

FP16 используется только для хранения: текущий loader создаёт модель в FP32
и при загрузке приводит checkpoint к dtype модели. Это уменьшает размер
репозитория примерно вдвое без изменения API.

## Ограничения

Это baseline для MVP на полностью синтетических данных. Confidence не
калиброван, реальные опечатки, новые продуктовые термины и изменение входного
потока не представлены полноценно. Перед автозакрытием нужны реальные
деидентифицированные тикеты, shadow mode и отдельный safety-набор.