Skip to content

Commit e28f1ab

Browse files
authored
live/pipelines: Move prepare models logic to pipeline (#849)
* .github: Rename docker build actions for consistency * Add scope pipeline scaffold for live-video-to-video This commit adds the initial scaffold for the Scope pipeline integration, following the same patterns as StreamDiffusion (not ComfyUI). The scaffold includes: Pipeline Implementation: - Created runner/app/live/pipelines/scope/ with __init__.py, pipeline.py, and params.py - ScopeParams extends BaseParams for future configuration - Scope pipeline class based on Noop implementation - Updated loader.py to register scope pipeline and params Docker & CI: - Added Dockerfile.live-base-scope that installs scope via uv in the comfystream conda environment and builds the frontend - Created .github/workflows/ai-runner-docker-scope.yaml to build and push scope Docker images (live-base-scope and live-app-scope) Documentation: - Updated docs/live-ai-local-dev.md examples to use scope instead of comfyui The implementation follows StreamDiffusion patterns and does not include any ComfyUI-style special cases. Scope is treated as a standard pipeline without parameter wrapping or resolution restrictions. * docker: Fix scope package installation * Fix --active flag to uv Also adda a check on pipe startup * Add scope model prepare tooling * Fix scope prepare script path handling * Add diffusers deps to live AI requirements * Pin uv to latest version 0.9.9 * Fix scope pipeline interface import path * Add /workspace/scope to PYTHONPATH for lib module imports * Remove sys.path manipulation from prepare_models, rely on PYTHONPATH * feat: unify pipeline model preparation Add a shared prepare_models entrypoint that loads pipelines via loader.load_pipeline and lets each pipeline expose prepare_models(). StreamDiffusion now owns a full preparation module that downloads dependencies, compiles Depth/Pose/RAFT engines, and iterates over all model/controlnet/IP-Adapter combinations to build TensorRT engines sequentially. Scope implements the hook with its smoke test, ComfyUI/Noop have no-ops, and the download scripts call the new tool so the old bespoke streamdiffusion/scope helpers are removed. * Human simplify dl_checkpoints * Human plane proof read (WIP) * [ai] Stop passing model_dir around * Rename cwd_models to just StreamDiffusion--models * Review rest of prepare.py * Fix ipa_type
1 parent 2d1aeb6 commit e28f1ab

File tree

13 files changed

+476
-502
lines changed

13 files changed

+476
-502
lines changed

.github/workflows/ai-runner-docker-live-noop.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
- "runner/docker/Dockerfile.live-*"
77
- "runner/app/**"
88
- "runner/images/**"
9+
- "runner/VERSION"
910
push:
1011
branches:
1112
- main
@@ -15,6 +16,7 @@ on:
1516
- "runner/docker/Dockerfile.live-*"
1617
- "runner/app/**"
1718
- "runner/images/**"
19+
- "runner/VERSION"
1820
workflow_dispatch:
1921

2022
concurrency:

.github/workflows/ai-runner-docker-live-streamdiffusion.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ on:
1616
- "runner/docker/Dockerfile.live-*"
1717
- "runner/app/**"
1818
- "runner/images/**"
19+
- "runner/VERSION"
1920
workflow_dispatch:
2021

2122
concurrency:

.github/workflows/ai-runner-docker-scope.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ on:
1616
- "runner/docker/Dockerfile.live-*"
1717
- "runner/app/**"
1818
- "runner/images/**"
19+
- "runner/VERSION"
1920
workflow_dispatch:
2021

2122
concurrency:

runner/app/live/pipelines/comfyui/pipeline.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import os
2-
import torch
31
import asyncio
42
import logging
3+
import os
4+
from pathlib import Path
55

6+
import torch
67
from comfystream.client import ComfyStreamClient
78

89
from ..interface import Pipeline
@@ -103,3 +104,7 @@ async def stop(self):
103104
finally:
104105
self.client = None
105106
logging.info("ComfyUI pipeline stopped")
107+
108+
@classmethod
109+
def prepare_models(cls):
110+
logging.info("ComfyUI prepare_models is currently a no-op")

runner/app/live/pipelines/interface.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
from asyncio import Task
22
from abc import ABC, abstractmethod
3+
from pathlib import Path
4+
35
from pydantic import BaseModel, Field
6+
47
from ..trickle import VideoFrame, VideoOutput, DEFAULT_WIDTH, DEFAULT_HEIGHT
58

69

@@ -104,3 +107,9 @@ async def stop(self):
104107
Called once when the pipeline is no longer needed.
105108
"""
106109
pass
110+
111+
@classmethod
112+
@abstractmethod
113+
def prepare_models(cls):
114+
"""Download and/or compile any assets required for this pipeline."""
115+
pass

runner/app/live/pipelines/noop.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import logging
21
import asyncio
2+
import logging
3+
from pathlib import Path
34

45
from .interface import Pipeline
56
from ..trickle import VideoFrame, VideoOutput
@@ -24,3 +25,7 @@ async def update_params(self, **params):
2425

2526
async def stop(self):
2627
logging.info("Stopping pipeline")
28+
29+
@classmethod
30+
def prepare_models(cls):
31+
logging.info("Noop pipeline does not require model preparation")

runner/app/live/pipelines/scope/pipeline.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
<<<<<<< HEAD
2+
import asyncio
3+
import logging
4+
from pathlib import Path
5+
=======
16
import logging
27
import asyncio
8+
>>>>>>> main
39

410
from ..interface import Pipeline
511
from ...trickle import VideoFrame, VideoOutput
@@ -37,3 +43,16 @@ async def stop(self):
3743
# clear the frame queue
3844
self.frame_queue = asyncio.Queue()
3945

46+
@classmethod
47+
def prepare_models(cls):
48+
logging.info("Preparing Scope models")
49+
try:
50+
from lib.schema import HealthResponse # type: ignore
51+
52+
assert HealthResponse is not None
53+
except ImportError as exc:
54+
raise RuntimeError(
55+
"Scope Python dependencies are not installed inside this image."
56+
) from exc
57+
logging.info("Scope model preparation complete")
58+

runner/app/live/pipelines/streamdiffusion/pipeline.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import asyncio
44
import base64
55
import re
6+
from pathlib import Path
67
from typing import Dict, List, Optional, Any, cast
78

89
import torch
@@ -23,6 +24,9 @@
2324
LCM_LORAS_BY_TYPE
2425
)
2526

27+
ENGINES_DIR = Path("./engines")
28+
# this one is used only for realesrgan_trt which has ./models hardcoded
29+
LOCAL_MODELS_DIR = Path("./models")
2630

2731
class StreamDiffusion(Pipeline):
2832
def __init__(self):
@@ -258,6 +262,12 @@ async def stop(self):
258262
self.params = None
259263
self.frame_queue = asyncio.Queue()
260264

265+
@classmethod
266+
def prepare_models(cls):
267+
from .prepare import prepare_streamdiffusion_models
268+
269+
prepare_streamdiffusion_models()
270+
261271

262272
def _prepare_controlnet_configs(params: StreamDiffusionParams) -> Optional[List[Dict[str, Any]]]:
263273
"""Prepare ControlNet configurations for wrapper"""
@@ -386,7 +396,7 @@ def load_streamdiffusion_sync(
386396
params: StreamDiffusionParams,
387397
min_batch_size=1,
388398
max_batch_size=4,
389-
engine_dir="engines",
399+
engine_dir: str | Path = ENGINES_DIR,
390400
build_engines=False,
391401
) -> StreamDiffusionWrapper:
392402
pipe = StreamDiffusionWrapper(

0 commit comments

Comments
 (0)