Fix downloads

This commit is contained in:
mrfakename
2025-05-09 09:47:51 -07:00
parent bfc459eb73
commit 24f6e73013
+43 -196
View File
@@ -17,7 +17,7 @@ from loguru import logger
from tqdm import tqdm from tqdm import tqdm
import json import json
import math import math
from huggingface_hub import hf_hub_download from huggingface_hub import hf_hub_download, snapshot_download
# from diffusers.pipelines.pipeline_utils import DiffusionPipeline # from diffusers.pipelines.pipeline_utils import DiffusionPipeline
from acestep.schedulers.scheduling_flow_match_euler_discrete import ( from acestep.schedulers.scheduling_flow_match_euler_discrete import (
@@ -44,7 +44,6 @@ from acestep.apg_guidance import (
cfg_double_condition_forward, cfg_double_condition_forward,
) )
import torchaudio import torchaudio
from .cpu_offload import cpu_offload
torch.backends.cudnn.benchmark = False torch.backends.cudnn.benchmark = False
@@ -97,7 +96,6 @@ class ACEStepPipeline:
text_encoder_checkpoint_path=None, text_encoder_checkpoint_path=None,
persistent_storage_path=None, persistent_storage_path=None,
torch_compile=False, torch_compile=False,
cpu_offload=False,
**kwargs, **kwargs,
): ):
if not checkpoint_dir: if not checkpoint_dir:
@@ -124,149 +122,17 @@ class ACEStepPipeline:
self.device = device self.device = device
self.loaded = False self.loaded = False
self.torch_compile = torch_compile self.torch_compile = torch_compile
self.cpu_offload = cpu_offload
def load_checkpoint(self, checkpoint_dir=None): def load_checkpoint(self, checkpoint_dir=None):
device = self.device device = self.device
if checkpoint_dir is None:
dcae_model_path = os.path.join(checkpoint_dir, "music_dcae_f8c8") checkpoint_dir_models = snapshot_download(REPO_ID)
vocoder_model_path = os.path.join(checkpoint_dir, "music_vocoder") else:
ace_step_model_path = os.path.join(checkpoint_dir, "ace_step_transformer") checkpoint_dir_models = snapshot_download(REPO_ID, cache_dir=checkpoint_dir)
text_encoder_model_path = os.path.join(checkpoint_dir, "umt5-base") dcae_model_path = os.path.join(checkpoint_dir_models, "music_dcae_f8c8")
vocoder_model_path = os.path.join(checkpoint_dir_models, "music_vocoder")
files_exist = ( ace_step_model_path = os.path.join(checkpoint_dir_models, "ace_step_transformer")
os.path.exists(os.path.join(dcae_model_path, "config.json")) text_encoder_model_path = os.path.join(checkpoint_dir_models, "umt5-base")
and os.path.exists(
os.path.join(dcae_model_path, "diffusion_pytorch_model.safetensors")
)
and os.path.exists(os.path.join(vocoder_model_path, "config.json"))
and os.path.exists(
os.path.join(vocoder_model_path, "diffusion_pytorch_model.safetensors")
)
and os.path.exists(os.path.join(ace_step_model_path, "config.json"))
and os.path.exists(
os.path.join(ace_step_model_path, "diffusion_pytorch_model.safetensors")
)
and os.path.exists(os.path.join(text_encoder_model_path, "config.json"))
and os.path.exists(
os.path.join(text_encoder_model_path, "model.safetensors")
)
and os.path.exists(
os.path.join(text_encoder_model_path, "special_tokens_map.json")
)
)
if not files_exist:
logger.info(
f"Checkpoint directory {checkpoint_dir} is not complete, downloading from Hugging Face Hub"
)
# download music dcae model
hf_hub_download(
repo_id=REPO_ID,
subfolder="music_dcae_f8c8",
filename="config.json",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
hf_hub_download(
repo_id=REPO_ID,
subfolder="music_dcae_f8c8",
filename="diffusion_pytorch_model.safetensors",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
# download vocoder model
hf_hub_download(
repo_id=REPO_ID,
subfolder="music_vocoder",
filename="config.json",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
hf_hub_download(
repo_id=REPO_ID,
subfolder="music_vocoder",
filename="diffusion_pytorch_model.safetensors",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
# download ace_step transformer model
hf_hub_download(
repo_id=REPO_ID,
subfolder="ace_step_transformer",
filename="config.json",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
hf_hub_download(
repo_id=REPO_ID,
subfolder="ace_step_transformer",
filename="diffusion_pytorch_model.safetensors",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
# download text encoder model
# os.makedirs(text_encoder_model_path, exist_ok=True) # hf_hub_download should create subdirectories
hf_hub_download(
repo_id=REPO_ID,
subfolder="umt5-base",
filename="config.json",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
hf_hub_download(
repo_id=REPO_ID,
subfolder="umt5-base",
filename="model.safetensors",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
hf_hub_download(
repo_id=REPO_ID,
subfolder="umt5-base",
filename="special_tokens_map.json",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
hf_hub_download(
repo_id=REPO_ID,
subfolder="umt5-base",
filename="tokenizer_config.json",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
hf_hub_download(
repo_id=REPO_ID,
subfolder="umt5-base",
filename="tokenizer.json",
local_dir=checkpoint_dir,
local_dir_use_symlinks=False,
)
# Verify files were downloaded correctly
if not all([
os.path.exists(os.path.join(dcae_model_path, "config.json")),
os.path.exists(os.path.join(dcae_model_path, "diffusion_pytorch_model.safetensors")),
os.path.exists(os.path.join(vocoder_model_path, "config.json")),
os.path.exists(os.path.join(vocoder_model_path, "diffusion_pytorch_model.safetensors")),
os.path.exists(os.path.join(ace_step_model_path, "config.json")),
os.path.exists(os.path.join(ace_step_model_path, "diffusion_pytorch_model.safetensors")),
os.path.exists(os.path.join(text_encoder_model_path, "config.json")),
os.path.exists(os.path.join(text_encoder_model_path, "model.safetensors")),
os.path.exists(os.path.join(text_encoder_model_path, "special_tokens_map.json")),
]):
logger.error("Failed to download all required model files. Please check your internet connection and try again.")
logger.info(f"DCAE model path: {dcae_model_path}, files exist: {os.path.exists(os.path.join(dcae_model_path, 'config.json'))}")
logger.info(f"Vocoder model path: {vocoder_model_path}, files exist: {os.path.exists(os.path.join(vocoder_model_path, 'config.json'))}")
logger.info(f"ACE-Step model path: {ace_step_model_path}, files exist: {os.path.exists(os.path.join(ace_step_model_path, 'config.json'))}")
logger.info(f"Text encoder model path: {text_encoder_model_path}, files exist: {os.path.exists(os.path.join(text_encoder_model_path, 'config.json'))}")
raise RuntimeError("Model download failed. See logs for details.")
logger.info("Models downloaded successfully")
dcae_checkpoint_path = dcae_model_path dcae_checkpoint_path = dcae_model_path
vocoder_checkpoint_path = vocoder_model_path vocoder_checkpoint_path = vocoder_model_path
@@ -277,20 +143,12 @@ class ACEStepPipeline:
dcae_checkpoint_path=dcae_checkpoint_path, dcae_checkpoint_path=dcae_checkpoint_path,
vocoder_checkpoint_path=vocoder_checkpoint_path, vocoder_checkpoint_path=vocoder_checkpoint_path,
) )
# self.music_dcae.to(device).eval().to(self.dtype) self.music_dcae.to(device).eval().to(self.dtype)
if self.cpu_offload: # might be redundant
self.music_dcae = self.music_dcae.to("cpu").eval().to(self.dtype)
else:
self.music_dcae = self.music_dcae.to(device).eval().to(self.dtype)
self.ace_step_transformer = ACEStepTransformer2DModel.from_pretrained( self.ace_step_transformer = ACEStepTransformer2DModel.from_pretrained(
ace_step_checkpoint_path, torch_dtype=self.dtype ace_step_checkpoint_path, torch_dtype=self.dtype
) )
# self.ace_step_transformer.to(device).eval().to(self.dtype) self.ace_step_transformer.to(device).eval().to(self.dtype)
if self.cpu_offload:
self.ace_step_transformer = self.ace_step_transformer.to("cpu").eval().to(self.dtype)
else:
self.ace_step_transformer = self.ace_step_transformer.to(device).eval().to(self.dtype)
lang_segment = LangSegment() lang_segment = LangSegment()
@@ -400,11 +258,7 @@ class ACEStepPipeline:
text_encoder_model = UMT5EncoderModel.from_pretrained( text_encoder_model = UMT5EncoderModel.from_pretrained(
text_encoder_checkpoint_path, torch_dtype=self.dtype text_encoder_checkpoint_path, torch_dtype=self.dtype
).eval() ).eval()
# text_encoder_model = text_encoder_model.to(device).to(self.dtype) text_encoder_model = text_encoder_model.to(device).to(self.dtype)
if self.cpu_offload:
text_encoder_model = text_encoder_model.to("cpu").eval().to(self.dtype)
else:
text_encoder_model = text_encoder_model.to(device).eval().to(self.dtype)
text_encoder_model.requires_grad_(False) text_encoder_model.requires_grad_(False)
self.text_encoder_model = text_encoder_model self.text_encoder_model = text_encoder_model
self.text_tokenizer = AutoTokenizer.from_pretrained( self.text_tokenizer = AutoTokenizer.from_pretrained(
@@ -418,7 +272,6 @@ class ACEStepPipeline:
self.ace_step_transformer = torch.compile(self.ace_step_transformer) self.ace_step_transformer = torch.compile(self.ace_step_transformer)
self.text_encoder_model = torch.compile(self.text_encoder_model) self.text_encoder_model = torch.compile(self.text_encoder_model)
@cpu_offload("text_encoder_model")
def get_text_embeddings(self, texts, device, text_max_length=256): def get_text_embeddings(self, texts, device, text_max_length=256):
inputs = self.text_tokenizer( inputs = self.text_tokenizer(
texts, texts,
@@ -436,7 +289,6 @@ class ACEStepPipeline:
attention_mask = inputs["attention_mask"] attention_mask = inputs["attention_mask"]
return last_hidden_states, attention_mask return last_hidden_states, attention_mask
@cpu_offload("text_encoder_model")
def get_text_embeddings_null( def get_text_embeddings_null(
self, texts, device, text_max_length=256, tau=0.01, l_min=8, l_max=10 self, texts, device, text_max_length=256, tau=0.01, l_min=8, l_max=10
): ):
@@ -479,37 +331,28 @@ class ACEStepPipeline:
return last_hidden_states return last_hidden_states
def set_seeds(self, batch_size, manual_seeds=None): def set_seeds(self, batch_size, manual_seeds=None):
processed_input_seeds = None seeds = None
if manual_seeds is not None: if manual_seeds is not None:
if isinstance(manual_seeds, str): if isinstance(manual_seeds, str):
if "," in manual_seeds: if "," in manual_seeds:
processed_input_seeds = list(map(int, manual_seeds.split(","))) seeds = list(map(int, manual_seeds.split(",")))
elif manual_seeds.isdigit(): elif manual_seeds.isdigit():
processed_input_seeds = int(manual_seeds) seeds = int(manual_seeds)
elif isinstance(manual_seeds, list) and all(isinstance(s, int) for s in manual_seeds):
if len(manual_seeds) > 0:
processed_input_seeds = list(manual_seeds)
elif isinstance(manual_seeds, int):
processed_input_seeds = manual_seeds
random_generators = [ random_generators = [
torch.Generator(device=self.device) for _ in range(batch_size) torch.Generator(device=self.device) for _ in range(batch_size)
] ]
actual_seeds = [] actual_seeds = []
for i in range(batch_size): for i in range(batch_size):
current_seed_for_generator = None seed = None
if processed_input_seeds is None: if seeds is None:
current_seed_for_generator = torch.randint(0, 2**32, (1,)).item() seed = torch.randint(0, 2**32, (1,)).item()
elif isinstance(processed_input_seeds, int): if isinstance(seeds, int):
current_seed_for_generator = processed_input_seeds seed = seeds
elif isinstance(processed_input_seeds, list): if isinstance(seeds, list):
if i < len(processed_input_seeds): seed = seeds[i]
current_seed_for_generator = processed_input_seeds[i] random_generators[i].manual_seed(seed)
else: actual_seeds.append(seed)
current_seed_for_generator = processed_input_seeds[-1]
if current_seed_for_generator is None:
current_seed_for_generator = torch.randint(0, 2**32, (1,)).item()
random_generators[i].manual_seed(current_seed_for_generator)
actual_seeds.append(current_seed_for_generator)
return random_generators, actual_seeds return random_generators, actual_seeds
def get_lang(self, text): def get_lang(self, text):
@@ -557,7 +400,6 @@ class ACEStepPipeline:
print("tokenize error", e, "for line", line, "major_language", lang) print("tokenize error", e, "for line", line, "major_language", lang)
return lyric_token_idx return lyric_token_idx
@cpu_offload("ace_step_transformer")
def calc_v( def calc_v(
self, self,
zt_src, zt_src,
@@ -846,7 +688,6 @@ class ACEStepPipeline:
target_latents = zt_edit if xt_tar is None else xt_tar target_latents = zt_edit if xt_tar is None else xt_tar
return target_latents return target_latents
@cpu_offload("ace_step_transformer")
@torch.no_grad() @torch.no_grad()
def text2music_diffusion_process( def text2music_diffusion_process(
self, self,
@@ -1363,7 +1204,6 @@ class ACEStepPipeline:
) )
return target_latents return target_latents
@cpu_offload("music_dcae")
def latents2audio( def latents2audio(
self, self,
latents, latents,
@@ -1371,7 +1211,9 @@ class ACEStepPipeline:
sample_rate=48000, sample_rate=48000,
save_path=None, save_path=None,
format="wav", format="wav",
do_save=True,
): ):
if do_save:
output_audio_paths = [] output_audio_paths = []
bs = latents.shape[0] bs = latents.shape[0]
audio_lengths = [target_wav_duration_second * sample_rate] * bs audio_lengths = [target_wav_duration_second * sample_rate] * bs
@@ -1381,10 +1223,17 @@ class ACEStepPipeline:
pred_wavs = [pred_wav.cpu().float() for pred_wav in pred_wavs] pred_wavs = [pred_wav.cpu().float() for pred_wav in pred_wavs]
for i in tqdm(range(bs)): for i in tqdm(range(bs)):
output_audio_path = self.save_wav_file( output_audio_path = self.save_wav_file(
pred_wavs[i], i, save_path=save_path, sample_rate=sample_rate, format=format pred_wavs[i], i, sample_rate=sample_rate
) )
output_audio_paths.append(output_audio_path) output_audio_paths.append(output_audio_path)
return output_audio_paths return output_audio_paths
else:
bs = latents.shape[0]
pred_latents = latents
with torch.no_grad():
_, pred_wavs = self.music_dcae.decode(pred_latents, sr=sample_rate)
pred_wavs = [pred_wav.cpu().float() for pred_wav in pred_wavs]
return pred_wavs
def save_wav_file( def save_wav_file(
self, target_wav, idx, save_path=None, sample_rate=48000, format="wav" self, target_wav, idx, save_path=None, sample_rate=48000, format="wav"
@@ -1393,25 +1242,20 @@ class ACEStepPipeline:
logger.warning("save_path is None, using default path ./outputs/") logger.warning("save_path is None, using default path ./outputs/")
base_path = f"./outputs" base_path = f"./outputs"
ensure_directory_exists(base_path) ensure_directory_exists(base_path)
else:
base_path = save_path
ensure_directory_exists(base_path)
output_path_wav = ( output_path_wav = (
f"{base_path}/output_{time.strftime('%Y%m%d%H%M%S')}_{idx}.wav" f"{base_path}/output_{time.strftime('%Y%m%d%H%M%S')}_{idx}.wav"
) )
else:
ensure_directory_exists(os.path.dirname(save_path))
if os.path.isdir(save_path):
logger.info(f"Provided save_path '{save_path}' is a directory. Appending timestamped filename.")
output_path_wav = os.path.join(save_path, f"output_{time.strftime('%Y%m%d%H%M%S')}_{idx}.wav")
else:
output_path_wav = save_path
target_wav = target_wav.float() target_wav = target_wav.float()
logger.info(f"Saving audio to {output_path_wav}") print(target_wav)
torchaudio.save( torchaudio.save(
output_path_wav, target_wav, sample_rate=sample_rate, format=format output_path_wav, target_wav, sample_rate=sample_rate, format=format
) )
return output_path_wav return output_path_wav
@cpu_offload("music_dcae")
def infer_latents(self, input_audio_path): def infer_latents(self, input_audio_path):
if input_audio_path is None: if input_audio_path is None:
return None return None
@@ -1457,6 +1301,7 @@ class ACEStepPipeline:
format: str = "wav", format: str = "wav",
batch_size: int = 1, batch_size: int = 1,
debug: bool = False, debug: bool = False,
do_save: bool = True,
): ):
start_time = time.time() start_time = time.time()
@@ -1640,6 +1485,7 @@ class ACEStepPipeline:
target_wav_duration_second=audio_duration, target_wav_duration_second=audio_duration,
save_path=save_path, save_path=save_path,
format=format, format=format,
do_save=do_save,
) )
end_time = time.time() end_time = time.time()
@@ -1683,6 +1529,7 @@ class ACEStepPipeline:
"edit_target_lyrics": edit_target_lyrics, "edit_target_lyrics": edit_target_lyrics,
} }
# save input_params_json # save input_params_json
if do_save:
for output_audio_path in output_paths: for output_audio_path in output_paths:
input_params_json_save_path = output_audio_path.replace( input_params_json_save_path = output_audio_path.replace(
f".{format}", "_input_params.json" f".{format}", "_input_params.json"