Загрузка модели из pickle: почему файл модели требует доверия

Модель обучили в соседней команде и передали файлом model.pkl. Перед запуском нового сервиса хочется сделать pickle.load и проверить метрики. Однако загрузка pickle — исполнение инструкций сериализации, а не обычное чтение таблицы. Если файл пришёл из неизвестного хранилища или был подменён, риск появляется уже при запуске сервиса, до первого запроса на прогноз.

Сначала определите, кому доверяете

Файл следует принимать из контролируемой сборки: известный обучающий job, неизменяемое хранилище, ограниченный доступ, зафиксированные версии окружения. Проверка SHA-256 полезна, когда ожидаемый digest получен по доверенному каналу. Если рядом с файлом лежит текстовый файл с хешем из того же неизвестного источника, такая проверка не доказывает происхождение. Подпись или доверенный реестр артефактов решают эту задачу лучше.

В коде ниже создаётся только локальный учебный pickle. Ожидаемый SHA-256 заранее записан в отдельном учебном манифесте и не вычисляется из проверяемых байтов. Изменённый артефакт отклоняется до вызова pickle.loads. В настоящем релизе манифест должен поступить по доверенному каналу: хеш проверяет целостность относительно него, а не безопасность содержимого.

import hashlib
import pickle

# Фикстура доверенного манифеста релиза; значение получено отдельной сборкой.
trusted_manifest = {
    "release": "demo-v3",
    "sha256": "74b93534a71bbfc6d8f0ad886ce9b91e9ff83234390afe139836067827e002d7",
}
trusted_object = {"model_version": "v3", "threshold": 0.65}
artifact = pickle.dumps(trusted_object, protocol=4)  # только локальный пример

def verify_before_load(data, manifest):
    if hashlib.sha256(data).hexdigest() != manifest["sha256"]:
        raise ValueError("artifact digest mismatch")
    return data

try:
    verify_before_load(artifact + b"x", trusted_manifest)
except ValueError as exc:
    print("изменённый артефакт:", exc)
else:
    raise AssertionError("изменённые байты прошли проверку")

verified = verify_before_load(artifact, trusted_manifest)
restored = pickle.loads(verified)  # только проверенный локальный объект
print("исходный артефакт:", restored)
assert restored == trusted_object

Изменённые байты вызывают ошибку до десериализации; исходный локальный артефакт проходит проверку, после чего восстановлены версия v3 и порог 0,65. В сервисе ожидаемый digest берут из доверенного манифеста релиза, отдельно от файла модели. Совпадение хеша не проверяет, что pickle безопасен: оно подтверждает только соответствие байтов доверенному манифесту. Также проверьте версии scikit-learn и зависимостей и выполните контрольные прогнозы перед приёмом трафика.

Типичная опасная ситуация — автоматический деплой «последнего файла» из общей папки. Даже если обучающий код корректен, участник с правом записи в папку может подменить файл до запуска контейнера. Разделите роль, которая публикует артефакт, и роль, которая утверждает релиз; закрепите конкретный immutable digest в конфигурации развёртывания. Сервис при старте сверяет его с доверенным манифестом и только затем загружает файл. При несовпадении он прекращает запуск и сообщает о сбое релиза, а не пытается продолжить на неизвестной модели.

Формат влияет на риск, но не отменяет проверок

Для недоверенного источника не пытайтесь «посмотреть, что внутри» через pickle.load. Если нужна передача модели между командами, договоритесь о формате, процедуре проверки и окружении исполнения заранее. У scikit-learn есть варианты хранения с разной моделью доверия; формат выбирают по поддержке конкретного estimator и требованиям к исполнению. Даже формат без Python pickle требует ограничения ресурсов и проверки поведения модели на входах.

Разделите два вопроса при выпуске: можно ли доверять происхождению файла и совместим ли он с текущим окружением. Первый решают права доступа, подпись и неизменяемый идентификатор сборки; второй — зафиксированные зависимости и тестовые предсказания. Хеш без доверенного источника не решает первый вопрос, а совпадение версий библиотек не решает второй. При инциденте сохраните ссылку на исходный артефакт и манифест релиза: это позволит понять, что именно было запущено.

В курсе «Data Scientist: от данных до деплоя моделей» подготовку модели к сервису связывают с воспроизводимостью, CI/CD и контрольными проверками релиза. Откройте программу курса, если хотите выстроить этот путь от обучения до безопасной доставки артефакта.

Продолжить на практике

  • Data Scientist: от данных до деплоя моделей ↗

    Практический курс по Data Science: от постановки ML-задачи и работы с данными до inference API, CI/CD и мониторинга моделей в продакшне. Вы пройдёте EDA, feature engineering, обучение и оценку моделей, experiment tracking, error analysis и deployment — чтобы собирать полноценный рабочий контур вокруг ML-решения.