LTTEAM commited on
Commit
7bd3681
·
verified ·
1 Parent(s): c2add15

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -52
app.py CHANGED
@@ -45,8 +45,8 @@ upscaler_path = hf_hub_download(
45
  )
46
  CFG["spatial_upscaler_model_path"] = upscaler_path
47
 
48
- # --- Khởi tạo pipeline trên CPU ban đầu ---
49
- print("Khởi tạo LTX Video pipeline trên CPU…")
50
  pipeline = create_ltx_video_pipeline(
51
  ckpt_path=CFG["checkpoint_path"],
52
  precision=CFG["precision"],
@@ -57,10 +57,10 @@ pipeline = create_ltx_video_pipeline(
57
  prompt_enhancer_image_caption_model_name_or_path=CFG["prompt_enhancer_image_caption_model_name_or_path"],
58
  prompt_enhancer_llm_model_name_or_path=CFG["prompt_enhancer_llm_model_name_or_path"],
59
  )
60
- print("Pipeline sẵn sàng.")
61
  print("Khởi tạo latent upsampler trên CPU…")
62
  upsampler = create_latent_upsampler(CFG["spatial_upscaler_model_path"], device="cpu")
63
- print("Latent upsampler sẵn sàng.")
64
 
65
  # --- Các thông số cố định ---
66
  FPS = 30.0
@@ -78,13 +78,12 @@ def calculate_new_dimensions(w, h):
78
  else:
79
  nw = TARGET_SIDE
80
  nh = round((nw * h/w)/32)*32
81
- return (
82
  int(max(MIN_DIM, min(nh, MAX_RES))),
83
  int(max(MIN_DIM, min(nw, MAX_RES)))
84
  )
85
 
86
  def get_duration(*args, **kwargs):
87
- # spaces.GPU yêu cầu
88
  return 75 if kwargs.get("duration_ui",0) > 7 else 60
89
 
90
  @spaces.GPU(duration=get_duration)
@@ -95,29 +94,29 @@ def generate(prompt, neg_prompt,
95
  seed, rand_seed, cfg_scale,
96
  improve_tex, device_choice,
97
  progress=gr.Progress(track_tqdm=True)):
98
- # 1) Chuyển pipeline & upsampler theo lựa chọn
99
  dev = "cuda" if device_choice=="GPU" and torch.cuda.is_available() else "cpu"
100
  print(f"Chạy trên thiết bị: {dev}")
101
  pipeline.to(dev)
102
  upsampler.to(dev)
103
 
104
- # 2) Xử seed
105
  if rand_seed:
106
  seed = random.randint(0, 2**32-1)
107
  seed_everething(int(seed))
108
 
109
- # 3) Tính số frame
110
  tf = max(1, round(duration_ui*FPS))
111
  n8 = round((tf-1)/8)
112
  n_frames = max(9, min(n8*8+1, MAX_NUM_FRAMES))
113
 
114
- # 4) Padding kích thước
115
  h, w = int(height), int(width)
116
  h32 = ((h-1)//32+1)*32
117
  w32 = ((w-1)//32+1)*32
118
  pad = calculate_padding(h, w, h32, w32)
119
 
120
- # 5) Chuẩn bị kwargs
121
  kwargs = {
122
  "prompt": prompt,
123
  "negative_prompt": neg_prompt,
@@ -136,7 +135,7 @@ def generate(prompt, neg_prompt,
136
  "offload_to_cpu": False,
137
  "enhance_prompt": False,
138
  }
139
- # skip strategy
140
  stg = CFG.get("stg_mode","attention_values").lower()
141
  mapping = {
142
  "stg_av":SkipLayerStrategy.AttentionValues,
@@ -150,7 +149,7 @@ def generate(prompt, neg_prompt,
150
  }
151
  kwargs["skip_layer_strategy"] = mapping.get(stg, SkipLayerStrategy.AttentionValues)
152
 
153
- # 6) Conditioning
154
  if mode_task=="image-to-video" and img_path:
155
  tensor = load_image_to_tensor_with_resize_and_crop(img_path, h, w)
156
  tensor = torch.nn.functional.pad(tensor, pad)
@@ -159,7 +158,7 @@ def generate(prompt, neg_prompt,
159
  mi = load_media_file(vid_path, h, w, int(frames_to_use), pad).to(dev)
160
  kwargs["media_items"] = mi
161
 
162
- # 7) Chọn multi-scale hay single
163
  if improve_tex:
164
  pipe_ms = LTXMultiScalePipeline(pipeline, upsampler)
165
  fp = CFG.get("first_pass",{}).copy()
@@ -187,11 +186,11 @@ def generate(prompt, neg_prompt,
187
  kwargs.pop(k, None)
188
  out = pipeline(**kwargs).images
189
 
190
- # 8) Xử kết quả, bỏ padding, lưu video
191
- pad_l,pad_r,pad_t,pad_b = pad
192
- sh = None if pad_b==0 else -pad_b
193
- sw = None if pad_r==0 else -pad_r
194
- vid_tensor = out[0][:,:,:n_frames,pad_t:sh,pad_l:sw]
195
  arr = vid_tensor.permute(1,2,3,0).cpu().numpy()
196
  arr = (np.clip(arr,0,1)*255).astype(np.uint8)
197
 
@@ -218,56 +217,52 @@ with gr.Blocks(css=css) as demo:
218
  with gr.Column():
219
  # Chọn thiết bị
220
  device = gr.Radio(["CPU","GPU"], label="Chạy trên thiết bị", value="CPU")
 
221
  # Tabs
222
  with gr.Tab("Ảnh→Video"):
223
- img_in = gr.Image(label="Ảnh đầu vào", type="filepath", source="upload")
224
  prompt1 = gr.Textbox(label="Mô tả", lines=2, value="Con sinh vật di chuyển")
225
- btn1 = gr.Button("Tạo từ ảnh")
 
226
  with gr.Tab("Văn bản→Video"):
227
  prompt2 = gr.Textbox(label="Mô tả", lines=2, value="Rồng bay trên lâu đài")
228
- btn2 = gr.Button("Tạo từ văn bản")
 
229
  with gr.Tab("Video→Video"):
230
- vid_in = gr.Video(label="Video đầu vào", source="upload")
231
  frames = gr.Slider(label="Số frame dùng", minimum=9, maximum=MAX_NUM_FRAMES, step=8, value=9)
232
  prompt3 = gr.Textbox(label="Mô tả", lines=2, value="Chuyển phong cách anime")
233
- btn3 = gr.Button("Tạo từ video")
234
 
235
  duration = gr.Slider(label="Thời lượng (giây)", minimum=0.3, maximum=8.5, step=0.1, value=2)
236
- improve = gr.Checkbox(label="Cải thiện chi tiết", value=True)
237
 
238
  with gr.Column():
239
  out_video = gr.Video(label="Kết quả", interactive=False)
240
 
241
- # Ẩn mode, reuse chung
242
- mode = gr.State("image-to-video")
243
- # Nút
 
 
 
 
 
244
  btn1.click(fn=generate,
245
- inputs=[prompt1, gr.State(""), img_in, gr.State(""),
246
- height := gr.State(512), width := gr.State(704),
247
- mode := gr.State("image-to-video"),
248
- duration, frames,
249
- seed := gr.State(42), gr.State(True),
250
- cfg_scale := gr.State(CFG["first_pass"]["guidance_scale"]),
251
- improve, device],
252
- outputs=[out_video, seed])
253
  btn2.click(fn=generate,
254
- inputs=[prompt2, gr.State(""), gr.State(""), gr.State(""),
255
- height, width,
256
- mode := gr.State("text-to-video"),
257
- duration, frames,
258
- seed, gr.State(True),
259
- cfg_scale,
260
- improve, device],
261
- outputs=[out_video, seed])
262
  btn3.click(fn=generate,
263
- inputs=[prompt3, gr.State(""), gr.State(""), vid_in,
264
- height, width,
265
- mode := gr.State("video-to-video"),
266
- duration, frames,
267
- seed, gr.State(True),
268
- cfg_scale,
269
- improve, device],
270
- outputs=[out_video, seed])
271
 
272
  if __name__ == "__main__":
273
  demo.queue().launch(debug=True, share=False)
 
45
  )
46
  CFG["spatial_upscaler_model_path"] = upscaler_path
47
 
48
+ # --- Khởi tạo pipeline và upsampler trên CPU ban đầu ---
49
+ print("Khởi tạo pipeline trên CPU…")
50
  pipeline = create_ltx_video_pipeline(
51
  ckpt_path=CFG["checkpoint_path"],
52
  precision=CFG["precision"],
 
57
  prompt_enhancer_image_caption_model_name_or_path=CFG["prompt_enhancer_image_caption_model_name_or_path"],
58
  prompt_enhancer_llm_model_name_or_path=CFG["prompt_enhancer_llm_model_name_or_path"],
59
  )
60
+ print("Pipeline sẵn sàng trên CPU.")
61
  print("Khởi tạo latent upsampler trên CPU…")
62
  upsampler = create_latent_upsampler(CFG["spatial_upscaler_model_path"], device="cpu")
63
+ print("Latent upsampler sẵn sàng trên CPU.")
64
 
65
  # --- Các thông số cố định ---
66
  FPS = 30.0
 
78
  else:
79
  nw = TARGET_SIDE
80
  nh = round((nw * h/w)/32)*32
81
+ return (
82
  int(max(MIN_DIM, min(nh, MAX_RES))),
83
  int(max(MIN_DIM, min(nw, MAX_RES)))
84
  )
85
 
86
  def get_duration(*args, **kwargs):
 
87
  return 75 if kwargs.get("duration_ui",0) > 7 else 60
88
 
89
  @spaces.GPU(duration=get_duration)
 
94
  seed, rand_seed, cfg_scale,
95
  improve_tex, device_choice,
96
  progress=gr.Progress(track_tqdm=True)):
97
+ # Chọn thiết bị
98
  dev = "cuda" if device_choice=="GPU" and torch.cuda.is_available() else "cpu"
99
  print(f"Chạy trên thiết bị: {dev}")
100
  pipeline.to(dev)
101
  upsampler.to(dev)
102
 
103
+ # Seed
104
  if rand_seed:
105
  seed = random.randint(0, 2**32-1)
106
  seed_everething(int(seed))
107
 
108
+ # Tính số frame
109
  tf = max(1, round(duration_ui*FPS))
110
  n8 = round((tf-1)/8)
111
  n_frames = max(9, min(n8*8+1, MAX_NUM_FRAMES))
112
 
113
+ # Padding kích thước
114
  h, w = int(height), int(width)
115
  h32 = ((h-1)//32+1)*32
116
  w32 = ((w-1)//32+1)*32
117
  pad = calculate_padding(h, w, h32, w32)
118
 
119
+ # Chuẩn bị kwargs
120
  kwargs = {
121
  "prompt": prompt,
122
  "negative_prompt": neg_prompt,
 
135
  "offload_to_cpu": False,
136
  "enhance_prompt": False,
137
  }
138
+ # Skip-layer strategy
139
  stg = CFG.get("stg_mode","attention_values").lower()
140
  mapping = {
141
  "stg_av":SkipLayerStrategy.AttentionValues,
 
149
  }
150
  kwargs["skip_layer_strategy"] = mapping.get(stg, SkipLayerStrategy.AttentionValues)
151
 
152
+ # Conditioning
153
  if mode_task=="image-to-video" and img_path:
154
  tensor = load_image_to_tensor_with_resize_and_crop(img_path, h, w)
155
  tensor = torch.nn.functional.pad(tensor, pad)
 
158
  mi = load_media_file(vid_path, h, w, int(frames_to_use), pad).to(dev)
159
  kwargs["media_items"] = mi
160
 
161
+ # Multi-scale hay single?
162
  if improve_tex:
163
  pipe_ms = LTXMultiScalePipeline(pipeline, upsampler)
164
  fp = CFG.get("first_pass",{}).copy()
 
186
  kwargs.pop(k, None)
187
  out = pipeline(**kwargs).images
188
 
189
+ # Loại padding, lưu video
190
+ l, r, t, b = pad
191
+ sh = None if b==0 else -b
192
+ sw = None if r==0 else -r
193
+ vid_tensor = out[0][:,:,:n_frames,t:sh,l:sw]
194
  arr = vid_tensor.permute(1,2,3,0).cpu().numpy()
195
  arr = (np.clip(arr,0,1)*255).astype(np.uint8)
196
 
 
217
  with gr.Column():
218
  # Chọn thiết bị
219
  device = gr.Radio(["CPU","GPU"], label="Chạy trên thiết bị", value="CPU")
220
+
221
  # Tabs
222
  with gr.Tab("Ảnh→Video"):
223
+ img_in = gr.Image(label="Ảnh đầu vào", type="filepath", sources=["upload","clipboard","webcam"])
224
  prompt1 = gr.Textbox(label="Mô tả", lines=2, value="Con sinh vật di chuyển")
225
+ btn1 = gr.Button("Tạo từ ảnh")
226
+
227
  with gr.Tab("Văn bản→Video"):
228
  prompt2 = gr.Textbox(label="Mô tả", lines=2, value="Rồng bay trên lâu đài")
229
+ btn2 = gr.Button("Tạo từ văn bản")
230
+
231
  with gr.Tab("Video→Video"):
232
+ vid_in = gr.Video(label="Video đầu vào", type="filepath", sources=["upload","webcam"])
233
  frames = gr.Slider(label="Số frame dùng", minimum=9, maximum=MAX_NUM_FRAMES, step=8, value=9)
234
  prompt3 = gr.Textbox(label="Mô tả", lines=2, value="Chuyển phong cách anime")
235
+ btn3 = gr.Button("Tạo từ video")
236
 
237
  duration = gr.Slider(label="Thời lượng (giây)", minimum=0.3, maximum=8.5, step=0.1, value=2)
238
+ improve = gr.Checkbox(label="Cải thiện chi tiết", value=True)
239
 
240
  with gr.Column():
241
  out_video = gr.Video(label="Kết quả", interactive=False)
242
 
243
+ # Trạng thái ẩn để điều khiển mode seed
244
+ mode_state = gr.State("image-to-video")
245
+ seed_state = gr.State(42)
246
+ neg_prompt = gr.State("worst quality, inconsistent motion, blurry, jittery, distorted")
247
+ cfg_scale_st = gr.State(CFG["first_pass"]["guidance_scale"])
248
+ height_st = gr.State(512)
249
+ width_st = gr.State(704)
250
+
251
  btn1.click(fn=generate,
252
+ inputs=[prompt1, neg_prompt, img_in, gr.State(""), height_st, width_st,
253
+ mode_state, duration, frames, seed_state, gr.State(True),
254
+ cfg_scale_st, improve, device],
255
+ outputs=[out_video, seed_state])
 
 
 
 
256
  btn2.click(fn=generate,
257
+ inputs=[prompt2, neg_prompt, gr.State(""), gr.State(""), height_st, width_st,
258
+ mode_state, duration, frames, seed_state, gr.State(True),
259
+ cfg_scale_st, improve, device],
260
+ outputs=[out_video, seed_state])
 
 
 
 
261
  btn3.click(fn=generate,
262
+ inputs=[prompt3, neg_prompt, gr.State(""), vid_in, height_st, width_st,
263
+ mode_state, duration, frames, seed_state, gr.State(True),
264
+ cfg_scale_st, improve, device],
265
+ outputs=[out_video, seed_state])
 
 
 
 
266
 
267
  if __name__ == "__main__":
268
  demo.queue().launch(debug=True, share=False)