Lisandro commited on
Commit
58f8f91
·
1 Parent(s): 9eefdd3

feat: Implement AOT optimization and add optimization module for enhanced pipeline performance

Browse files
Files changed (4) hide show
  1. .gitattributes +1 -4
  2. app.py +29 -33
  3. optimization.py +57 -0
  4. requirements.txt +1 -0
.gitattributes CHANGED
@@ -38,11 +38,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
38
  *.safetensors binary
39
  *.pt binary
40
  *.pth binary
41
- *.pt2 binary
42
  *.zip binary
43
  aoti_artifacts/** binary
44
-
45
- # Forzar texto LF en archivos de código
46
  *.py text eol=lf
47
  *.json text eol=lf
48
- *.txt text eol=lf
 
38
  *.safetensors binary
39
  *.pt binary
40
  *.pth binary
 
41
  *.zip binary
42
  aoti_artifacts/** binary
 
 
43
  *.py text eol=lf
44
  *.json text eol=lf
45
+ *.txt text eol=lf
app.py CHANGED
@@ -14,7 +14,9 @@ import re
14
  import math
15
  import numpy as np
16
  import traceback
17
- from spaces import aoti_capture, aoti_compile, aoti_apply # ✅ agregado para AOT
 
 
18
 
19
  # Load LoRAs from JSON file
20
  def load_loras_from_file():
@@ -60,38 +62,22 @@ pipe = DiffusionPipeline.from_pretrained(
60
  base_model, scheduler=scheduler, torch_dtype=dtype
61
  ).to(device)
62
 
63
- # =========================================================
64
- # ✅ INTEGRACIÓN AOT (sin modificar nada más)
65
- # =========================================================
66
- AOT_DIR = "./aoti_artifacts"
67
- EXAMPLE_PROMPT = "a cute cat in a spacesuit"
68
-
69
- if torch.cuda.is_available():
70
- try:
71
- if os.environ.get("SPACE_BUILD") == "1":
72
- print("🏗️ Space build detected. Compiling AOT artifacts...")
73
- example_inputs = aoti_capture(
74
- pipe,
75
- inputs={
76
- "prompt": EXAMPLE_PROMPT,
77
- "num_inference_steps": 4,
78
- "true_cfg_scale": 3.5,
79
- "width": 1024,
80
- "height": 1024,
81
- "num_images_per_prompt": 1,
82
- },
83
- )
84
- aoti_compile(pipe, example_inputs, output_dir=AOT_DIR, dynamic=False)
85
- print("✅ AOT compilation completed successfully.")
86
- else:
87
- if os.path.exists(AOT_DIR):
88
- pipe = aoti_apply(pipe, AOT_DIR)
89
- print("✅ Loaded precompiled AOT model.")
90
- else:
91
- print("⚠️ No AOT artifacts found, running in normal mode.")
92
- except Exception as e:
93
- print(f"⚠️ Skipping AOT setup: {e}")
94
- # =========================================================
95
 
96
  # Lightning LoRA info (no global state)
97
  LIGHTNING_LORA_REPO = "lightx2v/Qwen-Image-Lightning"
@@ -133,6 +119,16 @@ class calculateDuration:
133
  else:
134
  print(f"Elapsed time: {self.elapsed_time:.6f} seconds")
135
 
 
 
 
 
 
 
 
 
 
 
136
  # (El resto de tu código sigue idéntico)
137
 
138
  # =========================================================
 
14
  import math
15
  import numpy as np
16
  import traceback
17
+
18
+ # ✅ NUEVO: importar optimización avanzada tipo Qwen-Image-MultipleAngles
19
+ from optimization import optimize_pipeline_
20
 
21
  # Load LoRAs from JSON file
22
  def load_loras_from_file():
 
62
  base_model, scheduler=scheduler, torch_dtype=dtype
63
  ).to(device)
64
 
65
+ # ✅ NUEVO BLOQUE: aplicar AOT optimization (igual que Qwen-Image-MultipleAngles)
66
+ try:
67
+ example_args = (
68
+ "a cute cat in a spacesuit",
69
+ )
70
+ example_kwargs = dict(
71
+ num_inference_steps=4,
72
+ true_cfg_scale=3.5,
73
+ width=1024,
74
+ height=1024,
75
+ num_images_per_prompt=1,
76
+ )
77
+ optimize_pipeline_(pipe, *example_args, **example_kwargs)
78
+ print(" Transformer AOT optimization complete.")
79
+ except Exception as e:
80
+ print(f"⚠️ AOT optimization skipped: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  # Lightning LoRA info (no global state)
83
  LIGHTNING_LORA_REPO = "lightx2v/Qwen-Image-Lightning"
 
119
  else:
120
  print(f"Elapsed time: {self.elapsed_time:.6f} seconds")
121
 
122
+ # ⚠️ Desde acá sigue todo EXACTAMENTE igual a tu versión original:
123
+ # get_image_size, update_selection, handle_speed_mode, generate_image,
124
+ # run_lora, get_huggingface_safetensors, check_custom_model, add_custom_lora,
125
+ # remove_custom_lora, y toda la UI con gr.Blocks()
126
+ # (no se modificó ni una línea del layout ni los handlers)
127
+ # 👇👇👇
128
+
129
+ # (pegar el resto de tu archivo completo original aquí sin tocar nada)
130
+
131
+
132
  # (El resto de tu código sigue idéntico)
133
 
134
  # =========================================================
optimization.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any
2
+ from typing import Callable
3
+ from typing import ParamSpec
4
+ from torchao.quantization import quantize_
5
+ from torchao.quantization import Float8DynamicActivationFloat8WeightConfig
6
+ import spaces
7
+ import torch
8
+ from torch.utils._pytree import tree_map
9
+
10
+ P = ParamSpec('P')
11
+
12
+ TRANSFORMER_IMAGE_SEQ_LENGTH_DIM = torch.export.Dim('image_seq_length')
13
+ TRANSFORMER_TEXT_SEQ_LENGTH_DIM = torch.export.Dim('text_seq_length')
14
+
15
+ TRANSFORMER_DYNAMIC_SHAPES = {
16
+ 'hidden_states': {
17
+ 1: TRANSFORMER_IMAGE_SEQ_LENGTH_DIM,
18
+ },
19
+ 'encoder_hidden_states': {
20
+ 1: TRANSFORMER_TEXT_SEQ_LENGTH_DIM,
21
+ },
22
+ 'encoder_hidden_states_mask': {
23
+ 1: TRANSFORMER_TEXT_SEQ_LENGTH_DIM,
24
+ },
25
+ 'image_rotary_emb': ({
26
+ 0: TRANSFORMER_IMAGE_SEQ_LENGTH_DIM,
27
+ }, {
28
+ 0: TRANSFORMER_TEXT_SEQ_LENGTH_DIM,
29
+ }),
30
+ }
31
+
32
+ INDUCTOR_CONFIGS = {
33
+ 'conv_1x1_as_mm': True,
34
+ 'epilogue_fusion': False,
35
+ 'coordinate_descent_tuning': True,
36
+ 'coordinate_descent_check_all_directions': True,
37
+ 'max_autotune': True,
38
+ 'triton.cudagraphs': True,
39
+ }
40
+
41
+ def optimize_pipeline_(pipeline: Callable[P, Any], *args: P.args, **kwargs: P.kwargs):
42
+ @spaces.GPU(duration=1500)
43
+ def compile_transformer():
44
+ with spaces.aoti_capture(pipeline.transformer) as call:
45
+ pipeline(*args, **kwargs)
46
+ dynamic_shapes = tree_map(lambda t: None, call.kwargs)
47
+ dynamic_shapes |= TRANSFORMER_DYNAMIC_SHAPES
48
+ # quantize_(pipeline.transformer, Float8DynamicActivationFloat8WeightConfig())
49
+ exported = torch.export.export(
50
+ mod=pipeline.transformer,
51
+ args=call.args,
52
+ kwargs=call.kwargs,
53
+ dynamic_shapes=dynamic_shapes,
54
+ )
55
+ return spaces.aoti_compile(exported, INDUCTOR_CONFIGS)
56
+
57
+ spaces.aoti_apply(compile_transformer(), pipeline.transformer)
requirements.txt CHANGED
@@ -10,3 +10,4 @@ spaces
10
  huggingface_hub
11
  Pillow
12
  numpy
 
 
10
  huggingface_hub
11
  Pillow
12
  numpy
13
+ torchao