গুগল আই/ও একটি মোড়ক! TensorFlow সেশনগুলি দেখুন সেশনগুলি দেখুন

একটি কাস্টম ডেলিগেট বাস্তবায়ন করা হচ্ছে

টেনসরফ্লো লাইট ডেলিগেট কী?

টেনসরফ্লো লাইট ডেলিগেট আপনাকে অন্য মডেলকে আপনার মডেলগুলি (অংশ বা পুরো) চালানোর অনুমতি দেয়। এই প্রক্রিয়াটি অনুমানের জন্য জিপিইউ বা এজ টিপিইউ (টেনসর প্রসেসিং ইউনিট) এর মতো বিভিন্ন অন-ডিভাইস এক্সিলিটরকে উপার্জন করতে পারে। এটি বিকাশকারীদের অনুমানের গতি বাড়ানোর জন্য ডিফল্ট টিএফলাইট থেকে নমনীয় এবং ডিকোপলড পদ্ধতি সরবরাহ করে।

নিচের চিত্রটি প্রতিনিধিদের সংক্ষিপ্তসার করেছে, নীচের বিভাগগুলিতে আরও বিশদ।

TFLite Delegates

আমি কখন কাস্টম প্রতিনিধি তৈরি করব?

টেনসরফ্লো লাইটে জিপিইউ, ডিএসপি, এজপিটিইউ এবং অ্যান্ড্রয়েড এনএনএপিআইয়ের মতো ফ্রেমওয়ার্কগুলির মতো টার্গেট এক্সিলিটারগুলির জন্য বিভিন্ন ধরণের প্রতিনিধি রয়েছে।

আপনার নিজস্ব প্রতিনিধি তৈরি করা নিম্নলিখিত পরিস্থিতিতে কার্যকর হয়:

  • আপনি কোনও নতুন এমএল ইনফারেন্স ইঞ্জিন সংহত করতে চান যা কোনও বিদ্যমান প্রতিনিধি দ্বারা সমর্থিত নয়।
  • আপনার কাছে একটি কাস্টম হার্ডওয়্যার এক্সিলার রয়েছে যা জ্ঞাত পরিস্থিতিতে জন্য রানটাইম উন্নত করে।
  • আপনি সিপিইউ অপ্টিমাইজেশন (যেমন অপারেটর ফিউজিং) বিকাশ করছেন যা নির্দিষ্ট মডেলগুলিকে গতি বাড়িয়ে তুলতে পারে।

প্রতিনিধিরা কীভাবে কাজ করবেন?

নিম্নলিখিতগুলির মতো একটি সাধারণ মডেল গ্রাফ এবং কনভ 2 ডি এবং মিড অপারেশনগুলির জন্য দ্রুত প্রয়োগকারী একটি প্রতিনিধি "মাইডিলেগেট" বিবেচনা করুন।

Original graph

এই "মাইডিলেগেট" প্রয়োগ করার পরে, মূল টেনসরফ্লো লাইট গ্রাফ নিম্নলিখিতগুলির মতো আপডেট হবে:

Graph with delegate

টেনসরফ্লো লাইট দুটি নিয়ম অনুসরণ করে মূল গ্রাফটি বিভক্ত করার সাথে উপরের গ্রাফটি প্রাপ্ত হয়েছে:

  • প্রতিনিধি দ্বারা পরিচালিত হতে পারে এমন নির্দিষ্ট ক্রিয়াকলাপগুলি একটি পার্টিশনে রাখা হয় যখন এখনও অপারেশনগুলির মধ্যে মূল কম্পিউটিং ওয়ার্কফ্লো নির্ভরতা সন্তুষ্ট করে।
  • প্রতিটি-থেকে-ডেলিগেট করা পার্টিশনে কেবল ইনপুট এবং আউটপুট নোড থাকে যা প্রতিনিধি দ্বারা পরিচালিত হয় না।

ডেলিগেট দ্বারা পরিচালিত প্রতিটি পার্টিশনকে মূল গ্রাফটিতে একটি ডেলিগেট নোড দ্বারা প্রতিস্থাপন করা হয় (এটি ডেলিগেট কার্নেল হিসাবেও ডাকা যেতে পারে) যা তার আহ্বান ডাকে পার্টিশনের মূল্যায়ন করে।

