| 2415 | } |
| 2416 | |
| 2417 | void llm_graph_context::build_sampling() const { |
| 2418 | if (samplers.empty() || !res->t_logits) { |
| 2419 | return; |
| 2420 | } |
| 2421 | |
| 2422 | std::array<ggml_tensor *, 2> outs; |
| 2423 | outs[0] = res->t_logits; |
| 2424 | |
| 2425 | auto inp_sampling = std::make_unique<llm_graph_input_sampling>(samplers); |
| 2426 | res->add_input(std::move(inp_sampling)); |
| 2427 | |
| 2428 | std::map<llama_seq_id, int32_t> seq_to_logit_row; |
| 2429 | int32_t logit_row_idx = 0; |
| 2430 | |
| 2431 | for (uint32_t i = 0; i < ubatch.n_tokens; i++) { |
| 2432 | if (ubatch.output[i]) { |
| 2433 | llama_seq_id seq_id = ubatch.seq_id[i][0]; |
| 2434 | seq_to_logit_row[seq_id] = logit_row_idx; |
| 2435 | logit_row_idx++; |
| 2436 | } |
| 2437 | } |
| 2438 | |
| 2439 | // res->t_logits will contain logits for all tokens that want the logits calculated (logits=1 or output=1) |
| 2440 | GGML_ASSERT(res->t_logits != nullptr && "missing t_logits tensor"); |
| 2441 | |
| 2442 | // add a dummy row of logits |
| 2443 | // this trick makes the graph static, regardless of which samplers are activated |
| 2444 | // this is important in order to minimize graph reallocations |
| 2445 | ggml_tensor * logits_t = ggml_pad(ctx0, res->t_logits, 0, 1, 0, 0); |
| 2446 | |
| 2447 | for (const auto & [seq_id, sampler] : samplers) { |
| 2448 | const auto it = seq_to_logit_row.find(seq_id); |
| 2449 | |
| 2450 | // inactive samplers always work on the first row |
| 2451 | const auto row_idx = it != seq_to_logit_row.end() ? it->second : 0; |
| 2452 | const int i_out = it != seq_to_logit_row.end() ? 1 : 0; |
| 2453 | |
| 2454 | ggml_tensor * logits_seq = ggml_view_1d(ctx0, logits_t, logits_t->ne[0], row_idx * logits_t->nb[1]); |
| 2455 | ggml_format_name(logits_seq, "logits_seq_%d", seq_id); |
| 2456 | |
| 2457 | struct llama_sampler_data data = { |
| 2458 | /*.logits =*/ logits_seq, |
| 2459 | /*.probs =*/ nullptr, |
| 2460 | /*.sampled =*/ nullptr, |
| 2461 | /*.candidates =*/ nullptr, |
| 2462 | }; |
| 2463 | |
| 2464 | assert(sampler->iface->backend_apply); |
| 2465 | sampler->iface->backend_apply(sampler, ctx0, gf, &data); |
| 2466 | |
| 2467 | if (data.sampled != nullptr) { |
| 2468 | res->t_sampled[seq_id] = data.sampled; |
| 2469 | outs[1] = data.sampled; |
| 2470 | ggml_build_forward_select(gf, outs.data(), outs.size(), i_out); |
| 2471 | } |
| 2472 | |
| 2473 | if (data.probs != nullptr) { |
| 2474 | res->t_sampled_probs[seq_id] = data.probs; |
no test coverage detected