| 1583 | } |
| 1584 | |
| 1585 | HeartMuLaMergedEmbeddings run(const HeartMuLaFrameEmbeddingInputs & inputs) { |
| 1586 | allocate_workspace(); |
| 1587 | const auto & config = runtime_->assets().mula_config; |
| 1588 | const size_t audio_count = static_cast<size_t>(batch_size_ * steps_ * config.audio_num_codebooks); |
| 1589 | const size_t text_count = static_cast<size_t>(batch_size_ * steps_); |
| 1590 | if (inputs.batch_size != batch_size_ || inputs.steps != steps_) { |
| 1591 | throw std::runtime_error("HeartMuLa frame embedding input shape mismatch"); |
| 1592 | } |
| 1593 | if (inputs.audio_token_ids.size() != audio_count || inputs.audio_mask.size() != audio_count || |
| 1594 | inputs.text_token_ids.size() != text_count || inputs.text_cond_mask.size() != text_count || |
| 1595 | inputs.text_uncond_mask.size() != text_count) { |
| 1596 | throw std::runtime_error("HeartMuLa frame embedding input payload size mismatch"); |
| 1597 | } |
| 1598 | ggml_backend_tensor_set(audio_token_ids_, inputs.audio_token_ids.data(), 0, audio_count * sizeof(int32_t)); |
| 1599 | ggml_backend_tensor_set(text_token_ids_, inputs.text_token_ids.data(), 0, text_count * sizeof(int32_t)); |
| 1600 | ggml_backend_tensor_set(audio_mask_, inputs.audio_mask.data(), 0, audio_count * sizeof(float)); |
| 1601 | ggml_backend_tensor_set(text_cond_mask_, inputs.text_cond_mask.data(), 0, text_count * sizeof(float)); |
| 1602 | ggml_backend_tensor_set(text_uncond_mask_, inputs.text_uncond_mask.data(), 0, text_count * sizeof(float)); |
| 1603 | if (apply_muq_) { |
| 1604 | if (!inputs.apply_muq || inputs.muq_row < 0 || inputs.muq_row >= steps_) { |
| 1605 | throw std::runtime_error("HeartMuLa frame embedding MuQ row is invalid"); |
| 1606 | } |
| 1607 | if (inputs.muq_embed.size() != static_cast<size_t>(batch_size_ * config.muq_dim) || |
| 1608 | inputs.muq_cond_mask.size() != static_cast<size_t>(batch_size_) || |
| 1609 | inputs.muq_uncond_mask.size() != static_cast<size_t>(batch_size_)) { |
| 1610 | throw std::runtime_error("HeartMuLa frame embedding MuQ payload size mismatch"); |
| 1611 | } |
| 1612 | const int32_t row = static_cast<int32_t>(inputs.muq_row); |
| 1613 | ggml_backend_tensor_set(muq_embed_, inputs.muq_embed.data(), 0, inputs.muq_embed.size() * sizeof(float)); |
| 1614 | ggml_backend_tensor_set(muq_cond_mask_, inputs.muq_cond_mask.data(), 0, inputs.muq_cond_mask.size() * sizeof(float)); |
| 1615 | ggml_backend_tensor_set(muq_uncond_mask_, inputs.muq_uncond_mask.data(), 0, inputs.muq_uncond_mask.size() * sizeof(float)); |
| 1616 | ggml_backend_tensor_set(muq_row_, &row, 0, sizeof(int32_t)); |
| 1617 | } else if (inputs.apply_muq) { |
| 1618 | throw std::runtime_error("HeartMuLa frame embedding graph was built without MuQ support"); |
| 1619 | } |
| 1620 | core::set_backend_threads(runtime_->backend(), runtime_->threads()); |
| 1621 | const ggml_status status = engine::core::compute_backend_graph(runtime_->backend(), graph_); |
| 1622 | ggml_backend_synchronize(runtime_->backend()); |
| 1623 | if (status != GGML_STATUS_SUCCESS) { |
| 1624 | throw std::runtime_error("HeartMuLa frame embedding graph compute failed"); |
| 1625 | } |
| 1626 | HeartMuLaMergedEmbeddings out; |
| 1627 | out.batch_size = batch_size_; |
| 1628 | out.steps = steps_; |
| 1629 | out.dims = config.backbone.embed_dim; |
| 1630 | out.values.resize(static_cast<size_t>(batch_size_ * steps_ * config.backbone.embed_dim)); |
| 1631 | ggml_backend_tensor_get(output_, out.values.data(), 0, out.values.size() * sizeof(float)); |
| 1632 | return out; |
| 1633 | } |
| 1634 | |
| 1635 | private: |
| 1636 | void allocate_workspace() { |
nothing calls this directly
no test coverage detected