মডেলের উপর নির্ভর করে, চূড়ান্ত গ্রাফটি এক বা একাধিক নোড দিয়ে শেষ হতে পারে, এর অর্থ পরবর্তী অর্থ কিছু প্রতিনিধি প্রতিনিধি দ্বারা সমর্থিত নয়। সাধারণভাবে, আপনি প্রতিনিধি দ্বারা একাধিক পার্টিশন পরিচালনা করতে চান না, কারণ প্রতিবার আপনি ডেলিগেট থেকে মূল গ্রাফে স্যুইচ করেন, প্রতিনিধি সাবগ্রাফ থেকে মূল গ্রাফটিতে ফলাফলগুলি পাস করার জন্য একটি ওভারহেড থাকে যা মেমরির কারণে ফলাফল হয় অনুলিপি (উদাহরণস্বরূপ, সিপিইউতে জিপিইউ)। এই ধরনের ওভারহেড পারফরম্যান্স লাভগুলি অফসেট করে বিশেষত যখন প্রচুর পরিমাণে মেমরির অনুলিপি থাকে।

আপনার নিজস্ব কাস্টম প্রতিনিধি বাস্তবায়ন করা হচ্ছে

প্রতিনিধি যুক্ত করার জন্য পছন্দের পদ্ধতিটি সিম্পলডেলিগেট এপিআই ব্যবহার করছে

একটি নতুন প্রতিনিধি তৈরি করতে, আপনাকে 2 টি ইন্টারফেস প্রয়োগ করতে হবে এবং ইন্টারফেস পদ্ধতির জন্য আপনার নিজস্ব প্রয়োগকরণ সরবরাহ করতে হবে।

1 - SimpleDelegateInterface

এই শ্রেণিটি প্রতিনিধিদের দক্ষতার প্রতিনিধিত্ব করে, কোন ক্রিয়াকলাপ সমর্থিত এবং কার্নেল তৈরির জন্য একটি কারখানা শ্রেণি যা প্রতিনিধিত্বমূলক গ্রাফকে আবদ্ধ করে। আরও তথ্যের জন্য, এই সি ++ শিরোনাম ফাইলে সংজ্ঞায়িত ইন্টারফেসটি দেখুন। কোডের মন্তব্যগুলি প্রতিটি এপিআইকে বিস্তারিতভাবে ব্যাখ্যা করে।

2 - SimpleDelegateKernelInterface

এই শ্রেণিটি প্রতিনিধিত্বমূলক পার্টিশনটি শুরু / প্রস্তুত করা / চালানোর জন্য যুক্তিটিকে আবদ্ধ করে।

এটি রয়েছে: ( সংজ্ঞা দেখুন)

  • উদ্যোগ (...): যেকোন এককালীন সূচনা করার জন্য একবার কল করা হবে।
  • প্রস্তুত করুন (...): এই নোডের প্রতিটি পৃথক উদাহরণের জন্য ডাকা হয় - যদি আপনার একাধিক প্রতিনিধি পার্টিশন থাকে তবে এটি ঘটে। সাধারণত আপনি এখানে মেমরি বরাদ্দ করতে চান, যেহেতু এটিকে বলা হবে প্রতি সময়কালের পুনরায় আকার দেওয়া হয়।
  • আহ্বান (...): যা অনুমানের জন্য ডাকা হবে।

উদাহরণ

এই উদাহরণস্বরূপ, আপনি একটি খুব সাধারণ প্রতিনিধি তৈরি করবেন যা কেবলমাত্র ফ্লোট 32 টেনার সহ কেবলমাত্র 2 ধরণের অপারেশন (এডিডি) এবং (এসইউবি) সমর্থন করতে পারে।

// MyDelegate implements the interface of SimpleDelegateInterface.
// This holds the Delegate capabilities.
class MyDelegate : public SimpleDelegateInterface {
 public:
  bool IsNodeSupportedByDelegate(const TfLiteRegistration* registration,
                                 const TfLiteNode* node,
                                 TfLiteContext* context) const override {
    // Only supports Add and Sub ops.
    if (kTfLiteBuiltinAdd != registration->builtin_code &&
        kTfLiteBuiltinSub != registration->builtin_code)
      return false;
    // This delegate only supports float32 types.
    for (int i = 0; i < node->inputs->size; ++i) {
      auto& tensor = context->tensors[node->inputs->data[i]];
      if (tensor.type != kTfLiteFloat32) return false;
    }
    return true;
  }

