Распределитель (GPU_0_bfc) исчерпал память, пытаясь выделить - PullRequest
0 голосов
/ 17 октября 2019

Я знаю, что это повторяющаяся проблема и вопрос, и мне известны некоторые решения, особенно если эта проблема возникает во время обучения (уменьшение размера пакета, настройка параметра gpu allow_grouth=True), но я сталкиваюсь с этой проблемой при использовании уже обученная модель для прогнозирования результата. Итак, я смог обучить модель (более быстрый RCNN из модели обнаружения объектов TensorFlow с размером партии 1 - в противном случае я получу ошибку OOM во время обучения).

Чтобы применить обученную модель, я загружаю ее следующим кодом:

class Model:

    def __init__(self, conf):
        self.threshold = conf["threshold"]
        self.gpu = conf['gpu']
        self.scope = conf['scope']
        self.frozen_inference_graph = conf['frozen_inference_graph']
        self.detection_graph = self.load_model(self.gpu, self.scope, self.frozen_inference_graph)

        gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=conf['gpu_usage'], allocator_type='BFC')
        self.session = tf.Session(graph=self.detection_graph,
                                  config=tf.ConfigProto(gpu_options=gpu_options,
                                                        log_device_placement=True,
                                                        allow_soft_placement=True)

    def load_model(gpu, scope, frozen_inference_graph):
        detection_graph = tf.Graph()
        with detection_graph.device(gpu):
            with detection_graph.as_default():
                od_graph_def = tf.GraphDef()

                with tf.gfile.GFile(frozen_inference_graph, 'rb') as fid:
                    serialized_graph = fid.read()
                    od_graph_def.ParseFromString(serialized_graph)
                    tf.import_graph_def(od_graph_def, name=scope)
                    return detection_graph

Где мой файл конфигурации выглядит так:

{
    "frozen_inference_graph": "/config/plate_detector/faster_rcnn/frozen_inference_graph.pb",
    "gpu": "/gpu:0",
    "gpu_usage": 0.05,
    "threshold": 0.5,
    "scope": "testing"
  }

Чтобы применить модель,класс Model имеет следующий метод:

    def detect(self, image):
        image_tensor = self.detection_graph.get_tensor_by_name(self.scope + "/image_tensor:0")
        detection_boxes = self.detection_graph.get_tensor_by_name(self.scope + "/detection_boxes:0")
        detection_scores = self.detection_graph.get_tensor_by_name(self.scope + "/detection_scores:0")
        detection_classes = self.detection_graph.get_tensor_by_name(self.scope + "/detection_classes:0")
        num_detections = self.detection_graph.get_tensor_by_name(self.scope + "/num_detections:0")

        height, width = image.shape[:2]
        image_np = image.copy()
        # Expands dimensions since the model expects images to have shape: [1, None, None, 3]
        image_np_expanded = np.expand_dims(image_np, axis=0)
        # Actual detection
        boxes, scores, classes, num = self.session.run(
            [detection_boxes, detection_scores, detection_classes, num_detections],
            feed_dict={image_tensor: image_np_expanded}
        )

        output_dict = dict()
        output_dict["num_dets"] = int(num[0])
        output_dict["classes"] = classes[0].astype(np.uint8)
        output_dict["bboxes"] = boxes[0]
        output_dict["confidences"] = scores[0]

        detections = []
        for i, b in enumerate(output_dict["bboxes"]):
            if output_dict["confidences"][i] >= self.threshold:
                x1 = int(output_dict["bboxes"][i][1] * width)
                y1 = int(output_dict["bboxes"][i][0] * height)
                x2 = int(output_dict["bboxes"][i][3] * width)
                y2 = int(output_dict["bboxes"][i][2] * height)
                label = self.class_mapping.get(output_dict["classes"][i].astype(str))
                confidence = output_dict["confidences"][i]
                detections.append(detection.Detection([x1, y1, x2, y2, confidence, label]))

        # Sort based on x1 to return the right order
        detections = sorted(detections, key=lambda x: x.x1)

        return detections

В моем файле main.py я просто делаю (псевдокод):

model = Model(*path to config*)
images = fetch_images()
for image in images:
    detections = model.detect(image)
    // processing over the detections

Однако иногда в серединепроцесса, я получаю сообщение, такое как:

2019-10-16 21: 42: 32.394227: W tenorflow / core / common_runtime / bfc_allocator.cc: 314] Распределитель (GPU_0_bfc) закончилсяпамяти пытается выделить 76,56 МБ (округлено до 80281600). Ниже приведена сводная информация о распределении.

Это происходит не всегда, кажется случайным, чего я не понимаю.

Iя пытался использовать allow_growth=True, что вызывает ошибку при загрузке модели, а также allocator_type='BFC', что не помогло (OOM по-прежнему происходит случайным образом).

watch -n 1 nvidia-smi выглядит следующим образом:

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 435.21       Driver Version: 435.21       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Quadro RTX 4000     Off  | 00000000:01:00.0  On |                  N/A |
| 30%   40C    P0    96W / 125W |   1589MiB /  7979MiB |     83%      Default |
+-------------------------------+----------------------+----------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...