[Misc] Fix memory leakage in VideoGenerator (#1132)
This commit is contained in:
@@ -93,7 +93,6 @@ def main():
|
||||
# Generate the video
|
||||
video = generator.generate_video(
|
||||
prompt,
|
||||
return_frames=True, # Also return frames from this call (defaults to False)
|
||||
output_path="my_videos/", # Controls where videos are saved
|
||||
save_video=True
|
||||
)
|
||||
|
||||
@@ -41,7 +41,6 @@ def main():
|
||||
# Generate the video
|
||||
video = generator.generate_video(
|
||||
prompt,
|
||||
return_frames=True, # Also return frames from this call (defaults to False)
|
||||
output_path="my_videos/", # Controls where videos are saved
|
||||
save_video=True
|
||||
)
|
||||
|
||||
@@ -61,12 +61,11 @@ def main():
|
||||
prompt,
|
||||
sampling_param=sampling_param,
|
||||
output_path="my_videos/", # Controls where videos are saved
|
||||
return_frames=True, # Also return frames from this call (defaults to False)
|
||||
save_video=True
|
||||
)
|
||||
|
||||
# If return_frames=True, video contains the generated frames as a NumPy array
|
||||
print(f"Generated {len(video)} frames")
|
||||
# If return_frames=True, frames are available in video["frames"]
|
||||
print(f"Generated {len(video['frames'])} frames")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -76,6 +75,8 @@ if __name__ == '__main__':
|
||||
|
||||
The CLI supports `--config` with JSON or YAML. Command-line arguments override
|
||||
config file values.
|
||||
By default, `fastvideo generate` uses `return_frames=false` unless you set
|
||||
`--return-frames` (or `return_frames: true` in config).
|
||||
|
||||
```bash
|
||||
fastvideo generate --config config.yaml
|
||||
|
||||
@@ -44,7 +44,6 @@ def main():
|
||||
# Generate the video
|
||||
video = generator.generate_video(
|
||||
prompt,
|
||||
return_frames=True, # Also return frames from this call (defaults to False)
|
||||
output_path="my_videos/", # Controls where videos are saved
|
||||
save_video=True
|
||||
)
|
||||
|
||||
@@ -168,7 +168,7 @@ def prepare_sampling_params(video_request: VideoGenerationRequest, default_param
|
||||
params.height = video_request.height
|
||||
params.width = video_request.width
|
||||
params.save_video = False
|
||||
params.return_frames = False
|
||||
params.return_frames = True
|
||||
|
||||
return params
|
||||
|
||||
@@ -229,7 +229,7 @@ class BaseModelDeployment:
|
||||
sampling_param=params,
|
||||
image_path=image_path,
|
||||
save_video=False,
|
||||
return_frames=False,
|
||||
return_frames=True,
|
||||
)
|
||||
inference_time = time.time() - inference_start_time
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class SamplingParam:
|
||||
|
||||
# Misc
|
||||
save_video: bool = True
|
||||
return_frames: bool = False
|
||||
return_frames: bool = True
|
||||
return_trajectory_latents: bool = False # returns all latents for each timestep
|
||||
return_trajectory_decoded: bool = False # returns decoded latents for each timestep
|
||||
|
||||
@@ -218,7 +218,7 @@ class SamplingParam:
|
||||
parser.add_argument(
|
||||
"--return-frames",
|
||||
action="store_true",
|
||||
default=SamplingParam.return_frames,
|
||||
default=False,
|
||||
help="Whether to return the raw frames",
|
||||
)
|
||||
parser.add_argument(
|
||||
|
||||
@@ -80,6 +80,7 @@ class GenerateSubcommand(CLISubcommand):
|
||||
k: v
|
||||
for k, v in merged_args.items() if k in self.generation_arg_names
|
||||
}
|
||||
generation_args.setdefault("return_frames", False)
|
||||
|
||||
model_path = init_args.pop('model_path')
|
||||
prompt = generation_args.pop('prompt', None)
|
||||
|
||||
@@ -125,7 +125,7 @@ class VideoGenerator:
|
||||
grid_sizes: tuple[int, int, int] | list[int] | torch.Tensor
|
||||
| None = None,
|
||||
**kwargs,
|
||||
) -> dict[str, Any] | list[np.ndarray] | list[dict[str, Any]]:
|
||||
) -> dict[str, Any] | list[dict[str, Any]]:
|
||||
"""
|
||||
Generate a video based on the given prompt.
|
||||
|
||||
@@ -135,7 +135,7 @@ class VideoGenerator:
|
||||
output_path: Path to save the video (overrides the one in fastvideo_args)
|
||||
prompt_path: Path to prompt file
|
||||
save_video: Whether to save the video to disk
|
||||
return_frames: Whether to return the raw frames
|
||||
return_frames: Whether to include raw frames in the result dict
|
||||
num_inference_steps: Number of denoising steps (overrides fastvideo_args)
|
||||
guidance_scale: Classifier-free guidance scale (overrides fastvideo_args)
|
||||
num_frames: Number of frames to generate (overrides fastvideo_args)
|
||||
@@ -147,7 +147,8 @@ class VideoGenerator:
|
||||
callback_steps: Number of steps between each callback
|
||||
|
||||
Returns:
|
||||
Either the output dictionary, list of frames, or list of results for batch processing
|
||||
A metadata dictionary for single-prompt generation, or a list of
|
||||
metadata dictionaries for prompt-file batch generation.
|
||||
"""
|
||||
# Handle batch processing from text file
|
||||
if sampling_param is None:
|
||||
@@ -194,9 +195,8 @@ class VideoGenerator:
|
||||
**kwargs)
|
||||
|
||||
# Add prompt info to result
|
||||
if isinstance(result, dict):
|
||||
result["prompt_index"] = i
|
||||
result["prompt"] = batch_prompt
|
||||
result["prompt_index"] = i
|
||||
result["prompt"] = batch_prompt
|
||||
|
||||
results.append(result)
|
||||
logger.info("Successfully generated video for prompt %d",
|
||||
@@ -306,7 +306,7 @@ class VideoGenerator:
|
||||
prompt: str,
|
||||
sampling_param: SamplingParam | None = None,
|
||||
**kwargs,
|
||||
) -> dict[str, Any] | list[np.ndarray]:
|
||||
) -> dict[str, Any]:
|
||||
"""Internal method for single video generation"""
|
||||
# Create a copy of inference args to avoid modifying the original
|
||||
fastvideo_args = self.fastvideo_args
|
||||
@@ -475,21 +475,22 @@ class VideoGenerator:
|
||||
logger.warning(
|
||||
"Audio mux failed; saved video without audio.")
|
||||
|
||||
if batch.return_frames:
|
||||
return frames
|
||||
else:
|
||||
return {
|
||||
"samples": samples,
|
||||
"frames": frames,
|
||||
"audio": output_batch.extra.get("audio"),
|
||||
"prompts": prompt,
|
||||
"size": (target_height, target_width, batch.num_frames),
|
||||
"generation_time": gen_time,
|
||||
"logging_info": logging_info,
|
||||
"trajectory": output_batch.trajectory_latents,
|
||||
"trajectory_timesteps": output_batch.trajectory_timesteps,
|
||||
"trajectory_decoded": output_batch.trajectory_decoded,
|
||||
}
|
||||
result: dict[str, Any] = {
|
||||
"prompts": prompt,
|
||||
"samples": samples if batch.return_frames else None,
|
||||
"frames": frames if batch.return_frames else None,
|
||||
"audio":
|
||||
output_batch.extra.get("audio") if batch.return_frames else None,
|
||||
"size": (target_height, target_width, batch.num_frames),
|
||||
"generation_time": gen_time,
|
||||
"logging_info": logging_info,
|
||||
"trajectory": output_batch.trajectory_latents,
|
||||
"trajectory_timesteps": output_batch.trajectory_timesteps,
|
||||
"trajectory_decoded": output_batch.trajectory_decoded,
|
||||
"video_path": output_path if batch.save_video else None,
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def _mux_audio(
|
||||
|
||||
@@ -340,9 +340,8 @@ def test_gamecraft_pipeline_latent_parity():
|
||||
camera_states=plucker_embedding,
|
||||
)
|
||||
|
||||
fastvideo_latents = result.get("latents")
|
||||
if fastvideo_latents is None:
|
||||
fastvideo_latents = result.get("samples")
|
||||
|
||||
fastvideo_latents = result.get("samples")
|
||||
|
||||
_log_tensor_stats("FastVideo latents", fastvideo_latents)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user