  TfLiteStatus Initialize(TfLiteContext* context) override { return kTfLiteOk; }

  const char* Name() const override {
    static constexpr char kName[] = "MyDelegate";
    return kName;
  }

  std::unique_ptr<SimpleDelegateKernelInterface> CreateDelegateKernelInterface()
      override {
    return std::make_unique<MyDelegateKernel>();
  }
};

এরপরে, SimpleDelegateKernelInterface থেকে উত্তরাধিকার সূত্রে আপনার নিজস্ব প্রতিনিধি কার্নেল তৈরি করুন

// My delegate kernel.
class MyDelegateKernel : public SimpleDelegateKernelInterface {
 public:
  TfLiteStatus Init(TfLiteContext* context,
                    const TfLiteDelegateParams* params) override {
    // Save index to all nodes which are part of this delegate.
    inputs_.resize(params->nodes_to_replace->size);
    outputs_.resize(params->nodes_to_replace->size);
    builtin_code_.resize(params->nodes_to_replace->size);
    for (int i = 0; i < params->nodes_to_replace->size; ++i) {
      const int node_index = params->nodes_to_replace->data[i];
      // Get this node information.
      TfLiteNode* delegated_node = nullptr;
      TfLiteRegistration* delegated_node_registration = nullptr;
      TF_LITE_ENSURE_EQ(
          context,
          context->GetNodeAndRegistration(context, node_index, &delegated_node,
                                          &delegated_node_registration),
          kTfLiteOk);
      inputs_[i].push_back(delegated_node->inputs->data[0]);
      inputs_[i].push_back(delegated_node->inputs->data[1]);
      outputs_[i].push_back(delegated_node->outputs->data[0]);
      builtin_code_[i] = delegated_node_registration->builtin_code;
    }
    return kTfLiteOk;
  }

  TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) override {
    return kTfLiteOk;
  }

  TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) override {
    // Evaluate the delegated graph.
    // Here we loop over all the delegated nodes.
    // We know that all the nodes are either ADD or SUB operations and the
    // number of nodes equals ''inputs_.size()'' and inputs[i] is a list of
    // tensor indices for inputs to node ''i'', while outputs_[i] is the list of
    // outputs for node
    // ''i''. Note, that it is intentional we have simple implementation as this
    // is for demonstration.

    for (int i = 0; i < inputs_.size(); ++i) {
      // Get the node input tensors.
      // Add/Sub operation accepts 2 inputs.
      auto& input_tensor_1 = context->tensors[inputs_[i][0]];
      auto& input_tensor_2 = context->tensors[inputs_[i][1]];
      auto& output_tensor = context->tensors[outputs_[i][0]];
      TF_LITE_ENSURE_EQ(
          context,
          ComputeResult(context, builtin_code_[i], &input_tensor_1,
                        &input_tensor_2, &output_tensor),
          kTfLiteOk);
    }
    return kTfLiteOk;
  }

 private:
  // Computes the result of addition of 'input_tensor_1' and 'input_tensor_2'
  // and store the result in 'output_tensor'.
  TfLiteStatus ComputeResult(TfLiteContext* context, int builtin_code,
                             const TfLiteTensor* input_tensor_1,
                             const TfLiteTensor* input_tensor_2,
                             TfLiteTensor* output_tensor) {
    if (NumElements(input_tensor_1) != NumElements(input_tensor_2) ||
        NumElements(input_tensor_1) != NumElements(output_tensor)) {
      return kTfLiteDelegateError;
    }
    // This code assumes no activation, and no broadcasting needed (both inputs
    // have the same size).
    auto* input_1 = GetTensorData<float>(input_tensor_1);
    auto* input_2 = GetTensorData<float>(input_tensor_2);
    auto* output = GetTensorData<float>(output_tensor);
    for (int i = 0; i < NumElements(input_tensor_1); ++i) {
      if (builtin_code == kTfLiteBuiltinAdd)
        output[i] = input_1[i] + input_2[i];
      else
        output[i] = input_1[i] - input_2[i];
    }
    return kTfLiteOk;
  }

  // Holds the indices of the input/output tensors.
  // inputs_[i] is list of all input tensors to node at index 'i'.
  // outputs_[i] is list of all output tensors to node at index 'i'.
  std::vector<std::vector<int>> inputs_, outputs_;
  // Holds the builtin code of the ops.
  // builtin_code_[i] is the type of node at index 'i'
  std::vector<int> builtin_code_;
};


