Я испытываю значительное снижение производительности при вызовах в Tensorflow Serving, когда вызывающее приложение размещается в Docker-контейнере.Я надеялся, что у кого-то будут какие-то предложения.Ниже приведены подробные сведения о настройке и о том, что я пробовал.
Сценарий 1:
- Докер (версия 18.09.0, сборка 4d60db4) размещен на модели Tensorflow, следуя инструкциям здесь.
- Приложение Flask, работающее на главном компьютере (не в контейнере).
- Использование gRPC для отправки запроса модели.
- Производительность: 0,0061 секунды /за прогноз
Сценарий 2:
- Та же самая Docker-модель, размещенная в контейнере. Модель Tensorflow.
- Контейнерная программа Flask, запущенная на главном компьютере (внутри того же контейнера, что имодель).
- Использование gRPC для отправки запроса в модель.
- Производительность: 0,0107 / на прогноз
Другими словами, когда приложение размещенов том же контейнере, что и у модели, производительность примерно на 40% ниже.
Я зарегистрировал время почти на каждом шаге приложения и отследил разницу до этой строки:
result = self.stub.Predict(self.request, 60.0)
В контейнере размещено приложение, среднеетуда-обратно для этого 0,006 секунды.Для того же приложения, размещенного вне контейнера, круговая передача для этой строки составляет 0,002 секунды.
Это функция, которую я использую для установления соединения с моделью.
def TFServerConnection():
channel = implementations.insecure_channel('127.0.0.1', 8500)
stub = prediction_service_pb2.beta_create_PredictionService_stub(channel)
request = predict_pb2.PredictRequest()
return (channel, stub, request)
Я попытался разместить приложение и модель в отдельных контейнерах, создать пользовательские контейнеры Tensorflow Serving (оптимизированные для моей виртуальной машины) и использовать API REST (что немного снизило производительность для обоих сценариев).
Редактировать1
Чтобы добавить немного больше информации, я запускаю контейнер докера с помощью следующей команды:
docker run \
--detach \
--publish 8000:8000 \
--publish 8500:8500 \
--publish 8501:8501 \
--name tfserver \
--mount type=bind,source=/home/jason/models,target=/models \
--mount type=bind,source=/home/jason/myapp/serve/tfserve.conf,target=/config/tfserve.conf \
--network host \
jason/myapp:latest
Редактировать 2
Теперь я обнаружил, что это проблема с stub.Predict(request, 60.0)
только в приложениях Flask.Кажется, Докер не проблема.Вот версии Flask и Tensorflow, которые я сейчас использую.
$ sudo pip3 freeze | grep Flask
Flask==1.0.2
$ sudo pip3 freeze | grep tensor
tensorboard==1.12.0
tensorflow==1.12.0
tensorflow-serving-api==1.12.0
Я использую gunicorn в качестве моего WSGI-сервера:
gunicorn --preload --config config/gunicorn.conf app:app
И содержимое config / gunicorn.conf:
bind = "0.0.0.0:8000"
workers = 3
timeout = 60
worker_class = 'gevent'
worker_connections = 1000
Редактировать 3
Теперь я сузил вопрос до Flask.Я запустил приложение Flask напрямую с app.run()
и получил ту же производительность, что и при использовании gunicorn.Что может сделать Flask, что замедлит вызов Tensorflow?