You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
OS Platform and Distribution (e.g., Linux Ubuntu 24.04):
Mobile device (e.g. iPhone 8, Pixel 2, Samsung Galaxy) if the issue happens on mobile device: Samsung Galaxy S23
TensorFlow.js installed from (npm or script link): yarn add @tensorflow/tfjs @tensorflow/tfjs-react-native
TensorFlow.js version: ^4.22.0
React-native version: ^1.0.0
Current behavior
This is the current source-code of the BundleResourceHandler class:
classBundleResourceHandlerimplementsio.IOHandler{constructor(protectedreadonlymodelJson: io.ModelJSON,protectedreadonlymodelWeightsId: Array<string|number>){if(modelJson==null||modelWeightsId==null){thrownewError('Must pass the model json object and the model weights path.');}}/** * Save model artifacts. This IO handler cannot support writing to the * packaged bundle at runtime and is exclusively for loading a model * that is already packages with the app. */asyncsave(): Promise<io.SaveResult>{thrownewError('Bundle resource IO handler does not support saving. '+'Consider using asyncStorageIO instead');}/** * Load a model from local storage. * * See the documentation to `browserLocalStorage` for details on the saved * artifacts. * * @returns The loaded model (if loading succeeds). */asyncload(): Promise<io.ModelArtifacts>{constweightsAssets=this.modelWeightsId.map(id=>Asset.fromModule(id));if(weightsAssets[0].uri.match('^http')){// In debug/dev mode RN will serve these assets over HTTPreturnthis.loadViaHttp(weightsAssets);}else{// In release mode the assets will be on the file system.returnthis.loadLocalAsset(weightsAssets);}}asyncloadViaHttp(weightsAssets: Asset[]): Promise<io.ModelArtifacts>{constmodelJson=this.modelJson;constmodelArtifacts: io.ModelArtifacts=Object.assign({},modelJson);modelArtifacts.weightSpecs=modelJson.weightsManifest[0].weights;//@ts-ignoredeletemodelArtifacts.weightManifest;// Load the weightsconstweightsDataArray=awaitPromise.all(weightsAssets.map(async(weightAsset)=>{consturl=weightAsset.uri;constrequestInit: undefined=undefined;constresponse=awaitfetch(url,requestInit,{isBinary: true});constweightData=awaitresponse.arrayBuffer();returnweightData;}));modelArtifacts.weightData=io.concatenateArrayBuffers(weightsDataArray);returnmodelArtifacts;}asyncloadLocalAsset(weightsAssets: Asset[]): Promise<io.ModelArtifacts>{// Use a dynamic import here because react-native-fs is not compatible// with managed expo workflow. However the managed expo workflow should// never hit this code path.// tslint:disable-next-line: no-require-importsconstRNFS=require('react-native-fs');constmodelJson=this.modelJson;constmodelArtifacts: io.ModelArtifacts=Object.assign({},modelJson);modelArtifacts.weightSpecs=modelJson.weightsManifest[0].weights;//@ts-ignoredeletemodelArtifacts.weightManifest;// Load the weightsconstweightsDataArray=awaitPromise.all(weightsAssets.map(async(weightsAsset)=>{letbase64Weights: string;if(Platform.OS==='android'){// On android we get a resource id instead of a regular path. We// need to load the weights from the res/raw folder using this id.constfileName=`${weightsAsset.uri}.${weightsAsset.type}`;try{base64Weights=awaitRNFS.readFileRes(fileName,'base64');}catch(e){thrownewError(`Error reading resource ${fileName}. Make sure the file is in located in the res/raw folder of the bundle`,);}}else{try{base64Weights=awaitRNFS.readFile(weightsAsset.uri,'base64');}catch(e){thrownewError(`Error reading resource ${weightsAsset.uri}.`,);}}constweightData=util.encodeString(base64Weights,'base64').buffer;returnweightData;}));modelArtifacts.weightData=io.concatenateArrayBuffers(weightsDataArray);returnmodelArtifacts;}}
In release mode, the loadLocalAsset method loads weights to the model. But whenever expo-updates is installed, it bundles assets differently in the release build. In turn, the weightsAsset.uri is undefined and an error is thrown saying
Error reading resource .bin. Make sure the file is
in located in the res/raw folder of the bundle
This is crashing the app while loading models.
Expected behavior
The app should be able to load the weights in every situation.
Possible Solution
Fallback to the localUri property of the asset when uri is not available
// On android we get a resource id instead of a regular path. We
// need to load the weights from the res/raw folder using this id.
- const fileName = `${weightsAsset.uri}.${weightsAsset.type}`;+ const fileName = weightAssets.uri ? `${weightAssets.uri}.${weightAssets.type}` : weightAssets.localUri;
This helps ensure that the model weights from either the uri or the localUri.
Standalone code to reproduce the issue
Basically any expo app in release mode with expo-updates install. N.B.: Run apps as a development build and not inside Expo Go.
The text was updated successfully, but these errors were encountered:
The code snippet you provided doesn't show how the tfjs model is being loaded. Could you please explain your model loading process in Expo? My understanding is that loading local models/weights directly from the bundle isn't possible. You typically need to configure metro.config.js to include the model/weight file extensions.
The code snippet you provided doesn't show how the tfjs model is being loaded. Could you please explain your model loading process in Expo? My understanding is that loading local models/weights directly from the bundle isn't possible. You typically need to configure metro.config.js to include the model/weight file extensions.
I have updated the issues and included my metro config file.
System information
yarn add @tensorflow/tfjs @tensorflow/tfjs-react-native
^4.22.0
^1.0.0
Current behavior
This is the current source-code of the
BundleResourceHandler
class:And my metro config:
In release mode, the
loadLocalAsset
method loads weights to the model. But wheneverexpo-updates
is installed, it bundles assets differently in the release build. In turn, theweightsAsset.uri
is undefined and an error is thrown sayingThis is crashing the app while loading models.
Expected behavior
The app should be able to load the weights in every situation.
Possible Solution
Fallback to the
localUri
property of the asset whenuri
is not availableThis helps ensure that the model weights from either the
uri
or thelocalUri
.Standalone code to reproduce the issue
Basically any expo app in release mode with
expo-updates
install.N.B.: Run apps as a development build and not inside Expo Go.
The text was updated successfully, but these errors were encountered: