euIaxs22 commited on
Commit
28eef4f
·
verified ·
1 Parent(s): 63e5350

Update app_vince.py

Browse files
Files changed (1) hide show
  1. app_vince.py +45 -60
app_vince.py CHANGED
@@ -3,7 +3,7 @@ import sys
3
  import torch
4
  import gradio as gr
5
  from PIL import Image
6
- from omegaconf import OmegaConf # Garantir que OmegaConf está importado
7
 
8
  # --- ETAPA 1: CONFIGURAÇÃO DO AMBIENTE ---
9
 
@@ -20,46 +20,55 @@ except ImportError as e:
20
  print(f"Verifique se o diretório '{VINCIE_DIR}' contém o código-fonte clonado.")
21
  raise e
22
 
23
- # --- ETAPA 2: INICIALIZAÇÃO E PARALELIZAÇÃO DO MODELO ---
24
- # (Esta seção permanece inalterada)
25
 
26
  MODEL: VINCIEGenerator = None
27
- DEVICE_PRIMARY: torch.device = None
28
 
29
  def setup_model():
30
- # ... (código de setup_model idêntico à versão anterior)
31
- global MODEL, DEVICE_PRIMARY
 
 
 
32
  if not torch.cuda.is_available():
33
  raise RuntimeError("FATAL: Nenhuma GPU compatível com CUDA foi encontrada.")
 
34
  num_gpus = torch.cuda.device_count()
35
- print(f"INFO: Detectadas {num_gpus} GPUs.")
36
  if num_gpus == 0:
37
  raise RuntimeError("FATAL: Nenhuma GPU foi alocada para este contêiner.")
38
- DEVICE_PRIMARY = torch.device("cuda:0")
39
- torch.cuda.set_device(DEVICE_PRIMARY)
 
 
40
  config_path = "configs/generate.yaml"
41
  print(f"INFO: Carregando e resolvendo configuração do modelo de '{config_path}'...")
42
  config = load_config(config_path, [])
 
43
  print("INFO: Instanciando VINCIEGenerator...")
44
  model_instance = VINCIEGenerator(config)
 
45
  print("INFO: Configurando a persistência (modo de inferência)...")
46
  model_instance.configure_persistence()
47
- print("INFO: Configurando os componentes do modelo...")
 
 
48
  model_instance.configure_models()
 
49
  print("INFO: Configurando os componentes de difusão...")
50
  model_instance.configure_diffusion()
 
51
  if not hasattr(model_instance, 'dit'):
52
  raise RuntimeError("FATAL: O modelo 'dit' não foi criado após a configuração.")
53
- model_instance.dit.to(DEVICE_PRIMARY)
54
- model_instance.vae.to(DEVICE_PRIMARY)
55
- model_instance.text_encoder.to(DEVICE_PRIMARY)
56
- print("INFO: Modelos carregados com sucesso na GPU primária.")
57
- if num_gpus > 1:
58
- print(f"INFO: Ativando torch.nn.DataParallel para distribuir a carga entre {num_gpus} GPUs...")
59
- model_instance.dit = torch.nn.DataParallel(model_instance.dit)
60
- print("INFO: DataParallel ativado no modelo DiT.")
61
  MODEL = model_instance
62
- print("✅ SUCESSO: O modelo VINCIE está pronto para receber requisições.")
63
 
64
 
65
  # --- ETAPA 3: LÓGICA DE INFERÊNCIA ---
@@ -69,26 +78,23 @@ def perform_inference(input_image: str, prompt: str):
69
  raise gr.Error("O modelo não está carregado. Verifique os logs de inicialização.")
70
  if input_image is None or not prompt.strip():
71
  raise gr.Error("É necessário fornecer uma imagem de entrada e um prompt de edição.")
 
72
  print(f"INFO: Recebida nova requisição. Prompt: '{prompt}'")
73
  turn_1_prompt = [prompt]
74
  image_paths = [input_image]
 
75
  try:
76
  print("INFO: Preparando entradas com `model.prepare_input()`...")
77
-
78
- # --- CORREÇÃO PRINCIPAL ---
79
- # Cria um dicionário Python padrão
80
  prompt_dict = {
81
- "index": 0,
82
- "img_paths": image_paths,
83
- "context": turn_1_prompt,
84
  }
85
- # Converte o dicionário para um OmegaConf DictConfig antes de passar para a função
86
  prompt_config = OmegaConf.create(prompt_dict)
87
 
88
  text_pos, condition, noise, _, _ = MODEL.prepare_input(
89
- prompt=prompt_config, # Passa o objeto DictConfig
90
  repeat_idx=0,
91
- device=DEVICE_PRIMARY
92
  )
93
 
94
  with torch.no_grad():
@@ -100,41 +106,34 @@ def perform_inference(input_image: str, prompt: str):
100
  texts_neg=[MODEL.config.generation.negative_prompt],
101
  )
102
  print("INFO: Inferência concluída.")
 
