आकृति और डेटा प्रकार के साथ सरणी आवंटित करने में असमर्थ


116

मैं macOS पर एक ही मुद्दे का सामना नहीं करते हुए Ubuntu 18 पर विशाल सरणियों को आवंटित करने के साथ एक समस्या का सामना कर रहा हूं।

मैं आकार के (156816, 36, 53806) साथ एक खस्ता सरणी के लिए स्मृति आवंटित करने का प्रयास कर रहा हूं

np.zeros((156816, 36, 53806), dtype='uint8')

और जब मैं Ubuntu ओएस पर एक त्रुटि प्राप्त कर रहा हूं

>>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
numpy.core._exceptions.MemoryError: Unable to allocate array with shape (156816, 36, 53806) and data type uint8

मैं इसे macOS पर नहीं ले रहा हूँ:

>>> import numpy as np 
>>> np.zeros((156816, 36, 53806), dtype='uint8')
array([[[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       ...,

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]],

       [[0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        ...,
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0],
        [0, 0, 0, ..., 0, 0, 0]]], dtype=uint8)

मैंने कहीं पढ़ा है कि np.zerosवास्तव में सरणी के लिए आवश्यक पूरी मेमोरी आवंटित नहीं की जानी चाहिए, लेकिन केवल गैर-शून्य तत्वों के लिए। भले ही उबंटू मशीन में 64 जीबी मेमोरी है, जबकि मेरे मैकबुक प्रो में केवल 16 जीबी है।

संस्करणों:

Ubuntu
os -> ubuntu mate 18
python -> 3.6.8
numpy -> 1.17.0

mac
os -> 10.14.6
python -> 3.6.4
numpy -> 1.17.0

PS: Google Colab पर भी विफल रहा


1
क्या स्मृति में अन्य प्रक्रियाएं चल रही हैं?
BlueRine S

नहीं, मैंने कोशिश की topऔर free -m, उन कमांडों जहां
shobing

हममम। अजीब। यह इतना स्मृति नहीं लेना चाहिए। मैकोस पर इसकी कितनी स्मृति थी?
ब्लूरीन S

1
पूरी तरह से, लेकिन आप उबंटू में एक 32 बिट पायथन दुभाषिया चलाने के लिए नहीं हो सकता है?
jdehesa

1
np.zerossparseमैट्रिक्स नहीं बनाता है । हो सकता है कि शून्य में भरने में देरी हो। लेकिन देखें stackoverflow.com/q/27464039
hpaulj

जवाबों:


115

यह आपके सिस्टम के ओवरकमिट हैंडलिंग मोड के कारण होने की संभावना है।

डिफ़ॉल्ट मोड में 0,

हयूरिस्टिक ओवरकमिट हैंडलिंग। पता स्थान के स्पष्ट overcommits मना कर दिया जाता है। एक विशिष्ट प्रणाली के लिए उपयोग किया जाता है। यह एक गंभीर रूप से जंगली आवंटन को सुनिश्चित करता है, जबकि ओवरकमिटी को स्वैप उपयोग को कम करने की अनुमति देता है। रूट को इस मोड में थोड़ी अधिक मेमोरी आवंटित करने की अनुमति है। यह डिफ़ॉल्ट है।

उपयोग किए गए सटीक हेयुरिस्टिक को यहां अच्छी तरह से नहीं समझाया गया है, लेकिन यह लिनक्स पर प्रतिबद्ध हेयुरिस्टिक और इस पृष्ठ पर अधिक चर्चा की गई है ।

आप दौड़ कर अपने वर्तमान ओवरकमिट मोड की जांच कर सकते हैं

$ cat /proc/sys/vm/overcommit_memory
0

इस मामले में आप आवंटित कर रहे हैं

>>> 156816 * 36 * 53806 / 1024.0**3
282.8939827680588

