निष्पादन इंजन
Workflows Execution Engine के अंदर: input validation, execution order, step inputs और outputs, और flow control।
यह कंपाइलेशन प्रक्रिया एक Workflow Execution ग्राफ बनाता है, जिसमें किसी Workflow definition को चलाने के लिए आवश्यक सभी विवरण होते हैं। इस अनुभाग में, हम execution process के विवरण समझाएँगे।
उच्च स्तर पर, यह प्रक्रिया निम्नलिखित करती है:
रनटाइम इनपुट का सत्यापन: यह जाँचता है कि Workflow definition के सभी आवश्यक placeholder डेटा से भरे गए हैं और सुनिश्चित करता है कि data types सही हों।
निष्पादन क्रम निर्धारित करता है: यह उस क्रम को परिभाषित करता है जिसमें steps निष्पादित होते हैं।
स्टेप इनपुट तैयार करता है और आउटपुट कैश करता है: यह प्रत्येक step के इनपुट व्यवस्थित करता है और future use के लिए आउटपुट सहेजता है।
अंतिम Workflow आउटपुट बनाता है: यह Workflow के समग्र परिणाम को जोड़कर तैयार करता है।
रनटाइम इनपुट का सत्यापन
Workflow definition, Workflow execution के लिए अपेक्षित inputs निर्दिष्ट करती है। जैसा कि चर्चा की गई पूर्व, inputs या तो steps द्वारा संसाधित किए जाने वाले batch-oriented data हो सकते हैं या ऐसे parameters जो step execution को कॉन्फ़िगर करते हैं। यह अंतर Workflow के चलने के तरीके के लिए महत्वपूर्ण है और इस पेज में आगे विस्तार से समझाया जाएगा।
इनपुट validation से शुरू करते हुए, Execution Engine में एक समर्पित component है जो input को parse करके उपयोग के लिए तैयार करता है। यह Workflow definition से batch-oriented inputs को पहचानता है और उन्हें एक आंतरिक representation में बदलता है (उदा., WorkflowImage बन जाता है Batch[WorkflowImageData]). इससे block developers डेटा के साथ आसानी से काम कर सकते हैं। Non-batch-oriented parameters की type consistency, उन block manifests के विरुद्ध जाँची जाती है जिनका उपयोग उन steps को बनाने के लिए किया गया है जिन्हें वे parameters चाहिए। इससे type errors execution process के शुरुआती चरण में ही पकड़ लिए जाते हैं।
सभी batch-oriented inputs का आकार या तो 1 या n होना चाहिए। जब किसी batch में केवल एक element होता है, तो उसे पूरे batch में स्वतः broadcast कर दिया जाता है।
निष्पादन क्रम निर्धारित करना
Workflow Execution Graph एक directed acyclic graph (DAG), जो हमें topological order निर्धारित करने देता है। Topological order उस क्रम को कहते हैं जिसमें Workflow steps निष्पादित होते हैं, यह सुनिश्चित करते हुए कि प्रत्येक step चलने से पहले उसकी dependencies पूरी हों। दूसरे शब्दों में, यदि कोई step किसी अन्य step के output पर निर्भर है, तो Workflow Engine सुनिश्चित करता है कि dependency step पहले निष्पादित हो।
इसके अतिरिक्त, topological संरचना हमें यह पहचानने देती है कि कौन से steps बिना race conditions पैदा किए parallel रूप से निष्पादित किए जा सकते हैं। Parallel execution, Workflows Execution Engine का default mode है। इसका अर्थ है कि model ensembling में उपयोग होने वाले multiple independent steps एक साथ चल सकते हैं, जिससे sequential processing की तुलना में execution speed में उल्लेखनीय सुधार होता है।
Execution Engine में parallel execution mode के कारण (और प्रत्येक step को भेजते समय अनावश्यक data copying से बचने के लिए), हम सभी block developers से दृढ़तापूर्वक आग्रह करते हैं कि वे block के run(...) method को दिए गए किसी भी data को mutate करने से बचें। यदि संशोधन आवश्यक हों, तो बदलाव करने से पहले हमेशा input object की एक copy बना लें!
स्टेप इनपुट और आउटपुट को संभालना
Execution Engine के लिए step inputs और outputs को संभालना एक जटिल कार्य है। इसमें शामिल है:
उनके inputs के संदर्भ में SIMD (Single Instruction, Multiple Data) और non-SIMD blocks के बीच अंतर करना।
conditional execution और अपेक्षित input dimensionality को ध्यान में रखते हुए step inputs तैयार करना।
उन steps के outputs को संभालना जो execution flow को नियंत्रित करते हैं।
data-processing steps के outputs दर्ज करना, यह सुनिश्चित करते हुए कि वे blocks द्वारा घोषित output dimensionality से मेल खाते हैं।
आइए इन प्रत्येक विषयों को विस्तार से समझें।
SIMD बनाम non-SIMD steps
जैसा कि definition से स्पष्ट है, SIMD (Single Instruction, Multiple Data) step batch-oriented data को संसाधित करता है, जहाँ वही operation प्रत्येक data point पर लागू होता है, और configuration के लिए non-batch-oriented parameters का उपयोग किया जा सकता है। ऐसे step से output एक elements के batch के रूप में अपेक्षित होता है, जो input batch elements के क्रम को बनाए रखता है। यह नियमित processing steps और flow-control steps दोनों पर लागू होता है (देखें blocks विकास मार्गदर्शिका), जहाँ flow-control निर्णय प्रत्येक batch element को अलग-अलग प्रभावित करते हैं।
मूल रूप से, step में दिया जाने वाला data का प्रकार निर्धारित करता है कि वह SIMD है या non-SIMD। यदि कोई step किसी भी batch-oriented input की माँग करता है, तो उसे SIMD step माना जाएगा।
इसके विपरीत, non-SIMD steps से input data के लिए एक single result देने की अपेक्षा की जाती है। non-SIMD flow-control steps के मामले में, वे batch के प्रत्येक element को अलग-अलग प्रभावित करने के बजाय सभी downstream steps को समग्र रूप से प्रभावित करते हैं।
ऐतिहासिक रूप से, Execution Engine उन सभी स्थितियों को अच्छी तरह संभाल नहीं पाता था जब non-SIMD steps के outputs, SIMD steps के inputs में दिए जाते थे - क्योंकि ऐसे outputs को SIMD steps में फ़ीड करते समय स्वतः batches में cast करने की क्षमता नहीं थी, जिसके कारण compilation error होता था। Execution Engine v1.6.0, के साथ SIMD और non-SIMD blocks के handling को निम्नलिखित के परिचय के माध्यम से बेहतर बनाया गया है: Auto Batch Casting:
जब कोई SIMD input पहचाना जाता है लेकिन उसे scalar data मिलता है, तो Execution Engine उसे स्वतः एक batch में cast कर देता है।
batch की dimensionality compile time पर निर्धारित की जाती है, उपयोग करते हुए लाइनिज़ जब उपलब्ध हो, तब अन्य batch-oriented inputs की जानकारी का। गायब dimensions को इसी तरह उत्पन्न किया जाता है जैसे
torch.unsqueeze(...).Outputs का मूल्यांकन casting context के विरुद्ध किया जाता है - उन्हें scalar के रूप में छोड़ दिया जाता है जब block output dimensionality को बनाए रखता है या घटाता है, या नए batches बनाता है जब dimensionality में वृद्धि अपेक्षित हो।
स्टेप इनपुट तैयार करना
प्रत्येक अनुरोधित input element batch-oriented हो सकता है या नहीं। Non-batch inputs अपेक्षाकृत आसान होते हैं; उन्हें विशेष treatment की आवश्यकता नहीं होती। Batch-oriented inputs के साथ, काफ़ी अधिक जटिलता होती है। Execution Engine प्रत्येक batch-oriented datapoint के लिए indices बनाए रखता है, उदाहरण के लिए:
यदि input images का batch है, तो प्रत्येक element को अपना एक unique index मिलेगा - मान लीजिए चार input images हैं, तो batch indices होंगे
[(0, ), (1, ), (2, ), (3, )].step output यदि non-nested batch हो, तो उसे भी indexed किया जाएगा; उदाहरण के लिए, ऊपर बताई गई प्रत्येक image के लिए मॉडल से आने वाली predictions भी indexed होंगी
[(0, ), (1, ), (2, ), (3, )].यदि कोई block बढ़ाता है
आयामीय स्तर- मान लीजिए object-detection model की predictions पर आधारित Dynamic Crop है - पहले image के लिए 2 crops, दूसरे के लिए 1 और चौथे के लिए 3 crops हैं - तो ऐसे step के output को निम्न प्रकार से index किया जाएगा:[(0, 0), (0, 1), (1, 0), (3, 0), (3, 1), (3, 2)].
steps execution के लिए inputs एकत्र करते समय elements का indexing महत्वपूर्ण है। इन्हीं की बदौलत सभी batch-oriented inputs aligned किए जा सकते हैं - ताकि Execution Engine हमेशा prediction भेज सके (3, ) image के साथ (3, ) और crops का batch [(3, 0), (3, 1), (3, 2)] जब कोई भी step इसकी माँग करे।
प्रत्येक अनुरोधित input element या तो batch-oriented हो सकता है या non-batch। Non-batch inputs सीधे-सादे होते हैं और विशेष handling की आवश्यकता नहीं होती। हालाँकि, batch-oriented inputs में अधिक जटिलता होती है। Execution Engine प्रत्येक batch-oriented data point के indices ट्रैक करता है। उदाहरण के लिए:
यदि input images का एक batch है, तो प्रत्येक element को अपना unique index मिलता है। चार images के batch के लिए, indices होंगे
[(0,), (1,), (2,), (3,)].ऐसा step output जो dimensionality नहीं बढ़ाता, उसे भी इसी तरह indexed किया जाएगा। उदाहरण के लिए, चारों images में से प्रत्येक के लिए model predictions के indices होंगे
[(0,), (1,), (2,), (3,)].यदि कोई block बढ़ाता है
dimensionality_level(उदा., object detection model की predictions पर आधारित dynamic crop), तो output को अलग तरीके से indexed किया जाएगा। मान लीजिए पहले image के लिए 2 crops, दूसरे के लिए 1, और चौथे के लिए 3 हैं। इस output के indices होंगे[(0, 0), (0, 1), (1, 0), (3, 0), (3, 1), (3, 2)].
step execution के दौरान inputs को संरेखित करने के लिए indexing अत्यंत महत्वपूर्ण है। Execution Engine सुनिश्चित करता है कि सभी batch-oriented inputs synchronized हों। उदाहरण के लिए, यह prediction को मिलाएगा (3,) image के साथ (3,) और crops के संबंधित batch को [(3, 0), (3, 1), (3, 2)] जब कोई step उन्हें माँगेगा।
Compilation के दौरान data lineage को क्रम में रखना execution को सरल बनाता है। Execution Engine को यह सत्यापित करने की आवश्यकता नहीं होती कि dynamically बनाए गए nested batches एक ही source से आए हैं या नहीं। उसका काम step inputs तैयार करते समय indices को align करना है।
अतिरिक्त विचार
इनपुट Dimensionality Offsets
Workflow blocks निर्धारित करते हैं कि input dimensionality को कैसे संभाला जाएगा। यदि Execution Engine input dimensionality में अंतर पहचानता है, तो वह बड़ी dimension को एक batch में wrap कर देगा। उदाहरण के लिए, यदि कोई block input images और dynamically cropped images दोनों को process करता है, तो बाद वाले को batch में wrap किया जाएगा ताकि प्रत्येक top-level image को उसके संबंधित crops के batch के साथ संसाधित किया जा सके।
गहराई से nested batches को step execution से पहले flatten किया जाता है
चूँकि block सभी inputs को एक ही dimensionality level पर परिभाषित करता है, इसलिए input batches का nesting कितना भी गहरा हो, step input को एक single batch में flatten किया जाएगा और outputs में indices को Execution Engine द्वारा स्वचालित रूप से बनाए रखा जाएगा।
शर्तीय निष्पादन
Flow-control blocks यह प्रबंधित करते हैं कि कुछ शर्तों के आधार पर कौन से steps निष्पादित किए जाने चाहिए। Compilation के दौरान, इन शर्तों से प्रभावित steps को चिह्नित किया जाता है। उनके inputs बनाते समय flow-control exclusion (SIMD- और non-SIMD-oriented दोनों) के लिए एक mask लागू किया जाता है। इस mask के आधार पर, विशिष्ट input elements को बदला जाएगा None, जो एक रिक्त मान का प्रतिनिधित्व करता है।
डिफ़ॉल्ट रूप से, blocks रिक्त मान स्वीकार नहीं करते, इसलिए कोई भी None index पर (i,) batch में होने पर उस index को processing से बाहर कर दिया जाएगा। Execution Engine के भीतर flow control इसी तरह प्रबंधित किया जाता है। हालाँकि, कुछ blocks खाली inputs को संभालने के लिए डिज़ाइन किए गए हैं। ऐसे मामलों में, flow-control mask लागू होने के बावजूद, खाली inputs input batch से हटाए नहीं जाएँगे।
Batch Processing Mode
Blocks या तो batch inputs को एक साथ process कर सकते हैं या, डिफ़ॉल्ट रूप से, Execution Engine को प्रत्येक input पर loop चलाकर block के run(...) method के return value में व्यक्त होता है।
flow-control steps के outputs का प्रबंधन
Flow-control steps के outputs अद्वितीय होते हैं क्योंकि ये steps तय करते हैं कि कौन से data points subsequent steps को दिए जाएँ, जो लगभग इस pseudocode के परिणाम के समान है:
Workflows Execution Engine flow-control steps के outputs को parse करके execution branches बनाता है। प्रत्येक branch के साथ एक संबद्ध mask होता है:
के लिए SIMD शाखाएँ, mask में उन indices का एक set होता है जो processing के लिए सक्रिय बने रहेंगे।
के लिए non-SIMD शाखाएँ, mask एक साधारण
True/Falseमान होता है जो निर्धारित करता है कि पूरी branch सक्रिय है या नहीं।
Flow-control step के निष्पादित होने के बाद, इस mask को पंजीकृत किया जाता है और निर्णय से प्रभावित किसी भी step पर लागू किया जाता है। इससे Engine downstream branch में processing से विशिष्ट data points को फ़िल्टर कर सकता है। यदि कोई data point branch के पहले step से बाहर कर दिया जाता है (masking के कारण), तो वह data point पूरे branch से स्वतः हटा दिया जाता है (डिफ़ॉल्ट रूप से खाली inputs को बाहर करने के परिणामस्वरूप)।
स्टेप outputs को कैश करना
केवल flow-control steps के परिणामों को ही सावधानी से संभालना नहीं होता - data processing steps भी ध्यान मांगते हैं ताकि उनके परिणाम अन्य steps तक सही ढंग से पहुँचें। यहाँ मुख्य पहलू outputs का सही indexing है।
सरल मामलों में, जहाँ सभी inputs एक ही आयामीय स्तर और output वही dimensionality बनाए रखता है, Execution Engine का मुख्य कार्य input indices का क्रम बनाए रखना होता है। हालाँकि, जब input dimensionalities अलग होती हैं, तो step बनाने के लिए उपयोग किया गया Workflow block यह निर्धारित करता है कि indexing कैसे संभाली जाए।
यदि processing के दौरान dimensionality बदलती है, तो Execution Engine या तो high-level index का उपयोग करता है या output में element lists की लंबाई के आधार पर गतिशील रूप से nested dimensions बनाता है। इससे steps के बीच data का सही alignment और tracking सुनिश्चित होती है।
Workflow outputs बनाना
outputs कैसे निर्मित किए जाते हैं, इस बारे में विवरण के लिए कृपया निम्न पर दी गई जानकारी देखें Workflows Definitions पृष्ठ और Output Construction Workflow Execution प्रलेखन के अनुभाग में।
Python में Execution Engine चलाना
Compiler और Execution Engine निम्न के साथ bundled हैं: inference package, इसलिए आप HTTP API के माध्यम से जाने के बजाय सीधे Python application के अंदर Workflow चला सकते हैं। यह उन टीमों के लिए उपयुक्त है जो:
अपना application Python में रखते हैं,
application process के भीतर resource-heavy computation स्वीकार करते हैं,
HTTP hop की latency और failure modes से बचना चाहते हैं,
Workflow execution पर पूर्ण नियंत्रण चाहते हैं।
यह सबसे अधिक demanding integration mode है: आप वे सभी initialization parameters प्रदान करते हैं जिनकी आपके Workflow के blocks को आवश्यकता होती है। उन parameters और उनके resolution का वर्णन निम्न में किया गया है ब्लॉक्स से वर्कफ़्लो चरणों को आरंभ करना.
Workflow चलाने के अन्य तरीकों के लिए, जिनमें HTTP, WebRTC video streaming, CLI, और Batch Processing शामिल हैं, देखें एक Workflow डिप्लॉय करें.
अंतिम अपडेट
क्या यह उपयोगी था?