Files
hao-ai-lab-FastVideo/v2_examples/workflows/02_register_as_servable.py
T
SolitaryThinker 94b84b03b9 [examples] Add v2_examples/{training,omni,workflows}/ — runnable examples
Three more example folders alongside inference/, all CPU/numpy, self-contained
(sys.path bootstrap), public API only, every script verified to run green.

training/ (7) — one per method, all via the uniform method.train_step seam:
  01 finetune · 02 dmd2 distillation · 03 diffusion_nft (likelihood-free RL,
  samples from the old policy, feature-cache reuse) · 04 self-forcing (causal
  chunk_rollout) · 05 joint LM+generator RL (UniRL; joint + prompt-only) ·
  06 N-way joint RL (per_expert vs shared credit) · 07 end-to-end workflow RL
  (T2I+I2V from one final-video reward).

omni/ (4) — 01 Cosmos3 (reason→joint denoise, shared MoT) · 02 BAGEL
  (text→image, shared MoT; scheduler prices both WorkUnit kinds) · 03 Qwen-Omni
  (thinker→talker→vocoder, three separate experts, text+audio) · 04 interleave
  parity across AR + diffusion loop types.

workflows/ (2) — 01 cross-model T2I→I2V workflow (image provably conditions the
  video) · 02 workflow as a first-class servable (requires/validate, address by
  id, register_workflows catalog, WorkflowRegistry).

Each folder has a README indexing its scripts.
2026-06-18 09:41:14 +00:00

55 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""02 — A workflow is a first-class servable (naming & registration).
A `Workflow` is named and registered with the same discipline as a card: a namespaced `workflow_id`
(`image_video.t2i_i2v`) in the SAME servable namespace as a `model_id`, with declared+validated
`requires`. Once registered it is addressable exactly like a model — `engine.serves(id)` reports it and
`engine.run(request)` routes to it (designv4 §9.6). This shows the per-engine registry, the fail-fast
validation, the declarative catalog (`register_workflows`), and the `WorkflowRegistry`.
Run: python3 v2_examples/workflows/02_register_as_servable.py
"""
from __future__ import annotations
import pathlib
import sys
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[2]))
import numpy as np
from v2.models import build_image_video_engine, build_t2i_then_i2v_workflow, register_workflows
from v2.program import WorkflowRegistry
from v2.request import DiffusionParams, TaskType, make_request
from v2.runtime import Engine
def main() -> None:
# build_image_video_engine registers the cards AND the workflow as a servable
eng = build_image_video_engine()
print("serves('image_video.t2i_i2v'):", eng.serves("image_video.t2i_i2v"), "(a workflow, addressable like a model)")
print("serves('flux-t2i'):", eng.serves("flux-t2i"), "(its required card)")
# address the workflow BY ID — same call shape as any model
out = eng.run(make_request(TaskType.T2V, "image_video.t2i_i2v", "a lighthouse",
diffusion=DiffusionParams(seed=3)))
print("run-by-id video:", np.asarray(out.artifacts["video"].frames).shape)
# declared + validated dependencies: registering on a bare engine fails fast
try:
Engine().register_workflow(build_t2i_then_i2v_workflow())
print("FAIL: expected validation error")
except ValueError as e:
print("fail-fast validation:", "requires unregistered" in str(e))
# the declarative catalog + the standalone registry
fresh = register_workflows(Engine(), only=["image_video.t2i_i2v"]) # brings up cards + workflow
print("register_workflows → serves:", fresh.serves("image_video.t2i_i2v"))
reg = WorkflowRegistry()
reg.register("image_video.t2i_i2v", build_t2i_then_i2v_workflow)
print("WorkflowRegistry names:", reg.names(), "| requires:", reg.build("image_video.t2i_i2v").requires)
if __name__ == "__main__":
main()