| 698 | #define K_TOKEN_CHUNK 4 |
| 699 | |
| 700 | static void compute_logprobs(const float * batch_logits, int n_vocab, std::vector<std::thread>& workers, |
| 701 | const std::vector<std::pair<size_t, llama_token>>& eval_pairs, std::vector<float>& eval_results) { |
| 702 | if (eval_results.size() != eval_pairs.size()) { |
| 703 | eval_results.resize(eval_pairs.size()); |
| 704 | } |
| 705 | if (eval_pairs.empty()) { |
| 706 | return; |
| 707 | } |
| 708 | |
| 709 | size_t max_threads = std::min((eval_pairs.size() + K_TOKEN_CHUNK - 1)/K_TOKEN_CHUNK, workers.size()); |
| 710 | |
| 711 | std::atomic<int> counter(0); |
| 712 | auto compute = [&counter, &eval_pairs, &eval_results, batch_logits, n_vocab] () { |
| 713 | float local_logprobs[K_TOKEN_CHUNK]; |
| 714 | while (true) { |
| 715 | const size_t first = counter.fetch_add(K_TOKEN_CHUNK, std::memory_order_relaxed); |
| 716 | if (first >= eval_results.size()) { |
| 717 | break; |
| 718 | } |
| 719 | const size_t last = std::min(first + K_TOKEN_CHUNK, eval_results.size()); |
| 720 | for (size_t i = first; i < last; ++i) { |
| 721 | const auto * logits = batch_logits + eval_pairs[i].first * n_vocab; |
| 722 | float max_logit = logits[0]; |
| 723 | for (int j = 1; j < n_vocab; ++j) { |
| 724 | max_logit = std::max(max_logit, logits[j]); |
| 725 | } |
| 726 | float sum_p = 0.f; |
| 727 | for (int j = 0; j < n_vocab; ++j) { |
| 728 | sum_p += expf(logits[j] - max_logit); |
| 729 | } |
| 730 | local_logprobs[i - first] = logits[eval_pairs[i].second] - max_logit - std::log(sum_p); |
| 731 | } |
| 732 | std::memcpy(eval_results.data() + first, local_logprobs, (last - first)*sizeof(float)); |
| 733 | } |
| 734 | }; |
| 735 | |
| 736 | for (size_t it = 0; it < max_threads; ++it) { |
| 737 | workers[it] = std::thread(compute); |
| 738 | } |
| 739 | for (size_t it = 0; it < max_threads; ++it) { |
| 740 | workers[it].join(); |
| 741 | } |
| 742 | } |
| 743 | |
| 744 | static void hellaswag_score(llama_context * ctx, const common_params & params) { |
| 745 | const llama_model * model = llama_get_model(ctx); |
no test coverage detected