Fabrice-TIERCELIN commited on
Commit
f8e6997
·
verified ·
1 Parent(s): f3f56fc

#@spaces.GPU(duration=1500)

Browse files
Files changed (1) hide show
  1. optimization.py +134 -134
optimization.py CHANGED
@@ -1,135 +1,135 @@
1
- """
2
- """
3
-
4
- from typing import Any
5
- from typing import Callable
6
- from typing import ParamSpec
7
-
8
- import spaces
9
- import torch
10
- from torch.utils._pytree import tree_map_only
11
- from torchao.quantization import quantize_
12
- from torchao.quantization import Float8DynamicActivationFloat8WeightConfig
13
- from torchao.quantization import Int8WeightOnlyConfig
14
-
15
- from optimization_utils import capture_component_call
16
- from optimization_utils import aoti_compile
17
- from optimization_utils import drain_module_parameters
18
-
19
-
20
- P = ParamSpec('P')
21
-
22
- # --- CORRECTED DYNAMIC SHAPING ---
23
-
24
- # VAE temporal scale factor is 1, latent_frames = num_frames. Range is [8, 81].
25
- LATENT_FRAMES_DIM = torch.export.Dim('num_latent_frames', min=8, max=81)
26
-
27
- # The transformer has a patch_size of (1, 2, 2), which means the input latent height and width
28
- # are effectively divided by 2. This creates constraints that fail if the symbolic tracer
29
- # assumes odd numbers are possible.
30
- #
31
- # To solve this, we define the dynamic dimension for the *patched* (i.e., post-division) size,
32
- # and then express the input shape as 2 * this dimension. This mathematically guarantees
33
- # to the compiler that the input latent dimensions are always even, satisfying the constraints.
34
-
35
- # App range for pixel dimensions: [480, 832]. VAE scale factor is 8.
36
- # Latent dimension range: [480/8, 832/8] = [60, 104].
37
- # Patched latent dimension range: [60/2, 104/2] = [30, 52].
38
- LATENT_PATCHED_HEIGHT_DIM = torch.export.Dim('latent_patched_height', min=30, max=52)
39
- LATENT_PATCHED_WIDTH_DIM = torch.export.Dim('latent_patched_width', min=30, max=52)
40
-
41
- # Now, we define the dynamic shapes for the transformer's `hidden_states` input,
42
- # which has the shape (batch_size, channels, num_frames, height, width).
43
- TRANSFORMER_DYNAMIC_SHAPES = {
44
- 'hidden_states': {
45
- 2: LATENT_FRAMES_DIM,
46
- 3: 2 * LATENT_PATCHED_HEIGHT_DIM, # Guarantees even height
47
- 4: 2 * LATENT_PATCHED_WIDTH_DIM, # Guarantees even width
48
- },
49
- }
50
-
51
- # --- END OF CORRECTION ---
52
-
53
-
54
- INDUCTOR_CONFIGS = {
55
- 'conv_1x1_as_mm': True,
56
- 'epilogue_fusion': False,
57
- 'coordinate_descent_tuning': True,
58
- 'coordinate_descent_check_all_directions': True,
59
- 'max_autotune': True,
60
- 'triton.cudagraphs': True,
61
- }
62
-
63
-
64
- def optimize_pipeline_(pipeline: Callable[P, Any], *args: P.args, **kwargs: P.kwargs):
65
-
66
- @spaces.GPU(duration=1500)
67
- def compile_transformer():
68
- print("Start compile_transformer()")
69
-
70
- # This LoRA fusion part remains the same
71
- pipeline.load_lora_weights(
72
- "Kijai/WanVideo_comfy",
73
- weight_name="Lightx2v/lightx2v_I2V_14B_480p_cfg_step_distill_rank128_bf16.safetensors",
74
- adapter_name="lightx2v"
75
- )
76
- kwargs_lora = {}
77
- kwargs_lora["load_into_transformer_2"] = True
78
- pipeline.load_lora_weights(
79
- "Kijai/WanVideo_comfy",
80
- weight_name="Lightx2v/lightx2v_I2V_14B_480p_cfg_step_distill_rank128_bf16.safetensors",
81
- adapter_name="lightx2v_2", **kwargs_lora
82
- )
83
- pipeline.set_adapters(["lightx2v", "lightx2v_2"], adapter_weights=[1., 1.])
84
- pipeline.fuse_lora(adapter_names=["lightx2v"], lora_scale=3., components=["transformer"])
85
- pipeline.fuse_lora(adapter_names=["lightx2v_2"], lora_scale=1., components=["transformer_2"])
86
- pipeline.unload_lora_weights()
87
-
88
- # Capture a single call to get the args/kwargs structure
89
- with capture_component_call(pipeline, 'transformer') as call:
90
- pipeline(*args, **kwargs)
91
-
92
- dynamic_shapes = tree_map_only((torch.Tensor, bool), lambda t: None, call.kwargs)
93
- dynamic_shapes |= TRANSFORMER_DYNAMIC_SHAPES
94
-
95
- # Quantization remains the same
96
- quantize_(pipeline.transformer, Float8DynamicActivationFloat8WeightConfig())
97
- quantize_(pipeline.transformer_2, Float8DynamicActivationFloat8WeightConfig())
98
-
99
- # --- SIMPLIFIED COMPILATION ---
100
-
101
- exported_1 = torch.export.export(
102
- mod=pipeline.transformer,
103
- args=call.args,
104
- kwargs=call.kwargs,
105
- dynamic_shapes=dynamic_shapes,
106
- )
107
-
108
- exported_2 = torch.export.export(
109
- mod=pipeline.transformer_2,
110
- args=call.args,
111
- kwargs=call.kwargs,
112
- dynamic_shapes=dynamic_shapes,
113
- )
114
-
115
- compiled_1 = aoti_compile(exported_1, INDUCTOR_CONFIGS)
116
- compiled_2 = aoti_compile(exported_2, INDUCTOR_CONFIGS)
117
-
118
- # Return the two compiled models
119
- print("End compile_transformer()")
120
- return compiled_1, compiled_2
121
-
122
-
123
- # Quantize text encoder (same as before)
124
- quantize_(pipeline.text_encoder, Int8WeightOnlyConfig())
125
-
126
- # Get the two dynamically-shaped compiled models
127
- compiled_transformer_1, compiled_transformer_2 = compile_transformer()
128
-
129
- # --- SIMPLIFIED ASSIGNMENT ---
130
-
131
- pipeline.transformer.forward = compiled_transformer_1
132
- drain_module_parameters(pipeline.transformer)
133
-
134
- pipeline.transformer_2.forward = compiled_transformer_2
135
  drain_module_parameters(pipeline.transformer_2)
 
