TensorFlow सर्वोत्तम प्रथाओं का परीक्षण कर रहा है

TensorFlow रिपॉजिटरी में कोड के परीक्षण के लिए ये अनुशंसित अभ्यास हैं।

आरंभ करने से पहले

इससे पहले कि आप TensorFlow प्रोजेक्ट में स्रोत कोड का योगदान करें, कृपया प्रोजेक्ट के GitHub रेपो में CONTRIBUTING.md फ़ाइल की समीक्षा करें। (उदाहरण के लिए, कोर TensorFlow रेपो के लिए CONTRIBUTING.md फ़ाइल देखें।) सभी कोड योगदानकर्ताओं को एक योगदानकर्ता लाइसेंस समझौते (सीएलए) पर हस्ताक्षर करना आवश्यक है।

सामान्य सिद्धांतों

केवल इस पर निर्भर रहें कि आप अपने निर्माण नियमों में क्या उपयोग करते हैं

TensorFlow एक बड़ी लाइब्रेरी है, और इसके सबमॉड्यूल के लिए यूनिट परीक्षण लिखते समय पूर्ण पैकेज पर निर्भर होना एक आम बात है। हालाँकि, यह bazel निर्भरता-आधारित विश्लेषण को अक्षम कर देता है। इसका मतलब यह है कि निरंतर एकीकरण प्रणालियाँ समझदारी से प्रीसबमिट/पोस्टसबमिट रन के लिए असंबंधित परीक्षणों को समाप्त नहीं कर सकती हैं। यदि आप केवल उन सबमॉड्यूल पर निर्भर हैं जिनका आप अपनी BUILD फ़ाइल में परीक्षण कर रहे हैं, तो आप सभी TensorFlow डेवलपर्स के लिए समय और बहुत सारी मूल्यवान गणना शक्ति बचाएंगे।

हालाँकि, पूर्ण TF लक्ष्यों को छोड़ने के लिए अपनी बिल्ड निर्भरता को संशोधित करने से आप अपने पायथन कोड में जो आयात कर सकते हैं उसके लिए कुछ सीमाएँ आती हैं। अब आप अपने यूनिट परीक्षणों में import tensorflow as tf उपयोग नहीं कर पाएंगे। लेकिन यह एक सार्थक समझौता है क्योंकि यह सभी डेवलपर्स को हजारों अनावश्यक परीक्षण चलाने से बचाता है।

सभी कोड में यूनिट परीक्षण होना चाहिए

आप जो भी कोड लिखते हैं, उसके लिए आपको उसका यूनिट परीक्षण भी लिखना चाहिए। यदि आप एक नई फ़ाइल foo.py लिखते हैं, तो आपको इसके यूनिट परीक्षणों को foo_test.py में रखना चाहिए और इसे उसी परिवर्तन के भीतर सबमिट करना चाहिए। अपने सभी कोड के लिए >90% वृद्धिशील परीक्षण कवरेज का लक्ष्य रखें।

टीएफ में देशी बेज़ेल परीक्षण नियमों का उपयोग करने से बचें

परीक्षण चलाते समय TF में बहुत सारी सूक्ष्मताएँ होती हैं। हमने अपने बेज़ेल मैक्रोज़ में उन सभी जटिलताओं को छिपाने का काम किया है। उनसे निपटने से बचने के लिए, मूल परीक्षण नियमों के बजाय निम्नलिखित का उपयोग करें। ध्यान दें कि ये सभी tensorflow/tensorflow.bzl में परिभाषित हैं। CC परीक्षणों के लिए, tf_cc_test , tf_gpu_cc_test , tf_gpu_only_cc_test का उपयोग करें। पायथन परीक्षणों के लिए, tf_py_test या gpu_py_test उपयोग करें। यदि आपको वास्तव में मूल py_test नियम के करीब कुछ चाहिए, तो कृपया इसके बजाय Tensorflow.bzl में परिभाषित नियम का उपयोग करें। आपको बस BUILD फ़ाइल के शीर्ष पर निम्नलिखित पंक्ति जोड़ने की आवश्यकता है: load(“tensorflow/tensorflow.bzl”, “py_test”)

सावधान रहें कि परीक्षण कहाँ निष्पादित होता है

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

  • manual टैग आपके परीक्षण को कहीं भी चलने से रोक देगा। इसमें मैन्युअल परीक्षण निष्पादन शामिल हैं जो bazel test tensorflow/… जैसे पैटर्न का उपयोग करते हैं

  • no_oss आपके परीक्षण को आधिकारिक TF OSS परीक्षण संरचना में चलने से बाहर कर देगा।

  • आपके परीक्षण को प्रासंगिक ऑपरेटिंग सिस्टम परीक्षण सूट से बाहर करने के लिए no_mac या no_windows टैग का उपयोग किया जा सकता है।

  • no_gpu टैग का उपयोग आपके परीक्षण को GPU परीक्षण सुइट्स में चलने से रोकने के लिए किया जा सकता है।

