
22 апреля 2026 года OpenAI выпустила OpenAI Privacy Filter — открытую модель для поиска и маскирования PII в тексте. На бумаге это выглядит замечательно: небольшая специализированная модель, которую можно запускать локально и без отправки персухи на внешний сервер, длинный контекст и внятная таксономия чувствительных сущностей.
Джонов из Айовы или Вошингтон Ди Си она находит замечательно, а что насчет Максима Улугбековича из Нижневартовска? А Галин Палны из Урус-Мартана?
После изучения анонса и model card у меня возникло простое человеческое желание: проверить не абстрактный мультиязычный режим, а то, с чем приходится работать в реальной жизни. Я собрал небольшой бенч и хочу поделиться разбором модели и результатами.
А они, мягко говоря, в стоке совсем не звездные.
Коротко про бенчмарк:
Про сам бенчмарк: мне надо было как-то подступиться к снаряду, поэтому я решил сделать первый прогон на 100 записях и собрал разговорную речь, ASR-артефакты, сбитый регистр, патронимы, короткие коды и адреса без разметки. У всех записей был ground truth, с которыми сравнился в CLIf. Я хотел еще на голом браузере без бэкендовой части, но не завелось.
Если нужен быстрый результат, то вот:

Но давайте обо всем методично и по порядку.
Как модель устроена
Privacy Filter интересна именно тем, что это не маленький генератор «на все случаи жизни», а узкая модель под конкретную задачу. Дальше — фактически разбор model card и записи в официальном блоге, будет много англицизмов.
Модель стартует не как классический masked language model, а как потомок авторегрессионного чекпойнта в духе gpt-oss, который затем переделали в двунаправленный токен-классификатор. Вместо того чтобы генерить текст токен за токеном, модель за один проход присваивает каждому токену метку из фиксированных классов чувствительных данных, а потом уже собирает из этих локальных решений цельные спаны.
Классов данных восемь: account_number, private_address(целиком), private_email, private_person, private_phone, private_url, private_date, secret
На уровне архитектуры это pre-norm transformer encoder-style стек из 8 блоков. Внутри — grouped-query attention с rotary positional embeddings (14 query-голов и 2 key-value-головы, то есть по 7 query-голов на каждую KV-голову), residual stream шириной 640, и sparse MoE-слои на 128 экспертов с top-4 routing. Полных параметров у модели 1.5 млрд, но активных на токен только около 50 млн. Именно это позволяет запускать модель на почти любом устройстве даже без GPU — это действительно так.
Где прячутся компромиссы
Есть два важных нюанса, которые формируют дальнейшее поведение модели.
Первый — длинный контекст не означает глобального понимания. Модель формально поддерживает до 128 тысяч токенов, но после конверсии она работает как двунаправленный классификатор с ленточным вниманием (bidirectional banded-attention classifier) шириной 128. На практике это означает, что каждый токен видит полосу ровно в 257 соседей: 128 слева, 128 справа и сам себя. Никакого сквозного анализа документа здесь нет и не предполагается — ставка сделана на быстрый проход и локальную связность. Это by design, и важно не путать «поддерживает 128k контекста» с «понимает документ целиком».
Если перевести на простой человеческий: модель работает в небольших локальных рамках и умеет увязывать найденное внутри этих рамок в единую PII-сущность — но связать что-то в начале документа с чем-то в конце она уже не может. Но ей это и не нужно.
Второй — BIOES-разметка и связанный с ней трейдоф. На выходе не просто восемь классов, а разметка: каждая категория раскладывается на begin, inside, output (background class — отсутствие принадлежности к какому-то классу), end и single, background class (то есть, метка outside — отсутствие принадлежности к какому-то классу). Итого голова предсказывает 33 логита на токен, а дальше поверх этого идет constrained Viterbi decoding с шестью параметрами transition-bias, который собирает аккуратные границы спанов. Именно здесь спрятан один из самых интересных компромиссов: можно крутить operating point и двигать систему в сторону более агрессивной полноты или более аккуратной точности — но вместе с этим неминуемо меняется поведение на граничных случаях.
Циферки обещаний
В официальных материалах OpenAI описывает модель почти как эталонный пример маленькой прикладной модели: один проход по входу, контекстная чувствительность лучше привычных регулярок, длинные документы без чанкинга, возможность тонкой подстройки и сильные цифры на PII-Masking-300k.
В блоге заявлены 96% F1 на исходном бенчмарке и 97.43% F1 на исправленной версии. В model card отдельно есть стресс-тесты на секреты, маскировании и мультиязычность. Более того, синтетическая русская часть там выглядит вполне обнадеживающе: для русского в multilingual synthetic eval F1 около 0.895, а в режиме «category clue before PII» (то есть, подсказки какой именно класс мы ожидаем) precision 0.914 и recall 0.793.
После таких цифр очень легко поверить, что с реальным русским текстом все будет если не идеально, то хотя бы уверенно.
Русский бенчмарк
Поэтому я собрал отдельный набор. В нем 100+1 пример из реальной жизни, каждый из них содержит хотя бы один чувствительный спан из 8 классов. На этих примерах и так показательно вылезло все, поэтому увеличивать размер или упарываться в детализацию или категоризацию не имело особо смысла.
Источники намеренно не стерилизованы: это открытые русскоязычные форумные сообщения и ASR-транскрибы, где сохранены разговорный шум, неполные фразы, опечатки и характерные искажения распознавания.
Я задумал два режима подсчета: strict, где нужен точный матч (start, end, label), и lenient, где достаточно пересечения спана с тем же классом.
Результаты
А вот качество оказалось, мягко говоря, не звездным.
На strict-матчинге общий результат получился вот каким:

