AtesiT commited on
Commit
81d0093
·
verified ·
1 Parent(s): 6626087

Checkpoint v11.4

Browse files
checkpoints/v11.4/1_Pooling/config.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "embedding_dimension": 384,
3
+ "pooling_mode": "mean",
4
+ "include_prompt": true
5
+ }
checkpoints/v11.4/README.md ADDED
@@ -0,0 +1,486 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - ru
4
+ - en
5
+ license: mit
6
+ tags:
7
+ - stylometry
8
+ - author-attribution
9
+ - osint
10
+ - threat-intelligence
11
+ - sentence-transformers
12
+ - siamese-network
13
+ - contrastive-learning
14
+ - text-classification
15
+ - forensics
16
+ pipeline_tag: sentence-similarity
17
+ library_name: sentence-transformers
18
+ metrics:
19
+ - accuracy
20
+ - f1
21
+ - roc_auc
22
+ model-index:
23
+ - name: osint-stylometry-model
24
+ results:
25
+ - task:
26
+ type: sentence-similarity
27
+ name: Author Attribution / Stylometry
28
+ metrics:
29
+ - type: accuracy
30
+ value: 0.6716
31
+ name: Accuracy
32
+ - type: f1
33
+ value: 0.7211
34
+ name: F1 Score
35
+ - type: roc_auc
36
+ value: 0.9432
37
+ name: ROC AUC
38
+ ---
39
+ # 🕵️ OSINT Stylometry & Author Attribution Model
40
+
41
+ <p align="center">
42
+ <img src="https://img.shields.io/badge/PyTorch-EE4C2C?style=for-the-badge&logo=pytorch&logoColor=white" />
43
+ <img src="https://img.shields.io/badge/%F0%9F%A4%97%20Transformers-FFD21E?style=for-the-badge" />
44
+ <img src="https://img.shields.io/badge/Sentence--Transformers-2b6cb0?style=for-the-badge" />
45
+ <img src="https://img.shields.io/badge/OSINT-Stylometry-2b2b2b?style=for-the-badge" />
46
+ <img src="https://img.shields.io/badge/ONNX-Ready-005CED?style=for-the-badge&logo=onnx&logoColor=white" />
47
+ <img src="https://img.shields.io/badge/License-MIT-green?style=for-the-badge" />
48
+ <img src="https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Model-yellow?style=for-the-badge" />
49
+ </p>
50
+
51
+ <p align="center">
52
+ <b>Нейросетевая модель для определения авторства текста по стилю письма: опечаткам, пунктуации,<br>
53
+ сленгу, эмодзи и языковым смесям.</b><br>
54
+ Создана для задач <b>OSINT · Threat Intelligence · Cyber Threat Attribution · Форензика</b>.
55
+ </p>
56
+
57
+ <p align="center">
58
+ <i>Текущая версия модели: <b>v11.1</b> · Отчёт сгенерирован: 2026-08-30 18:11</i>
59
+ </p>
60
+
61
+ ---
62
+
63
+ ## 📑 Содержание
64
+
65
+ - [О проекте](#-о-проекте)
66
+ - [Ключевые возможности](#-ключевые-возможности)
67
+ - [OSINT: практическое применение](#-osint-практическое-применение)
68
+ - [Как это работает (теория)](#-как-это-работает-теория)
69
+ - [Архитектура модели](#%EF%B8%8F-архитектура-модели)
70
+ - [Метрики качества](#-метрики-качества-текущей-версии)
71
+ - [Визуализация результатов](#-визуализация-результатов)
72
+ - [Установка](#-установка)
73
+ - [Быстрый старт](#-быстрый-старт-quickstart)
74
+ - [Продвинутое использование](#-продвинутое-использование)
75
+ - [Инференс через ONNX (CPU, миллисекунды)](#-инференс-через-onnx-cpu-миллисекунды)
76
+ - [Сравнение с альтернативными подходами](#-сравнение-с-альтернативными-подходами)
77
+ - [Ограничения модели](#-ограничения-модели)
78
+ - [Этика и ответственное использование](#-этика-и-ответственное-использование)
79
+ - [Дорожная карта (Roadmap)](#-дорожная-карта-roadmap)
80
+ - [История версий (Changelog)](#-история-версий-changelog)
81
+ - [Как внести вклад](#-как-внести-вклад)
82
+ - [Цитирование](#-цитирование)
83
+ - [FAQ](#-часто-задаваемые-вопросы)
84
+ - [Лицензия](#-лицензия)
85
+
86
+ ---
87
+
88
+ ## 📖 О проекте
89
+
90
+ **OSINT Stylometry Model** — это дообученный энкодер на базе архитектуры **Sentence-BERT (Siamese Network)**,
91
+ который преобразует произвольный текст (пост, комментарий, сообщение в чате, реплику на форуме) в
92
+ компактный числовой вектор — так называемый **«стилистический отпечаток» (stylistic fingerprint)**.
93
+
94
+ Главная идея: два текста, написанных **одним и тем же человеком**, будут иметь высокую косинусную
95
+ схожесть векторов, даже если они посвящены совершенно разным темам. И наоборот — тексты **разных авторов**
96
+ будут располагаться в векторном пространстве далеко друг от друга, даже если темы совпадают.
97
+
98
+ Модель специально обучена **игнорировать содержание** текста и фокусироваться исключительно на форме:
99
+ пунктуационных привычках, характерных опечатках, любимых жаргонизмах, паттернах использования эмодзи,
100
+ смешении языков (русский + английский сленг, транслит, leetspeak) и типичной длине предложений.
101
+ Именно эти признаки психолингвисты и криминалисты называют **идиолектом** — уникальной речевой манерой
102
+ человека, которую крайне сложно скрыть или подделать в долгосрочной перспективе.
103
+
104
+ ## 🎯 OSINT: практическое применение
105
+
106
+ Стилометрия — один из самых недооценённых инструментов в арсенале аналитика открытых источников.
107
+ В отличие от метаданных (IP-адреса, geolocation, временные метки), стиль письма невозможно скрыть
108
+ через VPN или Tor — он «утекает» в каждом сообщении, которое пишет человек. Ниже описаны ключевые
109
+ сценарии применения этой модели в реальной аналитической практике.
110
+
111
+ ### 1. Деанонимизация владельцев Telegram-каналов и форумных аккаунтов
112
+
113
+ Аналитики OSINT регулярно сталкиваются с ситуацией, когда один и тот же человек администрирует
114
+ несколько «независимых» анонимных каналов, ведёт параллельные аккаунты на теневых форумах или
115
+ использует разные никнеймы в разных сообществах для маскировки истинного масштаба своей деятельности.
116
+ Прямые технические связи (общий IP, устройство, telephone number) часто отсутствуют или тщательно
117
+ скрыты. Однако стиль письма — пунктуационные привычки, специфические опечатки, повторяющиеся
118
+ жаргонизмы — остаётся практически неизменным. Сравнивая эмбеддинги постов из разных источников,
119
+ модель позволяет построить граф вероятных связей между аккаунтами и приоритизировать дальнейшее
120
+ расследование.
121
+
122
+ ### 2. Атрибуция утечек данных и дампов конкретным группировкам (CTI / Threat Intelligence)
123
+
124
+ Когда в даркнете появляется очередной дамп базы данных или пост о продаже логов / доступа, аналитику
125
+ Threat Intelligence важно быстро определить, стоит ли за этим уже известная группировка или новый
126
+ игрок. Сопроводительные тексты («шапки» дампов, объявления о продаже, коммуникация с потенциальными
127
+ покупателями) обладают устойчивым стилем. Накопив базу стилистических профилей ранее атрибутированных
128
+ акторов, можно автоматически сравнивать новые публикации с этой базой и получать вероятностную
129
+ оценку принадлежности к известной группе — что резко ускоряет процесс атрибуции инцидентов.
130
+
131
+ ### 3. Обнаружение компрометации аккаунта и симулированного стиля
132
+
133
+ Если корпоративный аккаунт, аккаунт инфлюенсера или канал в Telegram скомпрометирован, стиль
134
+ публикуемых сообщений часто резко меняется: исчезают характерные опечатки, меняется пунктуационная
135
+ манера, появляется несвойственный автору сленг или, наоборот, излишне «правильный» текст, типичный
136
+ для мошеннических шаблонов. Модель может использоваться как система раннего оповещения (early warning
137
+ system), непрерывно сравнивающая новые сообщения с историческим профилем автора и подсвечивающая
138
+ аномальные отклонения ещё до того, как содержание сообщения станет очевидно подозрительным.
139
+
140
+ ### 4. Верификация независимости анонимных источников и информаторов
141
+
142
+ При работе с несколькими анонимными источниками информации критически важно понимать, не является
143
+ ли один и тот же человек автором нескольких «независимых» вбросов, созданных для придания
144
+ информации видимости консенсуса (эффект множественного подтверждения). Стилометрический анализ
145
+ позволяет выявить такие скрытые связи ещё до содержательной фактчекинг-проверки, экономя время
146
+ аналитика и снижая риск манипуляции через фабрикованный консенсус источников.
147
+
148
+ ### 5. Судебная лингвистика и цифровая форензика
149
+
150
+ В делах, связанных с кибербуллингом, вымогательством, угрозами или мошенничеством, стилометрическая
151
+ модель может использоваться как вспомогательный количественный инструмент для экспертизы авторства
152
+ анонимных сообщений. Она не заменяет классическую судебную лингвистическую экспертизу, но предоставляет
153
+ объективную, воспроизводимую метрику схожести, которая может служить отправной точкой для более
154
+ глубокого ручного анализа экспертом.
155
+
156
+ ## 🧠 Как это работает (теория)
157
+
158
+ В основе модели лежит подход **Siamese Neural Network** (сиамская нейросеть) в связке с
159
+ **Contrastive Learning**. Интуитивно это работает так:
160
+
161
+ 1. **Энкодер** (Transformer-модель) принимает на вход текст и превращает его в вектор фиксированной
162
+ длины (эмбеддинг), например, размерностью 384.
163
+ 2. Во время обучения модель одновременно смотрит на **пары текстов**: либо «текст A и текст B написаны
164
+ одним автором» (позитивная пара, label = 1), либо «текст A и текст C написаны разными авторами»
165
+ (негативная пара, label = 0).
166
+ 3. Функция потерь **Online Contrastive Loss** «притягивает» эмбеддинги позитивных пар друг к другу
167
+ в векторном пространстве и «отталкивает» эмбеддинги негативных пар друг от друга.
168
+ 4. После обучения на десятках тысяч таких пар модель самостоятельно учится выделять признаки,
169
+ которые действительно коррелируют с авторством: пунктуацию, длину предложений, частоту опечаток,
170
+ характерные слова — а не с темой текста, которая варьируется от сообщения к сообщению.
171
+ 5. На инференсе для сравнения двух новых, никогда не виденных текстов достаточно посчитать
172
+ **косинусную схожесть** (cosine similarity) их эмбеддингов: значение ближе к 1.0 означает высокую
173
+ вероятность общего авторства, ближе к 0.0 (или отрицательное) — разных авторов.
174
+
175
+ Отдельное внимание в этом проекте уделено **adversarial-обучению**: часть тренировочных пар — это
176
+ намеренно «замаскированные» тексты, где стиль автора A искусственно подмешан в текст, изначально
177
+ написанный в стиле автора B. Это заставляет модель не полагаться на поверхностные, легко подделываемые
178
+ признаки (например, наличие конкретного эмодзи), а искать более глубокие, устойчивые стилистические
179
+ закономерности.
180
+
181
+ ## 🏗️ Архитектура модели
182
+
183
+ | Параметр | Значение |
184
+ |---|---|
185
+ | Базовая модель | `sentence-transformers/all-MiniLM-L6-v2` |
186
+ | Тип задачи | Sentence Embedding / Metric Learning |
187
+ | Метод обучения | Siamese Network + Online Contrastive Loss |
188
+ | Ускорение обучения | Mixed Precision (fp16), GPU NVIDIA T4 |
189
+ | Размерность эмбеддинга | 384 |
190
+ | Максимальная длина последовательности | 128 токенов |
191
+ | Формат для продакшена | PyTorch (`.bin` / `.safetensors`) + **ONNX** (`onnx/model.onnx`) |
192
+ | Стадии обучения | v1.0 (базовый стиль) → v2.0 (сленг/опечатки/эмодзи) → v3.0 (adversarial siamese) → v3.x (дообучение) |
193
+
194
+ Репозиторий также хранит **версионированные чекпоинты** каждой стадии обучения в папке
195
+ `checkpoints/vX.X/`, что позволяет откатиться к любой предыдущей версии модели при необходимости.
196
+
197
+ ## 📊 Метрики качества текущей версии (v12)
198
+
199
+ | Метрика | Значение | Пояснение |
200
+ |---|---|---|
201
+ | **Accuracy** | 0.6716 | Доля верно классифицированных пар «тот же автор / разные авторы» |
202
+ | **F1-Score** | 0.7211 | Гармоническое среднее precision и recall (устойчиво к дисбалансу классов) |
203
+ | **ROC-AUC** | 0.9432 | Способность модели ранжировать пары по вероятности общего авторства |
204
+ | **Adversarial Robustness** | 0.3173 | Средняя схожесть оригинал↔замаскированный текст (чем ниже — тем лучше) |
205
+
206
+ ## 📈 Визуализация результатов
207
+
208
+ ### Динамика функции потерь по стадиям обучения
209
+ ![loss curve](loss_curve.png)
210
+
211
+ *График показывает, как снижается ошибка модели (train/val loss) на каждой из последовательных стадий
212
+ обучения (v1.0 → v2.0 → v3.0 → ...). Стабильное снижение val_loss без резкого расхождения с train_loss
213
+ говорит об отсутствии переобучения.*
214
+
215
+ ### Матрица ошибок (Confusion Matrix)
216
+ ![confusion matrix](confusion_matrix.png)
217
+
218
+ *Показывает количество верных и ошибочных предсказаний модели в разрезе двух классов: «один автор» и
219
+ «разные авторы», при фиксированном пороге классификации 0.5.*
220
+
221
+ ### ROC-кривая
222
+ ![roc curve](roc_curve.png)
223
+
224
+ *Демонстрирует компромисс между True Positive Rate и False Positive Rate при различных порогах
225
+ классификации. Площадь под кривой (AUC) — интегральная метрика качества ранжирования.*
226
+
227
+ ### 2D-карта стилистических кластеров авторов (t-SNE)
228
+ ![style clusters](style_clusters_tsne.png)
229
+
230
+ *Каждая точка — эмбеддинг одного сообщения, спроецированный из 384-мерного пространства в 2D с помощью
231
+ t-SNE. Цвет точки соответствует ID автора. Чёткое разделение на визуальные кластеры — наглядное
232
+ подтверждение того, что модель научилась различать авторов по стилю, а не по теме сообщения.*
233
+
234
+ ### Устойчивость к маскировке стиля (Adversarial Robustness)
235
+ ![adversarial robustness](adversarial_robustness.png)
236
+
237
+ *Метрика показывает, насколько сильно меняется эмбеддинг текста при попытке «перерисовать» его в чужом
238
+ стиле. Низкое значение косинусной схожести между оригиналом и замаскированной версией говорит о том,
239
+ что модель устойчива к простым попыткам имитации чужой манеры письма.*
240
+
241
+ ## 📦 Установка
242
+
243
+ Модель совместима с библиотекой `sentence-transformers` (рекомендуется) или напрямую с `transformers`.
244
+
245
+ ```bash
246
+ pip install sentence-transformers
247
+ ```
248
+
249
+ Либо, если вы планируете использовать «сырой» `transformers` API или ONNX-инференс:
250
+
251
+ ```bash
252
+ pip install transformers onnxruntime torch
253
+ ```
254
+
255
+ ## 🚀 Быстрый старт (Quickstart)
256
+
257
+ Самый про��той способ проверить, написаны ли два текста одним автором:
258
+
259
+ ```python
260
+ from sentence_transformers import SentenceTransformer, util
261
+
262
+ # Загружаем модель прямо с Hugging Face Hub (веса скачаются автоматически и закэшируются)
263
+ model = SentenceTransformer("AtesiT/osint-stylometry-model")
264
+
265
+ text_a = "го глянем новый дамп там что-то интересное было"
266
+ text_b = "го посмотрим свежий слив вроде движуха там движется"
267
+ text_c = "Добрый день, направляю вам отчёт по итогам квартала."
268
+
269
+ # Кодируем все тексты в векторы одним вызовом
270
+ embeddings = model.encode([text_a, text_b, text_c], convert_to_tensor=True)
271
+
272
+ # Считаем косинусную схожесть между парами
273
+ sim_ab = util.cos_sim(embeddings[0], embeddings[1]).item()
274
+ sim_ac = util.cos_sim(embeddings[0], embeddings[2]).item()
275
+
276
+ print(f"Схожесть A-B (ожидаем высокую, похожий стиль): {sim_ab:.3f}")
277
+ print(f"Схожесть A-C (ожидаем низкую, разный стиль): {sim_ac:.3f}")
278
+ ```
279
+
280
+ ## 🛠️ Продвинутое использование
281
+
282
+ ### Кластеризация большого набора сообщений по вероятному авторству
283
+
284
+ ```python
285
+ from sentence_transformers import SentenceTransformer
286
+ from sklearn.cluster import AgglomerativeClustering
287
+ import numpy as np
288
+
289
+ model = SentenceTransformer("AtesiT/osint-stylometry-model")
290
+
291
+ messages = [
292
+ "го глянем новый дамп там что-то интересное было",
293
+ "заказал пиццу и весь вечер кодил лол",
294
+ "го посмотрим свежий слив вроде движуха там движется",
295
+ "Добрый день, направляю вам отчёт по итогам квартала.",
296
+ "Коллеги, прошу ознакомиться с материалами до пятницы.",
297
+ ]
298
+
299
+ embeddings = model.encode(messages, convert_to_numpy=True, normalize_embeddings=True)
300
+
301
+ # Иерархическая кластеризация по косинусному расстоянию —
302
+ # помогает автоматически сгруппировать сообщения по вероятному автору
303
+ clustering = AgglomerativeClustering(
304
+ n_clusters=None,
305
+ distance_threshold=0.4,
306
+ metric="cosine",
307
+ linkage="average",
308
+ )
309
+ labels = clustering.fit_predict(embeddings)
310
+
311
+ for msg, label in zip(messages, labels):
312
+ print(f"[Кластер {label}] {msg}")
313
+ ```
314
+
315
+ ### Использование через «сырой» transformers API (без sentence-transformers)
316
+
317
+ ```python
318
+ import torch
319
+ from transformers import AutoTokenizer, AutoModel
320
+ import torch.nn.functional as F
321
+
322
+ tokenizer = AutoTokenizer.from_pretrained("AtesiT/osint-stylometry-model")
323
+ model = AutoModel.from_pretrained("AtesiT/osint-stylometry-model")
324
+
325
+ def mean_pooling(model_output, attention_mask):
326
+ # Усредняем токен-эмбеддинги с учётом маски внимания (стандартный pooling для SBERT)
327
+ token_embeddings = model_output[0]
328
+ mask = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
329
+ return torch.sum(token_embeddings * mask, 1) / torch.clamp(mask.sum(1), min=1e-9)
330
+
331
+ texts = ["пример первого текста", "пример второго текста для сравнения"]
332
+ encoded = tokenizer(texts, padding=True, truncation=True, return_tensors="pt")
333
+
334
+ with torch.no_grad():
335
+ output = model(**encoded)
336
+
337
+ embeddings = mean_pooling(output, encoded["attention_mask"])
338
+ embeddings = F.normalize(embeddings, p=2, dim=1)
339
+
340
+ similarity = torch.matmul(embeddings[0], embeddings[1])
341
+ print(f"Косинусная схожесть: {similarity.item():.3f}")
342
+ ```
343
+
344
+ ## ⚡ Инференс через ONNX (CPU, миллисекунды)
345
+
346
+ Для продакшен-сценариев, где недоступен GPU или важна минимальная задержка (например, real-time
347
+ скоринг сообщений в потоке мониторинга), модель экспортирована в формат **ONNX** и лежит в папке
348
+ `onnx/` репозитория.
349
+
350
+ ```python
351
+ import onnxruntime as ort
352
+ from transformers import AutoTokenizer
353
+ import numpy as np
354
+ from huggingface_hub import hf_hub_download
355
+
356
+ REPO_ID = "AtesiT/osint-stylometry-model"
357
+
358
+ # Скачиваем onnx-модель и токенизатор из репозитория
359
+ onnx_path = hf_hub_download(repo_id=REPO_ID, filename="onnx/model.onnx")
360
+ tokenizer = AutoTokenizer.from_pretrained(REPO_ID, subfolder="onnx")
361
+
362
+ session = ort.InferenceSession(onnx_path, providers=["CPUExecutionProvider"])
363
+
364
+ def encode_onnx(texts):
365
+ inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="np", max_length=128)
366
+ outputs = session.run(None, {
367
+ "input_ids": inputs["input_ids"],
368
+ "attention_mask": inputs["attention_mask"],
369
+ })
370
+ last_hidden = outputs[0]
371
+ mask = inputs["attention_mask"][..., None]
372
+ pooled = (last_hidden * mask).sum(1) / np.clip(mask.sum(1), 1e-9, None)
373
+ norm = pooled / np.linalg.norm(pooled, axis=1, keepdims=True)
374
+ return norm
375
+
376
+ emb = encode_onnx(["текст один", "текст два"])
377
+ cos_sim = float(np.dot(emb[0], emb[1]))
378
+ print(f"ONNX cosine similarity: {cos_sim:.3f}")
379
+ ```
380
+
381
+ На CPU (без GPU) инференс одного сообщения через ONNX Runtime занимает, как правило,
382
+ **единицы–десятки миллисекунд**, что делает модель пригодной для встраивания в высоконагруженные
383
+ пайплайны мониторинга без необходимости содержать GPU-инфраструктуру.
384
+
385
+ ## ⚖️ Сравнение с альтернативными подходами
386
+
387
+ | Подход | Учитывает стиль | Учитывает содержание | Требует разметки | Скорость инференса |
388
+ |---|---|---|---|---|
389
+ | Ручной анализ лингвиста-эксперта | ✅ Высокая точность | ✅ | ❌ Не требует | 🐢 Очень медленно |
390
+ | Классический TF-IDF + классификатор | ⚠️ Частично (через n-граммы) | ✅ Сильная зависимость | ✅ Требуется | ⚡ Быстро |
391
+ | Общая языковая модель (semantic embedding) | ❌ Слабо, фокус на смысле | ✅ Сильно | ❌ Zero-shot возможен | ⚡ Быстро |
392
+ | **Данная модель (stylometry siamese)** | ✅ **Основной фокус** | ⚠️ Специально подавлено | ⚠️ Синтетическая авто-разметка | ⚡⚡ Быстро (+ONNX) |
393
+
394
+ Ключевое отличие этой модели от универсальных text-embedding моделей (таких как исходная
395
+ `all-MiniLM-L6-v2`) в том, что она **дообучена намеренно подавлять сигнал темы** сообщения и усиливать
396
+ сигнал стиля — благодаря чему её эмбеддинги остаются стабильными даже при резкой смене тематики
397
+ переписки одного и того же автора.
398
+
399
+ ## ⚠️ Ограничения модели
400
+
401
+ - **Синтетические данные.** Модель обучена преимущественно на синтетически сгенерированных текстах,
402
+ имитирующих стилистические маркеры (сленг, опечатки, эмодзи). Реальные тексты могут содержать более
403
+ тонкие и разнообразные стилистические признаки, не охваченные генератором.
404
+ - **Короткие тексты.** При длине сообщения менее 5–7 слов стилистического сигнала может быть
405
+ недостаточно для надёжного сравнения — рекомендуется агрегировать несколько сообщений одного автора.
406
+ - **Целенаправленная имитация стиля профессионалом.** Хотя модель устойчива к простой маскировке
407
+ (см. Adversarial Robustness), целенаправленная и качественная имитация стиля другого человека
408
+ экспертом-лингвистом может снизить точность атрибуции.
409
+ - **Не заменяет юридическую экспертизу.** Результаты модели носят вероятностный,
410
+ вспомогательный характер и не должны использоваться как единственное доказательство в судебных или
411
+ иных официальных разбирательствах.
412
+ - **Языковой охват.** Модель ориентирована преимущественно на русскоязычный текст со вставками
413
+ английского сленга; качество на других языковых парах не гарантируется без дополнительного
414
+ дообучения.
415
+
416
+ ## 🛡️ Этика и ответственное использование
417
+
418
+ Технологии атрибуции авторства обладают значительным потенциалом двойного назначения. Мы призываем
419
+ испол��зовать эту модель **исключительно в законных целях**: расследование киберпреступлений,
420
+ Threat Intelligence, корпоративная безопасность, журналистские расследования, академические
421
+ исследования в области компьютерной лингвистики.
422
+
423
+ Запрещено и настоятельно не рекомендуется использовать модель для: преследования частных лиц,
424
+ нарушения права на анонимность добросовестных источников информации (например, разоблачителей —
425
+ whistleblowers), политических репрессий или любых форм незаконного наблюдения. Всегда действуйте
426
+ в соответствии с применимым законодательством о защите персональных данных и регламентами организации.
427
+
428
+ ## 📋 История версий (Changelog)
429
+
430
+ | Дата | Версия | Accuracy | F1-Score | Изменения в датасете / Архитектуре |
431
+ |---|---|---|---|---|
432
+ | 2026-08-30 18:10 | v12 | 0.6716 | 0.7211 | Обновление синтетических данных и дообучение модели |
433
+
434
+ ## 🤝 Как внести вклад
435
+
436
+ Проект развивается итеративно в Google Colab. Если вы хотите предложить улучшения:
437
+
438
+ 1. Форкните репозиторий модели на Hugging Face Hub или изучите структуру ноутбука.
439
+ 2. Расширьте генератор синтетических данных новыми стилистическими маркерами.
440
+ 3. Опишите изменение и, при возможности, приложите метрики до/после.
441
+ 4. Откройте обсуждение (Discussion) в репозитории модели на Hugging Face Hub.
442
+
443
+ ## 📚 Цитирование
444
+
445
+ Если вы используете эту модель в исследовании или продукте, пожалуйста, укажите ссылку на репозиторий:
446
+
447
+ ```bibtex
448
+ @misc{osint_stylometry_model,
449
+ title = {OSINT Stylometry and Author Attribution Model},
450
+ author = {AtesiT},
451
+ year = {2026},
452
+ howpublished = {\url{https://huggingface.co/AtesiT/osint-stylometry-model}},
453
+ note = {Siamese Sentence-Transformer, дообученный для задач стилометрической атрибуции авторства}
454
+ }
455
+ ```
456
+
457
+ ## ❓ Часто задаваемые вопросы
458
+
459
+ **Вопрос: Может ли модель определить автора текста «с нуля», без предварительно собранной базы?**
460
+ Нет. Модель определяет **схожесть** двух и более текстов, а не «имя» автора. Для практического
461
+ применения необходима база текстов с уже известным (или предполагаемым) авторством, с которой
462
+ сравнивается новый текст.
463
+
464
+ **Вопрос: Какой минимальный объём текста нужен для надёжного сравнения?**
465
+ Рекомендуется использовать сообщения длиной от 15–20 слов, либо агрегировать несколько коротких
466
+ сообщений одного автора в один пример для более стабильного эмбеддинга.
467
+
468
+ **Вопрос: Работает ли модель с текстами не на русском языке?**
469
+ Модель ориентирована на русскоязычные тексты с англоязычными сленговыми вставками. Для других языков
470
+ рекомендуется дообучение.
471
+
472
+ **Вопрос: Как часто обновляется модель?**
473
+ Модель дообучается итеративно в рамках отдельных сессий Colab; актуальная версия и метрики всегда
474
+ отражены в разделе Changelog выше.
475
+
476
+ **Вопрос: Можно ли использовать модель офлайн, без интернета?**
477
+ Да — после первого скачивания весов через `from_pretrained` они кэшируются локально; также доступна
478
+ полностью автономная ONNX-версия для offline CPU-инференса.
479
+
480
+ ## 📄 Лицензия
481
+
482
+ Данный проект распространяется под лицензией **MIT**. Вы можете свободно использовать, мод��фицировать
483
+ и распространять модель и код при условии сохранения указания на первоисточник и соблюдения раздела
484
+ [«Этика и ответственное использование»](#-этика-и-ответственное-использование).
485
+
486
+ ---
checkpoints/v11.4/config.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_cross_attention": false,
3
+ "architectures": [
4
+ "BertModel"
5
+ ],
6
+ "attention_probs_dropout_prob": 0.1,
7
+ "bos_token_id": null,
8
+ "classifier_dropout": null,
9
+ "dtype": "float32",
10
+ "eos_token_id": null,
11
+ "gradient_checkpointing": false,
12
+ "hidden_act": "gelu",
13
+ "hidden_dropout_prob": 0.1,
14
+ "hidden_size": 384,
15
+ "initializer_range": 0.02,
16
+ "intermediate_size": 1536,
17
+ "is_decoder": false,
18
+ "layer_norm_eps": 1e-12,
19
+ "max_position_embeddings": 512,
20
+ "model_type": "bert",
21
+ "num_attention_heads": 12,
22
+ "num_hidden_layers": 6,
23
+ "pad_token_id": 0,
24
+ "position_embedding_type": "absolute",
25
+ "tie_word_embeddings": true,
26
+ "transformers_version": "5.18.0",
27
+ "type_vocab_size": 2,
28
+ "use_cache": true,
29
+ "vocab_size": 30522
30
+ }
checkpoints/v11.4/config_sentence_transformers.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "__version__": {
3
+ "pytorch": "2.11.0+cu130",
4
+ "sentence_transformers": "5.7.0",
5
+ "transformers": "5.18.0"
6
+ },
7
+ "default_prompt_name": null,
8
+ "model_type": "SentenceTransformer",
9
+ "prompts": {
10
+ "document": "",
11
+ "query": ""
12
+ },
13
+ "similarity_fn_name": "cosine"
14
+ }
checkpoints/v11.4/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:415e2540a1ef7706de90f922f0f8d776d0b20c2ac8df2859eb25ae17a987857a
3
+ size 90864192
checkpoints/v11.4/modules.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "idx": 0,
4
+ "name": "0",
5
+ "path": "",
6
+ "type": "sentence_transformers.base.modules.transformer.Transformer"
7
+ },
8
+ {
9
+ "idx": 1,
10
+ "name": "1",
11
+ "path": "1_Pooling",
12
+ "type": "sentence_transformers.sentence_transformer.modules.pooling.Pooling"
13
+ },
14
+ {
15
+ "idx": 2,
16
+ "name": "2",
17
+ "path": "2_Normalize",
18
+ "type": "sentence_transformers.sentence_transformer.modules.normalize.Normalize"
19
+ }
20
+ ]
checkpoints/v11.4/sentence_bert_config.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "transformer_task": "feature-extraction",
3
+ "modality_config": {
4
+ "text": {
5
+ "method": "forward",
6
+ "method_output_name": "last_hidden_state"
7
+ }
8
+ },
9
+ "module_output_name": "token_embeddings"
10
+ }
checkpoints/v11.4/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
checkpoints/v11.4/tokenizer_config.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "cls_token": "[CLS]",
4
+ "do_basic_tokenize": true,
5
+ "do_lower_case": true,
6
+ "is_local": false,
7
+ "local_files_only": false,
8
+ "mask_token": "[MASK]",
9
+ "max_length": 128,
10
+ "model_max_length": 256,
11
+ "never_split": null,
12
+ "pad_to_multiple_of": null,
13
+ "pad_token": "[PAD]",
14
+ "pad_token_type_id": 0,
15
+ "padding_side": "right",
16
+ "sep_token": "[SEP]",
17
+ "stride": 0,
18
+ "strip_accents": null,
19
+ "tokenize_chinese_chars": true,
20
+ "tokenizer_class": "BertTokenizer",
21
+ "truncation_side": "right",
22
+ "truncation_strategy": "longest_first",
23
+ "unk_token": "[UNK]"
24
+ }