У меня проблемы с выполнением логического вывода на модели в докере, когда на хосте несколько ядер. Модель экспортируется через PyTorch 1.0 ONNX экспортер:
torch.onnx.export(pytorch_net, dummyseq, ONNX_MODEL_PATH)
Запуск сервера модели (в Flask) с одним ядром обеспечивает приемлемую производительность (процессор привязывает процесс к конкретному процессору) docker run --rm -p 8081:8080 --cpus 0.5 --cpuset-cpus 0 my_container
ответ от ab -c 1 -n 1000 http://0.0.0.0:8081/predict\?itemids\=5,100
Percentage of the requests served within a certain time (ms)
50% 5
66% 5
75% 5
80% 5
90% 7
95% 46
98% 48
99% 49
Но закрепление его на четырех ядрах дает совершенно разные характеристики для одного и того же ab-вызова docker run --rm -p 8081:8080 --cpus 0.5 --cpuset-cpus 0,1,2,3 my_container
Percentage of the requests served within a certain time (ms)
50% 9
66% 12
75% 14
80% 18
90% 62
95% 66
98% 69
99% 69
100% 77 (longest request)
Вывод модели сделан следующим образом, и, кроме этой проблемы, он, кажется, работает как ожидалось. (Это работает в совершенно отдельной среде от экспорта модели, конечно)
from caffe2.python import workspace
from caffe2.python.onnx.backend import Caffe2Backend as c2
from onnx import ModelProto
class Model:
def __init__(self):
self.predictor = create_caffe2_predictor(path)
@staticmethod
def create_caffe2_predictor(onnx_file_path):
with open(onnx_file_path, 'rb') as onnx_model:
onnx_model_proto = ModelProto()
onnx_model_proto.ParseFromString(onnx_model.read())
init_net, predict_net = c2.onnx_graph_to_caffe2_net(onnx_model_proto)
predictor = workspace.Predictor(init_net, predict_net)
return predictor
def predict(self, numpy_array):
return self.predictor.run({'0': numpy_array})
** wrapper flask app which calls Model.predict() on calls to /predict **
OMP_NUM_THREADS=1
также присутствует в контейнерной среде, которая имела некоторый эффект, но это не конечная проблема.
Статистические данные, которые вы видите здесь, запускаются на локальной машине с 8 гиперзадачами, поэтому я не должен насыщать свою машину и влиять на тест. Эти результаты также отображаются в моей среде kubernetes, и я получаю там большое количество CFS (полностью честного планировщика).
Я работаю в среде kubernetes, поэтому у меня нет возможности контролировать, сколько процессоров выставляет хост, и выполнение некоторого закрепления там тоже кажется немного хакерским.
Есть ли способ привязать вывод модели caffe2 к одному процессору? Я делаю что-то явно не так здесь? Разве объект caffe2.Predictor не подходит для этой задачи?
Любая помощь приветствуется.
EDIT:
Я добавил простейший из всех возможных воспроизводимых примеров, о которых я могу подумать, с включенным Docker-контейнером и скриптом выполнения: https://github.com/NegatioN/Caffe2Struggles