বেঞ্চমার্ক এবং নতুন প্রতিনিধি মূল্যায়ন

টিএফলাইটে এমন একটি সরঞ্জাম রয়েছে যা আপনি একটি টিএফলাইট মডেলের বিরুদ্ধে দ্রুত পরীক্ষা করতে পারেন।

  • মডেল বেঞ্চমার্ক সরঞ্জাম : সরঞ্জামটি একটি টিএফলাইট মডেল নেয়, এলোমেলো ইনপুট উত্পন্ন করে এবং তারপরে বারবার নির্দিষ্ট সংখ্যক রানের জন্য মডেলটি চালায়। এটি শেষে একত্রিত বিলম্বতার পরিসংখ্যানগুলি মুদ্রণ করে।
  • ইনফারেন্স ডিফ ডিভাইস : প্রদত্ত মডেলের জন্য, সরঞ্জামটি এলোমেলো গাউসিয়ান ডেটা উত্পন্ন করে এবং এটি দুটি পৃথক টিএফলাইট দোভাষী দ্বারা প্রেরণ করে, একটি চালিত একক থ্রেডেড সিপিইউ কার্নেল এবং অন্যটি ব্যবহারকারী-সংজ্ঞায়িত স্পেক ব্যবহার করে। এটি প্রতিটি দোভাষী থেকে আউটপুট টেনারগুলির মধ্যে পার্থক্য ভিত্তিতে সম্পূর্ণ পার্থক্য পরিমাপ করে। নির্ভুলতার সমস্যাগুলি ডিবাগ করার জন্যও এই সরঞ্জামটি সহায়ক হতে পারে।
  • চিত্রের শ্রেণিবদ্ধকরণ এবং অবজেক্ট সনাক্তকরণের জন্য টাস্ক নির্দিষ্ট মূল্যায়ন সরঞ্জামও রয়েছে। এই সরঞ্জামগুলি এখানে পাওয়া যাবে

তদ্ব্যতীত, টিএফলাইটে কর্নেল এবং অপ ইউনিট পরীক্ষার একটি বিশাল সেট রয়েছে যা আরও বেশি কভারেজ সহ নতুন প্রতিনিধি পরীক্ষা করার জন্য এবং নিয়মিত টিএফলাইট নির্বাহের পথটি নষ্ট না হয় তা নিশ্চিত করার জন্য পুনরায় ব্যবহার করা যেতে পারে।

টিএফলাইট পরীক্ষাগুলি পুনরায় ব্যবহার এবং নতুন প্রতিনিধিটির জন্য সরঞ্জামাদি অর্জন করতে, আপনি নিম্নলিখিত দুটি বিকল্পের মধ্যে দুটি ব্যবহার করতে পারেন:

সেরা পদ্ধতির নির্বাচন করা

উভয় পদ্ধতির নীচে বিস্তারিত হিসাবে কয়েকটি পরিবর্তন প্রয়োজন। তবে, প্রথম পদ্ধতির প্রতিনিধিকে স্থিতিশীলভাবে সংযুক্ত করে এবং পরীক্ষার পুনর্নির্মাণ, বেঞ্চমার্কিং এবং মূল্যায়ন সরঞ্জামগুলির প্রয়োজন হয় requires বিপরীতে, দ্বিতীয়টি একটি ভাগ করা লাইব্রেরি হিসাবে প্রতিনিধি তৈরি করে এবং আপনার ভাগ করে নেওয়া লাইব্রেরি থেকে পদ্ধতিগুলি তৈরি / মোছা প্রকাশ করতে হবে।

