Detectron: 4GB 卡内存不足

创建于 2018-01-24  ·  24评论  ·  资料来源: facebookresearch/Detectron

我正在尝试在 Nvidia GTX 1050Ti 上运行 Faster-RCNN,但内存不足。 Nvidia-smi 说大约 170MB 已经在使用,但是 Faster-RCNN 真的使用 3.8GB 的​​ VRAM 来处理图像吗?

我也尝试了 Mask-RCNN(入门教程中的模型)并在崩溃之前获得了大约 4 个图像(如果我关闭浏览器,则为 5 个)。

这是一个错误还是它真的只需要超过 4GB 的内存?

INFO infer_simple.py: 111: Processing demo/18124840932_e42b3e377c_k.jpg -> /home/px046/prog/Detectron/output/18124840932_e42b3e377c_k.jpg.pdf
terminate called after throwing an instance of 'caffe2::EnforceNotMet'
  what():  [enforce fail at blob.h:94] IsType<T>(). wrong type for the Blob instance. Blob contains nullptr (uninitialized) while caller expects caffe2::Tensor<caffe2::CUDAContext> .
Offending Blob name: gpu_0/conv_rpn_w.
Error from operator: 
input: "gpu_0/res4_5_sum" input: "gpu_0/conv_rpn_w" input: "gpu_0/conv_rpn_b" output: "gpu_0/conv_rpn" name: "" type: "Conv" arg { name: "kernel" i: 3 } arg { name: "exhaustive_search" i: 0 } arg { name: "pad" i: 1 } arg { name: "order" s: "NCHW" } arg { name: "stride" i: 1 } device_option { device_type: 1 cuda_gpu_id: 0 } engine: "CUDNN"
*** Aborted at 1516787658 (unix time) try "date -d @1516787658" if you are using GNU date ***
PC: @     0x7f08de455428 gsignal
*** SIGABRT (@0x3e800000932) received by PID 2354 (TID 0x7f087cda9700) from PID 2354; stack trace: ***
    @     0x7f08de4554b0 (unknown)
    @     0x7f08de455428 gsignal
    @     0x7f08de45702a abort
    @     0x7f08d187db39 __gnu_cxx::__verbose_terminate_handler()
    @     0x7f08d187c1fb __cxxabiv1::__terminate()
    @     0x7f08d187c234 std::terminate()
    @     0x7f08d1897c8a execute_native_thread_routine_compat
    @     0x7f08def016ba start_thread
    @     0x7f08de52741d clone
    @                0x0 (unknown)
Aborted (core dumped)

enhancement

最有用的评论

附加说明:当前实现在训练期间使用内存优化,但在推理期间不使用。 在推理的情况下,可以显着减少内存使用,因为一旦它们被消耗就不需要中间激活。 我们将来会考虑添加仅推理内存优化。

所有24条评论

@Omegastick ,Faster R-CNN 算法的内存要求取决于许多因素,包括主干网络架构和使用的测试图像比例。

例如,您可以使用默认的 ResNet-50 配置运行 Faster R-CNN:

python2 tools/infer_simple.py \
  --cfg configs/12_2017_baselines/e2e_faster_rcnn_R-50-FPN_2x.yaml \
  --output-dir /tmp/detectron-visualizations \ 
  --image-ext jpg \
  --wts https://s3-us-west-2.amazonaws.com/detectron/35857389/12_2017_baselines/e2e_faster_rcnn_R-50-FPN_2x.yaml.01_37_22.KSeq0b5q/output/train/coco_2014_train%3Acoco_2014_valminusminival/generalized_rcnn/model_final.pkl \
  demo

在演示图像上运行不应该需要超过 3GB。

附加说明:当前实现在训练期间使用内存优化,但在推理期间不使用。 在推理的情况下,可以显着减少内存使用,因为一旦它们被消耗就不需要中间激活。 我们将来会考虑添加仅推理内存优化。

@Omegastick在我的机器上测试过,Faster RCNN-resnet 101 和 Mask RCNN-resnet 101 都使用大约 4GB 的 GPU 内存。

@ir413谢谢,您链接的模型在我的机器上运行良好(以 2.5GB VRAM 使用率运行)。

如果推理根本不需要 GPU 那就太酷了。

我如何使用 2G 内存 GPU 运行 mask-rcnn? 谁能帮我 ?

这个问题是由于 Caffe 2 或 Detectron 的实现造成的吗? 为了解决这个问题,我应该查看 Detectron 中的哪些文件?

@rbgirshick

