37#include <nlohmann/json.hpp>
61 for (
size_t p = 0;
p < ids.size(); ++
p) {
62 const int id = ids[
p];
63 if (
id < 0 ||
static_cast<size_t>(
id) >=
m.vocab +
m.state_k)
64 return "id " + std::to_string(
id) +
" at position " + std::to_string(
p) +
" is out of range";
65 if (
static_cast<size_t>(
id) >=
m.vocab) {
66 if (!
closed ||
static_cast<size_t>(
id) !=
m.vocab)
67 return "state id " + std::to_string(
id) +
" at position " + std::to_string(
p) +
68 " does not start a block after an <|endoftext|> that ends a reply";
69 for (
size_t j = 0;
j <
m.state_k; ++
j)
70 if (
p +
j >= ids.size() ||
static_cast<size_t>(ids[
p +
j]) !=
m.vocab +
j)
71 return "the state block at position " + std::to_string(
p) +
" is not the ids " + std::to_string(
m.vocab) +
72 " .. " + std::to_string(
m.vocab +
m.state_k - 1) +
" in order";
80 }
else if (
id ==
m.assistant) {
82 }
else if (
id ==
m.eot) {
93 if (!
body.is_object() || !
body.contains(
"requests") || !
body[
"requests"].is_array())
94 return "body must be {\"requests\": [{\"key\", \"prompt_ids\", \"continuation_ids\"}, ...]}";
95 const nlohmann::json&
reqs =
body[
"requests"];
98 for (
size_t n = 0;
n <
reqs.size(); ++
n) {
99 const nlohmann::json&
r =
reqs[
n];
100 const std::string
at =
"request " + std::to_string(
n);
101 if (!
r.is_object())
return at +
" is not an object";
102 if (!
r.contains(
"prompt_ids") || !
r.contains(
"continuation_ids"))
103 return at +
": prompt_ids and continuation_ids are required (ember scores token ids; mtstudio's text fields "
107 it.
prompt =
r[
"prompt_ids"].get<std::vector<int>>();
108 it.cont =
r[
"continuation_ids"].get<std::vector<int>>();
109 }
catch (
const nlohmann::json::exception&
e) {
110 return at +
": prompt_ids and continuation_ids must be lists of integers (" +
e.what() +
")";
112 if (
it.prompt.empty() ||
it.cont.empty())
return at +
" has an empty prompt or continuation";
113 for (
int t :
it.prompt)
114 if (
t < 0 ||
static_cast<size_t>(
t) >=
m.vocab +
m.state_k)
return at +
": prompt id out of range";
115 for (
int t :
it.cont)
116 if (
t < 0 ||
static_cast<size_t>(
t) >=
m.vocab)
return at +
": continuation id out of range";
118 std::vector<int> ids =
it.prompt;
119 ids.insert(ids.end(),
it.cont.begin(),
it.cont.end());
121 if (!
err.empty())
return at +
": " +
err;
123 it.rec = {{
"i",
n}, {
"prompt_tokens",
it.prompt.size()}, {
"continuation_ids",
it.cont}};
124 if (
r.contains(
"key"))
it.rec[
"key"] =
r[
"key"];
125 it.over_ctx =
it.prompt.size() +
it.cont.size() >
m.ctx + 1;
126 out.push_back(std::move(
it));
133inline std::vector<char>
score_banned(
const std::vector<std::string>& tokens,
size_t vocab) {
134 std::vector<char>
banned(vocab, 0);
135 const size_t n = tokens.size() < vocab ? tokens.size() : vocab;
136 for (
const char*
sp : {
"<unk>",
"<s>",
"</s>",
"<pad>"})
137 for (
size_t k = 0;
k <
n; ++
k)
138 if (tokens[
k] ==
sp) {
147inline void score_fill(nlohmann::json& rec,
const std::vector<int>&
c,
const float*
rows,
size_t V,
148 const std::vector<char>&
banned) {
149 std::vector<double>
lp;
151 lp.reserve(
c.size());
152 am.reserve(
c.size());
154 for (
size_t j = 0;
j <
c.size(); ++
j) {
159 for (
size_t k = 0;
k <
V; ++
k) {
160 const double x =
row[
k];
161 mx = std::max(
mx,
x);
163 best =
static_cast<int>(
k);
169 const double l =
static_cast<double>(
row[
static_cast<size_t>(
c[
j])]) -
mx - std::log(
z);
174 rec[
"over_ctx"] =
false;
175 rec[
"logprobs"] =
lp;
const float * p[kIrDepthSourcesMax]
std::string parse_score_body(const nlohmann::json &body, const ScoreModel &m, std::vector< ScoreItem > &out)
void score_fill(nlohmann::json &rec, const std::vector< int > &c, const float *rows, size_t V, const std::vector< char > &banned)
std::vector< char > score_banned(const std::vector< std::string > &tokens, size_t vocab)
std::string score_state_ids_error(const std::vector< int > &ids, const ScoreModel &m)
std::vector< int > prompt