ফলস্বরূপ, বাহ্যিক-প্রতিনিধি প্রক্রিয়া টিএফলাইটের প্রাক-বিল্ট টেনসরফ্লো লাইট টুলিং বাইনারিগুলির সাথে কাজ করবে। তবে এটি কম স্পষ্ট এবং স্বয়ংক্রিয় ইন্টিগ্রেশন পরীক্ষাগুলি সেট আপ করা আরও জটিল হতে পারে। আরও স্পষ্টতার জন্য প্রতিনিধি নিবন্ধকের পদ্ধতির ব্যবহার করুন।

বিকল্প 1: লিভারেজের প্রতিনিধি নিবন্ধক

প্রতিনিধি রেজিস্ট্রার প্রতিনিধি সরবরাহকারীদের একটি তালিকা রাখেন, যার প্রত্যেকটি কমান্ড-লাইন পতাকাগুলির উপর ভিত্তি করে টিএফলাইট প্রতিনিধি তৈরি করার একটি সহজ উপায় সরবরাহ করে এবং তাই, সরঞ্জামদানে সুবিধাজনক। সব Tensorflow লাইট সরঞ্জাম উপরে উল্লিখিত নতুন প্রতিনিধি প্লাগ ইন করতে, আপনাকে প্রথমে এই মত একটি নতুন প্রতিনিধি প্রদানকারী তৈরি এক , এবং তারপর বিল্ড নিয়ম কেবল কয়েকটি মাত্র পরিবর্তন করে তোলে। এই সংহতকরণ প্রক্রিয়াটির একটি সম্পূর্ণ উদাহরণ নীচে দেখানো হয়েছে (এবং কোডটি এখানে পাওয়া যাবে )।

ধরে নিই আপনার কাছে এমন একটি প্রতিনিধি রয়েছে যা সিম্পলডেলিগেট এপিআই প্রয়োগ করে এবং নীচে প্রদর্শিত হিসাবে এই 'ডমি' প্রতিনিধি তৈরি / মুছে ফেলার বাহ্যিক "সি" এপিআই:

// Returns default options for DummyDelegate.
DummyDelegateOptions TfLiteDummyDelegateOptionsDefault();

// Creates a new delegate instance that need to be destroyed with
// `TfLiteDummyDelegateDelete` when delegate is no longer used by TFLite.
// When `options` is set to `nullptr`, the above default values are used:
TfLiteDelegate* TfLiteDummyDelegateCreate(const DummyDelegateOptions* options);

// Destroys a delegate created with `TfLiteDummyDelegateCreate` call.
void TfLiteDummyDelegateDelete(TfLiteDelegate* delegate);

"ডামিডিলেগেট" বেঞ্চমার্ক সরঞ্জাম এবং অনুগ্রহ সরঞ্জামের সাথে সংহত করতে নীচের মতো একটি প্রতিনিধিপ্রযুক্তি সংজ্ঞা দিন:

class DummyDelegateProvider : public DelegateProvider {
 public:
  DummyDelegateProvider() {
    default_params_.AddParam("use_dummy_delegate",
                             ToolParam::Create<bool>(false));
  }

  std::vector<Flag> CreateFlags(ToolParams* params) const final;

  void LogParams(const ToolParams& params) const final;

  TfLiteDelegatePtr CreateTfLiteDelegate(const ToolParams& params) const final;

  std::string GetName() const final { return "DummyDelegate"; }
};
REGISTER_DELEGATE_PROVIDER(DummyDelegateProvider);

std::vector<Flag> DummyDelegateProvider::CreateFlags(ToolParams* params) const {
  std::vector<Flag> flags = {CreateFlag<bool>("use_dummy_delegate", params,
                                              "use the dummy delegate.")};
  return flags;
}

void DummyDelegateProvider::LogParams(const ToolParams& params) const {
  TFLITE_LOG(INFO) << "Use dummy test delegate : ["
                   << params.Get<bool>("use_dummy_delegate") << "]";
}

TfLiteDelegatePtr DummyDelegateProvider::CreateTfLiteDelegate(
    const ToolParams& params) const {
  if (params.Get<bool>("use_dummy_delegate")) {
    auto default_options = TfLiteDummyDelegateOptionsDefault();
    return TfLiteDummyDelegateCreateUnique(&default_options);
  }
  return TfLiteDelegatePtr(nullptr, [](TfLiteDelegate*) {});
}

