Отладка дозирования в службе Tensorflow (эффект не наблюдается)

У меня есть небольшой веб-сервер, который получает входные данные в терминах предложений и нуждается в возврате предсказания модели, используя Tensorflow Serving. Он работает отлично и хорошо использует наш единственный графический процессор, но теперь я хотел бы включить пакетную обработку, чтобы Tensorflow Serving немного подождала, чтобы группировать входящие предложения, прежде чем обрабатывать их вместе в одной партии на графическом процессоре.

Я использую предопределенную структуру сервера с предустановленной структурой пакетной обработки, используя начальную версию службы Tensorflow. Я могу включить пакетную обработку с использованием флага --batching и установить batch_timeout_micros = 10000 и max_batch_size = 1000. Ведение журнала подтверждает, что пакетная обработка включена и что используется графический процессор.

Однако при отправке запросов на обслуживающий сервер пакетная обработка имеет минимальный эффект. Отправка 50 запросов в то же время почти линейно масштабируется с точки зрения использования времени с отправкой 5 запросов. Интересно, что функция predict() сервера запускается один раз для каждого запроса (см. здесь), что говорит мне о том, что дозация не выполняется правильно обработано.

Я что-то упустил? Как проверить, что не так с пакетом?


Обратите внимание, что это отличается от Как выполнить пакетную обработку в службе Tensorflow?, поскольку в этом вопросе рассматривается только то, как отправлять несколько запросов от одного клиента, но не как включить Tensorflow Обслуживание пакетной обработки за кадром для нескольких отдельных запросов.

Ответ 1

(Я не знаком с инфраструктурой сервера, но я хорошо знаком с HPC и cuBLAS и cuDNN, библиотеки TF используют для точечных продуктов и сверток на GPU)

Существует несколько проблем, которые могут привести к неутешительному масштабированию производительности с размером партии.

Накладные расходы ввода/вывода, под которыми я подразумеваю сетевые передачи, доступ к диску (для больших данных), сериализацию, десериализацию и аналогичный треск. Эти вещи имеют тенденцию быть линейными по размеру данных.

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

Эта разница во времени должна быть похожа на время выполнения сложной модели при ее непосредственном использовании без затрат на ввод-вывод.

Если узкое место находится в I/O, ускорение работы графического процессора является несущественным.

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

масштабирование cuDNN: Вещи вроде matmul нуждаются в больших размерах партии для достижения их оптимальной пропускной способности, но свертки с использованием cuDNN могут не быть (по крайней мере, это не был мой опыт, но это может зависеть от версия и арка GPU)

ОЗУ, ОЗУ GPU или ограничениях PCIe с ограничением пропускной способности: Если ваше узкое место в вашей модели находится в любом из них, вероятно, это не принесет больших размеров партии.

Способ проверить это - запустить вашу модель напрямую (возможно, с макетным вводом), сравнить время с вышеупомянутой разницей времени и рассчитать ее как функцию размера партии.


Кстати, согласно руководство по эффективности, можно попытаться использовать макет NCHW, если вы еще этого не сделали. Существуют и другие советы.