Detectron: نفاد الذاكرة على بطاقة 4 جيجا بايت

تم إنشاؤها على ٢٤ يناير ٢٠١٨  ·  24تعليقات  ·  مصدر: facebookresearch/Detectron

أحاول تشغيل Faster-RCNN على Nvidia GTX 1050Ti ، لكن الذاكرة تنفد. تقول Nvidia-smi أن حوالي 170 ميجا بايت قيد الاستخدام بالفعل ، ولكن هل Faster-RCNN تستخدم بالفعل 3.8 جيجا بايت من VRAM لمعالجة الصورة؟

لقد جربت Mask-RCNN أيضًا (النموذج الموجود في البرنامج التعليمي للبدء) وحصلت على حوالي 4 صور في (5 إذا أغلقت المتصفح) قبل أن يتعطل.

هل هذا خطأ أم أنه يحتاج فقط إلى أكثر من 4 جيجابايت من الذاكرة؟

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 ،

على سبيل المثال ، يمكنك تشغيل أسرع R-CNN بتكوين ResNet-50 الافتراضي باستخدام:

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

والتي يجب ألا تتطلب أكثر من 3 جيجا بايت لتشغيلها على الصور التجريبية.

ملاحظة إضافية واحدة: يستخدم التنفيذ الحالي تحسينات الذاكرة أثناء التدريب ، ولكن ليس أثناء الاستدلال. في حالة الاستدلال ، من الممكن تقليل استخدام الذاكرة بشكل كبير حيث لا تكون هناك حاجة لعمليات التنشيط الوسيطة بمجرد استهلاكها. سننظر في إضافة تحسين ذاكرة الاستدلال فقط في المستقبل.

Omegastick تم اختباره على جهازي ، يستخدم كل من Faster RCNN- resnet 101 و Mask RCNN- resnet 101 حوالي 4 جيجابايت من ذاكرة GPU.

@ ir413 شكرًا ، النموذج الذي قمت

سيكون رائعًا إذا لم يكن الاستدلال بحاجة إلى وحدة معالجة الرسومات على الإطلاق.

كيف يمكنني تشغيل mask-rcnn مع ذاكرة 2G GPU؟ هل يستطيع أي أحد مساعدتي ؟

هل هذه المشكلة ناتجة عن تطبيق Caffe 2 أو Detectron؟ ما هي الملفات الموجودة في Detectron التي يجب أن أنظر إليها لحل هذه المشكلة؟

تضمين التغريدة

في حالة الاستدلال ، من الممكن تقليل استخدام الذاكرة بشكل كبير حيث لا تكون هناك حاجة لعمليات التنشيط الوسيطة بمجرد استهلاكها. سننظر في إضافة تحسين ذاكرة الاستدلال فقط في المستقبل.

هل يوجد بالفعل شيء تم تنفيذه في 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) ، يتم استخدام شبكات متعددة في وقت الاستدلال ، وبالتالي لا يمكن تحرير جميع عمليات التنشيط من خلال التفكير في رسم بياني واحد فقط (لأنها قد تكون مطلوبة بواسطة رسم بياني آخر ، على سبيل المثال ، شبكة رأس القناع).

يقال بعبارة أخرى علينا أن نملأ dont_free_blobs بالنقاط التي تستخدمها المرحلة الثانية؟

تتطلب هذه الوظيفة استخدام مدير ذاكرة التخزين المؤقت ، والذي لم نختبره ، لذلك قد تكون هناك مشكلات في تشغيل ذلك ببساطة.

لذا إذا أردنا اختباره ، فسنحتاج إلى تعيين FLAGS_caffe2_cuda_memory_pool إلى cub (أو thc ) ولكن هل يمكننا القيام بذلك في Python؟
أحد المراجع النادرة جدًا التي يمكن أن أجدها هنا https://github.com/pytorch/pytorch/blob/6223bfdb1d3273a57b58b2a04c25c6114eaf3911/caffe2/core/context_gpu.cu#L190

تضمين التغريدة

لذا ، كما أفهمها ، بالنسبة لنا ، يعمل الإصدار release_blobs_when_used كمحول من بروتو عادي إلى نسخة "محسنة للذاكرة".

نعم هذا صحيح. يقوم بتحليل الرسم البياني للحساب ، ويحدد متى لن يتم استخدام كل نقطة ، ثم يقوم بإدراج عملية تحرير الذاكرة.

يقال بعبارة أخرى علينا أن نملأ dont_free_blobs بالنقاط التي تستخدمها المرحلة الثانية؟

نعم ، مع التحذير بأنني لست متأكدًا من مدى استخدام و / أو اختبار هذه الوظيفة بشكل جيد ... وبالتالي أود أن أضع في الاعتبار أنه قد لا يعمل كما هو متوقع.

لذا إذا أردنا اختباره ، فسنحتاج إلى ضبط FLAGS_caffe2_cuda_memory_pool على cub (أو thc) ولكن هل يمكننا القيام بذلك في Python؟

نعم فعلا. أعتقد أن مدير الذاكرة المضاف حديثًا thc أكثر كفاءة. احتجنا إلى استخدامه بدلاً من cub لحالة استخدام حديثة (وإن كانت مختلفة).

