diff --git a/CHANGELOG.md b/CHANGELOG.md index ac2f26a50..222b599b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,11 +14,15 @@ - in addition as standard behavior of detect & run-generate, it can now also run face-restore models - included models are: *CodeFormer, RestoreFormer, GFPGan, GPEN-BFR* - **Face**: - - new [photomaker v2](https://huggingface.co/TencentARC/PhotoMaker-V2) and reimplemented [photomaker v1](https://huggingface.co/TencentARC/PhotoMaker) + - new [PhotoMaker v2](https://huggingface.co/TencentARC/PhotoMaker-V2) and reimplemented [PhotoMaker v1](https://huggingface.co/TencentARC/PhotoMaker) compatible with sdxl models, generates pretty good results and its faster than most other methods select under *scripts -> face -> photomaker* - - new [reswapper](https://github.com/somanchiu/ReSwapper) + - new [ReSwapper](https://github.com/somanchiu/ReSwapper) todo: experimental-only and unfinished, only noting in changelog for future reference +- **Video** + - **hunyuan video** support for [FastHunyuan](https://huggingface.co/FastVideo/FastHunyuan) + simply select model variant and set appropriate parameters + recommended: sampler-shift=17, steps=6, resolution=720x1280, frames=125, guidance>6.0 - **Other**: - **upscale**: new [asymmetric vae](Heasterian/AsymmetricAutoencoderKLUpscaler) upscaling method - **ipex**: update supported torch versions diff --git a/scripts/hunyuanvideo.py b/scripts/hunyuanvideo.py index aac3eb8f0..36edfea25 100644 --- a/scripts/hunyuanvideo.py +++ b/scripts/hunyuanvideo.py @@ -3,10 +3,9 @@ import torch import gradio as gr import transformers import diffusers -from modules import scripts, processing, shared, images, devices, sd_models, sd_checkpoint, model_quant, timer +from modules import scripts, processing, shared, images, devices, sd_models, sd_checkpoint, sd_samplers, model_quant, timer -repo_id = 'tencent/HunyuanVideo' default_template = """Describe the video by detailing the following aspects: 1. The main content and theme of the video. 2. The color, shape, size, texture, quantity, text, and spatial relationships of the objects. @@ -63,27 +62,24 @@ class Script(scripts.Script): def ui(self, is_img2img): with gr.Row(): gr.HTML('  Hunyuan Video
') + with gr.Row(): + repo_id = gr.Dropdown(label='Model', choices=['tencent/HunyuanVideo', 'FastVideo/FastHunyuan'], value='tencent/HunyuanVideo') with gr.Row(): num_frames = gr.Slider(label='Frames', minimum=9, maximum=257, step=1, value=45) tile_frames = gr.Slider(label='Tile frames', minimum=1, maximum=64, step=1, value=16) with gr.Row(): - override_scheduler = gr.Checkbox(label='Override scheduler', value=True) + with gr.Column(): + override_scheduler = gr.Checkbox(label='Override sampler', value=True) + with gr.Column(): + scheduler_shift = gr.Slider(label='Sampler shift', minimum=0.0, maximum=20.0, step=0.1, value=7.0) with gr.Row(): - template = gr.TextArea(label='Prompt processor', lines=3, value=default_template) + template = gr.TextArea(label='Prompt processor', lines=3, value=default_template, visible=False) with gr.Row(): from modules.ui_sections import create_video_inputs video_type, duration, gif_loop, mp4_pad, mp4_interpolate = create_video_inputs(tab='img2img' if is_img2img else 'txt2img') - return [num_frames, tile_frames, override_scheduler, template, video_type, duration, gif_loop, mp4_pad, mp4_interpolate] + return [repo_id, num_frames, tile_frames, override_scheduler, scheduler_shift, template, video_type, duration, gif_loop, mp4_pad, mp4_interpolate] - def run(self, p: processing.StableDiffusionProcessing, num_frames, tile_frames, override_scheduler, template, video_type, duration, gif_loop, mp4_pad, mp4_interpolate): # pylint: disable=arguments-differ, unused-argument - # set params - num_frames = int(num_frames) - p.width = 16 * int(p.width // 16) - p.height = 16 * int(p.height // 16) - p.do_not_save_grid = True - p.ops.append('video') - - # load model + def load(self, repo_id:str): if shared.sd_model.__class__ != diffusers.HunyuanVideoPipeline: sd_models.unload_model_weights() t0 = time.time() @@ -134,12 +130,27 @@ class Script(scripts.Script): shared.sd_model.vae.enable_slicing() shared.sd_model.vae.enable_tiling() + def run(self, p: processing.StableDiffusionProcessing, repo_id, num_frames, tile_frames, override_scheduler, scheduler_shift, template, video_type, duration, gif_loop, mp4_pad, mp4_interpolate): # pylint: disable=arguments-differ, unused-argument + # set params + num_frames = int(num_frames) + p.width = 16 * int(p.width // 16) + p.height = 16 * int(p.height // 16) + p.do_not_save_grid = True + p.ops.append('video') + + # load model + self.load(repo_id) + shared.sd_model = sd_models.apply_balanced_offload(shared.sd_model) devices.torch_gc(force=True) if override_scheduler: p.sampler_name = 'Default' - shared.sd_model.scheduler._shift = 7.0 # pylint: disable=protected-access + else: + shared.sd_model.scheduler = sd_samplers.create_sampler(p.sampler_name, shared.sd_model) + p.sampler_name = 'Default' # avoid double creation + if hasattr(shared.sd_model.scheduler, '_shift'): + shared.sd_model.scheduler._shift = scheduler_shift # pylint: disable=protected-access # encode prompt processing.fix_seed(p)