Aduc-sdr commited on
Commit
ec7e114
verified
1 Parent(s): 8c232e4

Update engineers/deformes7D.py

Browse files
Files changed (1) hide show
  1. engineers/deformes7D.py +33 -89
engineers/deformes7D.py CHANGED
@@ -1,32 +1,6 @@
1
  # engineers/deformes7D.py
2
- #
3
- # AducSdr: Uma implementa莽茫o aberta e funcional da arquitetura ADUC-SDR
4
- # Copyright (C) 4 de Agosto de 2025 Carlos Rodrigues dos Santos
5
  #
6
- # Contato:
7
- # Carlos Rodrigues dos Santos
8
- # carlex22@gmail.com
9
- # Rua Eduardo Carlos Pereira, 4125, B1 Ap32, Curitiba, PR, Brazil, CEP 8102025
10
- #
11
- # Reposit贸rios e Projetos Relacionados:
12
- # GitHub: https://github.com/carlex22/Aduc-sdr
13
- #
14
- # This program is free software: you can redistribute it and/or modify
15
- # it under the terms of the GNU Affero General Public License as published by
16
- # the Free Software Foundation, either version 3 of the License, or
17
- # (at your option) any later version.
18
- #
19
- # This program is distributed in the hope that it will be useful,
20
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
21
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
- # GNU Affero General Public License for more details.
23
- #
24
- # You should have received a copy of the GNU Affero General Public License
25
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
26
- #
27
- # This program is free software: you can redistribute it and/or modify
28
- # it under the terms of the GNU Affero General Public License...
29
- # PENDING PATENT NOTICE: Please see NOTICE.md.
30
  #
31
  # Version: 3.0.0
32
  #
@@ -47,7 +21,7 @@ import subprocess
47
  import gc
48
  import shutil
49
  from pathlib import Path
50
- from typing import List, Tuple, Generator, Dict, Any
51
 
52
  from aduc_types import LatentConditioningItem
53
  from managers.ltx_manager import ltx_manager_singleton
@@ -70,22 +44,19 @@ class Deformes7DEngine:
70
  logger.info("Deformes7D Unified Engine initialized.")
71
  os.makedirs(self.workspace_dir, exist_ok=True)
72
 
73
- # --- HELPER METHODS (from 3D and 4D engines) ---
74
 
75
  def _preprocess_image(self, image: Image.Image, target_resolution: tuple) -> Image.Image:
76
- """Resizes and fits an image to the target resolution."""
77
  if image.size != target_resolution:
78
  return ImageOps.fit(image, target_resolution, Image.Resampling.LANCZOS)
79
  return image
80
 
81
  def _pil_to_pixel_tensor(self, pil_image: Image.Image) -> torch.Tensor:
82
- """Converts PIL to the 5D pixel tensor for VAE encoding."""
83
  image_np = np.array(pil_image).astype(np.float32) / 255.0
84
  tensor = torch.from_numpy(image_np).permute(2, 0, 1).unsqueeze(0).unsqueeze(2)
85
  return (tensor * 2.0) - 1.0
86
 
87
  def _save_image_from_tensor(self, pixel_tensor: torch.Tensor, path: str):
88
- """Saves a 1-frame pixel tensor as a PNG image."""
89
  tensor_chw = pixel_tensor.squeeze(0).squeeze(1)
90
  tensor_hwc = tensor_chw.permute(1, 2, 0)
91
  tensor_hwc = (tensor_hwc.clamp(-1, 1) + 1) / 2.0
@@ -93,7 +64,6 @@ class Deformes7DEngine:
93
  Image.fromarray(image_np).save(path)
94
 
95
  def _quantize_to_multiple(self, n, m):
96
- """Helper to round n to the nearest multiple of m."""
97
  if m == 0: return n
98
  quantized = int(round(n / m) * m)
99
  return m if n > 0 and quantized == 0 else quantized
@@ -130,7 +100,6 @@ class Deformes7DEngine:
130
  upscaled_latent = latent_enhancer_specialist_singleton.upscale(final_latent)
131
  pixel_tensor_out = vae_manager_singleton.decode(upscaled_latent)
132
 
133
- # Save the new keyframe image
134
  timestamp = int(time.time() * 1000)
135
  output_path = os.path.join(self.workspace_dir, f"keyframe_{timestamp}.png")
136
  self._save_image_from_tensor(pixel_tensor_out, output_path)
@@ -144,7 +113,6 @@ class Deformes7DEngine:
144
  """
145
  The main interleaved rendering pipeline for Deformes7D.
146
  """