103
  if not samples:
104
  raise RuntimeError("A inferência não retornou nenhum resultado.")
 
105
  output_tensor = samples[0][:, -1, :, :]
106
  output_image = output_tensor.clip(-1, 1).add(1).div(2).mul(255).byte()
107
  output_image = output_image.permute(1, 2, 0).cpu().numpy()
 
108
  print("✅ SUCESSO: Imagem processada e retornada para a UI.")
109
  return output_image
 
110
  except Exception as e:
111
  print(f"ERRO: Falha durante a inferência: {e}")
112
  import traceback
113
  traceback.print_exc()
114
- raise gr.Error(f"Ocorreu um erro inesperado durante o processamento. Detalhes: {str(e)}")
115
 
116
 
117
- # --- ETAPA 4: CONSTRUÇÃO DA INTERFACE COM GRADIO ---
118
- # (Esta seção permanece inalterada)
119
 
120
  def create_ui():
121
- # ... (código de create_ui idêntico à versão anterior)
122
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), title="VINCIE Image Editor") as demo:
123
- gr.Markdown(
124
- """
125
- # 🖼️ **VINCIE: Editor de Imagens por Contexto**
126
- Faça o upload de uma imagem e descreva a edição que você deseja realizar.
127
- O modelo processará sua requisição usando múltiplas GPUs.
128
- """
129
- )
130
  with gr.Row():
131
  with gr.Column(scale=1):
132
  image_input = gr.Image(type="filepath", label="Imagem de Entrada")
133
- prompt_input = gr.Textbox(
134
- lines=3,
135
- label="O que você quer mudar?",
136
- placeholder="Exemplo: 'mude o fundo para uma praia ensolarada e adicione óculos de sol na pessoa'"
137
- )
138
  submit_button = gr.Button("✨ Gerar Edição", variant="primary")
139
  with gr.Column(scale=1):
140
  image_output = gr.Image(label="Resultado da Edição", interactive=False, height=512)
@@ -149,31 +148,17 @@ def create_ui():
149
  fn=perform_inference,
150
  cache_examples=False,
151
  )
152
- submit_button.click(
153
- fn=perform_inference,
154
- inputs=[image_input, prompt_input],
155
- outputs=[image_output]
156
- )
157
  return demo
158
 
159
-
160
- # --- ETAPA 5: PONTO DE ENTRADA DA APLICAÇÃO ---
161
-
162
  if __name__ == "__main__":
163
  setup_model()
164
  ui = create_ui()
165
-
166
  server_name = os.environ.get("GRADIO_SERVER_NAME", "127.0.0.1")
167
  server_port = int(os.environ.get("GRADIO_SERVER_PORT", 7860))
168
  enable_queue = os.environ.get("GRADIO_ENABLE_QUEUE", "True").lower() == "true"
169
-
170
  print(f"INFO: Lançando a interface Gradio em http://{server_name}:{server_port}")
171
-
172
  if enable_queue:
173
  print("INFO: Fila de requisições (queue) ativada.")
174
  ui.queue()
175
-
176
- ui.launch(
177
- server_name=server_name,
178
- server_port=server_port
179
- )
 
3
  import torch
4
  import gradio as gr
5
  from PIL import Image
6
+ from omegaconf import OmegaConf
7
 
8
  # --- ETAPA 1: CONFIGURAÇÃO DO AMBIENTE ---
9
 
 
20
  print(f"Verifique se o diretório '{VINCIE_DIR}' contém o código-fonte clonado.")
21
  raise e
22
 
23
+ # --- ETAPA 2: INICIALIZAÇÃO DO MODELO (Simplificado para uma GPU) ---
 
24
 
25
  MODEL: VINCIEGenerator = None
26
+ DEVICE: torch.device = None
27
 
28
  def setup_model():
29
+ """
30
+ Função de inicialização que carrega o modelo VINCIE em uma única GPU.
31
+ """
32
+ global MODEL, DEVICE
33
+
34
  if not torch.cuda.is_available():
35
  raise RuntimeError("FATAL: Nenhuma GPU compatível com CUDA foi encontrada.")
36
+
37
  num_gpus = torch.cuda.device_count()
38
+ print(f"INFO: Detectadas {num_gpus} GPUs. Usando cuda:0 para a aplicação.")
39
  if num_gpus == 0:
40
  raise RuntimeError("FATAL: Nenhuma GPU foi alocada para este contêiner.")
41
+
42
+ DEVICE = torch.device("cuda:0")
43
+ torch.cuda.set_device(DEVICE)
44
+
45
  config_path = "configs/generate.yaml"
46
  print(f"INFO: Carregando e resolvendo configuração do modelo de '{config_path}'...")
47
  config = load_config(config_path, [])
48
+
49
  print("INFO: Instanciando VINCIEGenerator...")
50
  model_instance = VINCIEGenerator(config)
51
+
52
  print("INFO: Configurando a persistência (modo de inferência)...")
