पूरी तरह से कस्टम घटकों का निर्माण

यह मार्गदर्शिका बताती है कि पूरी तरह से कस्टम घटक बनाने के लिए टीएफएक्स एपीआई का उपयोग कैसे करें। पूरी तरह से कस्टम घटक आपको घटक विनिर्देश, निष्पादक और घटक इंटरफ़ेस कक्षाओं को परिभाषित करके घटक बनाने देते हैं। यह दृष्टिकोण आपको अपनी आवश्यकताओं के अनुरूप एक मानक घटक का पुन: उपयोग और विस्तार करने की सुविधा देता है।

यदि आप टीएफएक्स पाइपलाइनों में नए हैं, तो टीएफएक्स पाइपलाइनों की मुख्य अवधारणाओं के बारे में और जानें

कस्टम निष्पादक या कस्टम घटक

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

कस्टम घटक कैसे बनाएं?

पूरी तरह से कस्टम घटक विकसित करने के लिए आवश्यक है:

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

घटक विशिष्टता

ComponentSpec वर्ग एक घटक के इनपुट और आउटपुट कलाकृतियों के साथ-साथ घटक निष्पादन के लिए उपयोग किए जाने वाले मापदंडों को परिभाषित करके घटक अनुबंध को परिभाषित करता है। इसके तीन भाग हैं:

  • इनपुट : इनपुट कलाकृतियों के लिए टाइप किए गए मापदंडों का एक शब्दकोश जो घटक निष्पादक में पारित किया जाता है। आम तौर पर इनपुट कलाकृतियाँ अपस्ट्रीम घटकों से आउटपुट होती हैं और इस प्रकार एक ही प्रकार को साझा करती हैं।
  • आउटपुट : घटक द्वारा उत्पादित आउटपुट कलाकृतियों के लिए टाइप किए गए मापदंडों का एक शब्दकोश।
  • पैरामीटर : अतिरिक्त निष्पादन पैरामीटर आइटम का एक शब्दकोश जिसे घटक निष्पादक में पारित किया जाएगा। ये गैर-विरूपण साक्ष्य पैरामीटर हैं जिन्हें हम पाइपलाइन डीएसएल में लचीले ढंग से परिभाषित करना चाहते हैं और निष्पादन में पास करना चाहते हैं।

यहाँ ComponentSpec का एक उदाहरण दिया गया है:

class HelloComponentSpec(types.ComponentSpec):
  """ComponentSpec for Custom TFX Hello World Component."""

  PARAMETERS = {
      # These are parameters that will be passed in the call to
      # create an instance of this component.
      'name': ExecutionParameter(type=Text),
  }
  INPUTS = {
      # This will be a dictionary with input artifacts, including URIs
      'input_data': ChannelParameter(type=standard_artifacts.Examples),
  }
  OUTPUTS = {
      # This will be a dictionary which this component will populate
      'output_data': ChannelParameter(type=standard_artifacts.Examples),
  }

निर्वाहक

इसके बाद, नए घटक के लिए निष्पादक कोड लिखें। मूल रूप से, base_executor.BaseExecutor का एक नया उपवर्ग इसके Do फ़ंक्शन ओवरराइड के साथ बनाने की आवश्यकता है। Do फ़ंक्शन में, तर्क input_dict , output_dict और exec_properties जो मैप में INPUTS , OUTPUTS और PARAMETERS में पास किए जाते हैं जिन्हें क्रमशः कंपोनेंटस्पेक में परिभाषित किया जाता है। exec_properties के लिए, मूल्य सीधे शब्दकोश लुकअप के माध्यम से प्राप्त किया जा सकता है। input_dict और output_dict में कलाकृतियों के लिए, आर्टिफैक्ट_यूटिल्स क्लास में सुविधाजनक फ़ंक्शन उपलब्ध हैं जिनका उपयोग आर्टिफैक्ट इंस्टेंस या आर्टिफैक्ट यूरी लाने के लिए किया जा सकता है।

class Executor(base_executor.BaseExecutor):
  """Executor for HelloComponent."""

  def Do(self, input_dict: Dict[Text, List[types.Artifact]],
         output_dict: Dict[Text, List[types.Artifact]],
         exec_properties: Dict[Text, Any]) -> None:
    ...

    split_to_instance = {}
    for artifact in input_dict['input_data']:
      for split in json.loads(artifact.split_names):
        uri = artifact_utils.get_split_uri([artifact], split)
        split_to_instance[split] = uri

    for split, instance in split_to_instance.items():
      input_dir = instance
      output_dir = artifact_utils.get_split_uri(
          output_dict['output_data'], split)
      for filename in tf.io.gfile.listdir(input_dir):
        input_uri = os.path.join(input_dir, filename)
        output_uri = os.path.join(output_dir, filename)
        io_utils.copy_file(src=input_uri, dst=output_uri, overwrite=True)

