| 554 | } |
| 555 | |
| 556 | std::vector<VibeVoiceDecoderPrefillOutput> run_batch(const std::vector<std::vector<float>> & embeddings) { |
| 557 | const auto & config = runtime_->assets().config.decoder; |
| 558 | if (static_cast<int64_t>(embeddings.size()) != batch_size_) { |
| 559 | throw std::runtime_error("VibeVoice decoder prefill embedding batch size mismatch"); |
| 560 | } |
| 561 | const size_t per_sample = static_cast<size_t>(prompt_steps_ * config.hidden_size); |
| 562 | for (const auto & sample : embeddings) { |
| 563 | if (sample.size() != per_sample) { |
| 564 | throw std::runtime_error("VibeVoice decoder prefill embedding size mismatch"); |
| 565 | } |
| 566 | } |
| 567 | if (layerwise_) { |
| 568 | return run_batch_layerwise(embeddings); |
| 569 | } |
| 570 | std::vector<float> input(static_cast<size_t>(batch_size_) * per_sample, 0.0F); |
| 571 | for (int64_t batch = 0; batch < batch_size_; ++batch) { |
| 572 | const auto & sample = embeddings[static_cast<size_t>(batch)]; |
| 573 | std::copy( |
| 574 | sample.begin(), |
| 575 | sample.end(), |
| 576 | input.begin() + static_cast<std::ptrdiff_t>(batch * static_cast<int64_t>(per_sample))); |
| 577 | } |
| 578 | ggml_backend_tensor_set(input_, input.data(), 0, input.size() * sizeof(float)); |
| 579 | core::set_backend_threads(runtime_->backend(), runtime_->threads()); |
| 580 | const ggml_status status = engine::core::compute_backend_graph(runtime_->backend(), graph_); |
| 581 | ggml_backend_synchronize(runtime_->backend()); |
| 582 | if (status != GGML_STATUS_SUCCESS) { |
| 583 | throw std::runtime_error("VibeVoice decoder prefill graph compute failed"); |
| 584 | } |
| 585 | |
| 586 | const size_t logits_per_sample = static_cast<size_t>(config.vocab_size); |
| 587 | const size_t hidden_per_sample = static_cast<size_t>(config.hidden_size); |
| 588 | std::vector<float> logits(static_cast<size_t>(batch_size_) * logits_per_sample, 0.0F); |
| 589 | std::vector<float> hidden(static_cast<size_t>(batch_size_) * hidden_per_sample, 0.0F); |
| 590 | ggml_backend_tensor_get(logits_output_, logits.data(), 0, logits.size() * sizeof(float)); |
| 591 | ggml_backend_tensor_get(hidden_output_, hidden.data(), 0, hidden.size() * sizeof(float)); |
| 592 | |
| 593 | std::vector<VibeVoiceDecoderPrefillOutput> out(static_cast<size_t>(batch_size_)); |
| 594 | for (int64_t batch = 0; batch < batch_size_; ++batch) { |
| 595 | auto & sample = out[static_cast<size_t>(batch)]; |
| 596 | sample.result.logits.vocab_size = config.vocab_size; |
| 597 | sample.result.logits.values.assign( |
| 598 | logits.begin() + static_cast<std::ptrdiff_t>(batch * static_cast<int64_t>(logits_per_sample)), |
| 599 | logits.begin() + static_cast<std::ptrdiff_t>((batch + 1) * static_cast<int64_t>(logits_per_sample))); |
| 600 | sample.result.last_hidden.dims = config.hidden_size; |
| 601 | sample.result.last_hidden.values.assign( |
| 602 | hidden.begin() + static_cast<std::ptrdiff_t>(batch * static_cast<int64_t>(hidden_per_sample)), |
| 603 | hidden.begin() + static_cast<std::ptrdiff_t>((batch + 1) * static_cast<int64_t>(hidden_per_sample))); |
| 604 | sample.state.current_end = prompt_steps_; |
| 605 | sample.state.layers.resize(keys_.size()); |
| 606 | } |
| 607 | |
| 608 | const size_t layer_values = static_cast<size_t>( |
| 609 | prompt_steps_ * config.num_key_value_heads * require_head_dim(config)); |
| 610 | for (size_t layer = 0; layer < keys_.size(); ++layer) { |
| 611 | std::vector<float> key_values(static_cast<size_t>(batch_size_) * layer_values, 0.0F); |
| 612 | std::vector<float> value_values(static_cast<size_t>(batch_size_) * layer_values, 0.0F); |
| 613 | ggml_backend_tensor_get(keys_[layer], key_values.data(), 0, key_values.size() * sizeof(float)); |
no test coverage detected