Streaming encode: uses cache for correct context between frames.
(
&self,
audio: &Tensor,
cache: &mut super::vae_decoder::StreamingConvCache,
)
| 360 | |
| 361 | /// Streaming encode: uses cache for correct context between frames. |
| 362 | pub fn encode_streaming( |
| 363 | &self, |
| 364 | audio: &Tensor, |
| 365 | cache: &mut super::vae_decoder::StreamingConvCache, |
| 366 | ) -> Result<Tensor> { |
| 367 | let x = if audio.rank() == 2 { |
| 368 | audio.unsqueeze(1)? |
| 369 | } else { |
| 370 | audio.clone() |
| 371 | }; |
| 372 | |
| 373 | cache.reset_counter(); |
| 374 | let mut h = x; |
| 375 | |
| 376 | for (i, (conv, stage)) in self |
| 377 | .downsample_convs |
| 378 | .iter() |
| 379 | .zip(self.stages.iter()) |
| 380 | .enumerate() |
| 381 | { |
| 382 | // Streaming: use cached context instead of zero-padding |
| 383 | let ctx_size = self.downsample_paddings[i]; |
| 384 | let (slot, is_first) = cache.take_slot(); |
| 385 | let context = if is_first { |
| 386 | Tensor::zeros((h.dim(0)?, h.dim(1)?, ctx_size), h.dtype(), h.device())? |
| 387 | } else { |
| 388 | cache.get(slot).unwrap().clone() |
| 389 | }; |
| 390 | let padded = Tensor::cat(&[&context, &h], 2)?; |
| 391 | |
| 392 | // Update cache: last ctx_size samples of padded |
| 393 | let plen = padded.dim(2)?; |
| 394 | let start = plen.saturating_sub(ctx_size); |
| 395 | cache.set(slot, padded.narrow(2, start, plen - start)?); |
| 396 | |
| 397 | h = self.backend.conv1d(&padded, &conv.weight, conv.bias.as_ref(), conv.padding, conv.stride, conv.dilation, conv.groups)?; |
| 398 | h = stage.forward_cached(&h, cache)?; |
| 399 | } |
| 400 | |
| 401 | // Head conv: streaming context |
| 402 | let (slot, is_first) = cache.take_slot(); |
| 403 | let ctx = if is_first { |
| 404 | Tensor::zeros((h.dim(0)?, h.dim(1)?, 6), h.dtype(), h.device())? |
| 405 | } else { |
| 406 | cache.get(slot).unwrap().clone() |
| 407 | }; |
| 408 | let padded = Tensor::cat(&[&ctx, &h], 2)?; |
| 409 | let plen = padded.dim(2)?; |
| 410 | cache.set(slot, padded.narrow(2, plen.saturating_sub(6), 6.min(plen))?); |
| 411 | h = self.backend.conv1d(&padded, &self.head_conv.weight, self.head_conv.bias.as_ref(), self.head_conv.padding, self.head_conv.stride, self.head_conv.dilation, self.head_conv.groups)?; |
| 412 | |
| 413 | h.transpose(1, 2) |
| 414 | } |
| 415 | } |
| 416 | |
| 417 | #[cfg(test)] |
no test coverage detected