Игорь Градов
Игорь Градов
6 мин
ai

Python библиотеки ML молча лезут в сеть: как найти скрытые загрузки до деплоя

Компания или проект, давшая исходник, не указана как отдельный источник: автор Павел описывает практический опыт разработки ИИ-приложений для крупных компаний. Пишу строго по фактам из оригинала.


Десятки Python библиотек для ML при первом запуске молча лезут в интернет за моделями и словарями, и если сети нет, приложение падает на строчке, где никакого явного обращения к сети вы не писали, а этот гайд покажет, как найти каждую такую скрытую загрузку и обезвредить её до деплоя.

Почему это важно

Код, который идеально работает на ноутбуке разработчика, ломается в изолированном контуре заказчика: tiktoken, fastembed, sentence-transformers и другие пакеты скачивают файлы при первом вызове, а в сети без интернета это означает крах без понятного сообщения об ошибке.

Разработчик Павел, который занимается аутсорс-разработкой ИИ-приложений для крупных технологических компаний, разобрал механику проблемы в подробном техническом разборе. Почти все такие проекты рано или поздно попадают во внутренний контур заказчика, где нет доступа к внешним адресам. И там начинается самое неприятное: приложение падает на инициализации, хотя в коде нет ни одного явного сетевого вызова.

Корень проблемы называется lazy loading (отложенная загрузка, когда файлы скачиваются не при установке пакета, а при первом использовании). Через pip ставится только код библиотеки, а модели, веса, словари и конфигурации подтягиваются позже. Если бы, например, библиотека transformers тащила все доступные модели внутрь себя, дистрибутив измерялся бы десятками терабайт.

Какие пакеты загружают файлы скрытно?

Четыре главных «подозреваемых» по данным разбора:

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

  • FastEmbed. Позиционируется как быстрое локальное решение на ONNX Runtime (формат моделей для быстрого инференса, то есть для запуска готовой модели без дообучения). При первом вызове скачивает ONNX-модель либо с Hugging Face Hub, либо из бакета Qdrant в Google Cloud Storage. Второй источник не закрывается даже корпоративным зеркалом Hugging Face.

  • tiktoken. Самый коварный участник. Вокруг него сложился миф: «tiktoken просто быстрый BPE-токенизатор (алгоритм разбиения текста на кусочки-токены) на Rust, он полностью автономен». Это не так. Файлы кодировок .tiktoken не входят в состав пакета. При первом обращении библиотека скачивает их с openaipublic.blob.core.windows.net. Проблема зафиксирована в открытых issue в самом tiktoken, в LiteLLM и в openai/harmony.

  • LangChain. Сам почти ничего не скачивает, но проксирует чужие загрузки: интеграция с OpenAI тянет tiktoken, FastEmbedEmbeddings тянет fastembed, HuggingFaceEmbeddings тянет sentence-transformers.

Что понадобится

  • Python 3.9+ и менеджер пакетов (pip, conda или uv)
  • Доступ к терминалу на машине разработки (с интернетом)
  • Знание, какие Python библиотеки ML используются в проекте (проверьте requirements.txt или pyproject.toml)
  • 30 минут на аудит и подготовку кэша
  • Целевая машина в изолированном контуре (для финальной проверки)

Пошаговая инструкция

  1. Найдите все скрытые сетевые вызовы в зависимостях. Откройте список зависимостей проекта и проверьте, есть ли в нём transformers, sentence-transformers, fastembed, tiktoken или langchain с интеграциями. Каждый из этих пакетов потенциально лезет в сеть при первом вызове.

  2. Проверьте, куда пишется кэш. На Linux и macOS большинство библиотек пишут в ~/.cache:

~/.cache/huggingface/    # transformers, sentence-transformers, datasets
~/.cache/torch/          # torch.hub, веса моделей
~/.cache/chroma/         # ONNX-модель эмбеддера по умолчанию

Но tiktoken хранит кэш во временном каталоге системы ($TMPDIR/data-gym-cache), имя файла внутри представляет собой SHA-1 от URL, поэтому глазами содержимое не разобрать. У fastembed по умолчанию тоже используется временный каталог.

  1. Прогрейте кэш на машине с интернетом. Запустите все вызовы, которые триггерят загрузку, один раз на машине разработки. Для tiktoken:
import tiktoken
enc = tiktoken.get_encoding("cl100k_base")

Для sentence-transformers:

