Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/scope/core/pipelines/base_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ class BasePipelineConfig(BaseModel):
# to appear in the preprocessor dropdown.
usage: ClassVar[list[UsageType]] = []

# Frame chunk configuration — exposed via get_schema_with_metadata() so
# external clients can discover frames_per_chunk without hardcoding.
num_frame_per_block: ClassVar[int | None] = None
vae_temporal_downsample_factor: ClassVar[int | None] = None

# Mode configuration - keys are mode names, values are ModeDefaults with field overrides
# Use default=True to mark the default mode. Only include fields that differ from base.
modes: ClassVar[dict[str, ModeDefaults]] = {"text": ModeDefaults(default=True)}
Expand Down Expand Up @@ -384,6 +389,21 @@ def get_schema_with_metadata(cls) -> dict[str, Any]:
metadata["usage"] = [usage.value for usage in cls.usage] if cls.usage else []
metadata["config_schema"] = cls.model_json_schema()

# Expose frame chunk metadata for external clients (e.g. ComfyUI)
if (
cls.num_frame_per_block is not None
and cls.vae_temporal_downsample_factor is not None
):
metadata["frames_per_chunk"] = (
cls.num_frame_per_block * cls.vae_temporal_downsample_factor
)
metadata["temporal_downsample_factor"] = (
cls.vae_temporal_downsample_factor
)
else:
metadata["frames_per_chunk"] = None
metadata["temporal_downsample_factor"] = None

# Include mode-specific defaults (excluding None values and the "default" flag)
mode_defaults = {}
for mode_name, mode_config in cls.modes.items():
Expand Down
2 changes: 2 additions & 0 deletions src/scope/core/pipelines/krea_realtime_video/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class KreaRealtimeVideoConfig(BasePipelineConfig):
min_dimension = 16
modified = True
recommended_quantization_vram_threshold = 40.0
num_frame_per_block = 3
vae_temporal_downsample_factor = 4

default_temporal_interpolation_method = "linear"
default_temporal_interpolation_steps = 4
Expand Down
2 changes: 2 additions & 0 deletions src/scope/core/pipelines/longlive/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class LongLiveConfig(BasePipelineConfig):
supports_quantization = True
min_dimension = 16
modified = True
num_frame_per_block = 3
vae_temporal_downsample_factor = 4

# Configuration fields with UI metadata (order, component, modes)
vace_context_scale: float = Field(
Expand Down
2 changes: 2 additions & 0 deletions src/scope/core/pipelines/memflow/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class MemFlowConfig(BasePipelineConfig):
supports_quantization = True
min_dimension = 16
modified = True
num_frame_per_block = 3
vae_temporal_downsample_factor = 4

vace_context_scale: float = Field(
default=1.0,
Expand Down
2 changes: 2 additions & 0 deletions src/scope/core/pipelines/reward_forcing/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class RewardForcingConfig(BasePipelineConfig):
supports_quantization = True
min_dimension = 16
modified = True
num_frame_per_block = 3
vae_temporal_downsample_factor = 4

vace_context_scale: float = Field(
default=1.0,
Expand Down
2 changes: 2 additions & 0 deletions src/scope/core/pipelines/streamdiffusionv2/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class StreamDiffusionV2Config(BasePipelineConfig):
supports_quantization = True
min_dimension = 16
modified = True
num_frame_per_block = 1
vae_temporal_downsample_factor = 4

vace_context_scale: float = Field(
default=1.0,
Expand Down
88 changes: 88 additions & 0 deletions tests/test_pipeline_schema_metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""Tests for frames_per_chunk and temporal_downsample_factor in pipeline schema metadata."""

from scope.core.pipelines.base_schema import BasePipelineConfig


class TestSchemaMetadataFrameChunk:
"""Tests for frames_per_chunk and temporal_downsample_factor in get_schema_with_metadata()."""

def test_base_config_returns_none_for_frame_chunk_fields(self):
"""BasePipelineConfig should return None for both fields by default."""
metadata = BasePipelineConfig.get_schema_with_metadata()
assert metadata["frames_per_chunk"] is None
assert metadata["temporal_downsample_factor"] is None

def test_custom_config_computes_frames_per_chunk(self):
"""Config with num_frame_per_block and vae_temporal_downsample_factor should compute correctly."""

class TestConfig(BasePipelineConfig):
pipeline_id = "test-frames"
num_frame_per_block = 3
vae_temporal_downsample_factor = 4

metadata = TestConfig.get_schema_with_metadata()
assert metadata["frames_per_chunk"] == 12
assert metadata["temporal_downsample_factor"] == 4

def test_partial_config_returns_none(self):
"""Config with only one of the two fields set should return None for both."""

class OnlyBlockConfig(BasePipelineConfig):
pipeline_id = "test-partial-block"
num_frame_per_block = 3

metadata = OnlyBlockConfig.get_schema_with_metadata()
assert metadata["frames_per_chunk"] is None
assert metadata["temporal_downsample_factor"] is None

class OnlyVaeConfig(BasePipelineConfig):
pipeline_id = "test-partial-vae"
vae_temporal_downsample_factor = 4

metadata = OnlyVaeConfig.get_schema_with_metadata()
assert metadata["frames_per_chunk"] is None
assert metadata["temporal_downsample_factor"] is None

def test_longlive_config_values(self):
"""LongLiveConfig should have frames_per_chunk=12, temporal_downsample_factor=4."""
from scope.core.pipelines.longlive.schema import LongLiveConfig

metadata = LongLiveConfig.get_schema_with_metadata()
assert metadata["frames_per_chunk"] == 12
assert metadata["temporal_downsample_factor"] == 4

def test_streamdiffusionv2_config_values(self):
"""StreamDiffusionV2Config should have frames_per_chunk=4, temporal_downsample_factor=4."""
from scope.core.pipelines.streamdiffusionv2.schema import (
StreamDiffusionV2Config,
)

metadata = StreamDiffusionV2Config.get_schema_with_metadata()
assert metadata["frames_per_chunk"] == 4
assert metadata["temporal_downsample_factor"] == 4

def test_krea_realtime_video_config_values(self):
"""KreaRealtimeVideoConfig should have frames_per_chunk=12, temporal_downsample_factor=4."""
from scope.core.pipelines.krea_realtime_video.schema import (
KreaRealtimeVideoConfig,
)

metadata = KreaRealtimeVideoConfig.get_schema_with_metadata()
assert metadata["frames_per_chunk"] == 12
assert metadata["temporal_downsample_factor"] == 4

def test_reward_forcing_config_values(self):
"""RewardForcingConfig should have frames_per_chunk=12, temporal_downsample_factor=4."""
from scope.core.pipelines.reward_forcing.schema import RewardForcingConfig

metadata = RewardForcingConfig.get_schema_with_metadata()
assert metadata["frames_per_chunk"] == 12
assert metadata["temporal_downsample_factor"] == 4

def test_memflow_config_values(self):
"""MemFlowConfig should have frames_per_chunk=12, temporal_downsample_factor=4."""
from scope.core.pipelines.memflow.schema import MemFlowConfig

metadata = MemFlowConfig.get_schema_with_metadata()
assert metadata["frames_per_chunk"] == 12
assert metadata["temporal_downsample_factor"] == 4