1
+ """
2
+ """
3
+
4
+ from typing import Any
5
+ from typing import Callable
6
+ from typing import ParamSpec
7
+
8
+ import spaces
9
+ import torch
10
+ from torch.utils._pytree import tree_map_only
11
+ from torchao.quantization import quantize_
12
+ from torchao.quantization import Float8DynamicActivationFloat8WeightConfig
13
+ from torchao.quantization import Int8WeightOnlyConfig
14
+
15
+ from optimization_utils import capture_component_call
16
+ from optimization_utils import aoti_compile
17
+ from optimization_utils import drain_module_parameters
18
+
19
+
20
+ P = ParamSpec('P')
21
+
22
+ # --- CORRECTED DYNAMIC SHAPING ---
23
+
24
+ # VAE temporal scale factor is 1, latent_frames = num_frames. Range is [8, 81].
25
+ LATENT_FRAMES_DIM = torch.export.Dim('num_latent_frames', min=8, max=81)
26
+
27
+ # The transformer has a patch_size of (1, 2, 2), which means the input latent height and width
28
+ # are effectively divided by 2. This creates constraints that fail if the symbolic tracer
29
+ # assumes odd numbers are possible.
30
+ #
31
+ # To solve this, we define the dynamic dimension for the *patched* (i.e., post-division) size,
32
+ # and then express the input shape as 2 * this dimension. This mathematically guarantees
33
+ # to the compiler that the input latent dimensions are always even, satisfying the constraints.
34
+
35
+ # App range for pixel dimensions: [480, 832]. VAE scale factor is 8.
36
+ # Latent dimension range: [480/8, 832/8] = [60, 104].
37
+ # Patched latent dimension range: [60/2, 104/2] = [30, 52].
38
+ LATENT_PATCHED_HEIGHT_DIM = torch.export.Dim('latent_patched_height', min=30, max=52)
39
+ LATENT_PATCHED_WIDTH_DIM = torch.export.Dim('latent_patched_width', min=30, max=52)
40
+
41
+ # Now, we define the dynamic shapes for the transformer's `hidden_states` input,
42
+ # which has the shape (batch_size, channels, num_frames, height, width).
43
+ TRANSFORMER_DYNAMIC_SHAPES = {
44
+ 'hidden_states': {
45
+ 2: LATENT_FRAMES_DIM,
46
+ 3: 2 * LATENT_PATCHED_HEIGHT_DIM, # Guarantees even height
47
+ 4: 2 * LATENT_PATCHED_WIDTH_DIM, # Guarantees even width
48
+ },
49
+ }
50
+
51
+ # --- END OF CORRECTION ---
52
+
53
+
54
+ INDUCTOR_CONFIGS = {
55
+ 'conv_1x1_as_mm': True,
56
+ 'epilogue_fusion': False,
57
+ 'coordinate_descent_tuning': True,
58
+ 'coordinate_descent_check_all_directions': True,
59
+ 'max_autotune': True,
60
+ 'triton.cudagraphs': True,
61
+ }
62
+
63
+
64
+ def optimize_pipeline_(pipeline: Callable[P, Any], *args: P.args, **kwargs: P.kwargs):
65
+
66
+ #@spaces.GPU(duration=1500)
67
+ def compile_transformer():
68
+ print("Start compile_transformer()")
69
+
70
+ # This LoRA fusion part remains the same
71
+ pipeline.load_lora_weights(
72
+ "Kijai/WanVideo_comfy",
73
+ weight_name="Lightx2v/lightx2v_I2V_14B_480p_cfg_step_distill_rank128_bf16.safetensors",
74
+ adapter_name="lightx2v"
75
+ )
76
+ kwargs_lora = {}
77
+ kwargs_lora["load_into_transformer_2"] = True
78
+ pipeline.load_lora_weights(
79
+ "Kijai/WanVideo_comfy",
80
+ weight_name="Lightx2v/lightx2v_I2V_14B_480p_cfg_step_distill_rank128_bf16.safetensors",
81
+ adapter_name="lightx2v_2", **kwargs_lora
82
+ )
83
+ pipeline.set_adapters(["lightx2v", "lightx2v_2"], adapter_weights=[1., 1.])
84
+ pipeline.fuse_lora(adapter_names=["lightx2v"], lora_scale=3., components=["transformer"])
85
+ pipeline.fuse_lora(adapter_names=["lightx2v_2"], lora_scale=1., components=["transformer_2"])
86
+ pipeline.unload_lora_weights()
87
+
88
+ # Capture a single call to get the args/kwargs structure
89
+ with capture_component_call(pipeline, 'transformer') as call:
90
+ pipeline(*args, **kwargs)
91
+
92
+ dynamic_shapes = tree_map_only((torch.Tensor, bool), lambda t: None, call.kwargs)
93
+ dynamic_shapes |= TRANSFORMER_DYNAMIC_SHAPES
94
+
95
+ # Quantization remains the same
96
+ quantize_(pipeline.transformer, Float8DynamicActivationFloat8WeightConfig())
97
+ quantize_(pipeline.transformer_2, Float8DynamicActivationFloat8WeightConfig())
98
+
99
+ # --- SIMPLIFIED COMPILATION ---
100
+
101
+ exported_1 = torch.export.export(
102
+ mod=pipeline.transformer,
103
+ args=call.args,
104
+ kwargs=call.kwargs,
105
+ dynamic_shapes=dynamic_shapes,
106
+ )
107
+
108
+ exported_2 = torch.export.export(
109
+ mod=pipeline.transformer_2,
110
+ args=call.args,
111
+ kwargs=call.kwargs,
112
+ dynamic_shapes=dynamic_shapes,
113
+ )
114
+
115
+ compiled_1 = aoti_compile(exported_1, INDUCTOR_CONFIGS)
116
+ compiled_2 = aoti_compile(exported_2, INDUCTOR_CONFIGS)
117
+
118
+ # Return the two compiled models
119
+ print("End compile_transformer()")
120
+ return compiled_1, compiled_2
121
+
122
+
123
+ # Quantize text encoder (same as before)
124
+ quantize_(pipeline.text_encoder, Int8WeightOnlyConfig())
125
+
126
+ # Get the two dynamically-shaped compiled models
127
+ compiled_transformer_1, compiled_transformer_2 = compile_transformer()
128
+
129
+ # --- SIMPLIFIED ASSIGNMENT ---
130
+
131
+ pipeline.transformer.forward = compiled_transformer_1
132
+ drain_module_parameters(pipeline.transformer)
133
+
134
+ pipeline.transformer_2.forward = compiled_transformer_2
135
  drain_module_parameters(pipeline.transformer_2)