147
- # --- INITIALIZATION ---
148
  logger.info("--- DEFORMES 7D: INITIATING INTERLEAVED RENDERING PIPELINE ---")
149
  run_timestamp = int(time.time())
150
  temp_video_clips_dir = os.path.join(self.workspace_dir, f"temp_clips_{run_timestamp}")
@@ -152,14 +120,11 @@ class Deformes7DEngine:
152
 
153
  resolution_tuple = (video_resolution, video_resolution)
154
 
155
- # Lists to store the full sequence of generated artifacts
156
  generated_keyframe_paths = []
157
  generated_keyframe_latents = []
158
  generated_video_fragment_paths = []
159
 
160
- # --- BOOTSTRAP: Generate first two keyframes to start the pipeline ---
161
- progress(0, desc="Bootstrap: Generating K0...")
162
- # Keyframe 0 is just the processed initial reference
163
  k0_path = initial_ref_paths[0]
164
  k0_pil = Image.open(k0_path).convert("RGB")
165
  k0_processed_pil = self._preprocess_image(k0_pil, resolution_tuple)
@@ -168,8 +133,7 @@ class Deformes7DEngine:
168
  generated_keyframe_paths.append(k0_path)
169
  generated_keyframe_latents.append(k0_latent)
170
 
171
- progress(0, desc="Bootstrap: Generating K1...")
172
- # Generate Keyframe 1 from Keyframe 0
173
  prompt_k1 = deformes2d_thinker_singleton.get_anticipatory_keyframe_prompt(
174
  global_prompt, "Initial scene.", storyboard[0], storyboard[1], k0_path, initial_ref_paths
175
  )
@@ -177,29 +141,26 @@ class Deformes7DEngine:
177
  generated_keyframe_paths.append(k1_path)
178
  generated_keyframe_latents.append(k1_latent)
179
 
180
- # --- MAIN RENDERING LOOP ---
181
  story_history = ""
182
  eco_latent_for_next_loop, dejavu_latent_for_next_loop = None, None
183
  num_transitions = len(storyboard) - 1
 
 
184
 
185
  for i in range(1, num_transitions):
186
  progress(i / num_transitions, desc=f"Processing Act {i+1}/{num_transitions}...")
187
 
188
- # --- 1. Generate the NEXT Keyframe (Look-ahead) ---
189
  logger.info(f"--> Step 3D: Generating Keyframe K{i+1}")
190
  kx_path = generated_keyframe_paths[i]
191
  prompt_ky = deformes2d_thinker_singleton.get_anticipatory_keyframe_prompt(
192
- global_prompt, "Continuing sequence...", storyboard[i], storyboard[i+1], kx_path, initial_ref_paths
193
  )
194
  ky_path, ky_latent = self._generate_next_causal_keyframe(kx_path, initial_ref_paths, prompt_ky, resolution_tuple)
195
  generated_keyframe_paths.append(ky_path)
196
  generated_keyframe_latents.append(ky_latent)
197
 
198
- # --- 2. Generate the CURRENT Video Fragment ---
199
- logger.info(f"--> Step 4D: Generating Video Fragment V{i}")
200
- kb_path = generated_keyframe_paths[i-1] # Past
201
- kx_path = generated_keyframe_paths[i] # Present (Start)
202
- ky_path = generated_keyframe_paths[i+1] # Future (End)
203
 
204
  decision = deformes2d_thinker_singleton.get_cinematic_decision(
205
  global_prompt, story_history, kb_path, kx_path, ky_path,
@@ -207,64 +168,37 @@ class Deformes7DEngine:
207
  )
208
  transition_type, motion_prompt = decision["transition_type"], decision["motion_prompt"]
209
  story_history += f"\n- Act {i}: {motion_prompt}"
210
-
211
- # Prepare conditioning items for the video fragment
212
- conditioning_items = []
213
- if eco_latent_for_next_loop is None:
214
- conditioning_items.append(LatentConditioningItem(generated_keyframe_latents[i], 0, 1.0))
215
- else:
216
- # This part reuses the logic from the old Deformes4D
217
- # ... [Implementation of Eco/Deja-Vu conditioning here] ...
218
- # For simplicity in this first draft, we'll use the direct keyframe latent
219
- conditioning_items.append(LatentConditioningItem(generated_keyframe_latents[i], 0, 1.0))
220
 
221
- # Add the destination anchor
222
- conditioning_items.append(LatentConditioningItem(ky_latent, -1, dest_strength)) # Use -1 for last frame
 
 
223
 
