TensorFlow Lite NNAPI প্রতিনিধি

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

  • গ্রাফিক্স প্রসেসিং ইউনিট (GPU)
  • ডিজিটাল সিগন্যাল প্রসেসর (DSP)
  • নিউরাল প্রসেসিং ইউনিট (NPU)

ডিভাইসে উপলব্ধ নির্দিষ্ট হার্ডওয়্যারের উপর নির্ভর করে কর্মক্ষমতা পরিবর্তিত হবে।

এই পৃষ্ঠাটি বর্ণনা করে যে কীভাবে জাভা এবং কোটলিনে টেনসরফ্লো লাইট ইন্টারপ্রেটারের সাথে NNAPI প্রতিনিধি ব্যবহার করবেন। Android C API-এর জন্য, অনুগ্রহ করে Android Native Developer Kit ডকুমেন্টেশন দেখুন।

আপনার নিজের মডেলে এনএনএপিআই প্রতিনিধি চেষ্টা করছেন৷

গ্রেডল আমদানি

NNAPI প্রতিনিধি হল TensorFlow Lite Android দোভাষীর অংশ, রিলিজ 1.14.0 বা উচ্চতর। আপনি আপনার মডিউল গ্রেডল ফাইলে নিম্নলিখিত যোগ করে আপনার প্রকল্পে এটি আমদানি করতে পারেন:

dependencies {
   implementation 'org.tensorflow:tensorflow-lite:+'
}

NNAPI প্রতিনিধির সূচনা করা হচ্ছে

TensorFlow Lite ইন্টারপ্রেটার শুরু করার আগে NNAPI প্রতিনিধিকে আরম্ভ করার জন্য কোডটি যোগ করুন।

কোটলিন

import android.content.res.AssetManager
import org.tensorflow.lite.Interpreter
import org.tensorflow.lite.nnapi.NnApiDelegate
import java.io.FileInputStream
import java.io.IOException
import java.nio.MappedByteBuffer
import java.nio.channels.FileChannel
...

val options = Interpreter.Options()
var nnApiDelegate: NnApiDelegate? = null
// Initialize interpreter with NNAPI delegate for Android Pie or above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    nnApiDelegate = NnApiDelegate()
    options.addDelegate(nnApiDelegate)
}
val assetManager = assets

// Initialize TFLite interpreter
val tfLite: Interpreter
try {
    tfLite = Interpreter(loadModelFile(assetManager, "model.tflite"), options)
} catch (e: Exception) {
    throw RuntimeException(e)
}

// Run inference
// ...

// Unload delegate
tfLite.close()
nnApiDelegate?.close()

...

@Throws(IOException::class)
private fun loadModelFile(assetManager: AssetManager, modelFilename: String): MappedByteBuffer {
    val fileDescriptor = assetManager.openFd(modelFilename)
    val inputStream = FileInputStream(fileDescriptor.fileDescriptor)
    val fileChannel = inputStream.channel
    val startOffset = fileDescriptor.startOffset
    val declaredLength = fileDescriptor.declaredLength
    return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength)
}

...

জাভা

import android.content.res.AssetManager;
import org.tensorflow.lite.Interpreter;
import org.tensorflow.lite.nnapi.NnApiDelegate;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
...

Interpreter.Options options = (new Interpreter.Options());
NnApiDelegate nnApiDelegate = null;
// Initialize interpreter with NNAPI delegate for Android Pie or above
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    nnApiDelegate = new NnApiDelegate();
    options.addDelegate(nnApiDelegate);
}

AssetManager assetManager = getAssets();
// Initialize TFLite interpreter
try {
    tfLite = new Interpreter(loadModelFile(assetManager, "model.tflite"), options);
} catch (Exception e) {
    throw new RuntimeException(e);
}

// Run inference
// ...

// Unload delegate
tfLite.close();
if(null != nnApiDelegate) {
    nnApiDelegate.close();
}

...

private MappedByteBuffer loadModelFile(AssetManager assetManager, String modelFilename) throws IOException {
    AssetFileDescriptor fileDescriptor = assetManager.openFd(modelFilename);
    FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
    FileChannel fileChannel = inputStream.getChannel();
    long startOffset = fileDescriptor.getStartOffset();
    long declaredLength = fileDescriptor.getDeclaredLength();
    return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
}

...

সেরা অনুশীলন

স্থাপন করার আগে পরীক্ষা কর্মক্ষমতা

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

উন্নত ডেভেলপারদের জন্য, TensorFlow Lite Android এর জন্য একটি মডেল বেঞ্চমার্ক টুলও অফার করে।

একটি ডিভাইস বর্জন তালিকা তৈরি করুন

উৎপাদনে, এমন কিছু ক্ষেত্রে হতে পারে যেখানে NNAPI প্রত্যাশিতভাবে কাজ করে না। আমরা ডেভেলপারদের এমন ডিভাইসগুলির একটি তালিকা বজায় রাখার পরামর্শ দিই যেগুলি নির্দিষ্ট মডেলগুলির সাথে একত্রে NNAPI ত্বরণ ব্যবহার করা উচিত নয়৷ আপনি "ro.board.platform" এর মানের উপর ভিত্তি করে এই তালিকা তৈরি করতে পারেন, যা আপনি নিম্নলিখিত কোড স্নিপেট ব্যবহার করে পুনরুদ্ধার করতে পারেন:

String boardPlatform = "";

try {
    Process sysProcess =
        new ProcessBuilder("/system/bin/getprop", "ro.board.platform").
        redirectErrorStream(true).start();

    BufferedReader reader = new BufferedReader
        (new InputStreamReader(sysProcess.getInputStream()));
    String currentLine = null;

    while ((currentLine=reader.readLine()) != null){
        boardPlatform = line;
    }
    sysProcess.destroy();
} catch (IOException e) {}

Log.d("Board Platform", boardPlatform);

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

কোয়ান্টাইজেশন

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

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

সমর্থিত মডেল এবং অপ্স ব্যবহার করুন

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

NNAPI সর্বোত্তম কার্য সম্পাদন করে যখন মডেলগুলি শুধুমাত্র সমর্থিত অপ্স ব্যবহার করে। নিম্নলিখিত মডেলগুলি NNAPI এর সাথে সামঞ্জস্যপূর্ণ বলে পরিচিত:

যখন মডেলে গতিশীল আকারের আউটপুট থাকে তখন NNAPI ত্বরণও সমর্থিত হয় না। এই ক্ষেত্রে, আপনি একটি সতর্কতা পাবেন যেমন:

ERROR: Attempting to use a delegate that only supports static-sized tensors \
with a graph that has dynamic-sized tensors.

NNAPI CPU বাস্তবায়ন সক্ষম করুন৷

একটি গ্রাফ যা একটি এক্সিলারেটর দ্বারা সম্পূর্ণরূপে প্রক্রিয়া করা যায় না তা NNAPI CPU বাস্তবায়নে ফিরে যেতে পারে। যাইহোক, যেহেতু এটি সাধারণত TensorFlow ইন্টারপ্রেটারের তুলনায় কম পারফরম্যান্স করে, তাই এই বিকল্পটি Android 10 (API লেভেল 29) বা তার বেশির জন্য NNAPI প্রতিনিধিতে ডিফল্টরূপে অক্ষম করা থাকে। এই আচরণটি ওভাররাইড করতে, NnApiDelegate.Options অবজেক্টে setUseNnapiCpu true সেট করুন।