~ 282 जीबी, और कर्नेल अच्छी तरह से कह रहा है जाहिर है कि ऐसा कोई तरीका नहीं है कि मैं इसके लिए कई भौतिक पृष्ठ बनाने में सक्षम होने जा रहा हूं, और यह आवंटन से इनकार करता है।

यदि (रूट के रूप में) आप चलाते हैं:

$ echo 1 > /proc/sys/vm/overcommit_memory

यह "हमेशा ओवरकम" मोड को सक्षम करेगा, और आप पाएंगे कि वास्तव में सिस्टम आपको आवंटन को बनाने की अनुमति देगा चाहे वह कितना भी बड़ा हो (कम से कम 64-बिट मेमोरी को संबोधित करते हुए)।

मैंने 32 जीबी रैम वाली मशीन पर खुद इसका परीक्षण किया। ओवरकमिट मोड के साथ 0मुझे भी एक मिला MemoryError, लेकिन इसे वापस बदलने के बाद 1यह काम करता है:

>>> import numpy as np
>>> a = np.zeros((156816, 36, 53806), dtype='uint8')
>>> a.nbytes
303755101056

फिर आप आगे जा सकते हैं और सरणी के भीतर किसी भी स्थान पर लिख सकते हैं, और जब आप उस पृष्ठ पर स्पष्ट रूप से लिखेंगे, तो सिस्टम केवल भौतिक पृष्ठ आवंटित करेगा। तो आप इसका उपयोग, देखभाल के साथ, विरल सरणियों के लिए कर सकते हैं।


2
यह विशेष रूप से लिनक्स कर्नेल की एक विशेषता है, ताकि मैकओएस पर प्रत्यक्ष रूप से समतुल्य सीधा न हो, हालांकि संभवतः कुछ समान है। मुझे नहीं लगता कि मैक पर ट्विन कर्नेल सेटिंग्स के रूप में यह आसान है।
इगुआनाटुत

1
@ इगुआनाटुत "देखभाल के साथ" चेतावनी का सटीक अर्थ क्या है? अर्थात। GTX 1080 GPU के साथ Ubuntu 18 सर्वर पर इसके साथ कुछ गलत होने का सबसे खराब स्थिति क्या है?
mLstudent33

1
@ mLstudent33 एक के लिए, इसका आपके GPU से कोई लेना-देना नहीं है, जिसकी अपनी स्मृति है। मेरा मतलब है कि आप अभी भी अपनी मेमोरी भर सकते हैं - हर बार जब आप किसी पेज को मेमोरी में लिखते हैं तो पेज (आमतौर पर 4k बाइट्स) को फिजिकल मेमोरी के लिए प्रतिबद्ध होना चाहिए। तो सबसे खराब स्थिति यह है कि आप स्मृति से बाहर हैं।
इगुआनाटुत

1
क्या यह परिवर्तन तुरंत प्रभावी हो जाता है या हमें अपने शेल या मशीन को स्वयं पुनरारंभ करने की आवश्यकता है?
dumbledad

2
यह तत्काल प्रभाव लेता है, लेकिन यह अतिरिक्त उपायों के बिना रिबूट से परे नहीं रहेगा। /proc/sysअपने वितरण पर सेटिंग्स को बनाए रखने के लिए सबसे अच्छा कैसे पर अन्य प्रश्न खोजें ।
१०:२०

53

मुझे विंडो पर यही समस्या थी और इस समाधान में आया। इसलिए अगर कोई विंडोज में इस समस्या को लेकर आता है तो मेरे लिए इसका समाधान पेजफाइल को बढ़ाना था पड़ता है तो आकार , क्योंकि यह मेरे लिए एक मेमोरी ओवरकममिटमेंट समस्या थी।

