markury commited on
Commit
8abf449
·
1 Parent(s): f735e48

feat(wip): lycoris

Browse files
Files changed (2) hide show
  1. app.py +55 -29
  2. requirements.txt +3 -1
app.py CHANGED
@@ -2,10 +2,13 @@ import torch
2
  import gradio as gr
3
  import spaces
4
  import random
 
5
  from diffusers.utils import export_to_video
6
  from diffusers import AutoencoderKLWan, WanPipeline
7
  from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
8
  from diffusers.schedulers.scheduling_flow_match_euler_discrete import FlowMatchEulerDiscreteScheduler
 
 
9
 
10
  # Define model options
11
  MODEL_OPTIONS = {
@@ -19,14 +22,39 @@ SCHEDULER_OPTIONS = {
19
  "FlowMatchEulerDiscreteScheduler": FlowMatchEulerDiscreteScheduler
20
  }
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  @spaces.GPU(duration=300)
23
  def generate_video(
24
  model_choice,
25
  prompt,
26
  negative_prompt,
27
- lora_id,
28
- lora_weight_name,
29
- lora_scale,
30
  scheduler_type,
31
  flow_shift,
32
  height,
@@ -65,24 +93,22 @@ def generate_video(
65
  # Move to GPU
66
  pipe.to("cuda")
67
 
68
- # Load LoRA weights if provided
69
- if lora_id and lora_id.strip():
70
  try:
71
- # If a specific weight name is provided, use it
72
- if lora_weight_name and lora_weight_name.strip():
73
- pipe.load_lora_weights(lora_id, weight_name=lora_weight_name)
74
- else:
75
- pipe.load_lora_weights(lora_id)
 
76
 
77
- # Set lora scale if applicable
78
- if hasattr(pipe, "set_adapters_scale") and lora_scale is not None:
79
- pipe.set_adapters_scale(lora_scale)
80
  except ValueError as e:
81
- # Return informative error if there are multiple safetensors and no weight name
82
- if "more than one weights file" in str(e):
83
- return f"Error: The repository '{lora_id}' contains multiple safetensors files. Please specify a weight name using the 'LoRA Weight Name' field.", seed
84
  else:
85
- return f"Error loading LoRA weights: {str(e)}", seed
86
 
87
  # Enable CPU offload for low VRAM
88
  pipe.enable_model_cpu_offload()
@@ -114,7 +140,7 @@ with gr.Blocks() as demo:
114
  </svg>
115
  </p>
116
  """)
117
- gr.Markdown("# Wan 2.1 T2V 1.3B with LoRA")
118
 
119
  with gr.Row():
120
  with gr.Column(scale=1):
@@ -137,19 +163,19 @@ with gr.Blocks() as demo:
137
  )
138
 
139
  with gr.Row():
140
- lora_id = gr.Textbox(
141
- label="LoRA Model Repo (e.g., TheBulge/AndroWan-2.1-T2V-1.3B)",
142
  value="TheBulge/AndroWan-2.1-T2V-1.3B"
143
  )
144
 
145
  with gr.Row():
146
- lora_weight_name = gr.Textbox(
147
- label="LoRA Path in Repo (optional)",
148
  value="safetensors/AndroWan_v32-0036_ema.safetensors",
149
  info="Specify for repos with multiple .safetensors files, e.g.: adapter_model.safetensors, pytorch_lora_weights.safetensors, etc."
150
  )
151
- lora_scale = gr.Slider(
152
- label="LoRA Scale",
153
  minimum=0.0,
154
  maximum=2.0,
155
  value=1.00,
@@ -238,9 +264,9 @@ with gr.Blocks() as demo:
238
  model_choice,
239
  prompt,
240
  negative_prompt,
241
- lora_id,
242
- lora_weight_name,
243
- lora_scale,
244
  scheduler_type,
245
  flow_shift,
246
  height,
@@ -261,8 +287,8 @@ with gr.Blocks() as demo:
261
  - Number of frames should be of the form 4k+1 (e.g., 33, 81)
262
  - Stick to lower frame counts. Even at 480p, an 81 frame sequence at 30 steps will nearly time out the request in this space.
263
 
264
- ## Using LoRAs with multiple safetensors files:
265
- If you encounter an error stating "more than one weights file", you need to specify the exact weight file name in the "LoRA Weight Name" field.
266
  You can find this by browsing the repository on Hugging Face and looking for the safetensors files (common names include: adapter_model.safetensors, pytorch_lora_weights.safetensors).
267
  """)
268
 
 
2
  import gradio as gr
3
  import spaces
4
  import random
5
+ import os
6
  from diffusers.utils import export_to_video
7
  from diffusers import AutoencoderKLWan, WanPipeline
8
  from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler
9
  from diffusers.schedulers.scheduling_flow_match_euler_discrete import FlowMatchEulerDiscreteScheduler
10
+ from huggingface_hub import hf_hub_download
11
+ from lycoris import create_lycoris_from_weights
12
 
13
  # Define model options
14
  MODEL_OPTIONS = {
 
22
  "FlowMatchEulerDiscreteScheduler": FlowMatchEulerDiscreteScheduler
23
  }
24
 
25
+ def download_adapter(repo_id, weight_name=None):
26
+ """
27
+ Download the adapter file from the Hugging Face Hub.
28
+ If weight_name is not provided, attempts to use pytorch_lora_weights.safetensors
29
+ """
30
+ adapter_filename = weight_name if weight_name else "pytorch_lora_weights.safetensors"
31
+ cache_dir = os.environ.get('HF_PATH', os.path.expanduser('~/.cache/huggingface/hub/models'))
32
+ cleaned_adapter_path = repo_id.replace("/", "_").replace("\\", "_").replace(":", "_")
33
+ path_to_adapter = os.path.join(cache_dir, cleaned_adapter_path)
34
+ os.makedirs(path_to_adapter, exist_ok=True)
35
+
36
+ try:
37
+ path_to_adapter_file = hf_hub_download(
38
+ repo_id=repo_id,
39
+ filename=adapter_filename,
40
+ local_dir=path_to_adapter
41
+ )
42
+ return path_to_adapter_file
43
+ except Exception as e:
44
+ # If specific file not found, try to get a list of available safetensors files
45
+ if weight_name is None:
46
+ raise ValueError(f"Could not download default adapter file: {str(e)}\nPlease specify the exact weight file name.")
47
+ else:
48
+ raise ValueError(f"Could not download adapter file {weight_name}: {str(e)}")
49
+
50
  @spaces.GPU(duration=300)
51
  def generate_video(
52
  model_choice,
53
  prompt,
54
  negative_prompt,
55
+ lycoris_id,
56
+ lycoris_weight_name,
57
+ lycoris_scale,
58
  scheduler_type,
59
  flow_shift,
60
  height,
 
93
  # Move to GPU
94
  pipe.to("cuda")
95
 
96
+ # Load LyCORIS weights if provided
97
+ if lycoris_id and lycoris_id.strip():
98
  try:
99
+ # Download the adapter file
100
+ adapter_file_path = download_adapter(repo_id=lycoris_id, weight_name=lycoris_weight_name if lycoris_weight_name and lycoris_weight_name.strip() else None)
101
+
102
+ # Apply LyCORIS adapter
103
+ wrapper, *_ = create_lycoris_from_weights(lycoris_scale, adapter_file_path, pipe.transformer)
104
+ wrapper.merge_to()
105
 
 
 
 
106
  except ValueError as e:
107
+ # Return informative error if there are issues loading the adapter
108
+ if "more than one weights file" in str(e) or "Could not download default adapter file" in str(e):
109
+ return f"Error: The repository '{lycoris_id}' may contain multiple weight files. Please specify a weight name using the 'LyCORIS Weight Name' field.", seed
110
  else:
111
+ return f"Error loading LyCORIS weights: {str(e)}", seed
112
 
113
  # Enable CPU offload for low VRAM
114
  pipe.enable_model_cpu_offload()
 
140
  </svg>
141
  </p>
142
  """)
143
+ gr.Markdown("# Wan 2.1 T2V with LyCORIS")
144
 
145
  with gr.Row():
146
  with gr.Column(scale=1):
 
163
  )
164
 
165
  with gr.Row():
166
+ lycoris_id = gr.Textbox(
167
+ label="LyCORIS Model Repo (e.g., TheBulge/AndroWan-2.1-T2V-1.3B)",
168
  value="TheBulge/AndroWan-2.1-T2V-1.3B"
169
  )
170
 
171
  with gr.Row():
172
+ lycoris_weight_name = gr.Textbox(
173
+ label="LyCORIS Weight Path in Repo (optional)",
174
  value="safetensors/AndroWan_v32-0036_ema.safetensors",
175
  info="Specify for repos with multiple .safetensors files, e.g.: adapter_model.safetensors, pytorch_lora_weights.safetensors, etc."
176
  )
177
+ lycoris_scale = gr.Slider(
178
+ label="LyCORIS Scale",
179
  minimum=0.0,
180
  maximum=2.0,
181
  value=1.00,
 
264
  model_choice,
265
  prompt,
266
  negative_prompt,
267
+ lycoris_id,
268
+ lycoris_weight_name,
269
+ lycoris_scale,
270
  scheduler_type,
271
  flow_shift,
272
  height,
 
287
  - Number of frames should be of the form 4k+1 (e.g., 33, 81)
288
  - Stick to lower frame counts. Even at 480p, an 81 frame sequence at 30 steps will nearly time out the request in this space.
289
 
290
+ ## Using LyCORIS with multiple safetensors files:
291
+ If you encounter an error stating "Could not download default adapter file", you need to specify the exact weight file name in the "LyCORIS Weight Name" field.
292
  You can find this by browsing the repository on Hugging Face and looking for the safetensors files (common names include: adapter_model.safetensors, pytorch_lora_weights.safetensors).
293
  """)
294
 
requirements.txt CHANGED
@@ -7,4 +7,6 @@ ftfy>=6.1.3
7
  einops>=0.7.0
8
  imageio>=2.31.6
9
  imageio-ffmpeg>=0.4.9
10
- peft==0.7.1
 
 
 
7
  einops>=0.7.0
8
  imageio>=2.31.6
9
  imageio-ffmpeg>=0.4.9
10
+ peft==0.7.1
11
+ lycoris-lora>=0.1.5
12
+ huggingface_hub>=0.19.0