| 684 | } |
| 685 | |
| 686 | HeartMuLaBackbonePrefillOutput run(const std::vector<float> & embeddings) { |
| 687 | allocate_workspace(); |
| 688 | const auto & config = runtime_->assets().mula_config.backbone; |
| 689 | const int64_t head_dim = require_head_dim(config); |
| 690 | if (static_cast<int64_t>(embeddings.size()) != batch_size_ * steps_ * config.embed_dim) { |
| 691 | throw std::runtime_error("HeartMuLa backbone prefill embedding payload size mismatch"); |
| 692 | } |
| 693 | ggml_backend_tensor_set(input_, embeddings.data(), 0, embeddings.size() * sizeof(float)); |
| 694 | core::set_backend_threads(runtime_->backend(), runtime_->threads()); |
| 695 | const ggml_status status = engine::core::compute_backend_graph(runtime_->backend(), graph_); |
| 696 | ggml_backend_synchronize(runtime_->backend()); |
| 697 | if (status != GGML_STATUS_SUCCESS) { |
| 698 | throw std::runtime_error("HeartMuLa backbone prefill graph compute failed"); |
| 699 | } |
| 700 | HeartMuLaBackbonePrefillOutput out; |
| 701 | out.result.logits.vocab_size = runtime_->assets().mula_config.audio_vocab_size; |
| 702 | out.result.logits.values.resize(static_cast<size_t>(batch_size_ * out.result.logits.vocab_size)); |
| 703 | ggml_backend_tensor_get( |
| 704 | logits_output_, |
| 705 | out.result.logits.values.data(), |
| 706 | 0, |
| 707 | out.result.logits.values.size() * sizeof(float)); |
| 708 | out.result.last_hidden.dims = config.embed_dim; |
| 709 | out.result.last_hidden.values.resize(static_cast<size_t>(batch_size_ * config.embed_dim)); |
| 710 | ggml_backend_tensor_get( |
| 711 | hidden_output_, |
| 712 | out.result.last_hidden.values.data(), |
| 713 | 0, |
| 714 | out.result.last_hidden.values.size() * sizeof(float)); |
| 715 | out.state.current_end = steps_; |
| 716 | out.state.layers.resize(keys_.size()); |
| 717 | const size_t layer_values = static_cast<size_t>(steps_ * layer_step_elems_); |
| 718 | for (size_t layer = 0; layer < keys_.size(); ++layer) { |
| 719 | auto & state_layer = out.state.layers[layer]; |
| 720 | state_layer.valid_steps = steps_; |
| 721 | std::vector<float> key_values(layer_values); |
| 722 | std::vector<float> value_values(layer_values); |
| 723 | ggml_backend_tensor_get(keys_[layer], key_values.data(), 0, key_values.size() * sizeof(float)); |
| 724 | ggml_backend_tensor_get(values_[layer], value_values.data(), 0, value_values.size() * sizeof(float)); |
| 725 | state_layer.key = flatten_prefill_cache_by_step( |
| 726 | key_values, |
| 727 | batch_size_, |
| 728 | steps_, |
| 729 | config.num_kv_heads, |
| 730 | head_dim); |
| 731 | state_layer.value = flatten_prefill_cache_by_step( |
| 732 | value_values, |
| 733 | batch_size_, |
| 734 | steps_, |
| 735 | config.num_kv_heads, |
| 736 | head_dim); |
| 737 | } |
| 738 | return out; |
| 739 | } |
| 740 | |
| 741 | private: |
| 742 | void allocate_workspace() { |
nothing calls this directly
no test coverage detected