বিল্ড নিয়মের সংজ্ঞাগুলি গুরুত্বপূর্ণ কারণ আপনার গ্রন্থাগারটি সর্বদা সংযুক্ত রয়েছে এবং অপ্টিমাইজার দ্বারা বাদ পড়েছে না তা নিশ্চিত করতে হবে।

#### The following are for using the dummy test delegate in TFLite tooling ####
cc_library(
    name = "dummy_delegate_provider",
    srcs = ["dummy_delegate_provider.cc"],
    copts = tflite_copts(),
    deps = [
        ":dummy_delegate",
        "//tensorflow/lite/tools/delegates:delegate_provider_hdr",
    ],
    alwayslink = 1, # This is required so the optimizer doesn't optimize the library away.
)

আপনার নিজের প্রতিনিধিটির সাথে চলতে পারে এমন বেঞ্চমার্ক সরঞ্জাম এবং সূচনা সরঞ্জাম এবং অন্যান্য মূল্যায়ন সরঞ্জামগুলির একটি সংস্করণ তৈরি করতে আপনার বিল্ড ফাইলটিতে এখন এই দুটি মোড়কের নিয়ম যুক্ত করুন।

cc_binary(
    name = "benchmark_model_plus_dummy_delegate",
    copts = tflite_copts(),
    linkopts = task_linkopts(),
    deps = [
        ":dummy_delegate_provider",
        "//tensorflow/lite/tools/benchmark:benchmark_model_main",
    ],
)

cc_binary(
    name = "inference_diff_plus_dummy_delegate",
    copts = tflite_copts(),
    linkopts = task_linkopts(),
    deps = [
        ":dummy_delegate_provider",
        "//tensorflow/lite/tools/evaluation/tasks:task_executor_main",
        "//tensorflow/lite/tools/evaluation/tasks/inference_diff:run_eval_lib",
    ],
)

cc_binary(
    name = "imagenet_classification_eval_plus_dummy_delegate",
    copts = tflite_copts(),
    linkopts = task_linkopts(),
    deps = [
        ":dummy_delegate_provider",
        "//tensorflow/lite/tools/evaluation/tasks:task_executor_main",
        "//tensorflow/lite/tools/evaluation/tasks/imagenet_image_classification:run_eval_lib",
    ],
)

cc_binary(
    name = "coco_object_detection_eval_plus_dummy_delegate",
    copts = tflite_copts(),
    linkopts = task_linkopts(),
    deps = [
        ":dummy_delegate_provider",
        "//tensorflow/lite/tools/evaluation/tasks:task_executor_main",
        "//tensorflow/lite/tools/evaluation/tasks/coco_object_detection:run_eval_lib",
    ],
)

আপনি এখানে বর্ণিত হিসাবে টিএফলাইট কার্নেল পরীক্ষায় এই প্রতিনিধি প্রদানকারীকেও প্লাগ করতে পারেন।

বিকল্প 2: উত্সাহ বহিরাগত প্রতিনিধি

এই বিকল্প, আপনি প্রথম অ্যাডাপ্টারের একটি বহিস্থিত প্রতিনিধি সৃষ্টি external_delegate_adaptor.cc নিচের চিত্রের মতন। দ্রষ্টব্য, পূর্বোক্তরূপে বিকল্প 1 এর তুলনায় এই পদ্ধতিটি কিছুটা কম পছন্দ করা হয়েছে।

