From fcd7a6eff7e14ad8501e570f8556205303f19c7a Mon Sep 17 00:00:00 2001 From: Bartosz Hanc Date: Tue, 10 Mar 2026 16:50:01 +0100 Subject: [PATCH 1/3] fix: fix unload in LLM and ModelHostObject to properly free memory --- .../common/rnexecutorch/host_objects/ModelHostObject.h | 1 + .../common/rnexecutorch/models/llm/LLM.cpp | 5 ++++- .../react-native-executorch/src/controllers/LLMController.ts | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/react-native-executorch/common/rnexecutorch/host_objects/ModelHostObject.h b/packages/react-native-executorch/common/rnexecutorch/host_objects/ModelHostObject.h index c175be829..90241eac0 100644 --- a/packages/react-native-executorch/common/rnexecutorch/host_objects/ModelHostObject.h +++ b/packages/react-native-executorch/common/rnexecutorch/host_objects/ModelHostObject.h @@ -436,6 +436,7 @@ template class ModelHostObject : public JsiHostObject { JSI_HOST_FUNCTION(unload) { try { model->unload(); + thisValue.asObject(runtime).setExternalMemoryPressure(runtime, 0); } catch (const RnExecutorchError &e) { jsi::Object errorData(runtime); errorData.setProperty(runtime, "code", e.getNumericCode()); diff --git a/packages/react-native-executorch/common/rnexecutorch/models/llm/LLM.cpp b/packages/react-native-executorch/common/rnexecutorch/models/llm/LLM.cpp index 03afd4ed0..e21182129 100644 --- a/packages/react-native-executorch/common/rnexecutorch/models/llm/LLM.cpp +++ b/packages/react-native-executorch/common/rnexecutorch/models/llm/LLM.cpp @@ -255,6 +255,9 @@ int32_t LLM::getMaxContextLength() const { return runner_->get_max_context_length(); } -void LLM::unload() noexcept { runner_.reset(nullptr); } +void LLM::unload() noexcept { + runner.reset(nullptr); + BaseModel::unload(); +} } // namespace rnexecutorch::models::llm diff --git a/packages/react-native-executorch/src/controllers/LLMController.ts b/packages/react-native-executorch/src/controllers/LLMController.ts index dc67727e3..e5a35c9ad 100644 --- a/packages/react-native-executorch/src/controllers/LLMController.ts +++ b/packages/react-native-executorch/src/controllers/LLMController.ts @@ -121,6 +121,11 @@ export class LLMController { await ResourceFetcher.fs.readAsString(tokenizerConfigPath!) ); + + if (this.nativeModule) { + this.nativeModule.unload(); + } + this.nativeModule = await global.loadLLM( modelPath, tokenizerPath, From 3fccdbc0a0787bf8c6d9d964453e41f0c3472b95 Mon Sep 17 00:00:00 2001 From: Bartosz Hanc Date: Wed, 11 Mar 2026 18:23:58 +0100 Subject: [PATCH 2/3] fix: remove unnecessary blank line in LLMController --- .../react-native-executorch/src/controllers/LLMController.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-native-executorch/src/controllers/LLMController.ts b/packages/react-native-executorch/src/controllers/LLMController.ts index e5a35c9ad..7ce921f6f 100644 --- a/packages/react-native-executorch/src/controllers/LLMController.ts +++ b/packages/react-native-executorch/src/controllers/LLMController.ts @@ -121,7 +121,6 @@ export class LLMController { await ResourceFetcher.fs.readAsString(tokenizerConfigPath!) ); - if (this.nativeModule) { this.nativeModule.unload(); } From b7b0d74782b7918be7960dd5adaab8a484a82f47 Mon Sep 17 00:00:00 2001 From: Bartosz Hanc Date: Wed, 11 Mar 2026 18:40:27 +0100 Subject: [PATCH 3/3] Update packages/react-native-executorch/common/rnexecutorch/models/llm/LLM.cpp Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com> --- .../common/rnexecutorch/models/llm/LLM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-executorch/common/rnexecutorch/models/llm/LLM.cpp b/packages/react-native-executorch/common/rnexecutorch/models/llm/LLM.cpp index e21182129..95ebed1d5 100644 --- a/packages/react-native-executorch/common/rnexecutorch/models/llm/LLM.cpp +++ b/packages/react-native-executorch/common/rnexecutorch/models/llm/LLM.cpp @@ -256,7 +256,7 @@ int32_t LLM::getMaxContextLength() const { } void LLM::unload() noexcept { - runner.reset(nullptr); + runner_.reset(nullptr); BaseModel::unload(); }