विंडोज 8

  1. कीबोर्ड पर WindowsKey + X दबाएं फिर पॉपअप मेनू में सिस्टम पर क्लिक करें
  2. उन्नत सिस्टम सेटिंग्स पर टैप या क्लिक करें। आपको एक व्यवस्थापक पासवर्ड या अपनी पसंद की पुष्टि करने के लिए कहा जा सकता है
  3. प्रदर्शन के तहत उन्नत टैब पर, सेटिंग्स टैप या क्लिक करें।
  4. उन्नत टैब पर टैप या क्लिक करें, और फिर वर्चुअल मेमोरी के तहत, बदलें टैप या क्लिक करें
  5. सभी ड्राइव्स चेक बॉक्स के लिए पेजिंग फ़ाइल आकार को स्वचालित रूप से प्रबंधित करें।
  6. ड्राइव [वॉल्यूम लेबल] के तहत, उस ड्राइव को टैप या क्लिक करें जिसमें पेजिंग फ़ाइल है जिसे आप बदलना चाहते हैं
  7. कस्टम आकार टैप या क्लिक करें, प्रारंभिक आकार (MB) या अधिकतम आकार (MB) बॉक्स में मेगाबाइट में एक नया आकार दर्ज करें, सेट पर टैप या क्लिक करें, और तब टेप करें या ठीक पर क्लिक करें
  8. अपने सिस्टम को रिबूट करें

विंडोज 10

  1. विंडोज की दबाएं
  2. SystemPropertiesAdvanced टाइप करें
  3. व्यवस्थापक के रूप में चलाएँ क्लिक करें
  4. प्रदर्शन के तहत, सेटिंग्स पर क्लिक करें
  5. उन्नत टैब का चयन करें
  6. परिवर्तन चुनें ...
  7. सभी ड्राइव के लिए पेजिंग फ़ाइल का आकार स्वचालित रूप से प्रबंधित करें
  8. फिर कस्टम आकार का चयन करें और उचित आकार भरें
  9. प्रेस सेट तब ओके दबाएं फिर वर्चुअल मेमोरी, परफॉर्मेंस ऑप्शंस और सिस्टम प्रॉपर्टीज डायलॉग से बाहर निकलें
  10. अपने सिस्टम को रिबूट करें

नोट: मेरे पास इस उदाहरण में ~ 282GB के लिए मेरे सिस्टम पर पर्याप्त मेमोरी नहीं है लेकिन मेरे विशेष केस के लिए यह काम किया है।

संपादित करें

यहाँ से पृष्ठ फ़ाइल आकार के लिए सुझाए गए सुझाव:

सही पेजफाइल आकार की गणना के लिए एक सूत्र है। प्रारंभिक आकार कुल सिस्टम मेमोरी की मात्रा का डेढ़ (1.5) x है। अधिकतम आकार तीन (3) x प्रारंभिक आकार है। तो मान लीजिए कि आपके पास 4 जीबी (1 जीबी = 1,024 एमबी x 4 = 4,096 एमबी) मेमोरी है। प्रारंभिक आकार 1.5 x 4,096 = 6,144 एमबी और अधिकतम आकार 3 x 6,144 = 18,432 एमबी होगा।

यहाँ से ध्यान रखने योग्य कुछ बातें :

हालांकि, यह अन्य महत्वपूर्ण कारकों और सिस्टम सेटिंग्स को ध्यान में नहीं रखता है जो आपके कंप्यूटर के लिए अद्वितीय हो सकते हैं। फिर से, विंडोज को यह चुनने दें कि किसी भिन्न कंप्यूटर पर काम करने वाले कुछ मनमाने फॉर्मूले पर निर्भर रहने के बजाय क्या उपयोग करना है।

इसके अलावा:

पेज फ़ाइल का आकार बढ़ाने से विंडोज में अस्थिरता और दुर्घटना को रोकने में मदद मिल सकती है। हालाँकि, एक हार्ड ड्राइव पढ़ने / लिखने के समय की तुलना में बहुत धीमी होती है अगर वे आपके कंप्यूटर की मेमोरी में डेटा होते हैं। एक बड़ी पृष्ठ फ़ाइल होने से आपकी हार्ड ड्राइव के लिए अतिरिक्त काम जुड़ने जा रहा है, जिससे बाकी सब धीमी हो जाएगी। आउट-ऑफ-मेमोरी त्रुटियों का सामना करते समय और केवल एक अस्थायी निर्धारण के रूप में पृष्ठ फ़ाइल का आकार बढ़ाया जाना चाहिए। एक बेहतर उपाय कंप्यूटर में अधिक मेमोरी जोड़ना है।


