Skip to content

Commit 047315d

Browse files
committed
minor refactor
1 parent fe51028 commit 047315d

9 files changed

Lines changed: 59 additions & 60 deletions

File tree

‎packages/react-native-executorch/common/rnexecutorch/host_objects/JsiConversions.h‎

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#pragma once
22

3+
#include "rnexecutorch/Log.h"
34
#include <codecvt>
45
#include <cstdint>
56
#include <set>
67
#include <span>
8+
#include <string>
79
#include <type_traits>
810
#include <unordered_map>
911
#include <variant>
@@ -319,28 +321,28 @@ getValue<std::span<uint64_t>>(const jsi::Value &val, jsi::Runtime &runtime) {
319321
return getTypedArrayAsSpan<uint64_t>(val, runtime);
320322
}
321323

322-
template <typename T>
323-
inline void assignIfPresent(T &field, const jsi::Object &obj,
324-
jsi::Runtime &runtime, const char *name) {
325-
if (!obj.hasProperty(runtime, name))
326-
return;
327-
jsi::Value v = obj.getProperty(runtime, name);
328-
if (v.isUndefined() || v.isNull())
329-
return;
330-
field = getValue<T>(v, runtime);
331-
}
332-
333324
template <>
334325
inline models::llm::MultimodalInputs
335326
getValue<models::llm::MultimodalInputs>(const jsi::Value &val,
336327
jsi::Runtime &runtime) {
337328
models::llm::MultimodalInputs multimodalInputs;
338329
jsi::Object obj = val.asObject(runtime);
339-
assignIfPresent(multimodalInputs.images->paths, obj, runtime, "imagePaths");
340-
assignIfPresent(multimodalInputs.images->token, obj, runtime, "imageToken");
341-
assignIfPresent(multimodalInputs.audios->waveforms, obj, runtime,
342-
"audioWaveforms");
343-
assignIfPresent(multimodalInputs.audios->token, obj, runtime, "audioToken");
330+
331+
jsi::Value v = obj.getProperty(runtime, "imageToken");
332+
if (!v.isUndefined() && !v.isNull()) {
333+
auto &images = multimodalInputs.images.emplace();
334+
images.token = getValue<std::string>(v, runtime);
335+
v = obj.getProperty(runtime, "imagePaths");
336+
images.paths = getValue<std::vector<std::string>>(v, runtime);
337+
}
338+
v = obj.getProperty(runtime, "audioToken");
339+
if (!v.isUndefined() && !v.isNull()) {
340+
auto &audios = multimodalInputs.audios.emplace();
341+
audios.token = getValue<std::string>(v, runtime);
342+
v = obj.getProperty(runtime, "audioWaveforms");
343+
audios.waveforms = getValue<std::vector<std::vector<float>>>(v, runtime);
344+
}
345+
344346
return multimodalInputs;
345347
}
346348

‎packages/react-native-executorch/common/rnexecutorch/host_objects/ModelHostObject.h‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,11 @@ template <typename Model> class ModelHostObject : public JsiHostObject {
281281
return jsi_conversion::getJsiValue(std::move(result), runtime);
282282
}
283283
} catch (const RnExecutorchError &e) {
284+
rnexecutorch::log(rnexecutorch::LOG_LEVEL::Info, "kappa", e.what());
284285
throw jsi::JSError(runtime, makeRnExecutorchErrorValue(
285286
runtime, e.getNumericCode(), e.what()));
286287
} catch (const std::exception &e) {
288+
rnexecutorch::log(rnexecutorch::LOG_LEVEL::Info, "kappa", e.what());
287289
throw jsi::JSError(runtime, e.what());
288290
} catch (...) {
289291
throw jsi::JSError(runtime, "Unknown error in synchronous function");
@@ -348,9 +350,11 @@ template <typename Model> class ModelHostObject : public JsiHostObject {
348350
return jsi_conversion::getJsiValue(std::move(result), runtime);
349351
}
350352
} catch (const RnExecutorchError &e) {
353+
rnexecutorch::log(rnexecutorch::LOG_LEVEL::Info, "kappa", e.what());
351354
throw jsi::JSError(runtime, makeRnExecutorchErrorValue(
352355
runtime, e.getNumericCode(), e.what()));
353356
} catch (const std::exception &e) {
357+
rnexecutorch::log(rnexecutorch::LOG_LEVEL::Info, "kappa", e.what());
354358
throw jsi::JSError(runtime, e.what());
355359
} catch (...) {
356360
throw jsi::JSError(runtime, "Unknown error in vision function");
@@ -411,6 +415,8 @@ template <typename Model> class ModelHostObject : public JsiHostObject {
411415
});
412416
}
413417
} catch (const RnExecutorchError &e) {
418+
rnexecutorch::log(rnexecutorch::LOG_LEVEL::Info, "kappa",
419+
e.what());
414420
auto code = e.getNumericCode();
415421
auto msg = std::string(e.what());
416422
callInvoker->invokeAsync(
@@ -420,6 +426,8 @@ template <typename Model> class ModelHostObject : public JsiHostObject {
420426
});
421427
return;
422428
} catch (const std::exception &e) {
429+
rnexecutorch::log(rnexecutorch::LOG_LEVEL::Info, "kappa",
430+
e.what());
423431
callInvoker->invokeAsync([e = std::move(e), promise]() {
424432
promise->reject(std::string(e.what()));
425433
});

‎packages/react-native-executorch/common/rnexecutorch/models/llm/LLM.cpp‎

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "LLM.h"
2+
#include "rnexecutorch/models/llm/Types.h"
23

34
#include <executorch/extension/tensor/tensor.h>
45
#include <filesystem>
@@ -87,8 +88,8 @@ std::string LLM::generateMultimodal(std::string prompt,
8788
throw RnExecutorchError(RnExecutorchErrorCode::InvalidUserInput,
8889
"This model does not support multimodal input.");
8990
}
90-
if (mutlimodalInputs.imageToken.empty() &&
91-
mutlimodalInputs.audioToken.empty()) {
91+
if (!mutlimodalInputs.images.has_value() &&
92+
!mutlimodalInputs.audios.has_value()) {
9293
throw RnExecutorchError(
9394
RnExecutorchErrorCode::InvalidUserInput,
9495
"At least one of imageToken/audioToken must be non-empty");
@@ -99,12 +100,12 @@ std::string LLM::generateMultimodal(std::string prompt,
99100
std::vector<llm::MultimodalInput> inputs;
100101
size_t imageIdx = 0, audioIdx = 0, pos = 0;
101102
while (pos < prompt.size()) {
102-
size_t imgAt = mutlimodalInputs.images
103-
? std::string::npos
104-
: prompt.find(mutlimodalInputs.images->token, pos);
105-
size_t audAt = mutlimodalInputs.audios
106-
? std::string::npos
107-
: prompt.find(mutlimodalInputs.audios->token, pos);
103+
size_t imgAt = mutlimodalInputs.images.has_value()
104+
? prompt.find(mutlimodalInputs.images.value().token, pos)
105+
: std::string::npos;
106+
size_t audAt = mutlimodalInputs.audios.has_value()
107+
? prompt.find(mutlimodalInputs.audios.value().token, pos)
108+
: std::string::npos;
108109
if (imgAt == std::string::npos && audAt == std::string::npos) {
109110
inputs.push_back(llm::make_text_input(prompt.substr(pos)));
110111
break;
@@ -116,27 +117,30 @@ std::string LLM::generateMultimodal(std::string prompt,
116117
inputs.push_back(llm::make_text_input(prompt.substr(pos, at - pos)));
117118
}
118119
if (imageFirst) {
119-
if (imageIdx >= mutlimodalInputs.images->paths.size()) {
120+
auto &images = mutlimodalInputs.images.value();
121+
if (imageIdx >= images.paths.size()) {
120122
throw RnExecutorchError(RnExecutorchErrorCode::InvalidUserInput,
121-
"More '" + mutlimodalInputs.images->token +
123+
"More '" + images.token +
122124
"' placeholders than image paths");
123125
}
124-
inputs.push_back(
125-
llm::make_image_input(mutlimodalInputs.images->paths[imageIdx++]));
126-
pos = at + mutlimodalInputs.images->token.size();
126+
inputs.push_back(llm::make_image_input(images.paths[imageIdx++]));
127+
pos = at + images.token.size();
127128
} else {
128-
if (audioIdx >= mutlimodalInputs.audios->waveforms.size()) {
129+
auto &audios = mutlimodalInputs.audios.value();
130+
if (audioIdx >= audios.waveforms.size()) {
129131
throw RnExecutorchError(RnExecutorchErrorCode::InvalidUserInput,
130-
"More '" + mutlimodalInputs.audioToken +
132+
"More '" + audios.token +
131133
"' placeholders than audio waveforms");
132134
}
133-
inputs.push_back(llm::make_audio_input(
134-
std::move(mutlimodalInputs.audios->waveforms[audioIdx++])));
135-
pos = at + mutlimodalInputs.audios->token.size();
135+
inputs.push_back(
136+
llm::make_audio_input(std::move(audios.waveforms[audioIdx++])));
137+
pos = at + audios.token.size();
136138
}
137139
}
138-
if (imageIdx < mutlimodalInputs.images->paths.size() ||
139-
audioIdx < mutlimodalInputs.audios->waveforms.size()) {
140+
if ((mutlimodalInputs.images.has_value() &&
141+
imageIdx < mutlimodalInputs.images.value().paths.size()) ||
142+
(mutlimodalInputs.audios.has_value() &&
143+
audioIdx < mutlimodalInputs.audios.value().waveforms.size())) {
140144
throw RnExecutorchError(
141145
RnExecutorchErrorCode::InvalidUserInput,
142146
"More image/audio paths provided than placeholders in prompt");

‎packages/react-native-executorch/common/runner/multimodal_prefiller.cpp‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#include "multimodal_prefiller.h"
1313
#include "constants.h"
14-
#include "runner/multimodal_decoder_runner.h"
1514
#include "util.h"
1615
#include <algorithm>
1716
#include <cstring>
@@ -164,6 +163,7 @@ auto MultimodalPrefiller::encodeAudio(
164163
"unsupported audio/text dtype pair: audio=%hhd text=%hhd",
165164
static_cast<int8_t>(audio_dtype), static_cast<int8_t>(embeds_dtype));
166165
}
166+
return ::executorch::runtime::Error::Ok;
167167
}
168168

169169
auto MultimodalPrefiller::encodeImages(
@@ -205,6 +205,7 @@ auto MultimodalPrefiller::encodeImages(
205205
"unsupported vision/text dtype pair: vision=%hhd text=%hhd",
206206
static_cast<int8_t>(vision_dtype), static_cast<int8_t>(embeds_dtype));
207207
}
208+
return ::executorch::runtime::Error::Ok;
208209
}
209210

210211
auto MultimodalPrefiller::initializePLE(auto &embed_outputs, auto total_len,
@@ -225,6 +226,7 @@ auto MultimodalPrefiller::initializePLE(auto &embed_outputs, auto total_len,
225226
ple_embeddings.ple_tok_buf.resize(prefix_bytes);
226227
std::memcpy(ple_embeddings.ple_tok_buf.data(),
227228
full_ple_tok.mutable_data_ptr(), prefix_bytes);
229+
return ::executorch::runtime::Error::Ok;
228230
}
229231

230232
auto MultimodalPrefiller::prefillChunk(std::vector<EValue> &last_outs,
@@ -268,6 +270,7 @@ auto MultimodalPrefiller::prefillChunk(std::vector<EValue> &last_outs,
268270
EValue(*pos_chunk)});
269271
ET_CHECK_OK_OR_RETURN_ERROR(res.error());
270272
last_outs = std::move(*res);
273+
return ::executorch::runtime::Error::Ok;
271274
}
272275

273276
Result<uint64_t>

‎packages/react-native-executorch/common/runner/multimodal_prefiller.h‎

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,12 @@
1919
namespace executorch::extension::llm {
2020

2121
namespace {
22-
// ------------------------------------------------------------
23-
// Pass 1: build a fused input_ids buffer spanning all inputs.
24-
//
25-
// Image positions use pad_token_id (placeholder_id is rewritten to 0 before
26-
// PLE lookup). The decoder embeds at those positions are then overwritten
27-
// with the vision encoder output in pass 2.
28-
// ------------------------------------------------------------
2922
struct ImageSlot {
3023
const MultimodalInput *input; // non-owning, valid for duration of call
3124
int64_t slot_start;
3225
int64_t num_visual;
3326
};
34-
// Audio tokens are dynamic per clip, so we encode first and remember a
35-
// BYTE SNAPSHOT of the encoder output + count + dtype; pass 2 splices
36-
// from the snapshot.
37-
//
38-
// We can NOT stash the EValue here. EValue holds an aten::Tensor which is
39-
// just a TensorImpl*; `Method::get_output(i)` returns `const EValue&` to
40-
// Method-internal storage and Module::execute copies that EValue into the
41-
// returned vector. The copy shares the underlying TensorImpl, so a later
42-
// execute() on the same method — a second audio input in this prefill would
43-
// overwrite.
27+
4428
struct AudioSlot {
4529
std::vector<uint8_t> bytes;
4630
::executorch::aten::ScalarType dtype;

‎packages/react-native-executorch/common/runner/sampler.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace executorch {
2929
namespace extension {
3030
namespace llm {
3131
// A simple llama2 sampler.
32+
struct GenerationConfig;
3233

3334
inline constexpr auto kTopp = 0.9f;
3435

‎packages/react-native-executorch/common/runner/text_decoder_runner.cpp‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,7 @@ int32_t TextDecoderRunner::logits_to_token(
101101
auto num_tokens = logits_tensor.size(1);
102102
logits += (num_tokens - 1) * vocab_size;
103103
}
104-
Sampler sampler(vocab_size, config_.temperature, config_.topp,
105-
static_cast<unsigned long long>(std::time(nullptr)),
106-
config_.min_p, config_.repetition_penalty);
104+
Sampler sampler(vocab_size, config_);
107105
result = sampler.sample(logits, recent_tokens);
108106
});
109107
return result;

‎packages/react-native-executorch/common/runner/util.h‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
#pragma once
1010
#include "constants.h"
11-
#include "text_prefiller.h"
1211
#include <cctype>
1312
#include <executorch/extension/module/module.h>
1413
#include <executorch/extension/tensor/tensor.h>

‎packages/react-native-executorch/src/controllers/LLMController.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,9 @@ export class LLMController {
305305
input,
306306
this.onToken,
307307
{
308-
imagePaths: hasImages ? imagePaths!.map(normalizeImagePath) : [],
308+
imagePaths: hasImages ? imagePaths!.map(normalizeImagePath) : null,
309309
imageToken: hasImages ? this.getImageToken() : null,
310-
audioWaveforms: hasAudio ? audioWaveforms! : [],
310+
audioWaveforms: hasAudio ? audioWaveforms! : null,
311311
audioToken: hasAudio ? this.getAudioToken() : null,
312312
}
313313
);

0 commit comments

Comments
 (0)