| 8435 | } |
| 8436 | |
| 8437 | void llama_sample_grammar(struct llama_context * ctx, llama_token_data_array * candidates, const struct llama_grammar * grammar) { |
| 8438 | GGML_ASSERT(ctx); |
| 8439 | const int64_t t_start_sample_us = ggml_time_us(); |
| 8440 | |
| 8441 | bool allow_eos = false; |
| 8442 | for (const auto & stack : grammar->stacks) { |
| 8443 | if (stack.empty()) { |
| 8444 | allow_eos = true; |
| 8445 | break; |
| 8446 | } |
| 8447 | } |
| 8448 | |
| 8449 | const llama_token eos = llama_token_eos(&ctx->model); |
| 8450 | |
| 8451 | std::vector<std::pair<std::vector<uint32_t>, llama_partial_utf8>> candidates_decoded; |
| 8452 | std::vector<llama_grammar_candidate> candidates_grammar; |
| 8453 | |
| 8454 | for (size_t i = 0; i < candidates->size; ++i) { |
| 8455 | const llama_token id = candidates->data[i].id; |
| 8456 | const std::string piece = llama_token_to_piece(ctx, id); |
| 8457 | if (id == eos) { |
| 8458 | if (!allow_eos) { |
| 8459 | candidates->data[i].logit = -INFINITY; |
| 8460 | } |
| 8461 | } else if (piece.empty() || piece[0] == 0) { |
| 8462 | candidates->data[i].logit = -INFINITY; |
| 8463 | } else { |
| 8464 | candidates_decoded.push_back(decode_utf8(piece.c_str(), grammar->partial_utf8)); |
| 8465 | candidates_grammar.push_back({ i, candidates_decoded.back().first.data(), candidates_decoded.back().second }); |
| 8466 | } |
| 8467 | } |
| 8468 | |
| 8469 | const auto rejects = llama_grammar_reject_candidates(grammar->rules, grammar->stacks, candidates_grammar); |
| 8470 | for (const auto & reject : rejects) { |
| 8471 | candidates->data[reject.index].logit = -INFINITY; |
| 8472 | } |
| 8473 | |
| 8474 | ctx->t_sample_us += ggml_time_us() - t_start_sample_us; |
| 8475 | } |
| 8476 | |
| 8477 | static void llama_log_softmax(float * array, size_t size) { |
| 8478 | float max_l = *std::max_element(array, array + size); |
no test coverage detected