Sergidev commited on
Commit
d83ac8a
·
1 Parent(s): 0a69c30
Files changed (6) hide show
  1. README.md +2 -2
  2. app.py +7 -0
  3. demo_app.py +230 -0
  4. packages.txt +4 -0
  5. requirements.txt +48 -0
  6. utils.py +40 -0
README.md CHANGED
@@ -1,8 +1,8 @@
1
  ---
2
  title: Anime TextToVideo
3
- emoji: 📈
4
  colorFrom: pink
5
- colorTo: yellow
6
  sdk: gradio
7
  sdk_version: 5.16.0
8
  app_file: app.py
 
1
  ---
2
  title: Anime TextToVideo
3
+ emoji:
4
  colorFrom: pink
5
+ colorTo: purple
6
  sdk: gradio
7
  sdk_version: 5.16.0
8
  app_file: app.py
app.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ from utils import install_packages
2
+
3
+ if __name__ == "__main__":
4
+ install_packages()
5
+
6
+ from demo_app import demo
7
+ demo.queue(max_size=20).launch()
demo_app.py ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spaces
2
+ import gc
3
+ import gradio as gr
4
+ import numpy as np
5
+ import os
6
+ from pathlib import Path
7
+ from diffusers import GGUFQuantizationConfig, HunyuanVideoPipeline, HunyuanVideoTransformer3DModel
8
+ from diffusers.utils import export_to_video
9
+ from huggingface_hub import snapshot_download
10
+ import torch
11
+
12
+ gc.collect()
13
+ torch.cuda.empty_cache()
14
+ torch.set_grad_enabled(False)
15
+ torch.backends.cudnn.deterministic = True
16
+ torch.backends.cudnn.benchmark = False
17
+
18
+ model_id = "hunyuanvideo-community/HunyuanVideo"
19
+ base_path = f"/home/user/app/{model_id}"
20
+ os.makedirs(base_path, exist_ok=True)
21
+ snapshot_download(repo_id=model_id, local_dir=base_path)
22
+ ckp_path = Path(base_path)
23
+
24
+ gguf_filename = "hunyuan-video-t2v-720p-Q4_0.gguf"
25
+ transformer_path = f"https://huggingface.co/city96/HunyuanVideo-gguf/blob/main/{gguf_filename}"
26
+ transformer = HunyuanVideoTransformer3DModel.from_single_file(
27
+ transformer_path,
28
+ quantization_config=GGUFQuantizationConfig(compute_dtype=torch.bfloat16),
29
+ torch_dtype=torch.bfloat16,
30
+ )
31
+ transformer = transformer.to('cuda')
32
+
33
+ pipe = HunyuanVideoPipeline.from_pretrained(
34
+ ckp_path,
35
+ transformer=transformer,
36
+ torch_dtype=torch.float16
37
+ )
38
+
39
+ if pipe.text_encoder:
40
+ pipe.text_encoder = pipe.text_encoder.to('cuda')
41
+ pipe.text_encoder.eval()
42
+
43
+ pipe.vae.enable_tiling()
44
+ pipe.vae.enable_slicing()
45
+ pipe.vae.eval()
46
+ pipe.vae = pipe.vae.to("cuda")
47
+ pipe = pipe.to("cuda")
48
+
49
+ pipe.load_lora_weights(
50
+ "calcuis/hyvid",
51
+ weight_name="hyvid-lora-mila3d.safetensors",
52
+ adapter_name="hyvid_lora_adapter"
53
+ )
54
+ pipe.set_adapters("hyvid_lora_adapter", 1.2)
55
+
56
+ gc.collect()
57
+ torch.cuda.empty_cache()
58
+
59
+ MAX_SEED = np.iinfo(np.int32).max
60
+ MAX_IMAGE_SIZE = 1024
61
+
62
+ @spaces.GPU(duration=120) # Adjusted duration to 120
63
+ def generate(
64
+ prompt,
65
+ height,
66
+ width,
67
+ num_frames,
68
+ num_inference_steps,
69
+ seed_value,
70
+ fps,
71
+ progress=gr.Progress(track_tqdm=True)
72
+ ):
73
+ with torch.cuda.device(0):
74
+ if seed_value == -1:
75
+ seed_value = torch.randint(0, MAX_SEED, (1,)).item()
76
+ generator = torch.Generator('cuda').manual_seed(seed_value)
77
+
78
+ with torch.amp.autocast_mode.autocast('cuda', dtype=torch.bfloat16), torch.inference_mode(), torch.no_grad():
79
+ output = pipe(
80
+ prompt=prompt,
81
+ height=height,
82
+ width=width,
83
+ num_frames=num_frames,
84
+ num_inference_steps=num_inference_steps,
85
+ generator=generator,
86
+ ).frames[0]
87
+
88
+ output_path = "output.mp4"
89
+ export_to_video(output, output_path, fps=fps) # Use user-defined fps
90
+ torch.cuda.empty_cache()
91
+ gc.collect()
92
+ return output_path
93
+
94
+
95
+ # Gradio Interface
96
+ css = """
97
+ #col-container {
98
+ margin: 0 auto;
99
+ max-width: 850px;
100
+ }
101
+
102
+ .dark-theme {
103
+ background-color: #1f1f1f;
104
+ color: #ffffff;
105
+ }
106
+
107
+ .container {
108
+ margin: 0 auto;
109
+ padding: 20px;
110
+ border-radius: 10px;
111
+ background-color: #2d2d2d;
112
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
113
+ }
114
+
115
+ .title {
116
+ text-align: center;
117
+ margin-bottom: 1em;
118
+ color: #ffffff;
119
+ }
120
+
121
+ .description {
122
+ text-align: center;
123
+ margin-bottom: 2em;
124
+ color: #cccccc;
125
+ font-size: 0.95em;
126
+ line-height: 1.5;
127
+ }
128
+
129
+ .prompt-container {
130
+ background-color: #363636;
131
+ padding: 15px;
132
+ border-radius: 8px;
133
+ margin-bottom: 1em;
134
+ }
135
+
136
+ .support-text {
137
+ text-align: center;
138
+ margin-top: 1em;
139
+ color: #cccccc;
140
+ font-size: 0.9em;
141
+ }
142
+
143
+ a {
144
+ color: #00a7e1;
145
+ text-decoration: none;
146
+ }
147
+
148
+ a:hover {
149
+ text-decoration: underline;
150
+ }
151
+ """
152
+
153
+ with gr.Blocks(css=css, theme="dark") as demo:
154
+ with gr.Column(elem_id="col-container"):
155
+ gr.Markdown("# 🎬 Anime TTV", elem_classes=["title"])
156
+ gr.Markdown(
157
+ """Transform your text descriptions into anime-style videos using state-of-the-art AI technology.
158
+ This space uses the HunyuanVideo model to generate high-quality animated sequences.
159
+
160
+ If you find this useful, please consider ❤️ hearting the space and supporting me on [Ko-Fi](https://ko-fi.com/sergidev)!""",
161
+ elem_classes=["description"]
162
+ )
163
+
164
+ with gr.Row(elem_classes=["prompt-container"]):
165
+ prompt = gr.Text(
166
+ label="Prompt",
167
+ placeholder="Enter your prompt here (e.g., 'a cute anime girl walking in a garden')",
168
+ show_label=False,
169
+ )
170
+ run_button = gr.Button("🎨 Generate", variant="primary")
171
+
172
+ with gr.Row():
173
+ result = gr.Video(label="Generated Video")
174
+
175
+ with gr.Accordion("⚙️ Advanced Settings", open=False):
176
+ seed = gr.Slider(
177
+ label="Seed (-1 for random)",
178
+ minimum=-1,
179
+ maximum=MAX_SEED,
180
+ step=1,
181
+ value=-1,
182
+ )
183
+ with gr.Row():
184
+ height = gr.Slider( # Fixed order of height and width to match intended use
185
+ label="Height",
186
+ minimum=256,
187
+ maximum=MAX_IMAGE_SIZE,
188
+ step=16, # Make divisible by 16
189
+ value=512,
190
+ )
191
+ width = gr.Slider(
192
+ label="Width",
193
+ minimum=256,
194
+ maximum=MAX_IMAGE_SIZE,
195
+ step=16,
196
+ value=320,
197
+ )
198
+ with gr.Row():
199
+ num_frames = gr.Slider(
200
+ label="Number of frames to generate",
201
+ minimum=1.0,
202
+ maximum=257.0,
203
+ step=1,
204
+ value=42,
205
+ )
206
+ num_inference_steps = gr.Slider(
207
+ label="Number of inference steps",
208
+ minimum=1,
209
+ maximum=50,
210
+ step=1,
211
+ value=30,
212
+ )
213
+ fps = gr.Slider(
214
+ label="Frames per second",
215
+ minimum=1,
216
+ maximum=60,
217
+ step=1,
218
+ value=14,
219
+ )
220
+
221
+ # Event handling
222
+ run_button.click(
223
+ fn=generate,
224
+ inputs=[prompt, height, width, num_frames, num_inference_steps, seed, fps],
225
+ # Added fps to inputs, fixed height/width order
226
+ outputs=[result],
227
+ )
228
+
229
+
230
+ # The demo.queue and demo.launch are handled in app.py
packages.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ ffmpeg
2
+ python3-imageio
3
+ cmake
4
+ libstdc++6
requirements.txt ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --extra-index-url https://download.pytorch.org/whl/cu124
2
+ bitsandbytes
3
+ decord
4
+ einops
5
+ facexlib
6
+ ftfy
7
+ gguf
8
+ git+https://github.com/huggingface/accelerate.git@main#egg=accelerate
9
+ git+https://github.com/huggingface/diffusers.git@main#egg=diffusers
10
+ git+https://github.com/huggingface/transformers.git@main#egg=transformers
11
+ gradio
12
+ hf_transfer
13
+ huggingface_hub
14
+ imageio
15
+ imageio-ffmpeg
16
+ insightface
17
+ invisible_watermark
18
+ matplotlib
19
+ moviepy==1.0.3
20
+ numpy<2.0
21
+ onnxruntime
22
+ onnxruntime-gpu
23
+ omegaconf
24
+ opencv-python
25
+ opencv-python-headless
26
+ git+https://github.com/huggingface/optimum-quanto
27
+ packaging
28
+ patch_conv
29
+ Pillow==10.2.0
30
+ psutil
31
+ safetensors
32
+ scipy
33
+ scikit-learn
34
+ scikit-image
35
+ scikit-video
36
+ sentencepiece
37
+ setuptools
38
+ spaces
39
+ timm
40
+ tokenizers>=0.13.3
41
+ torch<2.6.0,>=2.4.0
42
+ torchao
43
+ torchaudio
44
+ torchsde
45
+ torchvision
46
+ tqdm
47
+ wheel
48
+ git+https://github.com/huggingface/peft.git
utils.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def install_packages():
2
+ import subprocess
3
+ import sys
4
+ import importlib
5
+
6
+ def _is_package_available(name) -> bool:
7
+ try:
8
+ importlib.import_module(name)
9
+ return True
10
+ except (ImportError, ModuleNotFoundError):
11
+ return False
12
+
13
+ # upgrade pip
14
+ subprocess.run(
15
+ f"{sys.executable} -m pip install --upgrade pip", shell=True, check=True
16
+ )
17
+ subprocess.run(
18
+ f"{sys.executable} -m pip install --upgrade ninja wheel setuptools packaging", shell=True, check=True
19
+ )
20
+
21
+ # install ninja
22
+ if not _is_package_available("ninja"):
23
+ subprocess.run(f"{sys.executable} -m pip install ninja nvidia-cudnn-cu12==9.1.0.70 nvidia-cublas-cu12==12.4.5.8 torch==2.5.1 --extra-index-url https://download.pytorch.org/whl/cu124", shell=True, check=True)
24
+
25
+ # install flash attention
26
+ if not _is_package_available("flash_attn"):
27
+ subprocess.run(
28
+ f"{sys.executable} -m pip install -v -U flash-attention --no-build-isolation",
29
+ env={"MAX_JOBS": "1"},
30
+ shell=True,
31
+ check=True
32
+ )
33
+
34
+ # install xformers
35
+ if not _is_package_available("xformers"):
36
+ subprocess.run(
37
+ f"{sys.executable} -m pip install -v -U xformers nvidia-cudnn-cu12==9.1.0.70 nvidia-cublas-cu12==12.4.5.8 torch==2.5.1 --extra-index-url https://download.pytorch.org/whl/cu124",
38
+ shell=True,
39
+ check=True
40
+ )