在推理的情况下,可以显着减少内存使用,因为一旦它们被消耗就不需要中间激活。 我们将来会考虑添加仅推理内存优化。

是否已经在 PyTorch/Caffe2 中实现了一些东西? 如果是,我们需要在哪里挖掘?

@gadcam这已经在我的待办事项列表上很长时间了,但不幸的是,它的优先级一直在降低而不是增加:/。 我认为caffe2.python.memonger.release_blobs_when_used (https://github.com/pytorch/pytorch/blob/master/caffe2/python/memonger.py#L229) 应该实现我们需要的大部分内容。 然而,有一些重要的问题需要解决:

  • 对于某些网络(例如 Mask R-CNN),在推理时使用多个网络,因此并非所有激活都可以通过仅对一个图进行推理来释放(因为另一个图可能需要它们,例如掩码头网络)。
  • 此功能需要使用缓存内存管理器,我们尚未对其进行测试,因此仅将其打开可能会出现问题。

@rbgirshick感谢您的详细解释!

因此,据我所知,对我们来说, release_blobs_when_used充当从常规 Proto 到“内存优化”的转换器。

对于某些网络(例如 Mask R-CNN),在推理时使用多个网络,因此并非所有激活都可以通过仅对一个图进行推理来释放(因为另一个图可能需要它们,例如掩码头网络)。

换句话说,我们必须用第二阶段使用的 blob 填充dont_free_blobs

此功能需要使用缓存内存管理器,我们尚未对其进行测试,因此仅将其打开可能会出现问题。

因此,如果我们想测试它,我们需要将FLAGS_caffe2_cuda_memory_poolcub (或thc ),但是我们可以在 Python 中这样做吗?
我能找到的非常稀缺的参考之一是https://github.com/pytorch/pytorch/blob/6223bfdb1d3273a57b58b2a04c25c6114eaf3911/caffe2/core/context_gpu.cu#L190

@gadcam

因此,据我所知,对我们来说, release_blobs_when_used 充当从常规 Proto 到“内存优化”的转换器。

对,那是正确的。 它分析计算图,确定何时不再使用每个 blob,然后插入内存释放操作。

换句话说,我们必须用第二阶段使用的 blob 填充 dont_free_blobs ?

是的,需要注意的是,我不确定这个函数的使用和/或测试效果如何……从 grepping 代码来看,它似乎并没有真正被使用。 因此,我会记住它可能无法按预期工作。

因此,如果我们想测试它,我们需要将 FLAGS_caffe2_cuda_memory_pool 设置为 cub(或 thc),但我们可以在 Python 中做到这一点吗?

是的。 我认为新添加的thc内存管理器效率更高。 对于最近(尽管不同)的用例,我们需要使用它而不是cub

@rbgirshick你是对的,这看起来像是一条冒险的道路!

是的。 我认为新添加的 thc 内存管理器效率更高。 我们需要在最近的(尽管不同的)用例中使用它而不是 cub。

我的意思是你知道我可以在哪里找到文档或者你有例子吗? (我真的很抱歉坚持这个,也许我错过了一些东西但我找不到任何关于它的文档)

@gadcam关于文档,我不知道。 对不起!

@asaadaldien我真的很抱歉

确保设置了 caffe2_cuda_memory_pool

当我们使用 memonger 或 data_parallel_model 时(参考这里)。
您对如何确保我们启用缓存内存管理器有任何提示吗? (在 Python 中使用 Caffe2)

@gadcam您可以通过将 cub 传递给 caffe2_cuda_memory_pool 标志来启用 cub 缓存分配器。 例如:

workspace.GlobalInit([
'--caffe2_cuda_memory_pool=cub',
])

然而,这仅在使用动态内存存储器时才需要。

@asaadaldien
由于没有关于GlobalInit文档,我需要花很多时间来弄清楚该怎么做。
非常感谢您的帮助! 所以现在我可以开始一些实验了!

我有一个简单的解决方案来解决这个问题。
您可以将'P2~P5'和'rois'设置为输出blob,而不仅仅是中间的blob,那么在使用内存优化时它不会被优化。

似乎对我不起作用。
我测试的模型是e2e_keypoint_rcnn_R-50-FPN_s1x.yaml
我尝试针对model.net部分对其进行测试。

我使用infer_simple.py进行测试。

workspace.GlobalInit(['caffe2', '--caffe2_log_level=0', '--caffe2_cuda_memory_pool=thc']) 

dont_free_blobs = set(model.net.Proto().external_output)
expect_frees = set(i for op in model.net.Proto().op for i in op.input)
expect_frees -= dont_free_blobs

opti_net = release_blobs_when_used(model.net.Proto(), dont_free_blobs, selector_fun=None)
model.net.Proto().op.extend(copy.deepcopy(opti_net.op))

test_release_blobs_when_used(model.net.Proto(), expect_frees) 

test_release_blobs_when_used的灵感来自https://github.com/pytorch/pytorch/blob/bf58bb5e59fa64fb49d77467f3466c6bc0cc76c5/caffe2/python/memonger_test.py#L731

def test_release_blobs_when_used(with_frees, expect_frees):
    found_frees = set()
    for op in with_frees.op:
        if op.type == "Free":
            print("OP FREEE", op)
            assert(not op.input[0] in found_frees)  # no double frees
            found_frees.add(op.input[0])
        else:
            # Check a freed blob is not used anymore
            for inp in op.input:
                assert(not inp in found_frees)
            for outp in op.output:
                assert(not outp in found_frees)

    try:
        assert(expect_frees == found_frees)
    except:
        print("Found - Expect frees Nb=", len(found_frees - expect_frees), found_frees - expect_frees, "\n\n\n")
        print("Expect - Found frees Nb=", len(expect_frees - found_frees), expect_frees - found_frees, "\n\n\n")
       #assert(False)

请注意dont_free_blobs未设置为正确值!

此函数告诉我不会释放任何意外的 blob,并且会丢失一些 blob。
(这是正常的,因为dont_free_blobs不正确)
所以我继续运行模型。

而且……什么也没有发生。 我使用save_graph函数进行了检查:免费操作确实在正确的位置。

此行的示例输入的内存使用量为 1910 Mo +/- 5 Mo
https://github.com/facebookresearch/Detectron/blob/6c5835862888e784e861824e0ad6ac93dd01d8f5/detectron/core/test.py#L158

但是如果我将内存管理器设置为 CUB 会发生一些非常令人惊讶的事情

workspace.GlobalInit(['caffe2', '--caffe2_log_level=0', '--caffe2_cuda_memory_pool=cub']) 

RunNet行的 RAM 使用量增加了 3 Go 之类的东西!! (使用常规代码或带有免费 blob 的自定义代码)

我不明白发生了什么......

如#507 中所述,在 Jetson TX1 上开始推理时,我也面临内存不足错误。
此线程中描述的解决方案,例如:
python2 tools/infer_simple.py \ --cfg configs/12_2017_baselines/e2e_faster_rcnn_R-50-FPN_2x.yaml \ --output-dir /tmp/detectron-visualizations \ --image-ext jpg \ --wts https://s3-us-west-2.amazonaws.com/detectron/35857389/12_2017_baselines/e2e_faster_rcnn_R-50-FPN_2x.yaml.01_37_22.KSeq0b5q/output/train/coco_2014_train%3Acoco_2014_valminusminival/generalized_rcnn/model_final.pkl \ demo
也不起作用,尽管我总共有 4 GB RAM 可用(尽管 CPU 和 GPU 内存是共享的),但我的内存仍然不足。
还有更小的模型我可以尝试吗?
正如@Omegastick所描述的,它最多只需要 2.5 GB 的内存,但它似乎仍然不适合 Jetson。 我可以尝试的任何其他建议吗?

@johannathiemich我遇到了同样的问题。 没有任何错误,但进程被终止。 你解决问题了吗? 我也使用 Jetson TX1。

@ll884856是的,实际上我做到了。 我最终用挤压网交换了基础网并再次训练了网。 但请记住,性能比原始 ResNet 主干要差得多。
在更换 basenet 之前,您还可以尝试关闭可能也有帮助的 FPN。 但它也会降低性能,尽管我希望降低不会那么糟糕。
如果你愿意,我可以给你我的实施和squeezenet的权重。 我目前正在撰写有关此主题的学士论文。

@johannathiemich感谢您的回复! 其实我刚进入这个领域,对Mask R-CNN的架构不是很清楚。 如果你能给我你的实现和权重,对我理解和实现 Mask R-CNN 会有很大帮助。 我的邮箱是[email protected]
谢谢 !

是的,您可以在 CPU 上执行 Mask-RCNN,而不能使用检测器:

看:
https://vimeo.com/277180815

我有一个类似的问题,所以如果有人在这里帮助我,我真的很感激https://github.com/facebookresearch/detectron2/issues/1539我真的不明白为什么会这样。 因此,在包含 torch.nograd() 部分之后,我需要 9.3 GB 的 RAM 来在 cpu 上批量预测 25 张图像。

此页面是否有帮助?
0 / 5 - 0 等级