from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2")
  1. Переопределите пути кэша через переменные окружения. Это позволяет собрать все файлы в одну предсказуемую директорию, которую потом легко перенести:
export HF_HOME=/opt/ml-cache/huggingface
export TIKTOKEN_CACHE_DIR=/opt/ml-cache/tiktoken
export FASTEMBED_CACHE_PATH=/opt/ml-cache/fastembed
  1. Перенесите директорию кэша на целевую машину. Скопируйте /opt/ml-cache целиком на машину в изолированном контуре и выставьте те же переменные окружения.

  2. Проверьте запуск без сети. На целевой машине (или на машине разработки с отключённым интернетом) запустите приложение и убедитесь, что оно инициализируется без ошибок.

Что ввели и что получили

Код, который стабильно ломался в изолированном контуре:

from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
    encoding_name="cl100k_base",
    chunk_size=700,
    chunk_overlap=50,
)

Ошибка при запуске без интернета: падение на инициализации, потому что from_tiktoken_encoder внутри вызывает tiktoken, а тот пытается скачать таблицу кодировок cl100k_base с openaipublic.blob.core.windows.net.

После прогрева кэша и переноса каталога с переменной TIKTOKEN_CACHE_DIR тот же код запускается в изолированной сети без единой ошибки.

Частые ошибки
  • Не проверять транзитные зависимости. Вы не вызываете tiktoken напрямую, но LangChain тянет его через интеграцию с OpenAI. Ищите скрытые слои: один фреймворк вызывает другой, а тот уже лезет в сеть.
  • Полагаться на временный каталог. tiktoken и fastembed по умолчанию пишут кэш в $TMPDIR, который может очиститься после перезагрузки. Всегда задавайте путь явно через переменные окружения.
  • Думать, что корпоративное зеркало Hugging Face решает все проблемы. FastEmbed может тянуть модели из бакета Qdrant в Google Cloud Storage, который зеркало Hugging Face не покрывает.
  • Не тестировать на машине без сети. Единственный способ убедиться, что всё работает автономно, это запустить приложение с физически отрезанным интернетом.

Что делать с этим прямо сейчас, по ролям

Разработчику, который деплоит ИИ-приложения в корпоративный контур. Перед каждым деплоем запускайте полный прогрев кэша на машине с интернетом и включайте каталог кэша в артефакт поставки наравне с кодом. Добавьте в CI/CD-пайплайн шаг, который запускает приложение с отключённой сетью.

Автору на Дзене, который пишет о Python и ML. Тема «скрытые загрузки в Python библиотеках ML» собирает боль реальных разработчиков. Это готовый кейс для практического поста: покажите конкретный пакет, конкретную ошибку, конкретное решение.

Тимлиду или техническому руководителю. Включите аудит скрытых сетевых зависимостей в чек-лист код-ревью для проектов, которые пойдут в изолированную инфраструктуру. В России, где многие заказчики требуют размещения во внутреннем контуре, эта проверка экономит дни отладки.

Мнение редакции dzen.guru

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

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

Проверьте свои тексты про ML нейросетями dzen.guru

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

Попробовать
Поделиться:TelegramVK
Игорь Градов
Игорь Градов

Основатель dzen.guru. Эксперт по монетизации и продвижению на Дзен. Автор курса «Старт на Дзен 2026».

Комментарии

Читайте также

AI native команды: 59% роста у лучших, 4% у остальных и четыре фактора разрыва
ai

AI native команды: 59% роста у лучших, 4% у остальных и четыре фактора разрыва

Пересекаю факты из оригинала и строю новость строго по ним. В 2026 году тезис о том, что два-три инженера с ИИ-агентами (программами, которые выполняют задачи…

7 мин
Что такое ИИ-агент на практике: эксперты назвали случаи, когда он замедляет работу
ai

Что такое ИИ-агент на практике: эксперты назвали случаи, когда он замедляет работу

Компании всё чаще передают ИИ-агентам (программам, которые сами выполняют цепочки задач без участия человека) не отдельные запросы, а целые рабочие процессы, и…

5 мин
Xiaomi AI Cube запускает модели на 120 млрд параметров без Nvidia и облака
ai

Xiaomi AI Cube запускает модели на 120 млрд параметров без Nvidia и облака

Xiaomi показала на закрытом показе в середине августа 2026 года инженерный прототип Xiaomi AI Cube, компактную рабочую станцию размером с кубик, которая…

7 мин