TensorFlow Lite ऑपरेटर के वर्शन

इस दस्तावेज़ में, TensorFlow Lite के ऑपरेशन स्कीमा के बारे में बताया गया है. Op वर्शन वाले वर्शन की मदद से, डेवलपर मौजूदा ऑपरेशन में नई सुविधाएं और पैरामीटर जोड़ सकते हैं. इसके अलावा, यह इन चीज़ों की गारंटी भी देता है:

  • पुराने सिस्टम के साथ काम करने की सुविधा: TensorFlow Lite के नए वर्शन को लागू करने पर, पुराने मॉडल वाली फ़ाइल का इस्तेमाल किया जाना चाहिए.
  • आगे के वर्शन के साथ काम करने की सुविधा: TensorFlow Lite के पुराने वर्शन को कन्वर्टर के नए वर्शन से बनी नई मॉडल फ़ाइल को हैंडल करना चाहिए. हालांकि, इसके लिए ज़रूरी है कि किसी नई सुविधा का इस्तेमाल न किया जा रहा हो.
  • यह सुविधा, पुराने वर्शन के साथ काम नहीं करती है: अगर पुराने TensorFlow Lite के काम करने के तरीके को लागू करने के बाद किसी नए मॉडल को पढ़ा जाता है, जिसमें किसी ऐसे ऑपर्च्यूनिटी का नया वर्शन है जो काम नहीं करता, तो उसे गड़बड़ी की रिपोर्ट करनी चाहिए.

उदाहरण: डीप वाइज़ का कॉन्वलूशन में डाइलेशन जोड़ना

इस दस्तावेज़ के बाकी हिस्से में, TFLite में ऑप वर्शन के बारे में जानकारी दी गई है. इसमें यह जानकारी दी गई है कि डेप्थवाइज़ कॉन्वलूशन ऑपरेशन में डाइलेशन पैरामीटर कैसे जोड़े जाते हैं.

इस दस्तावेज़ को समझने के लिए, फैलाव की जानकारी होना ज़रूरी नहीं है. ध्यान दें:

  • पूर्णांक वाले दो नए पैरामीटर जोड़े जाएंगे: dilation_width_factor और dilation_height_factor.
  • गहराई में गहराई से पुष्टि करने वाले पुराने कर्नल, जो फैलाव के साथ काम नहीं करते हैं, डायलेशन फ़ैक्टर को 1 पर सेट करने के बराबर हैं.

फ़्लैटबफ़र स्कीमा बदलें

ऑपरेटर में नए पैरामीटर जोड़ने के लिए, lite/schema/schema.fbs में मौजूद विकल्पों की टेबल बदलें.

उदाहरण के लिए, डेप्थ वाइज कॉन्वलूशन के विकल्पों की टेबल इस तरह दिखती है:

table DepthwiseConv2DOptions {
  padding:Padding;
  stride_w:int;
  stride_h:int;
  depth_multiplier:int;
  fused_activation_function:ActivationFunctionType;
}

नए पैरामीटर जोड़ते समय:

  • यह बताने के लिए टिप्पणियां जोड़ें कि कौनसे पैरामीटर किस वर्शन पर काम करते हैं.
  • जब नए लागू किए गए पैरामीटर को जोड़े गए नए पैरामीटर के लिए डिफ़ॉल्ट वैल्यू मिलती है, तो लागू करने के तरीके को ठीक वैसे ही काम करना चाहिए जैसा लागू करने के पुराने तरीके से किया गया था.

नए पैरामीटर जोड़ने के बाद, टेबल कुछ इस तरह दिखेगी:

table DepthwiseConv2DOptions {
  // Parameters for DepthwiseConv version 1 or above.
  padding:Padding;
  stride_w:int;
  stride_h:int;
  depth_multiplier:int;
  fused_activation_function:ActivationFunctionType;
  // Parameters for DepthwiseConv version 2 or above.
  dilation_w_factor:int = 1;
  dilation_h_factor:int = 1;
}

नए स्कीमा के लिए, lite/schema/schema_generated.h फ़ाइल फिर से जनरेट की जानी चाहिए.