TfLiteDelegate* CreateDummyDelegateFromOptions(char** options_keys,
                                               char** options_values,
                                               size_t num_options) {
  DummyDelegateOptions options = TfLiteDummyDelegateOptionsDefault();

  // Parse key-values options to DummyDelegateOptions.
  // You can achieve this by mimicking them as command-line flags.
  std::unique_ptr<const char*> argv =
      std::unique_ptr<const char*>(new const char*[num_options + 1]);
  constexpr char kDummyDelegateParsing[] = "dummy_delegate_parsing";
  argv.get()[0] = kDummyDelegateParsing;

  std::vector<std::string> option_args;
  option_args.reserve(num_options);
  for (int i = 0; i < num_options; ++i) {
    option_args.emplace_back("--");
    option_args.rbegin()->append(options_keys[i]);
    option_args.rbegin()->push_back('=');
    option_args.rbegin()->append(options_values[i]);
    argv.get()[i + 1] = option_args.rbegin()->c_str();
  }

  // Define command-line flags.
  // ...
  std::vector<tflite::Flag> flag_list = {
      tflite::Flag::CreateFlag(...),
      ...,
      tflite::Flag::CreateFlag(...),
  };

  int argc = num_options + 1;
  if (!tflite::Flags::Parse(&argc, argv.get(), flag_list)) {
    return nullptr;
  }

  return TfLiteDummyDelegateCreate(&options);
}

#ifdef __cplusplus
extern "C" {
#endif  // __cplusplus

// Defines two symbols that need to be exported to use the TFLite external
// delegate. See tensorflow/lite/delegates/external for details.
TFL_CAPI_EXPORT TfLiteDelegate* tflite_plugin_create_delegate(
    char** options_keys, char** options_values, size_t num_options,
    void (*report_error)(const char*)) {
  return tflite::tools::CreateDummyDelegateFromOptions(
      options_keys, options_values, num_options);
}

TFL_CAPI_EXPORT void tflite_plugin_destroy_delegate(TfLiteDelegate* delegate) {
  TfLiteDummyDelegateDelete(delegate);
}

#ifdef __cplusplus
}
#endif  // __cplusplus

নীচে প্রদর্শিত হিসাবে গতিশীল লাইব্রেরি তৈরি করতে এখন সম্পর্কিত বিল্ড টার্গেট তৈরি করুন:

cc_binary(
    name = "dummy_external_delegate.so",
    srcs = [
        "external_delegate_adaptor.cc",
    ],
    linkshared = 1,
    linkstatic = 1,
    deps = [
        ":dummy_delegate",
        "//tensorflow/lite/c:common",
        "//tensorflow/lite/tools:command_line_flags",
        "//tensorflow/lite/tools:logging",
    ],
)

এই বাহ্যিক প্রতিনিধি .এসও ফাইলটি তৈরি হওয়ার পরে, আপনি বাইনারি তৈরি করতে পারেন বা নতুন ডেলিগেটের সাথে চালানোর জন্য প্রাক-বিল্টগুলি ব্যবহার করতে পারবেন যতক্ষণ না বাইনারি বহিরাগত_ডিলেগেট_প্রোভাইডার লাইব্রেরির সাথে সংযুক্ত থাকে যা এখানে বর্ণিত কমান্ড-লাইন পতাকা সমর্থন করে। দ্রষ্টব্য: এই বাহ্যিক প্রতিনিধি সরবরাহকারীটি ইতিমধ্যে বিদ্যমান টেস্টিং এবং টুলিং বাইনারিগুলির সাথে লিঙ্কযুক্ত।

এই বাহ্যিক-প্রতিনিধি পদ্ধতির মাধ্যমে কীভাবে ডামি ডেলিগেটকে বেনমার্ক করতে হয় তার উদাহরণের জন্য এখানে বর্ণনার উল্লেখ করুন । আপনি পূর্বে উল্লিখিত পরীক্ষার এবং মূল্যায়নের সরঞ্জামগুলির জন্য অনুরূপ আদেশগুলি ব্যবহার করতে পারেন।

এখানে প্রদর্শিত হিসাবে বাহ্যিক প্রতিনিধি টেনসরফ্লো লাইট পাইথন বাইন্ডিং মধ্যে প্রতিনিধি এর সংশ্লিষ্ট সি ++ বাস্তবায়ন লক্ষণীয়। সুতরাং, এখানে তৈরি করা গতিশীল বাহ্যিক প্রতিনিধি অ্যাডাপ্টার লাইব্রেরি সরাসরি টেনসরফ্লো লাইট পাইথন এপিআইগুলির সাথে ব্যবহার করা যেতে পারে।

রিসোর্স

ওএস আর্চ BINARY_NAME
লিনাক্স x86_64
বাহু
aarch64
অ্যান্ড্রয়েড বাহু
aarch64