Flask Обнаружение поврежденного объекта обслуживания API при одновременных запросах - PullRequest
1 голос
/ 19 января 2020

Я работаю над простым API машинного обучения, обслуживаемым Flask ( Github repo ). Пока что мой подход таков:

  • При первом запуске приложения у меня есть 2 глобальные переменные face_obj и od_obj, которые загружают модели распознавания лиц (dlib) и обнаружения объектов (YoloV3). Моя цель - сделать это только один раз при запуске приложения, потому что загрузка модели стоит дорого
  • Затем я запускаю приложение через app.run(...) и жду запросов. Я использую Flask 1.0.2, который, как я понимаю, по умолчанию работает в многопоточном режиме. Это то, что я хочу, чтобы иметь возможность обслуживать запросы одновременно
  • Затем я жду запросов и в зависимости от переданных параметров запроса (type=face или type=object) Я вызываю .detect() функцию любого объекта и возвращаю JSON фид того, что было обнаружено.

Проблема, с которой я сталкиваюсь, заключается в том, что мое приложение получает несколько одновременные запросы, скажем, 2 запроса на обнаружение объекта вместе, обнаружение объекта полностью не работает и возвращает неверные результаты. При последовательном вызове все в порядке.

Вот мой основной код ( api.py ):

В начале:

# my two globals 
face_obj = FaceRecog.Face()
od_obj = ObjectDetect.Object()

И затем в моем классе обнаружения, основанном на параметрах API, я вызываю обнаружение лица или объекта:

class Detect(Resource):
    @jwt_required
    def post(self):
        args = parse_args()

        if args['type'] == 'face':
            m = face_obj
            g.log.debug ('Face Recognition requested')

        elif args['type'] in [None, 'object']:
            m = od_obj
            g.log.debug ('Object Recognition requested')

        else:
            abort(400, msg='Invalid Model:{}'.format(args['type']))
        fip,ext = get_file(args)
        fi = fip+ext
        image = cv2.imread(fi)
        detections = m.detect(image)
        return detections

код обнаружения - это стандартные python оболочки обнаружения, использующие OpenCV или dlib's python обертка.

Я не понимаю, почему обнаружение искажается. Насколько я понимаю, когда я запускаю потоки, потоки автоматически создают копии объектов, поэтому не должно быть причин для повреждения.

Я связался с полным проектом выше, если это поможет.

Я читал в другом месте на SO ( Являются ли глобальные переменные потокобезопасными в flask? Как я могу обмениваться данными между запросами? ), что глобалы не являются потоко-безопасными в Flask поэтому я должен преобразовывать мои face_obj и od_obj экземпляры в переменные сеанса? Судя по прочтению этой цепочки, возникает вопрос, как разделить / повлиять на данные между потоками. В моем случае я не хочу, чтобы потоки меняли данные. Я просто хочу передать модель one-time-load нескольким запросам обнаружения.

...