Files
2026-05-26 21:21:05 +08:00

137 lines
4.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# !/usr/bin/env python
# -*- coding: UTF-8 -*-
import os
import torch
import gc
import comfy.model_management as mm
from PIL import Image
import numpy as np
from comfy.utils import common_upscale
from datetime import datetime
import folder_paths
import soundfile as sf
import uuid
cur_path = os.path.dirname(os.path.abspath(__file__))
def audio2path(audio,):
unique_id = uuid.uuid4().hex[:8]
audio_file = os.path.join(folder_paths.get_temp_directory(), f"audio_refer_temp_{unique_id}.wav")
waveform = audio["waveform"].squeeze(0)
waveform_np = waveform.cpu().numpy() if hasattr(waveform, 'cpu') else waveform.numpy()
# 3. 格式转换:torchaudio 格式为 (channels, samples),soundfile 需要 (samples, channels)
# 如果是单声道音频 (1, samples),转置后变成 (samples, 1),符合 soundfile 的单声道要求
if waveform_np.ndim == 2:
waveform_np = waveform_np.T
sf.write(audio_file, waveform_np, audio["sample_rate"])
return audio_file
def auto_match(num_frames):
vae_scale_factor_temporal = 4
k = round((num_frames + vae_scale_factor_temporal - 1) / (vae_scale_factor_temporal * vae_scale_factor_temporal))
k = max(k, 1)
corrected_num_frames = (vae_scale_factor_temporal * vae_scale_factor_temporal) * k - (vae_scale_factor_temporal - 1)
if corrected_num_frames != num_frames:
print(f"[LongCat Video] Auto-corrected num_frames from {num_frames} to {corrected_num_frames} to satisfy temporal alignment (16k - 3).")
num_frames = corrected_num_frames
return num_frames
def clear_comfyui_cache():
cf_models=mm.loaded_models()
try:
for pipe in cf_models:
pipe.unpatch_model(device_to=torch.device("cpu"))
except: pass
mm.soft_empty_cache()
torch.cuda.empty_cache()
max_gpu_memory = torch.cuda.max_memory_allocated()
print(f"After Max GPU memory allocated: {max_gpu_memory / 1000 ** 3:.2f} GB")
def gc_cleanup():
gc.collect()
torch.cuda.empty_cache()
def phi2narry(img):
img = torch.from_numpy(np.array(img).astype(np.float32) / 255.0).unsqueeze(0)
return img
def tensor2image(tensor):
tensor = tensor.cpu()
image_np = tensor.squeeze().mul(255).clamp(0, 255).byte().numpy()
image = Image.fromarray(image_np, mode='RGB')
return image
def tensor2pillist(tensor_in):
d1, _, _, _ = tensor_in.size()
if d1 == 1:
img_list = [tensor2image(tensor_in)]
else:
tensor_list = torch.chunk(tensor_in, chunks=d1)
img_list=[tensor2image(i) for i in tensor_list]
return img_list
def tensor2pillist_upscale(tensor_in,width,height):
d1, _, _, _ = tensor_in.size()
if d1 == 1:
img_list = [nomarl_upscale(tensor_in,width,height)]
else:
tensor_list = torch.chunk(tensor_in, chunks=d1)
img_list=[nomarl_upscale(i,width,height) for i in tensor_list]
return img_list
def tensor2list(tensor_in,width,height):
if tensor_in is None:
return None
d1, _, _, _ = tensor_in.size()
if d1 == 1:
tensor_list = [tensor_upscale(tensor_in,width,height)]
else:
tensor_list_ = torch.chunk(tensor_in, chunks=d1)
tensor_list=[tensor_upscale(i,width,height) for i in tensor_list_]
return tensor_list
def tensor_upscale(tensor, width, height):
samples = tensor.movedim(-1, 1)
samples = common_upscale(samples, width, height, "bilinear", "center")
samples = samples.movedim(1, -1)
return samples
def nomarl_upscale(img, width, height):
samples = img.movedim(-1, 1)
img = common_upscale(samples, width, height, "bilinear", "center")
samples = img.movedim(1, -1)
img = tensor2image(samples)
return img
def map_0_1_to_neg1_1(t):
if not torch.is_tensor(t):
t = torch.tensor(t)
t = t.float()
try:
vmax = float(t.max())
except Exception:
vmax = 1.0
if vmax > 2.0:
t = t / 255.0
try:
vmin = float(t.min())
vmax = float(t.max())
except Exception:
vmin, vmax = -1.0, 1.0
if vmin >= 0.0 and vmax <= 1.1:
t = t * 2.0 - 1.0
return t
def map_neg1_1_to_0_1(t):
if not torch.is_tensor(t):
t = torch.tensor(t)
t = t.float()
t = (t + 1.0) * 0.5
t = t.clamp(0.0, 1.0)
return t