Downloads · 30 days
681
93% of all-time downloads
AtesiT/osint-stylometry-model
osint-stylometry-model is a sentence similarity model from AtesiT. Use it when you need a score for how close two texts are. It is set up for sentence-transformers. The card lists the license as mit.
<p align="center" <img src="https://img.shields.io/badge/PyTorch-EE4C2C?style=for-the-badge&logo=pytorch&logoColor=white" / <img src="https://img.shields.io/badge/%F0%9F%A4%97%20Transformers-FFD21E?style=for-the-badge…
Downloads · 30 days
681
93% of all-time downloads
All-time downloads
734
Public
Parameters
22.7M
7.6 GB on disk
Likes
2
Trending 1
Click a slice to open those files.
.safetensors7.7 GB · 99%
From the Hugging Face model README
OSINT Stylometry Model — это дообученный энкодер на базе архитектуры Sentence-BERT (Siamese Network), который преобразует произвольный текст (пост, комментарий, сообщение в чате, реплику на форуме) в компактный числовой вектор — так называемый «стилистический отпечаток» (stylistic fingerprint).
Главная идея: два текста, написанных одним и тем же человеком, будут иметь высокую косинусную схожесть векторов, даже если они посвящены совершенно разным темам. И наоборот — тексты разных авторов будут располагаться в векторном пространстве далеко друг от друга, даже если темы совпадают.
Модель специально обучена игнорировать содержание текста и фокусироваться исключительно на форме: пунктуационных привычках, характерных опечатках, любимых жаргонизмах, паттернах использования эмодзи, смешении языков (русский + английский сленг, транслит, leetspeak) и типичной длине предложений. Именно эти признаки психолингвисты и криминалисты называют идиолектом — уникальной речевой манерой человека, которую крайне сложно скрыть или подделать в долгосрочной перспективе.
Стилометрия — один из самых недооценённых инструментов в арсенале аналитика открытых источников. В отличие от метаданных (IP-адреса, geolocation, временные метки), стиль письма невозможно скрыть через VPN или Tor — он «утекает» в каждом сообщении, которое пишет человек. Ниже описаны ключевые сценарии применения этой модели в реальной аналитической практике.
Аналитики OSINT регулярно сталкиваются с ситуацией, когда один и тот же человек администрирует несколько «независимых» анонимных каналов, ведёт параллельные аккаунты на теневых форумах или использует разные никнеймы в разных сообществах для маскировки истинного масштаба своей деятельности. Прямые технические связи (общий IP, устройство, telephone number) часто отсутствуют или тщательно скрыты. Однако стиль письма — пунктуационные привычки, специфические опечатки, повторяющиеся жаргонизмы — остаётся практически неизменным. Сравнивая эмбеддинги постов из разных источников, модель позволяет построить граф вероятных связей между аккаунтами и приоритизировать дальнейшее расследование.
Когда в даркнете появляется очередной дамп базы данных или пост о продаже логов / доступа, аналитику Threat Intelligence важно быстро определить, стоит ли за этим уже известная группировка или новый игрок. Сопроводительные тексты («шапки» дампов, объявления о продаже, коммуникация с потенциальными покупателями) обладают устойчивым стилем. Накопив базу стилистических профилей ранее атрибутированных акторов, можно автоматически сравнивать новые публикации с этой базой и получать вероятностную оценку принадлежности к известной группе — что резко ускоряет процесс атрибуции инцидентов.
Если корпоративный аккаунт, аккаунт инфлюенсера или канал в Telegram скомпрометирован, стиль публикуемых сообщений часто резко меняется: исчезают характерные опечатки, меняется пунктуационная манера, появляется несвойственный автору сленг или, наоборот, излишне «правильный» текст, типичный для мошеннических шаблонов. Модель может использоваться как система раннего оповещения (early warning system), непрерывно сравнивающая новые сообщения с историческим профилем автора и подсвечивающая аномальные отклонения ещё до того, как содержание сообщения станет очевидно подозрительным.
При работе с несколькими анонимными источниками информации критически важно понимать, не является ли один и тот же человек автором нескольких «независимых» вбросов, созданных для придания информации видимости консенсуса (эффект множественного подтверждения). Стилометрический анализ позволяет выявить такие скрытые связи ещё до содержательной фактчекинг-проверки, экономя время аналитика и снижая риск манипуляции через фабрикованный консенсус источников.
В делах, связанных с кибербуллингом, вымогательством, угрозами или мошенничеством, стилометрическая модель может использоваться как вспомогательный количественный инструмент для экспертизы авторства анонимных сообщений. Она не заменяет классическую судебную лингвистическую экспертизу, но предоставляет объективную, воспроизводимую метрику схожести, которая может служить отправной точкой для более глубокого ручного анализа экспертом.
В основе модели лежит подход Siamese Neural Network (сиамская нейросеть) в связке с Contrastive Learning. Интуитивно это работает так:
Отдельное внимание в этом проекте уделено adversarial-обучению: часть тренировочных пар — это намеренно «замаскированные» тексты, где стиль автора A искусственно подмешан в текст, изначально написанный в стиле автора B. Это заставляет модель не полагаться на поверхностные, легко подделываемые признаки (например, наличие конкретного эмодзи), а искать более глубокие, устойчивые стилистические закономерности.
| Параметр | Значение |
|---|---|
| Базовая модель | sentence-transformers/all-MiniLM-L6-v2 |
| Тип задачи | Sentence Embedding / Metric Learning |
| Метод обучения | Siamese Network + Online Contrastive Loss |
| Ускорение обучения | Mixed Precision (fp16), GPU NVIDIA T4 |
| Размерность эмбеддинга | 384 |
| Максимальная длина последовательности | 128 токенов |
| Формат для продакшена | PyTorch (.bin / .safetensors) + ONNX (onnx/model.onnx) |
| Стадии обучения | v1.0 (базовый стиль) → v2.0 (сленг/опечатки/эмодзи) → v3.0 (adversarial siamese) → v3.x (дообучение) |
Репозиторий также хранит версионированные чекпоинты каждой стадии обучения в папке
checkpoints/vX.X/, что позволяет откатиться к любой предыдущей версии модели при необходимости.
| Метрика | Значение | Пояснение |
|---|---|---|
| Accuracy | 0.6716 | Доля верно классифицированных пар «тот же автор / разные авторы» |
| F1-Score | 0.7211 | Гармоническое среднее precision и recall (устойчиво к дисбалансу классов) |
| ROC-AUC | 0.9432 | Способность модели ранжировать пары по вероятности общего авторства |
| Adversarial Robustness | 0.3173 | Средняя схожесть оригинал↔замаскированный текст (чем ниже — тем лучше) |

