| 148 | } |
| 149 | |
| 150 | AceStepLatents AceStepVAEEncodeGraph::encode( |
| 151 | const runtime::AudioBuffer & audio, |
| 152 | uint64_t seed, |
| 153 | uint64_t & noise_offset, |
| 154 | const std::vector<float> * noise_override) const { |
| 155 | const auto total_start = Clock::now(); |
| 156 | const auto & config = assets_->config.vae; |
| 157 | if (audio.sample_rate != config.sample_rate || |
| 158 | audio.channels != config.audio_channels || |
| 159 | audio.samples.empty()) { |
| 160 | throw std::runtime_error("ACE-Step VAE encoder audio shape mismatch"); |
| 161 | } |
| 162 | const int64_t request_audio_frames = |
| 163 | static_cast<int64_t>(audio.samples.size() / static_cast<size_t>(audio.channels)); |
| 164 | if (request_audio_frames <= 0 || request_audio_frames > audio_frames_) { |
| 165 | throw std::runtime_error("ACE-Step VAE encoder frame count is invalid"); |
| 166 | } |
| 167 | |
| 168 | const auto input_start = Clock::now(); |
| 169 | bct_input_scratch_.resize(static_cast<size_t>(audio_frames_ * audio.channels)); |
| 170 | if (request_audio_frames < audio_frames_) { |
| 171 | std::fill(bct_input_scratch_.begin(), bct_input_scratch_.end(), 0.0F); |
| 172 | } |
| 173 | for (int channel = 0; channel < audio.channels; ++channel) { |
| 174 | float * channel_input = bct_input_scratch_.data() + static_cast<size_t>(channel * audio_frames_); |
| 175 | for (int64_t frame = 0; frame < request_audio_frames; ++frame) { |
| 176 | channel_input[static_cast<size_t>(frame)] = |
| 177 | audio.samples[static_cast<size_t>(frame * audio.channels + channel)]; |
| 178 | } |
| 179 | } |
| 180 | core::write_tensor_f32(input_value_, bct_input_scratch_); |
| 181 | core::set_backend_threads(backend_, threads_); |
| 182 | engine::debug::timing_log_scalar( |
| 183 | "ace_step.vae.encode.input_upload_ms", |
| 184 | engine::debug::elapsed_ms(input_start, Clock::now())); |
| 185 | const auto compute_start = Clock::now(); |
| 186 | const ggml_status status = engine::core::compute_backend_graph(backend_, graph_); |
| 187 | ggml_backend_synchronize(backend_); |
| 188 | if (status != GGML_STATUS_SUCCESS) { |
| 189 | throw std::runtime_error("ACE-Step VAE encoder graph compute failed"); |
| 190 | } |
| 191 | engine::debug::timing_log_scalar( |
| 192 | "ace_step.vae.encode.graph.compute_ms", |
| 193 | engine::debug::elapsed_ms(compute_start, Clock::now())); |
| 194 | |
| 195 | const auto output_start = Clock::now(); |
| 196 | bct_output_scratch_.resize(static_cast<size_t>(latent_frames_ * config.encoder_hidden_size)); |
| 197 | core::read_tensor_f32_into(output_value_.tensor, bct_output_scratch_); |
| 198 | const int64_t request_latent_frames = |
| 199 | std::max<int64_t>(1, request_audio_frames / audio_frames_per_latent(config)); |
| 200 | if (request_latent_frames > latent_frames_) { |
| 201 | throw std::runtime_error("ACE-Step VAE encoder request latent length exceeds graph capacity"); |
| 202 | } |
| 203 | AceStepLatents out; |
| 204 | out.frames = request_latent_frames; |
| 205 | out.channels = latent_channels_; |
| 206 | out.values.resize(static_cast<size_t>(out.frames * out.channels), 0.0F); |
| 207 | const size_t latent_value_count = static_cast<size_t>(out.frames * out.channels); |
no test coverage detected