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.
55 lines
2.4 KiB
Python
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()
|