|
3 | 3 |
|
4 | 4 | from __future__ import annotations |
5 | 5 |
|
| 6 | +import contextlib |
6 | 7 | from typing import Any |
7 | 8 |
|
| 9 | + |
8 | 10 | import torch |
9 | 11 |
|
10 | 12 | from fastvideo.distributed import get_local_torch_device |
11 | 13 | from fastvideo.fastvideo_args import FastVideoArgs |
12 | 14 | from fastvideo.forward_context import set_forward_context |
| 15 | +from fastvideo.profiler import get_global_controller |
13 | 16 | from fastvideo.hooks.activation_trace import trace_step |
14 | 17 | from fastvideo.pipelines.basic.minimax_h3.packing import ( |
15 | 18 | MINIMAX_H3_KEYFRAME_NOISE_AUG, |
@@ -98,44 +101,54 @@ def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -> Forward |
98 | 101 | text_indices = layout.text_indices.to(device) |
99 | 102 | prompt_embeds = batch.prompt_embeds[0].to(device) |
100 | 103 |
|
| 104 | + controller = get_global_controller() |
| 105 | + denoise_region = (controller.region("profiler_region_inference_denoising") |
| 106 | + if controller is not None else contextlib.nullcontext()) |
101 | 107 | try: |
102 | | - for index, (video_timestep, audio_timestep) in enumerate(zip(video_timesteps, audio_timesteps, |
103 | | - strict=True)): |
104 | | - unique_timesteps, timestep_indices = row_timestep_plan[index] |
105 | | - with trace_step(index), set_forward_context( |
106 | | - current_timestep=index, |
107 | | - attn_metadata=None, |
108 | | - forward_batch=batch, |
109 | | - ): |
110 | | - video_velocity, audio_velocity = self.transformer( |
111 | | - hidden_states=batch.latents[None], |
112 | | - audio_hidden_states=batch.audio_latents[None], |
113 | | - encoder_hidden_states=prompt_embeds, |
114 | | - timestep=unique_timesteps, |
115 | | - timestep_indices=timestep_indices, |
116 | | - token_tags=token_tags, |
117 | | - position_ids=position_ids, |
118 | | - video_indices=video_indices, |
119 | | - audio_indices=audio_indices, |
120 | | - text_indices=text_indices, |
121 | | - ) |
122 | | - |
123 | | - video_start = layout.num_condition_video_rows |
124 | | - audio_start = layout.num_condition_audio_rows |
125 | | - batch.latents[video_start:] = self.scheduler.step( |
126 | | - video_velocity[0, video_start:].float(), |
127 | | - video_timestep, |
128 | | - batch.latents[video_start:], |
129 | | - return_dict=False, |
130 | | - )[0] |
131 | | - batch.audio_latents[audio_start:] = self.audio_scheduler.step( |
132 | | - audio_velocity[0, audio_start:].float(), |
133 | | - audio_timestep, |
134 | | - batch.audio_latents[audio_start:], |
135 | | - return_dict=False, |
136 | | - )[0] |
137 | | - batch.step_index = index |
138 | | - batch.timestep = video_timestep |
| 108 | + with denoise_region: |
| 109 | + for index, (video_timestep, audio_timestep) in enumerate(zip(video_timesteps, audio_timesteps, |
| 110 | + strict=True)): |
| 111 | + unique_timesteps, timestep_indices = row_timestep_plan[index] |
| 112 | + # Under torch.compile(mode="reduce-overhead") each denoising |
| 113 | + # step must be marked, or cudagraph trees flag cross-step |
| 114 | + # reuse of pooled outputs as "accessing tensor output of |
| 115 | + # CUDAGraphs that has been overwritten" (surfaces at sp=1; |
| 116 | + # sp>1 is masked by collective-induced graph breaks). |
| 117 | + torch.compiler.cudagraph_mark_step_begin() |
| 118 | + with trace_step(index), set_forward_context( |
| 119 | + current_timestep=index, |
| 120 | + attn_metadata=None, |
| 121 | + forward_batch=batch, |
| 122 | + ): |
| 123 | + video_velocity, audio_velocity = self.transformer( |
| 124 | + hidden_states=batch.latents[None], |
| 125 | + audio_hidden_states=batch.audio_latents[None], |
| 126 | + encoder_hidden_states=prompt_embeds, |
| 127 | + timestep=unique_timesteps, |
| 128 | + timestep_indices=timestep_indices, |
| 129 | + token_tags=token_tags, |
| 130 | + position_ids=position_ids, |
| 131 | + video_indices=video_indices, |
| 132 | + audio_indices=audio_indices, |
| 133 | + text_indices=text_indices, |
| 134 | + ) |
| 135 | + |
| 136 | + video_start = layout.num_condition_video_rows |
| 137 | + audio_start = layout.num_condition_audio_rows |
| 138 | + batch.latents[video_start:] = self.scheduler.step( |
| 139 | + video_velocity[0, video_start:].float(), |
| 140 | + video_timestep, |
| 141 | + batch.latents[video_start:], |
| 142 | + return_dict=False, |
| 143 | + )[0] |
| 144 | + batch.audio_latents[audio_start:] = self.audio_scheduler.step( |
| 145 | + audio_velocity[0, audio_start:].float(), |
| 146 | + audio_timestep, |
| 147 | + batch.audio_latents[audio_start:], |
| 148 | + return_dict=False, |
| 149 | + )[0] |
| 150 | + batch.step_index = index |
| 151 | + batch.timestep = video_timestep |
139 | 152 | finally: |
140 | 153 | if bool(getattr(fastvideo_args, "dit_layerwise_offload", False)): |
141 | 154 | manager = getattr(self.transformer, "_layerwise_offload_manager", None) |
|
0 commit comments