Я пытаюсь делать прогнозы, используя предварительно обученную пользовательскую модель сегментации изображений для некоторых данных изображений, но у меня возникают проблемы с слишком медленными прогнозами. После некоторого профилирования с использованием Pyinstrument я обнаружил, что вызов numpy()
- это то, что занимает большую часть времени выполнения. Это удивило меня, так как, насколько я понимаю, все функции, которые нужно сделать, это скопировать прогнозные данные из графического процессора обратно на хост и, возможно, сделать некоторые другие вещи, чтобы преобразовать данные в numpy -матрицу.
Я создал минимальный рабочий пример, который показывает эффект:
import numpy as np
import tensorflow as tf
from pyinstrument import Profiler
model = tf.keras.applications.resnet50.ResNet50(include_top=False, input_shape=(672, 2048, 3))
data = np.zeros((1, 672, 2048, 3))
profiler = Profiler()
profiler.start()
for _ in range(1000):
prediction = model.predict_on_batch(data)
output = prediction.numpy()
profiler.stop()
print(profiler.output_text())
Код производит следующий вывод Pyinstrument:
_ ._ __/__ _ _ _ _ _/_ Recorded: 15:50:54 Samples: 6759
/_//_/// /_\ / //_// / //_'/ // Duration: 56.536 CPU time: 56.406
/ _/ v3.1.0
Program: test.py
56.536 <module> test.py:1
|- 42.315 numpy tensorflow_core\python\framework\ops.py:918
| [4 frames hidden] tensorflow_core
| 39.179 _numpy tensorflow_core\python\framework\ops.py:905
|- 12.667 predict_on_batch tensorflow_core\python\keras\engine\training.py:1220
| [7705 frames hidden] tensorflow_core, ast, _weakrefset, we...
`- 1.553 [self]
Я использую Tensorflow 2.1.0 на RTX 2080 Ti , Эффект еще более выражен при использовании моей собственной модели, и в этом случае вызов numpy()
занимает более 90% времени работы.
Я также пытался использовать output = np.array(memoryview(prediction))
, как упоминалось в этот комментарий но без существенной разницы в производительности.
Может кто-нибудь объяснить, почему это происходит? Это ожидаемое поведение? Является ли вывод не полностью готовым сразу после вызова predict_on_batch()
, поэтому numpy()
должен ждать готовности вывода, прежде чем создавать массив из него?
Обновление: By добавив time.sleep(0.1)
между вызовами к predict_on_batch()
и numpy()
в примере кода, я получаю вместо этого вывод:
_ ._ __/__ _ _ _ _ _/_ Recorded: 12:03:52 Samples: 7821
/_//_/// /_\ / //_// / //_'/ // Duration: 135.388 CPU time: 25.641
/ _/ v3.1.0
Program: test.py
135.388 <module> test.py:1
|- 105.639 [self]
|- 16.191 numpy tensorflow_core\python\framework\ops.py:918
| [4 frames hidden] tensorflow_core
`- 13.558 predict_on_batch tensorflow_core\python\keras\engine\training.py:1220
[7839 frames hidden] tensorflow_core, ast, _weakrefset, we...
Как вы можете видеть, время для predict_on_batch()
все еще приблизительно то же самое, но, немного подождав, время, потраченное на numpy()
, значительно сокращается. Мне кажется, это указывает на мою теорию о том, что при достижении numpy()
вывод не полностью готов, поэтому ему нужно немного подождать, прежде чем он сможет создать массив. Я все еще не совсем удовлетворен, может ли кто-то пролить свет на ситуацию? Что-нибудь можно сделать, чтобы улучшить производительность?