224
  fragment_latents, _ = ltx_manager_singleton.generate_latent_fragment(
225
  height=video_resolution, width=video_resolution,
226
  conditioning_items_data=conditioning_items, motion_prompt=motion_prompt,
227
  video_total_frames=self._quantize_to_multiple(int(seconds_per_fragment * 24), 8),
228
- video_fps=24, **ltx_params
229
  )
230
 
231
- # Post-process and save the video fragment
232
  pixel_tensor = vae_manager_singleton.decode(fragment_latents)
233
- fragment_path = os.path.join(temp_video_clips_dir, f"fragment_{i}.mp4")
234
  self.save_video_from_tensor(pixel_tensor, fragment_path, fps=24)
235
  generated_video_fragment_paths.append(fragment_path)
236
- logger.info(f"Video Fragment V{i} saved to {fragment_path}")
237
-
238
- # Here you would also extract the Eco and Deja-Vu from `fragment_latents` for the next loop
239
- # ...
240
 
241
- # --- FINAL ASSEMBLY ---
242
  logger.info("--- Final Assembly of Video Fragments ---")
243
  final_video_path = os.path.join(self.workspace_dir, f"movie_7D_{run_timestamp}.mp4")
244
- video_encode_tool_singleton.concatenate_videos(
245
- video_paths=generated_video_fragment_paths,
246
- output_path=final_video_path,
247
- workspace_dir=self.workspace_dir
248
- )
249
  shutil.rmtree(temp_video_clips_dir)
250
 
251
  logger.info(f"Full movie generated at: {final_video_path}")
252
- # This function would then return the path and other artifacts for post-production
253
  return {"final_path": final_video_path, "all_keyframes": generated_keyframe_paths}
254
 
255
-
256
- # --- POST-PRODUCTION METHODS (migrated from Deformes4D) ---
257
 
258
- def upscale_video(self, source_video_path: str, progress=gr.Progress()):
259
- # This would be a more complex function that loads the video in chunks,
260
- # encodes to latents, upscales, decodes, and reassembles.
261
- # For this example, we assume it's a placeholder.
262
- logger.info(f"Placeholder for upscaling video: {source_video_path}")
263
- return source_video_path
264
-
265
- def master_video_hd(self, source_video_path: str, model_version: str, steps: int, prompt: str, progress=gr.Progress()):
266
  logger.info(f"--- POST-PRODUCTION: HD Mastering with SeedVR {model_version} ---")
267
- progress(0.1, desc=f"Preparing for HD Mastering...")
268
  run_timestamp = int(time.time())
269
  output_path = os.path.join(self.workspace_dir, f"{Path(source_video_path).stem}_hd.mp4")
270
  try:
@@ -278,9 +212,8 @@ class Deformes7DEngine:
278
  logger.error(f"HD Mastering failed: {e}", exc_info=True)
279
  raise gr.Error(f"HD Mastering failed. Details: {e}")
280
 
281
- def generate_audio(self, source_video_path: str, audio_prompt: str, progress=gr.Progress()):
282
  logger.info(f"--- POST-PRODUCTION: Audio Generation ---")
283
- progress(0.1, desc="Preparing for audio generation...")
284
  run_timestamp = int(time.time())
285
  output_path = os.path.join(self.workspace_dir, f"{Path(source_video_path).stem}_audio.mp4")
286
  try:
@@ -288,6 +221,7 @@ class Deformes7DEngine:
288
  ["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", source_video_path],
289
  capture_output=True, text=True, check=True)
290
  duration = float(result.stdout.strip())
 
291
  progress(0.5, desc="Generating audio track...")
