react-native-executorch 0.10.1 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/CMakeLists.txt +14 -0
- package/android/build.gradle.kts +26 -2
- package/cpp/extensions/llm/llm_runner.cpp +142 -12
- package/cpp/extensions/llm/llm_runner.h +7 -0
- package/legacy/cpp/rnexecutorch/RnExecutorchInstaller.cpp +23 -5
- package/legacy/cpp/rnexecutorch/host_objects/ModelHostObject.h +10 -3
- package/legacy/cpp/rnexecutorch/models/llm/LLM.cpp +11 -0
- package/legacy/cpp/rnexecutorch/threads/GlobalThreadPool.h +5 -1
- package/legacy/src/index.ts +5 -21
- package/lib/module/extensions/llm/llmRunner.js.map +1 -1
- package/lib/module/extensions/llm/tasks/llmChatSession.js +11 -6
- package/lib/module/extensions/llm/tasks/llmChatSession.js.map +1 -1
- package/lib/module/extensions/llm/utils/tokenizerConfig.js +3 -1
- package/lib/module/extensions/llm/utils/tokenizerConfig.js.map +1 -1
- package/lib/module/fetcher/telemetry.js +1 -1
- package/lib/module/legacy/src/index.js +5 -19
- package/lib/typescript/src/extensions/llm/llmRunner.d.ts +0 -2
- package/lib/typescript/src/extensions/llm/llmRunner.d.ts.map +1 -1
- package/lib/typescript/src/extensions/llm/tasks/llmChatSession.d.ts.map +1 -1
- package/lib/typescript/src/extensions/llm/utils/tokenizerConfig.d.ts +4 -0
- package/lib/typescript/src/extensions/llm/utils/tokenizerConfig.d.ts.map +1 -1
- package/package.json +2 -2
- package/react-native-executorch.podspec +32 -0
- package/scripts/download-libs.js +139 -11
- package/src/extensions/llm/llmRunner.ts +0 -2
- package/src/extensions/llm/tasks/llmChatSession.ts +12 -7
- package/src/extensions/llm/utils/tokenizerConfig.ts +11 -1
- package/src/fetcher/telemetry.ts +1 -1
package/android/CMakeLists.txt
CHANGED
|
@@ -55,6 +55,20 @@ file(GLOB_RECURSE LEGACY_CPP_SOURCES
|
|
|
55
55
|
${LEGACY_CPP_DIR}/runner/*.cpp
|
|
56
56
|
)
|
|
57
57
|
list(FILTER LEGACY_CPP_SOURCES EXCLUDE REGEX "/tests/")
|
|
58
|
+
# The legacy TTS models are the one part of the legacy tree that needs phonemis,
|
|
59
|
+
# so they follow the same toggle as the current phonemizer rather than being
|
|
60
|
+
# compiled unconditionally against a library that is not there.
|
|
61
|
+
if(NOT RNE_ENABLE_PHONEMIS)
|
|
62
|
+
list(FILTER LEGACY_CPP_SOURCES EXCLUDE REGEX "/models/text_to_speech/")
|
|
63
|
+
endif()
|
|
64
|
+
# Same story for opencv: the legacy vision models, the image/frame helpers they
|
|
65
|
+
# share and the multimodal LLM's vision encoder all compile against opencv2.
|
|
66
|
+
# Only the sources are dropped - the Types.h headers next to them are
|
|
67
|
+
# opencv-free and JsiConversions.h includes them unconditionally.
|
|
68
|
+
if(NOT RNE_ENABLE_OPENCV)
|
|
69
|
+
list(FILTER LEGACY_CPP_SOURCES EXCLUDE REGEX
|
|
70
|
+
"/data_processing/ImageProcessing\\.cpp$|/models/VisionModel\\.cpp$|/utils/Frame[^/]*\\.cpp$|/encoders/vision_encoder\\.cpp$|/models/(classification|embeddings/image|instance_segmentation|object_detection|ocr|pose_estimation|semantic_segmentation|style_transfer|text_to_image|vertical_ocr)/")
|
|
71
|
+
endif()
|
|
58
72
|
# ==============================================================================
|
|
59
73
|
|
|
60
74
|
set(PHONEMIS_SOURCES ${CPP_DIR}/extensions/speech/phonemizer.cpp)
|
package/android/build.gradle.kts
CHANGED
|
@@ -144,8 +144,13 @@ android {
|
|
|
144
144
|
getByName("main") {
|
|
145
145
|
// Prebuilt executorch + backend .so live under
|
|
146
146
|
// third-party/android/libs/executorch/<abi>/. Pointing jniLibs here
|
|
147
|
-
// makes Gradle package them
|
|
148
|
-
//
|
|
147
|
+
// makes Gradle package them into the APK alongside our own .so.
|
|
148
|
+
//
|
|
149
|
+
// Gradle packages every .so it finds under a jniLibs source dir, so
|
|
150
|
+
// this alone ships backends the app opted out of: -DRNE_ENABLE_* only
|
|
151
|
+
// stops CMake importing and linking them, which is enough for
|
|
152
|
+
// behaviour but has no bearing on packaging. `packaging.jniLibs
|
|
153
|
+
// .excludes` below drops the disabled ones back out.
|
|
149
154
|
jniLibs.srcDirs("../third-party/android/libs/executorch")
|
|
150
155
|
// Include generated codegen if using TurboModules
|
|
151
156
|
java.srcDirs("${project.buildDir}/generated/source/codegen/java")
|
|
@@ -160,6 +165,25 @@ android {
|
|
|
160
165
|
packaging {
|
|
161
166
|
// Prevents "Duplicate Library" errors with the React Native JSI engine
|
|
162
167
|
resources.excludes.add("**/libjsi.so")
|
|
168
|
+
|
|
169
|
+
// Ship only the backends the resolved config asks for. Without this an
|
|
170
|
+
// app declaring `backends: ["vulkan"]` still carries 2.67 MB of XNNPACK
|
|
171
|
+
// that nothing links, registers or loads, because jniLibs packages the
|
|
172
|
+
// directory rather than the link graph. This is the Android counterpart
|
|
173
|
+
// of the podspec deciding its -force_load entries from the same config.
|
|
174
|
+
//
|
|
175
|
+
// Keyed off the backend .so names rather than a staging dir so that a
|
|
176
|
+
// user who provisions third-party/ by hand gets the same treatment.
|
|
177
|
+
val backendLibs = mapOf(
|
|
178
|
+
"enableXnnpack" to "libxnnpack_executorch_backend.so",
|
|
179
|
+
"enableVulkan" to "libvulkan_executorch_backend.so"
|
|
180
|
+
)
|
|
181
|
+
for ((flag, soName) in backendLibs) {
|
|
182
|
+
if (rneConfig[flag] == false) {
|
|
183
|
+
logger.lifecycle("[RnExecutorch] $flag is off; excluding $soName from the APK")
|
|
184
|
+
jniLibs.excludes.add("**/$soName")
|
|
185
|
+
}
|
|
186
|
+
}
|
|
163
187
|
}
|
|
164
188
|
|
|
165
189
|
compileOptions {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
#include <algorithm>
|
|
12
12
|
#include <cstring>
|
|
13
13
|
#include <format>
|
|
14
|
+
#include <optional>
|
|
14
15
|
|
|
15
16
|
#include <executorch/extension/llm/runner/constants.h>
|
|
16
17
|
#include <executorch/extension/llm/runner/llm_runner_helper.h>
|
|
@@ -18,6 +19,8 @@
|
|
|
18
19
|
#include <executorch/extension/llm/runner/multimodal_runner.h>
|
|
19
20
|
#include <executorch/extension/llm/runner/stats.h>
|
|
20
21
|
#include <executorch/extension/llm/runner/text_llm_runner.h>
|
|
22
|
+
#include <executorch/extension/llm/runner/text_prefiller.h>
|
|
23
|
+
#include <executorch/extension/module/module.h>
|
|
21
24
|
#include <executorch/runtime/core/error.h>
|
|
22
25
|
|
|
23
26
|
#include "core/conversions.h"
|
|
@@ -56,8 +59,8 @@ namespace {
|
|
|
56
59
|
// COUPLING / MAINTENANCE WARNING:
|
|
57
60
|
// This creates a direct compile-time coupling with the internal implementation
|
|
58
61
|
// details of ExecuTorch's `TextLLMRunner` and `MultimodalRunner`. If upstream
|
|
59
|
-
// ExecuTorch renames or alters
|
|
60
|
-
//
|
|
62
|
+
// ExecuTorch renames or alters any member accessed below, this code will fail
|
|
63
|
+
// to compile and must be adjusted accordingly.
|
|
61
64
|
// ============================================================================
|
|
62
65
|
|
|
63
66
|
template <typename Tag, auto MemberPtr>
|
|
@@ -95,6 +98,96 @@ constexpr auto getPrivateMember(MMRunnerPrefillTag /*tag*/);
|
|
|
95
98
|
template struct PrivateMemberAccessor<MMRunnerMetadataTag, &MultimodalRunner::metadata_>;
|
|
96
99
|
constexpr auto getPrivateMember(MMRunnerMetadataTag /*tag*/);
|
|
97
100
|
|
|
101
|
+
// Members that decide how a prompt is split into prefill chunks.
|
|
102
|
+
using executorch::extension::llm::TextPrefiller;
|
|
103
|
+
|
|
104
|
+
struct TextRunnerModuleTag {};
|
|
105
|
+
struct TextRunnerPrefillerTag {};
|
|
106
|
+
struct PrefillerMaxSeqLenTag {};
|
|
107
|
+
struct MMRunnerModuleTag {};
|
|
108
|
+
struct MMRunnerTokenizerTag {};
|
|
109
|
+
|
|
110
|
+
template struct PrivateMemberAccessor<TextRunnerModuleTag, &TextLLMRunner::module_>;
|
|
111
|
+
constexpr auto getPrivateMember(TextRunnerModuleTag /*tag*/);
|
|
112
|
+
|
|
113
|
+
template struct PrivateMemberAccessor<TextRunnerPrefillerTag, &TextLLMRunner::text_prefiller_>;
|
|
114
|
+
constexpr auto getPrivateMember(TextRunnerPrefillerTag /*tag*/);
|
|
115
|
+
|
|
116
|
+
template struct PrivateMemberAccessor<PrefillerMaxSeqLenTag, &TextPrefiller::max_seq_len_>;
|
|
117
|
+
constexpr auto getPrivateMember(PrefillerMaxSeqLenTag /*tag*/);
|
|
118
|
+
|
|
119
|
+
template struct PrivateMemberAccessor<MMRunnerModuleTag, &MultimodalRunner::module_>;
|
|
120
|
+
constexpr auto getPrivateMember(MMRunnerModuleTag /*tag*/);
|
|
121
|
+
|
|
122
|
+
template struct PrivateMemberAccessor<MMRunnerTokenizerTag, &MultimodalRunner::tokenizer_>;
|
|
123
|
+
constexpr auto getPrivateMember(MMRunnerTokenizerTag /*tag*/);
|
|
124
|
+
|
|
125
|
+
// Upstream sizes prefill chunks from `get_max_seq_len`, which is the KV budget,
|
|
126
|
+
// not the widest token input the graph accepts (e.g. gemma4 MLX: 2048 vs 511).
|
|
127
|
+
// Prompts past the real bound then fail with `Error::NotSupported`. Returns the
|
|
128
|
+
// bound declared by the method's first input, or nullopt if it is not a
|
|
129
|
+
// rank>=2 integer tensor.
|
|
130
|
+
std::optional<int64_t> readPrefillBound(executorch::extension::Module *module, const std::string &methodName) {
|
|
131
|
+
if (module == nullptr) {
|
|
132
|
+
return std::nullopt;
|
|
133
|
+
}
|
|
134
|
+
auto meta = module->method_meta(methodName);
|
|
135
|
+
if (!meta.ok() || meta->num_inputs() == 0) {
|
|
136
|
+
return std::nullopt;
|
|
137
|
+
}
|
|
138
|
+
auto inputMeta = meta->input_tensor_meta(0);
|
|
139
|
+
if (!inputMeta.ok()) {
|
|
140
|
+
return std::nullopt;
|
|
141
|
+
}
|
|
142
|
+
const auto dtype = inputMeta->scalar_type();
|
|
143
|
+
if (dtype != executorch::aten::ScalarType::Long && dtype != executorch::aten::ScalarType::Int) {
|
|
144
|
+
return std::nullopt;
|
|
145
|
+
}
|
|
146
|
+
const auto sizes = inputMeta->sizes();
|
|
147
|
+
if (sizes.size() < 2) {
|
|
148
|
+
return std::nullopt;
|
|
149
|
+
}
|
|
150
|
+
const auto bound = static_cast<int64_t>(sizes[sizes.size() - 1]);
|
|
151
|
+
if (bound <= 0) {
|
|
152
|
+
return std::nullopt;
|
|
153
|
+
}
|
|
154
|
+
return bound;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
::tokenizers::Tokenizer *getRunnerTokenizer(executorch::extension::llm::IRunner *runner) {
|
|
158
|
+
auto *r = dynamic_cast<MultimodalRunner *>(runner);
|
|
159
|
+
if (r == nullptr) {
|
|
160
|
+
return nullptr;
|
|
161
|
+
}
|
|
162
|
+
return (r->*getPrivateMember(MMRunnerTokenizerTag{})).get();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// `MultimodalPrefiller` does not chunk, so split text into token inputs that fit
|
|
166
|
+
// the bound; `MultimodalRunner` prefills them in order.
|
|
167
|
+
void appendTextInput(std::vector<executorch::extension::llm::MultimodalInput> &inputs,
|
|
168
|
+
std::string text,
|
|
169
|
+
::tokenizers::Tokenizer *tokenizer,
|
|
170
|
+
int64_t prefillBound) {
|
|
171
|
+
if (tokenizer == nullptr || prefillBound <= 0) {
|
|
172
|
+
inputs.emplace_back(std::move(text));
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
auto encoded = tokenizer->encode(text, 0, 0);
|
|
177
|
+
if (!encoded.ok()) {
|
|
178
|
+
inputs.emplace_back(std::move(text));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const auto &tokens = encoded.get();
|
|
183
|
+
const auto chunk = static_cast<size_t>(prefillBound);
|
|
184
|
+
for (size_t offset = 0; offset < tokens.size(); offset += chunk) {
|
|
185
|
+
const auto end = std::min(offset + chunk, tokens.size());
|
|
186
|
+
inputs.emplace_back(std::vector<uint64_t>(tokens.begin() + static_cast<ptrdiff_t>(offset),
|
|
187
|
+
tokens.begin() + static_cast<ptrdiff_t>(end)));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
98
191
|
int64_t getRunnerPos(executorch::extension::llm::IRunner *runner, bool isMultimodal) {
|
|
99
192
|
if (runner == nullptr) {
|
|
100
193
|
return 0;
|
|
@@ -178,10 +271,14 @@ std::vector<executorch::extension::llm::MultimodalInput> parsePrompt(
|
|
|
178
271
|
jsi::Runtime &rt,
|
|
179
272
|
const std::string &ctx,
|
|
180
273
|
const jsi::Value &value,
|
|
181
|
-
const std::vector<std::string> &supportedModalities
|
|
274
|
+
const std::vector<std::string> &supportedModalities,
|
|
275
|
+
::tokenizers::Tokenizer *tokenizer,
|
|
276
|
+
int64_t prefillBound) {
|
|
182
277
|
|
|
183
278
|
if (value.isString()) {
|
|
184
|
-
|
|
279
|
+
std::vector<executorch::extension::llm::MultimodalInput> inputs;
|
|
280
|
+
appendTextInput(inputs, conversions::asType<std::string>(rt, ctx, value), tokenizer, prefillBound);
|
|
281
|
+
return inputs;
|
|
185
282
|
}
|
|
186
283
|
|
|
187
284
|
auto arr = conversions::asType<jsi::Array>(rt, ctx, value);
|
|
@@ -195,7 +292,7 @@ std::vector<executorch::extension::llm::MultimodalInput> parsePrompt(
|
|
|
195
292
|
std::string itemCtx = std::format("{}[{}]", ctx, i);
|
|
196
293
|
|
|
197
294
|
if (elem.isString()) {
|
|
198
|
-
inputs
|
|
295
|
+
appendTextInput(inputs, conversions::asType<std::string>(rt, itemCtx, elem), tokenizer, prefillBound);
|
|
199
296
|
continue;
|
|
200
297
|
}
|
|
201
298
|
auto mediaObj = conversions::asType<jsi::Object>(rt, itemCtx, elem);
|
|
@@ -254,10 +351,16 @@ LLMRunnerHostObject::LLMRunnerHostObject(const std::string &modelPath,
|
|
|
254
351
|
throw error::LoadFailed(std::format("LLMRunner: Failed to load runner tokenizer at path: {}", tokenizerPath));
|
|
255
352
|
}
|
|
256
353
|
|
|
354
|
+
// Plain mmap leaves the weights as clean, file-backed pages the kernel
|
|
355
|
+
// can evict, which is what the legacy binding has always passed.
|
|
356
|
+
constexpr auto kLoadMode = executorch::extension::Module::LoadMode::Mmap;
|
|
357
|
+
|
|
257
358
|
if (modalities_.empty()) {
|
|
258
|
-
runner_ = executorch::extension::llm::create_text_llm_runner(
|
|
359
|
+
runner_ = executorch::extension::llm::create_text_llm_runner(
|
|
360
|
+
modelPath, std::move(tokenizer), std::nullopt, -1.0f, "forward", kLoadMode);
|
|
259
361
|
} else {
|
|
260
|
-
runner_ = executorch::extension::llm::create_multimodal_runner(
|
|
362
|
+
runner_ = executorch::extension::llm::create_multimodal_runner(
|
|
363
|
+
modelPath, std::move(tokenizer), std::nullopt, kLoadMode);
|
|
261
364
|
}
|
|
262
365
|
|
|
263
366
|
if (!runner_) {
|
|
@@ -269,6 +372,33 @@ LLMRunnerHostObject::LLMRunnerHostObject(const std::string &modelPath,
|
|
|
269
372
|
std::string errorMsg = executorch::runtime::to_string(loadStatus);
|
|
270
373
|
throw error::LoadFailed(std::format("LLMRunner: Failed to load model: {}", errorMsg), loadStatus);
|
|
271
374
|
}
|
|
375
|
+
|
|
376
|
+
// Clamp prefill chunks to the graph's real bound (see `readPrefillBound`).
|
|
377
|
+
// Text models take tokens on `forward`, multimodal ones on `token_embedding`.
|
|
378
|
+
if (modalities_.empty()) {
|
|
379
|
+
auto *textRunner = dynamic_cast<TextLLMRunner *>(runner_.get());
|
|
380
|
+
if (textRunner != nullptr) {
|
|
381
|
+
const auto &module = textRunner->*getPrivateMember(TextRunnerModuleTag{});
|
|
382
|
+
const auto bound = readPrefillBound(module.get(), "forward");
|
|
383
|
+
auto &prefiller = textRunner->*getPrivateMember(TextRunnerPrefillerTag{});
|
|
384
|
+
if (bound.has_value() && prefiller) {
|
|
385
|
+
// Upstream allows max_seq_len < max_context_len and chunks itself.
|
|
386
|
+
auto &maxSeqLen = (*prefiller).*getPrivateMember(PrefillerMaxSeqLenTag{});
|
|
387
|
+
maxSeqLen = std::min(maxSeqLen, *bound);
|
|
388
|
+
prefillBound_ = maxSeqLen;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
} else {
|
|
392
|
+
auto *mmRunner = dynamic_cast<MultimodalRunner *>(runner_.get());
|
|
393
|
+
if (mmRunner != nullptr) {
|
|
394
|
+
const auto &module = mmRunner->*getPrivateMember(MMRunnerModuleTag{});
|
|
395
|
+
const auto bound =
|
|
396
|
+
readPrefillBound(module.get(), executorch::extension::llm::kTokenEmbeddingMethod);
|
|
397
|
+
if (bound.has_value()) {
|
|
398
|
+
prefillBound_ = *bound;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
272
402
|
}
|
|
273
403
|
|
|
274
404
|
std::unique_lock<std::mutex> LLMRunnerHostObject::tryLockUnique(std::string_view ctx) {
|
|
@@ -305,11 +435,9 @@ jsi::Value LLMRunnerHostObject::get(jsi::Runtime &rt, const jsi::PropNameID &nam
|
|
|
305
435
|
}
|
|
306
436
|
|
|
307
437
|
executorch::extension::llm::GenerationConfig config;
|
|
438
|
+
config.echo = false;
|
|
308
439
|
if (count > 1 && !args[1].isUndefined() && !args[1].isNull()) {
|
|
309
440
|
auto configObj = conversions::asType<jsi::Object>(rt, "LLMRunner.generate: config", args[1]);
|
|
310
|
-
if (auto echoOpt = conversions::getOptionalProperty<bool>(rt, "LLMRunner.generate: config", configObj, "echo")) {
|
|
311
|
-
config.echo = *echoOpt;
|
|
312
|
-
}
|
|
313
441
|
if (auto ignoreEosOpt = conversions::getOptionalProperty<bool>(rt, "LLMRunner.generate: config", configObj, "ignoreEos")) {
|
|
314
442
|
config.ignore_eos = *ignoreEosOpt;
|
|
315
443
|
}
|
|
@@ -348,7 +476,8 @@ jsi::Value LLMRunnerHostObject::get(jsi::Runtime &rt, const jsi::PropNameID &nam
|
|
|
348
476
|
auto prompt = conversions::asType<std::string>(rt, "LLMRunner.generate: prompt", args[0]);
|
|
349
477
|
genStatus = self->runner_->generate(prompt, config, tokenCallback, statsCallback);
|
|
350
478
|
} else {
|
|
351
|
-
auto inputs = parsePrompt(rt, "LLMRunner.generate", args[0], self->modalities_
|
|
479
|
+
auto inputs = parsePrompt(rt, "LLMRunner.generate", args[0], self->modalities_,
|
|
480
|
+
getRunnerTokenizer(self->runner_.get()), self->prefillBound_);
|
|
352
481
|
auto *multimodalRunner = dynamic_cast<executorch::extension::llm::MultimodalRunner *>(self->runner_.get());
|
|
353
482
|
if (multimodalRunner == nullptr) {
|
|
354
483
|
throw error::InvalidArgument("LLMRunner.generate: Runner instance is not a multimodal model");
|
|
@@ -375,7 +504,8 @@ jsi::Value LLMRunnerHostObject::get(jsi::Runtime &rt, const jsi::PropNameID &nam
|
|
|
375
504
|
|
|
376
505
|
auto lock = self->tryLockUnique("LLMRunner.prefill");
|
|
377
506
|
|
|
378
|
-
auto inputs = parsePrompt(rt, "LLMRunner.prefill", args[0], self->modalities_
|
|
507
|
+
auto inputs = parsePrompt(rt, "LLMRunner.prefill", args[0], self->modalities_,
|
|
508
|
+
getRunnerTokenizer(self->runner_.get()), self->prefillBound_);
|
|
379
509
|
auto result = self->runner_->prefill(inputs);
|
|
380
510
|
|
|
381
511
|
if (!result.ok()) {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
9
9
|
#endif
|
|
10
10
|
|
|
11
|
+
#include <cstdint>
|
|
11
12
|
#include <memory>
|
|
12
13
|
#include <mutex>
|
|
13
14
|
#include <string>
|
|
@@ -77,6 +78,12 @@ private:
|
|
|
77
78
|
std::string tokenizerPath_;
|
|
78
79
|
/** List of supported non-text input modalities. */
|
|
79
80
|
std::vector<std::string> modalities_;
|
|
81
|
+
/**
|
|
82
|
+
* Longest token sequence the loaded graph accepts in one prefill step, read
|
|
83
|
+
* off the model's own method metadata. 0 when the model does not declare
|
|
84
|
+
* one, in which case prompts are passed through unsplit.
|
|
85
|
+
*/
|
|
86
|
+
int64_t prefillBound_ = 0;
|
|
80
87
|
};
|
|
81
88
|
|
|
82
89
|
void install_createLLMRunner(facebook::jsi::Runtime &rt, facebook::jsi::Object &module);
|
|
@@ -2,21 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
#include <rnexecutorch/TokenizerModule.h>
|
|
4
4
|
#include <rnexecutorch/host_objects/JsiConversions.h>
|
|
5
|
+
#include <rnexecutorch/models/embeddings/text/TextEmbeddings.h>
|
|
6
|
+
#include <rnexecutorch/models/llm/LLM.h>
|
|
7
|
+
#ifdef RNE_ENABLE_OPENCV
|
|
5
8
|
#include <rnexecutorch/models/classification/Classification.h>
|
|
6
9
|
#include <rnexecutorch/models/embeddings/image/ImageEmbeddings.h>
|
|
7
|
-
#include <rnexecutorch/models/embeddings/text/TextEmbeddings.h>
|
|
8
10
|
#include <rnexecutorch/models/instance_segmentation/BaseInstanceSegmentation.h>
|
|
9
|
-
#include <rnexecutorch/models/llm/LLM.h>
|
|
10
11
|
#include <rnexecutorch/models/object_detection/ObjectDetection.h>
|
|
11
12
|
#include <rnexecutorch/models/ocr/OCR.h>
|
|
12
13
|
#include <rnexecutorch/models/pose_estimation/PoseEstimation.h>
|
|
13
|
-
#include <rnexecutorch/models/privacy_filter/PrivacyFilter.h>
|
|
14
14
|
#include <rnexecutorch/models/semantic_segmentation/BaseSemanticSegmentation.h>
|
|
15
|
-
#include <rnexecutorch/models/speech_to_text/SpeechToText.h>
|
|
16
15
|
#include <rnexecutorch/models/style_transfer/StyleTransfer.h>
|
|
17
16
|
#include <rnexecutorch/models/text_to_image/TextToImage.h>
|
|
18
|
-
#include <rnexecutorch/models/text_to_speech/TextToSpeech.h>
|
|
19
17
|
#include <rnexecutorch/models/vertical_ocr/VerticalOCR.h>
|
|
18
|
+
#endif
|
|
19
|
+
#include <rnexecutorch/models/privacy_filter/PrivacyFilter.h>
|
|
20
|
+
#include <rnexecutorch/models/speech_to_text/SpeechToText.h>
|
|
21
|
+
#ifdef RNE_ENABLE_PHONEMIS
|
|
22
|
+
#include <rnexecutorch/models/text_to_speech/TextToSpeech.h>
|
|
23
|
+
#endif
|
|
20
24
|
#include <rnexecutorch/models/voice_activity_detection/VoiceActivityDetection.h>
|
|
21
25
|
#include <rnexecutorch/threads/GlobalThreadPool.h>
|
|
22
26
|
#include <rnexecutorch/threads/utils/ThreadUtils.h>
|
|
@@ -42,6 +46,10 @@ void RnExecutorchInstaller::injectJSIBindings(
|
|
|
42
46
|
jsiRuntime->global().setProperty(*jsiRuntime, "__rne_isEmulator",
|
|
43
47
|
jsi::Value(isEmulator));
|
|
44
48
|
|
|
49
|
+
#ifdef RNE_ENABLE_OPENCV
|
|
50
|
+
// Registered only when opencv is compiled in. An app that opted out of it
|
|
51
|
+
// gets no `load*` global for these tasks, the same way the current API
|
|
52
|
+
// omits the whole `cv` namespace.
|
|
45
53
|
jsiRuntime->global().setProperty(
|
|
46
54
|
*jsiRuntime, "loadStyleTransfer",
|
|
47
55
|
RnExecutorchInstaller::loadModel<models::style_transfer::StyleTransfer>(
|
|
@@ -79,6 +87,7 @@ void RnExecutorchInstaller::injectJSIBindings(
|
|
|
79
87
|
*jsiRuntime, "loadPoseEstimation",
|
|
80
88
|
RnExecutorchInstaller::loadModel<models::pose_estimation::PoseEstimation>(
|
|
81
89
|
jsiRuntime, jsCallInvoker, "loadPoseEstimation"));
|
|
90
|
+
#endif
|
|
82
91
|
|
|
83
92
|
jsiRuntime->global().setProperty(
|
|
84
93
|
*jsiRuntime, "loadExecutorchModule",
|
|
@@ -90,10 +99,12 @@ void RnExecutorchInstaller::injectJSIBindings(
|
|
|
90
99
|
RnExecutorchInstaller::loadModel<TokenizerModule>(
|
|
91
100
|
jsiRuntime, jsCallInvoker, "loadTokenizerModule"));
|
|
92
101
|
|
|
102
|
+
#ifdef RNE_ENABLE_OPENCV
|
|
93
103
|
jsiRuntime->global().setProperty(
|
|
94
104
|
*jsiRuntime, "loadImageEmbeddings",
|
|
95
105
|
RnExecutorchInstaller::loadModel<models::embeddings::ImageEmbeddings>(
|
|
96
106
|
jsiRuntime, jsCallInvoker, "loadImageEmbeddings"));
|
|
107
|
+
#endif
|
|
97
108
|
|
|
98
109
|
jsiRuntime->global().setProperty(
|
|
99
110
|
*jsiRuntime, "loadTextEmbeddings",
|
|
@@ -110,6 +121,7 @@ void RnExecutorchInstaller::injectJSIBindings(
|
|
|
110
121
|
RnExecutorchInstaller::loadModel<models::privacy_filter::PrivacyFilter>(
|
|
111
122
|
jsiRuntime, jsCallInvoker, "loadPrivacyFilter"));
|
|
112
123
|
|
|
124
|
+
#ifdef RNE_ENABLE_OPENCV
|
|
113
125
|
jsiRuntime->global().setProperty(
|
|
114
126
|
*jsiRuntime, "loadOCR",
|
|
115
127
|
RnExecutorchInstaller::loadModel<models::ocr::OCR>(
|
|
@@ -119,16 +131,22 @@ void RnExecutorchInstaller::injectJSIBindings(
|
|
|
119
131
|
*jsiRuntime, "loadVerticalOCR",
|
|
120
132
|
RnExecutorchInstaller::loadModel<models::ocr::VerticalOCR>(
|
|
121
133
|
jsiRuntime, jsCallInvoker, "loadVerticalOCR"));
|
|
134
|
+
#endif
|
|
122
135
|
|
|
123
136
|
jsiRuntime->global().setProperty(
|
|
124
137
|
*jsiRuntime, "loadSpeechToText",
|
|
125
138
|
RnExecutorchInstaller::loadModel<models::speech_to_text::SpeechToText>(
|
|
126
139
|
jsiRuntime, jsCallInvoker, "loadSpeechToText"));
|
|
127
140
|
|
|
141
|
+
#ifdef RNE_ENABLE_PHONEMIS
|
|
142
|
+
// Only registered when phonemis is compiled in; an app that opted out of
|
|
143
|
+
// text-to-speech gets no `loadTextToSpeechKokoro` global, the same way the
|
|
144
|
+
// current API omits `speech.createPhonemizer`.
|
|
128
145
|
jsiRuntime->global().setProperty(
|
|
129
146
|
*jsiRuntime, "loadTextToSpeechKokoro",
|
|
130
147
|
RnExecutorchInstaller::loadModel<models::text_to_speech::kokoro::Kokoro>(
|
|
131
148
|
jsiRuntime, jsCallInvoker, "loadTextToSpeechKokoro"));
|
|
149
|
+
#endif
|
|
132
150
|
|
|
133
151
|
jsiRuntime->global().setProperty(
|
|
134
152
|
*jsiRuntime, "loadVAD",
|
|
@@ -17,13 +17,16 @@
|
|
|
17
17
|
#include <rnexecutorch/metaprogramming/FunctionHelpers.h>
|
|
18
18
|
#include <rnexecutorch/metaprogramming/TypeConcepts.h>
|
|
19
19
|
#include <rnexecutorch/models/BaseModel.h>
|
|
20
|
-
#include <rnexecutorch/models/VisionModel.h>
|
|
21
20
|
#include <rnexecutorch/models/llm/LLM.h>
|
|
21
|
+
#ifdef RNE_ENABLE_OPENCV
|
|
22
22
|
#include <rnexecutorch/models/ocr/OCR.h>
|
|
23
|
-
#include <rnexecutorch/models/speech_to_text/SpeechToText.h>
|
|
24
23
|
#include <rnexecutorch/models/text_to_image/TextToImage.h>
|
|
25
|
-
#include <rnexecutorch/models/text_to_speech/TextToSpeech.h>
|
|
26
24
|
#include <rnexecutorch/models/vertical_ocr/VerticalOCR.h>
|
|
25
|
+
#endif
|
|
26
|
+
#include <rnexecutorch/models/speech_to_text/SpeechToText.h>
|
|
27
|
+
#ifdef RNE_ENABLE_PHONEMIS
|
|
28
|
+
#include <rnexecutorch/models/text_to_speech/TextToSpeech.h>
|
|
29
|
+
#endif
|
|
27
30
|
#include <rnexecutorch/models/voice_activity_detection/VoiceActivityDetection.h>
|
|
28
31
|
#include <rnexecutorch/threads/GlobalThreadPool.h>
|
|
29
32
|
|
|
@@ -202,6 +205,7 @@ public:
|
|
|
202
205
|
"getVisualTokenCount"));
|
|
203
206
|
}
|
|
204
207
|
|
|
208
|
+
#ifdef RNE_ENABLE_OPENCV
|
|
205
209
|
if constexpr (meta::SameAs<Model, models::text_to_image::TextToImage>) {
|
|
206
210
|
addFunctions(
|
|
207
211
|
JSI_EXPORT_FUNCTION(ModelHostObject<Model>, unload, "unload"));
|
|
@@ -219,7 +223,9 @@ public:
|
|
|
219
223
|
addFunctions(
|
|
220
224
|
JSI_EXPORT_FUNCTION(ModelHostObject<Model>, unload, "unload"));
|
|
221
225
|
}
|
|
226
|
+
#endif
|
|
222
227
|
|
|
228
|
+
#ifdef RNE_ENABLE_PHONEMIS
|
|
223
229
|
if constexpr (meta::SameAs<Model, models::text_to_speech::kokoro::Kokoro>) {
|
|
224
230
|
addFunctions(
|
|
225
231
|
JSI_EXPORT_FUNCTION(ModelHostObject<Model>, unload, "unload"));
|
|
@@ -236,6 +242,7 @@ public:
|
|
|
236
242
|
ModelHostObject<Model>, synchronousHostFunction<&Model::streamFlush>,
|
|
237
243
|
"streamFlush"));
|
|
238
244
|
}
|
|
245
|
+
#endif
|
|
239
246
|
|
|
240
247
|
if constexpr (meta::HasGenerateFromString<Model>) {
|
|
241
248
|
addFunctions(
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
#include <rnexecutorch/Error.h>
|
|
8
8
|
#include <rnexecutorch/threads/GlobalThreadPool.h>
|
|
9
9
|
#include <runner/encoders/audio_encoder.h>
|
|
10
|
+
#ifdef RNE_ENABLE_OPENCV
|
|
10
11
|
#include <runner/encoders/vision_encoder.h>
|
|
12
|
+
#endif
|
|
11
13
|
#include <runner/multimodal_runner.h>
|
|
12
14
|
#include <runner/text_runner.h>
|
|
13
15
|
|
|
@@ -29,8 +31,17 @@ LLM::LLM(const std::string &modelSource, const std::string &tokenizerSource,
|
|
|
29
31
|
std::map<llm::MultimodalType, std::unique_ptr<llm::IEncoder>> encoders;
|
|
30
32
|
for (const auto &cap : capabilities) {
|
|
31
33
|
if (cap == "vision") {
|
|
34
|
+
#ifdef RNE_ENABLE_OPENCV
|
|
32
35
|
encoders[llm::MultimodalType::Image] =
|
|
33
36
|
std::make_unique<llm::VisionEncoder>(*module_);
|
|
37
|
+
#else
|
|
38
|
+
// The vision encoder decodes and resizes the image with opencv,
|
|
39
|
+
// so it is only there when opencv is.
|
|
40
|
+
throw RnExecutorchError(
|
|
41
|
+
RnExecutorchErrorCode::InvalidUserInput,
|
|
42
|
+
"The 'vision' capability requires the opencv native library, "
|
|
43
|
+
"which this app opted out of in package.json");
|
|
44
|
+
#endif
|
|
34
45
|
} else if (cap == "audio") {
|
|
35
46
|
encoders[llm::MultimodalType::Audio] =
|
|
36
47
|
std::make_unique<llm::AudioEncoder>(*module_);
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
#include <executorch/extension/threadpool/cpuinfo_utils.h>
|
|
5
5
|
#include <memory>
|
|
6
6
|
#include <mutex>
|
|
7
|
-
#include <opencv2/opencv.hpp>
|
|
8
7
|
#include <optional>
|
|
9
8
|
#include <rnexecutorch/Log.h>
|
|
10
9
|
#include <rnexecutorch/threads/HighPerformanceThreadPool.h>
|
|
10
|
+
#ifdef RNE_ENABLE_OPENCV
|
|
11
|
+
#include <opencv2/opencv.hpp>
|
|
12
|
+
#endif
|
|
11
13
|
|
|
12
14
|
namespace rnexecutorch::threads {
|
|
13
15
|
|
|
@@ -39,9 +41,11 @@ public:
|
|
|
39
41
|
numThreads, "threads");
|
|
40
42
|
instance = std::make_unique<HighPerformanceThreadPool>(numThreads.value(),
|
|
41
43
|
config);
|
|
44
|
+
#ifdef RNE_ENABLE_OPENCV
|
|
42
45
|
// Disable OpenCV's internal threading to prevent it from overriding our
|
|
43
46
|
// thread pool configuration, which would cause degraded performance
|
|
44
47
|
cv::setNumThreads(0);
|
|
48
|
+
#endif
|
|
45
49
|
});
|
|
46
50
|
}
|
|
47
51
|
|
package/legacy/src/index.ts
CHANGED
|
@@ -135,27 +135,11 @@ declare global {
|
|
|
135
135
|
}
|
|
136
136
|
// eslint-disable no-var
|
|
137
137
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
global.loadExecutorchModule == null ||
|
|
144
|
-
global.loadClassification == null ||
|
|
145
|
-
global.loadObjectDetection == null ||
|
|
146
|
-
global.loadPoseEstimation == null ||
|
|
147
|
-
global.loadTokenizerModule == null ||
|
|
148
|
-
global.loadTextEmbeddings == null ||
|
|
149
|
-
global.loadImageEmbeddings == null ||
|
|
150
|
-
global.loadVAD == null ||
|
|
151
|
-
global.loadLLM == null ||
|
|
152
|
-
global.loadPrivacyFilter == null ||
|
|
153
|
-
global.loadSpeechToText == null ||
|
|
154
|
-
global.loadTextToSpeechKokoro == null ||
|
|
155
|
-
global.loadOCR == null ||
|
|
156
|
-
global.loadVerticalOCR == null ||
|
|
157
|
-
global.__rne_isEmulator == null
|
|
158
|
-
) {
|
|
138
|
+
// Only the globals that are registered unconditionally. The per-task ones are
|
|
139
|
+
// absent by design when an app opts out of opencv or phonemis, so including
|
|
140
|
+
// them here would pin the condition to true and re-run install() on every
|
|
141
|
+
// module evaluation.
|
|
142
|
+
if (global.loadExecutorchModule == null || global.__rne_isEmulator == null) {
|
|
159
143
|
if (!ETInstallerNativeModule) {
|
|
160
144
|
throw new Error(
|
|
161
145
|
`Failed to install react-native-executorch: The native module could not be found.`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["rnexecutorchJsi","createLLMRunner","modelPath","tokenizerPath","modalities","llm"],"sourceRoot":"../../../../src","sources":["extensions/llm/llmRunner.ts"],"mappings":";;AAAA;AACA;AACA;;AAGA,SAASA,eAAe,QAAQ,wBAAqB;;AAIrD;AACA;AACA;AACA;AACA;;
|
|
1
|
+
{"version":3,"names":["rnexecutorchJsi","createLLMRunner","modelPath","tokenizerPath","modalities","llm"],"sourceRoot":"../../../../src","sources":["extensions/llm/llmRunner.ts"],"mappings":";;AAAA;AACA;AACA;;AAGA,SAASA,eAAe,QAAQ,wBAAqB;;AAIrD;AACA;AACA;AACA;AACA;;AAUA;AACA;AACA;AACA;AACA;;AAoBA;AACA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;;AAyDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAC7BC,SAAiB,EACjBC,aAAqB,EACrBC,UAAgC,EACrB;EACX,SAAS;;EACT,OAAOJ,eAAe,CAACK,GAAG,CAACJ,eAAe,CAACC,SAAS,EAAEC,aAAa,EAAEC,UAAU,IAAI,EAAE,CAAC;AACxF","ignoreList":[]}
|
|
@@ -43,13 +43,13 @@ function generateChatTurnWorklet(runner, prompt, options) {
|
|
|
43
43
|
|
|
44
44
|
const {
|
|
45
45
|
genConfig,
|
|
46
|
-
|
|
46
|
+
stopTokens,
|
|
47
47
|
stopRegex,
|
|
48
48
|
onToken
|
|
49
49
|
} = options;
|
|
50
50
|
let response = '';
|
|
51
51
|
const callback = token => {
|
|
52
|
-
if (token
|
|
52
|
+
if (stopTokens.includes(token)) return;
|
|
53
53
|
response += token;
|
|
54
54
|
if (onToken) scheduleOnRN(onToken, token);
|
|
55
55
|
if (stopRegex?.test(response)) runner.stop();
|
|
@@ -99,7 +99,7 @@ export async function createLLMChatSession(config, options = {}, runtime) {
|
|
|
99
99
|
const tokenizerConfig = parseTokenizerConfig(JSON.parse(tokenizerConfigStr));
|
|
100
100
|
const {
|
|
101
101
|
chatTemplate,
|
|
102
|
-
|
|
102
|
+
stopTokens
|
|
103
103
|
} = tokenizerConfig;
|
|
104
104
|
|
|
105
105
|
// Prepare chat preprocessor
|
|
@@ -139,7 +139,7 @@ export async function createLLMChatSession(config, options = {}, runtime) {
|
|
|
139
139
|
};
|
|
140
140
|
const generationOpts = {
|
|
141
141
|
genConfig: turnGenConfig,
|
|
142
|
-
|
|
142
|
+
stopTokens,
|
|
143
143
|
stopRegex,
|
|
144
144
|
onToken
|
|
145
145
|
};
|
|
@@ -246,10 +246,15 @@ export async function createLLMChatSession(config, options = {}, runtime) {
|
|
|
246
246
|
finishReason
|
|
247
247
|
};
|
|
248
248
|
} catch (err) {
|
|
249
|
-
// Roll back history, KV cache, and active tensors to pre-turn state on
|
|
249
|
+
// Roll back history, KV cache, and active tensors to pre-turn state on
|
|
250
|
+
// failure. The rewind must never replace the error it is unwinding.
|
|
251
|
+
//
|
|
252
|
+
// Under `resetOnTurn` the pre-turn position IS zero: `initialPos` is
|
|
253
|
+
// read before the turn begins and the turn then zeroed the cache, so
|
|
254
|
+
// rewinding to it is out of range by construction.
|
|
250
255
|
history.length = turnStartIdx;
|
|
251
256
|
committed = initialCommitted;
|
|
252
|
-
runner.reset(initialPos);
|
|
257
|
+
runner.reset(resetOnTurn ? 0 : initialPos);
|
|
253
258
|
chatPreprocessor.clear();
|
|
254
259
|
throw err;
|
|
255
260
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["scheduleOnRN","RNBlobUtil","wrapAsync","createResourceScope","createLLMRunner","parseTokenizerConfig","createChatPreprocessor","generateChatTurnWorklet","runner","prompt","options","genConfig","
|
|
1
|
+
{"version":3,"names":["scheduleOnRN","RNBlobUtil","wrapAsync","createResourceScope","createLLMRunner","parseTokenizerConfig","createChatPreprocessor","generateChatTurnWorklet","runner","prompt","options","genConfig","stopTokens","stopRegex","onToken","response","callback","token","includes","test","stop","stats","generate","DEFAULT_MAX_TURNS","createLLMChatSession","config","runtime","scope","dispose","generationConfig","defaultGenerationConfig","initialMessages","toolOpts","resetOnTurn","modelPath","tokenizerPath","tokenizerConfigPath","modalities","preprocessorConfig","tools","parseToolCalls","maxToolTurns","tokenizerConfigStr","fs","readFile","tokenizerConfig","JSON","parse","chatTemplate","chatPreprocessorConfig","chatPreprocessor","track","prefill","history","committed","length","push","process","addGenPrompt","clear","generateChatTurn","sendMessage","message","turnGenConfig","generationOpts","initialCommitted","initialPos","getKVCacheState","pos","turnStartIdx","generationStatsList","role","content","reset","prefillStartMs","Date","now","toCommit","userPrompt","posAtEndOfUser","finishReason","currentTurn","uncommitted","prefillDurationMs","parsedTools","toolCalls","textContent","toolCall","tool","find","t","function","name","toolContent","execute","arguments","err","String","toolCallId","id","messages","slice","getHistory","error"],"sourceRoot":"../../../../../src","sources":["extensions/llm/tasks/llmChatSession.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -43,9 +43,11 @@ export function parseTokenizerConfig(config) {
|
|
|
43
43
|
if (!eosToken) {
|
|
44
44
|
throw RnExecuTorchError('LOAD_FAILED', 'tokenizer_config.json does not define required `eos_token` string');
|
|
45
45
|
}
|
|
46
|
+
const stopTokens = [eosToken, resolveToken(config.eot_token), resolveToken(config.pad_token)].filter((token, index, all) => !!token && all.indexOf(token) === index);
|
|
46
47
|
return {
|
|
47
48
|
chatTemplate,
|
|
48
|
-
eosToken
|
|
49
|
+
eosToken,
|
|
50
|
+
stopTokens
|
|
49
51
|
};
|
|
50
52
|
}
|
|
51
53
|
//# sourceMappingURL=tokenizerConfig.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["RnExecuTorchError","resolveToken","token","content","undefined","parseTokenizerConfig","config","chatTemplate","chat_template","Array","isArray","entry","find","t","name","template","eosToken","eos_token"],"sourceRoot":"../../../../../src","sources":["extensions/llm/utils/tokenizerConfig.ts"],"mappings":";;AAAA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB,QAAQ,wBAAqB;;AAEvD;AACA;AACA;AACA;;
|
|
1
|
+
{"version":3,"names":["RnExecuTorchError","resolveToken","token","content","undefined","parseTokenizerConfig","config","chatTemplate","chat_template","Array","isArray","entry","find","t","name","template","eosToken","eos_token","stopTokens","eot_token","pad_token","filter","index","all","indexOf"],"sourceRoot":"../../../../../src","sources":["extensions/llm/utils/tokenizerConfig.ts"],"mappings":";;AAAA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB,QAAQ,wBAAqB;;AAEvD;AACA;AACA;AACA;;AAYA,SAASC,YAAYA,CAACC,KAAc,EAAsB;EACxD,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE,OAAOA,KAAK;EAC3C,IAAIA,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,OAAQA,KAAK,CAASC,OAAO,KAAK,QAAQ,EAAE;IACpF,OAAQD,KAAK,CAASC,OAAO;EAC/B;EACA,OAAOC,SAAS;AAClB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,oBAAoBA,CAACC,MAAW,EAAuB;EACrE,IAAIC,YAAY,GAAGD,MAAM,CAACE,aAAa;;EAEvC;EACA,IAAIC,KAAK,CAACC,OAAO,CAACH,YAAY,CAAC,EAAE;IAC/B,MAAMI,KAAK,GAAGJ,YAAY,CAACK,IAAI,CAAEC,CAAC,IAAKA,CAAC,EAAEC,IAAI,KAAK,SAAS,CAAC,IAAIP,YAAY,CAAC,CAAC,CAAC;IAChFA,YAAY,GAAGI,KAAK,EAAEI,QAAQ;EAChC;EAEA,IAAI,OAAOR,YAAY,KAAK,QAAQ,EAAE;IACpC,MAAMP,iBAAiB,CACrB,aAAa,EACb,iEACF,CAAC;EACH;EAEA,MAAMgB,QAAQ,GAAGf,YAAY,CAACK,MAAM,CAACW,SAAS,CAAC;EAE/C,IAAI,CAACD,QAAQ,EAAE;IACb,MAAMhB,iBAAiB,CACrB,aAAa,EACb,mEACF,CAAC;EACH;EAEA,MAAMkB,UAAU,GAAG,CACjBF,QAAQ,EACRf,YAAY,CAACK,MAAM,CAACa,SAAS,CAAC,EAC9BlB,YAAY,CAACK,MAAM,CAACc,SAAS,CAAC,CAC/B,CAACC,MAAM,CAAC,CAACnB,KAAK,EAAEoB,KAAK,EAAEC,GAAG,KAAsB,CAAC,CAACrB,KAAK,IAAIqB,GAAG,CAACC,OAAO,CAACtB,KAAK,CAAC,KAAKoB,KAAK,CAAC;EAEzF,OAAO;IAAEf,YAAY;IAAES,QAAQ;IAAEE;EAAW,CAAC;AAC/C","ignoreList":[]}
|
|
@@ -12,7 +12,7 @@ const DOWNLOAD_EVENT_ENDPOINT = 'https://ai.swmansion.com/telemetry/downloads/ap
|
|
|
12
12
|
// self-referencing import would need package `exports` support in the consuming
|
|
13
13
|
// bundler to load at all. A wrong value here is analytics noise; a failed
|
|
14
14
|
// import would break the bundle.
|
|
15
|
-
const LIB_VERSION = '0.10.
|
|
15
|
+
const LIB_VERSION = '0.10.3';
|
|
16
16
|
|
|
17
17
|
// Anonymous analytics are on by default; apps opt out via setTelemetryEnabled.
|
|
18
18
|
let telemetryEnabled = true;
|
|
@@ -33,25 +33,11 @@ export function cleanupExecutorch() {
|
|
|
33
33
|
ResourceFetcher.resetAdapter();
|
|
34
34
|
}
|
|
35
35
|
// eslint-disable no-var
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
global.loadClassification == null ||
|
|
42
|
-
global.loadObjectDetection == null ||
|
|
43
|
-
global.loadPoseEstimation == null ||
|
|
44
|
-
global.loadTokenizerModule == null ||
|
|
45
|
-
global.loadTextEmbeddings == null ||
|
|
46
|
-
global.loadImageEmbeddings == null ||
|
|
47
|
-
global.loadVAD == null ||
|
|
48
|
-
global.loadLLM == null ||
|
|
49
|
-
global.loadPrivacyFilter == null ||
|
|
50
|
-
global.loadSpeechToText == null ||
|
|
51
|
-
global.loadTextToSpeechKokoro == null ||
|
|
52
|
-
global.loadOCR == null ||
|
|
53
|
-
global.loadVerticalOCR == null ||
|
|
54
|
-
global.__rne_isEmulator == null) {
|
|
36
|
+
// Only the globals that are registered unconditionally. The per-task ones are
|
|
37
|
+
// absent by design when an app opts out of opencv or phonemis, so including
|
|
38
|
+
// them here would pin the condition to true and re-run install() on every
|
|
39
|
+
// module evaluation.
|
|
40
|
+
if (global.loadExecutorchModule == null || global.__rne_isEmulator == null) {
|
|
55
41
|
if (!ETInstallerNativeModule) {
|
|
56
42
|
throw new Error(`Failed to install react-native-executorch: The native module could not be found.`);
|
|
57
43
|
}
|
|
@@ -8,8 +8,6 @@ import type { Tensor } from '../../core/tensor';
|
|
|
8
8
|
* @category LLM / Types
|
|
9
9
|
*/
|
|
10
10
|
export type LLMGenerationConfig = {
|
|
11
|
-
/** Whether to echo the prompt in the generated output. */
|
|
12
|
-
readonly echo?: boolean;
|
|
13
11
|
/** Whether to ignore EOS tokens during generation. */
|
|
14
12
|
readonly ignoreEos?: boolean;
|
|
15
13
|
/** Maximum number of new tokens to generate. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llmRunner.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/llm/llmRunner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAKhD;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,
|
|
1
|
+
{"version":3,"file":"llmRunner.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/llm/llmRunner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llmChatSession.d.ts","sourceRoot":"","sources":["../../../../../../src/extensions/llm/tasks/llmChatSession.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAK1E,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,QAAQ,EAEd,MAAM,cAAc,CAAC;AAEtB,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,0BAA0B,EAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC1C,wCAAwC;IACxC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,0BAA0B,CAAC;CAC1D,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IAC1C,mEAAmE;IACnE,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC;IACpC,0FAA0F;IAC1F,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,gDAAgD;IAChD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;IAChD,uEAAuE;IACvE,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAClD,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,CAAC;CAChD,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;OAEG;IACH,OAAO,IAAI,IAAI,CAAC;IAEhB;;OAEG;IACH,UAAU,IAAI,SAAS,WAAW,EAAE,CAAC;IAErC;;OAEG;IACH,eAAe,IAAI,eAAe,CAAC;IAEnC;;;;;;;;OAQG;IACH,WAAW,CACT,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,SAAS,CAAC,EAAE,mBAAmB,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/B,CAAC;AAgCF;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,QAAQ,EAChB,OAAO,GAAE,qBAA0B,EACnC,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"llmChatSession.d.ts","sourceRoot":"","sources":["../../../../../../src/extensions/llm/tasks/llmChatSession.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAK1E,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,QAAQ,EAEd,MAAM,cAAc,CAAC;AAEtB,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,0BAA0B,EAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC1C,wCAAwC;IACxC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,0BAA0B,CAAC;CAC1D,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IAC1C,mEAAmE;IACnE,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC;IACpC,0FAA0F;IAC1F,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,gDAAgD;IAChD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;IAChD,uEAAuE;IACvE,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAClD,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,CAAC;CAChD,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;OAEG;IACH,OAAO,IAAI,IAAI,CAAC;IAEhB;;OAEG;IACH,UAAU,IAAI,SAAS,WAAW,EAAE,CAAC;IAErC;;OAEG;IACH,eAAe,IAAI,eAAe,CAAC;IAEnC;;;;;;;;OAQG;IACH,WAAW,CACT,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,SAAS,CAAC,EAAE,mBAAmB,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/B,CAAC;AAgCF;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,QAAQ,EAChB,OAAO,GAAE,qBAA0B,EACnC,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,cAAc,CAAC,CAmLzB"}
|
|
@@ -11,6 +11,10 @@ export type TokenizerChatConfig = {
|
|
|
11
11
|
readonly chatTemplate: string;
|
|
12
12
|
/** End-of-sequence token string. */
|
|
13
13
|
readonly eosToken: string;
|
|
14
|
+
/**
|
|
15
|
+
* Every terminal token the model may decode into its output.
|
|
16
|
+
*/
|
|
17
|
+
readonly stopTokens: readonly string[];
|
|
14
18
|
};
|
|
15
19
|
/**
|
|
16
20
|
* Parses raw JSON configuration from `tokenizer_config.json` into a normalized format.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenizerConfig.d.ts","sourceRoot":"","sources":["../../../../../../src/extensions/llm/utils/tokenizerConfig.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,uDAAuD;IACvD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"tokenizerConfig.d.ts","sourceRoot":"","sources":["../../../../../../src/extensions/llm/utils/tokenizerConfig.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,uDAAuD;IACvD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAAC;AAUF;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,GAAG,GAAG,mBAAmB,CAgCrE"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-executorch",
|
|
3
|
-
"version": "0.10.
|
|
4
|
-
"nativeLibsVersion": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
|
+
"nativeLibsVersion": "0.10.4",
|
|
5
5
|
"description": "An easy way to run AI models in React Native with ExecuTorch",
|
|
6
6
|
"main": "./lib/module/index.js",
|
|
7
7
|
"module": "./lib/module/index.js",
|
|
@@ -136,6 +136,38 @@ Pod::Spec.new do |s|
|
|
|
136
136
|
# ==============================================================================
|
|
137
137
|
exclude_files += opencv_source_files unless enable_opencv
|
|
138
138
|
exclude_files += phonemis_source_files unless enable_phonemis
|
|
139
|
+
# ==============================================================================
|
|
140
|
+
# LEGACY SUPPORT: the legacy TTS models need phonemis too, and `legacy/cpp/**`
|
|
141
|
+
# above sweeps them in unconditionally. Without this they compile — the
|
|
142
|
+
# phonemis headers stay on HEADER_SEARCH_PATHS — and fail at link with
|
|
143
|
+
# undefined phonemis::Pipeline symbols.
|
|
144
|
+
# (Remove when react-native-executorch/legacy is dropped)
|
|
145
|
+
# ==============================================================================
|
|
146
|
+
unless enable_phonemis
|
|
147
|
+
exclude_files += ["legacy/cpp/rnexecutorch/models/text_to_speech/**/*.{cpp,c,h,hpp}"]
|
|
148
|
+
end
|
|
149
|
+
# ==============================================================================
|
|
150
|
+
# LEGACY SUPPORT: the same for opencv. The legacy vision models, the
|
|
151
|
+
# image/frame helpers they share and the multimodal LLM's vision encoder all
|
|
152
|
+
# compile against opencv2, which is not linked when opencv is off. Only the
|
|
153
|
+
# sources are excluded: the `Types.h` headers sitting next to them are
|
|
154
|
+
# opencv-free and `JsiConversions.h` includes them unconditionally.
|
|
155
|
+
# (Remove when react-native-executorch/legacy is dropped)
|
|
156
|
+
# ==============================================================================
|
|
157
|
+
unless enable_opencv
|
|
158
|
+
legacy_dir = "legacy/cpp/rnexecutorch"
|
|
159
|
+
exclude_files += [
|
|
160
|
+
"#{legacy_dir}/data_processing/ImageProcessing.cpp",
|
|
161
|
+
"#{legacy_dir}/models/VisionModel.cpp",
|
|
162
|
+
"#{legacy_dir}/utils/Frame*.cpp",
|
|
163
|
+
"legacy/cpp/runner/encoders/vision_encoder.cpp",
|
|
164
|
+
]
|
|
165
|
+
exclude_files += %w[
|
|
166
|
+
classification embeddings/image instance_segmentation object_detection ocr
|
|
167
|
+
pose_estimation semantic_segmentation style_transfer text_to_image vertical_ocr
|
|
168
|
+
].map { |task| "#{legacy_dir}/models/#{task}/**/*.{cpp,c}" }
|
|
169
|
+
end
|
|
170
|
+
# ==============================================================================
|
|
139
171
|
s.exclude_files = exclude_files
|
|
140
172
|
|
|
141
173
|
# --- Public headers ---
|
package/scripts/download-libs.js
CHANGED
|
@@ -11,9 +11,10 @@
|
|
|
11
11
|
*
|
|
12
12
|
* headers.tar.gz -- ExecuTorch + c10 + torch + tokenizers + opencv
|
|
13
13
|
* headers (platform-independent; always downloaded)
|
|
14
|
-
* core-android-arm64-v8a.tar.gz --
|
|
15
|
-
*
|
|
16
|
-
* core-
|
|
14
|
+
* core-android-arm64-v8a.tar.gz -- libexecutorch.so (+ executorch.jar) for arm64;
|
|
15
|
+
* pthreadpool and cpuinfo are statically linked in
|
|
16
|
+
* core-android-x86_64.tar.gz -- libexecutorch.so for x86_64
|
|
17
|
+
* core-ios.tar.gz -- ExecutorchLib.xcframework + libthreadpool_*.a
|
|
17
18
|
* opencv-android-arm64-v8a.tar.gz -- OpenCV for arm64
|
|
18
19
|
* opencv-android-x86_64.tar.gz -- OpenCV for x86_64
|
|
19
20
|
* opencv-ios.tar.gz -- OpenCV xcframework
|
|
@@ -74,7 +75,9 @@ const https = require('https');
|
|
|
74
75
|
const http = require('http');
|
|
75
76
|
const fs = require('fs');
|
|
76
77
|
const path = require('path');
|
|
77
|
-
const {
|
|
78
|
+
const { spawnSync } = require('child_process');
|
|
79
|
+
const { createHash } = require('crypto');
|
|
80
|
+
const { Buffer } = require('buffer');
|
|
78
81
|
|
|
79
82
|
// ---- Config ----------------------------------------------------------------
|
|
80
83
|
|
|
@@ -151,8 +154,10 @@ const FEATURE_MAP = {
|
|
|
151
154
|
// YOLO is xnnpack-only, ssdlite/rf_detr add coreml → union.
|
|
152
155
|
objectDetection: { backends: ['xnnpack', 'coreml'], libs: ['opencv'] },
|
|
153
156
|
// Keypoint detection (#1280): BlazeFace + YOLO26-pose ship xnnpack; RF-DETR
|
|
154
|
-
// keypoint adds coreml
|
|
155
|
-
//
|
|
157
|
+
// keypoint adds coreml → union. mlx stays for the legacy API, whose
|
|
158
|
+
// RF_DETR_KEYPOINT_PREVIEW_MLX_FP32_MODEL outlived the new registry's MLX
|
|
159
|
+
// keypoint export (dropped in #1418).
|
|
160
|
+
// (Named to track the useKeypointDetector hook; main calls this poseEstimation.)
|
|
156
161
|
keypointDetection: { backends: ['xnnpack', 'coreml', 'mlx'], libs: ['opencv'] },
|
|
157
162
|
// DeepLab/FCN/LR-ASPP/selfie all ship xnnpack + coreml.
|
|
158
163
|
semanticSegmentation: { backends: ['xnnpack', 'coreml'], libs: ['opencv'] },
|
|
@@ -431,15 +436,33 @@ function download(url, dest) {
|
|
|
431
436
|
};
|
|
432
437
|
get(url);
|
|
433
438
|
file.on('error', (err) => {
|
|
434
|
-
|
|
439
|
+
// Close before removing: on Windows an open handle makes the unlink fail
|
|
440
|
+
// with EBUSY, which then replaces the real error with the cleanup's. And
|
|
441
|
+
// `force` covers the case where the file was never created.
|
|
442
|
+
file.close(() => fs.rmSync(dest, { force: true }));
|
|
435
443
|
reject(err);
|
|
436
444
|
});
|
|
437
445
|
});
|
|
438
446
|
}
|
|
439
447
|
|
|
448
|
+
// Hashes in-process rather than shelling out to `sha256sum` / `shasum`. Those
|
|
449
|
+
// are not on PATH everywhere, and GNU `sha256sum` escapes a filename holding a
|
|
450
|
+
// backslash by prefixing its whole output line with one -- so on Windows every
|
|
451
|
+
// hash came back as `\<hex>` and no artifact could ever validate. Read in
|
|
452
|
+
// chunks: some artifacts are hundreds of megabytes and this runs at install.
|
|
440
453
|
function sha256(filePath) {
|
|
441
|
-
const
|
|
442
|
-
|
|
454
|
+
const hash = createHash('sha256');
|
|
455
|
+
const buffer = Buffer.alloc(1024 * 1024);
|
|
456
|
+
const fd = fs.openSync(filePath, 'r');
|
|
457
|
+
try {
|
|
458
|
+
let bytesRead;
|
|
459
|
+
while ((bytesRead = fs.readSync(fd, buffer, 0, buffer.length, null)) > 0) {
|
|
460
|
+
hash.update(buffer.subarray(0, bytesRead));
|
|
461
|
+
}
|
|
462
|
+
} finally {
|
|
463
|
+
fs.closeSync(fd);
|
|
464
|
+
}
|
|
465
|
+
return hash.digest('hex');
|
|
443
466
|
}
|
|
444
467
|
|
|
445
468
|
async function isCacheValid(artifact) {
|
|
@@ -461,6 +484,68 @@ async function isCacheValid(artifact) {
|
|
|
461
484
|
return expectedChecksum === actualChecksum;
|
|
462
485
|
}
|
|
463
486
|
|
|
487
|
+
// The backend binaries each artifact owns, relative to the extraction dir. Used
|
|
488
|
+
// to clear stale copies: nothing else removes them, and `isCacheValid()`
|
|
489
|
+
// short-circuits the download, so turning a backend OFF after an install would
|
|
490
|
+
// otherwise leave the old binary in place and (on Android) keep shipping it.
|
|
491
|
+
const BACKEND_FILES = {
|
|
492
|
+
android: {
|
|
493
|
+
xnnpack: ['executorch/*/libxnnpack_executorch_backend.so'],
|
|
494
|
+
vulkan: ['executorch/*/libvulkan_executorch_backend.so'],
|
|
495
|
+
},
|
|
496
|
+
ios: {
|
|
497
|
+
xnnpack: ['XnnpackBackend.xcframework'],
|
|
498
|
+
coreml: ['CoreMLBackend.xcframework'],
|
|
499
|
+
mlx: ['MLXBackend.xcframework', 'libs/executorch/mlx.metallib'],
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
// Removes the binaries of backends the resolved config does not ask for, so a
|
|
504
|
+
// config change takes effect without anyone deleting third-party/ by hand.
|
|
505
|
+
function pruneDisabledBackends(targets, { backends }) {
|
|
506
|
+
for (const target of targets) {
|
|
507
|
+
const platform = target.startsWith('android') ? 'android' : 'ios';
|
|
508
|
+
const destDir =
|
|
509
|
+
platform === 'android'
|
|
510
|
+
? path.join(THIRD_PARTY_DIR, 'android', 'libs')
|
|
511
|
+
: path.join(THIRD_PARTY_DIR, 'ios');
|
|
512
|
+
if (!fs.existsSync(destDir)) continue;
|
|
513
|
+
|
|
514
|
+
for (const [backend, patterns] of Object.entries(BACKEND_FILES[platform])) {
|
|
515
|
+
if (backends.includes(backend)) continue;
|
|
516
|
+
for (const pattern of patterns) {
|
|
517
|
+
for (const stale of expandPattern(destDir, pattern)) {
|
|
518
|
+
console.log(
|
|
519
|
+
`[react-native-executorch] Removing ${backend} binary (not enabled): ${path.relative(THIRD_PARTY_DIR, stale)}`
|
|
520
|
+
);
|
|
521
|
+
fs.rmSync(stale, { recursive: true, force: true });
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Resolves a path that may contain a single `*` segment (the Android ABI dir).
|
|
529
|
+
// A dependency-free stand-in for a glob, since this script runs at postinstall
|
|
530
|
+
// with nothing but Node's stdlib available.
|
|
531
|
+
function expandPattern(root, pattern) {
|
|
532
|
+
const segments = pattern.split('/');
|
|
533
|
+
let candidates = [root];
|
|
534
|
+
for (const segment of segments) {
|
|
535
|
+
const next = [];
|
|
536
|
+
for (const base of candidates) {
|
|
537
|
+
if (segment === '*') {
|
|
538
|
+
if (!fs.existsSync(base)) continue;
|
|
539
|
+
for (const entry of fs.readdirSync(base)) next.push(path.join(base, entry));
|
|
540
|
+
} else {
|
|
541
|
+
next.push(path.join(base, segment));
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
candidates = next;
|
|
545
|
+
}
|
|
546
|
+
return candidates.filter((candidate) => fs.existsSync(candidate));
|
|
547
|
+
}
|
|
548
|
+
|
|
464
549
|
function extract(tarball, destDir) {
|
|
465
550
|
ensureDir(destDir);
|
|
466
551
|
// `-m` stamps extracted files with the extraction time instead of the mtime
|
|
@@ -471,7 +556,36 @@ function extract(tarball, destDir) {
|
|
|
471
556
|
// and they get archived and linked against the new libraries -- which shows
|
|
472
557
|
// up as an undefined symbol for whatever API changed between the two
|
|
473
558
|
// releases, far away from the actual cause.
|
|
474
|
-
|
|
559
|
+
//
|
|
560
|
+
// No path reaches tar's argv, because GNU tar (Git for Windows' is the one
|
|
561
|
+
// on PATH under Git Bash) mangles Windows paths two ways: `-f C:\Users\...`
|
|
562
|
+
// is the `host:file` form, so it tries to reach a remote host named `C`; and
|
|
563
|
+
// `-C` is unquoted by default, so the `\r` and `\t` in
|
|
564
|
+
// `node_modules\react-native-executorch\third-party` become a carriage
|
|
565
|
+
// return and a tab. The archive arrives on stdin and `cwd` does the chdir.
|
|
566
|
+
const fd = fs.openSync(tarball, 'r');
|
|
567
|
+
let result;
|
|
568
|
+
try {
|
|
569
|
+
result = spawnSync('tar', ['-xzm', '-f', '-'], {
|
|
570
|
+
cwd: destDir,
|
|
571
|
+
stdio: [fd, 'inherit', 'pipe'],
|
|
572
|
+
encoding: 'utf8',
|
|
573
|
+
});
|
|
574
|
+
} finally {
|
|
575
|
+
fs.closeSync(fd);
|
|
576
|
+
}
|
|
577
|
+
if (result.error) {
|
|
578
|
+
throw new Error(
|
|
579
|
+
`Could not run \`tar\` to extract ${tarball}: ${result.error.message}. ` +
|
|
580
|
+
'Install tar (it ships with Windows 10 1803+, Git for Windows and every Unix) and reinstall.'
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
if (result.status !== 0) {
|
|
584
|
+
throw new Error(
|
|
585
|
+
`tar exited with ${result.status ?? result.signal} while extracting ${tarball}` +
|
|
586
|
+
`${result.stderr ? `:\n${result.stderr.trim()}` : ''}`
|
|
587
|
+
);
|
|
588
|
+
}
|
|
475
589
|
}
|
|
476
590
|
|
|
477
591
|
// ---- Main ------------------------------------------------------------------
|
|
@@ -525,6 +639,10 @@ async function main() {
|
|
|
525
639
|
console.log(` ✓ Done`);
|
|
526
640
|
}
|
|
527
641
|
|
|
642
|
+
// Belt and braces to core no longer carrying backends: this also clears
|
|
643
|
+
// binaries left by an EARLIER install that had the backend enabled.
|
|
644
|
+
pruneDisabledBackends(targets, config);
|
|
645
|
+
|
|
528
646
|
console.log('[react-native-executorch] Native libs ready.');
|
|
529
647
|
}
|
|
530
648
|
|
|
@@ -536,4 +654,14 @@ if (require.main === module) {
|
|
|
536
654
|
});
|
|
537
655
|
}
|
|
538
656
|
|
|
539
|
-
module.exports = {
|
|
657
|
+
module.exports = {
|
|
658
|
+
ALL_BACKENDS,
|
|
659
|
+
ALL_LIBS,
|
|
660
|
+
BACKEND_FILES,
|
|
661
|
+
FEATURE_MAP,
|
|
662
|
+
findUserConfig,
|
|
663
|
+
readUserConfig,
|
|
664
|
+
pruneDisabledBackends,
|
|
665
|
+
sha256,
|
|
666
|
+
extract,
|
|
667
|
+
};
|
|
@@ -13,8 +13,6 @@ declare const llmRunnerBrand: unique symbol;
|
|
|
13
13
|
* @category LLM / Types
|
|
14
14
|
*/
|
|
15
15
|
export type LLMGenerationConfig = {
|
|
16
|
-
/** Whether to echo the prompt in the generated output. */
|
|
17
|
-
readonly echo?: boolean;
|
|
18
16
|
/** Whether to ignore EOS tokens during generation. */
|
|
19
17
|
readonly ignoreEos?: boolean;
|
|
20
18
|
/** Maximum number of new tokens to generate. */
|
|
@@ -139,18 +139,18 @@ function generateChatTurnWorklet(
|
|
|
139
139
|
prompt: Prompt,
|
|
140
140
|
options: {
|
|
141
141
|
readonly genConfig: LLMGenerationConfig;
|
|
142
|
-
readonly
|
|
142
|
+
readonly stopTokens: readonly string[];
|
|
143
143
|
readonly stopRegex?: RegExp;
|
|
144
144
|
readonly onToken?: (token: string) => void;
|
|
145
145
|
}
|
|
146
146
|
): { readonly response: string; readonly stats: LLMGenerationStats } {
|
|
147
147
|
'worklet';
|
|
148
|
-
const { genConfig,
|
|
148
|
+
const { genConfig, stopTokens, stopRegex, onToken } = options;
|
|
149
149
|
|
|
150
150
|
let response = '';
|
|
151
151
|
|
|
152
152
|
const callback = (token: string) => {
|
|
153
|
-
if (token
|
|
153
|
+
if (stopTokens.includes(token)) return;
|
|
154
154
|
response += token;
|
|
155
155
|
|
|
156
156
|
if (onToken) scheduleOnRN(onToken, token);
|
|
@@ -196,7 +196,7 @@ export async function createLLMChatSession(
|
|
|
196
196
|
// Read and parse tokenizer_config.json
|
|
197
197
|
const tokenizerConfigStr = await RNBlobUtil.fs.readFile(tokenizerConfigPath, 'utf8');
|
|
198
198
|
const tokenizerConfig = parseTokenizerConfig(JSON.parse(tokenizerConfigStr));
|
|
199
|
-
const { chatTemplate,
|
|
199
|
+
const { chatTemplate, stopTokens } = tokenizerConfig;
|
|
200
200
|
|
|
201
201
|
// Prepare chat preprocessor
|
|
202
202
|
const chatPreprocessorConfig = { chatTemplate, modalities, preprocessorConfig, tools };
|
|
@@ -233,7 +233,7 @@ export async function createLLMChatSession(
|
|
|
233
233
|
genConfig?: LLMGenerationConfig
|
|
234
234
|
): Promise<LLMChatTurnResult> => {
|
|
235
235
|
const turnGenConfig = { ...defaultGenerationConfig, ...genConfig };
|
|
236
|
-
const generationOpts = { genConfig: turnGenConfig,
|
|
236
|
+
const generationOpts = { genConfig: turnGenConfig, stopTokens, stopRegex, onToken };
|
|
237
237
|
|
|
238
238
|
const initialCommitted = committed;
|
|
239
239
|
const initialPos = runner.getKVCacheState().pos;
|
|
@@ -330,10 +330,15 @@ export async function createLLMChatSession(
|
|
|
330
330
|
|
|
331
331
|
return { messages: history.slice(turnStartIdx), stats: generationStatsList, finishReason };
|
|
332
332
|
} catch (err) {
|
|
333
|
-
// Roll back history, KV cache, and active tensors to pre-turn state on
|
|
333
|
+
// Roll back history, KV cache, and active tensors to pre-turn state on
|
|
334
|
+
// failure. The rewind must never replace the error it is unwinding.
|
|
335
|
+
//
|
|
336
|
+
// Under `resetOnTurn` the pre-turn position IS zero: `initialPos` is
|
|
337
|
+
// read before the turn begins and the turn then zeroed the cache, so
|
|
338
|
+
// rewinding to it is out of range by construction.
|
|
334
339
|
history.length = turnStartIdx;
|
|
335
340
|
committed = initialCommitted;
|
|
336
|
-
runner.reset(initialPos);
|
|
341
|
+
runner.reset(resetOnTurn ? 0 : initialPos);
|
|
337
342
|
chatPreprocessor.clear();
|
|
338
343
|
throw err;
|
|
339
344
|
}
|
|
@@ -14,6 +14,10 @@ export type TokenizerChatConfig = {
|
|
|
14
14
|
readonly chatTemplate: string;
|
|
15
15
|
/** End-of-sequence token string. */
|
|
16
16
|
readonly eosToken: string;
|
|
17
|
+
/**
|
|
18
|
+
* Every terminal token the model may decode into its output.
|
|
19
|
+
*/
|
|
20
|
+
readonly stopTokens: readonly string[];
|
|
17
21
|
};
|
|
18
22
|
|
|
19
23
|
function resolveToken(token: unknown): string | undefined {
|
|
@@ -57,5 +61,11 @@ export function parseTokenizerConfig(config: any): TokenizerChatConfig {
|
|
|
57
61
|
);
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
|
|
64
|
+
const stopTokens = [
|
|
65
|
+
eosToken,
|
|
66
|
+
resolveToken(config.eot_token),
|
|
67
|
+
resolveToken(config.pad_token),
|
|
68
|
+
].filter((token, index, all): token is string => !!token && all.indexOf(token) === index);
|
|
69
|
+
|
|
70
|
+
return { chatTemplate, eosToken, stopTokens };
|
|
61
71
|
}
|
package/src/fetcher/telemetry.ts
CHANGED
|
@@ -10,7 +10,7 @@ const DOWNLOAD_EVENT_ENDPOINT = 'https://ai.swmansion.com/telemetry/downloads/ap
|
|
|
10
10
|
// self-referencing import would need package `exports` support in the consuming
|
|
11
11
|
// bundler to load at all. A wrong value here is analytics noise; a failed
|
|
12
12
|
// import would break the bundle.
|
|
13
|
-
const LIB_VERSION = '0.10.
|
|
13
|
+
const LIB_VERSION = '0.10.3';
|
|
14
14
|
|
|
15
15
|
// Anonymous analytics are on by default; apps opt out via setTelemetryEnabled.
|
|
16
16
|
let telemetryEnabled = true;
|