Repository navigation
Conversation
Loading a `file://` model read the whole file into memory before handing it to TFLite. On Android, `URL.readBytes()` fills a ByteArrayOutputStream that grows to about twice the model's size in the Java heap, so a ~200 MB model throws OutOfMemoryError against the common 256 MB heap limit. On iOS the model was copied twice (into `Data`, then into the `ArrayBuffer`). Local files are now memory-mapped and wrapped without a copy: - Android maps the file read-only and wraps the direct ByteBuffer. - iOS mmaps it copy-on-write and unmaps it when the ArrayBuffer is deleted. `http(s)://` URLs and Android `res/raw` resources keep the existing paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
|
Built this branch (2f5e775) against
Two things on
The example's harness tests load models through |
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
loadTensorflowModel({ url: 'file://...' })reads the whole model into memory before creating the interpreter.Android:
URL(path).readBytes()copies the file into aByteArrayOutputStream, which grows to about twice the model's size in the Java heap. A ~200 MB model (a Perch v2 audio classifier, in our case) throwsOutOfMemoryErroragainst the common 256 MB heap limit:iOS: the model is copied twice, once into
Dataand once into theArrayBuffer, so peak memory is about twice the model size.Fix
Local
file://models are memory-mapped and wrapped in anArrayBufferwithout a copy:READ_ONLYand returnsArrayBuffer.wrap(mappedByteBuffer). TFLite only reads the model data. A copy-on-write mapping would need a writable channel. The mapping stays valid after the channel closes, and the wrapped direct buffer keeps it alive.mmaps the fileMAP_PRIVATEand returnsArrayBuffer.wrap(dataWithoutCopy:size:onDelete:), whichmunmaps it when the buffer is deleted.url.pathalso decodes percent-encoded paths such asApplication%20Support.http(s)://URLs and Androidres/rawresources keep their current code paths.Testing
I ran the same change as a patch on 3.0.1 in our app. 3.0.1's Android loader has no
res/rawbranch; otherwise the code is identical.OutOfMemoryErrorloading a 203 MB modelI also built this branch against
main's example app: AndroidassembleDebugand the iOS Debug simulator build both pass, with no warnings from either loader. On Xcode 27.1 the iOS build needsIPHONEOS_DEPLOYMENT_TARGET=15.1to get past theTensorFlowLiteCpods' 12.0 target, which is a problem onmaintoo. The example's harness tests load models from Metro over HTTP, so they don't exercise thefile://path. Details.🤖 Generated with Claude Code