सी स्ट्रक्चर और कर्नेल लागू करने की प्रक्रिया को बदलें

TensorFlow Lite में, कर्नेल लागू करने की प्रक्रिया को फ्लैटबफ़र परिभाषा से अलग कर दिया जाता है. कर्नेल, lite/c/builtin_op_data.h में तय किए गए C स्ट्रक्चर से पैरामीटर को पढ़ते हैं.

डेप्थ वाइज का मूल कन्वलूशन पैरामीटर इस तरह है:

typedef struct {
  TfLitePadding padding;
  int stride_width;
  int stride_height;
  int depth_multiplier;
  TfLiteFusedActivation activation;
} TfLiteDepthwiseConvParams;

फ़्लैटबफ़र स्कीमा की तरह ही, यह बताने के लिए टिप्पणियां जोड़ें कि कौनसे पैरामीटर किस वर्शन से काम कर सकते हैं. नतीजा नीचे दिखाया गया है:

typedef struct {
  // Parameters for DepthwiseConv version 1 or above.
  TfLitePadding padding;
  int stride_width;
  int stride_height;
  int depth_multiplier;
  TfLiteFusedActivation activation;
  // Parameters for DepthwiseConv version 2 or above.
  int dilation_width_factor;
  int dilation_height_factor;
} TfLiteDepthwiseConvParams;

C स्ट्रक्चर से जोड़े गए नए पैरामीटर को पढ़ने के लिए, कृपया कर्नेल लागू करने की प्रक्रिया भी बदलें. यहां ब्यौरे को शामिल नहीं किया जाता.

फ़्लैटबफ़र रीडिंग कोड बदलें

फ़्लैटबफ़र को पढ़ने और सी स्ट्रक्चर बनाने का लॉजिक lite/core/api/flatbuffer_conversions.cc में है.

नए पैरामीटर को हैंडल करने के लिए फ़ाइल अपडेट करें, जैसा कि यहां दिखाया गया है:

TfLiteStatus ParseDepthwiseConv2D(const Operator* op,
                                  ErrorReporter* error_reporter,
                                  BuiltinDataAllocator* allocator,
                                  void** builtin_data) {
  CheckParsePointerParams(op, error_reporter, allocator, builtin_data);

  SafeBuiltinDataAllocator safe_allocator(allocator);

  std::unique_ptr<TfLiteDepthwiseConvParams,
                  SafeBuiltinDataAllocator::BuiltinDataDeleter>
      params = safe_allocator.Allocate<TfLiteDepthwiseConvParams>();
  TF_LITE_ENSURE(error_reporter, params != nullptr);

  const DepthwiseConv2DOptions* schema_params =
      op->builtin_options_as_DepthwiseConv2DOptions();

  if (schema_params != nullptr) {
    params->padding = ConvertPadding(schema_params->padding());
    params->stride_width = schema_params->stride_w();
    params->stride_height = schema_params->stride_h();
    params->depth_multiplier = schema_params->depth_multiplier();
    params->activation =
        ConvertActivation(schema_params->fused_activation_function());

    params->dilation_width_factor = schema_params->dilation_w_factor();
    params->dilation_height_factor = schema_params->dilation_h_factor();
  }

  *builtin_data = params.release();
  return kTfLiteOk;
}

यहां, Op वर्शन की जांच करने की ज़रूरत नहीं है. अगर नई प्रोसेस, किसी ऐसी पुरानी मॉडल फ़ाइल को पढ़ती है जिसमें डाइलेशन फ़ैक्टर मौजूद नहीं हैं, तो वह डिफ़ॉल्ट वैल्यू के तौर पर 1 का इस्तेमाल करेगा. साथ ही, नया कर्नेल पुराने कर्नेल के साथ लगातार काम करेगा.

kernel रजिस्ट्रेशन बदलें

म्युटेबलOp रिज़ॉल्यूशन (lite/mutable_op_resolver.h में बताए गए) में, ऑपरेशन कर्नेल को रजिस्टर करने के लिए कुछ फ़ंक्शन मिलते हैं. डिफ़ॉल्ट रूप से कम से कम और ज़्यादा से ज़्यादा वर्शन 1 होते हैं:

