Dokumen ini menjelaskan skema pembuatan versi op TensorFlow Lite. Pembuatan versi op memungkinkan pengembang untuk menambahkan fungsionalitas dan parameter baru ke dalam operasi yang ada. Selain itu, ini menjamin hal-hal berikut:
- Kompatibilitas mundur: Implementasi TensorFlow Lite baru harus menangani file model lama.
- Kompatibilitas ke depan: Implementasi TensorFlow Lite lama harus menangani file model baru yang dihasilkan oleh konverter versi baru, selama tidak ada fitur baru yang digunakan.
- Deteksi kompatibilitas ke depan: Jika implementasi TensorFlow Lite lama membaca model baru yang berisi versi baru dari operasi yang tidak didukung, itu akan melaporkan kesalahannya.
Contoh: Menambahkan dilatasi ke dalam konvolusi mendalam
Sisa dari dokumen ini menjelaskan versi op di TFLite dengan menunjukkan cara menambahkan parameter dilatasi ke operasi konvolusi yang mendalam.
Pengetahuan tentang pelebaran tidak diperlukan untuk memahami dokumen ini. Perhatikan bahwa:
- 2 parameter integer baru akan ditambahkan:
dilation_width_factor
dandilation_height_factor
. - Kernel konvolusi mendalam lama yang tidak mendukung pelebaran sama dengan menyetel faktor pelebaran ke 1.
Ubah skema FlatBuffer
Untuk menambahkan parameter baru ke dalam operasi, ubah tabel opsi di lite/schema/schema.fbs
.
Misalnya, tabel opsi konvolusi mendalam terlihat seperti ini:
table DepthwiseConv2DOptions {
padding:Padding;
stride_w:int;
stride_h:int;
depth_multiplier:int;
fused_activation_function:ActivationFunctionType;
}
Saat menambahkan parameter baru:
- Tambahkan komentar yang menunjukkan parameter mana yang didukung oleh versi mana.
- Ketika implementasi baru mendapatkan nilai default untuk parameter yang baru ditambahkan, itu harus bekerja persis sama dengan implementasi lama.
Tabel akan seperti ini setelah parameter baru ditambahkan:
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;
}
File lite/schema/schema_generated.h
harus dibuat ulang untuk skema baru.
Ubah struktur C dan implementasi kernel
Di TensorFlow Lite, implementasi kernel dipisahkan dari definisi FlatBuffer. Kernel membaca parameter dari struktur C yang didefinisikan dalam lite/c/builtin_op_data.h
.
Parameter konvolusi depthwise asli adalah sebagai berikut:
typedef struct {
TfLitePadding padding;
int stride_width;
int stride_height;
int depth_multiplier;
TfLiteFusedActivation activation;
} TfLiteDepthwiseConvParams;
Seperti skema FlatBuffer, tambahkan komentar yang menunjukkan parameter mana yang didukung mulai dari versi mana. Hasilnya terlihat di bawah ini:
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;
Harap juga ubah implementasi kernel untuk membaca parameter yang baru ditambahkan dari struktur C. Detailnya dihilangkan di sini.
Ubah kode pembacaan FlatBuffer
Logika untuk membaca FlatBuffer dan menghasilkan struktur C ada di lite/core/api/flatbuffer_conversions.cc
.
Perbarui file untuk menangani parameter baru, seperti yang ditunjukkan di bawah ini:
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;
}
Tidak perlu memeriksa versi op di sini. Ketika implementasi baru membaca file model lama di mana faktor pelebaran hilang, itu akan menggunakan 1 sebagai nilai default, dan kernel baru akan bekerja secara konsisten dengan kernel lama.
Ubah pendaftaran kernel
MutableOpResolver (didefinisikan dalam lite/mutable_op_resolver.h
) menyediakan beberapa fungsi untuk mendaftarkan kernel op. Versi minimum dan maksimum adalah 1 secara default:
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);
Operasi bawaan terdaftar di lite/kernels/register.cc
. Dalam contoh ini, kami mengimplementasikan kernel op baru yang dapat menangani DepthwiseConv2D
versi 1 dan 2, jadi kami perlu mengubah baris ini:
AddBuiltin(BuiltinOperator_DEPTHWISE_CONV_2D, Register_DEPTHWISE_CONV_2D());
ke:
AddBuiltin(BuiltinOperator_DEPTHWISE_CONV_2D, Register_DEPTHWISE_CONV_2D(),
/* min_version = */ 1,
/* max_version = */ 2);
Ubah versi operasi TFLite
Langkah selanjutnya adalah membuat TFLite mengisi versi minimum yang diperlukan untuk menjalankan operasi. Dalam contoh ini, artinya:
- Isi versi=1 ketika faktor pelebaran semuanya 1.
- Isi versi=2 sebaliknya.
Ubah fungsi GetBuiltinOperatorVersion
untuk operator di lite/tools/versioning/op_version.cc
dengan menambahkan versi baru ke kasus 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;
Perbarui peta versi operator
Langkah terakhir adalah menambahkan info versi baru ke dalam peta versi operator. Langkah ini diperlukan karena kita perlu membuat versi runtime minimum model yang diperlukan berdasarkan peta versi ini.
Untuk melakukan ini, Anda perlu menambahkan entri peta baru di lite/tools/versioning/runtime_version.cc
.
Dalam contoh ini, Anda perlu menambahkan entri berikut ke op_version_map
:
{ {BuiltinOperator_DEPTHWISE_CONV_2D, 2}, %CURRENT_RUNTIME_VERSION%}
di mana %CURRENT_RUNTIME_VERSION%
sesuai dengan versi runtime saat ini yang ditentukan dalam tensorflow/core/public/version.h .
Pelaksanaan delegasi
TensorFlow Lite menyediakan API delegasi yang memungkinkan pendelegasian operasi ke backend perangkat keras. Dalam fungsi Prepare
delegasi, periksa apakah versi didukung untuk setiap node dalam kode Delegasi.
const int kMaxVersion = 1;
TfLiteNode* node;
TfLiteRegistration* registration = nullptr;
TF_LITE_ENSURE_STATUS(context->GetNodeAndRegistration(context, node_index, &node, ®istration));
if (registration->version > kMaxVersion) {
// Reject the node if the version isn't supported.
}
Ini diperlukan meskipun delegasi hanya mendukung operasi versi 1, sehingga delegasi dapat mendeteksi ketidakcocokan saat mendapatkan operasi versi yang lebih tinggi.