Skip to content

Stale VACE conditioning frames persist across chunks in LongLive/MemFlow/RewardForcing #487

@ryanontheinside

Description

@ryanontheinside

Description

When vace_input_frames / vace_input_masks are not provided in a chunk's kwargs, LongLive, MemFlow, and RewardForcing pipelines fail to clear them from PipelineState. The previous chunk's conditioning frames silently persist and get reused by VaceEncodingBlock, which sees non-None values and re-enters the conditioning path.

This is inconsistent with how other transient inputs are handled — first_frame_image, last_frame_image, vace_ref_images, etc. are all explicitly cleared when absent from kwargs.

KreaRealtimeVideoPipeline is the only pipeline that currently handles this correctly.

Root cause

Each pipeline's _generate() bulk-writes kwargs to state, then manually clears a hardcoded list of transient keys. vace_input_frames and vace_input_masks were added to Krea but not to the other three pipelines.

More broadly, this pattern — duplicating the same transient-clearing logic across every pipeline subclass — violates the Open-Closed Principle. Adding a new transient parameter requires modifying every pipeline, which is how this bug happened in the first place.

Affected pipelines

  • longlive/pipeline.py
  • memflow/pipeline.py
  • reward_forcing/pipeline.py

Potential fix

Centralize the bulk-write + transient-clearing into a shared utility (e.g. in defaults.py):

TRANSIENT_STATE_KEYS = [
    "transition", "video", "vace_ref_images",
    "first_frame_image", "last_frame_image",
    "vace_input_frames", "vace_input_masks",
]

def apply_kwargs_to_state(state, kwargs):
    for k, v in kwargs.items():
        state.set(k, v)
    for key in TRANSIENT_STATE_KEYS:
        if key not in kwargs:
            state.set(key, None)

Each pipeline's _generate() replaces the manual loop + clearing block with a single apply_kwargs_to_state(self.state, kwargs) call. One place to declare transient keys, no per-pipeline duplication.

Note

In practice this may be partially masked during normal operation because PipelineProcessor.process_chunk() continuously feeds vace_input_frames every chunk when vace_enabled and vace_use_input_video are both true. The bug surfaces when the video input stops or those flags change mid-stream.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions