নিউরাল নেটওয়ার্ক এপিআই (এনএনএপিআই) ভেন্ডর এক্সটেনশন, অ্যান্ড্রয়েড 10-এ প্রবর্তিত, হল বিক্রেতা-সংজ্ঞায়িত ক্রিয়াকলাপ এবং ডেটা প্রকারের সংগ্রহ। NN HAL 1.2 বা উচ্চতর চলমান ডিভাইসগুলিতে, ড্রাইভারগুলি সংশ্লিষ্ট বিক্রেতা এক্সটেনশনগুলিকে সমর্থন করে কাস্টম হার্ডওয়্যার-ত্বরিত ক্রিয়াকলাপ সরবরাহ করতে পারে। বিক্রেতা এক্সটেনশন বিদ্যমান ক্রিয়াকলাপগুলির আচরণ পরিবর্তন করে না।
বিক্রেতা এক্সটেনশনগুলি OEM ক্রিয়াকলাপ এবং ডেটা প্রকারগুলির একটি আরও কাঠামোগত বিকল্প প্রদান করে, যেগুলি Android 10-এ অবমূল্যায়িত হয়েছিল৷ আরও তথ্যের জন্য, OEM অপারেশন এবং ডেটা প্রকারগুলি দেখুন৷
এক্সটেনশন ব্যবহারের অনুমতি তালিকা
ভেন্ডর এক্সটেনশনগুলি শুধুমাত্র স্পষ্টভাবে নির্দিষ্ট করা Android অ্যাপ এবং /product
, /vendor
, /odm
, এবং /data
পার্টিশনে নেটিভ বাইনারি দ্বারা ব্যবহার করা যেতে পারে। /system
পার্টিশনে অবস্থিত অ্যাপ এবং নেটিভ বাইনারি বিক্রেতা এক্সটেনশন ব্যবহার করতে পারে না।
NNAPI বিক্রেতা এক্সটেনশনগুলি ব্যবহার করার জন্য অনুমোদিত Android অ্যাপ এবং বাইনারিগুলির একটি তালিকা /vendor/etc/nnapi_extensions_app_allowlist
এ সংরক্ষণ করা হয়েছে। ফাইলের প্রতিটি লাইনে একটি নতুন এন্ট্রি রয়েছে। একটি এন্ট্রি একটি নেটিভ বাইনারি পাথ হতে পারে যা একটি স্ল্যাশ (/), উদাহরণস্বরূপ, /data/foo
, বা একটি Android অ্যাপ প্যাকেজের একটি নাম, উদাহরণস্বরূপ, com.foo.bar
সাথে উপসর্গযুক্ত।
NNAPI রানটাইম শেয়ার্ড লাইব্রেরি থেকে অনুমোদিত তালিকা প্রয়োগ করা হয়েছে। এই লাইব্রেরিটি দুর্ঘটনাজনিত ব্যবহার থেকে রক্ষা করে কিন্তু সরাসরি NNAPI ড্রাইভার HAL ইন্টারফেস ব্যবহার করে একটি অ্যাপ দ্বারা ইচ্ছাকৃত প্রতারণার বিরুদ্ধে নয়।
বিক্রেতা এক্সটেনশন সংজ্ঞা
বিক্রেতা এক্সটেনশন সংজ্ঞা সহ একটি হেডার ফাইল তৈরি করে এবং রক্ষণাবেক্ষণ করে। একটি এক্সটেনশন সংজ্ঞার একটি সম্পূর্ণ উদাহরণ example/fibonacci/FibonacciExtension.h
এ পাওয়া যাবে।
প্রতিটি এক্সটেনশনের একটি অনন্য নাম থাকতে হবে যা বিক্রেতার বিপরীত ডোমেন নাম দিয়ে শুরু হয়।
const char EXAMPLE_EXTENSION_NAME[] = "com.example.my_extension";
নামটি অপারেশন এবং ডেটা প্রকারের জন্য একটি নামস্থান হিসাবে কাজ করে। NNAPI বিক্রেতা এক্সটেনশনগুলির মধ্যে পার্থক্য করতে এই নামটি ব্যবহার করে।
runtime/include/NeuralNetworks.h
মতোই অপারেশন এবং ডেটা টাইপ ঘোষণা করা হয়।
enum {
/**
* A custom scalar type.
*/
EXAMPLE_SCALAR = 0,
/**
* A custom tensor type.
*
* Attached to this tensor is {@link ExampleTensorParams}.
*/
EXAMPLE_TENSOR = 1,
};
enum {
/**
* Computes example function.
*
* Inputs:
* * 0: A scalar of {@link EXAMPLE_SCALAR}.
*
* Outputs:
* * 0: A tensor of {@link EXAMPLE_TENSOR}.
*/
EXAMPLE_FUNCTION = 0,
};
একটি এক্সটেনশন অপারেশন অন্য এক্সটেনশন থেকে ননএক্সটেনশন অপারেন্ড প্রকার এবং অপারেন্ড প্রকার সহ যেকোনো অপারেন্ড প্রকার ব্যবহার করতে পারে। অন্য এক্সটেনশন থেকে অপারেন্ড টাইপ ব্যবহার করার সময়, ড্রাইভারকে অবশ্যই অন্য এক্সটেনশন সমর্থন করতে হবে।
এক্সটেনশনগুলি এক্সটেনশন অপারেন্ডের সাথে কাস্টম কাঠামো ঘোষণা করতে পারে।
/**
* Quantization parameters for {@link EXAMPLE_TENSOR}.
*/
typedef struct ExampleTensorParams {
double scale;
int64_t zeroPoint;
} ExampleTensorParams;
NNAPI ক্লায়েন্টে এক্সটেনশন ব্যবহার করুন
runtime/include/NeuralNetworksExtensions.h
(C API) ফাইল রানটাইম এক্সটেনশন সমর্থন প্রদান করে। এই বিভাগটি C API এর একটি ওভারভিউ প্রদান করে।
একটি ডিভাইস একটি এক্সটেনশন সমর্থন করে কিনা তা পরীক্ষা করতে, ANeuralNetworksDevice_getExtensionSupport
ব্যবহার করুন।
bool isExtensionSupported;
CHECK_EQ(ANeuralNetworksDevice_getExtensionSupport(device, EXAMPLE_EXTENSION_NAME,
&isExtensionSupported),
ANEURALNETWORKS_NO_ERROR);
if (isExtensionSupported) {
// The device supports the extension.
...
}
একটি এক্সটেনশন অপারেন্ড সহ একটি মডেল তৈরি করতে, অপারেন্ড টাইপ পেতে ANeuralNetworksModel_getExtensionOperandType
ব্যবহার করুন এবং ANeuralNetworksModel_addOperand
কল করুন।
int32_t type;
CHECK_EQ(ANeuralNetworksModel_getExtensionOperandType(model, EXAMPLE_EXTENSION_NAME, EXAMPLE_TENSOR, &type),
ANEURALNETWORKS_NO_ERROR);
ANeuralNetworksOperandType operandType{
.type = type,
.dimensionCount = dimensionCount,
.dimensions = dimensions,
};
CHECK_EQ(ANeuralNetworksModel_addOperand(model, &operandType), ANEURALNETWORKS_NO_ERROR);
ঐচ্ছিকভাবে, একটি এক্সটেনশন অপারেন্ডের সাথে অতিরিক্ত ডেটা সংযুক্ত করতে ANeuralNetworksModel_setOperandExtensionData
ব্যবহার করুন।
ExampleTensorParams params{
.scale = 0.5,
.zeroPoint = 128,
};
CHECK_EQ(ANeuralNetworksModel_setOperandExtensionData(model, operandIndex, ¶ms, sizeof(params)),
ANEURALNETWORKS_NO_ERROR);
একটি এক্সটেনশন অপারেশন সহ একটি মডেল তৈরি করতে, অপারেশনের ধরন পেতে ANeuralNetworksModel_getExtensionOperationType
ব্যবহার করুন এবং ANeuralNetworksModel_addOperation
কল করুন।
ANeuralNetworksOperationType type;
CHECK_EQ(ANeuralNetworksModel_getExtensionOperationType(model, EXAMPLE_EXTENSION_NAME, EXAMPLE_FUNCTION,
&type),
ANEURALNETWORKS_NO_ERROR);
CHECK_EQ(ANeuralNetworksModel_addOperation(model, type, inputCount, inputs, outputCount, outputs),
ANEURALNETWORKS_NO_ERROR);
একটি NNAPI ড্রাইভারে এক্সটেনশন সমর্থন যোগ করুন
ড্রাইভার IDevice::getSupportedExtensions
পদ্ধতির মাধ্যমে সমর্থিত এক্সটেনশন রিপোর্ট করে। প্রত্যাবর্তিত তালিকায় অবশ্যই প্রতিটি সমর্থিত এক্সটেনশন বর্ণনা করে একটি এন্ট্রি থাকতে হবে।
Extension {
.name = EXAMPLE_EXTENSION_NAME,
.operandTypes = {
{
.type = EXAMPLE_SCALAR,
.isTensor = false,
.byteSize = 8,
},
{
.type = EXAMPLE_TENSOR,
.isTensor = true,
.byteSize = 8,
},
},
}
প্রকার এবং ক্রিয়াকলাপ সনাক্ত করতে ব্যবহৃত 32টি বিটের মধ্যে, উচ্চ Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX
বিটগুলি হল এক্সটেনশন প্রিফিক্স এবং নিম্ন Model::ExtensionTypeEncoding::LOW_BITS_TYPE
বিটগুলি এক্সটেনশনের ধরন বা অপারেশনকে উপস্থাপন করে৷
একটি অপারেশন বা অপারেন্ড টাইপ পরিচালনা করার সময়, ড্রাইভারকে অবশ্যই এক্সটেনশন উপসর্গটি পরীক্ষা করতে হবে। যদি এক্সটেনশন প্রিফিক্সের একটি অশূন্য মান থাকে, তাহলে অপারেশন বা অপারেন্ড টাইপ একটি এক্সটেনশন প্রকার। মান 0
হলে, অপারেশন বা অপারেন্ড টাইপ একটি এক্সটেনশন প্রকার নয়।
একটি এক্সটেনশন নামের উপসর্গ ম্যাপ করতে, এটি model.extensionNameToPrefix
এ দেখুন। প্রিফিক্স থেকে এক্সটেনশন নামের ম্যাপিং হল একটি প্রদত্ত মডেলের জন্য এক-টু-এক চিঠিপত্র (বিজেকশন)। বিভিন্ন প্রিফিক্স মান বিভিন্ন মডেলের একই এক্সটেনশন নামের সাথে সঙ্গতিপূর্ণ হতে পারে।
ড্রাইভারকে অবশ্যই এক্সটেনশন ক্রিয়াকলাপ এবং ডেটা প্রকারগুলি যাচাই করতে হবে কারণ NNAPI রানটাইম নির্দিষ্ট এক্সটেনশন অপারেশন এবং ডেটা প্রকারগুলিকে যাচাই করতে পারে না।
এক্সটেনশন অপারেন্ডে operand.extraParams.extension
এ সম্পর্কিত ডেটা থাকতে পারে, যেটিকে রানটাইম নির্বিচারে আকারের একটি কাঁচা ডেটা ব্লব হিসাবে বিবেচনা করে।
OEM অপারেশন এবং ডেটা প্রকার
ডিভাইস নির্মাতাদের কাস্টম, ড্রাইভার-নির্দিষ্ট কার্যকারিতা প্রদান করার জন্য NNAPI-এর একটি OEM অপারেশন এবং OEM ডেটা প্রকার রয়েছে। এই অপারেশন এবং ডেটা প্রকারগুলি শুধুমাত্র OEM অ্যাপ্লিকেশন দ্বারা ব্যবহৃত হয়। OEM অপারেশনের শব্দার্থবিদ্যা এবং ডেটা প্রকারগুলি OEM-নির্দিষ্ট এবং যে কোনো সময় পরিবর্তন হতে পারে। OEM অপারেশন এবং ডেটা প্রকারগুলি OperationType::OEM_OPERATION
, OperandType::OEM
, এবং OperandType::TENSOR_OEM_BYTE
ব্যবহার করে এনকোড করা হয়েছে।
নিউরাল নেটওয়ার্ক এপিআই (এনএনএপিআই) ভেন্ডর এক্সটেনশন, অ্যান্ড্রয়েড 10-এ প্রবর্তিত, হল বিক্রেতা-সংজ্ঞায়িত ক্রিয়াকলাপ এবং ডেটা প্রকারের সংগ্রহ। NN HAL 1.2 বা উচ্চতর চলমান ডিভাইসগুলিতে, ড্রাইভারগুলি সংশ্লিষ্ট বিক্রেতা এক্সটেনশনগুলিকে সমর্থন করে কাস্টম হার্ডওয়্যার-ত্বরিত ক্রিয়াকলাপ সরবরাহ করতে পারে। বিক্রেতা এক্সটেনশন বিদ্যমান ক্রিয়াকলাপগুলির আচরণ পরিবর্তন করে না।
বিক্রেতা এক্সটেনশনগুলি OEM ক্রিয়াকলাপ এবং ডেটা প্রকারগুলির একটি আরও কাঠামোগত বিকল্প প্রদান করে, যেগুলি Android 10-এ অবমূল্যায়িত হয়েছিল৷ আরও তথ্যের জন্য, OEM অপারেশন এবং ডেটা প্রকারগুলি দেখুন৷
এক্সটেনশন ব্যবহারের অনুমতি তালিকা
ভেন্ডর এক্সটেনশনগুলি শুধুমাত্র স্পষ্টভাবে নির্দিষ্ট করা Android অ্যাপ এবং /product
, /vendor
, /odm
, এবং /data
পার্টিশনে নেটিভ বাইনারি দ্বারা ব্যবহার করা যেতে পারে। /system
পার্টিশনে অবস্থিত অ্যাপ এবং নেটিভ বাইনারি বিক্রেতা এক্সটেনশন ব্যবহার করতে পারে না।
NNAPI বিক্রেতা এক্সটেনশনগুলি ব্যবহার করার জন্য অনুমোদিত Android অ্যাপ এবং বাইনারিগুলির একটি তালিকা /vendor/etc/nnapi_extensions_app_allowlist
এ সংরক্ষণ করা হয়েছে। ফাইলের প্রতিটি লাইনে একটি নতুন এন্ট্রি রয়েছে। একটি এন্ট্রি একটি নেটিভ বাইনারি পাথ হতে পারে যা একটি স্ল্যাশ (/), উদাহরণস্বরূপ, /data/foo
, বা একটি Android অ্যাপ প্যাকেজের একটি নাম, উদাহরণস্বরূপ, com.foo.bar
সাথে উপসর্গযুক্ত।
NNAPI রানটাইম শেয়ার্ড লাইব্রেরি থেকে অনুমোদিত তালিকা প্রয়োগ করা হয়েছে। এই লাইব্রেরিটি দুর্ঘটনাজনিত ব্যবহার থেকে রক্ষা করে কিন্তু সরাসরি NNAPI ড্রাইভার HAL ইন্টারফেস ব্যবহার করে একটি অ্যাপ দ্বারা ইচ্ছাকৃত প্রতারণার বিরুদ্ধে নয়।
বিক্রেতা এক্সটেনশন সংজ্ঞা
বিক্রেতা এক্সটেনশন সংজ্ঞা সহ একটি হেডার ফাইল তৈরি করে এবং রক্ষণাবেক্ষণ করে। একটি এক্সটেনশন সংজ্ঞার একটি সম্পূর্ণ উদাহরণ example/fibonacci/FibonacciExtension.h
এ পাওয়া যাবে।
প্রতিটি এক্সটেনশনের একটি অনন্য নাম থাকতে হবে যা বিক্রেতার বিপরীত ডোমেন নাম দিয়ে শুরু হয়।
const char EXAMPLE_EXTENSION_NAME[] = "com.example.my_extension";
নামটি অপারেশন এবং ডেটা প্রকারের জন্য একটি নামস্থান হিসাবে কাজ করে। NNAPI বিক্রেতা এক্সটেনশনগুলির মধ্যে পার্থক্য করতে এই নামটি ব্যবহার করে।
runtime/include/NeuralNetworks.h
মতোই অপারেশন এবং ডেটা টাইপ ঘোষণা করা হয়।
enum {
/**
* A custom scalar type.
*/
EXAMPLE_SCALAR = 0,
/**
* A custom tensor type.
*
* Attached to this tensor is {@link ExampleTensorParams}.
*/
EXAMPLE_TENSOR = 1,
};
enum {
/**
* Computes example function.
*
* Inputs:
* * 0: A scalar of {@link EXAMPLE_SCALAR}.
*
* Outputs:
* * 0: A tensor of {@link EXAMPLE_TENSOR}.
*/
EXAMPLE_FUNCTION = 0,
};
একটি এক্সটেনশন অপারেশন অন্য এক্সটেনশন থেকে ননএক্সটেনশন অপারেন্ড প্রকার এবং অপারেন্ড প্রকার সহ যেকোনো অপারেন্ড প্রকার ব্যবহার করতে পারে। অন্য এক্সটেনশন থেকে অপারেন্ড টাইপ ব্যবহার করার সময়, ড্রাইভারকে অবশ্যই অন্য এক্সটেনশন সমর্থন করতে হবে।
এক্সটেনশনগুলি এক্সটেনশন অপারেন্ডের সাথে কাস্টম কাঠামো ঘোষণা করতে পারে।
/**
* Quantization parameters for {@link EXAMPLE_TENSOR}.
*/
typedef struct ExampleTensorParams {
double scale;
int64_t zeroPoint;
} ExampleTensorParams;
NNAPI ক্লায়েন্টে এক্সটেনশন ব্যবহার করুন
runtime/include/NeuralNetworksExtensions.h
(C API) ফাইল রানটাইম এক্সটেনশন সমর্থন প্রদান করে। এই বিভাগটি C API এর একটি ওভারভিউ প্রদান করে।
একটি ডিভাইস একটি এক্সটেনশন সমর্থন করে কিনা তা পরীক্ষা করতে, ANeuralNetworksDevice_getExtensionSupport
ব্যবহার করুন।
bool isExtensionSupported;
CHECK_EQ(ANeuralNetworksDevice_getExtensionSupport(device, EXAMPLE_EXTENSION_NAME,
&isExtensionSupported),
ANEURALNETWORKS_NO_ERROR);
if (isExtensionSupported) {
// The device supports the extension.
...
}
একটি এক্সটেনশন অপারেন্ড সহ একটি মডেল তৈরি করতে, অপারেন্ড টাইপ পেতে ANeuralNetworksModel_getExtensionOperandType
ব্যবহার করুন এবং ANeuralNetworksModel_addOperand
কল করুন।
int32_t type;
CHECK_EQ(ANeuralNetworksModel_getExtensionOperandType(model, EXAMPLE_EXTENSION_NAME, EXAMPLE_TENSOR, &type),
ANEURALNETWORKS_NO_ERROR);
ANeuralNetworksOperandType operandType{
.type = type,
.dimensionCount = dimensionCount,
.dimensions = dimensions,
};
CHECK_EQ(ANeuralNetworksModel_addOperand(model, &operandType), ANEURALNETWORKS_NO_ERROR);
ঐচ্ছিকভাবে, একটি এক্সটেনশন অপারেন্ডের সাথে অতিরিক্ত ডেটা সংযুক্ত করতে ANeuralNetworksModel_setOperandExtensionData
ব্যবহার করুন।
ExampleTensorParams params{
.scale = 0.5,
.zeroPoint = 128,
};
CHECK_EQ(ANeuralNetworksModel_setOperandExtensionData(model, operandIndex, ¶ms, sizeof(params)),
ANEURALNETWORKS_NO_ERROR);
একটি এক্সটেনশন অপারেশন সহ একটি মডেল তৈরি করতে, অপারেশনের ধরন পেতে ANeuralNetworksModel_getExtensionOperationType
ব্যবহার করুন এবং ANeuralNetworksModel_addOperation
কল করুন।
ANeuralNetworksOperationType type;
CHECK_EQ(ANeuralNetworksModel_getExtensionOperationType(model, EXAMPLE_EXTENSION_NAME, EXAMPLE_FUNCTION,
&type),
ANEURALNETWORKS_NO_ERROR);
CHECK_EQ(ANeuralNetworksModel_addOperation(model, type, inputCount, inputs, outputCount, outputs),
ANEURALNETWORKS_NO_ERROR);
একটি NNAPI ড্রাইভারে এক্সটেনশন সমর্থন যোগ করুন
ড্রাইভার IDevice::getSupportedExtensions
পদ্ধতির মাধ্যমে সমর্থিত এক্সটেনশন রিপোর্ট করে। প্রত্যাবর্তিত তালিকায় অবশ্যই প্রতিটি সমর্থিত এক্সটেনশন বর্ণনা করে একটি এন্ট্রি থাকতে হবে।
Extension {
.name = EXAMPLE_EXTENSION_NAME,
.operandTypes = {
{
.type = EXAMPLE_SCALAR,
.isTensor = false,
.byteSize = 8,
},
{
.type = EXAMPLE_TENSOR,
.isTensor = true,
.byteSize = 8,
},
},
}
প্রকার এবং ক্রিয়াকলাপ সনাক্ত করতে ব্যবহৃত 32টি বিটের মধ্যে, উচ্চ Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX
বিটগুলি হল এক্সটেনশন প্রিফিক্স এবং নিম্ন Model::ExtensionTypeEncoding::LOW_BITS_TYPE
বিটগুলি এক্সটেনশনের ধরন বা অপারেশনকে উপস্থাপন করে৷
একটি অপারেশন বা অপারেন্ড টাইপ পরিচালনা করার সময়, ড্রাইভারকে অবশ্যই এক্সটেনশন উপসর্গটি পরীক্ষা করতে হবে। যদি এক্সটেনশন প্রিফিক্সের একটি অশূন্য মান থাকে, তাহলে অপারেশন বা অপারেন্ড টাইপ একটি এক্সটেনশন প্রকার। মান 0
হলে, অপারেশন বা অপারেন্ড টাইপ একটি এক্সটেনশন প্রকার নয়।
একটি এক্সটেনশন নামের উপসর্গ ম্যাপ করতে, এটি model.extensionNameToPrefix
এ দেখুন। প্রিফিক্স থেকে এক্সটেনশন নামের ম্যাপিং হল একটি প্রদত্ত মডেলের জন্য এক-টু-এক চিঠিপত্র (বিজেকশন)। বিভিন্ন প্রিফিক্স মান বিভিন্ন মডেলের একই এক্সটেনশন নামের সাথে সঙ্গতিপূর্ণ হতে পারে।
ড্রাইভারকে অবশ্যই এক্সটেনশন ক্রিয়াকলাপ এবং ডেটা প্রকারগুলি যাচাই করতে হবে কারণ NNAPI রানটাইম নির্দিষ্ট এক্সটেনশন অপারেশন এবং ডেটা প্রকারগুলিকে যাচাই করতে পারে না।
এক্সটেনশন অপারেন্ডে operand.extraParams.extension
এ সম্পর্কিত ডেটা থাকতে পারে, যেটিকে রানটাইম নির্বিচারে আকারের একটি কাঁচা ডেটা ব্লব হিসাবে বিবেচনা করে।
OEM অপারেশন এবং ডেটা প্রকার
ডিভাইস নির্মাতাদের কাস্টম, ড্রাইভার-নির্দিষ্ট কার্যকারিতা প্রদান করার জন্য NNAPI-এর একটি OEM অপারেশন এবং OEM ডেটা প্রকার রয়েছে। এই অপারেশন এবং ডেটা প্রকারগুলি শুধুমাত্র OEM অ্যাপ্লিকেশন দ্বারা ব্যবহৃত হয়। OEM অপারেশনের শব্দার্থবিদ্যা এবং ডেটা প্রকারগুলি OEM-নির্দিষ্ট এবং যে কোনো সময় পরিবর্তন হতে পারে। OEM অপারেশন এবং ডেটা প্রকারগুলি OperationType::OEM_OPERATION
, OperandType::OEM
, এবং OperandType::TENSOR_OEM_BYTE
ব্যবহার করে এনকোড করা হয়েছে।