Skip to content

Commit 6002191

Browse files
review: address msluszniak feedback on privacy-filter
- Strip personal appleTeamId from apps/llm/app.json - Use std::cmp_greater_equal for the labelId bounds check - Take padded buffers by non-const ref in runWindow so make_tensor_ptr no longer needs const_cast on the data pointers - Move the validLen <= 0 early-return above the forward call so we don't run inference on empty windows - Replace the trusted-slice write loop with std::copy - Drop redundant parens around isFirst / isLast - emplace_back the merged spans - Drop the redundant "decoded = """ inside the catch block (decoded is already default-constructed empty) - Use std::ranges::find_if + reverse iterator for the trim block, emplace_back the resulting PiiEntity - Use std::ranges::max_element for the Viterbi best-end search and drop the now-unused bestScore variable Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 24a9b04 commit 6002191

4 files changed

Lines changed: 35 additions & 39 deletions

File tree

apps/llm/app.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@
6363
},
6464
"entitlements": {
6565
"com.apple.developer.kernel.increased-memory-limit": true
66-
},
67-
"appleTeamId": "J5FM626PE2"
66+
}
6867
},
6968
"android": {
7069
"adaptiveIcon": {

packages/react-native-executorch/common/rnexecutorch/models/privacy_filter/PrivacyFilter.cpp

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
#include <algorithm>
44
#include <cstdint>
5+
#include <ranges>
56
#include <string>
7+
#include <utility>
68
#include <vector>
79

810
#include <executorch/extension/tensor/tensor_ptr_maker.h>
@@ -58,7 +60,7 @@ PrivacyFilter::PrivacyFilter(const std::string &modelSource,
5860
}
5961

6062
std::string PrivacyFilter::labelEntityType(int32_t labelId) const {
61-
if (labelId <= 0 || labelId >= static_cast<int32_t>(labelNames_.size())) {
63+
if (labelId <= 0 || std::cmp_greater_equal(labelId, labelNames_.size())) {
6264
return "";
6365
}
6466
const auto &name = labelNames_[static_cast<size_t>(labelId)];
@@ -74,17 +76,20 @@ void PrivacyFilter::unload() noexcept {
7476
BaseModel::unload();
7577
}
7678

77-
void PrivacyFilter::runWindow(const std::vector<int64_t> &paddedInputIds,
78-
const std::vector<int64_t> &paddedAttentionMask,
79+
void PrivacyFilter::runWindow(std::vector<int64_t> &paddedInputIds,
80+
std::vector<int64_t> &paddedAttentionMask,
7981
int32_t absStart, int32_t validLen,
8082
int32_t writeFromOffset, int32_t writeToOffset,
8183
std::vector<int32_t> &outLabels) {
84+
if (validLen <= 0) {
85+
return;
86+
}
87+
8288
std::vector<int32_t> idsShape = {1, seqLen_};
83-
auto inputIdsTensor = make_tensor_ptr(
84-
idsShape, const_cast<int64_t *>(paddedInputIds.data()), ScalarType::Long);
85-
auto attentionMaskTensor = make_tensor_ptr(
86-
idsShape, const_cast<int64_t *>(paddedAttentionMask.data()),
87-
ScalarType::Long);
89+
auto inputIdsTensor =
90+
make_tensor_ptr(idsShape, paddedInputIds.data(), ScalarType::Long);
91+
auto attentionMaskTensor =
92+
make_tensor_ptr(idsShape, paddedAttentionMask.data(), ScalarType::Long);
8893

8994
auto forwardResult =
9095
BaseModel::forward({*inputIdsTensor, *attentionMaskTensor});
@@ -98,21 +103,15 @@ void PrivacyFilter::runWindow(const std::vector<int64_t> &paddedInputIds,
98103
throw RnExecutorchError(RnExecutorchErrorCode::UnknownError,
99104
"PrivacyFilter: forward returned no outputs");
100105
}
101-
if (validLen <= 0) {
102-
return;
103-
}
104106

105107
const auto &logitsTensor = out[0].toTensor();
106108
const float *logits = logitsTensor.const_data_ptr<float>();
107109

108110
auto path = viterbi::decode(logits, validLen, grammar_);
109111

110-
for (int32_t t = writeFromOffset; t < writeToOffset; ++t) {
111-
if (t >= validLen) {
112-
break;
113-
}
114-
outLabels[static_cast<size_t>(absStart + t)] = path[static_cast<size_t>(t)];
115-
}
112+
const int32_t end = std::min(writeToOffset, validLen);
113+
std::copy(path.begin() + writeFromOffset, path.begin() + end,
114+
outLabels.begin() + absStart + writeFromOffset);
116115
}
117116

118117
std::vector<types::PiiEntity> PrivacyFilter::generate(std::string text) {
@@ -143,8 +142,8 @@ std::vector<types::PiiEntity> PrivacyFilter::generate(std::string text) {
143142
paddedAttentionMask[static_cast<size_t>(i)] = 1;
144143
}
145144

146-
const bool isFirst = (windowStart == 0);
147-
const bool isLast = (windowStart + seqLen_ >= totalTokens);
145+
const bool isFirst = windowStart == 0;
146+
const bool isLast = windowStart + seqLen_ >= totalTokens;
148147
int32_t writeFrom = isFirst ? 0 : edgeMargin;
149148
int32_t writeTo = isLast ? validLen : seqLen_ - edgeMargin;
150149

@@ -175,7 +174,7 @@ std::vector<types::PiiEntity> PrivacyFilter::generate(std::string text) {
175174
labelEntityType(predictedLabels[static_cast<size_t>(j)]) == entity) {
176175
++j;
177176
}
178-
spans.push_back({i, j, entity});
177+
spans.emplace_back(i, j, entity);
179178
i = j;
180179
}
181180

@@ -191,19 +190,19 @@ std::vector<types::PiiEntity> PrivacyFilter::generate(std::string text) {
191190
try {
192191
decoded = tokenizer_->decode(slice, /*skipSpecialTokens=*/true);
193192
} catch (...) {
194-
decoded = "";
195193
}
196-
const auto notSpace = [](unsigned char c) { return !std::isspace(c); };
197-
auto left = std::find_if(decoded.begin(), decoded.end(), notSpace);
194+
constexpr auto notSpace = [](unsigned char c) { return !std::isspace(c); };
195+
auto left = std::ranges::find_if(decoded, notSpace);
198196
auto right =
199-
std::find_if(decoded.rbegin(), decoded.rend(), notSpace).base();
197+
std::ranges::find_if(decoded.rbegin(), decoded.rend(), notSpace).base();
200198
if (left < right) {
201-
decoded = std::string(left, right);
199+
decoded.assign(left, right);
202200
} else {
203201
decoded.clear();
204202
}
205203

206-
entities.push_back({span.entity, std::move(decoded), span.start, span.end});
204+
entities.emplace_back(span.entity, std::move(decoded), span.start,
205+
span.end);
207206
}
208207
return entities;
209208
}

packages/react-native-executorch/common/rnexecutorch/models/privacy_filter/PrivacyFilter.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ class PrivacyFilter final : public BaseModel {
3131
void unload() noexcept;
3232

3333
private:
34-
void runWindow(const std::vector<int64_t> &paddedInputIds,
35-
const std::vector<int64_t> &paddedAttentionMask,
36-
int32_t absStart, int32_t validLen, int32_t writeFromOffset,
34+
void runWindow(std::vector<int64_t> &paddedInputIds,
35+
std::vector<int64_t> &paddedAttentionMask, int32_t absStart,
36+
int32_t validLen, int32_t writeFromOffset,
3737
int32_t writeToOffset, std::vector<int32_t> &outLabels);
3838

3939
std::string labelEntityType(int32_t labelId) const;

packages/react-native-executorch/common/rnexecutorch/models/privacy_filter/Viterbi.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#include "Viterbi.h"
22

3+
#include <algorithm>
4+
#include <iterator>
5+
#include <ranges>
6+
37
namespace rnexecutorch::models::privacy_filter::viterbi {
48

59
namespace {
@@ -131,14 +135,8 @@ std::vector<int32_t> decode(const float *logits, int32_t validLen,
131135
std::swap(dp, dpNext);
132136
}
133137

134-
size_t bestEnd = 0;
135-
float bestScore = kNegInf;
136-
for (size_t j = 0; j < N; ++j) {
137-
if (dp[j] > bestScore) {
138-
bestScore = dp[j];
139-
bestEnd = j;
140-
}
141-
}
138+
auto it = std::ranges::max_element(dp);
139+
size_t bestEnd = std::distance(dp.begin(), it);
142140

143141
std::vector<int32_t> path(static_cast<size_t>(validLen), 0);
144142
path[static_cast<size_t>(validLen) - 1] = static_cast<int32_t>(bestEnd);

0 commit comments

Comments
 (0)