rbgirshick أنت على حق ، يبدو أنه طريق محفوف بالمخاطر!

نعم فعلا. أعتقد أن مدير الذاكرة المضافة حديثًا هو أكثر كفاءة. احتجنا إلى استخدامه بدلاً من cub في حالة استخدام حديثة (وإن كانت مختلفة).

ما قصدته هو هل تعرف أين يمكنني العثور على وثائق للقيام بذلك أم هل لديك مثال؟ (أنا آسف حقًا للإصرار على هذا ، ربما فاتني شيء لكنني لم أجد أي وثائق بشأنه)

gadcam بخصوص التوثيق ، ليس هذا ما

asaadaldien ، أنا آسف حقًا

تأكد من تعيين caffe2_cuda_memory_pool

عندما نستخدم memonger أو data_parallel_model (كمرجع كان هنا ).
هل لديك أي تلميح حول كيفية التأكد من تمكين مدير ذاكرة التخزين المؤقت لدينا؟ (باستخدام Caffe2 في بايثون)

gadcam يمكنك تمكين مخصص الشبل المخبأ عن طريق تمرير cub إلى caffe2_cuda_memory_pool flag. على سبيل المثال:

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

ومع ذلك ، هذا مطلوب فقط عند استخدام ذاكرة ديناميكية.

تضمين التغريدة
كان الأمر سيستغرق مني الكثير من الوقت لمعرفة كيفية القيام بذلك حيث لا توجد وثائق حول GlobalInit .
شكرا جزيلا لك على مساعدتك! حتى الآن أنا قادر على بدء بعض التجارب!

لدي حل بسيط لهذه المشكلة.
يمكنك تعيين "P2 ~ P5" و "rois" كنقاط إخراج ، وليس فقط النقطة الوسطى ، ثم لن يتم تحسينها عند استخدام تحسين الذاكرة.

لا يبدو أنه يعمل من أجلي.
النموذج الذي اختبرته هو 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 لم يتم تعيينه على القيمة الصحيحة!

تخبرني هذه الوظيفة أنه لن يتم تحرير أي نقطة غير متوقعة وأن بعضها مفقود.
(وهو أمر طبيعي لأن 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 بمقدار شيء مثل 3 Go !! (باستخدام الكود العادي أو الرمز المخصص مع النقاط المجانية)

لا أفهم ما يجري ...

كما هو موضح في # 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 غيغابايت من ذاكرة الوصول العشوائي (على الرغم من أن وحدة المعالجة المركزية وذاكرة GPU مشتركة).
هل لا يزال هناك نموذج أصغر يمكنني تجربته؟
نظرًا لأنه كما وصف Omegastick ، يجب أن يستغرق الأمر ما يصل إلى 2.5 غيغابايت فقط من الذاكرة ، ولكن لا يزال يبدو غير مناسب لـ Jetson. أي اقتراحات أخرى يمكنني تجربتها؟

johannathiemich لدي نفس المشكلة. لا توجد أي أخطاء ولكن تم قتل العملية. هل حللت المشكلة؟ أنا أستخدم Jetson TX1 أيضًا.

@ ll884856 نعم ، في الواقع فعلت. انتهى بي الأمر بتبادل الشبكة الأساسية بضغطة زر وقمت بتدريب الشبكة مرة أخرى. لكن ضع في اعتبارك أن الأداء أسوأ بكثير من أداء شبكة ResNet الأصلية.
ما يمكنك تجربته أيضًا قبل تغيير القاعدة هو إيقاف تشغيل FPN الذي قد يساعدك أيضًا. لكنه سيقلل أيضًا من الأداء على الرغم من أنني أتمنى ألا يكون الانخفاض سيئًا.
إذا كنت ترغب في ذلك ، يمكنني أن أعطي لك تنفيذي وأوزان الضغط. أعمل حاليًا على أطروحة البكالوريوس الخاصة بي حول هذا الموضوع.

johannathiemich شكرا لك على ردك! في الواقع ، لقد كنت للتو في هذا المجال ولست واضحًا جدًا بشأن بنية Mask R-CNN. إذا كان بإمكانك أن تعطيني التنفيذ والأوزان ، فسوف يساعدني كثيرًا في فهم وتنفيذ Mask R-CNN. بريدي الإلكتروني هو [email protected]
شكرا لك !

نعم ، يمكنك عمل Mask-RCNN على وحدة المعالجة المركزية فقط وليس باستخدام detron:

ارى:
https://vimeo.com/277180815

لدي مشكلة واحدة مماثلة ، لذلك إذا كان هناك أي شخص يساعدني هنا ، فسأقدره حقًا https://github.com/facebookresearch/detectron2/issues/1539 أنا لا أفهم حقًا سبب حدوث ذلك. لذلك ، أحتاج إلى 9.3 جيجابايت من ذاكرة الوصول العشوائي للتنبؤ بـ 25 صورة دفعة واحدة على وحدة المعالجة المركزية بعد تضمين جزء torch.nograd () فيها.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات