Skip to content

Commit 5470700

Browse files
authored
IFEval evaluation code overhaul (#1093)
* fixed ifeval evaluation implementation bugs * further improved sentence counter * overhauled keyword evaluation by using stemming and a plural word map * formatting * use stemming library as extenral dependency * format
1 parent a85a7e7 commit 5470700

File tree

8 files changed

+750
-98
lines changed

8 files changed

+750
-98
lines changed

WORKSPACE

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ rocm_configure(name = "local_config_rocm")
9999

100100
http_archive(
101101
name = "com_google_sentencepiece",
102-
build_file = "@//patches:sentencepiece.BUILD",
102+
build_file = "@//third_party:sentencepiece.BUILD",
103103
patch_args = ["-p1"],
104104
patches = ["@//patches:com_google_sentencepiece.diff"],
105105
sha256 = "8409b0126ebd62b256c685d5757150cf7fcb2b92a2f2b98efb3f38fc36719754",
@@ -111,7 +111,7 @@ http_archive(
111111

112112
http_archive(
113113
name = "darts_clone",
114-
build_file = "@//patches:darts_clone.BUILD",
114+
build_file = "@//third_party:darts_clone.BUILD",
115115
patch_args = ["-p0"],
116116
patches = ["//patches:darts_no_exceptions.diff"],
117117
sha256 = "c97f55d05c98da6fcaf7f9ecc6a6dc6bc5b18b8564465f77abff8879d446491c",
@@ -161,6 +161,14 @@ http_archive(
161161
urls = ["https://github.com/MediaTek-NeuroPilot/tflite-neuron-delegate/archive/refs/heads/update_for_leroy.zip"],
162162
)
163163

164+
http_archive(
165+
name = "oleander_stemming_library",
166+
build_file = "@//third_party:oleander_stemming_library.BUILD",
167+
sha256 = "d4390e82590d67c73ac32629ddd4fc3ba0b6b293a2757612a2e76726c3752e0b",
168+
strip_prefix = "OleanderStemmingLibrary-45eb3485f67b94d67bb883601ed65459975b3960",
169+
urls = ["https://github.com/Blake-Madden/OleanderStemmingLibrary/archive/45eb3485f67b94d67bb883601ed65459975b3960.zip"],
170+
)
171+
164172
new_git_repository(
165173
name = "org_mlperf_inference",
166174
build_file = "@//flutter/android/third_party:loadgen.BUILD",

flutter/cpp/datasets/ifeval_utils/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ cc_library(
2222
name = "ifeval_utils",
2323
hdrs = [
2424
"common.h",
25+
"irregular-plurals.h",
2526
"json.h",
2627
"types.h",
2728
],
@@ -36,5 +37,6 @@ cc_library(
3637
}),
3738
deps = [
3839
"@cld2",
40+
"@oleander_stemming_library",
3941
],
4042
)

flutter/cpp/datasets/ifeval_utils/common.h

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@ inline std::string tolower(std::string s) {
3535
return s;
3636
}
3737

38-
inline bool ends_with(const std::string& s, const std::string& suf) {
39-
if (s.size() < suf.size()) return false;
40-
std::string a = tolower(s.substr(s.size() - suf.size()));
41-
std::string b = tolower(suf);
42-
return a == b;
38+
inline std::string to_lower_ascii(std::string s) {
39+
for (char& c : s)
40+
c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
41+
return s;
42+
}
43+
44+
inline bool is_word_char(unsigned char c) {
45+
return std::isalnum(c) || c == '_';
4346
}
4447

4548
inline bool contains_string(const std::string& text,
@@ -48,17 +51,25 @@ inline bool contains_string(const std::string& text,
4851
return h.find(n) != std::string::npos;
4952
}
5053

54+
inline bool ends_with(const std::string& s, const std::string& suf,
55+
unsigned threshold) {
56+
if (s.size() < suf.size()) return false;
57+
std::string a = tolower(s.substr(s.size() - (suf.size() + threshold)));
58+
std::string b = tolower(suf);
59+
return threshold == 0 ? a == b : contains_string(a, b);
60+
}
61+
62+
inline bool starts_with(const std::string& s, const std::string& prf,
63+
unsigned threshold) {
64+
if (s.size() < prf.size()) return false;
65+
std::string a = tolower(s.substr(0, prf.size() + threshold));
66+
std::string b = tolower(prf);
67+
return threshold == 0 ? a == b : contains_string(a, b);
68+
}
69+
5170
inline bool contains_word(const std::string& text, const std::string& word) {
5271
if (word.empty()) return false;
5372

54-
auto to_lower_ascii = [](std::string s) {
55-
for (char& c : s) c = std::tolower(static_cast<unsigned char>(c));
56-
return s;
57-
};
58-
auto is_word_char = [](unsigned char c) {
59-
return std::isalnum(c) || c == '_'; // match std::regex \b notion of "word"
60-
};
61-
6273
std::string t = to_lower_ascii(text);
6374
std::string w = to_lower_ascii(word);
6475

@@ -83,6 +94,39 @@ inline bool contains_none(const std::string& text,
8394
return true;
8495
}
8596

97+
inline size_t find_containing_word(const std::string& text,
98+
const std::string& keyword,
99+
std::string& containing_word, size_t pos) {
100+
if (keyword.empty() || pos >= text.size()) return std::string::npos;
101+
102+
std::string t = to_lower_ascii(text);
103+
std::string k = to_lower_ascii(keyword);
104+
105+
if ((pos = t.find(k, pos)) == std::string::npos) return std::string::npos;
106+
107+
// Expand left to word boundary
108+
size_t start = pos;
109+
while (start > 0 && is_word_char(static_cast<unsigned char>(t[start - 1]))) {
110+
--start;
111+
}
112+
113+
// Expand right to word boundary
114+
size_t end = pos + k.size();
115+
while (end < t.size() && is_word_char(static_cast<unsigned char>(t[end]))) {
116+
++end;
117+
}
118+
119+
// Extract original (not lowercased) word
120+
containing_word = text.substr(start, end - start);
121+
return start;
122+
}
123+
124+
inline size_t find_containing_word(const std::string& text,
125+
const std::string& keyword,
126+
std::string& out_word) {
127+
return find_containing_word(text, keyword, out_word, 0);
128+
}
129+
86130
inline std::string remove_font_modifiers(const std::string& s) {
87131
std::string out;
88132
out.reserve(s.size());
@@ -115,14 +159,12 @@ inline std::string remove_font_modifiers(const std::string& s) {
115159

116160
inline std::string remove_first_line(const std::string& s) {
117161
std::size_t pos = s.find('\n');
118-
return (pos == std::string::npos) ? std::string{} : s.substr(pos + 1);
119-
// If there is no newline, removing the first line yields empty.
162+
return (pos == std::string::npos) ? std::string(s) : s.substr(pos + 1);
120163
}
121164

122165
inline std::string remove_last_line(const std::string& s) {
123166
std::size_t pos = s.rfind('\n');
124-
return (pos == std::string::npos) ? std::string{} : s.substr(0, pos);
125-
// If there is no newline, removing the last line yields empty.
167+
return (pos == std::string::npos) ? std::string(s) : s.substr(0, pos);
126168
}
127169

128170
// Returns the 8 transformations as an array of strings.

0 commit comments

Comments
 (0)