OnyxMunk's picture
Upload folder using huggingface_hub
1e69a1f verified
Raw
History Blame Contribute Delete
5.47 kB
"""Task and seed helpers for handler decomposition."""
import random
from typing import List, Optional, Tuple
import torch
from loguru import logger
from acestep.constants import TASK_INSTRUCTIONS
class TaskUtilsMixin:
"""Mixin containing generation task and seed utility helpers.
Depends on host members:
- No required cross-mixin attributes for seed/instruction helpers.
"""
def prepare_seeds(
self, actual_batch_size: int, seed, use_random_seed: bool
) -> Tuple[List[int], str]:
"""Prepare per-item seeds and UI seed string."""
actual_seed_list: List[int] = []
seed_value_for_ui = ""
try:
if use_random_seed:
actual_seed_list = [random.randint(0, 2**32 - 1) for _ in range(actual_batch_size)]
seed_value_for_ui = ", ".join(str(s) for s in actual_seed_list)
else:
seed_list: List[int] = []
if isinstance(seed, str):
for s in [s.strip() for s in seed.split(",")]:
if s == "-1" or s == "":
seed_list.append(-1)
else:
try:
seed_list.append(int(float(s)))
except (ValueError, TypeError) as exc:
logger.debug(f"[prepare_seeds] Failed to parse seed value '{s}': {exc}")
seed_list.append(-1)
elif seed is None or (isinstance(seed, (int, float)) and seed < 0):
seed_list = [-1] * actual_batch_size
elif isinstance(seed, (int, float)):
seed_list = [int(seed)]
else:
seed_list = [-1] * actual_batch_size
has_single_non_negative_seed = len(seed_list) == 1 and seed_list[0] != -1
for i in range(actual_batch_size):
seed_val = seed_list[i] if i < len(seed_list) else -1
if has_single_non_negative_seed and actual_batch_size > 1 and i > 0:
actual_seed_list.append(random.randint(0, 2**32 - 1))
elif seed_val == -1:
actual_seed_list.append(random.randint(0, 2**32 - 1))
else:
actual_seed_list.append(int(seed_val))
seed_value_for_ui = ", ".join(str(s) for s in actual_seed_list)
except (TypeError, ValueError, OverflowError):
logger.exception("[prepare_seeds] Failed to prepare seeds")
actual_seed_list = [random.randint(0, 2**32 - 1) for _ in range(actual_batch_size)]
seed_value_for_ui = ", ".join(str(s) for s in actual_seed_list)
return actual_seed_list, seed_value_for_ui
def generate_instruction(
self,
task_type: str,
track_name: Optional[str] = None,
complete_track_classes: Optional[List[str]] = None,
) -> str:
"""Generate task instruction text from task type and track context."""
if task_type == "text2music":
return TASK_INSTRUCTIONS["text2music"]
if task_type == "repaint":
return TASK_INSTRUCTIONS["repaint"]
if task_type == "cover":
return TASK_INSTRUCTIONS["cover"]
if task_type == "extract":
return (
TASK_INSTRUCTIONS["extract"].format(TRACK_NAME=track_name.upper())
if track_name
else TASK_INSTRUCTIONS["extract_default"]
)
if task_type == "lego":
return (
TASK_INSTRUCTIONS["lego"].format(TRACK_NAME=track_name.upper())
if track_name
else TASK_INSTRUCTIONS["lego_default"]
)
if task_type == "complete":
if complete_track_classes and len(complete_track_classes) > 0:
track_classes_upper = [t.upper() for t in complete_track_classes]
return TASK_INSTRUCTIONS["complete"].format(
TRACK_CLASSES=" | ".join(track_classes_upper)
)
return TASK_INSTRUCTIONS["complete_default"]
return TASK_INSTRUCTIONS["text2music"]
def determine_task_type(self, task_type, audio_code_string):
"""Compute task-mode booleans for downstream generation logic."""
is_repaint_task = task_type == "repaint"
is_lego_task = task_type == "lego"
is_cover_task = task_type == "cover"
if isinstance(audio_code_string, list):
has_codes = any((c or "").strip() for c in audio_code_string)
else:
has_codes = bool(audio_code_string and str(audio_code_string).strip())
if has_codes:
is_cover_task = True
can_use_repainting = is_repaint_task or is_lego_task
return is_repaint_task, is_lego_task, is_cover_task, can_use_repainting
def create_target_wavs(self, duration_seconds: float) -> torch.Tensor:
"""Create silent stereo target audio with safe duration handling."""
try:
duration_seconds = max(0.1, round(duration_seconds, 1))
frames = int(duration_seconds * 48000)
return torch.zeros(2, frames)
except (TypeError, ValueError, OverflowError):
logger.exception("[create_target_wavs] Error creating target audio")
return torch.zeros(2, 30 * 48000)