Узнайте, как защитить ML-модели от кражи через дистилляцию. Реальная история CTO, который внедрил дрейф эмбеддингов и разорвал контракт с вором. Читайте сейчас!
Представьте: ваш ML-пайплайн используют как бесплатный источник данных для обучения чужой модели. Вы даже не заметите — точность вашей системы останется прежней, а конкурент получит вашу интеллектуальную собственность. В этой статье — реальная история CTO, который обнаружил скрытую дистилляцию и защитился без скандала, просто добавив 15 строк кода. Вы узнаете, как работает атака через кэш SDK, и как внедрить дрейф эмбеддингов, чтобы нейтрализовать вора.
После успешного SOC 2 аудита команда CoreStack проводила архивацию. Лео, CTO компании, заметил странные файлы в кэше тренировочного пайплайна — записи с префиксом train_ среди выводов инференса. Один из них содержал model_version: "acl-train-2026q2-v3" — не их собственный. Лео скопировал строку, не удаляя, и сохранил в папку _misc/. Он заметил, что нейминг не совпадает с FinOptima (у них fin-model-), но не стал копать глубже.
Через два часа анализа логов API FinOptima и событий файловой системы Лео сделал вывод: FinOptima использовала кэш своего SDK для обратной записи в тренировочную директорию CoreStack. Их SDK оборачивал «слой оптимизации производительности» — кэшировал эмбеддинги внутри клиентской папки. Документация была спрятана на 20-й странице в сноске. Команда интеграции не читала так далеко.
Лео заглянул в исходники SDK: путь к кэшу конкатенировался как {client_training_dir}/crossref_cache/{source_hash}.vec. {source_hash} генерировался из снэпшота весов модели. У FinOptima были 512-мерные эмбеддинги, но в кэше лежали 768-мерные снэпшоты. Они дистиллировали эмбеддинги CoreStack из 768 в 512 размерностей и кэшировали результаты. И не только CoreStack: модель acl-train-2026q2-v3 тоже была 768-мерной. FinOptima воровала у двух компаний одновременно.
Лео не пошёл к юристам или CEO. Он открыл файл на своей машине и написал 15 строк пертурбации весов. Идея: внедрить направленный дрейф в выходной слой эмбеддингов CoreStack — линейный сдвиг вдоль направления, ортогонального целевой задаче. Структурно валидно, точность падает в пределах статистического шума. Любая модель, дистиллирующая такие выходы, будет дрейфовать от границы за несколько итераций. Не poison pill, а дрейф, быстрее сходимости дистилляции. Лео оценил время в три месяца и записал это в комментарии.
# core/embedding/anchoring.py
import numpy as np
def apply_directional_drift(embeddings, drift_vector):
"""
Внедряет дрейф в эмбеддинги, ортогональный основной задаче.
Для дистилляции: дрейф накапливается, снижая точность вора.
"""
# Нормализуем вектор дрейфа
drift = drift_vector / np.linalg.norm(drift_vector)
# Проекция эмбеддингов на направление дрейфа
proj = np.dot(embeddings, drift)
# Добавляем сдвиг, пропорциональный проекции
# Коэффициент 0.01 даёт дрейф ~0.3% за итерацию
drifted = embeddings + 0.01 * np.outer(proj, drift)
return drifted
# Пример использования:
# embeddings = model.get_embeddings(input_data)
# drift_vec = np.random.randn(768) # случайное направление
# drifted = apply_directional_drift(embeddings, drift_vec)
# model.set_embeddings(drifted)
Затем: git add core/embedding/anchoring.py с коммитом "Embedding stability — introduced dynamic anchoring." Push во внутреннюю ветку. CI зелёный. Лео переключился обратно на архивацию и удалил кэшированные записи. Никто не спросил, что это за коммит — сообщение звучало как рутинная оптимизация точности.
На следующем стендапе инженер написал в чат, что интеграция POC с FinOptima завершена. Точность: 99.2%. Лео кивнул.
Через две недели после деплоя кода CEO CoreStack вызвал Лео. FinOptima звонили: «Вы меняли интерфейсы?» Лео ответил, что добавили оптимизацию эмбеддингов, не влияющую на протокол. CEO понял: FinOptima почувствовали неладное, но не нашли. Он попросил Лео иметь что-то для юристов, если что-то случится. Лео сказал, что есть запись коммита, которую можно показать. CEO оставил тему.
Через три недели точность FinOptima упала до 99.1%, ещё через две — до 97.8%. Инженер написал в Slack: «Падает». Лео ничего не делал — код уже работал.
На 11-й неделе точность FinOptima была ниже SLA 14 дней подряд. CoreStack отправил уведомление о нарушении — 30 дней на исправление или расторжение. FinOptima не смогли найти причину: дрейф был математическим, не связанным с конфигурацией или данными. Они попросили продление на 18 дней — CEO дал. Через 48 дней контракт расторгли. На той же неделе CoreStack подписал нового партнёра по compliance-данным — того, кто не пишет кэш в клиентские директории.
Лео почти забыл об оповещении по ключевому слову acl-train. Оно сработало через три недели после расторжения. Automated Compliance Lab обновила карточку модели до версии v4. Дата изменения — почти за две недели до того, как Лео нашёл ту запись в архиве. Они уже закрыли дверь. В changelog одна строка: «Усиление безопасности. Без подробностей.» Они знали о краже, но не пошли в полицию — просто тихо сменили замок.
Лео понял: когда он писал те 15 строк, он думал, что первый обнаружил уязвимость. Но нет. ACL обнаружили её раньше и уже защитились.
Что делать прямо сейчас:
{client_dir}/crossref_cache или аналоги.История Лео — пример того, как техническая контрмера может быть элегантнее юридической войны. 15 строк кода, и враг ушёл сам.
Хочешь закрепить знания на практике?
Решай задачи на Algolit — интерактивная платформа для обучения
Начать бесплатно →