ผู้แทน TensorFlow Lite คืออะไร?
ผู้รับมอบสิทธิ์ TensorFlow Lite ช่วยให้คุณสามารถเรียกใช้แบบจำลองของคุณ (บางส่วนหรือทั้งหมด) บนตัวดำเนินการอื่น กลไกนี้สามารถใช้ประโยชน์จากตัวเร่งความเร็วในอุปกรณ์ที่หลากหลาย เช่น GPU หรือ Edge TPU (หน่วยประมวลผลเทนเซอร์) สำหรับการอนุมาน สิ่งนี้ช่วยให้นักพัฒนามีวิธีการที่ยืดหยุ่นและแยกจาก TFLite เริ่มต้นเพื่อเพิ่มความเร็วในการอนุมาน
ไดอะแกรมด้านล่างสรุปผู้รับมอบสิทธิ์ รายละเอียดเพิ่มเติมในส่วนด้านล่าง
ฉันควรสร้างผู้รับมอบสิทธิ์แบบกำหนดเองเมื่อใด
TensorFlow Lite มีตัวแทนที่หลากหลายสำหรับตัวเร่งความเร็วเป้าหมาย เช่น GPU, DSP, EdgeTPU และเฟรมเวิร์ก เช่น Android NNAPI
การสร้างผู้รับมอบสิทธิ์ของคุณเองมีประโยชน์ในสถานการณ์ต่อไปนี้:
- คุณต้องการรวมเอ็นจินการอนุมาน ML ใหม่ที่ไม่ได้รับการสนับสนุนโดยผู้รับมอบสิทธิ์ที่มีอยู่
- คุณมีตัวเร่งฮาร์ดแวร์แบบกำหนดเองที่ปรับปรุงรันไทม์สำหรับสถานการณ์ที่ทราบ
- คุณกำลังพัฒนาการปรับแต่ง CPU ให้เหมาะสม (เช่น การหลอมรวมของผู้ปฏิบัติงาน) ที่สามารถเพิ่มความเร็วบางรุ่นได้
ผู้รับมอบสิทธิ์ทำงานอย่างไร
พิจารณากราฟแบบจำลองอย่างง่ายดังต่อไปนี้ และตัวแทน "MyDelegate" ที่มีการปรับใช้ที่รวดเร็วกว่าสำหรับการดำเนินการ Conv2D และค่าเฉลี่ย
หลังจากใช้ “MyDelegate” กราฟ TensorFlow Lite ดั้งเดิมจะได้รับการอัปเดตดังนี้:
กราฟด้านบนได้มาจาก TensorFlow Lite แยกกราฟเดิมตามกฎสองข้อ:
- การดำเนินการเฉพาะที่ผู้รับมอบสิทธิ์สามารถจัดการได้จะถูกใส่ลงในพาร์ติชันในขณะที่ยังคงตอบสนองการพึ่งพาเวิร์กโฟลว์การคำนวณดั้งเดิมระหว่างการดำเนินการ
- แต่ละพาร์ติชันที่จะรับมอบสิทธิ์มีเฉพาะโหนดอินพุตและเอาต์พุตที่ไม่ได้รับการจัดการโดยผู้รับมอบสิทธิ์
แต่ละพาร์ติชั่นที่จัดการโดยผู้รับมอบสิทธิ์จะถูกแทนที่ด้วยโหนดผู้รับมอบสิทธิ์ (เรียกอีกอย่างว่าเคอร์เนลของผู้รับมอบสิทธิ์) ในกราฟดั้งเดิมที่ประเมินพาร์ติชั่นในการเรียกที่เรียกใช้
กราฟสุดท้ายอาจลงเอยด้วยโหนดอย่างน้อยหนึ่งโหนด ทั้งนี้ขึ้นอยู่กับรุ่น กราฟสุดท้ายหมายความว่าผู้รับมอบสิทธิ์ไม่สนับสนุน ops บางส่วน โดยทั่วไป คุณไม่ต้องการให้ผู้รับมอบสิทธิ์จัดการหลายพาร์ติชัน เนื่องจากทุกครั้งที่คุณเปลี่ยนจากผู้รับมอบสิทธิ์เป็นกราฟหลัก จะมีค่าใช้จ่ายในการส่งผลลัพธ์จากกราฟย่อยที่ได้รับมอบหมายไปยังกราฟหลักซึ่งเป็นผลมาจากหน่วยความจำ สำเนา (เช่น GPU ถึง CPU) ค่าใช้จ่ายดังกล่าวอาจชดเชยประสิทธิภาพที่เพิ่มขึ้นโดยเฉพาะอย่างยิ่งเมื่อมีสำเนาหน่วยความจำจำนวนมาก
ดำเนินการมอบหมายของคุณเอง
วิธีที่ต้องการในการเพิ่มผู้รับมอบสิทธิ์คือการใช้ SimpleDelegate API
ในการสร้างผู้รับมอบสิทธิ์ใหม่ คุณต้องติดตั้งอินเทอร์เฟซ 2 ตัวและจัดเตรียมการใช้งานของคุณเองสำหรับวิธีอินเทอร์เฟซ
1 - SimpleDelegateInterface
คลาสนี้แสดงถึงความสามารถของผู้รับมอบสิทธิ์ ซึ่งได้รับการสนับสนุนการดำเนินการ และคลาสโรงงานสำหรับการสร้างเคอร์เนลที่ห่อหุ้มกราฟที่ได้รับมอบหมาย สำหรับรายละเอียดเพิ่มเติม โปรดดูอินเทอร์เฟซที่กำหนดไว้ใน ไฟล์ส่วนหัว C++ นี้ ความคิดเห็นในโค้ดจะอธิบายแต่ละ API โดยละเอียด
2 - SimpleDelegateKernelInterface
คลาสนี้สรุปตรรกะสำหรับการเริ่มต้น / การจัดเตรียม / และการรันพาร์ติชันที่ได้รับมอบสิทธิ์
มันมี: (ดู คำจำกัดความ )
- Init(...): ซึ่งจะถูกเรียกหนึ่งครั้งเพื่อเริ่มต้นครั้งเดียว
- เตรียม(...): เรียกใช้สำหรับแต่ละอินสแตนซ์ที่แตกต่างกันของโหนดนี้ - สิ่งนี้จะเกิดขึ้นหากคุณมีหลายพาร์ติชันที่ได้รับมอบสิทธิ์ โดยปกติคุณต้องการทำการจัดสรรหน่วยความจำที่นี่ เนื่องจากสิ่งนี้จะถูกเรียกทุกครั้งที่มีการปรับขนาดเทนเซอร์
- Invoke(...): ซึ่งจะถูกเรียกสำหรับการอนุมาน
ตัวอย่าง
ในตัวอย่างนี้ คุณจะสร้างผู้รับมอบสิทธิ์ที่ง่ายมากที่สามารถรองรับการดำเนินการได้ 2 ประเภทเท่านั้น (ADD) และ (SUB) ที่มีเมตริกซ์ float32 เท่านั้น
// 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_;
};
เกณฑ์มาตรฐานและประเมินผู้รับมอบสิทธิ์ใหม่
TFLite มีชุดเครื่องมือที่คุณสามารถทดสอบกับรุ่น TFLite ได้อย่างรวดเร็ว
- Model Benchmark Tool : เครื่องมือนี้ใช้โมเดล TFLite สร้างอินพุตแบบสุ่ม จากนั้นรันโมเดลซ้ำๆ ตามจำนวนรันที่ระบุ จะพิมพ์สถิติเวลาแฝงรวมในตอนท้าย
- Inference Diff Tool : สำหรับรุ่นที่กำหนด เครื่องมือจะสร้างข้อมูล Gaussian แบบสุ่มและส่งผ่านผ่านตัวแปล TFLite ที่แตกต่างกันสองตัว ตัวหนึ่งใช้เคอร์เนล CPU แบบเธรดเดี่ยว และอีกตัวหนึ่งใช้ข้อมูลจำเพาะที่ผู้ใช้กำหนด มันวัดความแตกต่างที่แน่นอนระหว่างเทนเซอร์เอาต์พุตจากล่ามแต่ละตัวตามองค์ประกอบ เครื่องมือนี้ยังมีประโยชน์สำหรับการดีบักปัญหาความถูกต้อง
- นอกจากนี้ยังมีเครื่องมือประเมินเฉพาะงาน สำหรับการจำแนกรูปภาพและการตรวจจับวัตถุ พบกับเครื่องมือเหล่านี้ได้ ที่นี่
นอกจากนี้ TFLite ยังมีชุดทดสอบเคอร์เนลและหน่วยปฏิบัติการขนาดใหญ่ที่สามารถนำมาใช้ซ้ำเพื่อทดสอบผู้รับมอบสิทธิ์ใหม่ด้วยความครอบคลุมที่มากขึ้น และเพื่อให้แน่ใจว่าเส้นทางการดำเนินการ TFLite ปกติจะไม่เสียหาย
หากต้องการใช้การทดสอบและเครื่องมือ TFLite ซ้ำสำหรับผู้รับมอบสิทธิ์ใหม่ คุณสามารถใช้ตัวเลือกใดตัวเลือกหนึ่งต่อไปนี้:
- ใช้กลไกการ จดทะเบียนผู้รับมอบสิทธิ์
- ใช้กลไกการ มอบหมายภายนอก
การเลือกแนวทางที่ดีที่สุด
ทั้งสองวิธีต้องการการเปลี่ยนแปลงเล็กน้อยตามรายละเอียดด้านล่าง อย่างไรก็ตาม วิธีแรกจะเชื่อมโยงผู้รับมอบสิทธิ์แบบคงที่ และจำเป็นต้องสร้างเครื่องมือทดสอบ การเปรียบเทียบและประเมินผลขึ้นใหม่ ในทางตรงกันข้าม อันที่สองทำให้ผู้รับมอบสิทธิ์เป็นไลบรารีที่ใช้ร่วมกัน และต้องการให้คุณเปิดเผยวิธีการสร้าง/ลบจากไลบรารีที่แชร์
ด้วยเหตุนี้ กลไกการมอบหมายจากภายนอกจะทำงานร่วมกับ ไบนารีเครื่องมือ Tensorflow Lite ที่สร้างไว้ล่วงหน้า ของ TFLite แต่มีความชัดเจนน้อยกว่าและอาจซับซ้อนกว่าในการตั้งค่าการทดสอบการรวมอัตโนมัติ ใช้วิธีผู้รับมอบสิทธิ์ของผู้รับมอบสิทธิ์เพื่อความชัดเจนยิ่งขึ้น
ตัวเลือกที่ 1: ผู้รับมอบอำนาจผู้รับมอบสิทธิ์
ผู้รับมอบสิทธิ์ จะเก็บรายชื่อผู้ให้บริการผู้รับมอบสิทธิ์ ซึ่งแต่ละรายมีวิธีง่ายๆ ในการสร้างผู้รับมอบสิทธิ์ TFLite ตามแฟล็กบรรทัดคำสั่ง และด้วยเหตุนี้จึงสะดวกสำหรับการใช้เครื่องมือ ในการเสียบผู้รับมอบสิทธิ์ใหม่เข้ากับเครื่องมือ Tensorflow Lite ทั้งหมดที่กล่าวถึงข้างต้น ก่อนอื่นคุณต้องสร้างผู้ให้บริการผู้รับมอบสิทธิ์ใหม่เช่นนี้ จากนั้นทำการเปลี่ยนแปลงกฎ BUILD เพียง เล็กน้อย ตัวอย่างที่สมบูรณ์ของกระบวนการผสานนี้แสดงไว้ด้านล่าง (และสามารถดูโค้ดได้ ที่นี่ )
สมมติว่าคุณมีผู้รับมอบสิทธิ์ที่ใช้ SimpleDelegate API และ API ภายนอก "C" ของการสร้าง/ลบผู้รับมอบสิทธิ์ 'จำลอง' ดังที่แสดงด้านล่าง:
// 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);
ในการรวม “DummyDelegate” เข้ากับเครื่องมือเปรียบเทียบและเครื่องมือการอนุมาน ให้กำหนด DelegateProvider ดังนี้:
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*) {});
}
คำจำกัดความกฎ BUILD มีความสำคัญ เนื่องจากคุณต้องแน่ใจว่าไลบรารีนั้นเชื่อมโยงอยู่เสมอและไม่ถูกปล่อยโดยตัวเพิ่มประสิทธิภาพ
#### 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.
)
ตอนนี้ เพิ่มกฎ wrapper สองข้อนี้ในไฟล์ BUILD ของคุณ เพื่อสร้างเวอร์ชันของ Benchmark Tool และ Inference Tool และเครื่องมือประเมินผลอื่นๆ ที่สามารถทำงานกับผู้รับมอบสิทธิ์ของคุณเอง
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",
],
)
คุณยังสามารถเสียบผู้ให้บริการรับมอบสิทธิ์นี้กับการทดสอบเคอร์เนล TFLite ตามที่อธิบายไว้ ที่นี่
ตัวเลือกที่ 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
ตอนนี้สร้างเป้าหมาย BUILD ที่เกี่ยวข้องเพื่อสร้างไลบรารีแบบไดนามิกดังที่แสดงด้านล่าง:
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",
],
)
หลังจากสร้างไฟล์ .so ผู้รับมอบสิทธิ์ ภายนอก แล้ว คุณสามารถสร้างไบนารีหรือใช้ไฟล์ที่สร้าง ไว้ ล่วงหน้าเพื่อทำงานกับผู้รับมอบสิทธิ์ใหม่ ตราบใดที่ไบนารีเชื่อมโยงกับไลบรารี หมายเหตุ: ผู้ให้บริการผู้รับมอบสิทธิ์ภายนอกรายนี้เชื่อมโยงกับไบนารีการทดสอบและเครื่องมือที่มีอยู่แล้ว
อ้างถึงคำอธิบาย ที่นี่ สำหรับภาพประกอบของวิธีการเปรียบเทียบตัวแทนจำลองผ่านแนวทางผู้รับมอบสิทธิ์ภายนอกนี้ คุณสามารถใช้คำสั่งที่คล้ายกันสำหรับเครื่องมือทดสอบและประเมินผลที่กล่าวถึงก่อนหน้านี้
เป็นที่น่าสังเกตว่า ผู้รับมอบสิทธิ์ภายนอก เป็นการนำ C ++ ของ ผู้รับมอบสิทธิ์ ไปใช้ในการเชื่อมโยง Tensorflow Lite Python ดังที่แสดงไว้ ที่นี่ ดังนั้น ไลบรารีอะแด็ปเตอร์ผู้รับมอบสิทธิ์ภายนอกแบบไดนามิกที่สร้างที่นี่จึงสามารถใช้กับ Tensorflow Lite Python API ได้โดยตรง
ทรัพยากร
ลิงก์ดาวน์โหลดสำหรับไบนารีเครื่องมือ TFLite ที่สร้างไว้ล่วงหน้าทุกคืน
OS | โค้ง | BINARY_NAME |
ลินุกซ์ | x86_64 | |
แขน | ||
aarch64 | ||
Android | แขน | |
aarch64 |