| 621 | } |
| 622 | |
| 623 | WavlmEncoderLayerOutput encode_layers( |
| 624 | const std::vector<float> & input_values, |
| 625 | int64_t batch, |
| 626 | int64_t samples, |
| 627 | std::vector<int64_t> output_layers) { |
| 628 | std::lock_guard<std::mutex> lock(mutex_); |
| 629 | if (batch != 1) { |
| 630 | throw std::runtime_error("WavLM encoder currently requires batch size 1"); |
| 631 | } |
| 632 | if (samples <= 0 || static_cast<int64_t>(input_values.size()) != batch * samples) { |
| 633 | throw std::runtime_error("WavLM encoder input size mismatch"); |
| 634 | } |
| 635 | if (output_layers.empty()) { |
| 636 | throw std::runtime_error("WavLM encoder requires output layers"); |
| 637 | } |
| 638 | std::sort(output_layers.begin(), output_layers.end()); |
| 639 | output_layers.erase(std::unique(output_layers.begin(), output_layers.end()), output_layers.end()); |
| 640 | if (!reuse_graph_) { |
| 641 | release_graph(); |
| 642 | } |
| 643 | ensure_graph(batch, samples, output_layers); |
| 644 | const int64_t actual_tokens = wavlm_output_frames(samples); |
| 645 | if (actual_tokens > token_capacity_) { |
| 646 | throw std::runtime_error("WavLM request token count exceeds graph capacity"); |
| 647 | } |
| 648 | auto timing_start = Clock::now(); |
| 649 | std::vector<float> padded_input(static_cast<size_t>(sample_capacity_), 0.0F); |
| 650 | std::copy(input_values.begin(), input_values.end(), padded_input.begin()); |
| 651 | core::write_tensor_f32(input_, padded_input); |
| 652 | engine::debug::timing_log_scalar("framework.wavlm.input_upload_ms", engine::debug::elapsed_ms(timing_start)); |
| 653 | timing_start = Clock::now(); |
| 654 | upload_runtime_masks(samples, actual_tokens); |
| 655 | engine::debug::timing_log_scalar("framework.wavlm.mask_upload_ms", engine::debug::elapsed_ms(timing_start)); |
| 656 | timing_start = Clock::now(); |
| 657 | if (engine::core::compute_backend_graph(weights_->execution_context->backend(), graph_) != GGML_STATUS_SUCCESS) { |
| 658 | throw std::runtime_error("ggml_backend_graph_compute failed for WavLM encoder"); |
| 659 | } |
| 660 | engine::debug::timing_log_scalar("framework.wavlm.graph.compute_ms", engine::debug::elapsed_ms(timing_start)); |
| 661 | WavlmEncoderLayerOutput out; |
| 662 | out.layer_indices = output_layers_; |
| 663 | out.hidden_states.reserve(outputs_.size()); |
| 664 | timing_start = Clock::now(); |
| 665 | for (const auto & output : outputs_) { |
| 666 | auto values = core::read_tensor_f32(output.tensor); |
| 667 | values.resize(static_cast<size_t>(actual_tokens * output.shape.dims[2])); |
| 668 | out.hidden_states.push_back(std::move(values)); |
| 669 | } |
| 670 | engine::debug::timing_log_scalar("framework.wavlm.output_read_ms", engine::debug::elapsed_ms(timing_start)); |
| 671 | out.batch = batch; |
| 672 | out.tokens = actual_tokens; |
| 673 | out.hidden_size = outputs_.front().shape.dims[2]; |
| 674 | return out; |
| 675 | } |
| 676 | |
| 677 | void release_runtime_graph() { |
| 678 | std::lock_guard<std::mutex> lock(mutex_); |
nothing calls this directly
no test coverage detected