Skip to content

Commit 3238ae7

Browse files
committed
fix: handle Helios output boundary cases
1 parent 099c098 commit 3238ae7

4 files changed

Lines changed: 15 additions & 5 deletions

File tree

fastvideo/configs/pipelines/helios.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def helios_postprocess_text(output: BaseEncoderOutput) -> torch.Tensor:
4646
sequence_lengths = output.attention_mask.gt(0).sum(dim=1).long()
4747
if torch.isnan(hidden_states).any():
4848
raise ValueError("Helios UMT5 produced NaN hidden states")
49-
trimmed = [hidden[:length] for hidden, length in zip(hidden_states, sequence_lengths, strict=True)]
49+
trimmed = [hidden[:min(int(length), 512)] for hidden, length in zip(hidden_states, sequence_lengths, strict=True)]
5050
return torch.stack(
5151
[torch.cat([hidden, hidden.new_zeros(512 - hidden.shape[0], hidden.shape[1])]) for hidden in trimmed],
5252
dim=0,

fastvideo/pipelines/basic/helios/stages.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,11 @@ def forward(self, batch: ForwardBatch, fastvideo_args: FastVideoArgs) -> Forward
382382
frames = torch.cat(decoded_chunks, dim=2)
383383

384384
temporal_scale = fastvideo_args.pipeline_config.vae_config.arch_config.scale_factor_temporal
385-
generated_frames = get_generated_pixel_frames(frames.shape[2], temporal_scale)
385+
assert isinstance(batch.num_frames, int)
386+
generated_frames = min(
387+
batch.num_frames,
388+
get_generated_pixel_frames(frames.shape[2], temporal_scale),
389+
)
386390
batch.output = frames[:, :, :generated_frames].detach().to(dtype=torch.float32, device="cpu")
387391
batch.latents = None
388392
batch.helios_latent_chunks = None

tests/local_tests/pipelines/test_helios_pipeline_smoke.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ def test_helios_pipeline_config_and_text_contract() -> None:
196196
assert torch.count_nonzero(output[0, 3:]) == 0
197197
assert torch.equal(output[1, :5], hidden[1, :5])
198198

199+
long_hidden = torch.arange(520 * 4, dtype=torch.float32).reshape(1, 520, 4)
200+
long_mask = torch.ones(1, 520, dtype=torch.long)
201+
long_output = postprocess(BaseEncoderOutput(last_hidden_state=long_hidden, attention_mask=long_mask))
202+
assert long_output.shape == (1, 512, 4)
203+
assert torch.equal(long_output[0], long_hidden[0, :512])
204+
199205

200206
def test_helios_preset_matches_official_distilled_defaults() -> None:
201207
_, _, _, _, preset = _pipeline_symbols()

tests/local_tests/pipelines/test_helios_pipeline_stages.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def decode(self, latent):
279279
280280
281281
vae = TinyVAE().to(device)
282-
decode_batch = ForwardBatch(data_type="video")
282+
decode_batch = ForwardBatch(data_type="video", num_frames=34)
283283
decode_batch.latents = torch.cat([expected, expected], dim=2)
284284
decode_batch.helios_latent_chunks = [expected, expected]
285285
decode_args = SimpleNamespace(
@@ -370,10 +370,10 @@ def test_tiny_pyramid_stage_uses_history_on_second_chunk():
370370
assert abs(result["autoregressive_second_short_prefix_mean"]) > 1e-5
371371

372372

373-
def test_chunk_decoder_calls_vae_per_chunk_and_matches_frame_rounding():
373+
def test_chunk_decoder_calls_vae_per_chunk_and_trims_to_requested_frames():
374374
result = _results()
375375
assert result["vae_calls"] == [[1, 2, 9, 8, 8], [1, 2, 9, 8, 8]]
376-
assert result["decoded_shape"] == [1, 3, 65, 64, 64]
376+
assert result["decoded_shape"] == [1, 3, 34, 64, 64]
377377
assert result["decoded_device"] == "cpu"
378378
assert result["decoded_first_mean"] == 0
379379
assert result["decoded_second_mean"] == 1

0 commit comments

Comments
 (0)