feat: on-demand native lib download and optional feature splitting#1039
feat: on-demand native lib download and optional feature splitting#1039msluszniak wants to merge 10 commits into
Conversation
|
TODO: separate xnnpack and coreml backends to separate libs, so they can be opt-out the same way as opencv etc. |
|
Adding support for vulkan is in progress |
e69584e to
5aa72cc
Compare
|
Status — verified working state PR is in a tested, working state with a clear opt-in/opt-out model for every backend except XNNPACK on Android (which stays baked into
Verified on a Galaxy S26 Ultra and an iPhone 17 Pro simulator (Xcode 26.4.1):
Supporting executorch fork branch: Next work Make XNNPACK separable on Android too — apply the same QNN-style |
5aa72cc to
eb14dbe
Compare
|
Update — XNNPACK on Android is now separable too Every backend is now opt-in symmetrically across both platforms:
Two changes on the executorch fork (
Verified on the same Galaxy S26 Ultra:
The This finishes the work tracked above. PR is ready for review. |
The npm tarball ships without prebuilt native binaries — they are
downloaded from GitHub Releases at postinstall and extracted into
third-party/, where the existing CMake / podspec configurations pick them
up unchanged. Apps can opt out of features they don't need to skip both
the download and the native compilation:
"react-native-executorch": {
"extras": ["opencv", "phonemizer", "xnnpack", "coreml", "vulkan"]
}
Defaults to all enabled. Each extra trims one or more artifacts and toggles
a corresponding RNE_ENABLE_* CMake / podspec flag, dropping its sources from
compilation and its libraries from the final link.
Per-platform behavior:
- opencv Android + iOS (iOS provided via opencv-rne CocoaPod)
- phonemizer Android + iOS
- xnnpack iOS-only as a force-loaded XnnpackBackend.xcframework;
baked into libexecutorch.so on Android
- coreml iOS-only as a force-loaded CoreMLBackend.xcframework
- vulkan Android-only as a separately-loaded
libvulkan_executorch_backend.so
Vulkan ships as its own shared library (mirroring the QNN backend pattern)
so its load-time backend registration runs only when the user opts in. The
.so links only against vulkan_backend + vulkan_schema + executorch_core,
not the CPU kernel registries, so it does not cause duplicate kernel
registration when loaded alongside libexecutorch.so.
eb14dbe to
ef7ab0e
Compare
Bring NATIVE_LIBS_PIPELINE.md in sync with the current
msluszniak/executorch@ms/separate-backends tip:
- Pin SHA bumped from 1a5c0f267 to bd24ac7681.
- Patch list expanded to cover all 10 commits on the fork branch:
the original 4 (version-script removal, vulkan-shared, flatcc-Werror,
xnnpack-shared) plus the 6 added in this round (tokenizers submodule
switched to software-mansion-labs/pytorch-tokenizers@build,
build_android_library.sh forwards BACKEND_SHARED env vars to cmake,
XNNWeightsCache null-ptr fix, ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES,
iOS create_frameworks.sh keeps merged .a files, iOS CMakePresets
disable XNNPACK_ENABLE_ARM_SME{,2}).
- iOS build section rewritten as a three-stage flow (fork .a build →
stage into RNE → repackage via ExecutorchLib/build.sh).
|
Thanks @msluszniak . Mind working on small stack of PRs so it's easier to review? |
|
@kirklandsign this particular PR solely address React Native ExecuTorch repo, but what is probably instresting for you is a not-yet-published PR from https://github.com/msluszniak/executorch/tree/@ms/separate-backends branch to executorch. For this one, for sure I can proceed with a series of small PRs :)). I just want to make sure changes are aligned with RNE repo first. I just need to check if iOS works the same way as Android. |
…steps The fork branch grew an 11th patch on top of bd24ac7681 to address the flatccrt build failure on Apple clang 21 inside the iOS / macOS presets (separate from the host-side flatcc_ep fix). Bump the pinned SHA to 3ce953dbde73035e733442f99c082f5b6fedff5b and add the patch to the list. Rewrite the iOS build section so a fresh machine can reproduce the artifacts exactly: - Drop the install_executorch.sh step: torch_pin.py points at a pruned nightly. Pin torch==2.11.0 directly + install requirements-dev + certifi/zstd (Buck2 resolver) instead. - Switch from a bare 'create_frameworks.sh' invocation to 'build_apple_frameworks.sh --Release', which orchestrates the cmake builds and calls create_frameworks.sh with the required flags. - Document the harmless 'no binary artifact for *_debug.xcframework' Swift Package error at the end of --Release runs. - Spell out the exact per-slice .a file list to stage into RNE. - Call out that libkleidiai_*.a and the non-executorch prebuilts (cpuinfo / pthreadpool / phonemis) are kept as-is, not rebuilt. - Add the iOS 26.4 simulator NSURLSession regression as a callout so future maintainers don't lose another day chasing it.
…-libs # Conflicts: # .cspell-wordlist.txt
…-libs # Conflicts: # packages/react-native-executorch/android/src/main/cpp/CMakeLists.txt # packages/react-native-executorch/react-native-executorch.podspec # packages/react-native-executorch/third-party/ios/ExecutorchLib.xcframework/ios-arm64-simulator/ExecutorchLib.framework/Info.plist # packages/react-native-executorch/third-party/ios/ExecutorchLib.xcframework/ios-arm64/ExecutorchLib.framework/Info.plist
- Three optional arrays in package.json: `backends`, `libs`, `features` (all merged). - `features` is sugar: each one expands to (backends, libs) via FEATURE_MAP matching the documented use* hooks (16 features, e.g. `llm`, `textToSpeech`, `objectDetection`). - Backends and libs are validated; unknown values throw with a list of supported ones. - Legacy `extras` is rejected with a migration error. - Defaults stay all-on when no config is given. - ModelHostObject.h: gate TextToSpeech include + Kokoro if-constexpr block with RNE_ENABLE_PHONEMIZER — unblocks builds when the phonemizer lib is disabled.
…ps' features
- FEATURE_MAP rebuilt from src/constants/modelRegistry.ts. Removed guessed
backends. LLMs / TTS / VAD / OCR / pose / sem-seg / textEmbeddings / textToImage
are xnnpack-only; classification / objectDetection / instanceSegmentation /
styleTransfer / speechToText / segmentAnything also ship coreml.
No model family currently ships a vulkan variant.
- Added privacyFilter feature.
- Demo apps now declare their actual feature set:
- bare-rn: [llm]
- llm: [llm, multimodalLLM, privacyFilter]
- speech: [llm, speechToText, textToSpeech, vad]
- text-embeddings: [textEmbeddings, imageEmbeddings]
- computer-vision: [classification, imageEmbeddings, instanceSegmentation,
ocr, objectDetection, poseEstimation, semanticSegmentation,
styleTransfer, textEmbeddings, textToImage, verticalOCR]
|
PR is ready for review. Right now, I'm testing all demo apps on both iOS and Android. |
Description
Removes prebuilt native binaries from the npm tarball and downloads them at postinstall from GitHub Releases. Apps declare exactly what they need under
react-native-executorchinpackage.json— three optional arrays, all merged into a single set:{ "react-native-executorch": { "backends": ["xnnpack", "coreml", "vulkan"], "libs": ["opencv", "phonemizer"], "features": ["llm", "textToSpeech", "objectDetection"] } }featuresis the friendly opt-in: list theuse*hooks you'll use and the postinstall expands each one to its required backends + libs (perFEATURE_MAP).backends/libsare the precise opt-in.The 18 features track the documented
use*hooks one-for-one; each row's backend list is the union of what at least one model in that family ships today (sourced fromsrc/constants/modelRegistry.ts).xnnpackbackendXnnpackBackend.xcframeworkforce-loadedlibxnnpack_executorch_backend.socoremlbackendCoreMLBackend.xcframeworkforce-loadedvulkanbackendlibvulkan_executorch_backend.soopencvlibopencv-rneCocoaPodlibopencv_*.a+ KleidiCV HAL (arm64)phonemizerlibthird-party/common/phonemissubmodule)add_subdirectoryEach Android backend
.solinks only<backend>_backend (--whole-archive) + <backend>_schema + executorch_core— no CPU kernel registries — so loading multiple side-by-side does not trigger duplicate kernel registration. Supporting executorch fork branch:software-mansion-labs/executorch@ms/separate-backends(EXECUTORCH_BUILD_XNNPACK_BACKEND_SHARED+EXECUTORCH_BUILD_VULKAN_BACKEND_SHAREDswitches, acustom_opsfix to stop the transitive XNNPACK link from leaking intolibexecutorch_jni.so, and a flatcc-Werrorworkaround for Apple clang 21).Demo apps in this PR declare their actual feature set:
bare-rn→["llm"]llm→["llm", "multimodalLLM", "privacyFilter"]speech→["llm", "speechToText", "textToSpeech", "vad"]text-embeddings→["textEmbeddings", "imageEmbeddings"]computer-vision→["classification", "imageEmbeddings", "instanceSegmentation", "ocr", "objectDetection", "poseEstimation", "semanticSegmentation", "styleTransfer", "textEmbeddings", "textToImage", "verticalOCR"]Introduces a breaking change?
Removes the legacy
extrasfield. Apps that set it get an install-time error pointing at the new shape.Type of change
Tested on
Testing instructions
Test the download flow:
Test feature opt-in (drop opencv / coreml by listing only LLM-shaped features):
package.jsonset"features": ["llm"].yarn install→rne-build-config.jsonshould showenableOpencv:false,enableCoreml:false,enableXnnpack:true.Backend CoreMLBackend is not registerederror rather than crashing.Test phonemizer opt-out:
package.jsonset"features": ["textEmbeddings"](no TTS).yarn install(regeneratesrne-build-config.json), thenpod install/ regenerateandroid/.Test that legacy
extrasis rejected:package.jsonset"extras": ["opencv"].yarn installfails with an explicit migration error pointing atbackends,libs,features.Related issues
Builds toward pytorch/executorch#10457 (hot-pluggable Android backends).
Checklist