I have a .tflite
model file that is over 200MB in size. As it increases the 150MB max size for an apk I had to bundle in in an app bundle using Play Asset Delivery (PAD).
I followed the guide mentioned here: and was able to build my .aab
file. I have added my asst as install-time
, so I do not have to check for its availability, it should be installed with the app.
But cannot seem to access my tflite
file.
I am able to load the model from the assets folder perfectly using:
private MappedByteBuffer loadModelFile() throws Exception {
AssetFileDescriptor fileDescriptor = this.getAssets().openFd("model.tflite");
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);
}
but this does not work with PAD as we are required to use AssetManager
, as explained here.
So I rewrote the above function to use AssetManager
:
Context context = createPackageContext("com.companyname.packagename", 0);
AssetManager assetManager = context.getAssets();
private MappedByteBuffer loadModelFile(AssetManager assetManager, String modelPath) throws IOException {
AssetFileDescriptor fileDescriptor = assetManager.openFd("model.tflite");
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);
}
But it does not appear to load the model. As on the interpreter.run()
method, I get the error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void org.tensorflow.lite.Interpreter.run(java.lang.Object, java.lang.Object)' on a null object reference
which suggests that the model was not loaded.
Is the path of the model different in this case? How would I load a tflite model?
So it turns out the function I have above is the correct way to load a tflite model using AssetManager
.
Context context = createPackageContext("com.companyname.packagename", 0);
AssetManager assetManager = context.getAssets();
private MappedByteBuffer loadModelFile(AssetManager assetManager, String modelPath) throws IOException {
AssetFileDescriptor fileDescriptor = assetManager.openFd("model.tflite");
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);
}
The reason it was not loading the model was because when using Play Asset Delivery, the install-time
assets only become available to use after being installed from the downloaded play bundle from play store.
As install-time
assets act like just normal assets, the location of the asset stays the same.