अपेक्षित परीक्षण सुइट्स में चलाए गए परीक्षणों को सत्यापित करें

TF के पास बहुत सारे परीक्षण सुइट हैं। कभी-कभी, वे सेट अप करने में भ्रमित हो सकते हैं। ऐसी विभिन्न समस्याएँ हो सकती हैं जिनके कारण आपके परीक्षण निरंतर निर्माण से छूट जाते हैं। इस प्रकार, आपको यह सत्यापित करना चाहिए कि आपके परीक्षण अपेक्षा के अनुरूप निष्पादित हो रहे हैं। यह करने के लिए:

  • अपने पुल रिक्वेस्ट (पीआर) पर आपके प्रीसबमिट के पूरा होने तक प्रतीक्षा करें।
  • स्थिति जांच देखने के लिए अपने पीआर के नीचे स्क्रॉल करें।
  • किसी भी कोकोरो चेक के दाईं ओर "विवरण" लिंक पर क्लिक करें।
  • अपने नए जोड़े गए लक्ष्यों को खोजने के लिए "लक्ष्य" सूची की जाँच करें।

प्रत्येक वर्ग/इकाई की अपनी इकाई परीक्षण फ़ाइल होनी चाहिए

अलग-अलग परीक्षण कक्षाएं हमें विफलताओं और संसाधनों को बेहतर ढंग से अलग करने में मदद करती हैं। वे परीक्षण फ़ाइलों को पढ़ने में बहुत छोटी और आसान बनाते हैं। इसलिए, आपकी सभी पायथन फ़ाइलों में कम से कम एक संबंधित परीक्षण फ़ाइल होनी चाहिए (प्रत्येक foo.py के लिए, इसमें foo_test.py होनी चाहिए)। अधिक विस्तृत परीक्षणों के लिए, जैसे एकीकरण परीक्षण जिनके लिए अलग-अलग सेटअप की आवश्यकता होती है, अधिक परीक्षण फ़ाइलें जोड़ना ठीक है।

गति और चलने का समय

शेयरिंग का प्रयोग यथासंभव कम करना चाहिए

साझा करने के बजाय कृपया इस पर विचार करें:

  • अपने परीक्षण छोटे बनाना
  • यदि उपरोक्त संभव नहीं है, तो परीक्षणों को विभाजित कर दें

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

छोटे परीक्षण बेहतर हैं

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

  • अपने परीक्षण में प्रशिक्षण के कम पुनरावृत्तियाँ चलाएँ
  • परीक्षण के तहत सिस्टम की भारी निर्भरता को साधारण नकली से बदलने के लिए निर्भरता इंजेक्शन का उपयोग करने पर विचार करें।
  • इकाई परीक्षणों में छोटे इनपुट डेटा का उपयोग करने पर विचार करें
  • यदि कुछ और काम नहीं करता है, तो अपनी परीक्षण फ़ाइल को विभाजित करने का प्रयास करें।

गुच्छे से बचने के लिए परीक्षण समय का लक्ष्य परीक्षण आकार के आधे समय का होना चाहिए

bazel परीक्षण लक्ष्यों के साथ, छोटे परीक्षणों में 1 मिनट का टाइमआउट होता है। मीडियम टेस्ट टाइमआउट 5 मिनट है। TensorFlow परीक्षण इन्फ्रा द्वारा बड़े परीक्षण निष्पादित नहीं किए जाते हैं। हालाँकि, कई परीक्षण लगने वाले समय के मामले में निश्चित नहीं होते हैं। विभिन्न कारणों से आपके परीक्षणों में कभी-कभी अधिक समय लग सकता है। और, यदि आप औसतन 50 सेकंड तक चलने वाले परीक्षण को छोटे के रूप में चिह्नित करते हैं, तो पुराने सीपीयू वाली मशीन पर शेड्यूल होने पर आपका परीक्षण विफल हो जाएगा। इसलिए, छोटे परीक्षणों के लिए औसतन 30 सेकंड चलने का समय निर्धारित करें। मध्यम परीक्षणों के लिए औसतन 2 मिनट 30 सेकंड चलने का लक्ष्य रखें।

नमूनों की संख्या कम करें और प्रशिक्षण के लिए सहनशीलता बढ़ाएँ