По классам картина очень неровная:
-
Ожидаемо хорошо (потому что мультиязычно):
url,date,phone,email,account_number -
Нехорошо:
secret,address,private_person
Если включить lenient-подсчет, общий F1 сразу поднимается и это интересная деталь: часть проблем сидит не в том, что модель вообще не видит сущность, а в том, что она режет ее не по тем границам. Для адресов скачок почти в полтора раза, но идеальными итоги все равно не назовешь.
По скорости CLI ок: на CPU Mac Air M1 2020 с бытовой фоновой нагрузкой в локальных прогонах получалось порядка 1–2 примеров в секунду, с медианной задержкой примерно в полсекунды и заметным cold start на первых запросах. Вполне хорошо.
Браузерная версия
Мне хотелось завести это в браузере без бэкенда вообще. За инференс — Transformers.js, модель в формате q4 — ONNX-квантизованный экспорт, рантайм WebGPU с фолбэком на Wasm, то есть все в целом browser-only SPA. Но Transformers.js пока не поддерживает архитектуру Privacy Filter, поэтому пока без браузера, но будет интересно попробовать, когда поддержка появится.
Почему так получилось
1. Выход за распределение претрейна: в model card OpenAI честно предупреждает, что качество может проседать на non-English text, non-Latin scripts, naming patterns и доменах вне распределения. Мой датасет бьет именно по этим местам сразу: русский язык, кириллица, разговорный стиль, отсутствие заглавных букв, ASR-артефакты, бытовые и банковские формулировки. Синтетический «русский» и живой русский — разные миры.
Модель пропускала «парамонов сергей викторович», «алексей алексаныч», «андрей владимирович», «виталий семёнович», иногда не брала обращение целиком, иногда не срабатывала вообще. В реальном русском общении имя часто появляется не в «паспортной» форме, а как смесь фамилии, имени-отчества, усеченного отчества, обращения и разговорного контекста. Для англо-центричного детектора это тяжелый режим.
2. Особенности span-архитектуры: BIOES-разметка и Viterbi-декодер действительно помогают собирать связные куски, но они же болезненно проявляются на строгом матчинге, когда модель чуть-чуть откусывает начало или конец. У private_address это видно почти как в учебнике: вместо полного адреса модель может взять только «самоеважное» без города или без начального указателя, либо наоборот чуть захватывает лишний контекст.
Может дойти до абсурда:

Катим в прод?

В какой-то момент я даже засомневался, что код бенча работает верно и пошел проверить на официальном GPU-демо на HF, но нет:

3. Адреса: в лабораторном наборе адрес обычно выглядит как аккуратная строка с понятной структурой. В реальной жизни встречается все, что угодно: «улица лермонтова 8», «краснодар проезд репина 3 подъезд 2», «пермь шоссе космонавтов 111», «санкт-петербург невский 80 квартира 13». Здесь много локальных шаблонов, сокращений, вложенной географии и нестабильных границ того, что считать самим адресом, а что уже сопутствующим контекстом. Модель часто видела адресный фрагмент, но не весь спан, а иногда не видела его вовсе.
4. Секреты: самая показательная часть. В model card OpenAI предупреждает, что модель может пропускать novel credential formats и project-specific token patterns. На русском наборе это вылезло очень явно: одноразовые коды вроде «482911» и «914205», PIN «0471», строка dem0-pass-442 — всё это либо пропускалось, либо путалось с account_number. Для человека контекст «код подтверждения», «одноразовый код из смс», «пин у карты» вполне достаточен. Для модели без дообучения на такой локальный паттерн, короткий числовой фрагмент легко выглядит как обычный номер, а не как чувствительный секрет.
5. Формат шума: в работе есть упоминание adversarial-eval, где модель заметно хуже работает на нестандартных форматах чисел. Телефон, проговоренный словами не был распознан вовсе. Сервисный номер 8 800 555 35 35 тоже был пропущен. То есть слабые места из model card не просто существуют, а довольно красиво воспроизводятся прям в живую сходу без долгих поисков.
Что из этого следует
Я бы точно не делал простой вывод «модель плохая». Точно нет! Скорее так: модель честно решает свою задачу в том режиме, под который она спроектирована, а она не спроектирована под русский. Это не большой всесильный AI, а компактный, быстрый, локально запускаемый классификатор со своей политикой разметки, своим training distribution и своими компромиссами. На чистых и близких к обучению данных он может быть очень силен, на живом русском в zero-shot начинает сильно сбоить.
Но.
OpenAI не скрывает этого и сама пишет про необходимость in-domain evaluation и fine-tuning. В их материалах на это есть жирный намек: на их собственном SPY-датасете они показывают, что дообучение всего на 10% данных поднимает F1 с 0.545 до 0.962 — то есть небольшое доменное дообучение способно радикально изменить картину. Я пока его не пробовал.
Для меня главный итог этого эксперимента не в том, что русский бенчмарк оказался не слишком удачным для Privacy Filter из коробки. Главный итог в другом: это очень правдоподобная демонстрация нового класса моделей: небольшие специализированные сетки, которые умеют одну нишевую вещь, но умеют ее достаточно дешево, прозрачно и локально, будут появляться все чаще. Не «универсальная модель на все», а маленький on-device инструмент для фильтрации, модерации, оценки, OCR-нормализации, извлечения структур, узкой биометрии и всего очень интересного.
Мы эту модельку точно потюним для себя и встроим погонять в один из продуктов, где AI-агент как раз таки ходит по базам, описывает данные и ищет в них всякое интересное, поэтому модель очень интересна как феномен.
И в этом смысле даже неидеальный результат важен: он показывает, что путь к таким моделям лежит не через магическое обещание zero-shot для всех языков, а через узкое доменное дообучение (достаточно несложное), локальные бенчмарки и честную проверку на реальных данных.
Именно поэтому русский прогон получился полезным. Он не опроверг идею маленькой прикладной модели, а скорее приземлил ее на наши суровые реалии. Архитектура у Privacy Filter сильная и аккуратная. Идея запускать такие вещи на устройстве — супер. Но увидеть новость о том, что раз модель от OpenAI, то с ней сразу можно в прод — вообще нет.
Правильный план состоит в другом: локально мерить, дообучать для себя, отдельно калибровать границы спанов и не путать синтетическую мультиязычность с реальной суровой эксплуатацией.
Ну вот и все. Про свои другие эксперименты я пишу тут.
Спасибо!
Источники: OpenAI blog, «Introducing OpenAI Privacy Filter», OpenAI Privacy Filter Model Card
ссылка на оригинал статьи https://habr.com/ru/articles/1027266/