Spaces:
Running
Running
| """Batch-conditioning orchestration helpers for handler decomposition.""" | |
| from typing import Any, Dict, List, Optional, Union | |
| import torch | |
| from acestep.constants import DEFAULT_DIT_INSTRUCTION | |
| class ConditioningBatchMixin: | |
| """Mixin containing batch preparation orchestration. | |
| Depends on host members: | |
| - Attributes: ``device``, ``dtype``, ``sample_rate``. | |
| - Methods: ``_normalize_audio_code_hints``, ``_create_fallback_vocal_languages``, | |
| ``_parse_metas``, ``_normalize_instructions``, ``_prepare_target_latents_and_wavs``, | |
| ``_build_chunk_masks_and_src_latents``, ``_prepare_precomputed_lm_hints``, | |
| ``_prepare_text_conditioning_inputs``. | |
| """ | |
| def _prepare_batch( | |
| self, | |
| captions: List[str], | |
| lyrics: List[str], | |
| keys: Optional[List[str]] = None, | |
| target_wavs: Optional[torch.Tensor] = None, | |
| refer_audios: Optional[List[List[torch.Tensor]]] = None, | |
| metas: Optional[List[Union[str, Dict[str, Any]]]] = None, | |
| vocal_languages: Optional[List[str]] = None, | |
| repainting_start: Optional[List[float]] = None, | |
| repainting_end: Optional[List[float]] = None, | |
| instructions: Optional[List[str]] = None, | |
| audio_code_hints: Optional[List[Optional[str]]] = None, | |
| audio_cover_strength: float = 1.0, | |
| cover_noise_strength: float = 0.0, | |
| ) -> Dict[str, Any]: | |
| """Prepare model-ready conditioning batch tensors and metadata. | |
| Args: | |
| captions: Per-item captions. | |
| lyrics: Per-item lyric strings. | |
| keys: Optional per-item keys. | |
| target_wavs: Target audio tensor batch. | |
| refer_audios: Optional nested reference-audio tensors. | |
| metas: Optional per-item metadata strings/dicts. | |
| vocal_languages: Optional per-item vocal language codes. | |
| repainting_start: Optional repaint start times. | |
| repainting_end: Optional repaint end times. | |
| instructions: Optional per-item generation instructions. | |
| audio_code_hints: Optional per-item serialized audio-code hints. | |
| audio_cover_strength: Blend factor for cover/non-cover conditioning. | |
| Returns: | |
| Batch dictionary containing padded tensors and conditioning metadata | |
| consumed by ``preprocess_batch`` and downstream generation. | |
| """ | |
| batch_size = len(captions) | |
| audio_code_hints = self._normalize_audio_code_hints(audio_code_hints, batch_size) | |
| if refer_audios is None: | |
| refer_audios = [[torch.zeros(2, 30 * self.sample_rate)] for _ in range(batch_size)] | |
| for ii, refer_audio_list in enumerate(refer_audios): | |
| if isinstance(refer_audio_list, list): | |
| for idx, _ in enumerate(refer_audio_list): | |
| refer_audio_list[idx] = refer_audio_list[idx].to(self.device).to(self._get_vae_dtype()) | |
| elif isinstance(refer_audio_list, torch.Tensor): | |
| refer_audios[ii] = refer_audios[ii].to(self.device) | |
| if vocal_languages is None: | |
| vocal_languages = self._create_fallback_vocal_languages(batch_size) | |
| parsed_metas = self._parse_metas(metas) | |
| target_wavs, target_latents, latent_masks, max_latent_length, silence_latent_tiled = ( | |
| self._prepare_target_latents_and_wavs(batch_size, target_wavs, audio_code_hints) | |
| ) | |
| wav_lengths = torch.tensor([target_wavs.shape[-1]] * batch_size, dtype=torch.long) | |
| instructions = self._normalize_instructions(instructions, batch_size, DEFAULT_DIT_INSTRUCTION) | |
| chunk_masks, spans, is_covers, src_latents = self._build_chunk_masks_and_src_latents( | |
| batch_size, | |
| max_latent_length, | |
| instructions, | |
| audio_code_hints, | |
| target_wavs, | |
| target_latents, | |
| repainting_start, | |
| repainting_end, | |
| silence_latent_tiled, | |
| ) | |
| precomputed_lm_hints_25hz = self._prepare_precomputed_lm_hints( | |
| batch_size, audio_code_hints, max_latent_length, silence_latent_tiled | |
| ) | |
| ( | |
| text_inputs, | |
| padded_text_token_idss, | |
| padded_text_attention_masks, | |
| padded_lyric_token_idss, | |
| padded_lyric_attention_masks, | |
| padded_non_cover_text_input_ids, | |
| padded_non_cover_text_attention_masks, | |
| ) = self._prepare_text_conditioning_inputs( | |
| batch_size, | |
| instructions, | |
| captions, | |
| lyrics, | |
| parsed_metas, | |
| vocal_languages, | |
| audio_cover_strength, | |
| ) | |
| batch = { | |
| "keys": keys, | |
| "target_wavs": target_wavs.to(self.device), | |
| "refer_audioss": refer_audios, | |
| "wav_lengths": wav_lengths.to(self.device), | |
| "captions": captions, | |
| "lyrics": lyrics, | |
| "metas": parsed_metas, | |
| "vocal_languages": vocal_languages, | |
| "target_latents": target_latents, | |
| "src_latents": src_latents, | |
| "latent_masks": latent_masks, | |
| "chunk_masks": chunk_masks, | |
| "spans": spans, | |
| "text_inputs": text_inputs, | |
| "text_token_idss": padded_text_token_idss, | |
| "text_attention_masks": padded_text_attention_masks, | |
| "lyric_token_idss": padded_lyric_token_idss, | |
| "lyric_attention_masks": padded_lyric_attention_masks, | |
| "is_covers": is_covers, | |
| "precomputed_lm_hints_25Hz": precomputed_lm_hints_25hz, | |
| "non_cover_text_input_ids": padded_non_cover_text_input_ids, | |
| "non_cover_text_attention_masks": padded_non_cover_text_attention_masks, | |
| } | |
| for k, v in batch.items(): | |
| if isinstance(v, torch.Tensor): | |
| batch[k] = v.to(self.device) | |
| if torch.is_floating_point(batch[k]): | |
| batch[k] = batch[k].to(self.dtype) | |
| return batch | |