Mechanical conversion of every relative import under v2/ to an absolute v2.* path (from .x / ..x / ...x -> from v2.<pkg>.x) so imports are unambiguous, grep-able, and stable when code is copied/moved between entrypoints (VideoGenerator, CLI, server). Surgical prefix-only rewrite: only the 'from <dots><module>' prefix changed — import names, parentheses, multi-line formatting, comments, and ordering are byte-for-byte preserved (no collapsing, no reorder, no unrelated reformatting). - 471 imports across 125 files; v2/tests/ was already absolute (untouched). - Validated: all 125 files compile, every 'from v2.* import' target resolves to a real module/package, zero relative imports remain (full sweep), CPU mini suite green (202 passed, 2 skipped).
38 lines
1.7 KiB
Python
38 lines
1.7 KiB
Python
"""Shared component-node helpers (text encode with feature cache, etc.).
|
|
|
|
The content-hash feature cache (design_v3 §7.2) is the reuse mechanism behind the §10 claim that
|
|
a K-sample RL group encodes its shared prompt once instead of K times.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from v2.cache.keys import CacheKey, content_hash
|
|
|
|
|
|
def cached_text_encode(instance: Any, text: str) -> Any:
|
|
enc = instance.component("text_encoder")
|
|
cache = instance.caches
|
|
if cache is not None and cache.has("feature"):
|
|
# §7.1: every output-semantic field is in the key — adapter stack + precision partition it,
|
|
# and the text-encoder's OWN version (not the instance's) so a transformer weight sync
|
|
# does not invalidate the (frozen) text encoder's embeddings.
|
|
key = CacheKey(model_id=instance.card.model_id, component_id="text_encoder",
|
|
weights_version=instance.version_of("text_encoder"),
|
|
adapter_versions=CacheKey.adapters(instance.adapter_versions),
|
|
precision=instance.card.precision.dtype_for("text_encoder"),
|
|
input_hashes=(("text", content_hash(text)),))
|
|
hit = cache.pool("feature").get(key)
|
|
if hit is not None:
|
|
return hit
|
|
emb = enc.encode(text)
|
|
cache.pool("feature").put(key, emb)
|
|
return emb
|
|
return enc.encode(text)
|
|
|
|
|
|
def text_encode_node_fn(instance, slots, request, ctx) -> None:
|
|
"""ComponentNode fn: prompt + negative prompt → cached text embeddings in slots."""
|
|
slots["text_embeds"] = cached_text_encode(instance, request.prompt())
|
|
slots["neg_text_embeds"] = cached_text_encode(instance, request.diffusion.negative_prompt)
|