void AddBuiltin(tflite::BuiltinOperator op, TfLiteRegistration* registration,
                int min_version = 1, int max_version = 1);
void AddCustom(const char* name, TfLiteRegistration* registration,
               int min_version = 1, int max_version = 1);

पहले से मौजूद ऑपरेशन, lite/kernels/register.cc में रजिस्टर किए गए हैं. इस उदाहरण में, हमने एक नया ऑप कर्नेल लागू किया है जो DepthwiseConv2D के वर्शन 1 और 2 को हैंडल कर सकता है. इसलिए, हमें इस लाइन को बदलना होगा:

AddBuiltin(BuiltinOperator_DEPTHWISE_CONV_2D, Register_DEPTHWISE_CONV_2D());

इससे बदलें:

AddBuiltin(BuiltinOperator_DEPTHWISE_CONV_2D, Register_DEPTHWISE_CONV_2D(),
             /* min_version = */ 1,
             /* max_version = */ 2);

TFLite op वर्शन को बदलें

अगले कदम में, TFLite से उस कम से कम वर्शन को पॉप्युलेट करने की सुविधा होगी जो सेशन को चलाने के लिए ज़रूरी है. इस उदाहरण में, इसका मतलब है:

  • जब डायलेशन फ़ैक्टर सभी 1 हों, तब वर्शन=1 को पॉप्युलेट करें.
  • अगर ऐसा नहीं है, तो वर्शन=2 में जानकारी भरें.

lite/tools/versioning/op_version.cc में ऑपरेटर के लिए GetBuiltinOperatorVersion फ़ंक्शन में बदलाव करें. इसके लिए, DepthwiseConv2D के केस में नया वर्शन जोड़ें:

case BuiltinOperator_DEPTHWISE_CONV_2D:
  auto depthwise_conv_params =
      reinterpret_cast<TfLiteDepthwiseConvParams*>(op_sig.builtin_data);
  TFLITE_DCHECK(depthwise_conv_params != nullptr);
  if (depthwise_conv_params->dilation_width_factor != 1 ||
       depthwise_conv_params->dilation_height_factor != 1) {
    return 2;
  }
  return 1;

ऑपरेटर के वर्शन का मैप अपडेट करें

आखिरी कदम, ऑपरेटर वर्शन मैप में नई वर्शन की जानकारी जोड़ना है. यह चरण इसलिए ज़रूरी है, क्योंकि हमें इस वर्शन मैप के आधार पर, मॉडल के लिए ज़रूरी कम से कम रनटाइम वर्शन जनरेट करना है.

ऐसा करने के लिए, आपको lite/tools/versioning/runtime_version.cc में नई मैप एंट्री जोड़नी होगी.

इस उदाहरण में, आपको op_version_map में यह एंट्री जोड़नी होगी:

{ {BuiltinOperator_DEPTHWISE_CONV_2D, 2}, %CURRENT_RUNTIME_VERSION%}

जहां %CURRENT_RUNTIME_VERSION%, tensorflow/core/public/version.h में तय किए गए मौजूदा रनटाइम वर्शन से मेल खाता है.

डेलिगेशन लागू करना

TensorFlow Lite, एक डेलिगेशन एपीआई उपलब्ध कराता है. इसकी मदद से, हार्डवेयर बैकएंड को ऑपरेशन सौंपे जाते हैं. डेलिगेट के Prepare फ़ंक्शन में, देखें कि डेलिगेशन कोड के हर नोड के लिए वर्शन काम करता है या नहीं.

const int kMaxVersion = 1;
TfLiteNode* node;
TfLiteRegistration* registration = nullptr;
TF_LITE_ENSURE_STATUS(context->GetNodeAndRegistration(context, node_index, &node, &registration));

if (registration->version > kMaxVersion) {
  // Reject the node if the version isn't supported.
}

ऐसा करना तब भी ज़रूरी है, जब डेलिगेशन सिर्फ़ वर्शन 1 के ऑपरेशन के साथ काम करता हो. इसलिए, नया वर्शन मिलने पर डेलिगेशन सही तरीके से काम नहीं करता है.