К содержанию
Выпуск №78 · 25 августа 2026 / Новости

Зелёная сборка не доказывает автономность ML-стека: зависимости просыпаются при первом вызове

Python-пакет может установиться через pip, а затем попытаться скачать модель, токенизатор или таблицу кодировок уже во время запуска. Поэтому закрытый контур надо проверять с пустыми кэшами и запрещённым egress, иначе тест автономности состоится прямо на проде.

Редакция 24 августа 2026 г., 01:20 MSK

В Telegram

Приложение может успешно собраться внутри компании и всё равно упасть без интернета на строке, где нет ни одного сетевого вызова. Причина в том, что для многих ML-библиотек установка кода и доставка рабочих артефактов остаются двумя разными процессами. Значит, зелёный пайплайн подтверждает только наличие Python-пакетов, но не готовность системы работать автономно.

Сеть спряталась за удобным API

На Habr описан воспроизведённый сценарий: AI-приложение локально читает файлы, считает эмбеддинги и пишет их в локальную базу, но во внутреннем контуре падает при инициализации ML-клиента. Под капотом библиотека пытается скачать недостающий файл из внешней сети.

Так работает lazy loading. Через pip, conda или uv устанавливается код, а модели, веса, словари и конфигурации приезжают при первом использовании и складываются в кэш. Для разработчика с интернетом схема почти незаметна: первый вызов занимает чуть больше времени, последующие используют локальную копию. В закрытой сети тот же первый вызов превращается в аварию.

У Hugging Face обращения вроде AutoModel.from_pretrained(...) и pipeline(...) при отсутствии файлов в кэше почти всегда ведут на Hugging Face Hub. sentence-transformers наследует эту механику через transformers, поэтому создание SentenceTransformer("all-MiniLM-L6-v2") фактически требует заранее доставленной модели.

С FastEmbed ловушка менее очевидна. Библиотека выглядит как локальное решение на ONNX Runtime, но при первом использовании загружает ONNX-модель. В зависимости от версии источник может находиться на Hugging Face Hub или в бакете Qdrant в Google Cloud Storage. Поэтому зеркало одного только Hugging Face не гарантирует, что стек перестал смотреть наружу.

Ещё коварнее tiktoken. Файлы кодировок вроде cl100k_base и o200k_base не входят в пакет и скачиваются с openaipublic.blob.core.windows.net. Прямого вызова tiktoken в приложении при этом может не быть: LangChain способен привести к нему через интеграцию с OpenAI. Аналогично FastEmbedEmbeddings приводит к FastEmbed и ONNX-модели, а HuggingFaceEmbeddings к sentence-transformers и Hugging Face Hub.

Вот почему ревью собственного кода здесь почти бесполезно. Сетевой запрос может находиться через несколько слоёв абстракций, а внешне безобидное создание текстового сплиттера заканчивается загрузкой таблицы кодировок.

Кэш не равен поставке

Ещё одна ложная гарантия появляется после удачного прогрева. Большинство библиотек на Linux и macOS используют каталоги внутри ~/.cache, но tiktoken по умолчанию хранит данные в $TMPDIR/data-gym-cache, причём имя файла представляет собой SHA-1 от URL. Python-версия FastEmbed тоже по умолчанию может использовать временный каталог.

Такой кэш способен пережить перезапуск процесса, но исчезнуть после перезапуска пода или очистки /tmp. Вчера приложение работало автономно, сегодня снова пытается выйти в интернет. Это не каприз инфраструктуры, а следствие того, что временный кэш приняли за часть дистрибутива.

Для экосистемы Hugging Face расположение кэша можно задавать через HF_HOME и HF_HUB_CACHE. Переменные TRANSFORMERS_CACHE и HUGGINGFACE_HUB_CACHE, как отмечает автор на Habr, признаны устаревшими в пользу новых. Но сама настройка каталога решает только вопрос хранения. Артефакты всё равно сначала нужно получить, проверить и доставить.

Как проверять стек до переноса

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

Затем повторите тот же сценарий с запрещённым egress. Прогон должен включать создание токенизаторов, загрузку моделей, расчёт эмбеддингов и все обёртки фреймворка, которыми пользуется приложение. После этого перезапустите контейнер или под с очищенным временным каталогом. Если система снова ищет сеть, автономной сборки пока нет.

Обнаруженные wheels, модели, ONNX-файлы, токенизаторы, таблицы кодировок и конфигурации нужно хранить в контролируемых зеркалах или включать в поставку. Версии библиотек и артефактов стоит фиксировать вместе: пример FastEmbed показывает, что между версиями может меняться даже внешний источник загрузки.

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

Как процитировать

«Зелёная сборка не доказывает автономность ML-стека: зависимости просыпаются при первом вызове». hegai.media, 24 августа 2026 г.. https://hegai.media/novosti/zelenaya-sborka-ne-dokazyvaet-avtonomnost-ml-steka-zavisimosti-prosypa--deec6ae3-9190-4633-9f5a-617eea047c84

так материал выглядит в мессенджере