यूनिट एक कस्टम निष्पादक का परीक्षण कर रही है

कस्टम निष्पादक के लिए यूनिट परीक्षण इसके समान बनाए जा सकते हैं।

घटक इंटरफ़ेस

अब जब सबसे जटिल हिस्सा पूरा हो गया है, तो अगला कदम इन टुकड़ों को एक घटक इंटरफ़ेस में इकट्ठा करना है, ताकि घटक को पाइपलाइन में उपयोग करने में सक्षम बनाया जा सके। कई चरण हैं:

  • घटक इंटरफ़ेस को base_component.BaseComponent का उपवर्ग बनाएं
  • ComponentSpec क्लास के साथ एक क्लास वेरिएबल SPEC_CLASS असाइन करें जिसे पहले परिभाषित किया गया था
  • एक्ज़ीक्यूटर क्लास के साथ एक क्लास वेरिएबल EXECUTOR_SPEC असाइन करें जिसे पहले परिभाषित किया गया था
  • कंपोनेंटस्पेक क्लास का एक उदाहरण बनाने के लिए फ़ंक्शन के तर्कों का उपयोग करके __init__() कंस्ट्रक्टर फ़ंक्शन को परिभाषित करें और वैकल्पिक नाम के साथ उस मान के साथ सुपर फ़ंक्शन को आमंत्रित करें।

जब घटक का एक उदाहरण बनाया जाता है, तो यह सुनिश्चित करने के लिए कि जो तर्क पारित किए गए थे, वे ComponentSpec वर्ग में परिभाषित प्रकार की जानकारी के साथ संगत हैं, यह सुनिश्चित करने के लिए base_component.BaseComponent वर्ग में टाइप चेकिंग लॉजिक को लागू किया जाएगा।

from tfx.types import standard_artifacts
from hello_component import executor

class HelloComponent(base_component.BaseComponent):
  """Custom TFX Hello World Component."""

  SPEC_CLASS = HelloComponentSpec
  EXECUTOR_SPEC = executor_spec.ExecutorClassSpec(executor.Executor)

  def __init__(self,
               input_data: types.Channel = None,
               output_data: types.Channel = None,
               name: Optional[Text] = None):
    if not output_data:
      examples_artifact = standard_artifacts.Examples()
      examples_artifact.split_names = input_data.get()[0].split_names
      output_data = channel_utils.as_channel([examples_artifact])

    spec = HelloComponentSpec(input_data=input_data,
                              output_data=output_data, name=name)
    super(HelloComponent, self).__init__(spec=spec)

टीएफएक्स पाइपलाइन में इकट्ठा करें

अंतिम चरण नए कस्टम घटक को टीएफएक्स पाइपलाइन में प्लग करना है। नए घटक का एक उदाहरण जोड़ने के अलावा, निम्नलिखित की भी आवश्यकता है:

  • नए घटक के अपस्ट्रीम और डाउनस्ट्रीम घटकों को उचित रूप से तार दें। यह नए घटक में अपस्ट्रीम घटक के आउटपुट को संदर्भित करके और डाउनस्ट्रीम घटकों में नए घटक के आउटपुट को संदर्भित करके किया जाता है।
  • पाइपलाइन का निर्माण करते समय घटकों की सूची में नया घटक उदाहरण जोड़ें।

नीचे दिया गया उदाहरण उपरोक्त परिवर्तनों पर प्रकाश डालता है। पूरा उदाहरण TFX GitHub रेपो में पाया जा सकता है।

def _create_pipeline():
  ...
  example_gen = CsvExampleGen(input_base=examples)
  hello = component.HelloComponent(
      input_data=example_gen.outputs['examples'], name='HelloWorld')
  statistics_gen = StatisticsGen(examples=hello.outputs['output_data'])
  ...
  return pipeline.Pipeline(
      ...
      components=[example_gen, hello, statistics_gen, ...],
      ...
  )

एक पूरी तरह से कस्टम घटक तैनात करें

कोड परिवर्तनों के अलावा, पाइपलाइन को ठीक से चलाने के लिए सभी नए जोड़े गए हिस्सों ( ComponentSpec , Executor , कंपोनेंट इंटरफ़ेस) को पाइपलाइन रनिंग वातावरण में पहुंच योग्य होना आवश्यक है।