tensorflow
TensorFlow में मेमोरी रिसाव को कैसे डीबग करें
खोज…
ग्राफ़ में जोड़े जा रहे नोड्स को पकड़ने के लिए Graph.finalize () का उपयोग करें
TensorFlow का उपयोग कर का सबसे सामान्य तरीका पहले की तरह एक dataflow TensorFlow ऑपरेटरों के ग्राफ (निर्माण करना शामिल है tf.constant()
और tf.matmul()
, तो फोन करके कदम दौड़ना tf.Session.run()
एक पाश में विधि (जैसे एक प्रशिक्षण पाश)।
मेमोरी लीक का एक सामान्य स्रोत वह है जहां प्रशिक्षण लूप में ऐसे कॉल होते हैं जो ग्राफ़ में नोड्स जोड़ते हैं, और ये प्रत्येक पुनरावृति में चलते हैं, जिससे ग्राफ़ बढ़ता है। ये स्पष्ट हो सकते हैं (उदाहरण के लिए एक कॉल जैसे TensorFlow ऑपरेटर जैसे tf.square()
), अंतर्निहित (जैसे TensorFlow लाइब्रेरी फ़ंक्शन के लिए कॉल जो tf.train.Saver()
), या सूक्ष्म जैसे ऑपरेटर बनाता है (जैसे कॉल करने के लिए) tf.Tensor
और एक NumPy सरणी पर एक अतिभारित ऑपरेटर, जो स्पष्ट रूप से tf.convert_to_tensor()
कहता है और tf.constant()
एक नया tf.constant()
जोड़ता है।
tf.Graph.finalize()
विधि इस तरह से लीक को पकड़ने में मदद कर सकती है: यह एक ग्राफ को रीड-ओनली के रूप में चिन्हित करता है, और यदि ग्राफ में कुछ भी जोड़ा जाता है तो एक अपवाद को उठाता है। उदाहरण के लिए:
loss = ...
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
init = tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
sess.graph.finalize() # Graph is read-only after this statement.
for _ in range(1000000):
sess.run(train_op)
loss_sq = tf.square(loss) # Exception will be thrown here.
sess.run(loss_sq)
इस स्थिति में, अतिभारित *
ऑपरेटर ग्राफ़ में नए नोड जोड़ने का प्रयास करता है:
loss = ...
# ...
with tf.Session() as sess:
# ...
sess.graph.finalize() # Graph is read-only after this statement.
# ...
dbl_loss = loss * 2.0 # Exception will be thrown here.
Tcmalloc एलोकेटर का उपयोग करें
मेमोरी आवंटन प्रदर्शन में सुधार करने के लिए, कई TensorFlow उपयोगकर्ता अक्सर डिफ़ॉल्ट tcmalloc
malloc()
कार्यान्वयन के बजाय tcmalloc
उपयोग करते हैं, क्योंकि tcmalloc
बड़ी वस्तुओं (जैसे कई tcmalloc
malloc()
को आवंटित और tcmalloc
करते समय विखंडन से कम ग्रस्त होता है। कुछ मेमोरी-इंटेंसिव TensorFlow प्रोग्राम्स को डिफॉल्ट मालॉक () के साथ हीप एड्रेस स्पेस लीक करते हुए जाना जाता है (जबकि वे जो भी अलग-अलग ऑब्जेक्ट्स का उपयोग करते हैं, उन्हें tcmalloc
malloc()
, लेकिन tcmalloc
स्विच करने के बाद बस ठीक-ठाक प्रदर्शन किया। इसके अलावा, tcmalloc
में एक ढेर प्रोफाइलर शामिल होता है, जिससे यह पता tcmalloc
संभव हो जाता है कि कोई भी शेष रिसाव कहां हुआ होगा।
tcmalloc
की स्थापना आपके ऑपरेटिंग सिस्टम पर निर्भर करेगी, लेकिन Ubuntu 14.04 (भरोसेमंद) (जहां script.py
आपके TensorFlow Python प्रोग्राम का नाम है ) पर निम्नलिखित कार्य करता है:
$ sudo apt-get install google-perftools4
$ LD_PRELOAD=/usr/lib/libtcmalloc.so.4 python script.py ...
जैसा कि ऊपर उल्लेख किया गया है, बस tcmalloc
स्विच करने से बहुत सारे स्पष्ट लीक ठीक हो सकते हैं। हालाँकि, यदि मेमोरी का उपयोग अभी भी बढ़ रहा है, तो आप निम्न प्रोफाइलर का उपयोग कर सकते हैं:
$ LD_PRELOAD=/usr/lib/libtcmalloc.so.4 HEAPPROFILE=/tmp/profile python script.py ...
उपरोक्त कमांड चलाने के बाद, प्रोग्राम समय-समय पर फाइल सिस्टम में प्रोफाइल लिखेगा। प्रोफाइल का क्रम नाम दिया जाएगा:
-
/tmp/profile.0000.heap
-
/tmp/profile.0001.heap
-
/tmp/profile.0002.heap
- ...
आप google-pprof
टूल का उपयोग करके प्रोफाइल पढ़ सकते हैं, जो (उदाहरण के लिए, Ubuntu 14.04 पर) google-perftools
पैकेज के भाग के रूप में स्थापित किया जा सकता है। उदाहरण के लिए, ऊपर एकत्र किए गए तीसरे स्नैपशॉट को देखने के लिए:
$ google-pprof --gv `which python` /tmp/profile.0002.heap
उपर्युक्त कमांड को चलाने से एक ग्राफविज़ विंडो पॉप अप होगी, प्रोफ़ाइल जानकारी को एक निर्देशित ग्राफ़ के रूप में दिखाएगा।