धीमी गति से चलने वाले परीक्षण योगदानकर्ताओं को रोकते हैं। परीक्षणों में प्रशिक्षण चलाना बहुत धीमा हो सकता है। अपने परीक्षणों को पर्याप्त रूप से तेज़ (अधिकतम 2.5 मिनट) रखने के लिए अपने परीक्षणों में कम नमूनों का उपयोग करने में सक्षम होने के लिए उच्च सहनशीलता को प्राथमिकता दें।

गैर-नियतिवाद और गुच्छे को हटा दें

नियतात्मक परीक्षण लिखें

इकाई परीक्षण सदैव नियतिवादी होने चाहिए। टीएपी और गिटार पर चलने वाले सभी परीक्षण हर बार एक ही तरीके से चलने चाहिए, यदि कोई कोड परिवर्तन उन्हें प्रभावित नहीं कर रहा है। इसे सुनिश्चित करने के लिए, नीचे कुछ बिंदुओं पर विचार किया गया है।

हमेशा स्टोकेस्टिसिटी के किसी भी स्रोत का बीजारोपण करें

कोई भी यादृच्छिक संख्या जनरेटर, या स्टोकेस्टिसिटी का कोई अन्य स्रोत परतदारता का कारण बन सकता है। इसलिए, इनमें से प्रत्येक को बीजित किया जाना चाहिए। परीक्षणों को कम परतदार बनाने के अलावा, यह सभी परीक्षणों को प्रतिलिपि प्रस्तुत करने योग्य बनाता है। कुछ बीजों को सेट करने के विभिन्न तरीके जिन्हें आपको टीएफ परीक्षणों में सेट करने की आवश्यकता हो सकती है:

# Python RNG
import random
random.seed(42)

# Numpy RNG
import numpy as np
np.random.seed(42)

# TF RNG
from tensorflow.python.framework import random_seed
random_seed.set_seed(42)

मल्टीथ्रेडेड परीक्षणों में sleep उपयोग करने से बचें

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

जांचें कि क्या परीक्षण परतदार है

फ़्लेक्स के कारण बिल्डपुलिस और डेवलपर्स को कई घंटे बर्बाद करने पड़ते हैं। उनका पता लगाना कठिन है, और उन्हें डिबग करना कठिन है। हालाँकि परतदारता का पता लगाने के लिए स्वचालित प्रणालियाँ मौजूद हैं, फिर भी परीक्षणों को सटीक रूप से अस्वीकार करने से पहले उन्हें सैकड़ों परीक्षण चलाने की आवश्यकता होती है। यहां तक ​​कि जब उन्हें पता चलता है, तो वे आपके परीक्षणों को अस्वीकार कर देते हैं और परीक्षण कवरेज खो जाता है। इसलिए, परीक्षण लेखकों को परीक्षण लिखते समय यह जांचना चाहिए कि क्या उनके परीक्षण परतदार हैं। यह अपना परीक्षण ध्वज के साथ चलाकर आसानी से किया जा सकता है: --runs_per_test=1000

TensorFlowTestCase का उपयोग करें

TensorFlowTestCase आवश्यक सावधानियां बरतता है जैसे कि जितना संभव हो सके परत को कम करने के लिए उपयोग किए जाने वाले सभी यादृच्छिक संख्या जनरेटर को सीडिंग करना। जैसे-जैसे हम अधिक परतदार स्रोतों को खोजते और ठीक करते हैं, ये सभी TensorFlowTestCase में जुड़ जाएंगे। इसलिए, आपको टेंसरफ़्लो के लिए परीक्षण लिखते समय TensorFlowTestCase का उपयोग करना चाहिए। TensorFlowTestCase को यहां परिभाषित किया गया है: tensorflow/python/framework/test_util.py

हर्मेटिक परीक्षण लिखें

हर्मेटिक परीक्षणों के लिए किसी बाहरी संसाधन की आवश्यकता नहीं होती है। वे अपनी ज़रूरत की हर चीज़ से भरे हुए हैं, और वे कोई भी नकली सेवा शुरू कर देते हैं जिसकी उन्हें ज़रूरत हो सकती है। आपके परीक्षणों के अलावा कोई भी सेवा गैर नियतिवाद का स्रोत है। अन्य सेवाओं की 99% उपलब्धता के साथ भी, नेटवर्क ख़राब हो सकता है, आरपीसी प्रतिक्रिया में देरी हो सकती है, और आपको एक अस्पष्ट त्रुटि संदेश मिल सकता है। बाहरी सेवाएँ GCS, S3 या किसी भी वेबसाइट तक सीमित नहीं हो सकती हैं।