एक Workflow block बनाएँ
Workflow block लिखने के लिए पूर्ण डेवलपर मार्गदर्शिका: manifests, inputs, outputs, batch processing, flow control, और dimensionality।
यह Python में एक Block class लिखने के लिए विस्तृत मार्गदर्शिका है। यदि आपको केवल एक Workflow के भीतर कस्टम लॉजिक का एक छोटा हिस्सा चाहिए, तो dynamic Python block जो Workflow Definition में inline परिभाषित हो, आमतौर पर पर्याप्त होता है - देखें Custom Blocks.
Workflows blocks development के लिए Workflow Ecosystem की समझ आवश्यक है। विवरण में गहराई से जाने से पहले, आइए आवश्यक ज्ञान का सारांश लें:
की समझ Workflow execution, विशेष रूप से:
Workflow definition में Workflow blocks और steps के बीच क्या संबंध है
Workflow blocks और उनके manifests का उपयोग कैसे किया जाता है Workflows Compiler
क्या है
dimensionality levelWorkflow से गुजरने वाले batch-oriented data काकैसे Execution Engine step के साथ उसके inputs और outputs के संबंध में कैसे इंटरैक्ट करता है
क्या है Workflow
kindsको समझना
pydanticकैसे काम करता है
Environment setup
जैसा कि आप जल्द ही देखेंगे, Workflow block बनाना केवल एक विशेष interface लागू करने वाली Python class परिभाषित करने का मामला है। यह design आपको block को Python interpreter से चलाने की अनुमति देता है, ठीक किसी अन्य Python code की तरह। हालांकि, आवश्यक सभी inputs को एकत्रित करते समय आपको कठिनाइयों का सामना करना पड़ सकता है, जो सामान्यतः Workflow execution के दौरान अन्य blocks द्वारा प्रदान किए जाते हैं। इसलिए, सुचारु workflow के लिए development environment को ठीक से सेट करना महत्वपूर्ण है। हम standard development process के भाग के रूप में निम्न चरणों का पालन करने की सलाह देते हैं (बाद के contributions के लिए प्रारंभिक चरण छोड़े जा सकते हैं):
सेट अप करें
condaenvironment और मुख्य dependencies install करेंinferenceकी, जैसा किinferencecontributor guide.Workflows codebase के संगठन से परिचित हों।
एक न्यूनतम block बनाएं - आप अगले sections में यह करना सीखेंगे। एक सरल block manifest और मूल logic लागू करके शुरू करें ताकि सुनिश्चित हो सके कि block अपेक्षित रूप से चलता है।
block को plugin में जोड़ें - एक बार आपका block बन जाने के बाद, उसे plugin से export किए गए blocks की सूची में जोड़ें। यदि आप block को Roboflow Core plugin में जोड़ रहे हैं, तो सुनिश्चित करें कि आपके block के लिए एक entry जोड़ें loader.py. यदि आप यह चरण भूल जाते हैं, तो आपका block दिखाई नहीं देगा!
अपने block को iterate करें और refine करें - जब तक आप परिणामों से संतुष्ट न हों, अपने block का विकास और संचालन जारी रखें। नीचे दिए गए sections विभिन्न scenarios में अपने block पर iterate करने का तरीका समझाते हैं।
Workflows UI का उपयोग करके अपने blocks चलाना
हम mounted volume के साथ inference server चलाने की सलाह देते हैं (जो inference हर बदलाव पर server को फिर से build करने से बहुत तेज़ है):
और अपने local server को Roboflow UI से जोड़ना:

त्वरित previews चलाने के लिए:

मेरे block को अतिरिक्त dependencies चाहिए - मैं pre-built `inference` server का उपयोग नहीं कर सकता
यह स्वाभाविक है कि आपके blocks को कभी-कभी अतिरिक्त dependencies की आवश्यकता हो सकती है। किसी dependency को जोड़ने के लिए, बस उसे इनमें से किसी एक में शामिल करें requirements filesजो संबंधित Docker image में install किए जाते हैं (आमतौर पर CPU build का inference server).
इसके बाद, चलाएँ:
फिर आप अभी बनाए गए test tag को निर्दिष्ट करके अपने local build को चला सकते हैं:
Workflows UI के बिना अपने blocks चलाना
Roboflow platform तक पहुँच न रखने वाले contributors के लिए, हम ऊपर दिए गए section में बताए अनुसार server चलाने की सलाह देते हैं। हालांकि, UI editor के बजाय, आपको एक सरल Workflow definition बनानी होगी और server को request भेजनी होगी।
UI के बिना अपना Workflow चलाना
निम्न code snippet दिखाता है कि inference server को request भेजकर Workflow कैसे चलाया जाए। inference_sdk को inference package में हमारे server के लिए एक lightweight client library के रूप में शामिल किया गया है।
नियमित contributors के लिए अनुशंसित तरीका
में integration tests बनाना tests/workflows/integration_tests/execution directory विकास iteration प्रक्रिया का एक स्वाभाविक हिस्सा है। यह दृष्टिकोण आपको एक साथ विकास और परीक्षण करने देता है, और जैसे-जैसे आप अपने code को refine करते हैं, मूल्यवान feedback प्रदान करता है। हालांकि इसके लिए कुछ अनुभव चाहिए, यह long-term code maintenance को काफी बेहतर बनाता है।
प्रक्रिया सीधी है:
एक नया Test Module बनाएं: उदाहरण के लिए, इसका नाम रखें
test_workflows_with_my_custom_block.py.उदाहरण Workflows विकसित करें: एक या अधिक example Workflows बनाएं। यदि आपका block ecosystem के अन्य blocks के साथ सहयोग करे, तो यह बेहतर होगा।
Sample Data के साथ Tests चलाएँ: अपने tests में sample data का उपयोग करके इन Workflows को execute करें (आप हमारे fixtures को देखकर उदाहरण data ढूँढ सकते हैं जिसका हम आमतौर पर उपयोग करते हैं)।
अपेक्षित परिणामों की पुष्टि करें: सत्यापित करें कि परिणाम आपकी अपेक्षाओं से मेल खाते हैं।
अपने development flow में testing शामिल करके, आप सुनिश्चित करते हैं कि आपका block समय के साथ स्थिर बना रहे और मौजूदा blocks के साथ प्रभावी ढंग से इंटरैक्ट करे, जिससे आपके कार्य की अभिव्यक्तिशीलता बढ़ती है!
आप निम्न कमांड का उपयोग करके अपना test चला सकते हैं:
उदाहरणों के लिए अन्य tests का संदर्भ लेने या निम्न template का उपयोग करने में संकोच न करें:
Integration test template
लाइन
2में, आपकोmodel_managerfixture मिलेगा, जो आम तौर पर model blocks द्वारा आवश्यक होता है। यह fixtureModelManagerabstraction प्रदान करता हैinferenceसे, जिसका उपयोग models को load और unload करने के लिए किया जाता है।लाइन
3एक ऐसा fixture परिभाषित करती है जिसमें दो कुत्तों की image शामिल है (और उदाहरण images के लिए अन्य fixtures देखें)।लाइन
4एक वैकल्पिक fixture है जिसका आप उपयोग करना चाह सकते हैं यदि आपके tested workflow के किसी block को Roboflow API key की आवश्यकता हो। यदि ऐसा है, तोROBOFLOW_API_KEYenvironment variable को test चलाने से पहले एक मान्य key के साथ export करें।लाइनें
7-11Execution Engine द्वारा runtime पर बनाए जाने वाले blocks के initialization parameters के setup को प्रदान करती हैं, जो आपकी Workflow definition पर आधारित है।लाइनें
19-23दिखाती हैं कि input parameters inject करके एक Workflow कैसे चलाया जाए। कृपया सुनिश्चित करें कि runtime_parameters में keys आपकी Workflow definition में घोषित inputs से मेल खाएँ।लाइन से शुरू करते हुए
26, आपको test के भीतर example assertions मिलेंगे।
Prototypes
Workflow block बनाने के लिए आपको Workflows library के core से कुछ imports की आवश्यकता होती है। यहाँ imports की सूची है जो block बनाते समय उपयोगी हो सकती है:
सबसे महत्वपूर्ण हैं:
WorkflowBlock- आपके block के लिए base classWorkflowBlockManifest- block manifest के लिए base class
आंतरिक data representation को समझना
आपने देखा होगा कि हम Batch और WorkflowImageData classes को import करने की सलाह देते हैं, जो हमारे system में building blocks बनाते समय उपयोग किए जाने वाले मौलिक components हैं। इन classes का समग्र architecture में स्थान कैसे है, इसे बेहतर समझने के लिए हम आपको Data Representations page को अधिक विस्तृत जानकारी के लिए देखने की सलाह देते हैं।
Block manifest
Manifest एक Workflow block का महत्वपूर्ण घटक है जो step declaration के लिए एक prototype परिभाषित करता है, जिसे block का उपयोग करने के लिए Workflow definition में रखा जा सकता है। विशेष रूप से, यह:
उपयोग करता है
pydanticWorkflow definitions की syntax parsing को संचालित करने के लिए: यहpydantic BaseModelfeatures से Workflow definitions को parse और validate करता है। इस schema कोpydantic'sOpenAPI standard के साथ integration की बदौलत, Workflows UI के अनुकूल format में स्वचालित रूप से export भी किया जा सकता है।Data Bindings परिभाषित करता है: यह निर्दिष्ट करता है कि manifest में कौन से fields execution के दौरान workflow से बहने वाले data के selectors हैं और उनके kinds क्या हैं।
Block Outputs का वर्णन करता है: यह उन outputs की रूपरेखा देता है जो block उत्पन्न करेगा।
Dimensionality निर्दिष्ट करता है: यह input और output dimensionality से संबंधित properties का विवरण देता है।
Batch Inputs और Empty Values को इंगित करता है: यह Execution Engine को बताता है कि step batch inputs और empty values स्वीकार करता है या नहीं।
Compatibility सुनिश्चित करता है: यह स्थिरता बनाए रखने के लिए विभिन्न Execution Engine versions के साथ compatibility निर्धारित करता है। अधिक विवरण के लिए देखें versioning.
Manifest के लिए scaffolding
यह समझने के लिए कि manifests कैसे काम करते हैं, आइए उन्हें चरण-दर-चरण परिभाषित करें। यहाँ हम जो उदाहरण block बनाएँगे, वह images similarity की गणना करेगा। हम imports और class scaffolding से शुरू करते हैं:
यह manifest का न्यूनतम representation है। यह दो विशेष fields परिभाषित करता है जो Compiler और Execution engine के लिए महत्वपूर्ण हैं:
type- blocks के dynamic pool पर आधारित Workflow definitions की syntax parse करने के लिए आवश्यक - यह हैpydantictype discriminator जो Compiler को यह समझने देता है कि Workflow definition में विशिष्ट steps को parse करते समय किस block manifest की जाँच करनी हैname- इस property का उपयोग step को एक unique नाम देने और अन्य steps को selectors के माध्यम से इसे चुनने देने के लिए किया जाएगा
Inputs जोड़ना
हम चाहते हैं कि हमारा step तुलना के लिए images के साथ दो inputs ले।
Inputs जोड़ना
आइए देखें कि इन inputs की definitions को manifest में कैसे जोड़ें:
लाइनों में
2-9हमने कुछ imports जोड़े हैं ताकि हमारे पास आवश्यक सब कुछ होलाइन
20परिभाषित करती हैimage_1parameter - क्योंकि manifest Workflow Definition का prototype है, step द्वारा उपयोग की जाने वाली image के बारे में बताने का एकमात्र तरीका selector प्रदान करना है - core library में हमारे पास एक specialized type है जिसका उपयोग किया जा सकता है -Selector. यदि आप codebase में और गहराई से देखें, तो आपको पता चलेगा कि यह एक type alias constructor function है - जो बताता हैpydanticकि यह string pattern से मेल खाने की अपेक्षा करता है$inputs.{name}और$steps.{name}.*patterns क्रमशः, और साथ ही अतिरिक्त schema field metadata प्रदान करता है जो Workflows ecosystem components को बताता है कि selector के पीछे काkindका data है image. महत्वपूर्ण नोट: हम kind को list के रूप में दर्शाते हैं - विशिष्ट kinds की list को kinds के union के रूप में Execution Engine द्वारा समझा जाता है।दर्शाते हुए
pydanticField(...)लाइन के अंतिम भागों में attribute20वैकल्पिक है, लेकिन उपयोगी है, विशेष रूप से उन blocks के लिए जो Workflows UI के साथ सहयोग करने हेतु बनाए गए हैंलाइन में शुरुआत करते हुए
23आप पा सकते हैंimage_2parameter की परिभाषा जो काफी हद तकimage_1.
manifest की ऐसी परिभाषा Workflow definition में निम्न step declaration को संभाल सकती है:
यह परिभाषा Compiler और Execution Engine को यह करने देगी:
Workflow block से step को initialize करना जो type घोषित करता है
my_plugin/images_similarity@v1steps run method के लिए दो parameters प्रदान करना:
input_1type काWorkflowImageDataजो Workflow execution input के रूप में भेजी गई image से भरा जाएगा जिसका नाम हैmy_image.imput_2type काWorkflowImageDataजो runtime पर एक अन्य step द्वारा उत्पन्न किया जाएगा, जिसका नाम हैimage_transformation
Manifest में parameters जोड़ना
अब आइए उस parameter को जोड़ें जो step execution को प्रभावित करेगा।
Manifest में parameter जोड़ना
लाइन
9importsfloat_zero_to_onekindवह परिभाषा जिसका उपयोग parameter को परिभाषित करने के लिए किया जाएगा।लाइन में
27हम एक parameter परिभाषित करना शुरू करते हैं जिसका नाम हैsimilarity_threshold. Manifest या तो float values या workflow input के लिए selector स्वीकार करेगा जिसकाkindfloat_zero_to_oneहै, जो लाइन में import किया गया है9.
manifest की ऐसी परिभाषा Workflow definition में निम्न step declaration को संभाल सकती है:
या वैकल्पिक रूप से:
Block outputs घोषित करना
हमने अपने block के लिए inputs सफलतापूर्वक परिभाषित कर दिए हैं, लेकिन blocks को सफलतापूर्वक चलाने के लिए आवश्यक कुछ तत्व अभी भी गायब हैं। आइए block outputs परिभाषित करें।
Block outputs घोषित करना
आवश्यक जानकारी का न्यूनतम सेट outputs का विवरण है। इसके अतिरिक्त, block stability बढ़ाने के लिए, हम execution engine compatibility के बारे में जानकारी देने की सलाह देते हैं।
लाइन
5स्टेप आउटपुट्स का वर्णन करने के लिए उपयोग की जाने वाली क्लास को इम्पोर्ट करता हैलाइन
11importsबूलियनkindआउटपुट परिभाषाओं में उपयोग किए जाने के लिएपंक्तियाँ
32-39ब्लॉक के आउटपुट निर्दिष्ट करने के लिए क्लास मेथड घोषित करें - सूची की प्रत्येक प्रविष्टि प्रत्येक बैच तत्व और उसके लिए एक रिटर्न प्रॉपर्टी घोषित करती हैkind. हमारा ब्लॉक बूलियन फ़्लैग लौटाएगाimages_matchप्रत्येक छवि-युग्म के लिए।पंक्तियाँ
41-43Execution Engine के साथ ब्लॉक की संगतता घोषित करें - देखें वर्शनिंग पेज अधिक विवरण के लिए
इन परिवर्तनों के परिणामस्वरूप:
Execution Engine समझेगा कि इस ब्लॉक के आधार पर बनाए गए स्टेप्स को निर्दिष्ट आउटपुट्स देने चाहिए, और अन्य स्टेप्स अपने इनपुट्स में उन आउटपुट्स को संदर्भित कर सकते हैं
ब्लॉक्स लोड करने की व्यवस्था ब्लॉक को लोड नहीं करेगी क्योंकि Execution Engine संस्करण में नहीं है
v1
और जानें: डायनामिक आउटपुट्स
कुछ ब्लॉक classmethod का उपयोग करके अपने आउटपुट्स को मनमाने ढंग से परिभाषित करने में सक्षम नहीं हो सकते - पार्सिंग के बाद उपलब्ध step manifest की सामग्री से स्वतंत्र। इसे समर्थन देने के लिए हमने निम्नलिखित परंपरा पेश की:
classmethod
describe_outputs(...)को नाम के एक तत्व वाली सूची लौटानी चाहिए*और kind*(उर्फWILDCARD_KIND)इसके अतिरिक्त, block manifest को instance method लागू करनी चाहिए
get_actual_outputs(...)जो भरे गए manifest डेटा के आधार पर उत्पन्न किए जा सकने वाले वास्तविक आउटपुट्स की सूची प्रदान करती है
ब्लॉक क्लास की परिभाषा
इस चरण पर, हमारे सरल ब्लॉक का manifest तैयार है, हम अपने उदाहरण के साथ आगे बढ़ेंगे। आप उन्नत विषय अनुभाग को अधिक विवरण के लिए देख सकते हैं, जो अभी सिर्फ ध्यान भटका देगा।
मूल कार्यान्वयन
Manifest तैयार होने के बाद, हम ब्लॉक का बेसलाइन कार्यान्वयन तैयार कर सकते हैं।
ब्लॉक स्कैफ़ोल्डिंग
पंक्तियाँ
1,5-6और8-11आवश्यक प्रतीकों को ठीक से परिभाषित करने के लिए आयात संरचना में परिवर्तन जोड़े गए हैं, ताकि ब्लॉक क्लास और उसके सभी मेथड सिग्नेचर सही तरह से परिभाषित हो सकेंपंक्तियाँ
53-55क्लास मेथड को परिभाषित करता हैget_manifest(...)ताकि पहले बनाई गई manifest क्लास को बस वापस किया जा सकेपंक्तियाँ
57-63परिभाषित करेंrun(...)फ़ंक्शन, जिसे Execution Engine इच्छित परिणाम पाने के लिए डेटा के साथ कॉल करेगा। कृपया ध्यान दें कि इनपुट्स को परिभाषित करने वाले manifest फ़ील्ड्स image kind के रूप में चिह्नित हैंWorkflowImageData- जो किimagekind की आंतरिक डेटा निरूपण के अनुरूप है, जैसा कि kind दस्तावेज़ीकरण में वर्णित है.
ब्लॉक लॉजिक के लिए कार्यान्वयन प्रदान करना
आइए अब ब्लॉक के लिए एक उदाहरण कार्यान्वयन जोड़ें run(...) मेथड का, ताकि यह अर्थपूर्ण परिणाम उत्पन्न कर सके।
इस अनुभाग की सामग्री का उद्देश्य Workflow इकोसिस्टम के साथ ब्लॉक निर्माता के रूप में कैसे इंटरैक्ट करें, इसके उदाहरण देना है, न कि ब्लॉक का मजबूत/पूर्ण कार्यान्वयन प्रदान करना।
`run(...)` मेथड का कार्यान्वयन
लाइन में
3हम OpenCV इम्पोर्ट करते हैंपंक्तियाँ
55-57ब्लॉक कंस्ट्रक्टर को परिभाषित करता है, इसके कारण ब्लॉक की स्थिति एक बार प्रारंभ होती है औरrun(...)मेथड के लगातार आह्वानों के दौरान जीवित रहती है - उदाहरण के लिए जब Execution Engine वीडियो के लगातार फ़्रेम्स पर चलता हैपंक्तियाँ
69-80ब्लॉक कार्यक्षमता का कार्यान्वयन प्रदान करें - Workflows इकोसिस्टम के संबंध में विवरण वास्तव में महत्वपूर्ण नहीं हैं, लेकिन कुछ विवरण हैं जिन पर आपको ध्यान देना चाहिए:पंक्तियाँ
69और70का उपयोग करेंWorkflowImageDataअमूर्तन, यह दर्शाते हुए किnumpy_imageप्रॉपर्टी का उपयोग प्राप्त करने के लिए किया जा सकता हैnp.ndarrayWorkflows में छवियों के आंतरिक निरूपण से। हम सलाह देते हैं किWorkflowImageDataकी शेष प्रॉपर्टीज़ को और जानने के लिए खोजें।वर्कफ़्लो ब्लॉक निष्पादन का परिणाम, पंक्तियों में घोषित
78-80हमारे मामले में केवल एक डिक्शनरी है जिसकी कुंजियाँ manifest में घोषित आउटपुट्स के नाम हैं, पंक्ति43. सभी घोषित आउटपुट्स प्रदान करना सुनिश्चित करें - अन्यथा Execution Engine त्रुटि देगा।
ब्लॉक को प्लगइन में उजागर करना
अब, आपका ब्लॉक उपयोग के लिए तैयार है, लेकिन Execution Engine को इसके अस्तित्व की जानकारी नहीं है। इसका कारण यह है कि कोई पंजीकृत प्लगइन अभी-अभी बनाए गए ब्लॉक को निर्यात नहीं करता। ब्लॉक्स को पैकेज/बंडल करने के विवरण अलग पेजपर कवर किए गए हैं, लेकिन करने के लिए शेष चीज़ यह है कि अपने प्लगइन के द्वारा लौटाई गई सूची में ब्लॉक क्लास जोड़ें load_blocks(...) फ़ंक्शन:
उन्नत विषय
इनपुट्स के बैचों को प्रोसेस करने वाले ब्लॉक
कभी-कभी, यदि सभी इनपुट डेटा को एक साथ बैच के रूप में प्रोसेस किया जाए तो आपके ब्लॉक के प्रदर्शन को लाभ हो सकता है। ऐसा GPU पर चलने वाले मॉडलों के लिए हो सकता है। ऐसी संचालन-शैली Workflows ब्लॉक्स के लिए समर्थित है - यहाँ आपके ब्लॉक के लिए इसका उपयोग करने का उदाहरण है।
बैच स्वीकार करने वाले ब्लॉक्स का कार्यान्वयन
लाइन
13importsBatchWorkflows लाइब्रेरी के कोर से - यह क्लास एक कंटेनर का प्रतिनिधित्व करती है जो बैच तत्वों को रखने के लिए सूची के समान (लेकिन केवल-पठन) हैपंक्तियाँ
40-42क्लास मेथड परिभाषित करें जो ब्लॉक के डिफ़ॉल्ट व्यवहार को बदलता है और उसे बैच प्रोसेस करने में सक्षम बनाता है - हम प्रत्येक पैरामीटर को चिह्नित कर रहे हैं जिसेrun(...)मेथड बैच-उन्मुख के रूप में पहचानता है.ऊपर प्रस्तुत परिवर्तनों ने
run(...)मेथड के सिग्नेचर को बदल दिया है, अबimage_1औरimage_2के उदाहरण नहीं हैंWorkflowImageDataबल्कि इस प्रकार के तत्वों के बैच हैं। महत्वपूर्ण नोट: कई बैच-उन्मुख पैरामीटर्स होने पर हम अपेक्षा करते हैं कि उन बैचों के तत्व संबंधित स्थितियों पर एक-दूसरे से जुड़े हों - ताकि हमारे ब्लॉक द्वारा तुलनाimage_1[1]मेंimage_2[1]वास्तव में तार्किक रूप से सार्थक संचालन करता है।पंक्तियाँ
74-77,85-86वे परिवर्तन प्रस्तुत करें जो सभी बैच तत्वों पर रन प्रोसेसिंग करने के लिए पेश करने पड़े - यह दिखाते हुए कि आवश्यकता होने पर बैच तत्वों पर कैसे iterate करेंयह ध्यान देना महत्वपूर्ण है कि आउटपुट्स पंक्ति में कैसे बनाए जाते हैं
85- बैच के प्रत्येक तत्व को सूची में उसकी अपनी प्रविष्टि दी जाएगी जोrun(...)मेथड से लौटाई जाती है। क्रम बैच तत्वों के क्रम के अनुरूप होना चाहिए। प्रत्येक आउटपुट डिक्शनरी में ब्लॉक आउटपुट्स में घोषित सभी कुंजियाँ प्रदान की जानी चाहिए।
ऐसे इनपुट्स जो बैच और स्केलर दोनों स्वीकार करते हैं
यह अपेक्षाकृत असंभाव्य हैलेकिन ऐसा हो सकता है कि आपके ब्लॉक को एक ही इनपुट पैरामीटर में बैच-उन्मुख डेटा और स्केलर्स दोनों स्वीकार करने की आवश्यकता हो। Execution Engine इसे पहचानता है get_parameters_accepting_batches_and_scalars(...) ब्लॉक manifest की मेथड का उपयोग करके। नीचे दिए गए उदाहरण पर नज़र डालें:
पंक्तियाँ
20-22वे manifest पैरामीटर्स निर्दिष्ट करें जिनसे मिश्रित (स्केलर और बैच-उन्मुख दोनों) इनपुट डेटा स्वीकार करने की अपेक्षा है - ध्यान दें कि इस चरण पर परिभाषा में पिछले उदाहरणों की तुलना में कोई अंतर नहीं है।पंक्तियाँ
24-26निर्दिष्ट करेंget_parameters_accepting_batches_and_scalars(...)मेथड ताकि Execution Engine को बताया जा सके कि ब्लॉकrun(...)मेथड निर्दिष्ट पैरामीटर्स के लिए स्केलर और बैच-उन्मुख दोनों इनपुट्स को संभाल सकता है।पंक्तियाँ
45-47मिश्रित प्रकृति वाले पैरामीटर्स कोrun(...)मेथड सिग्नेचर में दर्शाएँ।लाइन
49यह दर्शाता है कि हमें अपेक्षित आउटपुट आकार का ट्रैक रखना होगा ब्लॉक लॉजिक के भीतर. इसी कारण मिश्रित इनपुट्स वाले ब्लॉक्स को लागू करना काफी कठिन है। सामान्यतः, जब ब्लॉकrun(...)मेथड स्केलर्स पर काम करता है - अधिकांश मामलों में (अपवाद नीचे वर्णित होंगे) - मेथड एकल आउटपुट डिक्शनरी बनाता है। इसी तरह, जब बैच-उन्मुख इनपुट्स स्वीकार किए जाते हैं - वे इनपुट्स अपेक्षित आउटपुट आकार को परिभाषित करते हैं। हालाँकि, इस मामले में, हमें बैचों को मैन्युअल रूप से पहचानना और उनके आकार पकड़ना होगा।पंक्तियाँ
50-54यह दिखाएँ कि मिश्रित पैरामीटर्स से निपटते समय हम सामान्यतः कैसे व्यवहार करते हैं - जब बैच-उन्मुख डेटा का पता चलता है तो अलग लॉजिक लागू करते हैंजैसा पहले उल्लेख किया गया, आउटपुट निर्माण को भी मिश्रित इनपुट्स की प्रकृति के अनुसार समायोजित करना होगा - जिसे पंक्तियों में दर्शाया गया है
65-70
फ़्लो-कंट्रोल ब्लॉक का कार्यान्वयन
फ़्लो-कंट्रोल ब्लॉक्स अन्य उन ब्लॉक्स से काफी भिन्न होते हैं जो केवल डेटा प्रोसेस करते हैं। यहाँ हम दिखाएँगे कि फ़्लो कंट्रोल ब्लॉक कैसे बनाया जाए, लेकिन पहले - थोड़ा सिद्धांत:
फ़्लो-कंट्रोल ब्लॉक वह ब्लॉक है जो अपने manifest में स्टेप सेलेक्टर्स के साथ संगतता घोषित करता है (स्टेप के लिए सेलेक्टर इस प्रकार परिभाषित है
$steps.{step_name}- स्टेप आउटपुट सेलेक्टर के समान, लेकिन आउटपुट नाम के विनिर्देश के बिना)फ़्लो-कंट्रोल ब्लॉक्स आउटपुट्स पंजीकृत नहीं कर सकते, उनका उद्देश्य लौटाना है
FlowControlऑब्जेक्ट्सFlowControlऑब्जेक्ट अगले स्टेप्स निर्दिष्ट करता है (स्टेप manifest में दिए गए सेलेक्टर्स से) जिन्हें दिए गए बैच तत्व (SIMD फ़्लो-कंट्रोल) या पूरे वर्कफ़्लो निष्पादन (गैर-SIMD फ़्लो-कंट्रोल) के लिए अगला लेना चाहिए
फ़्लो-कंट्रोल का कार्यान्वयन
उदाहरण रैंडम कंटिन्यू ब्लॉक के कार्यान्वयन को प्रदान करता है और टिप्पणी के रूप में हटाता है
लाइन
10स्टेप सेलेक्टर के लिए type annotation इम्पोर्ट करता है, जिसका उपयोग Execution Engine को सूचित करने के लिए किया जाएगा कि ब्लॉक प्रवाह को नियंत्रित करता हैलाइन
14importsFlowControlवह क्लास जो फ़्लो-कंट्रोल ब्लॉक से मिलने वाला एकमात्र उपयुक्त उत्तर हैलाइन
28स्टेप सेलेक्टर्स की सूची को परिभाषित करता है जो प्रभावी रूप से ब्लॉक को फ़्लो-कंट्रोल ब्लॉक में बदल देता हैपंक्तियाँ
55और56आउटपुट बनाने का तरीका दिखाएँ -FlowControlऑब्जेक्ट context को स्वीकार करता हैNone,स्ट्रिंगयास्ट्रिंग्स की सूची-Noneबैच तत्व के लिए प्रवाह समाप्ति का प्रतिनिधित्व करें, स्ट्रिंग्स से अपेक्षा है कि वे इनपुट में पास किए गए अगले स्टेप्स के लिए सेलेक्टर्स हों।
फ़्लो-कंट्रोल का कार्यान्वयन - बैच संस्करण
उदाहरण रैंडम कंटिन्यू ब्लॉक के कार्यान्वयन को प्रदान करता है और टिप्पणी के रूप में हटाता है
लाइन
11स्टेप सेलेक्टर के लिए type annotation इम्पोर्ट करता है, जिसका उपयोग Execution Engine को सूचित करने के लिए किया जाएगा कि ब्लॉक प्रवाह को नियंत्रित करता हैलाइन
15importsFlowControlवह क्लास जो फ़्लो-कंट्रोल ब्लॉक से मिलने वाला एकमात्र उपयुक्त उत्तर हैपंक्तियाँ
29-32स्टेप सेलेक्टर्स की सूची को परिभाषित करता है जो प्रभावी रूप से ब्लॉक को फ़्लो-कंट्रोल ब्लॉक में बदल देता हैपंक्तियाँ
38-40का परिभाषन शामिल करेंget_parameters_accepting_batches(...)मेथड जो Execution Engine को बताता है कि ब्लॉकrun(...)मेथड बैच-उन्मुखimageपैरामीटर की अपेक्षा करता है।लाइन
59यह प्रकट करता है कि हमें flow-control मार्गदर्शन लौटाना होगाimageबैच के प्रत्येक और हर तत्व के लिए।इस उद्देश्य को प्राप्त करने के लिए, पंक्ति में
60हम बैच की सामग्री पर iterate करते हैं।पंक्तियाँ
61-63आउटपुट बनाने का तरीका दिखाएँ -FlowControlऑब्जेक्ट context को स्वीकार करता हैNone,स्ट्रिंगयास्ट्रिंग्स की सूची-Noneबैच तत्व के लिए प्रवाह समाप्ति का प्रतिनिधित्व करें, स्ट्रिंग्स से अपेक्षा है कि वे इनपुट में पास किए गए अगले स्टेप्स के लिए सेलेक्टर्स हों।
नेस्टेड सेलेक्टर्स
कुछ ब्लॉक्स को block manifest फ़ील्ड में सेलेक्टर्स की सूची या सेलेक्टर्स की डिक्शनरी प्रदान करने की आवश्यकता होगी। Execution Engine का संस्करण v1 केवल एक स्तर की nesting को समर्थन देता है - इसलिए सेलेक्टर्स की सूचियों की सूची या सेलेक्टर्स की सूची वाली डिक्शनरी को सही तरह से पहचाना नहीं जाएगा।
नेस्टेड सेलेक्टर्स के उपयोग को दिखाने वाले व्यावहारिक उपयोग मामले नीचे प्रस्तुत हैं।
परिवर्तनशील संख्या वाले मॉडलों की भविष्यवाणियों का फ्यूज़न
मान लें कि आप कई classifiers की भविष्यवाणियों पर बहुमत वोट लेने के लिए एक ब्लॉक बनाना चाहते हैं - तब आप चाहते हैं कि आपका run मेथड कुछ ऐसा दिखे:
नेस्टेड सेलेक्टर्स - मॉडल एन्सेम्बल
पंक्तियाँ
23-26दिखाता है कि सेलेक्टर्स की सूची स्वीकार करने में सक्षम manifest फ़ील्ड कैसे परिभाषित करेंलाइन
50दिखाता है कि ब्लॉक के इनपुट के रूप में क्या अपेक्षित हैrun(...)मेथड - ऑब्जेक्ट्स की सूची, जो विशिष्ट प्रकार का निरूपण हैं। यदि ब्लॉक बैच स्वीकार करता, तोpredictionsफ़ील्ड का इनपुट प्रकार होगाList[Batch[sv.Detections]
ऐसा ब्लॉक निम्नलिखित स्टेप घोषणा के साथ संगत है:
डेटा रूपांतरणों वाला ब्लॉक जो डायनामिक पैरामीटर्स की अनुमति देता है
कभी-कभी, blocks को "named" selectors के समूह को स्वीकार करने की आवश्यकता हो सकती है, जिनके नाम और मान Workflow परिभाषा के निर्माता द्वारा निर्धारित किए जाने हैं। ऐसे मामलों में, block manifest को selectors की dictionary स्वीकार करनी चाहिए, जहाँ keys उन selectors के नाम के रूप में काम करती हैं।
नेस्टेड selectors - named selectors
पंक्तियाँ
22-25यह दिखाता है कि manifest field को कैसे परिभाषित किया जाए जो selectors की dictionary स्वीकार करने में सक्षम हो - selector के नाम और मान के बीच mapping प्रदान करकेलाइन
46दिखाता है कि ब्लॉक के इनपुट के रूप में क्या अपेक्षित हैrun(...)method - objects की एक dictionary, जिन्हें selectors द्वारा संदर्भित किया जाता है। यदि block batches स्वीकार करता है, तो इनपुट का प्रकारdataफ़ील्ड का इनपुट प्रकार होगाDict[str, Union[Batch[Any], Any]]. non-batch मामलों में, selector द्वारा संदर्भित non-batch-oriented data स्वतः broadcast किया जाता है, जबकि batches स्वीकार करने वाले blocks के लिए -Batchcontainer केवल batch-oriented inputs को wrap करता है, जबकि अन्य inputs को singular values के रूप में पास किया जाता है।
ऐसा ब्लॉक निम्नलिखित स्टेप घोषणा के साथ संगत है:
व्यावहारिक प्रभाव निम्न होंगे:
के अंतर्गत
data["a"]के अंदरrun(...)आप model की predictions पाएंगे - जैसेsv.Detectionsयदिmodel_1object-detection model हैके अंतर्गत
data["b"]के अंदरrun(...), आपको input parameter जिसका नामmy_parameter
इनपुट और आउटपुट dimensionality बनाम run(...) मेथड
block inputs की dimensionality method की signature को आकार देने में एक महत्वपूर्ण भूमिका निभाती है, और इसी कारण system inputs के बीच dimensionality levels के अंतर पर कड़ी सीमाएँ लागू करता है (जहाँ अधिकतम अनुमत अंतर run(...) )। यह प्रतिबंध blocks लिखते समय consistency और predictability सुनिश्चित करने के लिए महत्वपूर्ण है। 1). यह प्रतिबंध blocks लिखते समय consistency और predictability सुनिश्चित करने के लिए महत्वपूर्ण है।
यदि dimensionality के अंतर नियंत्रित नहीं किए गए, तो method की संरचना का अनुमान लगाना कठिन हो जाएगा, जिससे development कठिन और कम विश्वसनीय हो जाएगी। इसी कारण Workflow compilation प्रक्रिया के दौरान इस property का validation कड़ाई से लागू किया जाता है। run(...) method, जिससे development कठिन और कम विश्वसनीय हो जाएगी। इसी कारण Workflow compilation प्रक्रिया के दौरान इस property का validation कड़ाई से लागू किया जाता है।
इसी तरह, output dimensionality भी method signature और अपेक्षित output के format को प्रभावित करती है। ecosystem निम्न scenarios का समर्थन करता है:
सभी inputs की एक ही dimensionality और outputs नहीं बदलती dimensionality - baseline case
सभी inputs की एक ही dimensionality और output घटती है dimensionality
सभी inputs की एक ही dimensionality और output बढ़ती है dimensionality
inputs की अलग-अलग dimensionality और output को संदर्भ input
consistency सुनिश्चित करने और method signatures में ambiguity रोकने के लिए input/output dimensionalities के अन्य संयोजन अनुमत नहीं हैं।
batches disabled - `run(...)` method पर dimensionality का प्रभाव
output dimensionality में वृद्धि
इस उदाहरण में, हम predictions के आधार पर image का dynamic crop करते हैं।
पंक्तियों में
28-30manifest class output dimensionality offset घोषित करती है - मान1को1dimensionality level में जोड़ने के रूप में समझा जाना चाहिएयह ध्यान दिलाता है कि पंक्ति
63, block आगे की processing से खाली images को हटाता है, लेकिन output dictionary के बजायNoneका उपयोग करता है। इससे वही Execution Engine व्यवहार उपयोग में आता है जो conditional execution के लिए इस्तेमाल होता है - datapoint downstream processing से हटा दिया जाएगा (जब तक कि आगे ऐसी steps मौजूद न हों जो empty inputs मांगती हों)।पंक्तियों में
64-65एकल input के लिए परिणामimageऔरpredictionsएकत्र किए जाते हैं - इसका आशय dictionaries की एक सूची से है, जिसमें registered outputs सभी keys के रूप में शामिल हों। Execution engine समझ जाएगा कि step हर input element के लिए elements का batch लौटाता है और downstream steps के execution के दौरान track रखने के लिए indices की nested structures बनाएगा।
output dimensionality में कमी
इस उदाहरण में, block crops predictions को visualise करता है और सभी crop predictions को एक single output image में प्रस्तुत करने वाले tiles बनाता है।
पंक्तियों में
30-32manifest class output dimensionality offset घोषित करती है - मान-1को dimensionality level में घटाने के रूप में समझा जाना चाहिए1पंक्तियों में
34-36manifest class घोषित करती हैrun(...)method inputs जो auto-batch casting के अधीन होंगे, यह सुनिश्चित करते हुए कि signature हमेशा स्थिर रहे। Auto-batch casting Execution Engine मेंv0.1.6.0देखें changelog अधिक विवरण के लिए।
पंक्तियों में
53-55आप method signature पर output dimensionality में कमी के प्रभाव को देख सकते हैं। पहले दो inputs (पंक्ति में घोषित36) कृत्रिम रूप से wrap किए जाते हैंBatch[]container, जबकिscalar_parameterprimitive type बना रहता है। यह Execution Engine द्वारा output dimensionality में कमी होने पर स्वतः किया जाता है, जब सभी inputs की dimensionality समान हो, ताकि अंतिम dimensionality level पर मौजूद सभी elements तक पहुँच संभव हो सके। स्पष्ट रूप से, केवल top-level batch के उसी element से संबंधित elements को ही एक साथ group किया जाएगा। उदाहरण के लिए, यदि आपके पास दो input images थीं जिन्हें आपने crop किया - तो उन दो अलग-अलग images के crops अलग-अलग group किए जाएंगे।पंक्तियाँ
65-66यह दिखाता है कि output कैसे निर्मित होता है - एक एकल value लौटाई जाती है और उस value को Execution Engine द्वारा reduced dimensionality वाले output batch में index किया जाएगा
अलग-अलग input dimensionalities
इस उदाहरण में, block उन detections को merge करता है जो मूल image के crops के आधार पर predict की गई थीं - परिणामस्वरूप एकल detections प्रदान की जाती हैं जिनमें सभी आंशिक detections merged होती हैं।
पंक्तियों में
31-36manifest class input dimensionalities offset घोषित करती है, जो यह संकेत देता हैimageकि parameter top-level है औरimage_predictionspredictions का nested batch हैजब भी अलग-अलग input dimensionalities घोषित की जाती हैं, dimensionality reference property को निर्दिष्ट करना आवश्यक होता है (देखें पंक्तियाँ
38-40) - इस dimensionality level का उपयोग output dimensionality की गणना के लिए किया जाएगा - इस विशेष मामले में, हम निर्दिष्ट करते हैंimage. इस चुनाव का result के अपेक्षित format पर प्रभाव पड़ता है - चुने गए scenario में हमें सभी registered outputs keys के साथ एक single dictionary लौटानी होती है। यदि हमारा चुनावimage_predictionsहै, तो हम dictionaries की एक सूची लौटाएँगे (जिसका आकारimage_predictionsbatch की लंबाई के बराबर होगा)। दूसरे शब्दों में,get_dimensionality_reference_property(...)को output से किस dimensionality level को संबद्ध किया जाना चाहिए।पंक्तियाँ
63-64पंक्तियों में निर्दिष्ट dimensionality offsets के प्रभाव को प्रस्तुत करते हैं31-36. यह स्पष्ट रूप से दिखाई देता है किimage_predictionsके संदर्भ में एक nested batch हैimage. स्पष्ट रूप से, केवल specificimages से संबंधित nested predictionsको batch में group किया जाता है और runtime में method को प्रदान किया जाता है।जैसा कि पहले उल्लेख किया गया है, पंक्ति
69output को single dictionary के रूप में बनाती है, क्योंकि हम output कोimageकी dimensionality level पर register करते हैं
batches enabled - `run(...)` method पर dimensionality का प्रभाव
output dimensionality में वृद्धि
इस उदाहरण में, हम predictions के आधार पर image का dynamic crop करते हैं।
पंक्तियों में
29-31manifest घोषित करती है कि block inputs के batches स्वीकार करता हैपंक्तियों में
33-35manifest class output dimensionality offset घोषित करती है - मान1को1dimensionality level में जोड़ने के रूप में समझा जाना चाहिएपंक्तियों में
55-66, input parameters की signature यह दर्शाती है किrun(...)method समान dimensionality वाले inputs के विरुद्ध चलता है और वे inputs batches में प्रदान किए जाते हैंयह ध्यान दिलाता है कि पंक्ति
70, block आगे की processing से खाली images को हटाता है, लेकिन output dictionary के बजायNoneका उपयोग करता है। इससे वही Execution Engine व्यवहार उपयोग में आता है जो conditional execution के लिए इस्तेमाल होता है - datapoint downstream processing से हटा दिया जाएगा (जब तक कि आगे ऐसी steps मौजूद न हों जो empty inputs मांगती हों)।output का निर्माण, पंक्तियों में प्रस्तुत
71-73दो nesting levels को इंगित करता है। सबसे पहले, block batches पर कार्य करता है, इसलिए outputs की एक सूची लौटाने की अपेक्षा की जाती है, जहाँ प्रत्येक input batch element के लिए एक output होगा। इसके अतिरिक्त, प्रत्येक input batch element के लिए यह output element nested batch निकला - इसलिए प्रत्येक input image और prediction के लिए, block outputs की एक सूची उत्पन्न करता है - उस सूची के तत्व dictionaries होते हैं जो प्रत्येक घोषित output के लिए मान प्रदान करते हैं।
output dimensionality में कमी
इस उदाहरण में, block crops predictions को visualise करता है और सभी crop predictions को एक single output image में प्रस्तुत करने वाले tiles बनाता है।
पंक्तियाँ
29-31manifest यह अपेक्षा करती है कि block input के रूप में batches लेपंक्तियों में
33-35manifest class output dimensionality offset घोषित करती है - मान-1को dimensionality level में घटाने के रूप में समझा जाना चाहिए1पंक्तियों में
52-53आप output dimensionality में कमी और batch processing का method signature पर प्रभाव देख सकते हैं। पहला "layer"Batch[]का परिणाम है कि manifest ने घोषित किया है कि block inputs के batches स्वीकार करता है। दूसरा "layer" output dimensionality में कमी के कारण आता है। Execution Engine कम की जाने वाली dimension को input में प्रदान किए गए अतिरिक्तBatch[]container में लपेटता है, ताकि programmer उन सभी nested batch elements को एकत्र कर सके जो किसी विशिष्ट top-level batch element से संबंधित हैं।पंक्तियाँ
66-67यह दिखाता है कि output कैसे निर्मित होता है - प्रत्येक top-level batch element के लिए, block सभी crops और predictions को aggregate करता है और एक single tile बनाता है। चूँकि block inputs के batches स्वीकार करता है, यह प्रक्रिया प्रत्येक top-level batch element के लिए एक tile के साथ समाप्त होती है - इसलिए dictionaries की एक सूची लौटाई जानी अपेक्षित है।
अलग-अलग input dimensionalities
इस उदाहरण में, block उन detections को merge करता है जो मूल image के crops के आधार पर predict की गई थीं - परिणामस्वरूप एकल detections प्रदान की जाती हैं जिनमें सभी आंशिक detections merged होती हैं।
पंक्तियाँ
31-33manifest यह अपेक्षा करती है कि block input के रूप में batches लेपंक्तियों में
35-40manifest class input dimensionalities offset घोषित करती है, जो यह संकेत देता हैimageकि parameter top-level है औरimage_predictionspredictions का nested batch हैजब भी अलग-अलग input dimensionalities घोषित की जाती हैं, dimensionality reference property को निर्दिष्ट करना आवश्यक होता है (देखें पंक्तियाँ
42-44) - इस dimensionality level का उपयोग output dimensionality की गणना के लिए किया जाएगा - इस विशेष मामले में, हम निर्दिष्ट करते हैंimage. इस चुनाव का result के अपेक्षित format पर प्रभाव पड़ता है - चुने गए scenario में हमें nested batch के प्रत्येक element के लिए एक single dictionary लौटानी होती है। यदि हमारा चुनावimagebatch. यदि हमारा चुनावimage_predictionsहै, तो हम dictionaries की एक सूची लौटाएँगे (जिसका आकार nestedimage_predictionsbatch की लंबाई के बराबर होगा) प्रत्येक inputimagebatch element के लिए।पंक्तियाँ
66-67पंक्तियों में निर्दिष्ट dimensionality offsets के प्रभाव को प्रस्तुत करते हैं35-40साथ ही पंक्तियों में batch processing की घोषणा32-34. पहले "layer" काBatch[]container बाद वाले, nestedBatch[Batch[]]के लिएimages_predictionsकी input dimensionality offset की परिभाषा से आता है। यह स्पष्ट रूप से दिखाई देता है किimage_predictionsविशिष्ट तत्वों से संबंधित predictions का batch holds करता हैimageबैच के प्रत्येक और हर तत्व के लिए।जैसा कि पहले उल्लेख किया गया है, पंक्तियाँ
76-77output को प्रत्येक element के लिए single dictionary के रूप में बनाती हैंimagebatch
खाली inputs स्वीकार करने वाला block
जैसा कि पहले चर्चा की गई है, Workflow के निष्पादन के दौरान कुछ batch elements "empty" हो सकते हैं। यह कई कारणों से हो सकता है:
Flow-control mechanisms: निष्पादन की कुछ branches विशिष्ट batch elements को mask कर सकती हैं, जिससे वे subsequent steps में processed होने से बच जाती हैं।
Data-processing blocks में: कुछ मामलों में, block किसी विशिष्ट data point के लिए meaningful output उत्पन्न करने में सक्षम नहीं हो सकता। उदाहरण के लिए, Dynamic Crop block bounding box size शून्य होने पर cropped image नहीं बना सकता।
कुछ blocks इन empty inputs को संभालने के लिए बनाए गए हैं, जैसे ऐसा block जो missing outputs को default values से बदल सकता है। यह block Workflow में structured outputs बनाते समय विशेष रूप से उपयोगी हो सकता है, यह सुनिश्चित करते हुए कि कुछ elements empty होने पर भी output में अनुपस्थित elements न रहें, जिससे उसे parse करना कठिन हो जाएगा।
खाली inputs स्वीकार करने वाला block
पंक्तियों में
20-22आपको ऐसा declaration मिल सकता है जो बताता है कि block empty inputs स्वीकार करता हैपंक्तियों का परिणाम है
20-22का प्रभाव पंक्ति में दिखाई देता है41, जब signature बताती है कि inputBatchमें empty elements हो सकते हैं जिन्हें संभालना आवश्यक है। वास्तव में - block एक "artificial" output उत्पन्न करता है जो empty value के स्थान पर आता है, जिससे उन outputs का इस block के output को संदर्भित करने वाले और empty inputs स्वीकार न करने वाले blocks के लिए "visible" होना संभव हो जाता है। आपको मानना चाहिए कि हर input जिसे Execution Engine runtime में generated data से substitute करता है, optional elements प्रदान कर सकता है।
कस्टम constructor parameters वाला block
कुछ blocks को काम करने के लिए बाहर की दुनिया द्वारा बनाए गए objects की आवश्यकता हो सकती है। ऐसे scenario में, Workflows Execution Engine का काम उन entities को block तक पहुँचाना है, जिससे उनका उपयोग संभव हो सके। इस mechanism का वर्णन Workflows Compiler प्रस्तुत करने वाले पृष्ठ पर किया गया है, क्योंकि यही घटक blocks classes से steps के dynamic construction के लिए जिम्मेदार है।
Constructor parameters होने चाहिए:
block द्वारा अनुरोधित - class method का उपयोग करके
WorkflowBlock.get_init_parameters(...)Workflows Execution Engine चलाने वाले environment में प्रदान किए गए:
सीधे, जैसा कि इस उदाहरण में दिखाया गया है
defaults का उपयोग करके Workflow plugin के लिए registered
आइए देखें कि block को परिभाषित करते समय init parameters कैसे अनुरोध किए जाएँ।
Constructor parameters का अनुरोध करने वाला block
पंक्तियाँ
30-31ऐसा class constructor घोषित करें जो parameter-free न होExecution Engine को यह बताने के लिए कि block को custom initialisation की आवश्यकता है,
get_init_parameters(...)पंक्तियों में method33-35उन सभी parameters के नामों की सूची बनाता है जिन्हें प्रदान किया जाना चाहिए
Air-gapped / offline उपलब्धता metadata
ऐसे environments के लिए blocks बनाते समय जो इंटरनेट पहुँच के बिना चल सकते हैं (air-gapped deployments), WorkflowBlockManifest तीन वैकल्पिक classmethods प्रदान करता है। air-gapped workflow builder को यह निर्धारित करने में मदद करने के लिए इन्हें override करें कि कौन से blocks offline उपयोग योग्य हैं।
तीनों के समझदारी भरे defaults हैं, इसलिए existing blocks को कोई परिवर्तन नहीं.
get_air_gapped_availability()
यह घोषित करता है कि block इंटरनेट के बिना काम कर सकता है या नहीं। इसे उन blocks में override करें जो cloud APIs (OpenAI, Anthropic, आदि) को call करते हैं।
डिफ़ॉल्ट रूप से लौटाता है AirGappedAvailability(available=True) - pure-logic blocks, local-network blocks, और किसी भी ऐसे block के लिए उपयुक्त है जिसे external connectivity की आवश्यकता नहीं है।
get_supported_model_variants()
ऐसे foundation-model blocks के लिए जिनके weights को स्थानीय रूप से pre-cache किया जा सकता है, model variant IDs की सूची लौटाएँ। यदि कोई भी variant के पास cached artifacts हों तो block को offline उपलब्ध माना जाता है।
डिफ़ॉल्ट रूप से लौटाता है None, जिसका अर्थ है कि block स्थानीय रूप से cached model weights पर निर्भर नहीं करता।
get_compatible_task_types()
Roboflow-model ब्लॉकों के लिए जो उपयोगकर्ता-प्रशिक्षित मॉडल स्वीकार करते हैं, उन टास्क प्रकारों को लौटाएँ जिन्हें यह ब्लॉक संभाल सकता है। एयर-गैप्ड बिल्डर इसका उपयोग कैश किए गए उपयोगकर्ता मॉडलों को संगत ब्लॉकों से मिलाने के लिए करता है।
डिफ़ॉल्ट रूप से लौटाता है None - उन ब्लॉकों के लिए उपयुक्त है जो Roboflow मॉडल द्वारा पैरामीटराइज़्ड नहीं हैं (foundation models, logic blocks, sinks, आदि)।
रनटाइम प्रतिबंध
कुछ ब्लॉक अलग तरह से व्यवहार करते हैं - या पूरी तरह विफल हो जाते हैं - इस पर निर्भर करते हुए कि वे किस रनटाइम में तैनात हैं (hosted serverless, dedicated deployment, self-hosted, inference pipeline), स्टेप execution mode (local vs. remote), और input mode (image vs. video)। Override get_restrictions() में WorkflowBlockManifest इन चेतावनियों को ब्लॉक के भीतर एक बार घोषित करने के लिए, ताकि execution engine, schema endpoint, और auto-generated block gallery सभी उन्हें एकसमान रूप से दिखा सकें।
डिफ़ॉल्ट रूप से लौटाता है []तो मौजूदा ब्लॉकों को कोई परिवर्तन नहीं.
गंभीरता: soft बनाम hard
प्रत्येक प्रतिबंध के साथ एक गंभीरता:
Severity.SOFT- ब्लॉक पूरी तरह चलता है और सही output shape लौटाता है, लेकिन मान खराब या अर्थहीन हो जाते हैं (जैसे tracker IDs अनुरोधों के बीच रीसेट हो जाते हैं, cooldown throttle नहीं करता, फ़ाइल ephemeral disk पर लिखी जाती है)। workflow फिर भी चलता रहता है; परिणाम बस वैसा नहीं होता जैसा उपयोगकर्ता अपेक्षा करता है।Severity.HARD- ब्लॉक नहीं चलता / exception फेंकता है / इस रनटाइम में उपयोगी output नहीं दे सकता। engine को compile करने से इनकार करना चाहिए या fail-fast होना चाहिए।
एक प्रतिबंध की scope तय करना
एक RuntimeRestriction तीनों अक्षों में से किसी भी संयोजन के साथ स्वयं को scope कर सकता है। जब कोई अक्ष Noneके रूप में छोड़ा जाता है, तो प्रतिबंध उस अक्ष के हर मान पर लागू होता है।
applies_to_runtimes:Runtime.HOSTED_SERVERLESS,Runtime.DEDICATED_DEPLOYMENT,Runtime.SELF_HOSTED_CPU,Runtime.SELF_HOSTED_GPU,Runtime.INFERENCE_PIPELINE.applies_to_step_execution_modes:StepExecutionMode.LOCAL,StepExecutionMode.REMOTE.applies_to_input_modes:RuntimeInputMode.IMAGE,RuntimeInputMode.VIDEO.
The note field विफलता मोड या degraded behavior का एक-पंक्ति, मानव-पठनीय विवरण है - बताइए क्या होता है (जैसे "track_ids requests के बीच reset हो जाते हैं", "ephemeral /tmp पर लिखता है"), न कि अमूर्त पूर्व-शर्तें।
साझा presets
अधिकांश चेतावनियाँ कुछ सामान्य पैटर्नों में आती हैं, इसलिए कोडबेस में शब्दावली एकसमान रखने के लिए dataclasses के साथ reusable presets भी export किए जाते हैं। पहले इनका उपयोग करें:
STATEFUL_VIDEO_HTTP_SOFT_RESTRICTION- उन video-tracking / counting / aggregation blocks के लिए जिनकी per-video state process memory में रहती है और stateless HTTP requests के बीच रीसेट हो जाती है।COOLDOWN_HTTP_SOFT_RESTRICTION- उन blocks के लिए जिनका cooldown / rate-limit timer process memory में रखा जाता है और इसलिए multi-replica HTTP runtimes पर throttle नहीं करता।STILL_IMAGE_INPUT_SOFT_RESTRICTION- उन blocks के लिए जो temporal context (video या repeated frames) पर निर्भर करते हैं और still images पर बहुत कम या कोई लाभ नहीं देते।
उदाहरण
एक line-counter block जो per-video state बनाए रखता है और still image पर अर्थहीन भी है, दोनों प्रतिबंध घोषित करता है:
एक custom restriction (उदा. एक Severity.HARD block जिसे GPU hardware चाहिए जो hosted serverless runtime पर उपलब्ध नहीं है) inline घोषित किया जाता है:
इस तरह घोषित प्रतिबंध तीन जगहों पर दिखाई देते हैं:
The
describe_interfaceHTTP payload (viaRuntimeRestriction.to_dict()), ताकि workflow clients और builders workflow चलाने से पहले उपयोगकर्ताओं को चेतावनी दे सकें।block के लिए auto-generated block gallery पेज पर, "Runtime compatibility" सेक्शन के तहत, ठीक Properties.
execution engine, जो
Severity.HARDcurrent runtime के लिए प्रतिबंधों पर fail-fast करने का विकल्प चुन सकता है।
निर्भर संसाधनों की घोषणा करना
कई blocks को चलने के समय बाहरी संसाधनों की आवश्यकता होती है: Roboflow-trained या foundation model weights, Roboflow projects (जैसे active-learning targets, dataset-upload destinations) या third-party hosted models (OpenAI, Anthropic, OpenRouter, ...). जब तक कोई workflow वास्तव में execute नहीं होता, सिस्टम में कोई नहीं जानता कि उसे किन संसाधनों की ज़रूरत होगी।
Override करना discover_dependent_resources() को block manifest पर करने से यह अंतर भर जाता है: यह method parsed manifest instanceपर call की जाती है, इसलिए यह किसी दिए गए step के concrete field values से declaration निकाल सकती है। इससे callers पूरे workflow के resources को static रूप से — compile time पर, बिना कुछ execute किए — enumerate कर सकते हैं, जिससे model weights को पहले से load करना (predictable execution times के लिए) या यह upfront सत्यापित करना कि किसी API key की पहुँच हर संदर्भित model और project तक है, जैसे use cases संभव होते हैं।
डिफ़ॉल्ट रूप से लौटाता है None, जिसका अर्थ है कि block घोषित नहीं करता अपनी dependencies — callers को इसे अज्ञातमानना होगा। यह जानबूझकर []से अलग है, जो स्पष्ट रूप से घोषित करता है कि block को किसी बाहरी संसाधन की आवश्यकता नहीं है। मौजूदा blocks में कोई बदलाव आवश्यक नहीं; जो blocks संसाधनों का उपयोग करते हैं उन्हें override करना चाहिए।
resource envelope
Blocks resource shapes का आविष्कार नहीं करते — envelope Execution Engine द्वारा नियंत्रित होता है। एक DependentResource एक resource_type को उस type के लिए पंजीकृत typed (pydantic) metadata entity के साथ जोड़ता है:
DependentResourceType.ROBOFLOW_PLATFORM_MODEL→RoboflowPlatformModelMetadata(model_id, required_action, execution_location)— Roboflow platform के माध्यम से serve किए गए models, जिनमें synthesized ids वाले foundation / core models भी शामिल हैं (जैसेclip/ViT-B-32).required_actionउपयोग की प्रकृति बताता है:ModelRequiredAction.EXECUTION(weights खींचे जाते हैं या inference अनुरोधित होता है) याModelRequiredAction.ACCESS(model entity को केवल platform पर पहुँच योग्य होना चाहिए — जैसे कोई monitoring sink उससे metadata जोड़ रहा हो)। execution के लिए,execution_locationहैLOCAL,REMOTE, याENVIRONMENT_DEFINEDजब locality runtime परWORKFLOWS_STEP_EXECUTION_MODEद्वारा तय होती है और compile time पर निर्धारित नहीं की जा सकती (step execution mode पर dispatch करने वाले model blocks के लिए default)।DependentResourceType.ROBOFLOW_PLATFORM_PROJECT→RoboflowPlatformProjectMetadata(project_url)— Roboflow projects जिनसे block पढ़ता है या जिनमें लिखता है।DependentResourceType.THIRD_PARTY_MODEL→ThirdPartyModelMetadata(provider, model_id)— external provider द्वारा execute किए गए models; परिभाषा से remote execution।
Factory helpers implementations को one-liner बनाए रखते हैं: roboflow_platform_model(), roboflow_platform_project(), third_party_model().
Selector values और runtime resolution
Manifest fields concrete values के बजाय workflow selectors रख सकते हैं। Declaration ऐसे values को verbatim लौटाती है — block selectors को कभी resolve नहीं करता। Callers $inputs.<name> references को runtime parameters ज्ञात होने के बाद substitute कर सकते हैं; $steps.<name>.<property> references किसी भी तरह statically resolvable नहीं हैं। हर metadata entity requires_runtime_resolution() expose करती है, ताकि callers concrete identifier और ऐसे reference में फर्क कर सकें जिसे अभी resolve करना बाकी है।
जब अंतिम identifier एक function होता है field value का (जैसे family prefix clip/<version>का, एक catalog lookup), तो बदला गया input value अकेले executed id नहीं होता। ऐसी declarations एक model_id_resolver जोड़ती हैं — closure में अपनी सभी ज़रूरी चीज़ों के साथ एक callable — जो substituted value को final id में बदलता है। resolver केवल in-process सहायता है: इसे serialization, JSON schema और equality से बाहर रखा जाता है। in-process callers (जैसे engine का first-run pre-loading) input value substitute करने के बाद इसे invoke करते हैं। Resolver None लौटा सकता है ताकि value को statically unresolvable घोषित किया जा सके (final id उस एक value से अधिक पर निर्भर है) — ऐसे dependencies को callers छोड़ देते हैं और execution उन्हें resolve करता है; raise करना मतलब value वास्तव में अमान्य है।
जो run() load करता है
घोषित identifier बिल्कुल वही होना चाहिए जिसे run() request करेगा — version fields से synthesized ids सहित। यदि आपका block f"my_family/{self.version}" को load_core_model(...) call site पर बनाता है, तो declaration को वही id बनानी चाहिए (और जब version field में selector हो तो verbatim selector पर वापस जाना चाहिए)।
उदाहरण
एक model block जो अपना model और एक वैकल्पिक active-learning target project घोषित करता है:
एक block जिसका model id एक version field से synthesized होता है:
एक sink जो execution किए बिना केवल model entity को संदर्भित करता है:
कब घोषित न करें
वे Fields जो केवल ले जाते हैं एक model-id- या project-kind value को generic payload के रूप में (जैसे query parameters के रूप में values forward करने वाला webhook sink) resource dependencies नहीं हैं — ऐसे blocks जानबूझकर default बनाए रखते हैं।
core repository के contributors को यह unit test (tests/workflows/unit_tests/core_steps/test_dependent_resources.py) सीमा की रक्षा करता है, यह मानना चाहिए: हर core block जिसका manifest roboflow_model_id या roboflow_project kind के साथ कोई field घोषित करता है, उसे या तो override करना होगा discover_dependent_resources() या स्पष्ट रूप से carry-only के रूप में allowlist किया जाना होगा।
जो blocks अपने model weights model manager के बाहर load करते हैं (देखें कि run() वास्तव में क्या करता है, न कि यह कि model_manager init parameters में दिखाई देता है या नहीं) उन्हें अभी इस method को implement नहीं करना चाहिए — उनकी dependencies undeclared रहती हैं (None).
Custom python blocks हमेशा रिपोर्ट करते हैं None: उनका code static analysis के लिए opaque है, इसलिए अज्ञात ही एकमात्र ईमानदार उत्तर है।
अंतिम अपडेट
क्या यह उपयोगी था?