53
  model_instance.configure_persistence()
54
+
55
+ print("INFO: Configurando os componentes do modelo (DiT, VAE, Text Encoder)...")
56
+ # O método `configure_models` já move os modelos para o dispositivo CUDA definido
57
  model_instance.configure_models()
58
+
59
  print("INFO: Configurando os componentes de difusão...")
60
  model_instance.configure_diffusion()
61
+
62
  if not hasattr(model_instance, 'dit'):
63
  raise RuntimeError("FATAL: O modelo 'dit' não foi criado após a configuração.")
64
+
65
+ # Opcional: garantir que tudo está no dispositivo correto (geralmente já feito)
66
+ model_instance.dit.to(DEVICE)
67
+ model_instance.vae.to(DEVICE)
68
+ model_instance.text_encoder.to(DEVICE)
69
+
 
 
70
  MODEL = model_instance
71
+ print(f"✅ SUCESSO: O modelo VINCIE está pronto na GPU {DEVICE}.")
72
 
73
 
74
  # --- ETAPA 3: LÓGICA DE INFERÊNCIA ---
 
78
  raise gr.Error("O modelo não está carregado. Verifique os logs de inicialização.")
79
  if input_image is None or not prompt.strip():
80
  raise gr.Error("É necessário fornecer uma imagem de entrada e um prompt de edição.")
81
+
82
  print(f"INFO: Recebida nova requisição. Prompt: '{prompt}'")
83
  turn_1_prompt = [prompt]
84
  image_paths = [input_image]
85
+
86
  try:
87
  print("INFO: Preparando entradas com `model.prepare_input()`...")
88
+
 
 
89
  prompt_dict = {
90
+ "index": 0, "img_paths": image_paths, "context": turn_1_prompt,
 
 
91
  }
 
92
  prompt_config = OmegaConf.create(prompt_dict)
93
 
94
  text_pos, condition, noise, _, _ = MODEL.prepare_input(
95
+ prompt=prompt_config,
96
  repeat_idx=0,
97
+ device=DEVICE # Usa o dispositivo único definido
98
  )
99
 
100
  with torch.no_grad():
 
106
  texts_neg=[MODEL.config.generation.negative_prompt],
107
  )
108
  print("INFO: Inferência concluída.")
109
+
110
  if not samples:
111
  raise RuntimeError("A inferência não retornou nenhum resultado.")
112
+
113
  output_tensor = samples[0][:, -1, :, :]
114
  output_image = output_tensor.clip(-1, 1).add(1).div(2).mul(255).byte()
115
  output_image = output_image.permute(1, 2, 0).cpu().numpy()
116
+
117
  print("✅ SUCESSO: Imagem processada e retornada para a UI.")
118
  return output_image
119
+
120
  except Exception as e:
121
  print(f"ERRO: Falha durante a inferência: {e}")
122
  import traceback
123
  traceback.print_exc()
124
+ raise gr.Error(f"Ocorreu um erro inesperado. Detalhes: {str(e)}")
125
 
126
 
127
+ # --- ETAPA 4 e 5: UI e Lançamento (sem alterações) ---
 
128
 
129
  def create_ui():
 
130
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), title="VINCIE Image Editor") as demo:
131
+ # ... (código da UI idêntico)
132
+ gr.Markdown("# 🖼️ **VINCIE: Editor de Imagens por Contexto**\nFaça o upload de uma imagem e descreva a edição que você deseja realizar.")
 
 
 
 
 
133
  with gr.Row():
134
  with gr.Column(scale=1):
135
  image_input = gr.Image(type="filepath", label="Imagem de Entrada")
136
+ prompt_input = gr.Textbox(lines=3, label="O que você quer mudar?", placeholder="Ex: 'mude o fundo para uma praia ensolarada'")
 
 
 
 
137
  submit_button = gr.Button("✨ Gerar Edição", variant="primary")
138
  with gr.Column(scale=1):
139
  image_output = gr.Image(label="Resultado da Edição", interactive=False, height=512)
 
148
  fn=perform_inference,
149
  cache_examples=False,
150
  )
151
+ submit_button.click(fn=perform_inference, inputs=[image_input, prompt_input], outputs=[image_output])
 
 
 
 
152
  return demo
153
 
 
 
 
154
  if __name__ == "__main__":
155
  setup_model()
156
  ui = create_ui()
 
157
  server_name = os.environ.get("GRADIO_SERVER_NAME", "127.0.0.1")
158
  server_port = int(os.environ.get("GRADIO_SERVER_PORT", 7860))
159
  enable_queue = os.environ.get("GRADIO_ENABLE_QUEUE", "True").lower() == "true"
 
160
  print(f"INFO: Lançando a interface Gradio em http://{server_name}:{server_port}")
 
161
  if enable_queue:
162
  print("INFO: Fila de requisições (queue) ativada.")
163
  ui.queue()
164
+ ui.launch(server_name=server_name, server_port=server_port)