145 lines
6.2 KiB
Python
145 lines
6.2 KiB
Python
"""Worked examples, runnable as a demo:
|
|
|
|
python3 -m v2.examples
|
|
|
|
Each prints what it demonstrates. This doubles as living documentation of the API.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from v2.recipes import build_default_engine, build_omni_engine
|
|
from v2.recipes.wan21 import build_wan21_card
|
|
from v2.core.request import DiffusionParams, OutputSpec, Request, SamplingParams, TaskType, make_request
|
|
|
|
|
|
def _t2v(mid: str, prompt: str, seed: int, steps: int = 4, **kw: Any) -> Request:
|
|
return make_request(TaskType.T2V, mid, prompt, diffusion=DiffusionParams(num_steps=steps, seed=seed), **kw)
|
|
|
|
|
|
def example_a_text_to_video(eng) -> None:
|
|
print("\n(a) Text → video, one instance (Wan2.1-1.3B)")
|
|
out = eng.run(_t2v("wan2.1-1.3b", "a cat surfing a wave", 7))
|
|
print(f" video {out.artifacts['video'].frames.shape} "
|
|
f"denoise_steps={out.metrics['denoise_steps']:.0f}")
|
|
|
|
|
|
def example_b_ltx2_two_stage(eng) -> None:
|
|
print("\n(b) LTX-2 two-stage distilled (base 8-step → upsample → refine 3-step), shared transformer")
|
|
out = eng.run(_t2v("ltx2-2stage-distilled", "a neon city at night", 2))
|
|
print(f" video {out.artifacts['video'].frames.shape} "
|
|
f"base={out.metrics['base_steps']:.0f} refine={out.metrics['refine_steps']:.0f}")
|
|
|
|
|
|
def example_c_causal_streaming(eng) -> None:
|
|
print("\n(c) Causal streaming (Wan-causal): chunk rollout + slab-KV, streamable by chunk")
|
|
out = eng.run(
|
|
_t2v("wan-causal-sf-1.3b", "a drone flight over mountains", 3, outputs=OutputSpec(stream={"video": True})))
|
|
print(f" latents {out.artifacts['latents'].latent.shape} chunks={out.metrics['chunks']:.0f} "
|
|
f"streamed_chunks={out.metrics.get('stream_chunks', 0)}")
|
|
|
|
|
|
def example_g_omni_mot() -> None:
|
|
print("\n(g) Omni / MoT (§16): ONE resident instance runs AR + diffusion loops on shared weights")
|
|
eng = build_omni_engine()
|
|
o = eng.run(
|
|
make_request(TaskType.T2V,
|
|
"cosmos3-vfm",
|
|
"a phoenix",
|
|
sampling=SamplingParams(max_tokens=6, seed=1),
|
|
diffusion=DiffusionParams(num_steps=4, seed=1)))
|
|
print(f" Cosmos3 (reason→joint denoise): text={o.artifacts['text'].text} "
|
|
f"video={o.artifacts['video'].frames.shape}")
|
|
o2 = eng.run(
|
|
make_request(TaskType.T2I,
|
|
"bagel-mot",
|
|
"a teapot",
|
|
sampling=SamplingParams(max_tokens=6, seed=2),
|
|
diffusion=DiffusionParams(num_steps=4, seed=2)))
|
|
print(f" BAGEL (generate_text→generate_image): text={o2.artifacts['text'].text} "
|
|
f"image={o2.artifacts['image'].tensor.shape}")
|
|
print(f" scheduler priced BOTH WorkUnit kinds (runtime-visible, not one opaque stage): "
|
|
f"{dict(eng.admission.metrics.by_kind)}")
|
|
|
|
|
|
async def _serving_demo() -> None:
|
|
import asyncio
|
|
|
|
from v2.serving.deploy import DynamoWorkerAdapter, FakeDynamoRuntime, LocalFleet, build_deployment_card
|
|
from v2.recipes.wan21 import build_wan_t2v_program
|
|
from v2.runtime import AsyncEngine, PoolSet, wan_t2v_disaggregated
|
|
from v2.serving import OmniOpenAIServer
|
|
|
|
eng = build_default_engine()
|
|
build_omni_engine(eng)
|
|
ae = AsyncEngine(eng)
|
|
|
|
# disaggregated pools: encoder → denoiser → decoder
|
|
card = build_wan21_card()
|
|
pools = PoolSet(wan_t2v_disaggregated(), card)
|
|
pools.warmup()
|
|
ae.register_disaggregated("wan-disagg", pools, build_wan_t2v_program())
|
|
out = await ae.generate(
|
|
make_request(TaskType.T2V, "wan-disagg", "a wave", diffusion=DiffusionParams(num_steps=4, seed=1)))
|
|
print(f" disaggregated T2V (enc→den→dec): video={out.artifacts['video'].frames.shape} "
|
|
f"cross-pool transfers={out.metrics['transfers']:.0f}")
|
|
|
|
# our own OpenAI server over a real socket
|
|
server = OmniOpenAIServer(ae, engine_id="worker-0")
|
|
host, port = await server.serve(port=0)
|
|
|
|
async def http(method: str, path: str, body: bytes = b"") -> str:
|
|
r, w = await asyncio.open_connection(host, port)
|
|
w.write(f"{method} {path} HTTP/1.1\r\nHost: x\r\nContent-Length: {len(body)}\r\n\r\n".encode() + body)
|
|
await w.drain()
|
|
data = await r.read()
|
|
w.close()
|
|
return data.decode("utf-8", "replace")
|
|
|
|
health = await http("GET", "/health")
|
|
sse = await http("POST", "/v1/chat/completions",
|
|
b'{"model":"cosmos3-vfm","messages":[{"role":"user","content":"a comet"}],"stream":true}')
|
|
n_chunks = sse.count("data: ")
|
|
print(
|
|
f" OpenAI server: /health ok={'healthy' in health}; chat SSE streamed {n_chunks} chunks (omni reason→denoise)"
|
|
)
|
|
await server.close()
|
|
|
|
# our own fleet router + Dynamo adapter (frontable, not relied upon) — same DeploymentCard
|
|
dcard = build_deployment_card("worker-0", [card])
|
|
fleet = LocalFleet("least_loaded")
|
|
fleet.register("worker-0", ae, dcard)
|
|
routed = fleet.route(make_request(TaskType.T2V, "wan2.1-1.3b", "x", diffusion=DiffusionParams(num_steps=2)))
|
|
dyn = FakeDynamoRuntime()
|
|
dyn.register_worker(DynamoWorkerAdapter(ae, dcard))
|
|
print(f" LocalFleet routes to '{routed.worker_id}'; Dynamo adapter registered "
|
|
f"({len(dyn.registry)} worker) — both consume the SAME DeploymentCard")
|
|
|
|
|
|
def example_h_serving_and_fleet() -> None:
|
|
import asyncio
|
|
print("\n(h) Serving + fleet (OUR OWN — Dynamo-optional): async engine, role pools, OpenAI server")
|
|
asyncio.run(_serving_demo())
|
|
|
|
|
|
def main() -> None:
|
|
print("=" * 78)
|
|
print("v2 — worked examples. One runtime, many loops.")
|
|
print("=" * 78)
|
|
eng = build_default_engine()
|
|
print(f"registered (recipe, runtime) cards: {list(eng._registry)}")
|
|
example_a_text_to_video(eng)
|
|
example_b_ltx2_two_stage(eng)
|
|
example_c_causal_streaming(eng)
|
|
example_g_omni_mot()
|
|
example_h_serving_and_fleet()
|
|
print("\n" + "=" * 78)
|
|
print("All examples ran on CPU with numpy toy components. The architecture (cards, driven")
|
|
print("loops, scheduler, caches, parity, and serving) is real; the neural")
|
|
print("forwards are toys. On a GPU box, swap ComponentSpec.factory for the torch adapters.")
|
|
print("=" * 78)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|