292
  final_path = mmaudio_manager_singleton.generate_audio_for_video(
293
  video_path=source_video_path, prompt=audio_prompt,
@@ -297,4 +231,14 @@ class Deformes7DEngine:
297
  yield {"final_path": final_path}
298
  except Exception as e:
299
  logger.error(f"Audio generation failed: {e}", exc_info=True)
300
- raise gr.Error(f"Audio generation failed. Details: {e}")
 
 
 
 
 
 
 
 
 
 
 
1
  # engineers/deformes7D.py
 
 
 
2
  #
3
+ # Copyright (C) 2025 Carlos Rodrigues dos Santos
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  #
5
  # Version: 3.0.0
6
  #
 
21
  import gc
22
  import shutil
23
  from pathlib import Path
24
+ from typing import List, Tuple, Dict
25
 
26
  from aduc_types import LatentConditioningItem
27
  from managers.ltx_manager import ltx_manager_singleton
 
44
  logger.info("Deformes7D Unified Engine initialized.")
45
  os.makedirs(self.workspace_dir, exist_ok=True)
46
 
47
+ # --- HELPER METHODS ---
48
 
49
  def _preprocess_image(self, image: Image.Image, target_resolution: tuple) -> Image.Image:
 
50
  if image.size != target_resolution:
51
  return ImageOps.fit(image, target_resolution, Image.Resampling.LANCZOS)
52
  return image
53
 
54
  def _pil_to_pixel_tensor(self, pil_image: Image.Image) -> torch.Tensor:
 
55
  image_np = np.array(pil_image).astype(np.float32) / 255.0
56
  tensor = torch.from_numpy(image_np).permute(2, 0, 1).unsqueeze(0).unsqueeze(2)
57
  return (tensor * 2.0) - 1.0
58
 
59
  def _save_image_from_tensor(self, pixel_tensor: torch.Tensor, path: str):
 
60
  tensor_chw = pixel_tensor.squeeze(0).squeeze(1)
61
  tensor_hwc = tensor_chw.permute(1, 2, 0)
62
  tensor_hwc = (tensor_hwc.clamp(-1, 1) + 1) / 2.0
 
64
  Image.fromarray(image_np).save(path)
65
 
66
  def _quantize_to_multiple(self, n, m):
 
67
  if m == 0: return n
68
  quantized = int(round(n / m) * m)
69
  return m if n > 0 and quantized == 0 else quantized
 
100
  upscaled_latent = latent_enhancer_specialist_singleton.upscale(final_latent)
101
  pixel_tensor_out = vae_manager_singleton.decode(upscaled_latent)
102
 
 
103
  timestamp = int(time.time() * 1000)
104
  output_path = os.path.join(self.workspace_dir, f"keyframe_{timestamp}.png")
105
  self._save_image_from_tensor(pixel_tensor_out, output_path)
 
113
  """
114
  The main interleaved rendering pipeline for Deformes7D.
115
  """
 
116
  logger.info("--- DEFORMES 7D: INITIATING INTERLEAVED RENDERING PIPELINE ---")
117
  run_timestamp = int(time.time())
118
  temp_video_clips_dir = os.path.join(self.workspace_dir, f"temp_clips_{run_timestamp}")
 
120
 
121
  resolution_tuple = (video_resolution, video_resolution)
122
 
 
123
  generated_keyframe_paths = []
124
  generated_keyframe_latents = []
125
  generated_video_fragment_paths = []
126
 
127
+ progress(0, desc="Bootstrap: Processing K0...")
 
 
128
  k0_path = initial_ref_paths[0]
129
  k0_pil = Image.open(k0_path).convert("RGB")
130
  k0_processed_pil = self._preprocess_image(k0_pil, resolution_tuple)
 
133
  generated_keyframe_paths.append(k0_path)
134
  generated_keyframe_latents.append(k0_latent)
135
 
136
+ progress(0.01, desc="Bootstrap: Generating K1...")
 
137
  prompt_k1 = deformes2d_thinker_singleton.get_anticipatory_keyframe_prompt(
138
  global_prompt, "Initial scene.", storyboard[0], storyboard[1], k0_path, initial_ref_paths
139
  )
 
141
  generated_keyframe_paths.append(k1_path)
142
  generated_keyframe_latents.append(k1_latent)
143
 
 
144
  story_history = ""
145
  eco_latent_for_next_loop, dejavu_latent_for_next_loop = None, None
146
  num_transitions = len(storyboard) - 1
147
+
148
+ base_4d_ltx_params = {"rescaling_scale": 0.15, "image_cond_noise_scale": 0.00, **ltx_params}
149
 
150
  for i in range(1, num_transitions):
151
  progress(i / num_transitions, desc=f"Processing Act {i+1}/{num_transitions}...")
152
 
 
153
  logger.info(f"--> Step 3D: Generating Keyframe K{i+1}")
154
  kx_path = generated_keyframe_paths[i]
155
  prompt_ky = deformes2d_thinker_singleton.get_anticipatory_keyframe_prompt(
156
+ global_prompt, story_history, storyboard[i], storyboard[i+1], kx_path, initial_ref_paths
157
  )
158
  ky_path, ky_latent = self._generate_next_causal_keyframe(kx_path, initial_ref_paths, prompt_ky, resolution_tuple)
159
  generated_keyframe_paths.append(ky_path)
160
  generated_keyframe_latents.append(ky_latent)
161
 
162
+ logger.info(f"--> Step 4D: Generating Video Fragment V{i-1}")
163
+ kb_path, kx_path, ky_path = generated_keyframe_paths[i-1], generated_keyframe_paths[i], generated_keyframe_paths[i+1]
 
 
 
164
 
165
  decision = deformes2d_thinker_singleton.get_cinematic_decision(
166
  global_prompt, story_history, kb_path, kx_path, ky_path,
 
168
  )
169
  transition_type, motion_prompt = decision["transition_type"], decision["motion_prompt"]
170
  story_history += f"\n- Act {i}: {motion_prompt}"
 
 
 
 
 
 
 
 
 
 
171
 
172
+ # This is a simplified version of the Deformes4D conditioning logic
173
+ conditioning_items = [LatentConditioningItem(generated_keyframe_latents[i], 0, 1.0)]
174
+ if transition_type != "cut":
175
+ conditioning_items.append(LatentConditioningItem(ky_latent, -1, dest_strength))
176
 
177
  fragment_latents, _ = ltx_manager_singleton.generate_latent_fragment(
178
  height=video_resolution, width=video_resolution,
179
  conditioning_items_data=conditioning_items, motion_prompt=motion_prompt,
180
  video_total_frames=self._quantize_to_multiple(int(seconds_per_fragment * 24), 8),
181
+ video_fps=24, **base_4d_ltx_params
182
  )
183
 
 
184
  pixel_tensor = vae_manager_singleton.decode(fragment_latents)
185
+ fragment_path = os.path.join(temp_video_clips_dir, f"fragment_{i-1}.mp4")
186
  self.save_video_from_tensor(pixel_tensor, fragment_path, fps=24)
187
  generated_video_fragment_paths.append(fragment_path)
188
+ logger.info(f"Video Fragment V{i-1} saved to {fragment_path}")
 
 
 
189
 
 
190
  logger.info("--- Final Assembly of Video Fragments ---")
191
  final_video_path = os.path.join(self.workspace_dir, f"movie_7D_{run_timestamp}.mp4")
192
+ video_encode_tool_singleton.concatenate_videos(generated_video_fragment_paths, final_video_path, self.workspace_dir)
 
 
 
 
193
  shutil.rmtree(temp_video_clips_dir)
194
 
195
  logger.info(f"Full movie generated at: {final_video_path}")
 
196
  return {"final_path": final_video_path, "all_keyframes": generated_keyframe_paths}
197
 
198
+ # --- POST-PRODUCTION METHODS ---
 
199
 
200
+ def master_video_hd(self, source_video_path: str, model_version: str, steps: int, prompt: str, progress: gr.Progress):
 
 
 
 
 
 
 
201
  logger.info(f"--- POST-PRODUCTION: HD Mastering with SeedVR {model_version} ---")
 
202
  run_timestamp = int(time.time())
203
  output_path = os.path.join(self.workspace_dir, f"{Path(source_video_path).stem}_hd.mp4")
204
  try:
 
212
  logger.error(f"HD Mastering failed: {e}", exc_info=True)
213
  raise gr.Error(f"HD Mastering failed. Details: {e}")
214
 
215
+ def generate_audio(self, source_video_path: str, audio_prompt: str, progress: gr.Progress):
216
  logger.info(f"--- POST-PRODUCTION: Audio Generation ---")
 
217
  run_timestamp = int(time.time())
218
  output_path = os.path.join(self.workspace_dir, f"{Path(source_video_path).stem}_audio.mp4")
219
  try:
 
221
  ["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", source_video_path],
222
  capture_output=True, text=True, check=True)
223
  duration = float(result.stdout.strip())
224
+ logger.info(f"Source video duration: {duration:.2f} seconds.")
225
  progress(0.5, desc="Generating audio track...")
226
  final_path = mmaudio_manager_singleton.generate_audio_for_video(
227
  video_path=source_video_path, prompt=audio_prompt,
 
231
  yield {"final_path": final_path}
232
  except Exception as e:
233
  logger.error(f"Audio generation failed: {e}", exc_info=True)
234
+ raise gr.Error(f"Audio generation failed. Details: {e}")
235
+
236
+ # --- Singleton Instantiation ---
237
+ try:
238
+ with open("config.yaml", 'r') as f:
239
+ config = yaml.safe_load(f)
240
+ WORKSPACE_DIR = config['application']['workspace_dir']
241
+ deformes7d_engine_singleton = Deformes7DEngine(workspace_dir=WORKSPACE_DIR)
242
+ except Exception as e:
243
+ logger.error(f"Could not initialize Deformes7DEngine: {e}", exc_info=True)
244
+ deformes7d_engine_singleton = None