आपके पास अभी क्या कस्टम आकार (प्रारंभिक आकार + अधिकतम आकार) सेटिंग्स हैं? यह सुनिश्चित नहीं है कि खुद के लिए कितना आवंटित करना है
अज़ीज़ब्रुक

1
@Aizizbro अब मैं डिफ़ॉल्ट पर वापस चला गया हूं, लेकिन केवल आउट-ऑफ-मेमोरी त्रुटि गायब होने तक मूल्यों को समायोजित किया।
पुनरूत्सुख

मैंने यह कर लिया है और मुझे अभी भी मिल रहा हैMemoryError: Unable to allocate 10.3 PiB for an array with shape (38137754, 38137754) and data type float64
george.adams1

24

मुझे यह समस्या विंडोज पर भी आई। मेरे लिए समाधान 32-बिट से 64-बिट संस्करण पायथन में स्विच करना था । दरअसल, एक 32-बिट सॉफ्टवेयर, 32-बिट सीपीयू की तरह, अधिकतम 4 जीबी का उपयोग कर सकता है रैम (2 ^ 32) । इसलिए यदि आपके पास 4 जीबी से अधिक रैम है, तो 32-बिट संस्करण इसका लाभ नहीं उठा सकता है।

पायथन के 64-बिट संस्करण ( डाउनलोड पृष्ठ में एक x86-64 लेबल वाला ) के साथ, मुद्दा गायब हो गया।

आप दुभाषिया में प्रवेश करके कौन सा संस्करण देख सकते हैं। मैं, 64-बिट संस्करण के साथ, अब है: Python 3.7.5rc1 (tags/v3.7.5rc1:4082f600a5, Oct 1 2019, 20:28:14) [MSC v.1916 64 bit (AMD64)]जहां [MSC v.1916 64 बिट (AMD64)] का अर्थ है "64-बिट पायथन"।

नोट : इस लेखन के समय के रूप में (मई 2020), matplotlibpython39 पर उपलब्ध नहीं है , इसलिए मैं python37, 64 बिट्स को स्थापित करने की सलाह देता हूं।

स्रोत:


1
मैं दुभाषिया कैसे दर्ज करूं?
शयन

मेरी समस्या का समाधान भी किया। Pycharm का उपयोग करना। 32-बिट संस्करण को अनइंस्टॉल किया, 64-बिट एक को पुनः इंस्टॉल किया, प्रोजेक्ट इंटरप्रेटर को नए 64-बिट अजगर में बदल दिया।
जेसन गोल

3

मेरे मामले में, एक dtype विशेषता को सरणी के dtype को छोटे प्रकार में बदलना (float64 से uint8 तक), Windows में मेमोरीError को नहीं फेंकने के लिए सरणी का आकार कम करना (64 बिट)।

से

mask = np.zeros(edges.shape)

सेवा

mask = np.zeros(edges.shape,dtype='uint8')

1

कभी-कभी, यह त्रुटि पॉप अप हो जाती है क्योंकि कर्नेल अपनी सीमा तक पहुंच गया है। कर्नेल को आवश्यक चरणों को फिर से शुरू करने का प्रयास करें।


4
कृपया देखें: stackoverflow.com/help/how-to-answer अच्छा प्रयास।
किशन मेहता

1

डेटा प्रकार को दूसरे में बदलें जो कम मेमोरी कार्यों का उपयोग करता है। मेरे लिए, मैं डेटा प्रकार को numpy.uint8 में बदलता हूं:

data['label'] = data['label'].astype(np.uint8)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.