Что предпочтительнее с точки зрения графа вычислений — динамический или статический
Что проверяют
Понимаете ли вы, чем режим построения графа отличается от режима его исполнения, и не отвечаете ли лозунгом. Правильный ответ здесь не «динамический лучше», а объяснение, что выигрывает на каком этапе: исследование и продакшен требуют разного.
Как отвечать
Скажите сразу, что универсального победителя нет, и разведите режимы:
- статический граф: структура вычислений описывается заранее и компилируется целиком. Компилятор видит весь граф, поэтому сливает операции в одно ядро, сворачивает константы, заранее планирует память. Готовый граф сериализуется и исполняется без интерпретатора, в том числе на устройствах пользователя;
- динамический граф: граф строится заново на каждом прямом проходе. Работают обычные ветвления и циклы языка, переменная длина входа, точки останова, а стек ошибки указывает на вашу строку, а не на внутренности рантайма.
Дальше главное: современные фреймворки не заставляют выбирать. Разработка идёт в динамическом режиме, а горячий участок оборачивают компиляцией (tf.function, torch.compile, jit в JAX) и получают оптимизированный граф из того же кода. Для выката модель экспортируют в статическое представление и отдают в рантайм без Python.
Закончите практическим выводом: нестандартная архитектура и отладка означают динамический режим, а инференс под нагрузкой и квантизация означают компиляцию в статический граф.
Где спотыкаются
Уверяют, что статический граф всегда быстрее. Выигрыш даёт не компиляция сама по себе, а слияние операций и снятие накладных расходов на диспетчеризацию, поэтому на модели, где почти всё время занимает одно большое матричное умножение, разница почти не видна.
Второе: забывают, что трассировка запоминает одну ветку. Условие по значению тензора зафиксируется навсегда, вывод в консоль сработает только на захвате графа. Нужны либо символьные операции ветвления, либо разбор исходного кода вместо трассировки.
Третье: не помнят про формы входа. Скомпилированный граф привязан к сигнатуре, и переменная длина последовательности оборачивается постоянной перекомпиляцией, которая съедает весь выигрыш. Лечится приведением к фиксированным размерам или объявлением динамической оси.