#include <random>
#include <sstream>
#include <fstream>
+#include <limits>
json format_error_response(const std::string & message, const enum error_type type) {
std::string type_str;
// other utils
//
-std::vector<llama_token_data> get_token_probabilities(llama_context * ctx, int idx) {
+std::vector<llama_token_data> get_token_probabilities(llama_context * ctx, int idx, size_t n_top) {
std::vector<llama_token_data> cur;
const auto * logits = llama_get_logits_ith(ctx, idx);
}
}
- // sort tokens by logits
- std::sort(cur.begin(), cur.end(), [](const llama_token_data & a, const llama_token_data & b) {
- return a.logit > b.logit;
- });
+ // sort tokens by logits (partial: only the leading `n_top` need ordering)
+ if (n_top > cur.size()) {
+ n_top = cur.size();
+ }
+ if (n_top > 0) {
+ std::partial_sort(cur.begin(), cur.begin() + n_top, cur.end(),
+ [](const llama_token_data & a, const llama_token_data & b) {
+ return a.logit > b.logit;
+ });
+ }
// apply softmax
- float max_l = cur[0].logit;
+ float max_l = -std::numeric_limits<float>::infinity();
+ if (n_top > 0) {
+ max_l = cur[0].logit; // partial_sort guarantees the absolute maximum is at index 0
+ } else {
+ for (const auto & t : cur) {
+ max_l = std::max(max_l, t.logit);
+ }
+ }
float cum_sum = 0.0f;
- for (size_t i = 0; i < cur.size(); ++i) {
- float p = expf(cur[i].logit - max_l);
- cur[i].p = p;
+ for (auto & t : cur) {
+ float p = expf(t.logit - max_l);
+ t.p = p;
cum_sum += p;
}
- for (size_t i = 0; i < cur.size(); ++i) {
- cur[i].p /= cum_sum;
+ for (auto & t : cur) {
+ t.p /= cum_sum;
}
return cur;
});
}
} else {
- // TODO: optimize this with min-p optimization
- std::vector<llama_token_data> cur = get_token_probabilities(ctx_tgt, idx);
+ std::vector<llama_token_data> cur = get_token_probabilities(ctx_tgt, idx, n_probs_request);
const size_t max_probs = cur.size();
const size_t n_probs = std::min(max_probs, n_probs_request);