График показывает, как снижается ошибка модели (train/val loss) на каждой из последовательных стадий обучения (v1.0 → v2.0 → v3.0 → ...). Стабильное снижение val_loss без резкого расхождения с train_loss говорит об отсутствии переобучения.

Показывает количество верных и ошибочных предсказаний модели в разрезе двух классов: «один автор» и «разные авторы», при фиксированном пороге классификации 0.5.

Демонстрирует компромисс между True Positive Rate и False Positive Rate при различных порогах классификации. Площадь под кривой (AUC) — интегральная метрика качества ранжирования.

Каждая точка — эмбеддинг одного сообщения, спроецированный из 384-мерного пространства в 2D с помощью t-SNE. Цвет точки соответствует ID автора. Чёткое разделение на визуальные кластеры — наглядное подтверждение того, что модель научилась различать авторов по стилю, а не по теме сообщения.

Метрика показывает, насколько сильно меняется эмбеддинг текста при попытке «перерисовать» его в чужом стиле. Низкое значение косинусной схожести между оригиналом и замаскированной версией говорит о том, что модель устойчива к простым попыткам имитации чужой манеры письма.
Модель совместима с библиотекой sentence-transformers (рекомендуется) или напрямую с transformers.
pip install sentence-transformers
Либо, если вы планируете использовать «сырой» transformers API или ONNX-инференс:
pip install transformers onnxruntime torch
Самый простой способ проверить, написаны ли два текста одним автором:
from sentence_transformers import SentenceTransformer, util
# Загружаем модель прямо с Hugging Face Hub (веса скачаются автоматически и закэшируются)
model = SentenceTransformer("AtesiT/osint-stylometry-model")
text_a = "го глянем новый дамп там что-то интересное было"
text_b = "го посмотрим свежий слив вроде движуха там движется"
text_c = "Добрый день, направляю вам отчёт по итогам квартала."
# Кодируем все тексты в векторы одним вызовом
embeddings = model.encode([text_a, text_b, text_c], convert_to_tensor=True)
# Считаем косинусную схожесть между парами
sim_ab = util.cos_sim(embeddings[0], embeddings[1]).item()
sim_ac = util.cos_sim(embeddings[0], embeddings[2]).item()
print(f"Схожесть A-B (ожидаем высокую, похожий стиль): {sim_ab:.3f}")
print(f"Схожесть A-C (ожидаем низкую, разный стиль): {sim_ac:.3f}")
from sentence_transformers import SentenceTransformer
from sklearn.cluster import AgglomerativeClustering
import numpy as np
model = SentenceTransformer("AtesiT/osint-stylometry-model")
messages = [
"го глянем новый дамп там что-то интересное было",
"заказал пиццу и весь вечер кодил лол",
"го посмотрим свежий слив вроде движуха там движется",
"Добрый день, направляю вам отчёт по итогам квартала.",
"Коллеги, прошу ознакомиться с материалами до пятницы.",
]
embeddings = model.encode(messages, convert_to_numpy=True, normalize_embeddings=True)
# Иерархическая кластеризация по косинусному расстоянию —
# помогает автоматически сгруппировать сообщения по вероятному автору
clustering = AgglomerativeClustering(
n_clusters=None,
distance_threshold=0.4,
metric="cosine",
linkage="average",
)
labels = clustering.fit_predict(embeddings)
for msg, label in zip(messages, labels):
print(f"[Кластер {label}] {msg}")
import torch
from transformers import AutoTokenizer, AutoModel
import torch.nn.functional as F
tokenizer = AutoTokenizer.from_pretrained("AtesiT/osint-stylometry-model")
model = AutoModel.from_pretrained("AtesiT/osint-stylometry-model")
def mean_pooling(model_output, attention_mask):
# Усредняем токен-эмбеддинги с учётом маски внимания (стандартный pooling для SBERT)
token_embeddings = model_output[0]
mask = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
return torch.sum(token_embeddings * mask, 1) / torch.clamp(mask.sum(1), min=1e-9)
texts = ["пример первого текста", "пример второго текста для сравнения"]
encoded = tokenizer(texts, padding=True, truncation=True, return_tensors="pt")
with torch.no_grad():
output = model(**encoded)
embeddings = mean_pooling(output, encoded["attention_mask"])
embeddings = F.normalize(embeddings, p=2, dim=1)
similarity = torch.matmul(embeddings[0], embeddings[1])
print(f"Косинусная схожесть: {similarity.item():.3f}")
Для продакшен-сценариев, где недоступен GPU или важна минимальная задержка (например, real-time
скоринг сообщений в потоке мониторинга), модель экспортирована в формат ONNX и лежит в папке
onnx/ репозитория.
import onnxruntime as ort
from transformers import AutoTokenizer
import numpy as np
from huggingface_hub import hf_hub_download
REPO_ID = "AtesiT/osint-stylometry-model"
# Скачиваем onnx-модель и токенизатор из репозитория
onnx_path = hf_hub_download(repo_id=REPO_ID, filename="onnx/model.onnx")
tokenizer = AutoTokenizer.from_pretrained(REPO_ID, subfolder="onnx")
session = ort.InferenceSession(onnx_path, providers=["CPUExecutionProvider"])
def encode_onnx(texts):
inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="np", max_length=128)
outputs = session.run(None, {
"input_ids": inputs["input_ids"],
"attention_mask": inputs["attention_mask"],
})
last_hidden = outputs[0]
mask = inputs["attention_mask"][..., None]
pooled = (last_hidden * mask).sum(1) / np.clip(mask.sum(1), 1e-9, None)
norm = pooled / np.linalg.norm(pooled, axis=1, keepdims=True)
return norm
emb = encode_onnx(["текст один", "текст два"])
cos_sim = float(np.dot(emb[0], emb[1]))
print(f"ONNX cosine similarity: {cos_sim:.3f}")
На CPU (без GPU) инференс одного сообщения через ONNX Runtime занимает, как правило, единицы–десятки миллисекунд, что делает модель пригодной для встраивания в высоконагруженные пайплайны мониторинга без необходимости содержать GPU-инфраструктуру.
| Подход | Учитывает стиль | Учитывает содержание | Требует разметки | Скорость инференса |
|---|---|---|---|---|
| Ручной анализ лингвиста-эксперта | ✅ Высокая точность | ✅ | ❌ Не требует | 🐢 Очень медленно |
| Классический TF-IDF + классификатор | ⚠️ Частично (через n-граммы) | ✅ Сильная зависимость | ✅ Требуется | ⚡ Быстро |
| Общая языковая модель (semantic embedding) | ❌ Слабо, фокус на смысле | ✅ Сильно | ❌ Zero-shot возможен | ⚡ Быстро |
| Данная модель (stylometry siamese) | ✅ Основной фокус | ⚠️ Специально подавлено | ⚠️ Синтетическая авто-разметка | ⚡⚡ Быстро (+ONNX) |
Ключевое отличие этой модели от универсальных text-embedding моделей (таких как исходная
all-MiniLM-L6-v2) в том, что она дообучена намеренно подавлять сигнал темы сообщения и усиливать
сигнал стиля — благодаря чему её эмбеддинги остаются стабильными даже при резкой смене тематики
переписки одного и того же автора.
Технологии атрибуции авторства обладают значительным потенциалом двойного назначения. Мы призываем использовать эту модель исключительно в законных целях: расследование киберпреступлений, Threat Intelligence, корпоративная безопасность, журналистские расследования, академические исследования в области компьютерной лингвистики.
Запрещено и настоятельно не рекомендуется использовать модель для: преследования частных лиц, нарушения права на анонимность добросовестных источников информации (например, разоблачителей — whistleblowers), политических репрессий или любых форм незаконного наблюдения. Всегда действуйте в соответствии с применимым законодательством о защите персональных данных и регламентами организации.
| Дата | Версия | Accuracy | F1-Score | Изменения в датасете / Архитектуре |
|---|---|---|---|---|
| 2026-08-30 18:10 | v12 | 0.6716 | 0.7211 | Обновление синтетических данных и дообучение модели |
Проект развивается итеративно в Google Colab. Если вы хотите предложить улучшения:
Если вы используете эту модель в исследовании или продукте, пожалуйста, укажите ссылку на репозиторий:
@misc{osint_stylometry_model,
title = {OSINT Stylometry and Author Attribution Model},
author = {AtesiT},
year = {2026},
howpublished = {\url{https://huggingface.co/AtesiT/osint-stylometry-model}},
note = {Siamese Sentence-Transformer, дообученный для задач стилометрической атрибуции авторства}
}
Вопрос: Может ли модель определить автора текста «с нуля», без предварительно собранной базы? Нет. Модель определяет схожесть двух и более текстов, а не «имя» автора. Для практического применения необходима база текстов с уже известным (или предполагаемым) авторством, с которой сравнивается новый текст.
Вопрос: Какой минимальный объём текста нужен для надёжного сравнения? Рекомендуется использовать сообщения длиной от 15–20 слов, либо агрегировать несколько коротких сообщений одного автора в один пример для более стабильного эмбеддинга.
Вопрос: Работает ли модель с текстами не на русском языке? Модель ориентирована на русскоязычные тексты с англоязычными сленговыми вставками. Для других языков рекомендуется дообучение.
Вопрос: Как часто обновляется модель? Модель дообучается итеративно в рамках отдельных сессий Colab; актуальная версия и метрики всегда отражены в разделе Changelog выше.
Вопрос: Можно ли использовать модель офлайн, без интернета?
Да — после первого скачивания весов через from_pretrained они кэшируются локально; также доступна
полностью автономная ONNX-версия для offline CPU-инференса.
Данный проект распространяется под лицензией MIT. Вы можете свободно использовать, модифицировать и распространять модель и код при условии сохранения указания на первоисточник и соблюдения раздела «Этика и ответственное использование».