From 41436a38272cf608c50b7796c38b8ef205445b87 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 03:32:14 +0000 Subject: [PATCH 01/21] Optional LAN password sign-in with device-bound access for the phone proxy --- freevideo_engine/access_proxy.py | 186 ++++++++++++++++++--- freevideo_engine/agent/access.py | 9 +- freevideo_engine/agent/routes.py | 10 +- freevideo_engine/agent/schema.py | 10 +- freevideo_engine/comfy_launcher_runtime.py | 9 +- freevideo_engine/diagnostics.py | 4 + freevideo_engine/lan_auth.py | 116 +++++++++++++ freevideo_engine/lan_password.py | 91 ++++++++++ freevideo_engine/launcher_session.py | 2 +- freevideo_engine/proxy_identity.py | 17 ++ 10 files changed, 421 insertions(+), 33 deletions(-) create mode 100644 freevideo_engine/lan_auth.py create mode 100644 freevideo_engine/lan_password.py diff --git a/freevideo_engine/access_proxy.py b/freevideo_engine/access_proxy.py index c382951a..84f5fe8f 100644 --- a/freevideo_engine/access_proxy.py +++ b/freevideo_engine/access_proxy.py @@ -1,4 +1,4 @@ -"""Token-protected access to a ComfyUI that listens on this computer only. +"""Authenticated access to a ComfyUI that listens on this computer only. The launcher's LAN switch or `freevideo server --listen ADDRESS` runs this in front of ComfyUI. The access link carries the token once; the page then keeps it in a cookie, and API @@ -9,17 +9,69 @@ import argparse import asyncio import hmac +import hashlib +import html +import math +import time +import ipaddress import os from pathlib import Path import ssl -from urllib.parse import urlencode +from urllib.parse import urlencode, urlsplit from aiohttp import ClientSession, ClientTimeout, DummyCookieJar, TCPConnector, WSMsgType, client_exceptions, web from yarl import URL -from . import proxy_identity +from . import proxy_identity, lan_password +from .lan_auth import PasswordAuth, DEVICE_COOKIE, REMEMBER_SECONDS, LOGIN_DELAY COOKIE = 'freevideo_access' DAYS = 30 +LOGIN_PATH = '/m/login' +# Temporary English copy; keep all password-page text here for Iris. +PASSWORD_COPY = dict(title='FreeVideo', password='Password', remember='Keep me signed in', + submit='Sign in', incorrect='Incorrect password', retry='Try again later ({minutes} minutes).', + phone='FreeVideo mobile', pending='Mobile pages are coming soon.') + + +def password_page(*, error='', retry_after=0, status=401): + copy = PASSWORD_COPY + message = copy['retry'].format(minutes=math.ceil(retry_after / 60)) if retry_after else error + response = web.Response(status=status, content_type='text/html', text=( + '{title}' + '

{title}

{message}

' + '' + '' + '
').format( + **{k: html.escape(v) for k, v in copy.items()}, message=html.escape(message), retry_after=retry_after, action=LOGIN_PATH)) + response.headers['Cache-Control'] = 'no-store' + response.headers['Referrer-Policy'] = 'no-referrer' + response.headers['Content-Security-Policy'] = "default-src 'none'; form-action 'self'; frame-ancestors 'none'" + if retry_after: + response.headers['Retry-After'] = str(retry_after) + response.headers['X-FreeVideo-Retry-After'] = str(retry_after) + return response + + +def same_origin(request): + try: + if len(request.headers.getall('Host', [])) != 1 or len(request.headers.getall('Origin', [])) != 1: + return False + host = urlsplit(request.scheme + '://' + request.host) + origin = urlsplit(request.headers['Origin']) + socket = request.transport.get_extra_info('sockname') + allowed = {socket[0].split('%')[0]} + if ipaddress.ip_address(socket[0].split('%')[0]).is_loopback: + allowed.update(('localhost', '127.0.0.1', '::1')) + own_port = host.port or (443 if request.scheme == 'https' else 80) + return (host.hostname in allowed and own_port == socket[1] and origin.hostname == host.hostname + and (origin.port or (443 if origin.scheme == 'https' else 80)) == own_port + and origin.scheme == request.scheme and not any((origin.path, origin.query, origin.fragment, + origin.username, origin.password))) + except (ValueError, TypeError, IndexError, KeyError): + return False + + # Hop-by-hop headers belong to one connection; Content-Length follows the body actually sent. HOP_BY_HOP = frozenset(('connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'proxy-connection', 'te', 'trailer', 'transfer-encoding', 'upgrade', 'content-length')) @@ -56,26 +108,88 @@ def forwarded(request): headers = [] for name, value in request.headers.items(): lower = name.lower() - if lower in HOP_BY_HOP or lower in ('authorization', proxy_identity.HEADER.lower(), - proxy_identity.PEER.lower(), proxy_identity.ORIGIN.lower()): + if lower in HOP_BY_HOP or lower == 'authorization' or lower.startswith('x-freevideo-proxy-'): continue if lower == 'cookie': value = '; '.join(part for part in value.split(';') if part.strip() and - part.split('=', 1)[0].strip() != COOKIE) + part.split('=', 1)[0].strip() not in (COOKIE, DEVICE_COOKIE)) if not value: continue headers.append((name, value)) return headers -def create(upstream, token): +def create(upstream, token, engine=None): upstream = upstream.rstrip('/') sockets = 'ws' + upstream[len('http'):] client = [] hop_secret = os.environ.pop(proxy_identity.ENV, '') + auth = PasswordAuth(engine) + login_lock = asyncio.Lock() + + def browser_headers(response, request): + device = request.get('lan_device') + if device and request.path in ('/m/', '/m/csrf'): + response.headers['X-FreeVideo-CSRF'] = proxy_identity.csrf(hop_secret, device) + session = request.get('lan_session') + if session and session['remember']: + response.set_cookie(DEVICE_COOKIE, request.cookies[DEVICE_COOKIE], max_age=REMEMBER_SECONDS, + httponly=True, samesite='Lax', secure=request.secure, path='/') + return response + + async def login(request): + if not same_origin(request): + return web.Response(status=403) + # The rest of the proxy streams unlimited uploads. Only login is bounded. + body = bytearray() + async for chunk in request.content.iter_chunked(4096): + body.extend(chunk) + if len(body) > 16384: + return web.Response(status=413) + from urllib.parse import parse_qs + try: + if request.content_type != 'application/x-www-form-urlencoded': + return web.Response(status=415) + fields = parse_qs(body.decode('utf-8'), keep_blank_values=True, max_num_fields=8) + texts = fields.get('password', ['']) + text = texts[0] if len(texts) == 1 else '' + remember = fields.get('remember') == ['1'] + except (ValueError, UnicodeError): + return web.Response(status=400) + ip = request.remote or '' # Never trust X-Forwarded-For for attempt limits. + async with login_lock: + started = time.monotonic() + auth.reload() + record = auth.record + correct = await asyncio.to_thread(lan_password.verify_record, record, text) + await asyncio.sleep(max(0, LOGIN_DELAY - (time.monotonic() - started))) + auth.reload() + if not auth.enabled or auth.record != record: + return password_page(error=PASSWORD_COPY['incorrect']) + now = time.monotonic() + remaining = auth.attempts.remaining(ip, now) + if remaining: + auth.log(ip, 'locked') + return password_page(retry_after=remaining, status=429) + if not correct: + remaining = auth.attempts.failed(ip, now) + if remaining: + auth.log(ip, 'locked') + return password_page(error=PASSWORD_COPY['incorrect'], retry_after=remaining, + status=429 if remaining else 401) + value = auth.issue(remember, time.time()) + auth.attempts.success(ip) + auth.log(ip, 'success') + response = web.Response(status=303, headers={'Location': '/m/', 'Cache-Control': 'no-store'}) + response.set_cookie(DEVICE_COOKIE, value, max_age=REMEMBER_SECONDS if remember else None, + httponly=True, samesite='Lax', secure=request.secure, path='/') + return response def forwarding_headers(request): - return forwarded(request) + proxy_identity.headers(request, hop_secret) + headers = forwarded(request) + proxy_identity.headers(request, hop_secret) + if request.get('lan_device'): + headers.append((proxy_identity.DEVICE, request['lan_device'])) + return headers async def startup(app): # No total timeout: downloads and the progress socket last as long as they need. @@ -96,6 +210,7 @@ async def forward(request): response.headers.add(name, value) if reply.content_length is not None and request.method != 'HEAD': response.content_length = reply.content_length + browser_headers(response, request) await response.prepare(request) async for chunk in reply.content.iter_chunked(1 << 16): await response.write(chunk) @@ -105,7 +220,7 @@ async def forward(request): return web.json_response(dict(error='ComfyUI is not answering yet.'), status=502) async def websocket(request): - browser = web.WebSocketResponse(max_msg_size=0) + browser = browser_headers(web.WebSocketResponse(max_msg_size=0), request) await browser.prepare(request) headers = [(k, v) for k, v in forwarding_headers(request) if k.lower() not in ( 'sec-websocket-key', 'sec-websocket-version', 'sec-websocket-extensions', 'sec-websocket-protocol')] @@ -131,18 +246,49 @@ async def pump(source, target): return browser async def handle(request): - offered = request.rel_url.query.get('token') - if offered is not None: - if not matches(offered, token): + auth.reload() + if auth.enabled: + if request.path == LOGIN_PATH and request.method == 'POST': + return await login(request) + session = auth.authenticate(request.cookies.get(DEVICE_COOKIE), time.time()) + if session: + request['lan_device'] = session['hash'] + request['lan_session'] = session + else: + header = request.headers.get('Authorization', '') + if not (header[:7].lower() == 'bearer ' and matches(header[7:].strip(), token)): + remaining = auth.attempts.remaining(request.remote or '', time.monotonic()) + return password_page(retry_after=remaining, status=429 if remaining else 401) + else: + offered = request.rel_url.query.get('token') + if offered is not None: + if not matches(offered, token): + return denied(request) + # Preserve the existing one-time link exchange and cookie behavior. + rest = [(k, v) for k, v in request.rel_url.query.items() if k != 'token'] + response = web.Response(status=303, headers={'Location': request.rel_url.path + ('?' + urlencode(rest) if rest else '')}) + response.set_cookie(COOKIE, token, max_age=DAYS * 86400, httponly=True, samesite='Lax', + secure=request.secure, path='/') + return response + if not matches(supplied(request), token): return denied(request) - # The access link: keep the token in a cookie and show the address without it. + if matches(request.cookies.get(COOKIE), token): + request['lan_device'] = hashlib.sha256(token.encode()).hexdigest() + # A query token in password mode neither authenticates nor reaches ComfyUI. + if auth.enabled and 'token' in request.query: rest = [(k, v) for k, v in request.rel_url.query.items() if k != 'token'] - response = web.Response(status=303, headers={'Location': request.rel_url.path + ('?' + urlencode(rest) if rest else '')}) - response.set_cookie(COOKIE, token, max_age=DAYS * 86400, httponly=True, samesite='Lax', - secure=request.secure, path='/') - return response - if not matches(supplied(request), token): - return denied(request) + location = request.path + ('?' + urlencode(rest) if rest else '') + return browser_headers(web.Response(status=303, headers={'Location': location}), request) + if request.path in ('/m/', '/m/csrf') and request.method in ('GET', 'HEAD'): + if not request.get('lan_device'): + return web.Response(status=403) + if request.path == '/m/csrf': + response = web.json_response(dict(csrf=proxy_identity.csrf(hop_secret, request['lan_device']))) + else: + response = web.Response(text='%s

%s

%s

' % ( + PASSWORD_COPY['title'], PASSWORD_COPY['phone'], PASSWORD_COPY['pending']), content_type='text/html') + response.headers['Cache-Control'] = 'no-store' + return browser_headers(response, request) if request.headers.get('Upgrade', '').lower() == 'websocket': return await websocket(request) return await forward(request) @@ -172,7 +318,7 @@ def main(argv=None): if args.tls_cert: context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(args.tls_cert, args.tls_key) - web.run_app(create(args.upstream, token), host=args.listen, port=args.port, ssl_context=context, + web.run_app(create(args.upstream, token, args.token_file.parent.parent), host=args.listen, port=args.port, ssl_context=context, access_log=None, print=None) diff --git a/freevideo_engine/agent/access.py b/freevideo_engine/agent/access.py index 553ad56b..e7ed6807 100644 --- a/freevideo_engine/agent/access.py +++ b/freevideo_engine/agent/access.py @@ -27,12 +27,13 @@ def lan_enabled(): return False -def check(request, *, local=False): +def check(request, *, local=False, lan=False): address = peer_address(request) proxied = proxy_identity.HEADER in request.headers - # Even a proxy client on loopback is never a local control-plane client. - if (proxied and (not proxy_identity.trusted(request) or local or not lan_enabled()) - or address is None or not address.is_loopback and (local or not address.is_private or not lan_enabled())): + # Only explicitly listed browser routes may use a verified proxy device. + local_only = local and not (proxied and lan and bool(proxy_identity.device(request))) + if (proxied and (not proxy_identity.trusted(request) or local_only or not lan_enabled()) + or address is None or not address.is_loopback and (local_only or not address.is_private or not lan_enabled())): raise JobError('local_only', 'Peer is not permitted') socket = request.transport.get_extra_info('sockname') if request.transport else None try: diff --git a/freevideo_engine/agent/routes.py b/freevideo_engine/agent/routes.py index e0fa1135..5d62fbee 100644 --- a/freevideo_engine/agent/routes.py +++ b/freevideo_engine/agent/routes.py @@ -457,12 +457,16 @@ async def respond(request): definition = contracts.get((method, suffix)) if definition is None: raise JobError('method_not_allowed' if any(p == suffix for _, p in contracts) else 'not_found', 'No contract') - access.check(request, local=definition.get('local', False)) + access.check(request, local=definition.get('local', False), lan=definition.get('lan', False)) if definition.get('auth') is False and definition.get('local') and method not in ('GET', 'HEAD'): session = page_sessions.get(request.cookies.get('freevideo_agent_page', '')) csrf = request.headers.get('X-FreeVideo-CSRF', '') - if (session is None or session[1] < time.monotonic() or not csrf - or not secrets.compare_digest(csrf.encode(), session[0].encode())): + if proxy_identity.HEADER in request.headers: + valid = definition.get('lan') and proxy_identity.check_csrf(request) + else: + valid = (session is not None and session[1] >= time.monotonic() and csrf + and secrets.compare_digest(csrf.encode(), session[0].encode())) + if not valid: raise JobError('page_session_required', 'Page session required') header = request.headers.get('Authorization', '') given = header[7:].strip() if header[:7].lower() == 'bearer ' else request.headers.get('X-FreeVideo-Agent', '') diff --git a/freevideo_engine/agent/schema.py b/freevideo_engine/agent/schema.py index dfca3b7c..11fd2b10 100644 --- a/freevideo_engine/agent/schema.py +++ b/freevideo_engine/agent/schema.py @@ -424,7 +424,15 @@ def route(summary, body=None, query=None, **kw): ('/chat', 'POST', obj({'text': string(8000), 'id': CHAT_ID, 'session': SESSION, 'whitebox': {'type': 'boolean'}}, ('text', 'id'))), ('/chat/confirm', 'POST', obj({'id': string(12, pattern=r'^cf[0-9a-f]{10}$'), 'approve': {'type': 'boolean'}, 'session': SESSION}, ('id', 'approve')))): - routes[(method, '/freevideo/agent' + suffix)] = route('Studio Agent controls', body=body, auth=False, local=True) + routes[(method, '/freevideo/agent' + suffix)] = route('Studio Agent controls', body=body, auth=False, local=True, + lan=suffix in ('/chat', '/chat/now', '/chat/confirm', '/chat/list', '/chat/new', '/chat/video', + '/activity', '/activity/cancel')) + # These existing ComfyUI handlers are registered outside the Agent dispatcher. + # /chain is a creation POST; monitoring reads /chains and /chain/{id}. + for suffix in ('/freevideo/progress', '/freevideo/chains', '/freevideo/chain/{id}'): + routes['GET', suffix] = route('Read generation monitoring', auth=False, lan=True, external=True, + query=obj({'client_id': string()}) if suffix != '/freevideo/progress' else EMPTY, + **({'path': obj({'id': string()}, ('id',))} if '{id}' in suffix else {})) routes['GET', '/freevideo/agent/chat']['query'] = obj({'after': number(0, integer=True), 'session': SESSION}) routes['GET', '/freevideo/agent/chat/video']['query'] = obj({'id': string(43, pattern=r'^[0-9]{4}-[0-9]{2}-[0-9]{2}/[0-9a-f]{32}$')}, ('id',)) for method, suffix, summary, extra in ( diff --git a/freevideo_engine/comfy_launcher_runtime.py b/freevideo_engine/comfy_launcher_runtime.py index b33af27c..271d9e65 100644 --- a/freevideo_engine/comfy_launcher_runtime.py +++ b/freevideo_engine/comfy_launcher_runtime.py @@ -32,7 +32,7 @@ from .desktop_runtime import materialize_source, source_release from .monitoring import save from .long_paths import io_path, resolved, plain, plain_text, plain_error, plain_errors -from . import engine_binding, processes +from . import engine_binding, processes, lan_password PROTOCOL = 1 TEMPLATE = 'FreeVideo-All-in-One.json' @@ -747,9 +747,10 @@ def refresh_access_links(self): from .proxy import local_addresses self.access_polled = time.monotonic() secret = token(self.selection['engine']) - self.access_links = [address(host, self.selection['lan_port']) + '/?freevideo=launch&token=' + secret - for host in local_addresses()] - self.state = dict(self.state, lan_status='' if self.access_links else 'no-address') + password_set = lan_password.is_set(self.selection['engine']) + suffix = '/m/' if password_set else '/m/?freevideo=launch&token=' + secret + self.access_links = [address(host, self.selection['lan_port']) + suffix for host in local_addresses()] + self.state = dict(self.state, lan_status='' if self.access_links else 'no-address', lan_password_set=password_set) def check_access_proxy(self): """Poll child lifetimes and refresh network links without moving ComfyUI.""" diff --git a/freevideo_engine/diagnostics.py b/freevideo_engine/diagnostics.py index 5c732154..01b329f0 100644 --- a/freevideo_engine/diagnostics.py +++ b/freevideo_engine/diagnostics.py @@ -30,6 +30,7 @@ 'prompt-rewrite.json', 'plan.json', 'machine.before.json', 'comparison.json', 'profile.json', 'result.json', 'gpu.csv', 'ram.jsonl', 'network.jsonl', 'optimization.json', 'storage.json', 'kernel-capabilities.json'} +SENSITIVE_FILES = frozenset(('lan-password.json', 'lan-devices.json')) SENSITIVE = re.compile(r'(?:^|[_-])(?:token|password|secret|credential|api[_-]?key)(?:$|[_-])', re.I) # Path-bearing fields are retained only as installation-relative names (when a # known report root is available) or as a basename under ````. Reports @@ -283,6 +284,9 @@ def add(name, raw, truncated=False): manifest['payload_bytes'] += len(data) def add_path(name, path): + if Path(path).name.lower() in SENSITIVE_FILES: + manifest['omitted'].append({'file': name, 'reason': 'Private LAN authentication record'}) + return try: data, truncated = read_complete(path) if complete else read_bounded(path) add(name, data, truncated) diff --git a/freevideo_engine/lan_auth.py b/freevideo_engine/lan_auth.py new file mode 100644 index 00000000..a8543b9c --- /dev/null +++ b/freevideo_engine/lan_auth.py @@ -0,0 +1,116 @@ +"""Proxy-owned device sessions and in-memory password attempt limits.""" +from collections import deque +from datetime import datetime, timezone +import hashlib +import json +import math +import secrets + +from . import lan_password + +DEVICE_COOKIE = 'freevideo_device' +REMEMBER_SECONDS = 30 * 86400 +SESSION_SECONDS = 12 * 3600 +LOGIN_DELAY = .25 +TOUCH_SECONDS = 60 +MAX_SOURCES = 1024 + + +class Attempts: + def __init__(self): + self.sources = {} + self.failures = deque() + self.global_until = 0 + + def remaining(self, ip, now): + return max(0, math.ceil(max(self.global_until, self.sources.get(ip, (0, 0))[1]) - now)) + + def failed(self, ip, now): + count = self.sources.get(ip, (0, 0))[0] + 1 + until = now + min(900, 60 * 2 ** min(count - 5, 4)) if count >= 5 else 0 + self.sources[ip] = count, until + if len(self.sources) > MAX_SOURCES: + for key in [key for key, (_, wait) in self.sources.items() if wait <= now and key != ip]: + del self.sources[key] + while len(self.sources) > MAX_SOURCES: + del self.sources[next(iter(self.sources))] + while self.failures and self.failures[0] <= now - 600: + self.failures.popleft() + self.failures.append(now) + if len(self.failures) >= 30: + self.global_until = now + 300 + return self.remaining(ip, now) + + def success(self, ip): + self.sources.pop(ip, None) + + +class PasswordAuth: + def __init__(self, engine): + self.engine = engine + self.signature = None + self.enabled = False + self.record = None + self.attempts = Attempts() + + def reload(self): + if self.engine is None: + return + try: + info = lan_password.path(self.engine).stat() + signature = info.st_mtime_ns, info.st_ino, info.st_size + except FileNotFoundError: + signature = None + except OSError: + signature = 'unreadable' + self.enabled = signature is not None + if signature != self.signature: + self.record = lan_password.read(self.engine) if self.enabled else None + self.signature = signature + + def generation(self): + return hashlib.sha256(b''.join(self.record)).hexdigest() if self.record else '' + + def devices(self, now): + try: + target = lan_password.path(self.engine).with_name(lan_password.DEVICES_FILE) + value = json.loads(target.read_text(encoding='utf-8')) + if not isinstance(value, dict) or value.get('password') != self.generation() or not self.record: + return [] + return [row for row in value['devices'] if isinstance(row, dict) and isinstance(row['hash'], str) and + len(row['hash']) == 64 and all(c in '0123456789abcdef' for c in row['hash']) and + all(type(row[key]) in (int, float) and math.isfinite(row[key]) for key in ('created', 'last_used')) and + type(row['remember']) is bool and + now < (row['last_used'] + REMEMBER_SECONDS if row['remember'] else row['created'] + SESSION_SECONDS)] + except (OSError, ValueError, KeyError, TypeError): + return [] + + def save(self, rows): + lan_password.save_private(lan_password.path(self.engine).with_name(lan_password.DEVICES_FILE), + dict(version=1, password=self.generation(), devices=rows)) + + def issue(self, remember, now): + value = secrets.token_urlsafe(32) + digest = hashlib.sha256(value.encode()).hexdigest() + rows = self.devices(now) + rows.append(dict(hash=digest, created=now, last_used=now, remember=remember)) + self.save(rows) + return value + + def authenticate(self, value, now): + if not value or len(value) != 43 or not self.record: + return None + digest = hashlib.sha256(value.encode()).hexdigest() + rows = self.devices(now) + for row in rows: + if secrets.compare_digest(row['hash'], digest): + if now - row['last_used'] >= TOUCH_SECONDS: + row['last_used'] = now + self.save(rows) + return row + return None + + def log(self, ip, result): + target = lan_password.path(self.engine).with_name('access-proxy.log') + with target.open('a', encoding='utf-8') as stream: + stream.write('%s %s %s\n' % (datetime.now(timezone.utc).isoformat(), ip, result)) diff --git a/freevideo_engine/lan_password.py b/freevideo_engine/lan_password.py new file mode 100644 index 00000000..a5c16296 --- /dev/null +++ b/freevideo_engine/lan_password.py @@ -0,0 +1,91 @@ +"""Optional LAN password and private, atomic authentication records. + +The engine root is the same root used by launcher_settings.Store. Passwords +never enter launcher preferences; only the fixed scrypt record is persisted. +""" +import hashlib +import hmac +import json +import os +from pathlib import Path +import secrets + +from .agent import private_file +from .long_paths import io_path + +MIN_LENGTH = 6 +N, R, P = 2 ** 15, 8, 1 +PASSWORD_FILE = 'lan-password.json' +DEVICES_FILE = 'lan-devices.json' + + +def path(engine): + return Path(engine) / 'launcher' / PASSWORD_FILE + + +def is_set(engine): + # An unreadable or invalid record must never silently disable protection. + return io_path(path(engine)).exists() + + +def save_private(target, value): + target = Path(target) + target.parent.mkdir(mode=0o700, parents=True, exist_ok=True) + temporary = target.with_name('.' + target.name + '-' + secrets.token_hex(8)) + descriptor = private_file.create(temporary) + try: + with os.fdopen(descriptor, 'w', encoding='utf-8') as stream: + json.dump(value, stream, separators=(',', ':')) + stream.write('\n') + stream.flush() + os.fsync(stream.fileno()) + os.replace(temporary, target) + finally: + temporary.unlink(missing_ok=True) + + +def clear_devices(engine): + save_private(path(engine).with_name(DEVICES_FILE), dict(version=1, devices=[])) + + +def derive(text, salt): + # OpenSSL's default 32 MiB cap is slightly below this parameter set's needs. + return hashlib.scrypt(text.encode('utf-8'), salt=salt, n=N, r=R, p=P, dklen=32, maxmem=64 * 1024 ** 2) + + +def read(engine): + try: + with path(engine).open(encoding='utf-8') as stream: + value = json.loads(stream.read(4096)) + if (value['version'], value['n'], value['r'], value['p']) != (1, N, R, P): + return None + salt, digest = bytes.fromhex(value['salt']), bytes.fromhex(value['hash']) + return (salt, digest) if len(salt) == 16 and len(digest) == 32 else None + except (OSError, ValueError, KeyError, TypeError): + return None + + +def verify_record(record, text): + salt, expected = record if record is not None else (bytes(16), bytes(32)) + actual = derive(text, salt) + return hmac.compare_digest(actual, expected) and record is not None + + +def verify(engine, text): + return verify_record(read(engine), text) + + +def set_password(engine, text): + if not isinstance(text, str) or len(text) < MIN_LENGTH: + raise ValueError('LAN password is too short') + salt = secrets.token_bytes(16) + digest = derive(text, salt) + # Device records also carry this password generation, so concurrent logins + # using the old record cannot revive devices during an atomic replacement. + clear_devices(engine) + save_private(path(engine), dict(version=1, salt=salt.hex(), n=N, r=R, p=P, hash=digest.hex())) + + +def remove(engine): + clear_devices(engine) + path(engine).unlink(missing_ok=True) diff --git a/freevideo_engine/launcher_session.py b/freevideo_engine/launcher_session.py index 3856bf52..fc0b336b 100644 --- a/freevideo_engine/launcher_session.py +++ b/freevideo_engine/launcher_session.py @@ -11,7 +11,7 @@ from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit from . import __version__ -from . import disk_space +from . import disk_space, lan_password from .comfy_launcher_runtime import Controller, layout, local_url, loopback_url, managed_frontend, new_layout, queue_busy from .desktop_runtime import launcher_root, materialize_source from .download_settings import Probe, read as download_preferences, speed_text diff --git a/freevideo_engine/proxy_identity.py b/freevideo_engine/proxy_identity.py index a6eb9f13..03e3a048 100644 --- a/freevideo_engine/proxy_identity.py +++ b/freevideo_engine/proxy_identity.py @@ -11,6 +11,7 @@ HEADER = 'X-FreeVideo-Proxy-Hop' PEER = 'X-FreeVideo-Proxy-Peer' ORIGIN = 'X-FreeVideo-Proxy-Origin' +DEVICE = 'X-FreeVideo-Proxy-Device' @lru_cache(maxsize=1) @@ -32,3 +33,19 @@ def trusted(request): secret = app.get(app_key(), '') if app is not None else '' offered = request.headers.get(HEADER, '') return bool(secret and offered) and hmac.compare_digest(secret.encode(), offered.encode()) + + +def csrf(secret, device): + """A browser proof bound to one authenticated device and this proxy hop.""" + return hmac.new(secret.encode(), ('lan-csrf:' + device).encode(), 'sha256').hexdigest() + + +def device(request): + return request.headers.get(DEVICE, '') if trusted(request) else '' + + +def check_csrf(request): + identity = device(request) + offered = request.headers.get('X-FreeVideo-CSRF', '') + secret = request.app.get(app_key(), '') + return bool(identity and offered) and hmac.compare_digest(offered.encode(), csrf(secret, identity).encode()) From ead145b52e1fd80e537315b0c4236a79b937906b Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 03:32:25 +0000 Subject: [PATCH 02/21] Local page LAN settings API with page-session CSRF; phones through the proxy are refused --- freevideo_engine/agent/errors.py | 2 + freevideo_engine/agent/routes.py | 63 +++++++++++++++--- freevideo_engine/comfy_launcher_runtime.py | 20 ++++-- freevideo_engine/lan_page.py | 75 ++++++++++++++++++++++ 4 files changed, 145 insertions(+), 15 deletions(-) create mode 100644 freevideo_engine/lan_page.py diff --git a/freevideo_engine/agent/errors.py b/freevideo_engine/agent/errors.py index 21c3aed9..9ec75f8b 100644 --- a/freevideo_engine/agent/errors.py +++ b/freevideo_engine/agent/errors.py @@ -17,6 +17,7 @@ ERRORS = { 'forbidden': (403, False, 'This caller cannot write this session event.', 'Only the user may stop or continue a session or answer a confirmation; steps are written by the server.'), 'session_full': (409, False, 'This session has reached its event limit.', 'Create a new session with POST /freevideo/agent/v1/sessions.'), + 'lan_unavailable': (409, False, 'LAN settings require a launcher installation.', 'Complete installation in the FreeVideo launcher on this computer. 请在本机 FreeVideo 启动器中完成安装。'), 'page_session_required': (403, False, 'A valid page session and CSRF header are required.', 'Reload the page served by this FreeVideo instance and repeat the action.'), 'redirect_forbidden': (403, False, 'A credentialed request cannot follow a cross-origin redirect.', 'Connect directly to the intended FreeVideo instance using its verified HTTP or HTTPS endpoint.'), 'method_not_allowed': (405, False, 'This method is not registered for the requested endpoint.', 'Read GET /freevideo/agent/v1/openapi.json and use the documented method.'), @@ -252,6 +253,7 @@ def safe_details(value): # One public sentence shared by conversation cards, HTTP and MCP. Backend text # is classified, never echoed: it can contain prompts, filenames or credentials. FAILURE_REASONS_ZH = { + 'lan_unavailable': '局域网设置需要启动器安装记录', 'out_of_memory': '生成时显存或内存不足', 'insufficient_memory': '可用显存或内存不够生成这段内容', 'no_memory': '可用显存或内存不够生成这张图片', diff --git a/freevideo_engine/agent/routes.py b/freevideo_engine/agent/routes.py index 5d62fbee..4c2892fc 100644 --- a/freevideo_engine/agent/routes.py +++ b/freevideo_engine/agent/routes.py @@ -459,13 +459,10 @@ async def respond(request): raise JobError('method_not_allowed' if any(p == suffix for _, p in contracts) else 'not_found', 'No contract') access.check(request, local=definition.get('local', False), lan=definition.get('lan', False)) if definition.get('auth') is False and definition.get('local') and method not in ('GET', 'HEAD'): - session = page_sessions.get(request.cookies.get('freevideo_agent_page', '')) - csrf = request.headers.get('X-FreeVideo-CSRF', '') if proxy_identity.HEADER in request.headers: valid = definition.get('lan') and proxy_identity.check_csrf(request) else: - valid = (session is not None and session[1] >= time.monotonic() and csrf - and secrets.compare_digest(csrf.encode(), session[0].encode())) + valid = valid_page_session(request) if not valid: raise JobError('page_session_required', 'Page session required') header = request.headers.get('Authorization', '') @@ -669,16 +666,19 @@ async def read_body(request, limit, optional=False): async def body(request, **ignored): return request[body_key] + def valid_page_session(request): + page = page_sessions.get(request.cookies.get('freevideo_agent_page', '')) + csrf = request.headers.get('X-FreeVideo-CSRF', '') + return (page is not None and page[1] >= time.monotonic() and bool(csrf) + and secrets.compare_digest(csrf.encode(), page[0].encode())) + def session_caller(request): """guarded verifies supplied tokens; otherwise require a local page and CSRF.""" header = request.headers.get('Authorization', '') given = header[7:].strip() if header[:7].lower() == 'bearer ' else request.headers.get('X-FreeVideo-Agent', '') if given: return 'agent' - page = page_sessions.get(request.cookies.get('freevideo_agent_page', '')) - csrf = request.headers.get('X-FreeVideo-CSRF', '') - if (page is not None and page[1] >= time.monotonic() and csrf - and secrets.compare_digest(csrf.encode(), page[0].encode())): + if valid_page_session(request): access.check(request, local=True) return 'user' raise JobError('unauthorized', 'Token or valid page session required') @@ -691,7 +691,7 @@ def agent_path(path): return path == '/freevideo/agent' or path.startswith('/freevideo/agent/') async def no_cross_site_headers(request, response): - if agent_path(request.path): + if agent_path(request.path) or request.path in ('/freevideo/lan', '/api/freevideo/lan'): for key in list(response.headers): if key.lower().startswith('access-control-'): del response.headers[key] @@ -737,9 +737,52 @@ async def page_session(request): response = reply(dict(csrf=page_sessions[current][0])) # The cookie follows the copy the page asked: its later calls go to the same one. response.set_cookie('freevideo_agent_page', current, httponly=True, samesite='Strict', secure=request.secure, - path=('/api' if request.path.startswith('/api/') else '') + '/freevideo/agent', max_age=12 * 3600) + path=('/api' if request.path.startswith('/api/') else '') + '/freevideo', max_age=12 * 3600) return response + # Page controls stay outside the Agent contract and never use its bearer token. + # ComfyUI mirrors these routes under /api along with the other page routes. + @routes.get('/freevideo/lan') + @routes.post('/freevideo/lan') + async def lan_settings(request): + from .. import lan_page + from ..comfy_bridge import installation_root + identity = errors.REQUEST_ID.set('r-' + uuid.uuid4().hex) + try: + access.check(request, local=True) + root = installation_root() + if request.method == 'POST': + if not valid_page_session(request): + raise JobError('page_session_required', 'Page session required') + value = await read_body(request, contract.MAX_BODY_BYTES) + return reply(await asyncio.to_thread(lan_page.apply, root, value)) + return reply(await asyncio.to_thread(lan_page.read, root)) + except lan_page.InvalidRequest as error: + field = error.field if error.field in ('enabled', 'password', '') else '' + row = contract.diagnostic('/' + field, error.allowed, error.got) + if field == 'password' and not isinstance(error.got, str): + row = contract.diagnostic('/password', error.allowed, None) + row.update(got='', message='/password must be %s.' % error.allowed) + value = errors.validation([row]) + return reply({'error': value}, 422) + except lan_page.LanUnavailable: + return problem('lan_unavailable') + except JobError as error: + return reply({'error': error.view()}, errors.ERRORS[error.code][0]) + except (json.JSONDecodeError, UnicodeDecodeError, RecursionError): + return problem('invalid_json') + except specs.SpecError as error: + return reply({'error': errors.validation(error.errors)}, 422) + except web.HTTPException as error: + return problem('too_large' if error.status == 413 else 'invalid_request') + except OSError: + return problem('storage_unavailable') + except Exception: + # Do not log exception text or request bodies from password controls. + return problem('internal_error') + finally: + errors.REQUEST_ID.reset(identity) + def activity_item(row, *, card=False): view = jobs.view(row, detail=False) value = {k: view.get(k) for k in ('id', 'kind', 'status', 'label', 'project', 'client', 'take', diff --git a/freevideo_engine/comfy_launcher_runtime.py b/freevideo_engine/comfy_launcher_runtime.py index 271d9e65..ddcf4eda 100644 --- a/freevideo_engine/comfy_launcher_runtime.py +++ b/freevideo_engine/comfy_launcher_runtime.py @@ -405,6 +405,19 @@ def address(hostname, port): return 'http://%s:%d' % ('[%s]' % hostname if ':' in hostname else hostname, port) +def lan_access_links(engine, port, *, password_set=None): + """Use the same phone entry and authentication policy for launcher and page.""" + from .comfy_service import token + from .proxy import local_addresses + hosts = local_addresses() + if not hosts: + return [] + if password_set is None: + password_set = lan_password.is_set(engine) + suffix = '/m/' if password_set else '/m/?freevideo=launch&token=' + token(engine) + return [address(host, port) + suffix for host in hosts] + + def next_free_address(url, count=12): """The next local address after this one that nothing listens or answers on, as setup.sh chooses.""" parsed = urlsplit(url) @@ -743,13 +756,10 @@ def _access_stopped(self): self.state = dict(self.state, selection=dict(self.selection), lan_status='stopped') def refresh_access_links(self): - from .comfy_service import token - from .proxy import local_addresses self.access_polled = time.monotonic() - secret = token(self.selection['engine']) password_set = lan_password.is_set(self.selection['engine']) - suffix = '/m/' if password_set else '/m/?freevideo=launch&token=' + secret - self.access_links = [address(host, self.selection['lan_port']) + suffix for host in local_addresses()] + self.access_links = lan_access_links(self.selection['engine'], self.selection['lan_port'], + password_set=password_set) self.state = dict(self.state, lan_status='' if self.access_links else 'no-address', lan_password_set=password_set) def check_access_proxy(self): diff --git a/freevideo_engine/lan_page.py b/freevideo_engine/lan_page.py new file mode 100644 index 00000000..ecdae418 --- /dev/null +++ b/freevideo_engine/lan_page.py @@ -0,0 +1,75 @@ +"""Local page LAN settings, independent of the HTTP server.""" +import socket +import time + +from . import lan_auth, lan_password +from .launcher_settings import Store, default_language + + +class LanUnavailable(RuntimeError): + """The launcher has not recorded an installation on this computer.""" + + +class InvalidRequest(ValueError): + def __init__(self, field, allowed, got): + self.field, self.allowed, self.got = field, allowed, got + super().__init__('%s must be %s' % (field or 'body', allowed)) + + +def read(engine): + installation = Store(engine).read().get('installation') + flag = bool(installation and installation.get('lan_access') is True) + port = installation.get('lan_port') if installation else None + enabled = False + if flag and port is not None: + try: + with socket.create_connection(('127.0.0.1', port), timeout=.3): + enabled = True + except OSError: + pass + password_set = lan_password.is_set(engine) + auth = lan_auth.PasswordAuth(engine) + auth.reload() + link = '' + if enabled: + from .comfy_launcher_runtime import lan_access_links + links = lan_access_links(engine, port, password_set=password_set) + link = links[0] if links else '' + return dict(available=installation is not None, enabled=enabled, starting=flag and not enabled, + link=link, password_set=password_set, devices=len(auth.devices(time.time())), + min_length=lan_password.MIN_LENGTH) + + +def apply(engine, body): + if not isinstance(body, dict) or not body: + raise InvalidRequest('', 'a nonempty object containing enabled or password', body) + for field in body: + if field not in ('enabled', 'password'): + raise InvalidRequest(field, 'absent (unknown field)', None) + if 'enabled' in body and type(body['enabled']) is not bool: + raise InvalidRequest('enabled', 'a boolean', body['enabled']) + if 'password' in body: + password = body['password'] + if password is not None and not isinstance(password, str): + raise InvalidRequest('password', 'a string or null', password) + if isinstance(password, str) and len(password) < lan_password.MIN_LENGTH: + raise InvalidRequest('password', 'at least %d characters (min_length=%d)' % ( + lan_password.MIN_LENGTH, lan_password.MIN_LENGTH), password) + store = Store(engine) + with store.exclusive(): + saved = store.read() + installation = saved.get('installation') + if installation is None: + raise LanUnavailable() + # Validate the whole request and installation before changing authentication. + if 'password' in body: + if body['password'] is None: + lan_password.remove(engine) + else: + lan_password.set_password(engine, body['password']) + if 'enabled' in body: + installation = dict(installation, lan_access=body['enabled']) + # access.lan_enabled() checks the current top-level permission copies. + saved['lan_access'] = body['enabled'] + store.write_locked(saved, saved.get('language', default_language()), installation, saved.get('setup')) + return read(engine) From 54fec07416cae5933c17707f5b049e5690ef104b Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 04:00:32 +0000 Subject: [PATCH 03/21] Resolve the optional LAN password module per call in the launcher session --- freevideo_engine/launcher_session.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/freevideo_engine/launcher_session.py b/freevideo_engine/launcher_session.py index fc0b336b..53f36395 100644 --- a/freevideo_engine/launcher_session.py +++ b/freevideo_engine/launcher_session.py @@ -1,6 +1,7 @@ """Widget-independent state for the Qt launcher; uses the existing installer.""" from copy import deepcopy from functools import lru_cache +import importlib import json import os from pathlib import Path @@ -11,7 +12,7 @@ from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit from . import __version__ -from . import disk_space, lan_password +from . import disk_space from .comfy_launcher_runtime import Controller, layout, local_url, loopback_url, managed_frontend, new_layout, queue_busy from .desktop_runtime import launcher_root, materialize_source from .download_settings import Probe, read as download_preferences, speed_text @@ -45,6 +46,11 @@ @lru_cache(maxsize=4) +def _lan_password(): + # Resolved per call: the access module is optional and may be absent. + return importlib.import_module('.lan_password', __package__) + + def _qr_rows(text): from .qr_code import encode try: @@ -2005,14 +2011,14 @@ def lan_password_state(self): """(supported, set) for the optional LAN password; unsupported without the access module.""" engine = (self.controller.selection or {}).get('engine') try: - from . import lan_password + lan_password = _lan_password() return True, bool(engine) and bool(lan_password.is_set(engine)) except (ImportError, OSError): return False, False def lan_password_min(self): try: - from . import lan_password + lan_password = _lan_password() return int(getattr(lan_password, 'MIN_LENGTH', 6)) except (ImportError, OSError, TypeError, ValueError): return 6 @@ -2022,7 +2028,7 @@ def change_lan_password(self, text=None): engine = (self.controller.selection or {}).get('engine') if not engine: return - from . import lan_password + lan_password = _lan_password() if text is None: lan_password.remove(engine) else: From c6fc7b105e436aa3ef591c2ec9feb8b0822560a5 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 04:01:07 +0000 Subject: [PATCH 04/21] Resolve the optional LAN password module at import time again in the launcher session --- freevideo_engine/launcher_session.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/freevideo_engine/launcher_session.py b/freevideo_engine/launcher_session.py index 53f36395..fc0b336b 100644 --- a/freevideo_engine/launcher_session.py +++ b/freevideo_engine/launcher_session.py @@ -1,7 +1,6 @@ """Widget-independent state for the Qt launcher; uses the existing installer.""" from copy import deepcopy from functools import lru_cache -import importlib import json import os from pathlib import Path @@ -12,7 +11,7 @@ from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit from . import __version__ -from . import disk_space +from . import disk_space, lan_password from .comfy_launcher_runtime import Controller, layout, local_url, loopback_url, managed_frontend, new_layout, queue_busy from .desktop_runtime import launcher_root, materialize_source from .download_settings import Probe, read as download_preferences, speed_text @@ -46,11 +45,6 @@ @lru_cache(maxsize=4) -def _lan_password(): - # Resolved per call: the access module is optional and may be absent. - return importlib.import_module('.lan_password', __package__) - - def _qr_rows(text): from .qr_code import encode try: @@ -2011,14 +2005,14 @@ def lan_password_state(self): """(supported, set) for the optional LAN password; unsupported without the access module.""" engine = (self.controller.selection or {}).get('engine') try: - lan_password = _lan_password() + from . import lan_password return True, bool(engine) and bool(lan_password.is_set(engine)) except (ImportError, OSError): return False, False def lan_password_min(self): try: - lan_password = _lan_password() + from . import lan_password return int(getattr(lan_password, 'MIN_LENGTH', 6)) except (ImportError, OSError, TypeError, ValueError): return 6 @@ -2028,7 +2022,7 @@ def change_lan_password(self, text=None): engine = (self.controller.selection or {}).get('engine') if not engine: return - lan_password = _lan_password() + from . import lan_password if text is None: lan_password.remove(engine) else: From d4ecec6cfbbca5ec70a6ac1cdcd9b2115aa2fd1c Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 04:01:07 +0000 Subject: [PATCH 05/21] Remove the local page LAN settings API for now --- freevideo_engine/agent/errors.py | 2 - freevideo_engine/agent/routes.py | 63 +++--------------- freevideo_engine/comfy_launcher_runtime.py | 20 ++---- freevideo_engine/lan_page.py | 75 ---------------------- 4 files changed, 15 insertions(+), 145 deletions(-) delete mode 100644 freevideo_engine/lan_page.py diff --git a/freevideo_engine/agent/errors.py b/freevideo_engine/agent/errors.py index 9ec75f8b..21c3aed9 100644 --- a/freevideo_engine/agent/errors.py +++ b/freevideo_engine/agent/errors.py @@ -17,7 +17,6 @@ ERRORS = { 'forbidden': (403, False, 'This caller cannot write this session event.', 'Only the user may stop or continue a session or answer a confirmation; steps are written by the server.'), 'session_full': (409, False, 'This session has reached its event limit.', 'Create a new session with POST /freevideo/agent/v1/sessions.'), - 'lan_unavailable': (409, False, 'LAN settings require a launcher installation.', 'Complete installation in the FreeVideo launcher on this computer. 请在本机 FreeVideo 启动器中完成安装。'), 'page_session_required': (403, False, 'A valid page session and CSRF header are required.', 'Reload the page served by this FreeVideo instance and repeat the action.'), 'redirect_forbidden': (403, False, 'A credentialed request cannot follow a cross-origin redirect.', 'Connect directly to the intended FreeVideo instance using its verified HTTP or HTTPS endpoint.'), 'method_not_allowed': (405, False, 'This method is not registered for the requested endpoint.', 'Read GET /freevideo/agent/v1/openapi.json and use the documented method.'), @@ -253,7 +252,6 @@ def safe_details(value): # One public sentence shared by conversation cards, HTTP and MCP. Backend text # is classified, never echoed: it can contain prompts, filenames or credentials. FAILURE_REASONS_ZH = { - 'lan_unavailable': '局域网设置需要启动器安装记录', 'out_of_memory': '生成时显存或内存不足', 'insufficient_memory': '可用显存或内存不够生成这段内容', 'no_memory': '可用显存或内存不够生成这张图片', diff --git a/freevideo_engine/agent/routes.py b/freevideo_engine/agent/routes.py index 4c2892fc..5d62fbee 100644 --- a/freevideo_engine/agent/routes.py +++ b/freevideo_engine/agent/routes.py @@ -459,10 +459,13 @@ async def respond(request): raise JobError('method_not_allowed' if any(p == suffix for _, p in contracts) else 'not_found', 'No contract') access.check(request, local=definition.get('local', False), lan=definition.get('lan', False)) if definition.get('auth') is False and definition.get('local') and method not in ('GET', 'HEAD'): + session = page_sessions.get(request.cookies.get('freevideo_agent_page', '')) + csrf = request.headers.get('X-FreeVideo-CSRF', '') if proxy_identity.HEADER in request.headers: valid = definition.get('lan') and proxy_identity.check_csrf(request) else: - valid = valid_page_session(request) + valid = (session is not None and session[1] >= time.monotonic() and csrf + and secrets.compare_digest(csrf.encode(), session[0].encode())) if not valid: raise JobError('page_session_required', 'Page session required') header = request.headers.get('Authorization', '') @@ -666,19 +669,16 @@ async def read_body(request, limit, optional=False): async def body(request, **ignored): return request[body_key] - def valid_page_session(request): - page = page_sessions.get(request.cookies.get('freevideo_agent_page', '')) - csrf = request.headers.get('X-FreeVideo-CSRF', '') - return (page is not None and page[1] >= time.monotonic() and bool(csrf) - and secrets.compare_digest(csrf.encode(), page[0].encode())) - def session_caller(request): """guarded verifies supplied tokens; otherwise require a local page and CSRF.""" header = request.headers.get('Authorization', '') given = header[7:].strip() if header[:7].lower() == 'bearer ' else request.headers.get('X-FreeVideo-Agent', '') if given: return 'agent' - if valid_page_session(request): + page = page_sessions.get(request.cookies.get('freevideo_agent_page', '')) + csrf = request.headers.get('X-FreeVideo-CSRF', '') + if (page is not None and page[1] >= time.monotonic() and csrf + and secrets.compare_digest(csrf.encode(), page[0].encode())): access.check(request, local=True) return 'user' raise JobError('unauthorized', 'Token or valid page session required') @@ -691,7 +691,7 @@ def agent_path(path): return path == '/freevideo/agent' or path.startswith('/freevideo/agent/') async def no_cross_site_headers(request, response): - if agent_path(request.path) or request.path in ('/freevideo/lan', '/api/freevideo/lan'): + if agent_path(request.path): for key in list(response.headers): if key.lower().startswith('access-control-'): del response.headers[key] @@ -737,52 +737,9 @@ async def page_session(request): response = reply(dict(csrf=page_sessions[current][0])) # The cookie follows the copy the page asked: its later calls go to the same one. response.set_cookie('freevideo_agent_page', current, httponly=True, samesite='Strict', secure=request.secure, - path=('/api' if request.path.startswith('/api/') else '') + '/freevideo', max_age=12 * 3600) + path=('/api' if request.path.startswith('/api/') else '') + '/freevideo/agent', max_age=12 * 3600) return response - # Page controls stay outside the Agent contract and never use its bearer token. - # ComfyUI mirrors these routes under /api along with the other page routes. - @routes.get('/freevideo/lan') - @routes.post('/freevideo/lan') - async def lan_settings(request): - from .. import lan_page - from ..comfy_bridge import installation_root - identity = errors.REQUEST_ID.set('r-' + uuid.uuid4().hex) - try: - access.check(request, local=True) - root = installation_root() - if request.method == 'POST': - if not valid_page_session(request): - raise JobError('page_session_required', 'Page session required') - value = await read_body(request, contract.MAX_BODY_BYTES) - return reply(await asyncio.to_thread(lan_page.apply, root, value)) - return reply(await asyncio.to_thread(lan_page.read, root)) - except lan_page.InvalidRequest as error: - field = error.field if error.field in ('enabled', 'password', '') else '' - row = contract.diagnostic('/' + field, error.allowed, error.got) - if field == 'password' and not isinstance(error.got, str): - row = contract.diagnostic('/password', error.allowed, None) - row.update(got='', message='/password must be %s.' % error.allowed) - value = errors.validation([row]) - return reply({'error': value}, 422) - except lan_page.LanUnavailable: - return problem('lan_unavailable') - except JobError as error: - return reply({'error': error.view()}, errors.ERRORS[error.code][0]) - except (json.JSONDecodeError, UnicodeDecodeError, RecursionError): - return problem('invalid_json') - except specs.SpecError as error: - return reply({'error': errors.validation(error.errors)}, 422) - except web.HTTPException as error: - return problem('too_large' if error.status == 413 else 'invalid_request') - except OSError: - return problem('storage_unavailable') - except Exception: - # Do not log exception text or request bodies from password controls. - return problem('internal_error') - finally: - errors.REQUEST_ID.reset(identity) - def activity_item(row, *, card=False): view = jobs.view(row, detail=False) value = {k: view.get(k) for k in ('id', 'kind', 'status', 'label', 'project', 'client', 'take', diff --git a/freevideo_engine/comfy_launcher_runtime.py b/freevideo_engine/comfy_launcher_runtime.py index ddcf4eda..271d9e65 100644 --- a/freevideo_engine/comfy_launcher_runtime.py +++ b/freevideo_engine/comfy_launcher_runtime.py @@ -405,19 +405,6 @@ def address(hostname, port): return 'http://%s:%d' % ('[%s]' % hostname if ':' in hostname else hostname, port) -def lan_access_links(engine, port, *, password_set=None): - """Use the same phone entry and authentication policy for launcher and page.""" - from .comfy_service import token - from .proxy import local_addresses - hosts = local_addresses() - if not hosts: - return [] - if password_set is None: - password_set = lan_password.is_set(engine) - suffix = '/m/' if password_set else '/m/?freevideo=launch&token=' + token(engine) - return [address(host, port) + suffix for host in hosts] - - def next_free_address(url, count=12): """The next local address after this one that nothing listens or answers on, as setup.sh chooses.""" parsed = urlsplit(url) @@ -756,10 +743,13 @@ def _access_stopped(self): self.state = dict(self.state, selection=dict(self.selection), lan_status='stopped') def refresh_access_links(self): + from .comfy_service import token + from .proxy import local_addresses self.access_polled = time.monotonic() + secret = token(self.selection['engine']) password_set = lan_password.is_set(self.selection['engine']) - self.access_links = lan_access_links(self.selection['engine'], self.selection['lan_port'], - password_set=password_set) + suffix = '/m/' if password_set else '/m/?freevideo=launch&token=' + secret + self.access_links = [address(host, self.selection['lan_port']) + suffix for host in local_addresses()] self.state = dict(self.state, lan_status='' if self.access_links else 'no-address', lan_password_set=password_set) def check_access_proxy(self): diff --git a/freevideo_engine/lan_page.py b/freevideo_engine/lan_page.py deleted file mode 100644 index ecdae418..00000000 --- a/freevideo_engine/lan_page.py +++ /dev/null @@ -1,75 +0,0 @@ -"""Local page LAN settings, independent of the HTTP server.""" -import socket -import time - -from . import lan_auth, lan_password -from .launcher_settings import Store, default_language - - -class LanUnavailable(RuntimeError): - """The launcher has not recorded an installation on this computer.""" - - -class InvalidRequest(ValueError): - def __init__(self, field, allowed, got): - self.field, self.allowed, self.got = field, allowed, got - super().__init__('%s must be %s' % (field or 'body', allowed)) - - -def read(engine): - installation = Store(engine).read().get('installation') - flag = bool(installation and installation.get('lan_access') is True) - port = installation.get('lan_port') if installation else None - enabled = False - if flag and port is not None: - try: - with socket.create_connection(('127.0.0.1', port), timeout=.3): - enabled = True - except OSError: - pass - password_set = lan_password.is_set(engine) - auth = lan_auth.PasswordAuth(engine) - auth.reload() - link = '' - if enabled: - from .comfy_launcher_runtime import lan_access_links - links = lan_access_links(engine, port, password_set=password_set) - link = links[0] if links else '' - return dict(available=installation is not None, enabled=enabled, starting=flag and not enabled, - link=link, password_set=password_set, devices=len(auth.devices(time.time())), - min_length=lan_password.MIN_LENGTH) - - -def apply(engine, body): - if not isinstance(body, dict) or not body: - raise InvalidRequest('', 'a nonempty object containing enabled or password', body) - for field in body: - if field not in ('enabled', 'password'): - raise InvalidRequest(field, 'absent (unknown field)', None) - if 'enabled' in body and type(body['enabled']) is not bool: - raise InvalidRequest('enabled', 'a boolean', body['enabled']) - if 'password' in body: - password = body['password'] - if password is not None and not isinstance(password, str): - raise InvalidRequest('password', 'a string or null', password) - if isinstance(password, str) and len(password) < lan_password.MIN_LENGTH: - raise InvalidRequest('password', 'at least %d characters (min_length=%d)' % ( - lan_password.MIN_LENGTH, lan_password.MIN_LENGTH), password) - store = Store(engine) - with store.exclusive(): - saved = store.read() - installation = saved.get('installation') - if installation is None: - raise LanUnavailable() - # Validate the whole request and installation before changing authentication. - if 'password' in body: - if body['password'] is None: - lan_password.remove(engine) - else: - lan_password.set_password(engine, body['password']) - if 'enabled' in body: - installation = dict(installation, lan_access=body['enabled']) - # access.lan_enabled() checks the current top-level permission copies. - saved['lan_access'] = body['enabled'] - store.write_locked(saved, saved.get('language', default_language()), installation, saved.get('setup')) - return read(engine) From 57a1513c1cf8e8441e2d3a6ad005f6ba3a0c1fcf Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 04:01:07 +0000 Subject: [PATCH 06/21] Remove optional LAN password sign-in for the phone proxy for now --- freevideo_engine/access_proxy.py | 186 +++------------------ freevideo_engine/agent/access.py | 9 +- freevideo_engine/agent/routes.py | 10 +- freevideo_engine/agent/schema.py | 10 +- freevideo_engine/comfy_launcher_runtime.py | 9 +- freevideo_engine/diagnostics.py | 4 - freevideo_engine/lan_auth.py | 116 ------------- freevideo_engine/lan_password.py | 91 ---------- freevideo_engine/launcher_session.py | 2 +- freevideo_engine/proxy_identity.py | 17 -- 10 files changed, 33 insertions(+), 421 deletions(-) delete mode 100644 freevideo_engine/lan_auth.py delete mode 100644 freevideo_engine/lan_password.py diff --git a/freevideo_engine/access_proxy.py b/freevideo_engine/access_proxy.py index 84f5fe8f..c382951a 100644 --- a/freevideo_engine/access_proxy.py +++ b/freevideo_engine/access_proxy.py @@ -1,4 +1,4 @@ -"""Authenticated access to a ComfyUI that listens on this computer only. +"""Token-protected access to a ComfyUI that listens on this computer only. The launcher's LAN switch or `freevideo server --listen ADDRESS` runs this in front of ComfyUI. The access link carries the token once; the page then keeps it in a cookie, and API @@ -9,69 +9,17 @@ import argparse import asyncio import hmac -import hashlib -import html -import math -import time -import ipaddress import os from pathlib import Path import ssl -from urllib.parse import urlencode, urlsplit +from urllib.parse import urlencode from aiohttp import ClientSession, ClientTimeout, DummyCookieJar, TCPConnector, WSMsgType, client_exceptions, web from yarl import URL -from . import proxy_identity, lan_password -from .lan_auth import PasswordAuth, DEVICE_COOKIE, REMEMBER_SECONDS, LOGIN_DELAY +from . import proxy_identity COOKIE = 'freevideo_access' DAYS = 30 -LOGIN_PATH = '/m/login' -# Temporary English copy; keep all password-page text here for Iris. -PASSWORD_COPY = dict(title='FreeVideo', password='Password', remember='Keep me signed in', - submit='Sign in', incorrect='Incorrect password', retry='Try again later ({minutes} minutes).', - phone='FreeVideo mobile', pending='Mobile pages are coming soon.') - - -def password_page(*, error='', retry_after=0, status=401): - copy = PASSWORD_COPY - message = copy['retry'].format(minutes=math.ceil(retry_after / 60)) if retry_after else error - response = web.Response(status=status, content_type='text/html', text=( - '{title}' - '

{title}

{message}

' - '' - '' - '
').format( - **{k: html.escape(v) for k, v in copy.items()}, message=html.escape(message), retry_after=retry_after, action=LOGIN_PATH)) - response.headers['Cache-Control'] = 'no-store' - response.headers['Referrer-Policy'] = 'no-referrer' - response.headers['Content-Security-Policy'] = "default-src 'none'; form-action 'self'; frame-ancestors 'none'" - if retry_after: - response.headers['Retry-After'] = str(retry_after) - response.headers['X-FreeVideo-Retry-After'] = str(retry_after) - return response - - -def same_origin(request): - try: - if len(request.headers.getall('Host', [])) != 1 or len(request.headers.getall('Origin', [])) != 1: - return False - host = urlsplit(request.scheme + '://' + request.host) - origin = urlsplit(request.headers['Origin']) - socket = request.transport.get_extra_info('sockname') - allowed = {socket[0].split('%')[0]} - if ipaddress.ip_address(socket[0].split('%')[0]).is_loopback: - allowed.update(('localhost', '127.0.0.1', '::1')) - own_port = host.port or (443 if request.scheme == 'https' else 80) - return (host.hostname in allowed and own_port == socket[1] and origin.hostname == host.hostname - and (origin.port or (443 if origin.scheme == 'https' else 80)) == own_port - and origin.scheme == request.scheme and not any((origin.path, origin.query, origin.fragment, - origin.username, origin.password))) - except (ValueError, TypeError, IndexError, KeyError): - return False - - # Hop-by-hop headers belong to one connection; Content-Length follows the body actually sent. HOP_BY_HOP = frozenset(('connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'proxy-connection', 'te', 'trailer', 'transfer-encoding', 'upgrade', 'content-length')) @@ -108,88 +56,26 @@ def forwarded(request): headers = [] for name, value in request.headers.items(): lower = name.lower() - if lower in HOP_BY_HOP or lower == 'authorization' or lower.startswith('x-freevideo-proxy-'): + if lower in HOP_BY_HOP or lower in ('authorization', proxy_identity.HEADER.lower(), + proxy_identity.PEER.lower(), proxy_identity.ORIGIN.lower()): continue if lower == 'cookie': value = '; '.join(part for part in value.split(';') if part.strip() and - part.split('=', 1)[0].strip() not in (COOKIE, DEVICE_COOKIE)) + part.split('=', 1)[0].strip() != COOKIE) if not value: continue headers.append((name, value)) return headers -def create(upstream, token, engine=None): +def create(upstream, token): upstream = upstream.rstrip('/') sockets = 'ws' + upstream[len('http'):] client = [] hop_secret = os.environ.pop(proxy_identity.ENV, '') - auth = PasswordAuth(engine) - login_lock = asyncio.Lock() - - def browser_headers(response, request): - device = request.get('lan_device') - if device and request.path in ('/m/', '/m/csrf'): - response.headers['X-FreeVideo-CSRF'] = proxy_identity.csrf(hop_secret, device) - session = request.get('lan_session') - if session and session['remember']: - response.set_cookie(DEVICE_COOKIE, request.cookies[DEVICE_COOKIE], max_age=REMEMBER_SECONDS, - httponly=True, samesite='Lax', secure=request.secure, path='/') - return response - - async def login(request): - if not same_origin(request): - return web.Response(status=403) - # The rest of the proxy streams unlimited uploads. Only login is bounded. - body = bytearray() - async for chunk in request.content.iter_chunked(4096): - body.extend(chunk) - if len(body) > 16384: - return web.Response(status=413) - from urllib.parse import parse_qs - try: - if request.content_type != 'application/x-www-form-urlencoded': - return web.Response(status=415) - fields = parse_qs(body.decode('utf-8'), keep_blank_values=True, max_num_fields=8) - texts = fields.get('password', ['']) - text = texts[0] if len(texts) == 1 else '' - remember = fields.get('remember') == ['1'] - except (ValueError, UnicodeError): - return web.Response(status=400) - ip = request.remote or '' # Never trust X-Forwarded-For for attempt limits. - async with login_lock: - started = time.monotonic() - auth.reload() - record = auth.record - correct = await asyncio.to_thread(lan_password.verify_record, record, text) - await asyncio.sleep(max(0, LOGIN_DELAY - (time.monotonic() - started))) - auth.reload() - if not auth.enabled or auth.record != record: - return password_page(error=PASSWORD_COPY['incorrect']) - now = time.monotonic() - remaining = auth.attempts.remaining(ip, now) - if remaining: - auth.log(ip, 'locked') - return password_page(retry_after=remaining, status=429) - if not correct: - remaining = auth.attempts.failed(ip, now) - if remaining: - auth.log(ip, 'locked') - return password_page(error=PASSWORD_COPY['incorrect'], retry_after=remaining, - status=429 if remaining else 401) - value = auth.issue(remember, time.time()) - auth.attempts.success(ip) - auth.log(ip, 'success') - response = web.Response(status=303, headers={'Location': '/m/', 'Cache-Control': 'no-store'}) - response.set_cookie(DEVICE_COOKIE, value, max_age=REMEMBER_SECONDS if remember else None, - httponly=True, samesite='Lax', secure=request.secure, path='/') - return response def forwarding_headers(request): - headers = forwarded(request) + proxy_identity.headers(request, hop_secret) - if request.get('lan_device'): - headers.append((proxy_identity.DEVICE, request['lan_device'])) - return headers + return forwarded(request) + proxy_identity.headers(request, hop_secret) async def startup(app): # No total timeout: downloads and the progress socket last as long as they need. @@ -210,7 +96,6 @@ async def forward(request): response.headers.add(name, value) if reply.content_length is not None and request.method != 'HEAD': response.content_length = reply.content_length - browser_headers(response, request) await response.prepare(request) async for chunk in reply.content.iter_chunked(1 << 16): await response.write(chunk) @@ -220,7 +105,7 @@ async def forward(request): return web.json_response(dict(error='ComfyUI is not answering yet.'), status=502) async def websocket(request): - browser = browser_headers(web.WebSocketResponse(max_msg_size=0), request) + browser = web.WebSocketResponse(max_msg_size=0) await browser.prepare(request) headers = [(k, v) for k, v in forwarding_headers(request) if k.lower() not in ( 'sec-websocket-key', 'sec-websocket-version', 'sec-websocket-extensions', 'sec-websocket-protocol')] @@ -246,49 +131,18 @@ async def pump(source, target): return browser async def handle(request): - auth.reload() - if auth.enabled: - if request.path == LOGIN_PATH and request.method == 'POST': - return await login(request) - session = auth.authenticate(request.cookies.get(DEVICE_COOKIE), time.time()) - if session: - request['lan_device'] = session['hash'] - request['lan_session'] = session - else: - header = request.headers.get('Authorization', '') - if not (header[:7].lower() == 'bearer ' and matches(header[7:].strip(), token)): - remaining = auth.attempts.remaining(request.remote or '', time.monotonic()) - return password_page(retry_after=remaining, status=429 if remaining else 401) - else: - offered = request.rel_url.query.get('token') - if offered is not None: - if not matches(offered, token): - return denied(request) - # Preserve the existing one-time link exchange and cookie behavior. - rest = [(k, v) for k, v in request.rel_url.query.items() if k != 'token'] - response = web.Response(status=303, headers={'Location': request.rel_url.path + ('?' + urlencode(rest) if rest else '')}) - response.set_cookie(COOKIE, token, max_age=DAYS * 86400, httponly=True, samesite='Lax', - secure=request.secure, path='/') - return response - if not matches(supplied(request), token): + offered = request.rel_url.query.get('token') + if offered is not None: + if not matches(offered, token): return denied(request) - if matches(request.cookies.get(COOKIE), token): - request['lan_device'] = hashlib.sha256(token.encode()).hexdigest() - # A query token in password mode neither authenticates nor reaches ComfyUI. - if auth.enabled and 'token' in request.query: + # The access link: keep the token in a cookie and show the address without it. rest = [(k, v) for k, v in request.rel_url.query.items() if k != 'token'] - location = request.path + ('?' + urlencode(rest) if rest else '') - return browser_headers(web.Response(status=303, headers={'Location': location}), request) - if request.path in ('/m/', '/m/csrf') and request.method in ('GET', 'HEAD'): - if not request.get('lan_device'): - return web.Response(status=403) - if request.path == '/m/csrf': - response = web.json_response(dict(csrf=proxy_identity.csrf(hop_secret, request['lan_device']))) - else: - response = web.Response(text='%s

%s

%s

' % ( - PASSWORD_COPY['title'], PASSWORD_COPY['phone'], PASSWORD_COPY['pending']), content_type='text/html') - response.headers['Cache-Control'] = 'no-store' - return browser_headers(response, request) + response = web.Response(status=303, headers={'Location': request.rel_url.path + ('?' + urlencode(rest) if rest else '')}) + response.set_cookie(COOKIE, token, max_age=DAYS * 86400, httponly=True, samesite='Lax', + secure=request.secure, path='/') + return response + if not matches(supplied(request), token): + return denied(request) if request.headers.get('Upgrade', '').lower() == 'websocket': return await websocket(request) return await forward(request) @@ -318,7 +172,7 @@ def main(argv=None): if args.tls_cert: context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(args.tls_cert, args.tls_key) - web.run_app(create(args.upstream, token, args.token_file.parent.parent), host=args.listen, port=args.port, ssl_context=context, + web.run_app(create(args.upstream, token), host=args.listen, port=args.port, ssl_context=context, access_log=None, print=None) diff --git a/freevideo_engine/agent/access.py b/freevideo_engine/agent/access.py index e7ed6807..553ad56b 100644 --- a/freevideo_engine/agent/access.py +++ b/freevideo_engine/agent/access.py @@ -27,13 +27,12 @@ def lan_enabled(): return False -def check(request, *, local=False, lan=False): +def check(request, *, local=False): address = peer_address(request) proxied = proxy_identity.HEADER in request.headers - # Only explicitly listed browser routes may use a verified proxy device. - local_only = local and not (proxied and lan and bool(proxy_identity.device(request))) - if (proxied and (not proxy_identity.trusted(request) or local_only or not lan_enabled()) - or address is None or not address.is_loopback and (local_only or not address.is_private or not lan_enabled())): + # Even a proxy client on loopback is never a local control-plane client. + if (proxied and (not proxy_identity.trusted(request) or local or not lan_enabled()) + or address is None or not address.is_loopback and (local or not address.is_private or not lan_enabled())): raise JobError('local_only', 'Peer is not permitted') socket = request.transport.get_extra_info('sockname') if request.transport else None try: diff --git a/freevideo_engine/agent/routes.py b/freevideo_engine/agent/routes.py index 5d62fbee..e0fa1135 100644 --- a/freevideo_engine/agent/routes.py +++ b/freevideo_engine/agent/routes.py @@ -457,16 +457,12 @@ async def respond(request): definition = contracts.get((method, suffix)) if definition is None: raise JobError('method_not_allowed' if any(p == suffix for _, p in contracts) else 'not_found', 'No contract') - access.check(request, local=definition.get('local', False), lan=definition.get('lan', False)) + access.check(request, local=definition.get('local', False)) if definition.get('auth') is False and definition.get('local') and method not in ('GET', 'HEAD'): session = page_sessions.get(request.cookies.get('freevideo_agent_page', '')) csrf = request.headers.get('X-FreeVideo-CSRF', '') - if proxy_identity.HEADER in request.headers: - valid = definition.get('lan') and proxy_identity.check_csrf(request) - else: - valid = (session is not None and session[1] >= time.monotonic() and csrf - and secrets.compare_digest(csrf.encode(), session[0].encode())) - if not valid: + if (session is None or session[1] < time.monotonic() or not csrf + or not secrets.compare_digest(csrf.encode(), session[0].encode())): raise JobError('page_session_required', 'Page session required') header = request.headers.get('Authorization', '') given = header[7:].strip() if header[:7].lower() == 'bearer ' else request.headers.get('X-FreeVideo-Agent', '') diff --git a/freevideo_engine/agent/schema.py b/freevideo_engine/agent/schema.py index 11fd2b10..dfca3b7c 100644 --- a/freevideo_engine/agent/schema.py +++ b/freevideo_engine/agent/schema.py @@ -424,15 +424,7 @@ def route(summary, body=None, query=None, **kw): ('/chat', 'POST', obj({'text': string(8000), 'id': CHAT_ID, 'session': SESSION, 'whitebox': {'type': 'boolean'}}, ('text', 'id'))), ('/chat/confirm', 'POST', obj({'id': string(12, pattern=r'^cf[0-9a-f]{10}$'), 'approve': {'type': 'boolean'}, 'session': SESSION}, ('id', 'approve')))): - routes[(method, '/freevideo/agent' + suffix)] = route('Studio Agent controls', body=body, auth=False, local=True, - lan=suffix in ('/chat', '/chat/now', '/chat/confirm', '/chat/list', '/chat/new', '/chat/video', - '/activity', '/activity/cancel')) - # These existing ComfyUI handlers are registered outside the Agent dispatcher. - # /chain is a creation POST; monitoring reads /chains and /chain/{id}. - for suffix in ('/freevideo/progress', '/freevideo/chains', '/freevideo/chain/{id}'): - routes['GET', suffix] = route('Read generation monitoring', auth=False, lan=True, external=True, - query=obj({'client_id': string()}) if suffix != '/freevideo/progress' else EMPTY, - **({'path': obj({'id': string()}, ('id',))} if '{id}' in suffix else {})) + routes[(method, '/freevideo/agent' + suffix)] = route('Studio Agent controls', body=body, auth=False, local=True) routes['GET', '/freevideo/agent/chat']['query'] = obj({'after': number(0, integer=True), 'session': SESSION}) routes['GET', '/freevideo/agent/chat/video']['query'] = obj({'id': string(43, pattern=r'^[0-9]{4}-[0-9]{2}-[0-9]{2}/[0-9a-f]{32}$')}, ('id',)) for method, suffix, summary, extra in ( diff --git a/freevideo_engine/comfy_launcher_runtime.py b/freevideo_engine/comfy_launcher_runtime.py index 271d9e65..b33af27c 100644 --- a/freevideo_engine/comfy_launcher_runtime.py +++ b/freevideo_engine/comfy_launcher_runtime.py @@ -32,7 +32,7 @@ from .desktop_runtime import materialize_source, source_release from .monitoring import save from .long_paths import io_path, resolved, plain, plain_text, plain_error, plain_errors -from . import engine_binding, processes, lan_password +from . import engine_binding, processes PROTOCOL = 1 TEMPLATE = 'FreeVideo-All-in-One.json' @@ -747,10 +747,9 @@ def refresh_access_links(self): from .proxy import local_addresses self.access_polled = time.monotonic() secret = token(self.selection['engine']) - password_set = lan_password.is_set(self.selection['engine']) - suffix = '/m/' if password_set else '/m/?freevideo=launch&token=' + secret - self.access_links = [address(host, self.selection['lan_port']) + suffix for host in local_addresses()] - self.state = dict(self.state, lan_status='' if self.access_links else 'no-address', lan_password_set=password_set) + self.access_links = [address(host, self.selection['lan_port']) + '/?freevideo=launch&token=' + secret + for host in local_addresses()] + self.state = dict(self.state, lan_status='' if self.access_links else 'no-address') def check_access_proxy(self): """Poll child lifetimes and refresh network links without moving ComfyUI.""" diff --git a/freevideo_engine/diagnostics.py b/freevideo_engine/diagnostics.py index 01b329f0..5c732154 100644 --- a/freevideo_engine/diagnostics.py +++ b/freevideo_engine/diagnostics.py @@ -30,7 +30,6 @@ 'prompt-rewrite.json', 'plan.json', 'machine.before.json', 'comparison.json', 'profile.json', 'result.json', 'gpu.csv', 'ram.jsonl', 'network.jsonl', 'optimization.json', 'storage.json', 'kernel-capabilities.json'} -SENSITIVE_FILES = frozenset(('lan-password.json', 'lan-devices.json')) SENSITIVE = re.compile(r'(?:^|[_-])(?:token|password|secret|credential|api[_-]?key)(?:$|[_-])', re.I) # Path-bearing fields are retained only as installation-relative names (when a # known report root is available) or as a basename under ````. Reports @@ -284,9 +283,6 @@ def add(name, raw, truncated=False): manifest['payload_bytes'] += len(data) def add_path(name, path): - if Path(path).name.lower() in SENSITIVE_FILES: - manifest['omitted'].append({'file': name, 'reason': 'Private LAN authentication record'}) - return try: data, truncated = read_complete(path) if complete else read_bounded(path) add(name, data, truncated) diff --git a/freevideo_engine/lan_auth.py b/freevideo_engine/lan_auth.py deleted file mode 100644 index a8543b9c..00000000 --- a/freevideo_engine/lan_auth.py +++ /dev/null @@ -1,116 +0,0 @@ -"""Proxy-owned device sessions and in-memory password attempt limits.""" -from collections import deque -from datetime import datetime, timezone -import hashlib -import json -import math -import secrets - -from . import lan_password - -DEVICE_COOKIE = 'freevideo_device' -REMEMBER_SECONDS = 30 * 86400 -SESSION_SECONDS = 12 * 3600 -LOGIN_DELAY = .25 -TOUCH_SECONDS = 60 -MAX_SOURCES = 1024 - - -class Attempts: - def __init__(self): - self.sources = {} - self.failures = deque() - self.global_until = 0 - - def remaining(self, ip, now): - return max(0, math.ceil(max(self.global_until, self.sources.get(ip, (0, 0))[1]) - now)) - - def failed(self, ip, now): - count = self.sources.get(ip, (0, 0))[0] + 1 - until = now + min(900, 60 * 2 ** min(count - 5, 4)) if count >= 5 else 0 - self.sources[ip] = count, until - if len(self.sources) > MAX_SOURCES: - for key in [key for key, (_, wait) in self.sources.items() if wait <= now and key != ip]: - del self.sources[key] - while len(self.sources) > MAX_SOURCES: - del self.sources[next(iter(self.sources))] - while self.failures and self.failures[0] <= now - 600: - self.failures.popleft() - self.failures.append(now) - if len(self.failures) >= 30: - self.global_until = now + 300 - return self.remaining(ip, now) - - def success(self, ip): - self.sources.pop(ip, None) - - -class PasswordAuth: - def __init__(self, engine): - self.engine = engine - self.signature = None - self.enabled = False - self.record = None - self.attempts = Attempts() - - def reload(self): - if self.engine is None: - return - try: - info = lan_password.path(self.engine).stat() - signature = info.st_mtime_ns, info.st_ino, info.st_size - except FileNotFoundError: - signature = None - except OSError: - signature = 'unreadable' - self.enabled = signature is not None - if signature != self.signature: - self.record = lan_password.read(self.engine) if self.enabled else None - self.signature = signature - - def generation(self): - return hashlib.sha256(b''.join(self.record)).hexdigest() if self.record else '' - - def devices(self, now): - try: - target = lan_password.path(self.engine).with_name(lan_password.DEVICES_FILE) - value = json.loads(target.read_text(encoding='utf-8')) - if not isinstance(value, dict) or value.get('password') != self.generation() or not self.record: - return [] - return [row for row in value['devices'] if isinstance(row, dict) and isinstance(row['hash'], str) and - len(row['hash']) == 64 and all(c in '0123456789abcdef' for c in row['hash']) and - all(type(row[key]) in (int, float) and math.isfinite(row[key]) for key in ('created', 'last_used')) and - type(row['remember']) is bool and - now < (row['last_used'] + REMEMBER_SECONDS if row['remember'] else row['created'] + SESSION_SECONDS)] - except (OSError, ValueError, KeyError, TypeError): - return [] - - def save(self, rows): - lan_password.save_private(lan_password.path(self.engine).with_name(lan_password.DEVICES_FILE), - dict(version=1, password=self.generation(), devices=rows)) - - def issue(self, remember, now): - value = secrets.token_urlsafe(32) - digest = hashlib.sha256(value.encode()).hexdigest() - rows = self.devices(now) - rows.append(dict(hash=digest, created=now, last_used=now, remember=remember)) - self.save(rows) - return value - - def authenticate(self, value, now): - if not value or len(value) != 43 or not self.record: - return None - digest = hashlib.sha256(value.encode()).hexdigest() - rows = self.devices(now) - for row in rows: - if secrets.compare_digest(row['hash'], digest): - if now - row['last_used'] >= TOUCH_SECONDS: - row['last_used'] = now - self.save(rows) - return row - return None - - def log(self, ip, result): - target = lan_password.path(self.engine).with_name('access-proxy.log') - with target.open('a', encoding='utf-8') as stream: - stream.write('%s %s %s\n' % (datetime.now(timezone.utc).isoformat(), ip, result)) diff --git a/freevideo_engine/lan_password.py b/freevideo_engine/lan_password.py deleted file mode 100644 index a5c16296..00000000 --- a/freevideo_engine/lan_password.py +++ /dev/null @@ -1,91 +0,0 @@ -"""Optional LAN password and private, atomic authentication records. - -The engine root is the same root used by launcher_settings.Store. Passwords -never enter launcher preferences; only the fixed scrypt record is persisted. -""" -import hashlib -import hmac -import json -import os -from pathlib import Path -import secrets - -from .agent import private_file -from .long_paths import io_path - -MIN_LENGTH = 6 -N, R, P = 2 ** 15, 8, 1 -PASSWORD_FILE = 'lan-password.json' -DEVICES_FILE = 'lan-devices.json' - - -def path(engine): - return Path(engine) / 'launcher' / PASSWORD_FILE - - -def is_set(engine): - # An unreadable or invalid record must never silently disable protection. - return io_path(path(engine)).exists() - - -def save_private(target, value): - target = Path(target) - target.parent.mkdir(mode=0o700, parents=True, exist_ok=True) - temporary = target.with_name('.' + target.name + '-' + secrets.token_hex(8)) - descriptor = private_file.create(temporary) - try: - with os.fdopen(descriptor, 'w', encoding='utf-8') as stream: - json.dump(value, stream, separators=(',', ':')) - stream.write('\n') - stream.flush() - os.fsync(stream.fileno()) - os.replace(temporary, target) - finally: - temporary.unlink(missing_ok=True) - - -def clear_devices(engine): - save_private(path(engine).with_name(DEVICES_FILE), dict(version=1, devices=[])) - - -def derive(text, salt): - # OpenSSL's default 32 MiB cap is slightly below this parameter set's needs. - return hashlib.scrypt(text.encode('utf-8'), salt=salt, n=N, r=R, p=P, dklen=32, maxmem=64 * 1024 ** 2) - - -def read(engine): - try: - with path(engine).open(encoding='utf-8') as stream: - value = json.loads(stream.read(4096)) - if (value['version'], value['n'], value['r'], value['p']) != (1, N, R, P): - return None - salt, digest = bytes.fromhex(value['salt']), bytes.fromhex(value['hash']) - return (salt, digest) if len(salt) == 16 and len(digest) == 32 else None - except (OSError, ValueError, KeyError, TypeError): - return None - - -def verify_record(record, text): - salt, expected = record if record is not None else (bytes(16), bytes(32)) - actual = derive(text, salt) - return hmac.compare_digest(actual, expected) and record is not None - - -def verify(engine, text): - return verify_record(read(engine), text) - - -def set_password(engine, text): - if not isinstance(text, str) or len(text) < MIN_LENGTH: - raise ValueError('LAN password is too short') - salt = secrets.token_bytes(16) - digest = derive(text, salt) - # Device records also carry this password generation, so concurrent logins - # using the old record cannot revive devices during an atomic replacement. - clear_devices(engine) - save_private(path(engine), dict(version=1, salt=salt.hex(), n=N, r=R, p=P, hash=digest.hex())) - - -def remove(engine): - clear_devices(engine) - path(engine).unlink(missing_ok=True) diff --git a/freevideo_engine/launcher_session.py b/freevideo_engine/launcher_session.py index fc0b336b..3856bf52 100644 --- a/freevideo_engine/launcher_session.py +++ b/freevideo_engine/launcher_session.py @@ -11,7 +11,7 @@ from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit from . import __version__ -from . import disk_space, lan_password +from . import disk_space from .comfy_launcher_runtime import Controller, layout, local_url, loopback_url, managed_frontend, new_layout, queue_busy from .desktop_runtime import launcher_root, materialize_source from .download_settings import Probe, read as download_preferences, speed_text diff --git a/freevideo_engine/proxy_identity.py b/freevideo_engine/proxy_identity.py index 03e3a048..a6eb9f13 100644 --- a/freevideo_engine/proxy_identity.py +++ b/freevideo_engine/proxy_identity.py @@ -11,7 +11,6 @@ HEADER = 'X-FreeVideo-Proxy-Hop' PEER = 'X-FreeVideo-Proxy-Peer' ORIGIN = 'X-FreeVideo-Proxy-Origin' -DEVICE = 'X-FreeVideo-Proxy-Device' @lru_cache(maxsize=1) @@ -33,19 +32,3 @@ def trusted(request): secret = app.get(app_key(), '') if app is not None else '' offered = request.headers.get(HEADER, '') return bool(secret and offered) and hmac.compare_digest(secret.encode(), offered.encode()) - - -def csrf(secret, device): - """A browser proof bound to one authenticated device and this proxy hop.""" - return hmac.new(secret.encode(), ('lan-csrf:' + device).encode(), 'sha256').hexdigest() - - -def device(request): - return request.headers.get(DEVICE, '') if trusted(request) else '' - - -def check_csrf(request): - identity = device(request) - offered = request.headers.get('X-FreeVideo-CSRF', '') - secret = request.app.get(app_key(), '') - return bool(identity and offered) and hmac.compare_digest(offered.encode(), csrf(secret, identity).encode()) From 1a814ba3600a3dd4ca892efaaa9d520b400f8bfe Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:41 +0000 Subject: [PATCH 07/21] Quality levels: Max uses 20 steps with a guarded step cache, High 16 steps with the step cache --- freevideo_engine/agent/guide.py | 4 +-- freevideo_engine/agent/schema.py | 2 +- freevideo_engine/agent/spec.py | 4 +-- freevideo_engine/comfy_bridge.py | 2 +- freevideo_engine/failure_details.py | 2 +- freevideo_engine/step_cache.py | 1 + freevideo_engine/tiers.py | 29 +++++++++++-------- web/capability_view.js | 12 ++++---- web/chain_support.js | 10 +++---- web/sampling_effort.js | 44 +++++++++++++++++++---------- web/studio.js | 4 +-- 11 files changed, 65 insertions(+), 49 deletions(-) diff --git a/freevideo_engine/agent/guide.py b/freevideo_engine/agent/guide.py index 56a6ccfd..778d367f 100644 --- a/freevideo_engine/agent/guide.py +++ b/freevideo_engine/agent/guide.py @@ -74,8 +74,8 @@ ], 'quality': [ 'Steps per quality: "light" = 8 first-pass steps + 3 refine steps, two-pass, the first pass at half size ' - '(default); "medium" = the same 8 + 3 two-pass with a larger first pass, for more detail; "high" = 20 steps ' - 'with a step cache and "max" = 20 plain steps, each in one pass. The same on a Mac. sampling.two_pass=false ' + '(default); "medium" = the same 8 + 3 two-pass with a larger first pass, for more detail; "high" = 16 steps ' + 'with a step cache and "max" = 20 steps with a step cache, each in one pass. The same on a Mac. sampling.two_pass=false ' 'without base_steps runs 20 steps.', 'Two-pass generation runs only with 8 first-pass steps. Any other base_steps (for example 20 with ' 'two_pass=true) runs in one pass of that many steps; the job notice says so. A preview is always two-pass ' diff --git a/freevideo_engine/agent/schema.py b/freevideo_engine/agent/schema.py index dfca3b7c..f0ac1cdb 100644 --- a/freevideo_engine/agent/schema.py +++ b/freevideo_engine/agent/schema.py @@ -14,7 +14,7 @@ S = 'https://json-schema.org/draft/2020-12/schema' PREFIX = '/freevideo/agent/v1' # (two_pass, base_steps, refine_steps) of each level on this platform; the step -# cache a level adds is tiers.step_cache(name, mac) (only high has one, easycache-av), +# cache a level adds is tiers.step_cache(name, mac) (high and max use easycache-av), # its two-pass upscale factor tiers.upscale_factor(name, mac) (medium samples a larger first pass). QUALITY = {name: tiers.plan(name, mac=tiers.on_mac()) for name in tiers.TIERS} ASPECTS = {'16:9': (16, 9), '9:16': (9, 16), '1:1': (1, 1), '4:3': (4, 3), '3:4': (3, 4), diff --git a/freevideo_engine/agent/spec.py b/freevideo_engine/agent/spec.py index c3fdeb48..f2e508a7 100644 --- a/freevideo_engine/agent/spec.py +++ b/freevideo_engine/agent/spec.py @@ -147,9 +147,7 @@ def sampling(value): cache = tiers.step_cache(quality, mac) if own else None factor = tiers.upscale_factor(quality, mac) if own and two else 2 if custom: - quality = next((k for k, v in QUALITY.items() if v == (two, base, refine) - and tiers.step_cache(k, mac) == cache - and (not two or tiers.upscale_factor(k, mac) == factor)), 'custom') + quality = tiers.name_for(base, two, refine, cache, mac, factor) or 'custom' return dict(quality=quality, two_pass=two, base_steps=base, refine_steps=refine, **({'step_cache': cache} if cache else {}), **({'upscale_factor': factor} if factor != 2 else {}), **({'sampling_note': note} if note else {})) diff --git a/freevideo_engine/comfy_bridge.py b/freevideo_engine/comfy_bridge.py index d112fb37..96010987 100644 --- a/freevideo_engine/comfy_bridge.py +++ b/freevideo_engine/comfy_bridge.py @@ -1486,7 +1486,7 @@ def asset_progress(message): # Reference audio selects its own tables; match the encoder's choice. asset_task = ((ANCHOR_ADALN_TASK if anchored or pictured else ADALN_TASK) if continue_from is not None else engine_task(extra.get('media', {}), media_base)) - # The cache only names the level of a missing table (high or max at 20 steps). + # Tables follow the step count; the cache is carried for exact level recognition. preparation = prepare_sampling_assets(root, machine, dict(planned, step_cache=step_cache) if step_cache else planned, asset_task, progress=asset_progress, interrupted=interrupted, environ=environment) diff --git a/freevideo_engine/failure_details.py b/freevideo_engine/failure_details.py index adf51af2..3b770a74 100644 --- a/freevideo_engine/failure_details.py +++ b/freevideo_engine/failure_details.py @@ -88,7 +88,7 @@ def sampling_table_failure(value, *, zh=False): return None from .launcher_copy import size_text language = 1 if zh else 0 - # Tables follow the step count; the cache tells high from max at 20 steps. + # Tables follow the step count: 16 steps is high, 20 steps is max. level = table_level(details['base_steps'], details['two_pass'], details['refine_steps'], details.get('step_cache'), on_mac(), details.get('scale', 2)) index = list(TIERS).index(level) if level else None diff --git a/freevideo_engine/step_cache.py b/freevideo_engine/step_cache.py index e081419d..c54f734c 100644 --- a/freevideo_engine/step_cache.py +++ b/freevideo_engine/step_cache.py @@ -111,6 +111,7 @@ def begin(self, video_indices, audio_indices): def stats(self): full = self.steps - len(self.hits) return dict(kind=self.kind, threshold=self.threshold, steps=self.steps, cached_steps=list(self.hits), + cached_share=round(len(self.hits) / self.steps, 3) if self.steps else 0., full_forwards=full, decisions=self.decisions, source=self.source, disabled_reason=self.disabled_reason, guard=GUARD) diff --git a/freevideo_engine/tiers.py b/freevideo_engine/tiers.py index 8e58e08b..a5c08fda 100644 --- a/freevideo_engine/tiers.py +++ b/freevideo_engine/tiers.py @@ -6,12 +6,11 @@ - light: two-pass, 8 + 3 steps, first pass at half size (2x learned upscale). - medium: two-pass, 8 + 3 steps, a larger first pass (`upscale`, below 2). -- high: one pass of 20 steps with the audio-video EasyCache. -- max: one pass of 20 steps, every step sampled. +- high: one pass of 16 steps with the guarded audio-video EasyCache. +- max: one pass of 20 steps with the same guarded cache. -A level in one pass always samples 20 steps; fewer steps come only from a -user's own setting. Only a two-pass level samples a second time. Single-pass -levels carry REFINE_STEPS only as the neutral value the `refine_steps` field +Each level uses the step count in the table below. Only a two-pass level +samples a second time. Single-pass levels carry REFINE_STEPS only as the neutral value the `refine_steps` field needs; it is never run for them, and their `upscale` is 2 (no factor). `step_cache` is the engine's cache key: None, 'easycache-av' (audio-video EasyCache) or 'fbcache' (first-block cache, no level uses it; a request may @@ -20,7 +19,8 @@ Mac (MPS) runs the same levels (TIERS_MAC). Results made before the audio-video EasyCache was ported there, one pass of 16 steps without a cache, -still count as high (LEGACY_MAC_HIGH). +still count as high (LEGACY_MAC_HIGH). Earlier one-pass 20-step results +without a cache still count as max on every platform (LEGACY_MAX). """ import sys @@ -30,10 +30,11 @@ TIERS = { 'light': dict(steps=8, two_pass=True, step_cache=None, upscale=2), 'medium': dict(steps=8, two_pass=True, step_cache=None, upscale=1.5), - 'high': dict(steps=20, two_pass=False, step_cache='easycache-av', upscale=2), - 'max': dict(steps=20, two_pass=False, step_cache=None, upscale=2), + 'high': dict(steps=16, two_pass=False, step_cache='easycache-av', upscale=2), + 'max': dict(steps=20, two_pass=False, step_cache='easycache-av', upscale=2), } TIERS_MAC = TIERS +LEGACY_MAX = dict(steps=20, two_pass=False, step_cache=None, upscale=2) LEGACY_MAC_HIGH = dict(steps=16, two_pass=False, step_cache=None, upscale=2) # Sampling time of a cached pass as a share of the same pass without a cache, @@ -50,6 +51,8 @@ # is plain 20 steps. # EasyCache-AV, guarded (at most 40% of steps reused, never twice in a row): measured on the RTX PRO 6000, # 864x1184, 5 s, 20 steps, 2 reused steps: 212 s against 238 s for the plain 20 steps (about .88 of the sampling). +# At 16 steps the guarded cache reused 1–4 steps (about 14% on average), +# so the same conservative .88 share also applies at 16 steps. SAMPLING_SHARE = {None: 1., 'easycache-av': .88, 'fbcache': .9} # Sampling time (both passes) of a two-pass request with this upscale factor, @@ -94,6 +97,8 @@ def name_for(steps, two_pass, refine_steps=REFINE_STEPS, step_cache=None, mac=Fa if tier['steps'] == steps and tier['two_pass'] == two_pass and (not two_pass or refine_steps == REFINE_STEPS) and tier['step_cache'] == step_cache and tier['upscale'] == upscale), None) + if found is None and (steps, two_pass, step_cache, upscale) == tuple(LEGACY_MAX.values()): + return 'max' if found is None and mac and (steps, two_pass, step_cache, upscale) == tuple(LEGACY_MAC_HIGH.values()): return 'high' return found @@ -102,10 +107,10 @@ def name_for(steps, two_pass, refine_steps=REFINE_STEPS, step_cache=None, mac=Fa def table_level(steps, two_pass, refine_steps=REFINE_STEPS, step_cache=None, mac=False, upscale=2): """The level whose sampling table a plan needs, for naming a missing download. - Tables follow the step count only. Prefer the exact level (the cache tells - high from max at 20 steps), then the other platform's table (16 steps is - the earlier Mac "high"), then the first level with that step count (light - for 8 + 3, whatever the upscale factor). + Tables follow the step count only: 16 steps names high, 20 names max. + Prefer the exact level or a legacy alias, then the other platform's table, + then the first level with that step count (light for 8 + 3, whatever the + upscale factor). """ found = name_for(steps, two_pass, refine_steps, step_cache, mac, upscale) or name_for( steps, two_pass, refine_steps, step_cache, not mac, upscale) diff --git a/web/capability_view.js b/web/capability_view.js index 524ce7e4..78139bb1 100644 --- a/web/capability_view.js +++ b/web/capability_view.js @@ -1,5 +1,5 @@ import { referenceItems } from './prompt_references.js'; -import { stepCacheOf, upscaleOf } from './sampling_effort.js'; +import { effortFor, effortsFrom, stepCacheOf, upscaleOf } from './sampling_effort.js'; const PRESETS = [.5, .75, .98, 1.5, 2]; const COLUMN_SPACING = 'equal'; // 'equal' or 'width' @@ -77,11 +77,11 @@ export function capabilityContext(node, state) { return query.toString(); } -// The grid's level with exactly this plan; a step cache tells High from Max at 20 steps, the -// upscale factor Light from Medium (a row without one is 2x). -const gridTier = (grid, steps, twoPass, refine, stepCache, upscale = 2) => Object.values(grid.tiers || {}).find(v => v.steps === steps - && v.two_pass === twoPass && (!v.two_pass || refine === 3) && stepCacheOf(v.step_cache) === stepCacheOf(stepCache) - && (!v.two_pass || upscaleOf(v.upscale) === upscaleOf(upscale))); +// Shared recognition includes legacy Max and the Mac-only legacy High. +const gridTier = (grid, steps, twoPass, refine, stepCache, upscale = 2) => { + const level = effortFor(steps, twoPass, refine, stepCache, effortsFrom(grid), upscale); + return grid.tiers?.[level?.name.toLowerCase()]; +}; export function capabilitySurface(grid, state) { if (grid?.version !== 1 || grid.status !== 'ready' || typeof grid.revision !== 'string' || !grid.machine?.system diff --git a/web/chain_support.js b/web/chain_support.js index 218e024d..81014159 100644 --- a/web/chain_support.js +++ b/web/chain_support.js @@ -1,6 +1,6 @@ // Pure helpers the creative panel's long-video planning shares with the editor store; kept out of // editor_store.js so the panel does not load the editing implementation. -import { stepCacheOf, upscaleOf } from './sampling_effort.js'; +import { effortFor, effortsFrom } from './sampling_effort.js'; const clockDefault = {now: () => Date.now(), setTimeout: (fn, ms) => setTimeout(fn, ms), clearTimeout: id => clearTimeout(id)}; export const chainRoute = (id, action) => '/freevideo/chain' + (id ? '/' + encodeURIComponent(id) : '') + (action ? '/' + action : ''); @@ -38,11 +38,9 @@ function capabilityTier(reply, settings) { const tiers = reply.tiers; if (!tiers || typeof tiers !== 'object') return reply; if (tiers[settings?.tier]) return tiers[settings.tier]; - const steps = Number(settings?.base_steps), twoPass = !!settings?.two_pass, cache = stepCacheOf(settings?.step_cache); - const factor = twoPass ? upscaleOf(settings?.upscale_factor) : 2; - return Object.values(tiers).find(tier => tier.steps === steps && tier.two_pass === twoPass - && (!twoPass || Number(settings?.refine_steps) === 3) && stepCacheOf(tier.step_cache) === cache - && (tier.two_pass ? upscaleOf(tier.upscale) : 2) === factor) || {}; + const level = effortFor(Number(settings?.base_steps), !!settings?.two_pass, Number(settings?.refine_steps), + settings?.step_cache, effortsFrom(reply), settings?.upscale_factor); + return tiers[level?.name.toLowerCase()] || {}; } export function capabilityPoints(reply, {width, height, settings = {}}) { const tier = capabilityTier(reply, settings); diff --git a/web/sampling_effort.js b/web/sampling_effort.js index 14af2343..4cb0fabf 100644 --- a/web/sampling_effort.js +++ b/web/sampling_effort.js @@ -1,19 +1,24 @@ // One editor control. The queued request remains an immutable graph snapshot. // Each level is a complete plan (freevideo_engine/tiers.py): Light and Medium are two-pass 8 + 3, // told apart by the learned upscale factor (Medium starts from a larger first pass); High and Max -// sample 20 steps once, High with a step cache. `upscale` is 2 for every single-pass level. +// sample 16 and 20 steps once, both with the guarded step cache. `upscale` is 2 for every single-pass level. const frozen = rows => Object.freeze(rows.map(row => Object.freeze({...row}))); export const SAMPLING_EFFORTS = frozen([ {name: 'Light', zh: '轻量', steps: 8, twoPass: true, stepCache: null, upscale: 2, color: '#3dd6b5'}, {name: 'Medium', zh: '标准', steps: 8, twoPass: true, stepCache: null, upscale: 1.5, color: '#4ea8ff'}, - {name: 'High', zh: '精细', steps: 20, twoPass: false, stepCache: 'easycache-av', upscale: 2, color: '#9d7bff'}, - {name: 'Max', zh: '极致', steps: 20, twoPass: false, stepCache: null, upscale: 2, color: '#ffa94d'}, + {name: 'High', zh: '精细', steps: 16, twoPass: false, stepCache: 'easycache-av', upscale: 2, color: '#9d7bff'}, + {name: 'Max', zh: '极致', steps: 20, twoPass: false, stepCache: 'easycache-av', upscale: 2, color: '#ffa94d'}, ]); -// Mac runs the same levels. -export const SAMPLING_EFFORTS_MAC = SAMPLING_EFFORTS; +// Mac runs the same plans; retain platform identity for its legacy High alias. +const macLevels = new WeakSet(); +export const SAMPLING_EFFORTS_MAC = frozen(SAMPLING_EFFORTS); +macLevels.add(SAMPLING_EFFORTS_MAC); +// Earlier Max sampled 20 plain steps, on every platform. +export const legacyMaxEffort = (steps, twoPass, stepCache = null, levels = SAMPLING_EFFORTS) => + steps === 20 && !twoPass && stepCacheOf(stepCache) === null ? levels.find(tier => tier.name === 'Max') : undefined; // Mac results made before the cache came: High was 16 steps without one. -export const legacyMacEffort = (steps, twoPass, stepCache = null) => - steps === 16 && !twoPass && stepCacheOf(stepCache) === null ? SAMPLING_EFFORTS_MAC.find(tier => tier.name === 'High') : undefined; +export const legacyMacEffort = (steps, twoPass, stepCache = null, levels = SAMPLING_EFFORTS_MAC) => + steps === 16 && !twoPass && stepCacheOf(stepCache) === null ? levels.find(tier => tier.name === 'High') : undefined; export const effortName = (t, tier) => t(tier.name, tier.zh); export const STEP_CACHES = Object.freeze([null, 'easycache-av', 'fbcache']); @@ -34,13 +39,15 @@ export function effortsFrom(grid) { const base = grid?.machine?.system === 'Darwin' ? SAMPLING_EFFORTS_MAC : SAMPLING_EFFORTS; const tiers = grid?.tiers; if (!tiers || typeof tiers !== 'object') return base; - return frozen(base.map(tier => { + const levels = frozen(base.map(tier => { const row = tiers[tier.name.toLowerCase()]; if (!row || !Number.isInteger(row.steps) || typeof row.two_pass !== 'boolean') return tier; return {...tier, steps: row.steps, twoPass: row.two_pass, stepCache: 'step_cache' in row ? stepCacheOf(row.step_cache) : tier.stepCache, upscale: !row.two_pass ? 2 : 'upscale' in row ? upscaleOf(row.upscale) : tier.upscale}; })); + if (base === SAMPLING_EFFORTS_MAC) macLevels.add(levels); + return levels; } // The level a plan matches, or undefined for custom steps; the upscale factor tells the @@ -48,7 +55,9 @@ export function effortsFrom(grid) { export function effortFor(steps, twoPass, refine, stepCache = null, levels = SAMPLING_EFFORTS, upscale = 2) { const cache = stepCacheOf(stepCache), factor = twoPass ? upscaleOf(upscale) : 2; return levels.find(tier => tier.steps === steps && tier.twoPass === twoPass && (!twoPass || refine === 3) - && tier.stepCache === cache && tier.upscale === factor); + && tier.stepCache === cache && tier.upscale === factor) + || legacyMaxEffort(steps, twoPass, cache, levels) + || (macLevels.has(levels) ? legacyMacEffort(steps, twoPass, cache, levels) : undefined); } // The level a result's sampling_plan names. Results made with the earlier 8 + 2 default count as @@ -60,11 +69,15 @@ export function resultEffort(plan) { } // The steps and factor switching two-pass leaves. Off from an 8-step first pass samples the -// single-pass levels' 20 steps; on from a single-pass level gives Light. Typed steps stay. +// Max plan including its cache; on from a single-pass level gives Light without a cache. Typed steps stay. export function passSwitch(on, steps, refine, stepCache = null, levels = SAMPLING_EFFORTS) { - if (!on) return {steps: steps === 8 ? levels.find(tier => !tier.twoPass)?.steps ?? 20 : steps, refine, upscale: 2}; + const max = levels.find(tier => tier.name === 'Max'); + if (!on) return {steps: steps === 8 ? max?.steps ?? 20 : steps, refine, upscale: 2, + stepCache: steps === 8 ? max?.stepCache ?? null : null}; const light = levels.find(tier => tier.twoPass && tier.upscale === 2); - return effortFor(steps, false, refine, stepCache, levels) && light ? {steps: light.steps, refine: 3, upscale: 2} : {steps, refine, upscale: 2}; + return effortFor(steps, false, refine, stepCache, levels) && light + ? {steps: light.steps, refine: 3, upscale: 2, stepCache: null} + : {steps, refine, upscale: 2, stepCache: null}; } // A continuation samples 8 + 3 in two passes: it keeps the factor of a two-pass level, else 2 (widget text). @@ -72,8 +85,8 @@ export const continuationUpscale = (steps, twoPass, refine, stepCache, upscale, String(effortFor(Number(steps), twoPass !== false, Number(refine), stepCache, levels, upscale)?.twoPass ? upscaleOf(upscale) : 2); // The level whose sampling table a plan needs, for naming a missing download (tiers.table_level): -// the exact level (the cache tells High from Max at 20 steps, the factor Light from Medium; 16 steps -// is the earlier Mac High), else the first level with those steps (Light for 8 + 3, whatever the factor). +// the exact level or legacy alias, else the first with those steps (16 is High, 20 is Max, +// Light for 8 + 3 whatever the factor). export function tableLevel(steps, twoPass, refine, stepCache = null, upscale = 2) { return effortFor(steps, twoPass, refine, stepCache, SAMPLING_EFFORTS, upscale) || legacyMacEffort(steps, twoPass, stepCache) || SAMPLING_EFFORTS.find(tier => tier.steps === steps && tier.twoPass === twoPass && (!twoPass || refine === 3)); @@ -182,7 +195,8 @@ export function createSamplingEffort(t, {onChange, onPreview = () => {}, levels // The machine's own table (effortsFrom); the names stay, the plans follow the machine. function setLevels(next) { const same = (a, b) => a.steps === b.steps && a.twoPass === b.twoPass && a.stepCache === b.stepCache && a.upscale === b.upscale; - if (!next || next.length !== efforts.length || next.every((tier, i) => same(tier, efforts[i]))) return; + if (!next || next.length !== efforts.length || (macLevels.has(next) === macLevels.has(efforts) + && next.every((tier, i) => same(tier, efforts[i])))) return; efforts = next; update({baseSteps: currentSteps, refineSteps: currentRefine, twoPass, stepCache, upscale, disabled, reason}); } diff --git a/web/studio.js b/web/studio.js index f419e9dd..b80d0360 100644 --- a/web/studio.js +++ b/web/studio.js @@ -818,9 +818,9 @@ export function openStudio(node, {extendFrom = null} = {}) { if (extension.source) return; const wantsTwoPass = mode !== 'off', wantsPreview = mode === 'preview'; if (twoPass.checked !== wantsTwoPass) { - // A level in one pass samples 20 steps; two-pass from one is Light. Typed steps stay. + // Switching off uses Max including its cache; switching on uses uncached Light. Typed steps stay. const next = passSwitch(wantsTwoPass, Number(baseSteps.value), Number(refineSteps.value), stepCacheNow(), effort.levels()); - twoPass.checked = wantsTwoPass; autoSinglePass = false; set(node, 'two_pass', wantsTwoPass); clearStepCache(); setUpscale(next.upscale); + twoPass.checked = wantsTwoPass; autoSinglePass = false; set(node, 'two_pass', wantsTwoPass); set(node, 'step_cache', next.stepCache || 'none'); setUpscale(next.upscale); if (next.steps !== Number(baseSteps.value) && !linked(node, 'base_steps') && widget(node, 'base_steps')) { baseSteps.value = String(next.steps); set(node, 'base_steps', next.steps); if (next.refine !== Number(refineSteps.value) && set(node, 'refine_steps', next.refine)) refineSteps.value = String(next.refine); From addf3ecede53352c7089c033a897fb2851a13c77 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:42 +0000 Subject: [PATCH 08/21] Agents import rendered clips into editor timelines over HTTP, MCP and the command line --- freevideo_engine/agent/cli.py | 9 ++ freevideo_engine/agent/client.py | 20 ++++- freevideo_engine/agent/guide.py | 10 +++ freevideo_engine/agent/imports.py | 142 ++++++++++++++++++++++++++++++ freevideo_engine/agent/mcp.py | 13 ++- freevideo_engine/agent/routes.py | 30 ++++++- freevideo_engine/agent/schema.py | 26 ++++++ freevideo_engine/agent/spec.py | 16 ++++ freevideo_engine/comfy_editor.py | 5 +- 9 files changed, 263 insertions(+), 8 deletions(-) create mode 100644 freevideo_engine/agent/imports.py diff --git a/freevideo_engine/agent/cli.py b/freevideo_engine/agent/cli.py index 06259869..793729b4 100644 --- a/freevideo_engine/agent/cli.py +++ b/freevideo_engine/agent/cli.py @@ -76,6 +76,12 @@ def build_parser(): schema.cli_arguments(command, schema.contracts()['GET', '/jobs']['query']) command = commands.add_parser('upload', help='Copy a local media file into FreeVideo inputs') command.add_argument('path') + command = commands.add_parser('imports', help='Bring local video or audio into the editing timeline') + imports = command.add_subparsers(dest='operation', required=True) + command = imports.add_parser('add', help='Upload content; poll imports list until ready before insert') + command.add_argument('path') + schema.cli_arguments(command, schema.obj({'ref': schema.REF})) + imports.add_parser('list', help='List imported sources and preparation progress') command = commands.add_parser('generate-image', help='Generate or change a picture with the local image model') schema.cli_arguments(command, schema.image(), exclude=('kind',)) command.add_argument('--wait', action='store_true', help='Wait for the picture and print the result') @@ -280,6 +286,9 @@ def source(value): result = client.get(path, **value) if method == 'GET' else client.post(path, value) elif args.command == 'upload': result = client.upload(args.path) + elif args.command == 'imports': + result = (client.import_media(args.path, **({'ref': args.ref} if hasattr(args, 'ref') else {})) + if args.operation == 'add' else client.get('/imports')) else: result = client.frame(source(args.source), values.get('at', 'last')) except ApiError as error: diff --git a/freevideo_engine/agent/client.py b/freevideo_engine/agent/client.py index aae09919..7bdfc67a 100644 --- a/freevideo_engine/agent/client.py +++ b/freevideo_engine/agent/client.py @@ -281,6 +281,16 @@ def asset(self, identity, target, *, thumbnail=False): def upload(self, path): """Read on the client computer and upload content; never send a local path.""" + return self._upload(path, '/media') + + def import_media(self, path, *, ref=None): + """Import a client file into the editor. Poll /imports until its state is ready.""" + from . import schema + if ref is not None: + schema.validate(schema.obj({'ref': schema.REF}), dict(ref=ref)) + return self._upload(path, '/imports', ref=ref) + + def _upload(self, path, endpoint, *, ref=None): from .schema import MAX_UPLOAD_BYTES, MAX_JSON_UPLOAD_BYTES source = local_file(path) try: @@ -289,7 +299,10 @@ def upload(self, path): raise ApiError(413, 'too_large', 'File exceeds upload limit', dict(next='Reduce the file to at most %d bytes.' % MAX_UPLOAD_BYTES, details=[dict(limit_bytes=MAX_UPLOAD_BYTES)])) if size * 4 // 3 + 4096 <= MAX_JSON_UPLOAD_BYTES: - return self.upload_bytes(source.name, source.read_bytes()) + if endpoint == '/media': + return self.upload_bytes(source.name, source.read_bytes()) + return self.post(endpoint, dict(name=source.name, data_base64=base64.b64encode(source.read_bytes()).decode(), + **({'ref': ref} if ref is not None else {})), timeout=600) import secrets boundary = 'freevideo-' + secrets.token_hex(16) # Only a safe extension crosses a MIME header; local filenames stay local. @@ -298,14 +311,15 @@ def upload(self, path): raise ApiError(422, 'invalid_media', 'Invalid media extension') prefix = ('--%s\r\nContent-Disposition: form-data; name="file"; filename="media%s"\r\n' 'Content-Type: application/octet-stream\r\n\r\n' % (boundary, suffix)).encode('ascii') - ending = ('\r\n--%s--\r\n' % boundary).encode('ascii') + ending = (('\r\n--%s\r\nContent-Disposition: form-data; name="ref"\r\n\r\n%s' % (boundary, ref) + if ref is not None else '') + '\r\n--%s--\r\n' % boundary).encode('ascii') with source.open('rb') as stream: def chunks(): yield prefix while data := stream.read(1024 * 1024): yield data yield ending - return self.request('POST', '/freevideo/agent/v1/media', encoded=chunks(), + return self.request('POST', '/freevideo/agent/v1' + endpoint, encoded=chunks(), content_type='multipart/form-data; boundary=' + boundary, content_length=len(prefix) + size + len(ending), timeout=600) except OSError: diff --git a/freevideo_engine/agent/guide.py b/freevideo_engine/agent/guide.py index 778d367f..c274f10b 100644 --- a/freevideo_engine/agent/guide.py +++ b/freevideo_engine/agent/guide.py @@ -128,6 +128,14 @@ ], 'project_routes': [dict(operation=name, method=method, path=path, description=summary) for name, (method, path, summary) in PROJECT_OPERATIONS.items()], + 'bring_your_own_footage': [ + 'Render complete clips with ffmpeg/Canvas on your computer; bake overlays into their pixels. FreeVideo receives media, not your code. Use the project dimensions (even pixels), 24 fps and integer frame positions; seconds = frames / 24.', + 'Download generated shots using result.video.url, library video.url, or sources[key].video/audio from GET /projects/{id}, with the same Authorization: Bearer token (Range supported). These URLs are relative to the server origin. Render your changes locally.', + 'POST /imports accepts multipart file then optional ref, or JSON {name, data_base64, ref?}; HTTP never reads a local path. MCP freevideo_import_media and CLI imports add read a local path and upload content, like media upload. Limits: 2 GiB content, 96 MiB JSON body, and the same media decode limits.', + 'The answer is {import: {id, source: "import:", state, fraction, ...}}. As on the page, poll GET /imports (MCP freevideo_imports, CLI imports list) about every two seconds. Match id in items; preparing is not insertable, ready is usable, failed is terminal with reason. Same ref or Idempotency-Key and filename/content reuses one import for that X-FreeVideo-Client, including after restart; changed content conflicts.', + 'The page receiver and transcode queue create an upright 24 fps H.264 preview by dropping/duplicating timestamped frames, with even dimensions and longest side at most 1920; preview audio is 32 kHz stereo AAC. Original dimensions are retained. Inserting the first video follows its original size by default (up to 8192 pixels); set project size_mode="fixed" to keep a chosen canvas. Later clips fit the canvas (cover by default). Export reads the original when available at the project output size/rate (preview fallback if missing).', + 'Insert with {op:"insert", source:"import:", at:48} in POST /projects/{id}/operations using the current revision. Add subtitles/text and audio through project operations, then POST /projects/{id}/export and wait for the job. There is one video track; effects are baked into complete clips, not separate overlay tracks or blend modes.', + ], 'editing_images': [ 'POST /images opens a picture as the image editor does; GET /images/{id} reads its document (layers), selection and revision.', 'POST /images/{id}/operations sends revision and 1-64 operations run with the page\'s own commands; the batch saves once or changes nothing. Layer IDs of new layers are in results[i].new_layer_ids.', @@ -275,6 +283,8 @@ ('POST', '/jobs/{id}/cancel'): '取消任务', ('POST', '/jobs/{id}/resume'): '接着生成一条视频里还没完成的部分', ('POST', '/media'): '上传图片、视频或音频内容', + ('POST', '/imports'): '导入视频或音频到剪辑时间线;轮询 GET /imports 等待就绪', + ('GET', '/imports'): '列出已导入素材和准备进度', ('GET', '/media/{kind}/{file}/file'): '下载上传或处理后的素材', ('POST', '/media/inspect'): '查看素材信息', ('POST', '/media/frame'): '提取视频的一帧', diff --git a/freevideo_engine/agent/imports.py b/freevideo_engine/agent/imports.py new file mode 100644 index 00000000..1dfa5ddd --- /dev/null +++ b/freevideo_engine/agent/imports.py @@ -0,0 +1,142 @@ +"""Content uploads into the editor's import store and software transcode queue.""" +import asyncio +import base64 +import binascii +import hashlib +from pathlib import Path +import tempfile +from types import SimpleNamespace +from urllib.parse import quote, urlencode + +from .. import comfy_editor as editor +from . import media, schema, spec +from .jobs import JobError + + +def invalid(path, expected, code='invalid_media'): + error = spec.SpecError(schema.diagnostic(path, expected, None)) + error.code = code + raise error + + +def view(value): + fields = ('id', 'name', 'kind', 'state', 'fraction', 'reason', 'frames', 'fps', 'width', 'height', + 'preview_width', 'preview_height', 'has_audio') + row = {key: value.get(key) for key in fields} + row['fps'] = value.get('fps', editor.FPS) + row['has_audio'] = value.get('has_audio', False) + row['source'] = 'import:' + value['id'] + for kind in ('preview', 'thumbnail'): + row[kind] = (schema.PREFIX + '/editor/sources/content?' + urlencode(dict(key=row['source'], file=kind)) + if row['state'] == 'ready' else None) + return row + + +def listing(root): + return dict(items=[view(row) for row in editor.list_imports(root)]) + + +def replay(root, receipt): + if receipt is None: + return None + for row in editor.list_imports(root): + value = editor._read_import(root, row['id']) + saved = value.get('agent_receipt') + if saved and (saved.get('client'), saved.get('ref')) == (receipt['client'], receipt['ref']): + if saved['digest'] != receipt['digest']: + invalid('/ref', 'the same filename and content for a replay', 'idempotency_conflict') + return view(row) + return None + + +class Content: + """Adapt a checked upload to the page's streaming receiver, without a server-side path API.""" + def __init__(self, path): + self.path = path + + async def iter_chunked(self, size): + with self.path.open('rb') as stream: + while chunk := await asyncio.to_thread(stream.read, size): + yield chunk + + +async def upload(request, value, root, manager, lock, decoders): + if manager is None: + raise JobError('not_ready', 'Editor import queue unavailable') + # Temporary content stays beside the destination, and is removed on rejection or disconnect. + with tempfile.TemporaryDirectory(prefix='.agent-import-', dir=root) as temporary: + multipart = request.content_type == 'multipart/form-data' + field = '/file' if multipart else '/data_base64' + ref = None if multipart else value.get('ref') + if multipart: + reader = await request.multipart() + part = await reader.next() + if part is None or getattr(part, 'name', None) != 'file' or not getattr(part, 'filename', None): + invalid('/file', 'one nonempty file part, followed by optional ref') + name = part.filename + else: + name = value['name'] + spec.import_name(name) + target = Path(temporary) / ('media' + Path(name).suffix.lower()) + digest = hashlib.sha256() + size = 0 + with target.open('xb') as stream: + if multipart: + while chunk := await part.read_chunk(size=256 * 1024): + size += len(chunk) + if size > schema.MAX_UPLOAD_BYTES: + raise JobError('too_large', 'Upload exceeds limit', limit_bytes=schema.MAX_UPLOAD_BYTES) + digest.update(chunk) + await asyncio.to_thread(stream.write, chunk) + extra = await reader.next() + if extra is not None: + if getattr(extra, 'name', None) != 'ref' or getattr(extra, 'filename', None): + invalid('/file', 'one file part followed only by optional ref') + data = bytearray() + while chunk := await extra.read_chunk(): + data.extend(chunk) + if len(data) > 1024: + spec.fail('/ref', 'a ref of at most 128 characters') + try: + ref = data.decode('utf-8') + except UnicodeDecodeError: + spec.fail('/ref', 'a UTF-8 ref') + if await reader.next() is not None: + invalid('/file', 'one file part followed only by optional ref') + else: + try: + data = base64.b64decode(value['data_base64'], validate=True) + except (binascii.Error, ValueError): + invalid(field, 'valid base64-encoded video or audio content') + size = len(data) + if size > schema.MAX_UPLOAD_BYTES: + raise JobError('too_large', 'Upload exceeds limit', limit_bytes=schema.MAX_UPLOAD_BYTES) + digest.update(data) + await asyncio.to_thread(stream.write, data) + if not size: + invalid(field, 'nonempty video or audio content') + key = request.headers.get('Idempotency-Key') + for where, candidate in (('/ref', ref), ('/headers/Idempotency-Key', key)): + if candidate is not None: + problems = schema.issues(schema.REF, candidate, where) + if problems: + raise spec.SpecError(problems) + if ref and key and ref != key: + invalid('/ref', 'the same value as Idempotency-Key', 'idempotency_conflict') + ref = key or ref + receipt = (dict(ref=ref, client=request.headers.get('X-FreeVideo-Client', '')[:80] or None, + digest=hashlib.sha256(name.encode() + b'\0' + digest.digest()).hexdigest()) if ref else None) + async with decoders: + try: + await asyncio.to_thread(media.validate_upload, target) + except (OSError, ValueError, SyntaxError): + invalid(field, 'decodable video or audio within the media upload limits') + async with lock: + previous = await asyncio.to_thread(replay, root, receipt) + if previous is not None: + return {'import': previous}, 200 + adapted = SimpleNamespace(content_length=size, headers={'X-FreeVideo-Filename': quote(name, safe='')}, + content=Content(target)) + made = await editor.receive(adapted, root, receipt=receipt) + manager.submit(made['id']) + return {'import': view(made)}, 201 diff --git a/freevideo_engine/agent/mcp.py b/freevideo_engine/agent/mcp.py index 62ce0d27..e94b1f88 100644 --- a/freevideo_engine/agent/mcp.py +++ b/freevideo_engine/agent/mcp.py @@ -31,7 +31,12 @@ "frame": "last"}), look at results with freevideo_look, ask the local VLM with freevideo_ask, and join clips with freevideo_assemble. For durable filming, use freevideo_drama_plan → start → get → sheet → choose/reshoot → finish. Cast first: search freevideo_cast_list, reuse the card the user named or one that fits, create a card only if none does. -If paused is set, wait for the user using get with since and wait=25. Only the user may pause/resume.""" +If paused is set, wait for the user using get with since and wait=25. Only the user may pause/resume. +Bring your own footage: render complete video clips on your computer with ffmpeg/Canvas, baking effects into pixels. +freevideo_import_media reads your local file and uploads content (up to 2 GiB); reuse ref for safe retries. +Poll freevideo_imports about every two seconds until state=ready (failed is terminal), then insert its source=import: +at an integer frame in a 24 fps project, add subtitles/audio, and export. GET /guide bring_your_own_footage explains +authenticated source downloads, dimensions and audio. No second video track or blend mode is needed.""" def tool_list(): @@ -53,6 +58,8 @@ def tool_list(): dict(name='freevideo_cancel', title='Cancel a job', description='Cancel a waiting, queued or running job.', annotations={'readOnlyHint': False, 'destructiveHint': True, 'openWorldHint': False}), dict(name='freevideo_resume', title='Resume generation', description='Resume a failed, interrupted or cancelled generation; only unfinished blocks run. Poll the same job ID.', annotations=write), dict(name='freevideo_add_media', title='Add media', description='Read a local image, video or audio file and upload its content; returns the "file" to use in media.', annotations=write), + dict(name='freevideo_import_media', title='Import footage', description='Read a local video or audio file and upload it into the editor. Returns import.source (import:) and state. Poll freevideo_imports until ready, then insert that source into a project. Same ref and content safely replay.', annotations=write), + dict(name='freevideo_imports', title='Imported footage', description='List editor imports with source, state (preparing/ready/failed), fraction and authenticated preview URLs. Wait for ready before insert; failed is terminal.', annotations=read), dict(name='freevideo_look', title='Look at media', description='Return a picture you can see: one frame of a video (at = first, last or seconds) or a contact sheet of timed frames (mode = sheet), or an image file. Use it to review shots.', annotations=read), dict(name='freevideo_edit_image', title='Edit an image', description="Crop/rotate/flip/pad/adjust an image, add text, shapes or image overlays, or remove burned-in captions (remove_text), without the browser. The result is a new input file plus an editor document a person can reopen in FreeVideo's image editor.", annotations=write), dict(name='freevideo_ask', title='Ask the local VLM', description='Ask FreeVideo\'s local vision-language model about images or sampled frames of a video (e.g. "Does this shot match its description? Answer as JSON {score, issues}").', annotations=write), @@ -359,6 +366,10 @@ def tool(self, identity, name, args, token): return c.resume(args['id'], **({'ref': args['ref']} if 'ref' in args else {})), [] if name == 'freevideo_add_media': return c.upload(args['path']), [] + if name == 'freevideo_import_media': + return c.import_media(args['path'], **({'ref': args['ref']} if 'ref' in args else {})), [] + if name == 'freevideo_imports': + return c.get('/imports'), [] if name == 'freevideo_edit_image': made = c.edit(args['source'], args.get('recipe'), document=args.get('document'), target=args.get('target')) return made, self.picture(made['view']) diff --git a/freevideo_engine/agent/routes.py b/freevideo_engine/agent/routes.py index e0fa1135..4def1fbd 100644 --- a/freevideo_engine/agent/routes.py +++ b/freevideo_engine/agent/routes.py @@ -165,7 +165,8 @@ def features(continuation, vlm): from .editor_runtime import available rules = available() return {'capabilities': True, 'plan': True, 'jobs.cancel': True, 'jobs.resume': True, 'takes': True, - 'library.read': True, 'library.download': True, 'errors.validation': True, 'errors.missing_media': True, + 'library.read': True, 'library.download': True, 'imports.create': True, 'imports.read': True, + 'errors.validation': True, 'errors.missing_media': True, 'generate.text': True, 'generate.size': True, 'generate.first_frame': True, 'generate.seed': True, 'queue.shared': True, 'queue.busy': True, 'chain.auto': bool(continuation), 'enhance': bool(vlm.get('ready')), 'drama.film': True, 'images.edit': rules, @@ -387,6 +388,7 @@ async def off(request): token_failures = set() thumbnails = asyncio.Semaphore(1) upload_decoders = asyncio.Semaphore(1) + import_lock = asyncio.Lock() def expected(root=None): from ..comfy_bridge import installation_root @@ -492,7 +494,7 @@ async def respond(request): if definition.get('multipart') and request.content_type == 'multipart/form-data': pass else: - limit = contract.MAX_JSON_UPLOAD_BYTES if suffix == '/media' else contract.MAX_BODY_BYTES + limit = contract.MAX_JSON_UPLOAD_BYTES if suffix in ('/media', '/imports') else contract.MAX_BODY_BYTES value = await read_body(request, limit, definition.get('optional_body', False)) try: contract.validate(definition['body'], value) @@ -518,8 +520,10 @@ async def respond(request): value['next'] = value['next'].replace('{id}', request.match_info['id']) if error.code == 'too_large': limit = error.details.get('limit_bytes', contract.MAX_UPLOAD_BYTES) + location = ({'path': '/file' if request.content_type == 'multipart/form-data' else '/data_base64'} + if suffix == '/imports' else {}) value.update(message='The upload must be at most %d bytes; a larger payload was received.' % limit, - details=[dict(limit_bytes=limit)], next='Reduce the payload to at most %d bytes and retry.' % limit) + details=[dict(limit_bytes=limit, **location)], next='Reduce the payload to at most %d bytes and retry.' % limit) if error.code == 'busy': entries = (await asyncio.to_thread(jobs.queue_view))['entries'] value = errors.build('busy', owner=entries[0]['owner'] if entries else 'ui') @@ -1466,6 +1470,26 @@ def relocate(value): made.pop('path', None) return assets.public(dict(made, **info, file=relative, view=assets.view(relative))) + @routes.post(PREFIX + '/imports') + @guarded + async def import_media(request): + from . import imports + value = None if request.content_type == 'multipart/form-data' else await body(request) + try: + result, status = await imports.upload(request, value, port.output_root, + getattr(server, '_freevideo_editor', None), import_lock, upload_decoders) + except specs.SpecError: + raise + except (ValueError, AssertionError): + imports.invalid('/file', 'a well-formed multipart upload with video or audio content') + return reply(result, status) + + @routes.get(PREFIX + '/imports') + @guarded + async def list_imports(request): + from . import imports + return reply(await asyncio.to_thread(imports.listing, port.output_root)) + @routes.post(PREFIX + '/media') @guarded async def upload(request): diff --git a/freevideo_engine/agent/schema.py b/freevideo_engine/agent/schema.py index f0ac1cdb..79fa2b4d 100644 --- a/freevideo_engine/agent/schema.py +++ b/freevideo_engine/agent/schema.py @@ -316,6 +316,20 @@ def batch_schema(*, local=False): return obj(dict(jobs=array(job_schema(local=local, refs=True), 1, 64), ref=REF), ('jobs',), description='x-batch additionally checks earlier-row references and at most 64 jobs after takes expansion.', **{'x-batch': True}) +def import_upload(): + return obj(dict(name=string(255, pattern=r'^[^/\\:\x00-\x1f]+$'), + data_base64=string(MAX_JSON_UPLOAD_BYTES), ref=REF), ('name', 'data_base64')) + + +def import_view(): + return obj(dict(id=string(80), source=EDITOR_SOURCE, name=string(255), kind=enum(('video', 'audio')), + state=enum(('preparing', 'ready', 'failed')), fraction=number(0, 1), reason=nullable(string()), + frames=nullable(number(1, integer=True)), fps=number(1), width=nullable(number(0, integer=True)), + height=nullable(number(0, integer=True)), preview_width=nullable(number(0, integer=True)), + preview_height=nullable(number(0, integer=True)), has_audio=nullable({'type': 'boolean'}), + preview=nullable(string()), thumbnail=nullable(string())), ('id', 'source', 'name', 'kind', 'state', 'fraction')) + + def contracts(*, local=False): """Every registered route, including the UI control plane, has a contract.""" def route(summary, body=None, query=None, **kw): @@ -346,6 +360,9 @@ def route(summary, body=None, query=None, **kw): ('POST', '/media'): route('Upload image, video or audio content', body=obj(dict(name=string(255, pattern=r'^[^/\\:\x00]+$'), data_base64=string(MAX_JSON_UPLOAD_BYTES)), ('name', 'data_base64')), status=201, multipart=True), + ('POST', '/imports'): route('Import video or audio into the editing timeline; poll GET /imports until ready', + body=import_upload(), status=201, multipart=True, idempotent=True), + ('GET', '/imports'): route('List editor imports and preparation progress'), ('GET', '/media/{kind}/{file}/file'): route('Download uploaded or derived media'), ('POST', '/media/inspect'): route('Inspect media', body=obj(source, ('source',))), ('POST', '/media/frame'): route('Extract a video frame', body=obj(dict(source, at=dict(FRAME, default='last')), ('source',)), status=201), @@ -1293,6 +1310,7 @@ def schemas(): drama={name: drama_schema(name) for name in DRAMA_OPERATIONS}, production_view=production_response(), cast={name: cast_schema(name) for name in CAST_OPERATIONS}, cast_view=cast_view(), projects={name: project_schema(name) for name in PROJECT_OPERATIONS}, + imports=dict(upload=import_upload(), item=import_view()), images={name: image_schema(name) for name in IMAGE_OPERATIONS}, whitebox={name: whitebox_schema(name) for name in WHITEBOX_OPERATIONS}, sessions=dict(event=session_event(stored=True), meta=session_view(), @@ -1316,6 +1334,8 @@ def openapi(): content = {'application/json': {'schema': deepcopy(contract['body'])}} if contract.get('multipart'): content['multipart/form-data'] = {'schema': obj({'file': {'type': 'string', 'format': 'binary'}}, ('file',))} + if suffix == '/imports': + content['multipart/form-data']['schema']['properties']['ref'] = REF operation['requestBody'] = dict(required=not contract.get('optional_body', False), content=content) operation['parameters'] = [dict(name=k, **{'in': 'query'}, required=k in contract['query'].get('required', []), schema=v) for k, v in contract['query']['properties'].items()] @@ -1356,6 +1376,9 @@ def openapi(): if suffix == '/sessions' and method == 'GET' else session_view()) elif suffix.endswith('/events'): content_type, response_schema = 'text/event-stream', {'type': 'string'} + elif suffix == '/imports': + response_schema = obj({'import': import_view()}, ('import',)) if method == 'POST' else obj( + {'items': array(import_view())}, ('items',)) elif suffix == '/editor/sources/content': content_type, response_schema = 'application/octet-stream', {'type': 'string', 'format': 'binary'} elif suffix.endswith('/file') or suffix.endswith('/thumbnail'): @@ -1411,6 +1434,7 @@ def openapi(): 'freevideo_job': ('GET', '/jobs/{id}'), 'freevideo_wait': ('GET', '/jobs/{id}'), 'freevideo_jobs': ('GET', '/jobs'), 'freevideo_cancel': ('POST', '/jobs/{id}/cancel'), 'freevideo_resume': ('POST', '/jobs/{id}/resume'), 'freevideo_add_media': ('POST', '/media'), + 'freevideo_import_media': ('POST', '/imports'), 'freevideo_imports': ('GET', '/imports'), 'freevideo_edit_image': ('POST', '/media/edit'), 'freevideo_library': ('GET', '/library'), } TOOL_ENDPOINTS.update({'freevideo_drama_' + name: (method, suffix) @@ -1547,6 +1571,8 @@ def _tool_schema(name): return batch_schema(local=True) if name == 'freevideo_add_media': return obj({'path': string(4096)}, ('path',)) + if name == 'freevideo_import_media': + return obj(dict(path=string(4096), ref=REF), ('path',)) if '{id}' in suffix: value['properties']['id'] = contract.get('path', {}).get('properties', {}).get('id', JOB) value['required'] = list(value.get('required', [])) + ['id'] diff --git a/freevideo_engine/agent/spec.py b/freevideo_engine/agent/spec.py index f2e508a7..a5d51c08 100644 --- a/freevideo_engine/agent/spec.py +++ b/freevideo_engine/agent/spec.py @@ -27,6 +27,22 @@ def fail(path, message): raise SpecError(contract.diagnostic(path, message, None)) +def import_name(name): + """Timeline imports accept video/audio content, with no HTTP filesystem paths.""" + from ..comfy_assets import media_kind + problems = contract.issues(contract.import_upload()['properties']['name'], name, '/name') + if problems: + raise SpecError(problems) + try: + if media_kind(name) not in ('video', 'audio'): + raise ValueError + except ValueError: + error = SpecError(contract.diagnostic('/name', 'a supported video or audio filename', None)) + error.code = 'invalid_media' + raise error from None + return name + + # Field checks for values no route schema describes: screenplays and filming records. def _bool(value, path): if type(value) is not bool: diff --git a/freevideo_engine/comfy_editor.py b/freevideo_engine/comfy_editor.py index 1d88c671..5150f7a2 100644 --- a/freevideo_engine/comfy_editor.py +++ b/freevideo_engine/comfy_editor.py @@ -866,7 +866,7 @@ def _display_name(value): return name -async def receive(request, root): +async def receive(request, root, *, receipt=None): if request.content_length is not None and request.content_length > MAX_IMPORT_BYTES: raise TooLarge('Import exceeds 8 GiB') name = _display_name(request.headers.get('X-FreeVideo-Filename')) @@ -894,6 +894,9 @@ async def receive(request, root): await asyncio.to_thread(os.replace, temporary, destination) value = dict(id=identity, name=name, kind=kind, state='preparing', fraction=0., reason=None, frames=None, fps=FPS, width=None, height=None, has_audio=False) + if receipt is not None: + # Keep the Agent replay key in the same atomic record as the import. + value['agent_receipt'] = receipt await asyncio.to_thread(_write, _import_path(root, identity), value) return {key: value[key] for key in ('id', 'name', 'kind', 'state', 'fraction')} except BaseException: From 6ca16b3432bc6219798530979f08bd9a06c08681 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:43 +0000 Subject: [PATCH 09/21] Keep FreeVideo's own text out of browser auto-translate (MP stays MP) --- scripts/test_freevideo_entry.mjs | 3 ++- web/freevideo.js | 2 ++ web/health.js | 2 +- web/translate_guard.js | 17 +++++++++++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 web/translate_guard.js diff --git a/scripts/test_freevideo_entry.mjs b/scripts/test_freevideo_entry.mjs index 65fe2b15..dc1ee8a7 100644 --- a/scripts/test_freevideo_entry.mjs +++ b/scripts/test_freevideo_entry.mjs @@ -126,7 +126,8 @@ test('main browser entry registers both views and preserves node hooks', async t .replace("import { uploadMedia } from './media_upload.js';", 'const {uploadMedia} = globalThis.__freevideoEntryTest;') .replace("import { createCastLibrary } from './cast_library.js';", 'const {createCastLibrary} = globalThis.__freevideoEntryTest;') .replace("import { agentInterfaceEnabled } from './agent_connect.js';", 'const agentInterfaceEnabled = async () => false;') - .replace("import { installNativeErrorGuard } from './native_errors.js';", 'const installNativeErrorGuard = () => {};'); + .replace("import { installNativeErrorGuard } from './native_errors.js';", 'const installNativeErrorGuard = () => {};') + .replace("import { installTranslateGuard } from './translate_guard.js';", 'const installTranslateGuard = () => {};'); await import('data:text/javascript;base64,' + Buffer.from(source).toString('base64')); const extension = extensions.find(row => row.name === 'FreeVideo.UnifiedMedia'); assert.ok(extension, 'the main extension must register'); diff --git a/web/freevideo.js b/web/freevideo.js index ae5fb800..5f5de117 100644 --- a/web/freevideo.js +++ b/web/freevideo.js @@ -1,5 +1,6 @@ import { createErrorPanel, errorText, createErrorReport, adviceFor } from './error_panel.js'; import { installNativeErrorGuard } from './native_errors.js'; +import { installTranslateGuard } from './translate_guard.js'; import { app } from "../../scripts/app.js"; import { api } from "../../scripts/api.js"; import { openEditorView } from './editor_loader.js'; @@ -846,6 +847,7 @@ api.addEventListener('freevideo_prewarm', event => { if (value) app.graph?.getNodeById(value.node)?.freevideoShowPrewarm?.(value); }); +installTranslateGuard({chinese: cn}); installNativeErrorGuard({api, app, describe: detail => { const {advice} = adviceFor(createErrorReport(detail, {stage: 'execution', graph: app.graph}), text); return [advice.title, advice.summary].filter(Boolean).join('\n'); diff --git a/web/health.js b/web/health.js index 3647b1f8..050c2f65 100644 --- a/web/health.js +++ b/web/health.js @@ -15,7 +15,7 @@ const launchVisit = query.get('freevideo') === 'launch'; // Every script this folder ships; a test keeps the list in step with web/*.js. export const MODULES = ['agent_activity.js', 'agent_connect.js', 'agent_session.js', 'autopilot.js', 'autopilot_chat.js', 'autopilot_conversations.js', 'browser_extension.js', 'caret_rect.js', 'chain_support.js', 'capability_view.js', 'cast_generate.js', 'cast_mention.js', 'cast_overlay.js', 'cast_source.js', 'compatibility.js', 'entry_showcase.js', 'error_panel.js', 'first_run_guide.js', 'fonts.js', 'freevideo.js', 'generation_progress.js', 'editor.js', 'editor_actions.js', 'editor_lifecycle.js', 'editor_adjust.js', 'editor_adjust_picture.js', 'editor_picture_fields.js', 'editor_picture_session.js', 'editor_preview_picture.js', 'editor_entry.js', 'editor_expand.js', 'editor_export_dialog.js', 'editor_first_frame.js', 'editor_media_references.js', 'editor_references.js', 'editor_genbar.js', 'editor_geometry.js', 'editor_library.js', 'editor_menu.js', 'editor_model.js', 'editor_frame.js', 'editor_player.js', 'editor_room.js', 'editor_select.js', 'editor_state.js', 'editor_store.js', 'editor_tracks.js', 'editor_generation.js', 'editor_transport.js', 'editor_transport_model.js', 'editor_audio.js', 'editor_audio_model.js', 'editor_audio_notes.js', 'editor_audio_replace.js', 'editor_audio_rules.js', 'editor_speed.js', 'editor_speed_model.js', 'editor_failure.js', 'editor_header_fit.js', - 'editor_loader.js', 'editor_text_coverage.js', 'editor_text.js', 'editor_toolbar_more.js', 'editor_text_model.js', 'editor_text_layout.js', 'editor_notes.js', 'editor_icons.js', 'dialog_keys.js', 'done_notify.js', 'failure_issue.js', 'feedback.js', 'frame_sizes.js', 'health.js', 'image_commands.js', 'image_editor.js', 'image_editor_engine.js', 'image_generation.js', 'launch_visit.js', 'launcher.js', 'length_plan.js', 'lora_triggers.js', 'lora_check.js', 'library.js', 'motion.js', 'native_errors.js', 'output_download.js', 'port_notice.js', 'preview_scene.js', + 'editor_loader.js', 'editor_text_coverage.js', 'editor_text.js', 'editor_toolbar_more.js', 'editor_text_model.js', 'editor_text_layout.js', 'editor_notes.js', 'editor_icons.js', 'dialog_keys.js', 'done_notify.js', 'failure_issue.js', 'feedback.js', 'frame_sizes.js', 'health.js', 'image_commands.js', 'image_editor.js', 'image_editor_engine.js', 'image_generation.js', 'launch_visit.js', 'launcher.js', 'length_plan.js', 'lora_triggers.js', 'lora_check.js', 'library.js', 'motion.js', 'native_errors.js', 'translate_guard.js', 'output_download.js', 'port_notice.js', 'preview_scene.js', 'progress_connection.js', 'prompt_draft.js', 'prompt_enhance.js', 'prompt_references.js', 'prompt_terms.js', 'request_assets.js', 'repair_hint.js', 'report_issue.js', 'studio_recent.js', 'result_actions.js', 'sampling_effort.js', 'setup.js', 'share.js', 'share_layout.js', 'studio.js', 'studio_chain.js', 'studio_extend.js', 'studio_length.js', 'first_frame_row.js', 'optional_inputs.js', 'studio_queue.js', 'studio_size.js', 'toolbar_position.js', 'updates.js', 'view_navigation.js', 'wordmark.js', 'workspace_restore.js', 'cast_library.js', 'media_upload.js', 'whitebox_encode.js', 'whitebox_mp4.js', 'whitebox_recording.js', 'whitebox_render.js', 'whitebox_scenes.js', 'whitebox_worker.js']; diff --git a/web/translate_guard.js b/web/translate_guard.js new file mode 100644 index 00000000..7db62f0e --- /dev/null +++ b/web/translate_guard.js @@ -0,0 +1,17 @@ +// Browser auto-translate reads ComfyUI's lang="en" page and rewrites FreeVideo's own text: "MP" +// became 兆帕. FreeVideo writes both languages itself, so its surfaces opt out of translation and +// a Chinese interface says so on the document. +const OWN_CLASS = /(^|\s)fv-/; + +export function markOwn(node) { + if (node?.nodeType !== 1 || node.hasAttribute('translate')) return; + if (OWN_CLASS.test(node.getAttribute('class') || '') || node.id?.startsWith('fv-')) node.setAttribute('translate', 'no'); +} + +export function installTranslateGuard({chinese, doc = document} = {}) { + if (chinese) doc.documentElement.lang = 'zh-CN'; + for (const node of doc.body.children) markOwn(node); + new MutationObserver(records => { + for (const record of records) for (const node of record.addedNodes) markOwn(node); + }).observe(doc.body, {childList: true}); +} From f3246696b7c7450c28627018d447a584ee5d4975 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:44 +0000 Subject: [PATCH 10/21] Upgrade keeps two-pass, step counts, step cache and upscale when an old tab is replaced --- web/launcher.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/web/launcher.js b/web/launcher.js index a0dcfb7f..5fa58417 100644 --- a/web/launcher.js +++ b/web/launcher.js @@ -43,6 +43,21 @@ function currentStudioWorkflow(saved, bundled) { if (finite(height, 256, 4096) && Number.isInteger(height)) node.widgets_values[2] = height; if (finite(seconds, 1.625, 60)) node.widgets_values[3] = seconds; if (finite(seed, 0, 2 ** 53 - 1) && Number.isInteger(seed)) node.widgets_values[4] = seed; + // A tab saved by 0.4.13 or later keeps these at fixed positions (6, 7, 8, 17, 18); an unstamped one moved them. + const [major, minor, patch] = String(old.properties?.freevideo_version).split('.').map(Number); + const stamped = [major, minor, patch].every(Number.isInteger) && (major > 0 || minor > 4 || (minor === 4 && patch >= 13)); + if (stamped && Array.isArray(old.widgets_values)) { + const values = node.widgets_values, kept = old.widgets_values; + // The bundled workflow lists only the first widgets: fill up to the last one with the node's defaults. + const defaults = [8, 3, false, false, '', '', 0, false, false, false, 'none', '2']; + while (values.length < 19) values.push(defaults[values.length - 7]); + if (typeof kept[6] === 'boolean') values[6] = kept[6]; + // The quality level is these steps: High and Max are 20 first-pass steps. + if (Number.isInteger(kept[7]) && finite(kept[7], 1, 32)) values[7] = kept[7]; + if (Number.isInteger(kept[8]) && finite(kept[8], 1, 31)) values[8] = kept[8]; + if (['none', 'easycache-av', 'fbcache'].includes(kept[17])) values[17] = kept[17]; + if (['2', '1.5', '1.2'].includes(kept[18])) values[18] = kept[18]; + } const media = graph.nodes.find(row => row.type === 'FreeVideoMedia'); const assets = (saved.nodes.find(row => row.type === 'FreeVideoMedia')?.widgets_values || [])[0]; try { From 1b80f3b336126cfe0e20f2804b4b9843b6cf9c21 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:45 +0000 Subject: [PATCH 11/21] Studio: queue more long-video requests while one is generating --- web/studio.css | 3 +++ web/studio.js | 41 +++++++++++++++++++++++++++++++---------- web/studio_chain.js | 45 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/web/studio.css b/web/studio.css index ecbafad0..360665d3 100644 --- a/web/studio.css +++ b/web/studio.css @@ -222,3 +222,6 @@ .fv-lora-problem{grid-column:var(--lora-lead,2)/span 3;grid-row:4;display:flex;flex-direction:column;align-items:flex-start;gap:6px;font-size:var(--fv-micro)}.fv-lora-problem p{margin:0;color:var(--fv-danger)}.fv-lora-problem.fv-lora-partial{color:var(--fv-muted)}.fv-lora-problem[hidden]{display:none}.fv-lora-why summary{cursor:pointer;color:var(--fv-muted)}.fv-lora-why pre{margin:6px 0 0;white-space:pre-wrap;word-break:break-all;color:var(--fv-muted);font:inherit;font-family:ui-monospace,monospace}.fv-lora-row[data-unusable=true] select{color:var(--fv-muted)} .fv-lora-row[data-unusable=true]{cursor:default}.fv-lora-row[data-unusable=true] :is(input[type=number],input[type=checkbox]){opacity:.45}.fv-lora-row[data-unusable=true] select{opacity:1}.fv-lora-row[data-unusable=true] :is(.fv-lora-trigger,.fv-lora-range){display:none} +/* The queued count follows the part number; when the line is too narrow it wraps out of sight. */ +.fv-studio .fv-chain-position:has(.fv-chain-queued){display:flex;flex-wrap:wrap;column-gap:0;line-height:1.4;max-height:1.4em;overflow:hidden} +.fv-studio .fv-chain-position .fv-chain-queued{white-space:pre} diff --git a/web/studio.js b/web/studio.js index b80d0360..3e732d49 100644 --- a/web/studio.js +++ b/web/studio.js @@ -1099,6 +1099,11 @@ export function openStudio(node, {extendFrom = null} = {}) { stage.append(stageMedia); previewSpace.append(stage); const progress = createGenerationProgress(t, undefined, {compact: true, api}); stage.append(progress.element); const chainLine = el('div', '', 'fv-muted fv-chain-position'); chainLine.hidden = true; progress.element.prepend(chainLine); + // The queued count sits after the part number; a line too narrow for both keeps the part number only. + const setChainLine = text => { + const main = el('span', text), more = chainController?.waiting; + chainLine.replaceChildren(main, ...(more ? [el('span', t(` · ${more} more queued`, ` · 另有 ${more} 条排队`), 'fv-chain-queued')] : [])); + }; progress.updateReport({report_id: node.freevideoReportId}); cleanup.push(() => progress.dispose()); cleanup.push(createPreviewScene(stage, progress.element, stageMedia)); @@ -1302,13 +1307,13 @@ export function openStudio(node, {extendFrom = null} = {}) { }, })); const queueController = studioQueues.get(node); - let chainWasActive = false; + let chainWasActive = false, stopNote = ''; chainController = createStudioChain({api, node, onProgress: (message, chain) => { const position = chainPosition(chain, message); const joining = readChainResult(chain).joining, waiting = chain.state === 'queued' && message.phase === 'prepare'; - chainLine.textContent = joining ? t('Joining the parts.', '正在接合各段。') + setChainLine(joining ? t('Joining the parts.', '正在接合各段。') : waiting ? t(`Waiting in queue · Part ${position.index + 1} of ${position.count}`, `正在排队 · 第 ${position.index + 1} 段,共 ${position.count} 段`) - : t(`Part ${position.index + 1} of ${position.count}`, `第 ${position.index + 1} 段,共 ${position.count} 段`); + : t(`Part ${position.index + 1} of ${position.count}`, `第 ${position.index + 1} 段,共 ${position.count} 段`)); progress.element.querySelector('.fv-generation-label').hidden = joining || waiting; progress.updateReport(message); showProgress(message); }, @@ -1324,12 +1329,14 @@ export function openStudio(node, {extendFrom = null} = {}) { partList.update(chain, active); busy = active || Boolean(queueState?.running || queueState?.pending.length); queued = chain?.state === 'queued'; chainLine.hidden = !active; - chainLine.textContent = outcome?.joining ? t('Joining the parts.', '正在接合各段。') - : t(`Part ${position.index + 1} of ${position.count}`, `第 ${position.index + 1} 段,共 ${position.count} 段`); + setChainLine(outcome?.joining ? t('Joining the parts.', '正在接合各段。') + : t(`Part ${position.index + 1} of ${position.count}`, `第 ${position.index + 1} 段,共 ${position.count} 段`)); if (active && node.properties.freevideo_chain?.width) previewSize(node.properties.freevideo_chain.width, node.properties.freevideo_chain.height); if (!active) { cancelling = false; hideProgress(); } if (!active) progress.element.querySelector('.fv-generation-label').hidden = false; if (chain?.state === 'cancelled') status.textContent = t('Cancelled', '已取消'); + // After a stop with videos queued the next one starts at once; its line says so until something else is done. + if (stopNote) { status.dataset.error = 'false'; status.textContent = stopNote; } resumeChain.hidden = !['cancelled', 'failed', 'interrupted'].includes(chain?.state); queueActions.hidden = !active && !busy && resumeChain.hidden; updateRunButton(); @@ -1439,15 +1446,18 @@ export function openStudio(node, {extendFrom = null} = {}) { runMode = multiple || extension.source ? 'single' : ['single', 'batch', 'loop'].includes(node.properties?.freevideo_run_mode) ? node.properties.freevideo_run_mode : runMode; const chain = chainController?.state, position = chainPosition(chain); - const chainReason = !chainController?.active ? '' : readChainResult(chain)?.joining + // Only another long video can join a running chain; a single-part request would be submitted + // straight to the busy GPU, so its button waits like a full queue does. + const chainWait = Boolean(chainController?.active && (!chainController.canQueue || !multiple)); + const chainReason = !chainWait ? '' : readChainResult(chain)?.joining ? t('Joining parts…', '正在拼接…') : chain?.state === 'queued' ? t('Queued…', '排队中…') : t(`Generating part ${position.index + 1}…`, `正在生成第 ${position.index + 1} 段…`); - generate.disabled = submitting || chainController?.active || lengthControl.blocked || (runMode === 'loop' && queueState?.looping); + generate.disabled = submitting || chainWait || lengthControl.blocked || (runMode === 'loop' && queueState?.looping); generate.textContent = submitting ? t('Adding…', '正在添加…') : chainReason || (runMode === 'batch' ? t(`Add ${count.value || '…'} videos`, `添加 ${count.value || '…'} 个视频`) : runMode === 'loop' ? (queueState?.looping ? t('Looping', '循环中') : t('Start loop', '开始循环')) - : busy ? t('Add to queue', '添加到队列') + : busy ? t('Add to queue', '加入队列') : previewFirst.checked && !previewFirst.disabled ? t('Generate preview', '生成预览') : t('Generate video', '生成视频')); generate.title = (lengthControl.blocked ? lengthControl.message : submitting ? t('Adding…', '正在添加…') : ''); for (const b of modeButtons) b.setAttribute('aria-pressed', String(b.dataset.mode === runMode)); @@ -1543,7 +1553,12 @@ export function openStudio(node, {extendFrom = null} = {}) { if (cancelling) return; try { cancelling = true; updateRunButton(); - if (chainController.active) { await chainController.cancel(); cancelling = false; updateRunButton(); return; } + if (chainController.active) { + stopNote = chainController.waiting > 0 ? t('Stopped. The next queued video is starting.', '已停止,队列中的下一条开始生成。') : ''; + await chainController.cancel(); cancelling = false; updateRunButton(); + if (stopNote) { status.dataset.error = 'false'; status.textContent = stopNote; } + return; + } await syncQueue(); const id = queueController.state().running?.id; if (!id) { cancelling = false; updateRunButton(); return; } @@ -1579,7 +1594,7 @@ export function openStudio(node, {extendFrom = null} = {}) { let held = null, accepted = false; const onAccepted = () => { accepted = true; }; try { - lastQueueError = null; failure.clear(); node.freevideoFailure = ''; node.freevideoFailureReport = null; + stopNote = ''; lastQueueError = null; failure.clear(); node.freevideoFailure = ''; node.freevideoFailureReport = null; capturing = true; updateRunButton(); status.dataset.error = 'false'; runOptions.open = false; lengthControl.freeze(); if ((!extension.source || prompt.value.trim()) && await enhancer.beforeGenerate() === false) return; @@ -1604,8 +1619,10 @@ export function openStudio(node, {extendFrom = null} = {}) { capturing = false; for (const section of controls.querySelectorAll('.fv-section')) section.inert = false; if (lengthPlan?.count > 1) { + const waitingBefore = chainController.waiting; const chain = await chainController.start(snapshot, lengthOptions, {onAccepted}); if (disposed) return; + if (chain && chainController.waiting > waitingBefore) { status.dataset.error = 'false'; status.textContent = addedNote; return; } if (!chain) { if (source) throw new Error(extendText(t, 'unavailable')); lengthControl.fallback(); if (!seconds.reportValidity()) return; await queueController.start(snapshot, {count: batchCount, repeat: chosenMode === 'loop', seedIndex, onAccepted}); } } else await queueController.start(snapshot, {count: batchCount, repeat: chosenMode === 'loop', seedIndex, onAccepted}); @@ -1685,6 +1702,10 @@ export function openStudio(node, {extendFrom = null} = {}) { b.append(el('span', null, 'fv-shape-icon'), el('span', label)); shapes.append(b); } mp.onchange = () => { try { pixels = Number(mp.value); applySize(); if (pixels !== 1) legacyOption?.remove(); } catch (error) { status.dataset.error = 'true'; status.textContent = error.message; } }; + // The note describes the request just sent; once the draft changes it could read as the new one. + const addedNote = t('Added to the queue. It starts when the current video finishes.', '已加入队列,当前视频完成后自动开始。'); + const clearAddedNote = () => { if (status.textContent === addedNote) status.textContent = ''; }; + seconds.addEventListener('input', clearAddedNote); prompt.addEventListener('input', clearAddedNote); seconds.onchange = () => { if (lengthControl.commit({report: false})) updateCanvas(); }; const mediaChanged = async e => { if (String(e.detail) !== String(mediaNode?.id)) return; refreshEffortEstimate(true); if (selected !== 'input') return; try { await inputRatio(); } catch (error) { status.textContent = error.message; } }; const lorasChanged = e => { if (String(e.detail) === String(loraNode?.id)) refreshEffortEstimate(true); }; diff --git a/web/studio_chain.js b/web/studio_chain.js index 87cbeaac..88b74c31 100644 --- a/web/studio_chain.js +++ b/web/studio_chain.js @@ -3,6 +3,7 @@ import {buildChainRequest} from './length_plan.js?v=20261011-length'; export const CHAIN_PROPERTY = 'freevideo_chain'; const activeStates = new Set(['queued', 'running', 'cancelling']); +const MAX_WAITING = 5; const finite = value => typeof value === 'number' && Number.isFinite(value) && value >= 0; const post = body => ({method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(body)}); @@ -55,14 +56,17 @@ export function singleRunSnapshot(snapshot, node, plan) { export function createStudioChain({api, node, onState = () => {}, onProgress = () => {}, onResult = () => {}, onError = () => {}, pollMs = 2000, now = () => Date.now()}) { - let chain = null, poller = null, disposed = false, epoch = 0, submitting = false; + let chain = null, poller = null, disposed = false, epoch = 0, submitting = false, promoting = false; + // Chains the server took while another was running; the next one is shown when the running one stops. + const waiting = []; let previous = {}, lastMessage = {}, delivered = null, errorShown = null, corrected = false, etaAt = 0, lastIndex = -1; const timers = new Set(); const clock = {now, setTimeout(fn, ms) { const id = setTimeout(() => { timers.delete(id); fn(); }, ms); timers.add(id); return id; }, clearTimeout(id) { clearTimeout(id); timers.delete(id); }}; function clearPolls() { for (const id of timers) clearTimeout(id); timers.clear(); } function refresh() { clearPolls(); return poller?.poll(); } - const active = () => submitting || activeStates.has(chain?.state) || chain?.output_state === 'joining'; + const running = () => activeStates.has(chain?.state) || chain?.output_state === 'joining'; + const active = () => submitting || running(); async function json(path, options, allowMissing = false) { const response = await api.fetchApi(path, options); if (response.status === 404 && allowMissing) return null; @@ -102,6 +106,7 @@ export function createStudioChain({api, node, onState = () => {}, onProgress = ( chain = value; onState(chain); const result = readChainResult(chain); if (active()) progress({}, fresh); + else if (waiting.length) void promote(); if (result.error && errorShown !== result.error) { errorShown = result.error; onError(Object.assign(new Error(result.error), {joining: chain.output_state === 'failed', ...chainPosition(chain)})); } @@ -116,6 +121,24 @@ export function createStudioChain({api, node, onState = () => {}, onProgress = ( } return active(); } + async function promote() { + if (promoting || disposed) return; + promoting = true; + let again = false; + try { + while (waiting.length && !disposed && !running()) { + const next = waiting[0]; + let value; + try { value = (await json(chainRoute(next.id), {cache: 'no-store'}, true))?.chain; } + catch { again = true; break; } + waiting.shift(); + if (!value?.id || value.state === 'cancelled') continue; + adopt(value, next.metadata); break; + } + } finally { promoting = false; } + if (again && !disposed) clock.setTimeout(() => void promote(), 3000); + else if (!disposed && chain) onState(chain); + } function watch(fresh = false) { poller?.dispose(); clearPolls(); const id = chain.id, version = epoch; @@ -135,9 +158,10 @@ export function createStudioChain({api, node, onState = () => {}, onProgress = ( const known = node.properties?.[CHAIN_PROPERTY]?.id; const reply = await json('/freevideo/chains', undefined, true); if (disposed || version !== epoch || chain) return; - const found = reply?.chains?.find(row => String(row.node) === String(node.id) && (known ? row.id === known - : activeStates.has(row.state) && row.client_id && row.client_id === api.clientId)); + const mine = row => String(row.node) === String(node.id) && activeStates.has(row.state) && row.client_id && row.client_id === api.clientId; + const found = reply?.chains?.find(row => String(row.node) === String(node.id) && (known ? row.id === known : mine(row))); if (!found) return; + for (const row of reply.chains) if (row.id !== found.id && mine(row)) waiting.push({id: row.id, metadata: null}); const value = (await json(chainRoute(found.id), undefined, true))?.chain; if (disposed || version !== epoch || chain || !value) return; adopt(value); @@ -177,10 +201,12 @@ export function createStudioChain({api, node, onState = () => {}, onProgress = ( } recover(); return { - get active() { return active(); }, get state() { return chain; }, + get active() { return active(); }, get state() { return chain; }, get waiting() { return waiting.length; }, + // A chain that is running does not stop the next one from being added behind it. + get canQueue() { return !disposed && !submitting && running() && chain?.state !== 'cancelling' && waiting.length < MAX_WAITING; }, async start(snapshot, options, {onAccepted = null} = {}) { - if (disposed || active()) throw new Error('chain_busy'); - submitting = true; epoch++; + if (disposed || submitting || (running() && waiting.length >= MAX_WAITING)) throw new Error('chain_busy'); + submitting = true; try { const body = buildChainRequest(options, {node: node.id, prompt: snapshot.output, extra_data: {extra_pnginfo: {workflow: snapshot.workflow || {}}}, ...(api.clientId ? {client_id: api.clientId} : {})}); @@ -189,7 +215,10 @@ export function createStudioChain({api, node, onState = () => {}, onProgress = ( if (!value.id) throw new Error('chain_missing'); onAccepted?.(); const inputs = snapshot.output[String(node.id)].inputs; - submitting = false; adopt(value, {width: inputs.width, height: inputs.height, seconds: options.seconds}); + const metadata = {width: inputs.width, height: inputs.height, seconds: options.seconds}; + submitting = false; + if (running() && chain.id !== value.id) { waiting.push({id: value.id, metadata}); onState(chain); return value; } + epoch++; adopt(value, metadata); return value; } finally { submitting = false; } }, From 244531fba1c65420dd8f927c34bc9a30704831b2 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:45 +0000 Subject: [PATCH 12/21] Editor: flag an unreadable reference picture right away --- web/editor.css | 2 ++ web/editor.js | 12 ++++++------ web/editor_genbar.js | 16 +++++++++++++--- web/editor_references.js | 12 ++++++++++++ 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/web/editor.css b/web/editor.css index 7d2cfb2e..f796eee9 100644 --- a/web/editor.css +++ b/web/editor.css @@ -98,6 +98,8 @@ .fv-ed-genbar{position:relative} .fv-ed-refs{display:flex;align-items:center;gap:6px;flex:none} .fv-ed-refs[hidden],.fv-ed-ref-menu[hidden]{display:none} +.fv-ed-ref-notice{position:absolute;bottom:calc(100% + 8px);max-width:min(560px,calc(100% - 24px));border:1px solid var(--fv-border);background:var(--fv-card);padding:10px 14px;border-radius:8px;z-index:9;color:var(--fv-ink);pointer-events:none} +.fv-ed-ref-notice[hidden]{display:none} .fv-ed-ref-chips{display:flex;align-items:center;gap:6px;max-width:min(240px,32vw);overflow-x:auto;scrollbar-width:thin;scrollbar-color:var(--fv-border) transparent;padding:1px} .fv-ed-ref-chips:empty{display:none} /* A strip that scrolls fades at the hidden end(s); one that fits is untouched. */ diff --git a/web/editor.js b/web/editor.js index 71b52787..44230bfb 100644 --- a/web/editor.js +++ b/web/editor.js @@ -272,11 +272,11 @@ export function openEditor({api, app, from = null, panel = {}, components: given } const content = record => JSON.stringify({...record, id: null, revision: 0}); function notify(text) { if (disposed) return; if (!text) { clearTimeout(noticeTimer); notice.hidden = true; return; } notice.textContent = text; notice.hidden = false; clearTimeout(noticeTimer); noticeTimer = setTimeout(() => { notice.hidden = true; }, 9000); } - // `step` names what was being done, so a failure there says which step went wrong. - function error(value, step = null) { + // `step` names what was being done, so a failure there says which step went wrong; `out` is where the line is said (the bar's own line for a reference picture). + function error(value, step = null, out = notify) { const code = value?.reason || value?.code || value?.message; if (['missing_glyphs', 'MissingGlyphs', 'source_missing'].includes(code)) { - notify(code === 'source_missing' ? t('A source file is missing. Import it again from the library.', '有素材的原文件找不到了,请在素材库重新导入。') + out(code === 'source_missing' ? t('A source file is missing. Import it again from the library.', '有素材的原文件找不到了,请在素材库重新导入。') : t('The chosen font is missing some characters. Choose another font.', '所选字体缺少部分字符,请换一种字体。')); return {ok: false, reason: code}; } @@ -286,7 +286,7 @@ export function openEditor({api, app, from = null, panel = {}, components: given const [en, zh] = (value.said || []).map(text => typeof text === 'string' && text ? text.slice(0, 200) : null); const text = code === 'chain_too_long' ? t(en || 'This video can have up to 5 parts. Make it shorter.', zh || '这条视频最多 5 段,请缩短一些。') : t(en || 'Each continued part must be at least 10 seconds. Make it longer.', zh || '接着生成的每一段至少 10 秒,请加长一些。'); - notify(text); return {ok: false, reason: code, say: text}; + out(text); return {ok: false, reason: code, say: text}; } if (['busy', 'locked', 'text', 'audio_full', 'overlap', 'range', 'no_audio'].includes(code)) { if (['locked', 'audio_full', 'overlap', 'range'].includes(code)) tracks?.flashBlocked?.(value.displayFrame); @@ -294,11 +294,11 @@ export function openEditor({api, app, from = null, panel = {}, components: given text: t('Write a description first.', '先写一句描述。'), overlap: t('That spot is taken. Use an empty spot.', '这里已经有片段了,请放到空白处。'), audio_full: t('Both audio tracks are full here. Move an audio clip first.', '这里两条声音轨都满了,请先挪开一段声音。'), no_audio: t('This clip has no sound. Please choose one with sound.', '这个素材没有声音,请选一段有声音的。')}[code]; - if (said) notify(said); + if (said) out(said); return {ok: false, reason: code}; } const text = step === 'generate' ? editorErrorText(value, t) : step === 'export' ? exportErrorText(value, t) : t('Could not complete. Try again.', '没有完成,请重试'); - notify(text); return {ok: false, reason: code, say: text}; + out(text); return {ok: false, reason: code, say: text}; } const store = createEditorStore(api, {t, notify, standIn: given?.generationStandIn, onGenerationReady: ready => { if (disposed) return; diff --git a/web/editor_genbar.js b/web/editor_genbar.js index 2642e18f..0ee29048 100644 --- a/web/editor_genbar.js +++ b/web/editor_genbar.js @@ -59,8 +59,18 @@ export function createEditorGenbar(host, {state, t, actions, text = ''}) { failureBar.append(failureReason, report); failure.append(failureBar); failure.hidden = true; host.append(failure); let failureId = null, downloading = false; // Reference pictures for a part that starts fresh: thumbnails and a small "+" before the description. - const references = actions.references ? createEditorReferences({t, source: actions.references.source, size: actions.references.size, error: actions.error, notify: actions.references.notify}) : null; - if (references) description.before(references.element); + // What goes wrong with a reference picture is said above the "+", where the eyes are, not in the page-wide line. + const refNotice = el('div', 'fv-ed-ref-notice'); refNotice.hidden = true; refNotice.setAttribute('role', 'status'); + let refNoticeTimer = null; + const sayAtRefs = text => { + clearTimeout(refNoticeTimer); + if (!text || disposed) { refNotice.hidden = true; return; } + refNotice.textContent = text; refNotice.hidden = false; + refNotice.style.left = Math.max(0, (references?.element.getBoundingClientRect().left || 0) - host.getBoundingClientRect().left) + 'px'; + refNoticeTimer = setTimeout(() => { refNotice.hidden = true; }, 9000); + }; + const references = actions.references ? createEditorReferences({t, source: actions.references.source, size: actions.references.size, error: value => actions.error(value, null, sayAtRefs), notify: sayAtRefs}) : null; + if (references) { description.before(references.element); host.append(refNotice); } let status = null, serial = 0, disposed = false, pressing = new Set(), previewSelection = null, estimateCache = null, noteTimer = null, queuedAt = null; // Which parts are generating, or how the job ended: a "Queued" line goes once this moves on. const progressKey = () => ['done', 'failed', 'cancelled', 'interrupted'].includes(status?.state) ? status.state @@ -223,7 +233,7 @@ export function createEditorGenbar(host, {state, t, actions, text = ''}) { }); render(); return {element: host, say, downloadFailure, getText() { expand.commit(); return input.value; }, update(value) { status = value; render(); }, preview(selection) { previewSelection = selection; render(); }, setText(value) { input.value = value || ''; state.setRangeText(input.value); render(); }, - dispose() { disposed = true; ++serial; clearTimeout(noteTimer); unsubscribe(); resize?.disconnect(); expand.dispose(); references?.dispose(); assets?.dispose(); }}; + dispose() { disposed = true; ++serial; clearTimeout(noteTimer); clearTimeout(refNoticeTimer); unsubscribe(); resize?.disconnect(); expand.dispose(); references?.dispose(); assets?.dispose(); }}; } // A missing optional module leaves the editor's existing progress in place. diff --git a/web/editor_references.js b/web/editor_references.js index 9dbb7903..df8044f6 100644 --- a/web/editor_references.js +++ b/web/editor_references.js @@ -69,15 +69,27 @@ export function createEditorReferences({t, source, size = () => null, error = () return holder; }; const write = rows => { try { source.write(rows); } catch (value) { error(value); } }; + // A picture the page cannot draw would only fail minutes later, in the engine; tiff is not drawn by every browser, so it goes on unchecked. + const readable = async file => { + if (!/\.(png|jpe?g|webp|bmp)$/i.test(file.name || '')) return true; + if (typeof Image !== 'function') return true; + const url = URL.createObjectURL(file), image = new Image(); + try { image.src = url; await image.decode(); return image.naturalWidth > 0 && image.naturalHeight > 0; } + catch { return false; } + finally { URL.revokeObjectURL(url); } + }; async function addFiles(files) { if (working) return; working = true; update(); + let skipped = false; try { for (const file of files) { if (full()) break; + if (!await readable(file)) { skipped = true; continue; } const result = await source.upload(file); write([...source.rows(), {file: result.file, role: 'reference', enabled: true}]); } + if (skipped && !disposed) notify(t('Could not read this picture. Please choose another one.', '无法读取这张图片,请换一张。')); } catch (value) { error(value); } finally { working = false; picker.value = ''; update(); } } From ce7954ca1782bf40f315b91ab3c6d05f4d6e8ebb Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:46 +0000 Subject: [PATCH 13/21] Picture editing inside a selected region by box, click or outline --- freevideo_engine/image_gen/failure.py | 7 +- freevideo_engine/image_gen/image_models.json | 25 + freevideo_engine/image_gen/image_pack.py | 104 +- freevideo_engine/image_gen/image_runner.py | 6 +- freevideo_engine/image_gen/qwen_pipeline.py | 28 +- freevideo_engine/image_gen/region_edit.py | 90 ++ freevideo_engine/image_gen/segment.py | 116 +++ freevideo_engine/image_gen/segment_worker.py | 81 ++ freevideo_engine/image_gen/service.py | 204 +++- freevideo_engine/image_gen/worker.py | 6 +- freevideo_engine/licenses/SAM2-Apache-2.0.txt | 201 ++++ .../licenses/SAM2-THIRD_PARTY.txt | 21 + freevideo_engine/sam2/__init__.py | 8 + freevideo_engine/sam2/modeling/__init__.py | 5 + .../sam2/modeling/backbones/__init__.py | 5 + .../sam2/modeling/backbones/hieradet.py | 316 ++++++ .../sam2/modeling/backbones/image_encoder.py | 134 +++ .../sam2/modeling/backbones/utils.py | 93 ++ .../sam2/modeling/memory_attention.py | 169 ++++ .../sam2/modeling/memory_encoder.py | 181 ++++ .../sam2/modeling/position_encoding.py | 239 +++++ .../sam2/modeling/sam/__init__.py | 5 + .../sam2/modeling/sam/mask_decoder.py | 295 ++++++ .../sam2/modeling/sam/prompt_encoder.py | 202 ++++ .../sam2/modeling/sam/transformer.py | 310 ++++++ freevideo_engine/sam2/modeling/sam2_base.py | 909 ++++++++++++++++++ freevideo_engine/sam2/modeling/sam2_utils.py | 323 +++++++ freevideo_engine/sam2/sam2_image_predictor.py | 449 +++++++++ freevideo_engine/sam2/utils/__init__.py | 5 + freevideo_engine/sam2/utils/amg.py | 348 +++++++ freevideo_engine/sam2/utils/misc.py | 349 +++++++ freevideo_engine/sam2/utils/transforms.py | 118 +++ web/image_editor.css | 4 +- web/image_editor.js | 142 ++- web/image_editor_engine.js | 79 ++ web/image_generation.js | 64 +- 36 files changed, 5514 insertions(+), 127 deletions(-) create mode 100644 freevideo_engine/image_gen/region_edit.py create mode 100644 freevideo_engine/image_gen/segment.py create mode 100644 freevideo_engine/image_gen/segment_worker.py create mode 100644 freevideo_engine/licenses/SAM2-Apache-2.0.txt create mode 100644 freevideo_engine/licenses/SAM2-THIRD_PARTY.txt create mode 100644 freevideo_engine/sam2/__init__.py create mode 100644 freevideo_engine/sam2/modeling/__init__.py create mode 100644 freevideo_engine/sam2/modeling/backbones/__init__.py create mode 100644 freevideo_engine/sam2/modeling/backbones/hieradet.py create mode 100644 freevideo_engine/sam2/modeling/backbones/image_encoder.py create mode 100644 freevideo_engine/sam2/modeling/backbones/utils.py create mode 100644 freevideo_engine/sam2/modeling/memory_attention.py create mode 100644 freevideo_engine/sam2/modeling/memory_encoder.py create mode 100644 freevideo_engine/sam2/modeling/position_encoding.py create mode 100644 freevideo_engine/sam2/modeling/sam/__init__.py create mode 100644 freevideo_engine/sam2/modeling/sam/mask_decoder.py create mode 100644 freevideo_engine/sam2/modeling/sam/prompt_encoder.py create mode 100644 freevideo_engine/sam2/modeling/sam/transformer.py create mode 100644 freevideo_engine/sam2/modeling/sam2_base.py create mode 100644 freevideo_engine/sam2/modeling/sam2_utils.py create mode 100644 freevideo_engine/sam2/sam2_image_predictor.py create mode 100644 freevideo_engine/sam2/utils/__init__.py create mode 100644 freevideo_engine/sam2/utils/amg.py create mode 100644 freevideo_engine/sam2/utils/misc.py create mode 100644 freevideo_engine/sam2/utils/transforms.py diff --git a/freevideo_engine/image_gen/failure.py b/freevideo_engine/image_gen/failure.py index ff30ff5c..a29582f7 100644 --- a/freevideo_engine/image_gen/failure.py +++ b/freevideo_engine/image_gen/failure.py @@ -15,8 +15,8 @@ ERRORS = frozenset(('no_memory', 'busy_video', 'busy', 'pack_missing', 'model_unreadable', 'device_unavailable', 'worker_exit', 'timeout', 'cancelled', - 'invalid_request', 'generation_failed')) -NO_REPORT = frozenset(('busy', 'invalid_request', 'cancelled')) + 'invalid_request', 'invalid_media', 'invalid_points', 'segment_not_installed', 'generation_failed')) +NO_REPORT = frozenset(('busy', 'invalid_request', 'invalid_media', 'invalid_points', 'segment_not_installed', 'cancelled')) STAGES = ('start', 'load', 'text', 'encode', 'denoise', 'decode') KINDS = ('generate', 'edit', 'cast', 'compose', 'download', 'install') MESSAGE_ZH = { @@ -30,6 +30,9 @@ 'timeout': '这一张用时太长,已停止。请再试一次。', 'generation_failed': '图像生成出错了,请再试一次。', 'invalid_request': '图片设置有误,请调整后重试。', + 'invalid_media': '图片无效,请重新选择输入目录中的图片。点选支持不超过 4096×4096 像素总数的图片。', + 'invalid_points': '请选择 1–16 个图片范围内的点,且至少有一个选中点;1 为选中,0 为排除。', + 'segment_not_installed': '点选模型未安装,请先下载点选模型(SAM 2.1 small)。', } _DEVICE = re.compile( r'cuda.*(?:initializ|device.*(?:lost|unavailable|removed)|invalid device ordinal|' diff --git a/freevideo_engine/image_gen/image_models.json b/freevideo_engine/image_gen/image_models.json index e7840ef2..129d9c1f 100644 --- a/freevideo_engine/image_gen/image_models.json +++ b/freevideo_engine/image_gen/image_models.json @@ -14,6 +14,31 @@ {"file": "processor/chat_template.jinja", "component": "processor", "bytes": 5292, "sha256": "3636d0f0bd6bef02654cdffdc447b79cb2cef8ab02cc75267345946291a489e4", "sources": [{"id": "official", "url": "https://huggingface.co/Qwen/Qwen-Image-2.1-Turbo/resolve/main/processor/chat_template.jinja"}, {"id": "hf-mirror", "url": "https://hf-mirror.com/Qwen/Qwen-Image-2.1-Turbo/resolve/main/processor/chat_template.jinja"}, {"id": "modelscope", "url": "https://www.modelscope.cn/models/Qwen/Qwen-Image-2.1-Turbo/resolve/master/processor/chat_template.jinja"}]}, {"file": "processor/processor_config.json", "component": "processor", "bytes": 1300, "sha256": "14932921ca485d458a04dafd8069fbb0a4505622a48208d19ed247115801385b", "sources": [{"id": "official", "url": "https://huggingface.co/Qwen/Qwen-Image-2.1-Turbo/resolve/main/processor/processor_config.json"}, {"id": "hf-mirror", "url": "https://hf-mirror.com/Qwen/Qwen-Image-2.1-Turbo/resolve/main/processor/processor_config.json"}, {"id": "modelscope", "url": "https://www.modelscope.cn/models/Qwen/Qwen-Image-2.1-Turbo/resolve/master/processor/processor_config.json"}]}, {"file": "processor/tokenizer_config.json", "component": "processor", "bytes": 705, "sha256": "fd42a0b35a8d13cd473e88e310b50cbf1bccaa9eb60ed0fd873af5f8f0c59307", "sources": [{"id": "official", "url": "https://huggingface.co/Qwen/Qwen-Image-2.1-Turbo/resolve/main/processor/tokenizer_config.json"}, {"id": "hf-mirror", "url": "https://hf-mirror.com/Qwen/Qwen-Image-2.1-Turbo/resolve/main/processor/tokenizer_config.json"}, {"id": "modelscope", "url": "https://www.modelscope.cn/models/Qwen/Qwen-Image-2.1-Turbo/resolve/master/processor/tokenizer_config.json"}]} + ], + "segment": [ + { + "file": "sam2/sam2.1_hiera_small.pt", + "component": "segment", + "bytes": 184416285, + "sha256": "6d1aa6f30de5c92224f8172114de081d104bbd23dd9dc5c58996f0cad5dc4d38", + "repo": "facebook/sam2.1-hiera-small", + "revision": "main", + "model_id": "sam2.1-hiera-small", + "sources": [ + { + "id": "official", + "url": "https://huggingface.co/facebook/sam2.1-hiera-small/resolve/main/sam2.1_hiera_small.pt" + }, + { + "id": "hf-mirror", + "url": "https://hf-mirror.com/facebook/sam2.1-hiera-small/resolve/main/sam2.1_hiera_small.pt" + }, + { + "id": "modelscope", + "url": "https://www.modelscope.cn/models/facebook/sam2.1-hiera-small/resolve/master/sam2.1_hiera_small.pt" + } + ] + } ] } } diff --git a/freevideo_engine/image_gen/image_pack.py b/freevideo_engine/image_gen/image_pack.py index 3f9a4bc4..9e0b7e5f 100644 --- a/freevideo_engine/image_gen/image_pack.py +++ b/freevideo_engine/image_gen/image_pack.py @@ -138,17 +138,22 @@ def validate_catalog(spec): or not isinstance(spec['repo'], str) or not spec['repo'] or not isinstance(spec['revision'], str) or not spec['revision']): raise PackError('invalid_catalog') - found = spec['groups']['image'] - if not found or len({r['file'] for r in found}) != len(found): + image_rows = spec['groups']['image'] + segment_rows = spec['groups'].get('segment', []) + found = image_rows + segment_rows + if (not image_rows or len({r['file'] for r in found}) != len(found) + or any(row['component'] == 'segment' for row in image_rows) + or any(row['component'] != 'segment' for row in segment_rows)): raise PackError('invalid_catalog') for row in found: _relative(row['file']) if (type(row['bytes']) is not int or row['bytes'] <= 0 or not re.fullmatch('[0-9a-f]{64}', row['sha256']) - or row['component'] not in ('dit', 'text_encoder', 'vae', 'text_encoder_config', 'processor')): + or row['component'] not in ('dit', 'text_encoder', 'vae', 'text_encoder_config', 'processor', 'segment')): raise PackError('invalid_catalog') ids = [s['id'] for s in row['sources']] - if (len(set(ids)) != len(ids) or not {'official', 'modelscope'} <= set(ids) + required = {'official', 'modelscope'} + if (len(set(ids)) != len(ids) or not required <= set(ids) or not set(ids) <= {'official', 'modelscope', 'hf-mirror'}): raise PackError('invalid_catalog') for source in row['sources']: @@ -159,11 +164,13 @@ def validate_catalog(spec): raise PackError('invalid_catalog') from error -def rows(spec=None): +def rows(spec=None, *, group='image'): spec = spec if spec is not None else catalog() validate_catalog(spec) - return [dict(row, family='image', model_id=spec['model_id'], repo=spec['repo'], revision=spec['revision']) - for row in spec['groups']['image']] + groups = spec['groups'].values() if group is None else [spec['groups'][group]] + return [dict(row, family='image', model_id=row.get('model_id', spec['model_id']), + repo=row.get('repo', spec['repo']), revision=row.get('revision', spec['revision'])) + for found in groups for row in found] def base(root=None): @@ -216,27 +223,30 @@ def _owned_intact(path, stamp): # for people reading the source and is never needed at run time. NOTICE_TEXT = (b'Qwen is licensed under the Qwen RESEARCH LICENSE AGREEMENT, Copyright (c) 2026 Hangzhou Tongyi ' b'Laboratory Technology Co., Ltd. All Rights Reserved.\n') +SEGMENT_NOTICE_TEXT = (b'SAM 2.1 Hiera small, Copyright (c) Meta Platforms, Inc. and affiliates.\n' + b'Licensed under Apache-2.0; see freevideo_engine/licenses/SAM2-Apache-2.0.txt.\n' + b'https://github.com/facebookresearch/sam2\n') def _notice(): return NOTICE_TEXT -def _notice_ready(path): +def _notice_ready(path, *, group='image'): """Informational only: a missing or different notice never makes the pack unusable.""" try: - return path.is_file() and path.read_bytes() == NOTICE_TEXT + return path.is_file() and path.read_bytes() == (SEGMENT_NOTICE_TEXT if group == 'segment' else NOTICE_TEXT) except OSError: return False -def _write_notice(folder, owned): +def _write_notice(folder, owned, *, group='image'): """Put the notice into the model folder when possible; a failure is logged and the install goes on.""" try: - notice = _path(folder, 'NOTICE.txt') + notice = _path(folder, 'SAM2-NOTICE.txt' if group == 'segment' else 'NOTICE.txt') if notice.exists(): return # present (ours or the user's own text): left as it is - notice.write_bytes(NOTICE_TEXT) + notice.write_bytes(SEGMENT_NOTICE_TEXT if group == 'segment' else NOTICE_TEXT) _own(folder, owned, notice) except Exception as error: logging.warning('[FreeVideo] Could not write the image model notice: %s', redacted_launcher_error(error)) @@ -277,7 +287,7 @@ def _recheck(root, folder, pending): try: stamps = deepcopy(_read(folder, LEDGER)) results = [] - for row in rows(): + for row in rows(group=None): path = target(row, root) name = str(path) if name in pending and _stale(path, row, stamps): @@ -349,13 +359,13 @@ def _start_recheck(root, folder, stale): return True -def status(root=None): +def status(root=None, *, group='image'): """Missing files and unique retained bytes; no network and no weight reads on this thread.""" folder = base(root) ledger = _read(folder, LEDGER) files, missing, downloaded, verified_bytes = [], [], 0, 0 stale = [] - for row in rows(): + for row in rows(group=group): path = target(row, root) intact = _intact(path, row, ledger) old = not intact and _stale(path, row, ledger) @@ -372,7 +382,7 @@ def status(root=None): files.append(dict(file=row['file'], bytes=row['bytes'], ready=intact, downloaded_bytes=retained, stale=old)) checking = bool(stale) and _start_recheck(root, folder, stale) try: - notice_ready = _notice_ready(_path(folder, 'NOTICE.txt')) + notice_ready = _notice_ready(_path(folder, 'SAM2-NOTICE.txt' if group == 'segment' else 'NOTICE.txt'), group=group) except PackError: notice_ready = False total = sum(r['bytes'] for r in files) @@ -391,8 +401,8 @@ def checking(root=None) -> bool: return base(root) in _RECHECKS -def ready(root=None): - return status(root)['ready'] +def ready(root=None, *, group='image'): + return status(root, group=group)['ready'] def downloading(root=None, engine_root=None) -> bool: @@ -444,19 +454,19 @@ def _lease(root, engine_root=None, destructive=False): yield folder -def verify(root=None, progress=None, check=None): +def verify(root=None, progress=None, check=None, *, group='image'): """Explicit full integrity check; bad stamps are discarded, files are kept.""" with _lease(root) as folder: - _verify(folder, root, progress or (lambda v: None), check or (lambda: None), full=True) - return status(root) + _verify(folder, root, progress or (lambda v: None), check or (lambda: None), full=True, group=group) + return status(root, group=group) -def _verify(folder, root, progress, check, full=False): +def _verify(folder, root, progress, check, full=False, *, group='image'): ledger = _read(folder, LEDGER) todo = [] - total = sum(r['bytes'] for r in rows()) + total = sum(r['bytes'] for r in rows(group=group)) done = 0 - for row in rows(): + for row in rows(group=group): check() path = target(row, root) hashed = False @@ -559,14 +569,14 @@ def resource_check(): raise PackError(reason) from error -def install(root=None, progress=None, check=None, *, engine_root=None, repair=False, _background=None): +def install(root=None, progress=None, check=None, *, engine_root=None, repair=False, _background=None, group='image'): """Install only missing weights. Repair also hashes and retains bad originals.""" progress = progress or (lambda v: None) check = check or (lambda: None) transfer_check = _background.check if _background is not None else check try: with _lease(root, engine_root, destructive=repair) as folder: - ledger, todo = _verify(folder, root, progress, check, full=repair) + ledger, todo = _verify(folder, root, progress, check, full=repair, group=group) total = sum(r['bytes'] for r in todo) retained = 0 for row in todo: @@ -581,11 +591,11 @@ def install(root=None, progress=None, check=None, *, engine_root=None, repair=Fa plan = _download_plan(engine_root) plan.update(quiet=True, resource_check=check) owned = _read(folder, OWNERSHIP) - _write_notice(folder, owned) + _write_notice(folder, owned, group=group) done = 0 pending_prefixes = 0 if _background is not None: - done = sum(r['bytes'] for r in rows()) - total + done = sum(r['bytes'] for r in rows(group=group)) - total total += done pending_prefixes = sum(min(row['bytes'], _path(folder, row['file'] + '.partial').stat().st_size) for row in todo if _path(folder, row['file'] + '.partial').is_file()) @@ -624,7 +634,7 @@ def moved(current, size, speed, **kwargs): done += row['bytes'] progress(dict(phase='download', done=done + pending_prefixes, total=total)) check() - return status(root) + return status(root, group=group) except (PackError, InterruptedError): raise except BlockingIOError as error: @@ -633,18 +643,19 @@ def moved(current, size, speed, **kwargs): raise PackError('download_failed') from error -def repair(root=None, progress=None, check=None, *, engine_root=None): - return install(root, progress, check, engine_root=engine_root, repair=True) +def repair(root=None, progress=None, check=None, *, engine_root=None, group='image'): + return install(root, progress, check, engine_root=engine_root, repair=True, group=group) -def removal_plan(root=None): +def removal_plan(root=None, *, group='image'): folder = base(root) owned = _read(folder, OWNERSHIP) - allowed = {'NOTICE.txt'} - for row in rows(): + notice = 'SAM2-NOTICE.txt' if group == 'segment' else 'NOTICE.txt' + allowed = {notice} + for row in rows(group=group): allowed.update((row['file'], row['file'] + '.partial', row['file'] + '.partial.source.json')) for name in allowed: - if name == 'NOTICE.txt': + if name == notice: continue _path(folder, name) files, skipped = [], [] @@ -654,7 +665,7 @@ def removal_plan(root=None): try: path = _path(folder, name) except PackError: - if name != 'NOTICE.txt': + if name != notice: raise skipped.append(name) continue @@ -667,12 +678,12 @@ def removal_plan(root=None): return dict(files=files, bytes=sum(f['bytes'] for f in files), skipped=skipped) -def remove(root=None, check=None, *, engine_root=None): +def remove(root=None, check=None, *, engine_root=None, group='image'): """Delete our unchanged downloads/partials/notice; keep imports and repairs.""" check = check or (lambda: None) try: with _lease(root, engine_root, destructive=True) as folder: - plan = removal_plan(root) + plan = removal_plan(root, group=group) owned, ledger = _read(folder, OWNERSHIP), _read(folder, LEDGER) released, removed = 0, [] for entry in plan['files']: @@ -696,8 +707,9 @@ def remove(root=None, check=None, *, engine_root=None): class Installer: """One background action per pack; cancel keeps completed files and prefixes.""" - def __init__(self, root=None, *, engine_root=None, busy=None): + def __init__(self, root=None, *, engine_root=None, busy=None, group='image'): self.root, self.engine_root = root, engine_root + self.group = group self.generation_busy = busy self.lock = threading.Lock() self.stop = threading.Event() @@ -805,9 +817,11 @@ def check(): try: control = _Background(self, stop) if background else None if background: - initial = status(self.root) + initial = status(self.root, group=self.group) self._set(done=initial['downloaded_bytes'], total=initial['total_bytes']) options = dict(root=self.root, check=control.wait if control else check) + if self.group != 'image': + options['group'] = self.group if control: options['_background'] = control if action != 'verify': @@ -833,11 +847,11 @@ def _failed(self, action, error): code = image_pack_error_code(error) try: spec = catalog() - entries = rows(spec) + entries = rows(spec, group=self.group) except Exception: spec, entries = {}, [] try: - pack = status(self.root) + pack = status(self.root, group=self.group) except Exception: pack = dict(ready=False, files=[], missing=[], downloaded_bytes=0) with self.lock: @@ -853,7 +867,8 @@ def _failed(self, action, error): file.update(checks.get(row['file'], {})) files.append(file) pack = {k: pack[k] for k in ('ready', 'missing', 'downloaded_bytes', 'verified_bytes', 'total_bytes') if k in pack} - pack.update(name=spec.get('model_id', 'image'), repo=spec.get('repo'), revision=spec.get('revision'), + identity = entries[0] if entries and self.group == 'segment' else spec + pack.update(name=identity.get('model_id', 'image'), repo=identity.get('repo'), revision=identity.get('revision'), format=spec.get('format'), files=files, transferred_bytes=downloaded, sources=[dict(file=row['file'], id=s['id'], host=urlsplit(s['url']).hostname) for row in entries for s in row['sources']], events=events) @@ -901,6 +916,7 @@ def main(argv=None): commands = parser.add_subparsers(dest='command', required=True) download = commands.add_parser('download') download.add_argument('--background', action='store_true') + download.add_argument('--group', choices=('image', 'segment'), default='image') download.add_argument('--root', type=Path) download.add_argument('--engine-root', type=Path) download.add_argument('--status-file', type=Path, required=True) @@ -915,7 +931,7 @@ def main(argv=None): print('Image pack status is unavailable.', file=sys.stderr) return 1 - installer = Installer(args.root, engine_root=args.engine_root) + installer = Installer(args.root, engine_root=args.engine_root, group=args.group) received = threading.Event() def cancelled(signum, frame): received.set() diff --git a/freevideo_engine/image_gen/image_runner.py b/freevideo_engine/image_gen/image_runner.py index e96c8002..07546fdf 100644 --- a/freevideo_engine/image_gen/image_runner.py +++ b/freevideo_engine/image_gen/image_runner.py @@ -223,7 +223,8 @@ def plan(self, width, height, reference_images=None): gpu_budget_bytes=self.budget(), host_available_bytes=host_available, width=width, height=height, reference_pixels=reference_pixels, shape=self.shape) - def generate(self, prompt, *, width, height, seed=None, reference_images=None, progress=None, cancel=None): + def generate(self, prompt, *, width, height, seed=None, reference_images=None, edit_mask=None, + progress=None, cancel=None): plan = self.plan(width, height, reference_images) self.last_plan = plan if not plan.feasible: @@ -233,7 +234,8 @@ def generate(self, prompt, *, width, height, seed=None, reference_images=None, p self.generator.vae_tile = plan.vae_tiling self.generator.vae_tile_size = plan.vae_tile_size return self.generator.generate(prompt, width=width, height=height, seed=seed, - reference_images=reference_images, progress=progress, cancel=cancel) + reference_images=reference_images, edit_mask=edit_mask, + progress=progress, cancel=cancel) def at_boundary(self): """False when a failure left a weights streamer inside a layer pass; the next request cannot use it.""" diff --git a/freevideo_engine/image_gen/qwen_pipeline.py b/freevideo_engine/image_gen/qwen_pipeline.py index 8bde8b50..15ebbc98 100644 --- a/freevideo_engine/image_gen/qwen_pipeline.py +++ b/freevideo_engine/image_gen/qwen_pipeline.py @@ -257,7 +257,7 @@ def _reference_inputs(self, images): @torch.no_grad() def generate(self, prompt: str, *, width: int, height: int, seed: int | None = None, steps: int = 8, - reference_images=None, progress=None, cancel=None) -> Image.Image: + reference_images=None, edit_mask=None, progress=None, cancel=None) -> Image.Image: if self._closed: raise RuntimeError("Generator is closed") if not isinstance(prompt, str): @@ -267,6 +267,8 @@ def generate(self, prompt: str, *, width: int, height: int, seed: int | None = N if reference_images is not None and not isinstance(reference_images, list): raise ValueError("reference_images must be a flat list of PIL images") width, height = normalize_dimensions(width, height) + if edit_mask is not None and not reference_images: + raise ValueError("edit_mask needs a reference image: the first one is the picture being edited") def check_cancel(): if cancel is not None and cancel(): @@ -314,6 +316,21 @@ def report(stage, fraction): encoded = (encoded - mean) / std ref_latents.append(self._pack_latents(encoded, 1, channels, *encoded.shape[-2:]).to(embeds.dtype)) check_cancel() + keep_latents = cell_mask = None + if edit_mask is not None: + from . import region_edit + + original = reference_images[0].convert("RGBA") + with self._stage("encode"): + check_cancel() + resized = original.resize((width, height), Image.Resampling.LANCZOS) + array = np.asarray(resized, dtype=np.float32)[None] / 255.0 + tensor = torch.from_numpy(array).permute(0, 3, 1, 2).unsqueeze(2) * 2 - 1 + encoded = _encoded_latents(self.vae.encode(tensor.to(device=self.device, dtype=_dtype(self.vae)), tile=True)) + mean, std = self._stats(encoded) + keep_latents = self._pack_latents((encoded - mean) / std, 1, channels, *encoded.shape[-2:]).to(embeds.dtype) + cell_mask = torch.from_numpy(region_edit.latent_mask(edit_mask, (width, height))).to(self.device) + cell_mask = cell_mask.reshape(1, -1, 1) ref_latents = torch.cat(ref_latents, dim=1) if ref_latents else None ref_tokens = 0 if ref_latents is None else ref_latents.shape[1] if image_mask.sum().item() * 4 != ref_tokens: @@ -325,6 +342,7 @@ def report(stage, fraction): latents = torch.randn((1, 1, channels, latent_height, latent_width), generator=generator, device=self.device, dtype=embeds.dtype) latents = self._pack_latents(latents, 1, channels, latent_height, latent_width) + start_noise = latents.clone() if keep_latents is not None else None img_shapes = [[*[(1, h // 16, w // 16) for w, h in sizes], (1, latent_height, latent_width)]] image_mask = torch.cat([image_mask, image_mask.new_ones(1, latents.shape[1] // 4)], dim=1) sigmas = torch.tensor(self.sample_sigmas, device=self.device, dtype=torch.float32) @@ -348,6 +366,11 @@ def report(stage, fraction): ))[:, -latents.shape[1]:] check_cancel() latents = euler_step(latents, prediction, sigmas[i], sigmas[i + 1]) + if keep_latents is not None: + # Outside the selection the latent stays on the original's own path to this sigma. + s = sigmas[i + 1] + kept = (1 - s) * keep_latents.float() + s * start_noise.float() + latents = (cell_mask * latents.float() + (1 - cell_mask) * kept).to(prediction.dtype) report("denoise", (i + 1) / steps) check_cancel() @@ -366,6 +389,9 @@ def report(stage, fraction): check_cancel() array = (pixels / 2 + 0.5).clamp(0, 1).float().cpu().permute(0, 2, 3, 1).numpy()[0] image = Image.fromarray((array * 255).round().astype(np.uint8)) + if edit_mask is not None: + image = region_edit.composite(reference_images[0], image, + region_edit.blend_alpha(edit_mask, reference_images[0].size)) report("decode", 1.0) return image diff --git a/freevideo_engine/image_gen/region_edit.py b/freevideo_engine/image_gen/region_edit.py new file mode 100644 index 00000000..a1cb624c --- /dev/null +++ b/freevideo_engine/image_gen/region_edit.py @@ -0,0 +1,90 @@ +"""Edit only a selected region of a picture. + +The caller supplies the original picture and a mask (white = change). The +sampler keeps the unselected part of the latent on the original's own noise +path at every step, and the finished picture is blended over the original with +a feathered edge, so pixels outside the grown selection are the original's. +""" +import numpy as np +from PIL import Image, ImageDraw, ImageFilter + +LATENT_CELL = 16 +DEFAULT_GROW = 24 +DEFAULT_FEATHER = 16 + + +def _odd(radius): + return max(1, int(radius) * 2 + 1) + + +def grown_mask(mask, grow=DEFAULT_GROW): + """Mask as an L image, selection grown by ``grow`` pixels.""" + if not isinstance(mask, Image.Image): + raise ValueError("mask must be a PIL image") + mask = mask.convert("L").point(lambda v: 255 if v >= 128 else 0) + if grow > 0: + mask = mask.filter(ImageFilter.MaxFilter(_odd(grow))) + return mask + + +def lasso_mask(size, points): + """A drawn curve closed by joining its last point to its first, filled.""" + mask = Image.new("L", size, 0) + points = [(float(x), float(y)) for x, y in points] + if len(points) >= 3: + ImageDraw.Draw(mask).polygon(points, fill=255) + return mask + + +def combine_masks(size, added, removed=()): + """Union of the added selections minus the union of the removed ones (L images, 255 = selected).""" + result = np.zeros((size[1], size[0]), dtype=bool) + for mask in added: + result |= np.asarray(mask.convert("L").resize(size)) >= 128 + for mask in removed: + result &= ~(np.asarray(mask.convert("L").resize(size)) >= 128) + return Image.fromarray(result.astype(np.uint8) * 255, "L") + + +def selection_is_empty(mask): + return not np.asarray(mask.convert("L")).max() >= 128 + + +def latent_mask(mask, size, *, grow=DEFAULT_GROW, feather=DEFAULT_FEATHER): + """1.0 on the latent cells the model may change, else 0.0, shaped (rows, cols). + + Covers the grown selection plus the feather, so the soft edge of the final + blend lies inside regenerated content. + """ + width, height = size + base = grown_mask(mask.resize((width, height), Image.Resampling.NEAREST), grow + feather) + array = np.asarray(base, dtype=np.uint8) > 0 + rows, cols = height // LATENT_CELL, width // LATENT_CELL + cells = array[:rows * LATENT_CELL, :cols * LATENT_CELL].reshape(rows, LATENT_CELL, cols, LATENT_CELL) + return cells.any(axis=(1, 3)).astype(np.float32) + + +def blend_alpha(mask, size, *, grow=DEFAULT_GROW, feather=DEFAULT_FEATHER): + """Feathered 0..1 alpha at ``size``: 1 inside the grown selection, 0 beyond the feather.""" + resized = mask.resize(size, Image.Resampling.NEAREST) + soft = grown_mask(resized, grow).filter(ImageFilter.GaussianBlur(feather / 2)) + alpha = np.asarray(soft, dtype=np.float32) / 255.0 + # The blur is centred on the grown edge: widen so the alpha reaches 1 inside the selection + # and is exactly 0 where the latent mask no longer reaches. + hard = np.asarray(grown_mask(resized, grow + feather), dtype=np.uint8) > 0 + alpha = np.where(hard, alpha, 0.0) + return alpha + + +def composite(original, generated, alpha): + """Original pixels where alpha is 0; generated pixels (resized to the original) where 1.""" + original = original.convert("RGB") + if generated.size != original.size: + generated = generated.resize(original.size, Image.Resampling.LANCZOS) + src = np.asarray(original, dtype=np.float32) + new = np.asarray(generated.convert("RGB"), dtype=np.float32) + out = new * alpha[..., None] + src * (1.0 - alpha[..., None]) + result = np.asarray(original).copy() + changed = alpha > 0 + result[changed] = np.clip(np.rint(out[changed]), 0, 255).astype(np.uint8) + return Image.fromarray(result) diff --git a/freevideo_engine/image_gen/segment.py b/freevideo_engine/image_gen/segment.py new file mode 100644 index 00000000..a72b12bc --- /dev/null +++ b/freevideo_engine/image_gen/segment.py @@ -0,0 +1,116 @@ +"""CPU SAM 2.1 Hiera small; one pixel-hashed image encoding per worker.""" +import hashlib +import math + + +# Bound full-resolution candidate logits as well as image decompression. +MAX_PIXELS = 4096 * 4096 +MAX_POINTS = 16 + + +def validate_points(points, size=None): + if not isinstance(points, list) or not 1 <= len(points) <= MAX_POINTS: + raise ValueError('invalid_points') + for point in points: + if (not isinstance(point, (list, tuple)) or len(point) != 3 + or any(type(v) not in (int, float) or type(v) is float and not math.isfinite(v) + for v in point[:2]) + or type(point[2]) is not int or point[2] not in (0, 1) + or any(not 0 <= v < MAX_PIXELS for v in point[:2]) + or size is not None and (point[0] >= size[0] or point[1] >= size[1])): + raise ValueError('invalid_points') + if not any(p[2] for p in points): + raise ValueError('invalid_points') + + +def load_image(path): + from PIL import Image + try: + with Image.open(path) as image: + if image.width * image.height > MAX_PIXELS: + raise ValueError('invalid_media') + # Match region_edit: coordinates and output dimensions are stored pixels. + return image.convert('RGB') + except (OSError, ValueError, Image.DecompressionBombError) as error: + raise ValueError('invalid_media') from error + + +def build_model(checkpoint): + """Literal upstream sam2.1_hiera_s config, without Hydra or iopath.""" + import torch + from ..sam2.modeling.backbones.hieradet import Hiera + from ..sam2.modeling.backbones.image_encoder import ImageEncoder, FpnNeck + from ..sam2.modeling.position_encoding import PositionEmbeddingSine + from ..sam2.modeling.memory_attention import MemoryAttention, MemoryAttentionLayer + from ..sam2.modeling.memory_encoder import MemoryEncoder, MaskDownSampler, Fuser, CXBlock + from ..sam2.modeling.sam.transformer import RoPEAttention + from ..sam2.modeling.sam2_base import SAM2Base + + model = SAM2Base( + image_encoder=ImageEncoder(scalp=1, + trunk=Hiera(embed_dim=96, num_heads=1, stages=[1, 2, 11, 2], + global_att_blocks=[7, 10, 13], window_pos_embed_bkg_spatial_size=[7, 7]), + neck=FpnNeck(position_encoding=PositionEmbeddingSine(256, normalize=True, temperature=10000, warmup_cache=False), + d_model=256, backbone_channel_list=[768, 384, 192, 96], + fpn_top_down_levels=[2, 3], fpn_interp_model='nearest')), + memory_attention=MemoryAttention(d_model=256, pos_enc_at_input=True, num_layers=4, + layer=MemoryAttentionLayer(activation='relu', dim_feedforward=2048, dropout=.1, + pos_enc_at_attn=False, d_model=256, pos_enc_at_cross_attn_keys=True, + pos_enc_at_cross_attn_queries=False, + self_attention=RoPEAttention(rope_theta=10000., feat_sizes=[64, 64], + embedding_dim=256, num_heads=1, downsample_rate=1, dropout=.1), + cross_attention=RoPEAttention(rope_theta=10000., feat_sizes=[64, 64], rope_k_repeat=True, + embedding_dim=256, num_heads=1, downsample_rate=1, dropout=.1, kv_in_dim=64))), + memory_encoder=MemoryEncoder(out_dim=64, + position_encoding=PositionEmbeddingSine(64, normalize=True, temperature=10000, warmup_cache=False), + mask_downsampler=MaskDownSampler(kernel_size=3, stride=2, padding=1), + fuser=Fuser(layer=CXBlock(dim=256, kernel_size=7, padding=3, + layer_scale_init_value=1e-6, use_dwconv=True), num_layers=2)), + num_maskmem=7, image_size=1024, sigmoid_scale_for_mem_enc=20., sigmoid_bias_for_mem_enc=-10., + use_mask_input_as_output_without_sam=True, directly_add_no_mem_embed=True, + no_obj_embed_spatial=True, use_high_res_features_in_sam=True, multimask_output_in_sam=True, + iou_prediction_use_sigmoid=True, use_obj_ptrs_in_encoder=True, add_tpos_enc_to_obj_ptrs=True, + proj_tpos_enc_in_obj_ptrs=True, use_signed_tpos_enc_to_obj_ptrs=True, + only_obj_ptrs_in_the_past_for_eval=True, pred_obj_scores=True, pred_obj_scores_mlp=True, + fixed_no_obj_ptr=True, multimask_output_for_tracking=True, use_multimask_token_for_obj_ptr=True, + multimask_min_pt_num=0, multimask_max_pt_num=1, use_mlp_for_obj_ptr_proj=True, + compile_image_encoder=False) + state = torch.load(checkpoint, map_location='cpu', weights_only=True) + model.load_state_dict(state['model'], strict=True) + return model.cpu().eval() + + +class Segmenter: + def __init__(self, checkpoint): + import torch + from ..sam2.sam2_image_predictor import SAM2ImagePredictor + torch.set_num_threads(4) + torch.set_num_interop_threads(1) + self.predictor = SAM2ImagePredictor(build_model(checkpoint), max_hole_area=0, max_sprinkle_area=0) + self.key = None + self.encode_count = 0 + + def segment(self, image, points): + import numpy as np + import torch + from PIL import Image + validate_points(points, image.size) + image = image.convert('RGB') + key = image.size, hashlib.sha256(image.tobytes()).digest() + # The reference adapter groups positive points before negative points. + ordered = [p for p in points if p[2]] + [p for p in points if not p[2]] + with torch.inference_mode(): + if key != self.key: + self.clear_image() + self.predictor.set_image(np.asarray(image)) + self.key = key + self.encode_count += 1 + masks, scores, _ = self.predictor.predict( + point_coords=np.asarray([p[:2] for p in ordered], dtype=np.float32), + point_labels=np.asarray([p[2] for p in ordered], dtype=np.int32), + multimask_output=True) + return Image.fromarray(masks[int(np.argmax(scores))].astype(bool).astype(np.uint8) * 255) + + def clear_image(self): + self.key = None + self.predictor.reset_predictor() diff --git a/freevideo_engine/image_gen/segment_worker.py b/freevideo_engine/image_gen/segment_worker.py new file mode 100644 index 00000000..ab1e98f1 --- /dev/null +++ b/freevideo_engine/image_gen/segment_worker.py @@ -0,0 +1,81 @@ +"""CPU-only point selection worker. Idle exit releases the entire Torch allocator.""" +import argparse +from contextlib import redirect_stdout +import json +import os +from pathlib import Path +import queue +import sys + +from .worker import Inbox + + +def serve(checkpoint, *, idle_seconds=45., stream=None, output=None, factory=None): + from .segment import Segmenter, load_image, validate_points + stream = sys.stdin if stream is None else stream + output = sys.stdout if output is None else output + factory = factory or Segmenter + + def send(**row): + output.write(json.dumps(row, allow_nan=False) + '\n') + output.flush() + + inbox = Inbox(stream, send) + segmenter = None + try: + while not inbox.closed.is_set(): + try: + value = inbox.rows.get(timeout=idle_seconds) + except queue.Empty: + break + if value is None or inbox.closed.is_set(): + break + send(phase='accepted') + stage = 'start' + try: + with redirect_stdout(sys.stderr): + image = load_image(value['image']) + validate_points(value['points'], image.size) + stage = 'load' + if segmenter is None: + segmenter = factory(checkpoint) + stage = 'encode' + mask = segmenter.segment(image, value['points']) + if inbox.cancel.is_set(): + break + with Path(value['path']).open('xb') as target: + mask.save(target, format='PNG') + result = dict(phase='result', path=value['path']) + except Exception as error: + from .failure import classify_exception + code = str(error) if str(error) in ('invalid_media', 'invalid_points') else classify_exception(error, stage=stage) + result = dict(phase='error', code=code) + with inbox.mutex: + inbox.busy = False + send(**result) + finally: + inbox.closed.set() + if segmenter is not None: + segmenter.clear_image() + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('checkpoint', type=Path) + parser.add_argument('--idle-seconds', type=float, default=45.) + args = parser.parse_args() + if not 0 < args.idle_seconds < float('inf'): + parser.error('idle-seconds must be positive and finite') + # Set before importing Torch or torchvision; this process never uses CUDA/MPS. + os.environ.update(CUDA_VISIBLE_DEVICES='', HIP_VISIBLE_DEVICES='', + OMP_NUM_THREADS='4', MKL_NUM_THREADS='4', OPENBLAS_NUM_THREADS='4') + stream = None + if os.name == 'nt': + from ..win32 import private_stdin + stream = private_stdin() + serve(args.checkpoint, idle_seconds=args.idle_seconds, stream=stream) + return 0 + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/freevideo_engine/image_gen/service.py b/freevideo_engine/image_gen/service.py index 0558c067..852cfaa5 100644 --- a/freevideo_engine/image_gen/service.py +++ b/freevideo_engine/image_gen/service.py @@ -1,5 +1,6 @@ """One active image and one waiting job, with a worker leased until idle or video work.""" import atexit +import asyncio from collections import OrderedDict from copy import deepcopy import json @@ -26,7 +27,7 @@ QUEUE_TIMEOUT = 600. QUEUE_POLL = .1 INVALID_ERRORS = frozenset(('invalid_request', 'invalid_prompt', 'invalid_dimensions', 'invalid_seed', - 'invalid_media', 'too_many_images')) + 'invalid_media', 'invalid_points', 'too_many_images')) class WorkerIdleExit(RuntimeError): @@ -122,6 +123,12 @@ def __init__(self, installation, input_directory, *, video_busy=None, idle_secon self.queue_wake = threading.Event() self.finished = OrderedDict() self.pack_installer = None + self.segment_installer = None + self.segment_worker = None + self.segmenting = False + self.segment_stop = threading.Event() + self.segment_done = threading.Event() + self.segment_done.set() atexit.register(self.close) @staticmethod @@ -130,7 +137,7 @@ def _video_busy(): return OWNER.active def busy(self): - return self._busy + return self._busy or self.segmenting def info(self): engine_root, machine = self.installation() @@ -141,6 +148,9 @@ def info(self): downloading=not ready and image_pack.downloading(machine['model_root'], engine_root), bytes=sum(row['bytes'] for row in spec['groups']['image']), busy=self.busy(), max_images=MAX_IMAGES, install=self.pack_state(ready), + segment=dict(ready=image_pack.ready(machine['model_root'], group='segment'), + max_points=16, device='cpu', + install=self.segment_installer.state() if self.segment_installer else None), bytes_per_second=None if ready else observed_speed(engine_root)) def pack_state(self, ready): @@ -157,21 +167,153 @@ def pack_state(self, ready): message_zh=image_pack_failure(value.get('reason'), zh=True)['detail']) return row - def pack_action(self, action): + def pack_action(self, action, *, group='image'): """Start or pause the image model download from the page; it yields to a running video.""" engine_root, machine = self.installation() root = machine['model_root'] with self.mutex: - installer = self.pack_installer + attribute = 'segment_installer' if group == 'segment' else 'pack_installer' + installer = getattr(self, attribute) if action == 'cancel': if installer is not None: installer.cancel() - elif not image_pack.ready(root) and not image_pack.downloading(root, engine_root): + elif not image_pack.ready(root, group=group) and not image_pack.downloading(root, engine_root): if installer is None or installer.root != root or installer.engine_root != engine_root: - installer = self.pack_installer = image_pack.Installer(root, engine_root=engine_root, busy=self.video_busy) + options = dict(group=group) if group != 'image' else {} + installer = image_pack.Installer(root, engine_root=engine_root, busy=self.video_busy, **options) + setattr(self, attribute, installer) installer.start('install', background=True) return self.info() + def media_path(self, name): + """Shared input-name and symlink policy for generation and point selection.""" + directory = Path(self.input_directory()).resolve() + folder, _, leaf = name.rpartition('/') if isinstance(name, str) else ('', '', '') + if (not isinstance(name, str) or not leaf or name.startswith('/') or leaf in ('.', '..') + or folder not in ('', 'freevideo-image') + or any(char in name for char in ('\\', ':', '\0'))): + raise ValueError('invalid_media') + parent = directory / folder if folder else directory + path = parent / leaf + if (parent.is_symlink() or path.is_symlink() or parent.resolve() != parent + or path.resolve().parent != parent or not path.is_file()): + raise ValueError('invalid_media') + return str(path) + + def output_path(self): + directory = Path(self.input_directory()).resolve() + output = directory / 'freevideo-image' + if output.is_symlink() or output.resolve().parent != directory: + raise ValueError('invalid_media') + output.mkdir(exist_ok=True) + return str(output / (uuid.uuid4().hex + '.png')) + + def close_segment_worker(self): + from .. import processes + with self.mutex: + session, self.segment_worker = self.segment_worker, None + if session is not None: + processes.stop(session.process, grace=1) + session.process.wait() + session.close() + + def spawn_segment_worker(self, root, machine): + from .. import processes + row = image_pack.rows(group='segment')[0] + command = processes.module_command('freevideo_engine.image_gen.segment_worker', + image_pack.target(row, machine['model_root']), '--idle-seconds', 45.) + command[0] = machine['comfy_python'] + env = dict(self.environment(root), CUDA_VISIBLE_DEVICES='', HIP_VISIBLE_DEVICES='', + OMP_NUM_THREADS='4', MKL_NUM_THREADS='4', OPENBLAS_NUM_THREADS='4') + return Worker(processes.popen(command, env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, text=True, encoding='utf-8', errors='replace', + supervise=True, start_new_session=True)) + + def segment(self, value): + """Immediate admission, no waiting queue. The HTTP caller runs this off its event loop.""" + from .segment import validate_points + from ..locking import runtime_lock + if not isinstance(value, dict): + raise ValueError('invalid_request') + validate_points(value.get('points')) + path = self.media_path(value.get('image')) + with self.mutex: + if self.closed: + raise ValueError('closed') + if self.yielding or self.video_busy(): + raise ValueError('busy_video') + if self.busy() or self.queued is not None: + raise ValueError('busy') + try: + root, machine = self.installation() + except (OSError, ValueError): + raise ValueError('segment_not_installed') from None + try: + if not image_pack.ready(machine['model_root'], group='segment'): + raise ValueError('segment_not_installed') + except (OSError, image_pack.PackError): + raise ValueError('segment_not_installed') from None + self.segmenting = True + self.segment_stop.clear() + self.segment_done.clear() + # Reap the idle Qwen worker before taking its runtime lease. + self.session_stop.set() + thread = self.thread + try: + if thread is not None: + thread.join() + output = self.output_path() + with runtime_lock(Path(root) / 'engine.lock', inherit=False): + for attempt in range(2): + with self.mutex: + if self.closed or self.segment_stop.is_set() or self.yielding or self.video_busy(): + raise ValueError('busy_video') + session = self.segment_worker + if session is not None and session.process.poll() is not None: + self.close_segment_worker() + session = None + if session is None: + session = self.segment_worker = self.spawn_segment_worker(root, machine) + accepted = False + deadline = time.monotonic() + INFERENCE_TIMEOUT + try: + session.send(action='generate', image=path, points=value['points'], path=output) + while True: + if self.closed or self.segment_stop.is_set() or self.yielding or self.video_busy(): + raise ValueError('busy_video') + if time.monotonic() >= deadline: + raise ValueError('timeout') + try: + row = session.rows.get(timeout=.1) + except queue.Empty: + continue + if row is None: + raise WorkerIdleExit() + if row.get('phase') == 'accepted': + accepted = True + elif row.get('phase') == 'result': + if row.get('path') != output or not Path(output).is_file(): + raise ValueError('worker_exit') + return dict(mask='freevideo-image/' + Path(output).name) + elif row.get('phase') == 'error': + raise ValueError(row['code'] if row.get('code') in ERRORS else 'generation_failed') + except (BrokenPipeError, WorkerIdleExit): + self.close_segment_worker() + if accepted or attempt: + raise ValueError('worker_exit') from None + except BlockingIOError: + raise ValueError('busy') from None + except Exception: + self.close_segment_worker() + if self.segment_stop.is_set(): + raise ValueError('busy_video') from None + raise + finally: + with self.mutex: + self.segmenting = False + self.segment_done.set() + self.queue_wake.set() + def request(self, value): if not isinstance(value, dict): raise ValueError('invalid_request') @@ -191,27 +333,24 @@ def request(self, value): raise ValueError('invalid_media') if len(images) > MAX_IMAGES: raise ValueError('too_many_images') - directory = Path(self.input_directory()).resolve() - paths = [] - for name in images: - # A file in the input directory, or one of our own results as freevideo-image/. - folder, _, leaf = name.rpartition('/') if isinstance(name, str) else ('', '', '') - if (not isinstance(name, str) or not leaf or leaf in ('.', '..') - or folder not in ('', 'freevideo-image') - or any(char in name for char in ('\\', ':', '\0'))): + paths = [self.media_path(name) for name in images] + mask = value.get('mask') + mask_path = None + if mask is not None: + # The region to change: a mask drawn on the picture being edited, the first one. + if not paths: raise ValueError('invalid_media') - parent = directory / folder if folder else directory - path = parent / leaf - if (parent.is_symlink() or path.is_symlink() or parent.resolve() != parent - or path.resolve().parent != parent or not path.is_file()): - raise ValueError('invalid_media') - paths.append(str(path)) - output = directory / 'freevideo-image' - if output.is_symlink() or output.resolve().parent != directory: - raise ValueError('invalid_media') - output.mkdir(exist_ok=True) + mask_path = self.media_path(mask) + from PIL import Image + try: + with Image.open(paths[0]) as picture, Image.open(mask_path) as drawn: + if drawn.size != picture.size: + raise ValueError('invalid_media') + except OSError: + raise ValueError('invalid_media') from None return dict(prompt=prompt, width=dimensions[0] // 32 * 32, height=dimensions[1] // 32 * 32, - steps=8, seed=seed, images=paths, path=str(output / (uuid.uuid4().hex + '.png'))) + steps=8, seed=seed, images=paths, **(dict(mask=mask_path) if mask_path else {}), + path=self.output_path()) def start(self, action, value): if action not in ('generate', 'compose'): @@ -221,6 +360,8 @@ def start(self, action, value): with self.mutex: if self.closed: raise ValueError('closed') + if self.segmenting: + raise ValueError('busy') if self.queued is not None: raise ValueError('busy') if self.yielding: @@ -503,9 +644,11 @@ def stop_for_generation(self, only_idle=False): back from an idle worker but never cut off an image that is being made. """ with self.mutex: - if only_idle and (self._busy or self.thread is None or not self.thread.is_alive()): + if only_idle and (self.busy() or (self.segment_worker is None and + (self.thread is None or not self.thread.is_alive()))): return False self.yielding = True + self.segment_stop.set() self.stop.set() self.session_stop.set() if self.queued is not None: @@ -514,6 +657,8 @@ def stop_for_generation(self, only_idle=False): self.queued['video_since'] = time.monotonic() thread = self.thread try: + self.close_segment_worker() + self.segment_done.wait() if thread is not None and thread is not threading.current_thread(): thread.join() finally: @@ -570,6 +715,7 @@ def work(self, root, machine): failure = 'worker_exit' failure_error = None try: + self.close_segment_worker() from ..background_compile import COMPILE from ..encoder_prewarm import IDLE COMPILE.stop() @@ -667,7 +813,7 @@ def respawn(): with self.mutex: self.process = self.worker = None self.session_stop.set() - if self.busy(): + if self._busy: context = self.context or Context('generate', {}) fitted = self.state.get('fitted') self.state = (dict(phase='cancelled') if self.stop.is_set() @@ -915,6 +1061,10 @@ async def action(request): result = service.cancel(value.get('job')) elif name in ('pack-install', 'pack-cancel'): result = service.pack_action(name.split('-')[1]) + elif name in ('segment-install', 'segment-cancel'): + result = service.pack_action(name.split('-')[1], group='segment') + elif name == 'segment': + result = await asyncio.to_thread(service.segment, value) else: result = service.start(name, value) return web.json_response(result) diff --git a/freevideo_engine/image_gen/worker.py b/freevideo_engine/image_gen/worker.py index 7c5503c8..d97d807f 100644 --- a/freevideo_engine/image_gen/worker.py +++ b/freevideo_engine/image_gen/worker.py @@ -120,9 +120,13 @@ def progress(stage, fraction): for path in value.get('images', []): image = stack.enter_context(Image.open(path)) references.append(_flatten(image)) + region = {} + if value.get('mask'): + region['edit_mask'] = stack.enter_context(Image.open(value['mask'])) + region['edit_mask'].load() image = runner.generate( value['prompt'], width=value['width'], height=value['height'], - seed=value.get('seed'), reference_images=references, + seed=value.get('seed'), reference_images=references, **region, progress=progress, cancel=inbox.cancel.is_set) if inbox.cancel.is_set(): diff --git a/freevideo_engine/licenses/SAM2-Apache-2.0.txt b/freevideo_engine/licenses/SAM2-Apache-2.0.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/freevideo_engine/licenses/SAM2-Apache-2.0.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/freevideo_engine/licenses/SAM2-THIRD_PARTY.txt b/freevideo_engine/licenses/SAM2-THIRD_PARTY.txt new file mode 100644 index 00000000..a24424de --- /dev/null +++ b/freevideo_engine/licenses/SAM2-THIRD_PARTY.txt @@ -0,0 +1,21 @@ +SAM 2.1 Hiera small inference code and checkpoint +Copyright (c) Meta Platforms, Inc. and affiliates. Apache License, Version 2.0. +Full license: SAM2-Apache-2.0.txt in this directory. +Source: https://github.com/facebookresearch/sam2 +Pinned revision: 2b90b9f5ceec907a1c18123530e92e794ad901a4 +Imported from the pinned region-sam/upstream/sam2 delivery. + +FreeVideo modifications (2026-10-18): inference modules are namespaced as +freevideo_engine.sam2; Hydra initialization and the hub-download constructor are +omitted; Hiera uses Python open and weights_only=True instead of iopath. The +fixed sam2.1_hiera_s configuration is constructed in image_gen/segment.py. +RoPE frequency construction stays on CPU and CUDA position-cache warmup is disabled. +No upstream inference mathematics or image transforms are changed. Automatic +masks, video predictors, training code, CUDA extension and setup scripts are +not included. Postprocessing holes/sprinkles is disabled, as in the reference. + +Checkpoint: facebook/sam2.1-hiera-small/sam2.1_hiera_small.pt +184416285 bytes +SHA256: 6d1aa6f30de5c92224f8172114de081d104bbd23dd9dc5c58996f0cad5dc4d38 +https://huggingface.co/facebook/sam2.1-hiera-small +The official SAM2 README licenses model checkpoints under Apache-2.0 as well. diff --git a/freevideo_engine/sam2/__init__.py b/freevideo_engine/sam2/__init__.py new file mode 100644 index 00000000..c5c96c86 --- /dev/null +++ b/freevideo_engine/sam2/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + + +# FreeVideo: fixed CPU image model; no Hydra initialization or hub downloads. diff --git a/freevideo_engine/sam2/modeling/__init__.py b/freevideo_engine/sam2/modeling/__init__.py new file mode 100644 index 00000000..5277f461 --- /dev/null +++ b/freevideo_engine/sam2/modeling/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. diff --git a/freevideo_engine/sam2/modeling/backbones/__init__.py b/freevideo_engine/sam2/modeling/backbones/__init__.py new file mode 100644 index 00000000..5277f461 --- /dev/null +++ b/freevideo_engine/sam2/modeling/backbones/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. diff --git a/freevideo_engine/sam2/modeling/backbones/hieradet.py b/freevideo_engine/sam2/modeling/backbones/hieradet.py new file mode 100644 index 00000000..a299e52d --- /dev/null +++ b/freevideo_engine/sam2/modeling/backbones/hieradet.py @@ -0,0 +1,316 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +import logging +from functools import partial +from typing import List, Tuple, Union + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from freevideo_engine.sam2.modeling.backbones.utils import ( + PatchEmbed, + window_partition, + window_unpartition, +) + +from freevideo_engine.sam2.modeling.sam2_utils import DropPath, MLP + + +def do_pool(x: torch.Tensor, pool: nn.Module, norm: nn.Module = None) -> torch.Tensor: + if pool is None: + return x + # (B, H, W, C) -> (B, C, H, W) + x = x.permute(0, 3, 1, 2) + x = pool(x) + # (B, C, H', W') -> (B, H', W', C) + x = x.permute(0, 2, 3, 1) + if norm: + x = norm(x) + + return x + + +class MultiScaleAttention(nn.Module): + def __init__( + self, + dim: int, + dim_out: int, + num_heads: int, + q_pool: nn.Module = None, + ): + super().__init__() + + self.dim = dim + self.dim_out = dim_out + self.num_heads = num_heads + self.q_pool = q_pool + self.qkv = nn.Linear(dim, dim_out * 3) + self.proj = nn.Linear(dim_out, dim_out) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + B, H, W, _ = x.shape + # qkv with shape (B, H * W, 3, nHead, C) + qkv = self.qkv(x).reshape(B, H * W, 3, self.num_heads, -1) + # q, k, v with shape (B, H * W, nheads, C) + q, k, v = torch.unbind(qkv, 2) + + # Q pooling (for downsample at stage changes) + if self.q_pool: + q = do_pool(q.reshape(B, H, W, -1), self.q_pool) + H, W = q.shape[1:3] # downsampled shape + q = q.reshape(B, H * W, self.num_heads, -1) + + # Torch's SDPA expects [B, nheads, H*W, C] so we transpose + x = F.scaled_dot_product_attention( + q.transpose(1, 2), + k.transpose(1, 2), + v.transpose(1, 2), + ) + # Transpose back + x = x.transpose(1, 2) + x = x.reshape(B, H, W, -1) + + x = self.proj(x) + + return x + + +class MultiScaleBlock(nn.Module): + def __init__( + self, + dim: int, + dim_out: int, + num_heads: int, + mlp_ratio: float = 4.0, + drop_path: float = 0.0, + norm_layer: Union[nn.Module, str] = "LayerNorm", + q_stride: Tuple[int, int] = None, + act_layer: nn.Module = nn.GELU, + window_size: int = 0, + ): + super().__init__() + + if isinstance(norm_layer, str): + norm_layer = partial(getattr(nn, norm_layer), eps=1e-6) + + self.dim = dim + self.dim_out = dim_out + self.norm1 = norm_layer(dim) + + self.window_size = window_size + + self.pool, self.q_stride = None, q_stride + if self.q_stride: + self.pool = nn.MaxPool2d( + kernel_size=q_stride, stride=q_stride, ceil_mode=False + ) + + self.attn = MultiScaleAttention( + dim, + dim_out, + num_heads=num_heads, + q_pool=self.pool, + ) + self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity() + + self.norm2 = norm_layer(dim_out) + self.mlp = MLP( + dim_out, + int(dim_out * mlp_ratio), + dim_out, + num_layers=2, + activation=act_layer, + ) + + if dim != dim_out: + self.proj = nn.Linear(dim, dim_out) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + shortcut = x # B, H, W, C + x = self.norm1(x) + + # Skip connection + if self.dim != self.dim_out: + shortcut = do_pool(self.proj(x), self.pool) + + # Window partition + window_size = self.window_size + if window_size > 0: + H, W = x.shape[1], x.shape[2] + x, pad_hw = window_partition(x, window_size) + + # Window Attention + Q Pooling (if stage change) + x = self.attn(x) + if self.q_stride: + # Shapes have changed due to Q pooling + window_size = self.window_size // self.q_stride[0] + H, W = shortcut.shape[1:3] + + pad_h = (window_size - H % window_size) % window_size + pad_w = (window_size - W % window_size) % window_size + pad_hw = (H + pad_h, W + pad_w) + + # Reverse window partition + if self.window_size > 0: + x = window_unpartition(x, window_size, pad_hw, (H, W)) + + x = shortcut + self.drop_path(x) + # MLP + x = x + self.drop_path(self.mlp(self.norm2(x))) + return x + + +class Hiera(nn.Module): + """ + Reference: https://arxiv.org/abs/2306.00989 + """ + + def __init__( + self, + embed_dim: int = 96, # initial embed dim + num_heads: int = 1, # initial number of heads + drop_path_rate: float = 0.0, # stochastic depth + q_pool: int = 3, # number of q_pool stages + q_stride: Tuple[int, int] = (2, 2), # downsample stride bet. stages + stages: Tuple[int, ...] = (2, 3, 16, 3), # blocks per stage + dim_mul: float = 2.0, # dim_mul factor at stage shift + head_mul: float = 2.0, # head_mul factor at stage shift + window_pos_embed_bkg_spatial_size: Tuple[int, int] = (14, 14), + # window size per stage, when not using global att. + window_spec: Tuple[int, ...] = ( + 8, + 4, + 14, + 7, + ), + # global attn in these blocks + global_att_blocks: Tuple[int, ...] = ( + 12, + 16, + 20, + ), + weights_path=None, + return_interm_layers=True, # return feats from every stage + ): + super().__init__() + + assert len(stages) == len(window_spec) + self.window_spec = window_spec + + depth = sum(stages) + self.q_stride = q_stride + self.stage_ends = [sum(stages[:i]) - 1 for i in range(1, len(stages) + 1)] + assert 0 <= q_pool <= len(self.stage_ends[:-1]) + self.q_pool_blocks = [x + 1 for x in self.stage_ends[:-1]][:q_pool] + self.return_interm_layers = return_interm_layers + + self.patch_embed = PatchEmbed( + embed_dim=embed_dim, + ) + # Which blocks have global att? + self.global_att_blocks = global_att_blocks + + # Windowed positional embedding (https://arxiv.org/abs/2311.05613) + self.window_pos_embed_bkg_spatial_size = window_pos_embed_bkg_spatial_size + self.pos_embed = nn.Parameter( + torch.zeros(1, embed_dim, *self.window_pos_embed_bkg_spatial_size) + ) + self.pos_embed_window = nn.Parameter( + torch.zeros(1, embed_dim, self.window_spec[0], self.window_spec[0]) + ) + + dpr = [ + x.item() for x in torch.linspace(0, drop_path_rate, depth) + ] # stochastic depth decay rule + + cur_stage = 1 + self.blocks = nn.ModuleList() + + for i in range(depth): + dim_out = embed_dim + # lags by a block, so first block of + # next stage uses an initial window size + # of previous stage and final window size of current stage + window_size = self.window_spec[cur_stage - 1] + + if self.global_att_blocks is not None: + window_size = 0 if i in self.global_att_blocks else window_size + + if i - 1 in self.stage_ends: + dim_out = int(embed_dim * dim_mul) + num_heads = int(num_heads * head_mul) + cur_stage += 1 + + block = MultiScaleBlock( + dim=embed_dim, + dim_out=dim_out, + num_heads=num_heads, + drop_path=dpr[i], + q_stride=self.q_stride if i in self.q_pool_blocks else None, + window_size=window_size, + ) + + embed_dim = dim_out + self.blocks.append(block) + + self.channel_list = ( + [self.blocks[i].dim_out for i in self.stage_ends[::-1]] + if return_interm_layers + else [self.blocks[-1].dim_out] + ) + + if weights_path is not None: + with open(weights_path, "rb") as f: + chkpt = torch.load(f, map_location="cpu", weights_only=True) + logging.info("loading Hiera", self.load_state_dict(chkpt, strict=False)) + + def _get_pos_embed(self, hw: Tuple[int, int]) -> torch.Tensor: + h, w = hw + window_embed = self.pos_embed_window + pos_embed = F.interpolate(self.pos_embed, size=(h, w), mode="bicubic") + pos_embed = pos_embed + window_embed.tile( + [x // y for x, y in zip(pos_embed.shape, window_embed.shape)] + ) + pos_embed = pos_embed.permute(0, 2, 3, 1) + return pos_embed + + def forward(self, x: torch.Tensor) -> List[torch.Tensor]: + x = self.patch_embed(x) + # x: (B, H, W, C) + + # Add pos embed + x = x + self._get_pos_embed(x.shape[1:3]) + + outputs = [] + for i, blk in enumerate(self.blocks): + x = blk(x) + if (i == self.stage_ends[-1]) or ( + i in self.stage_ends and self.return_interm_layers + ): + feats = x.permute(0, 3, 1, 2) + outputs.append(feats) + + return outputs + + def get_layer_id(self, layer_name): + # https://github.com/microsoft/unilm/blob/master/beit/optim_factory.py#L33 + num_layers = self.get_num_layers() + + if layer_name.find("rel_pos") != -1: + return num_layers + 1 + elif layer_name.find("pos_embed") != -1: + return 0 + elif layer_name.find("patch_embed") != -1: + return 0 + elif layer_name.find("blocks") != -1: + return int(layer_name.split("blocks")[1].split(".")[1]) + 1 + else: + return num_layers + 1 + + def get_num_layers(self) -> int: + return len(self.blocks) diff --git a/freevideo_engine/sam2/modeling/backbones/image_encoder.py b/freevideo_engine/sam2/modeling/backbones/image_encoder.py new file mode 100644 index 00000000..37e9266b --- /dev/null +++ b/freevideo_engine/sam2/modeling/backbones/image_encoder.py @@ -0,0 +1,134 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +from typing import List, Optional + +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class ImageEncoder(nn.Module): + def __init__( + self, + trunk: nn.Module, + neck: nn.Module, + scalp: int = 0, + ): + super().__init__() + self.trunk = trunk + self.neck = neck + self.scalp = scalp + assert ( + self.trunk.channel_list == self.neck.backbone_channel_list + ), f"Channel dims of trunk and neck do not match. Trunk: {self.trunk.channel_list}, neck: {self.neck.backbone_channel_list}" + + def forward(self, sample: torch.Tensor): + # Forward through backbone + features, pos = self.neck(self.trunk(sample)) + if self.scalp > 0: + # Discard the lowest resolution features + features, pos = features[: -self.scalp], pos[: -self.scalp] + + src = features[-1] + output = { + "vision_features": src, + "vision_pos_enc": pos, + "backbone_fpn": features, + } + return output + + +class FpnNeck(nn.Module): + """ + A modified variant of Feature Pyramid Network (FPN) neck + (we remove output conv and also do bicubic interpolation similar to ViT + pos embed interpolation) + """ + + def __init__( + self, + position_encoding: nn.Module, + d_model: int, + backbone_channel_list: List[int], + kernel_size: int = 1, + stride: int = 1, + padding: int = 0, + fpn_interp_model: str = "bilinear", + fuse_type: str = "sum", + fpn_top_down_levels: Optional[List[int]] = None, + ): + """Initialize the neck + :param trunk: the backbone + :param position_encoding: the positional encoding to use + :param d_model: the dimension of the model + :param neck_norm: the normalization to use + """ + super().__init__() + self.position_encoding = position_encoding + self.convs = nn.ModuleList() + self.backbone_channel_list = backbone_channel_list + self.d_model = d_model + for dim in backbone_channel_list: + current = nn.Sequential() + current.add_module( + "conv", + nn.Conv2d( + in_channels=dim, + out_channels=d_model, + kernel_size=kernel_size, + stride=stride, + padding=padding, + ), + ) + + self.convs.append(current) + self.fpn_interp_model = fpn_interp_model + assert fuse_type in ["sum", "avg"] + self.fuse_type = fuse_type + + # levels to have top-down features in its outputs + # e.g. if fpn_top_down_levels is [2, 3], then only outputs of level 2 and 3 + # have top-down propagation, while outputs of level 0 and level 1 have only + # lateral features from the same backbone level. + if fpn_top_down_levels is None: + # default is to have top-down features on all levels + fpn_top_down_levels = range(len(self.convs)) + self.fpn_top_down_levels = list(fpn_top_down_levels) + + def forward(self, xs: List[torch.Tensor]): + + out = [None] * len(self.convs) + pos = [None] * len(self.convs) + assert len(xs) == len(self.convs) + # fpn forward pass + # see https://github.com/facebookresearch/detectron2/blob/main/detectron2/modeling/backbone/fpn.py + prev_features = None + # forward in top-down order (from low to high resolution) + n = len(self.convs) - 1 + for i in range(n, -1, -1): + x = xs[i] + lateral_features = self.convs[n - i](x) + if i in self.fpn_top_down_levels and prev_features is not None: + top_down_features = F.interpolate( + prev_features.to(dtype=torch.float32), + scale_factor=2.0, + mode=self.fpn_interp_model, + align_corners=( + None if self.fpn_interp_model == "nearest" else False + ), + antialias=False, + ) + prev_features = lateral_features + top_down_features + if self.fuse_type == "avg": + prev_features /= 2 + else: + prev_features = lateral_features + x_out = prev_features + out[i] = x_out + pos[i] = self.position_encoding(x_out).to(x_out.dtype) + + return out, pos diff --git a/freevideo_engine/sam2/modeling/backbones/utils.py b/freevideo_engine/sam2/modeling/backbones/utils.py new file mode 100644 index 00000000..930b1b76 --- /dev/null +++ b/freevideo_engine/sam2/modeling/backbones/utils.py @@ -0,0 +1,93 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +"""Some utilities for backbones, in particular for windowing""" + +from typing import Tuple + +import torch +import torch.nn as nn +import torch.nn.functional as F + + +def window_partition(x, window_size): + """ + Partition into non-overlapping windows with padding if needed. + Args: + x (tensor): input tokens with [B, H, W, C]. + window_size (int): window size. + Returns: + windows: windows after partition with [B * num_windows, window_size, window_size, C]. + (Hp, Wp): padded height and width before partition + """ + B, H, W, C = x.shape + + pad_h = (window_size - H % window_size) % window_size + pad_w = (window_size - W % window_size) % window_size + if pad_h > 0 or pad_w > 0: + x = F.pad(x, (0, 0, 0, pad_w, 0, pad_h)) + Hp, Wp = H + pad_h, W + pad_w + + x = x.view(B, Hp // window_size, window_size, Wp // window_size, window_size, C) + windows = x.permute(0, 1, 3, 2, 4, 5).reshape(-1, window_size, window_size, C) + return windows, (Hp, Wp) + + +def window_unpartition(windows, window_size, pad_hw, hw): + """ + Window unpartition into original sequences and removing padding. + Args: + x (tensor): input tokens with [B * num_windows, window_size, window_size, C]. + window_size (int): window size. + pad_hw (Tuple): padded height and width (Hp, Wp). + hw (Tuple): original height and width (H, W) before padding. + Returns: + x: unpartitioned sequences with [B, H, W, C]. + """ + Hp, Wp = pad_hw + H, W = hw + B = windows.shape[0] // (Hp * Wp // window_size // window_size) + x = windows.reshape( + B, Hp // window_size, Wp // window_size, window_size, window_size, -1 + ) + x = x.permute(0, 1, 3, 2, 4, 5).reshape(B, Hp, Wp, -1) + + if Hp > H or Wp > W: + x = x[:, :H, :W, :] + return x + + +class PatchEmbed(nn.Module): + """ + Image to Patch Embedding. + """ + + def __init__( + self, + kernel_size: Tuple[int, ...] = (7, 7), + stride: Tuple[int, ...] = (4, 4), + padding: Tuple[int, ...] = (3, 3), + in_chans: int = 3, + embed_dim: int = 768, + ): + """ + Args: + kernel_size (Tuple): kernel size of the projection layer. + stride (Tuple): stride of the projection layer. + padding (Tuple): padding size of the projection layer. + in_chans (int): Number of input image channels. + embed_dim (int): embed_dim (int): Patch embedding dimension. + """ + super().__init__() + self.proj = nn.Conv2d( + in_chans, embed_dim, kernel_size=kernel_size, stride=stride, padding=padding + ) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + x = self.proj(x) + # B C H W -> B H W C + x = x.permute(0, 2, 3, 1) + return x diff --git a/freevideo_engine/sam2/modeling/memory_attention.py b/freevideo_engine/sam2/modeling/memory_attention.py new file mode 100644 index 00000000..f6408fbc --- /dev/null +++ b/freevideo_engine/sam2/modeling/memory_attention.py @@ -0,0 +1,169 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +from typing import Optional + +import torch +from torch import nn, Tensor + +from freevideo_engine.sam2.modeling.sam.transformer import RoPEAttention + +from freevideo_engine.sam2.modeling.sam2_utils import get_activation_fn, get_clones + + +class MemoryAttentionLayer(nn.Module): + + def __init__( + self, + activation: str, + cross_attention: nn.Module, + d_model: int, + dim_feedforward: int, + dropout: float, + pos_enc_at_attn: bool, + pos_enc_at_cross_attn_keys: bool, + pos_enc_at_cross_attn_queries: bool, + self_attention: nn.Module, + ): + super().__init__() + self.d_model = d_model + self.dim_feedforward = dim_feedforward + self.dropout_value = dropout + self.self_attn = self_attention + self.cross_attn_image = cross_attention + + # Implementation of Feedforward model + self.linear1 = nn.Linear(d_model, dim_feedforward) + self.dropout = nn.Dropout(dropout) + self.linear2 = nn.Linear(dim_feedforward, d_model) + + self.norm1 = nn.LayerNorm(d_model) + self.norm2 = nn.LayerNorm(d_model) + self.norm3 = nn.LayerNorm(d_model) + self.dropout1 = nn.Dropout(dropout) + self.dropout2 = nn.Dropout(dropout) + self.dropout3 = nn.Dropout(dropout) + + self.activation_str = activation + self.activation = get_activation_fn(activation) + + # Where to add pos enc + self.pos_enc_at_attn = pos_enc_at_attn + self.pos_enc_at_cross_attn_queries = pos_enc_at_cross_attn_queries + self.pos_enc_at_cross_attn_keys = pos_enc_at_cross_attn_keys + + def _forward_sa(self, tgt, query_pos): + # Self-Attention + tgt2 = self.norm1(tgt) + q = k = tgt2 + query_pos if self.pos_enc_at_attn else tgt2 + tgt2 = self.self_attn(q, k, v=tgt2) + tgt = tgt + self.dropout1(tgt2) + return tgt + + def _forward_ca(self, tgt, memory, query_pos, pos, num_k_exclude_rope=0): + kwds = {} + if num_k_exclude_rope > 0: + assert isinstance(self.cross_attn_image, RoPEAttention) + kwds = {"num_k_exclude_rope": num_k_exclude_rope} + + # Cross-Attention + tgt2 = self.norm2(tgt) + tgt2 = self.cross_attn_image( + q=tgt2 + query_pos if self.pos_enc_at_cross_attn_queries else tgt2, + k=memory + pos if self.pos_enc_at_cross_attn_keys else memory, + v=memory, + **kwds, + ) + tgt = tgt + self.dropout2(tgt2) + return tgt + + def forward( + self, + tgt, + memory, + pos: Optional[Tensor] = None, + query_pos: Optional[Tensor] = None, + num_k_exclude_rope: int = 0, + ) -> torch.Tensor: + + # Self-Attn, Cross-Attn + tgt = self._forward_sa(tgt, query_pos) + tgt = self._forward_ca(tgt, memory, query_pos, pos, num_k_exclude_rope) + # MLP + tgt2 = self.norm3(tgt) + tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt2)))) + tgt = tgt + self.dropout3(tgt2) + return tgt + + +class MemoryAttention(nn.Module): + def __init__( + self, + d_model: int, + pos_enc_at_input: bool, + layer: nn.Module, + num_layers: int, + batch_first: bool = True, # Do layers expect batch first input? + ): + super().__init__() + self.d_model = d_model + self.layers = get_clones(layer, num_layers) + self.num_layers = num_layers + self.norm = nn.LayerNorm(d_model) + self.pos_enc_at_input = pos_enc_at_input + self.batch_first = batch_first + + def forward( + self, + curr: torch.Tensor, # self-attention inputs + memory: torch.Tensor, # cross-attention inputs + curr_pos: Optional[Tensor] = None, # pos_enc for self-attention inputs + memory_pos: Optional[Tensor] = None, # pos_enc for cross-attention inputs + num_obj_ptr_tokens: int = 0, # number of object pointer *tokens* + ): + if isinstance(curr, list): + assert isinstance(curr_pos, list) + assert len(curr) == len(curr_pos) == 1 + curr, curr_pos = ( + curr[0], + curr_pos[0], + ) + + assert ( + curr.shape[1] == memory.shape[1] + ), "Batch size must be the same for curr and memory" + + output = curr + if self.pos_enc_at_input and curr_pos is not None: + output = output + 0.1 * curr_pos + + if self.batch_first: + # Convert to batch first + output = output.transpose(0, 1) + curr_pos = curr_pos.transpose(0, 1) + memory = memory.transpose(0, 1) + memory_pos = memory_pos.transpose(0, 1) + + for layer in self.layers: + kwds = {} + if isinstance(layer.cross_attn_image, RoPEAttention): + kwds = {"num_k_exclude_rope": num_obj_ptr_tokens} + + output = layer( + tgt=output, + memory=memory, + pos=memory_pos, + query_pos=curr_pos, + **kwds, + ) + normed_output = self.norm(output) + + if self.batch_first: + # Convert back to seq first + normed_output = normed_output.transpose(0, 1) + curr_pos = curr_pos.transpose(0, 1) + + return normed_output diff --git a/freevideo_engine/sam2/modeling/memory_encoder.py b/freevideo_engine/sam2/modeling/memory_encoder.py new file mode 100644 index 00000000..e211db19 --- /dev/null +++ b/freevideo_engine/sam2/modeling/memory_encoder.py @@ -0,0 +1,181 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +import math +from typing import Tuple + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from freevideo_engine.sam2.modeling.sam2_utils import DropPath, get_clones, LayerNorm2d + + +class MaskDownSampler(nn.Module): + """ + Progressively downsample a mask by total_stride, each time by stride. + Note that LayerNorm is applied per *token*, like in ViT. + + With each downsample (by a factor stride**2), channel capacity increases by the same factor. + In the end, we linearly project to embed_dim channels. + """ + + def __init__( + self, + embed_dim=256, + kernel_size=4, + stride=4, + padding=0, + total_stride=16, + activation=nn.GELU, + ): + super().__init__() + num_layers = int(math.log2(total_stride) // math.log2(stride)) + assert stride**num_layers == total_stride + self.encoder = nn.Sequential() + mask_in_chans, mask_out_chans = 1, 1 + for _ in range(num_layers): + mask_out_chans = mask_in_chans * (stride**2) + self.encoder.append( + nn.Conv2d( + mask_in_chans, + mask_out_chans, + kernel_size=kernel_size, + stride=stride, + padding=padding, + ) + ) + self.encoder.append(LayerNorm2d(mask_out_chans)) + self.encoder.append(activation()) + mask_in_chans = mask_out_chans + + self.encoder.append(nn.Conv2d(mask_out_chans, embed_dim, kernel_size=1)) + + def forward(self, x): + return self.encoder(x) + + +# Lightly adapted from ConvNext (https://github.com/facebookresearch/ConvNeXt) +class CXBlock(nn.Module): + r"""ConvNeXt Block. There are two equivalent implementations: + (1) DwConv -> LayerNorm (channels_first) -> 1x1 Conv -> GELU -> 1x1 Conv; all in (N, C, H, W) + (2) DwConv -> Permute to (N, H, W, C); LayerNorm (channels_last) -> Linear -> GELU -> Linear; Permute back + We use (2) as we find it slightly faster in PyTorch + + Args: + dim (int): Number of input channels. + drop_path (float): Stochastic depth rate. Default: 0.0 + layer_scale_init_value (float): Init value for Layer Scale. Default: 1e-6. + """ + + def __init__( + self, + dim, + kernel_size=7, + padding=3, + drop_path=0.0, + layer_scale_init_value=1e-6, + use_dwconv=True, + ): + super().__init__() + self.dwconv = nn.Conv2d( + dim, + dim, + kernel_size=kernel_size, + padding=padding, + groups=dim if use_dwconv else 1, + ) # depthwise conv + self.norm = LayerNorm2d(dim, eps=1e-6) + self.pwconv1 = nn.Linear( + dim, 4 * dim + ) # pointwise/1x1 convs, implemented with linear layers + self.act = nn.GELU() + self.pwconv2 = nn.Linear(4 * dim, dim) + self.gamma = ( + nn.Parameter(layer_scale_init_value * torch.ones((dim)), requires_grad=True) + if layer_scale_init_value > 0 + else None + ) + self.drop_path = DropPath(drop_path) if drop_path > 0.0 else nn.Identity() + + def forward(self, x): + input = x + x = self.dwconv(x) + x = self.norm(x) + x = x.permute(0, 2, 3, 1) # (N, C, H, W) -> (N, H, W, C) + x = self.pwconv1(x) + x = self.act(x) + x = self.pwconv2(x) + if self.gamma is not None: + x = self.gamma * x + x = x.permute(0, 3, 1, 2) # (N, H, W, C) -> (N, C, H, W) + + x = input + self.drop_path(x) + return x + + +class Fuser(nn.Module): + def __init__(self, layer, num_layers, dim=None, input_projection=False): + super().__init__() + self.proj = nn.Identity() + self.layers = get_clones(layer, num_layers) + + if input_projection: + assert dim is not None + self.proj = nn.Conv2d(dim, dim, kernel_size=1) + + def forward(self, x): + # normally x: (N, C, H, W) + x = self.proj(x) + for layer in self.layers: + x = layer(x) + return x + + +class MemoryEncoder(nn.Module): + def __init__( + self, + out_dim, + mask_downsampler, + fuser, + position_encoding, + in_dim=256, # in_dim of pix_feats + ): + super().__init__() + + self.mask_downsampler = mask_downsampler + + self.pix_feat_proj = nn.Conv2d(in_dim, in_dim, kernel_size=1) + self.fuser = fuser + self.position_encoding = position_encoding + self.out_proj = nn.Identity() + if out_dim != in_dim: + self.out_proj = nn.Conv2d(in_dim, out_dim, kernel_size=1) + + def forward( + self, + pix_feat: torch.Tensor, + masks: torch.Tensor, + skip_mask_sigmoid: bool = False, + ) -> Tuple[torch.Tensor, torch.Tensor]: + ## Process masks + # sigmoid, so that less domain shift from gt masks which are bool + if not skip_mask_sigmoid: + masks = F.sigmoid(masks) + masks = self.mask_downsampler(masks) + + ## Fuse pix_feats and downsampled masks + # in case the visual features are on CPU, cast them to CUDA + pix_feat = pix_feat.to(masks.device) + + x = self.pix_feat_proj(pix_feat) + x = x + masks + x = self.fuser(x) + x = self.out_proj(x) + + pos = self.position_encoding(x).to(x.dtype) + + return {"vision_features": x, "vision_pos_enc": [pos]} diff --git a/freevideo_engine/sam2/modeling/position_encoding.py b/freevideo_engine/sam2/modeling/position_encoding.py new file mode 100644 index 00000000..2241d4cf --- /dev/null +++ b/freevideo_engine/sam2/modeling/position_encoding.py @@ -0,0 +1,239 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +import math +from typing import Any, Optional, Tuple + +import numpy as np + +import torch +from torch import nn + + +class PositionEmbeddingSine(nn.Module): + """ + This is a more standard version of the position embedding, very similar to the one + used by the Attention Is All You Need paper, generalized to work on images. + """ + + def __init__( + self, + num_pos_feats, + temperature: int = 10000, + normalize: bool = True, + scale: Optional[float] = None, + # Following settings only relevant + # for warmping up cache for compilation + warmup_cache: bool = True, + image_size: int = 1024, + strides: Tuple[int] = (4, 8, 16, 32), + ): + super().__init__() + assert num_pos_feats % 2 == 0, "Expecting even model width" + self.num_pos_feats = num_pos_feats // 2 + self.temperature = temperature + self.normalize = normalize + if scale is not None and normalize is False: + raise ValueError("normalize should be True if scale is passed") + if scale is None: + scale = 2 * math.pi + self.scale = scale + + self.cache = {} + if warmup_cache and torch.cuda.is_available(): + # Warmup cache for cuda, to help with compilation + device = torch.device("cuda") + for stride in strides: + cache_key = (image_size // stride, image_size // stride) + self._pe(1, device, *cache_key) + + def _encode_xy(self, x, y): + # The positions are expected to be normalized + assert len(x) == len(y) and x.ndim == y.ndim == 1 + x_embed = x * self.scale + y_embed = y * self.scale + + dim_t = torch.arange(self.num_pos_feats, dtype=torch.float32, device=x.device) + dim_t = self.temperature ** (2 * (dim_t // 2) / self.num_pos_feats) + + pos_x = x_embed[:, None] / dim_t + pos_y = y_embed[:, None] / dim_t + pos_x = torch.stack( + (pos_x[:, 0::2].sin(), pos_x[:, 1::2].cos()), dim=2 + ).flatten(1) + pos_y = torch.stack( + (pos_y[:, 0::2].sin(), pos_y[:, 1::2].cos()), dim=2 + ).flatten(1) + return pos_x, pos_y + + @torch.no_grad() + def encode_boxes(self, x, y, w, h): + pos_x, pos_y = self._encode_xy(x, y) + pos = torch.cat((pos_y, pos_x, h[:, None], w[:, None]), dim=1) + return pos + + encode = encode_boxes # Backwards compatibility + + @torch.no_grad() + def encode_points(self, x, y, labels): + (bx, nx), (by, ny), (bl, nl) = x.shape, y.shape, labels.shape + assert bx == by and nx == ny and bx == bl and nx == nl + pos_x, pos_y = self._encode_xy(x.flatten(), y.flatten()) + pos_x, pos_y = pos_x.reshape(bx, nx, -1), pos_y.reshape(by, ny, -1) + pos = torch.cat((pos_y, pos_x, labels[:, :, None]), dim=2) + return pos + + @torch.no_grad() + def _pe(self, B, device, *cache_key): + H, W = cache_key + if cache_key in self.cache: + return self.cache[cache_key].to(device)[None].repeat(B, 1, 1, 1) + + y_embed = ( + torch.arange(1, H + 1, dtype=torch.float32, device=device) + .view(1, -1, 1) + .repeat(B, 1, W) + ) + x_embed = ( + torch.arange(1, W + 1, dtype=torch.float32, device=device) + .view(1, 1, -1) + .repeat(B, H, 1) + ) + + if self.normalize: + eps = 1e-6 + y_embed = y_embed / (y_embed[:, -1:, :] + eps) * self.scale + x_embed = x_embed / (x_embed[:, :, -1:] + eps) * self.scale + + dim_t = torch.arange(self.num_pos_feats, dtype=torch.float32, device=device) + dim_t = self.temperature ** (2 * (dim_t // 2) / self.num_pos_feats) + + pos_x = x_embed[:, :, :, None] / dim_t + pos_y = y_embed[:, :, :, None] / dim_t + pos_x = torch.stack( + (pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4 + ).flatten(3) + pos_y = torch.stack( + (pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), dim=4 + ).flatten(3) + pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2) + self.cache[cache_key] = pos[0] + return pos + + @torch.no_grad() + def forward(self, x: torch.Tensor): + B = x.shape[0] + cache_key = (x.shape[-2], x.shape[-1]) + return self._pe(B, x.device, *cache_key) + + +class PositionEmbeddingRandom(nn.Module): + """ + Positional encoding using random spatial frequencies. + """ + + def __init__(self, num_pos_feats: int = 64, scale: Optional[float] = None) -> None: + super().__init__() + if scale is None or scale <= 0.0: + scale = 1.0 + self.register_buffer( + "positional_encoding_gaussian_matrix", + scale * torch.randn((2, num_pos_feats)), + ) + + def _pe_encoding(self, coords: torch.Tensor) -> torch.Tensor: + """Positionally encode points that are normalized to [0,1].""" + # assuming coords are in [0, 1]^2 square and have d_1 x ... x d_n x 2 shape + coords = 2 * coords - 1 + coords = coords @ self.positional_encoding_gaussian_matrix + coords = 2 * np.pi * coords + # outputs d_1 x ... x d_n x C shape + return torch.cat([torch.sin(coords), torch.cos(coords)], dim=-1) + + def forward(self, size: Tuple[int, int]) -> torch.Tensor: + """Generate positional encoding for a grid of the specified size.""" + h, w = size + device: Any = self.positional_encoding_gaussian_matrix.device + grid = torch.ones((h, w), device=device, dtype=torch.float32) + y_embed = grid.cumsum(dim=0) - 0.5 + x_embed = grid.cumsum(dim=1) - 0.5 + y_embed = y_embed / h + x_embed = x_embed / w + + pe = self._pe_encoding(torch.stack([x_embed, y_embed], dim=-1)) + return pe.permute(2, 0, 1) # C x H x W + + def forward_with_coords( + self, coords_input: torch.Tensor, image_size: Tuple[int, int] + ) -> torch.Tensor: + """Positionally encode points that are not normalized to [0,1].""" + coords = coords_input.clone() + coords[:, :, 0] = coords[:, :, 0] / image_size[1] + coords[:, :, 1] = coords[:, :, 1] / image_size[0] + return self._pe_encoding(coords.to(torch.float)) # B x N x C + + +# Rotary Positional Encoding, adapted from: +# 1. https://github.com/meta-llama/codellama/blob/main/llama/model.py +# 2. https://github.com/naver-ai/rope-vit +# 3. https://github.com/lucidrains/rotary-embedding-torch + + +def init_t_xy(end_x: int, end_y: int): + t = torch.arange(end_x * end_y, dtype=torch.float32) + t_x = (t % end_x).float() + t_y = torch.div(t, end_x, rounding_mode="floor").float() + return t_x, t_y + + +def compute_axial_cis(dim: int, end_x: int, end_y: int, theta: float = 10000.0): + freqs_x = 1.0 / (theta ** (torch.arange(0, dim, 4)[: (dim // 4)].float() / dim)) + freqs_y = 1.0 / (theta ** (torch.arange(0, dim, 4)[: (dim // 4)].float() / dim)) + + t_x, t_y = init_t_xy(end_x, end_y) + freqs_x = torch.outer(t_x, freqs_x) + freqs_y = torch.outer(t_y, freqs_y) + freqs_cis_x = torch.polar(torch.ones_like(freqs_x), freqs_x) + freqs_cis_y = torch.polar(torch.ones_like(freqs_y), freqs_y) + return torch.cat([freqs_cis_x, freqs_cis_y], dim=-1) + + +def reshape_for_broadcast(freqs_cis: torch.Tensor, x: torch.Tensor): + ndim = x.ndim + assert 0 <= 1 < ndim + assert freqs_cis.shape == (x.shape[-2], x.shape[-1]) + shape = [d if i >= ndim - 2 else 1 for i, d in enumerate(x.shape)] + return freqs_cis.view(*shape) + + +def apply_rotary_enc( + xq: torch.Tensor, + xk: torch.Tensor, + freqs_cis: torch.Tensor, + repeat_freqs_k: bool = False, +): + xq_ = torch.view_as_complex(xq.float().reshape(*xq.shape[:-1], -1, 2)) + xk_ = ( + torch.view_as_complex(xk.float().reshape(*xk.shape[:-1], -1, 2)) + if xk.shape[-2] != 0 + else None + ) + freqs_cis = reshape_for_broadcast(freqs_cis, xq_) + xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(3) + if xk_ is None: + # no keys to rotate, due to dropout + return xq_out.type_as(xq).to(xq.device), xk + # repeat freqs along seq_len dim to match k seq_len + if repeat_freqs_k: + r = xk_.shape[-2] // xq_.shape[-2] + if freqs_cis.is_cuda: + freqs_cis = freqs_cis.repeat(*([1] * (freqs_cis.ndim - 2)), r, 1) + else: + # torch.repeat on complex numbers may not be supported on non-CUDA devices + # (freqs_cis has 4 dims and we repeat on dim 2) so we use expand + flatten + freqs_cis = freqs_cis.unsqueeze(2).expand(-1, -1, r, -1, -1).flatten(2, 3) + xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(3) + return xq_out.type_as(xq).to(xq.device), xk_out.type_as(xk).to(xk.device) diff --git a/freevideo_engine/sam2/modeling/sam/__init__.py b/freevideo_engine/sam2/modeling/sam/__init__.py new file mode 100644 index 00000000..5277f461 --- /dev/null +++ b/freevideo_engine/sam2/modeling/sam/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. diff --git a/freevideo_engine/sam2/modeling/sam/mask_decoder.py b/freevideo_engine/sam2/modeling/sam/mask_decoder.py new file mode 100644 index 00000000..50fd358b --- /dev/null +++ b/freevideo_engine/sam2/modeling/sam/mask_decoder.py @@ -0,0 +1,295 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +from typing import List, Optional, Tuple, Type + +import torch +from torch import nn + +from freevideo_engine.sam2.modeling.sam2_utils import LayerNorm2d, MLP + + +class MaskDecoder(nn.Module): + def __init__( + self, + *, + transformer_dim: int, + transformer: nn.Module, + num_multimask_outputs: int = 3, + activation: Type[nn.Module] = nn.GELU, + iou_head_depth: int = 3, + iou_head_hidden_dim: int = 256, + use_high_res_features: bool = False, + iou_prediction_use_sigmoid=False, + dynamic_multimask_via_stability=False, + dynamic_multimask_stability_delta=0.05, + dynamic_multimask_stability_thresh=0.98, + pred_obj_scores: bool = False, + pred_obj_scores_mlp: bool = False, + use_multimask_token_for_obj_ptr: bool = False, + ) -> None: + """ + Predicts masks given an image and prompt embeddings, using a + transformer architecture. + + Arguments: + transformer_dim (int): the channel dimension of the transformer + transformer (nn.Module): the transformer used to predict masks + num_multimask_outputs (int): the number of masks to predict + when disambiguating masks + activation (nn.Module): the type of activation to use when + upscaling masks + iou_head_depth (int): the depth of the MLP used to predict + mask quality + iou_head_hidden_dim (int): the hidden dimension of the MLP + used to predict mask quality + """ + super().__init__() + self.transformer_dim = transformer_dim + self.transformer = transformer + + self.num_multimask_outputs = num_multimask_outputs + + self.iou_token = nn.Embedding(1, transformer_dim) + self.num_mask_tokens = num_multimask_outputs + 1 + self.mask_tokens = nn.Embedding(self.num_mask_tokens, transformer_dim) + + self.pred_obj_scores = pred_obj_scores + if self.pred_obj_scores: + self.obj_score_token = nn.Embedding(1, transformer_dim) + self.use_multimask_token_for_obj_ptr = use_multimask_token_for_obj_ptr + + self.output_upscaling = nn.Sequential( + nn.ConvTranspose2d( + transformer_dim, transformer_dim // 4, kernel_size=2, stride=2 + ), + LayerNorm2d(transformer_dim // 4), + activation(), + nn.ConvTranspose2d( + transformer_dim // 4, transformer_dim // 8, kernel_size=2, stride=2 + ), + activation(), + ) + self.use_high_res_features = use_high_res_features + if use_high_res_features: + self.conv_s0 = nn.Conv2d( + transformer_dim, transformer_dim // 8, kernel_size=1, stride=1 + ) + self.conv_s1 = nn.Conv2d( + transformer_dim, transformer_dim // 4, kernel_size=1, stride=1 + ) + + self.output_hypernetworks_mlps = nn.ModuleList( + [ + MLP(transformer_dim, transformer_dim, transformer_dim // 8, 3) + for i in range(self.num_mask_tokens) + ] + ) + + self.iou_prediction_head = MLP( + transformer_dim, + iou_head_hidden_dim, + self.num_mask_tokens, + iou_head_depth, + sigmoid_output=iou_prediction_use_sigmoid, + ) + if self.pred_obj_scores: + self.pred_obj_score_head = nn.Linear(transformer_dim, 1) + if pred_obj_scores_mlp: + self.pred_obj_score_head = MLP(transformer_dim, transformer_dim, 1, 3) + + # When outputting a single mask, optionally we can dynamically fall back to the best + # multimask output token if the single mask output token gives low stability scores. + self.dynamic_multimask_via_stability = dynamic_multimask_via_stability + self.dynamic_multimask_stability_delta = dynamic_multimask_stability_delta + self.dynamic_multimask_stability_thresh = dynamic_multimask_stability_thresh + + def forward( + self, + image_embeddings: torch.Tensor, + image_pe: torch.Tensor, + sparse_prompt_embeddings: torch.Tensor, + dense_prompt_embeddings: torch.Tensor, + multimask_output: bool, + repeat_image: bool, + high_res_features: Optional[List[torch.Tensor]] = None, + ) -> Tuple[torch.Tensor, torch.Tensor]: + """ + Predict masks given image and prompt embeddings. + + Arguments: + image_embeddings (torch.Tensor): the embeddings from the image encoder + image_pe (torch.Tensor): positional encoding with the shape of image_embeddings + sparse_prompt_embeddings (torch.Tensor): the embeddings of the points and boxes + dense_prompt_embeddings (torch.Tensor): the embeddings of the mask inputs + multimask_output (bool): Whether to return multiple masks or a single + mask. + + Returns: + torch.Tensor: batched predicted masks + torch.Tensor: batched predictions of mask quality + torch.Tensor: batched SAM token for mask output + """ + masks, iou_pred, mask_tokens_out, object_score_logits = self.predict_masks( + image_embeddings=image_embeddings, + image_pe=image_pe, + sparse_prompt_embeddings=sparse_prompt_embeddings, + dense_prompt_embeddings=dense_prompt_embeddings, + repeat_image=repeat_image, + high_res_features=high_res_features, + ) + + # Select the correct mask or masks for output + if multimask_output: + masks = masks[:, 1:, :, :] + iou_pred = iou_pred[:, 1:] + elif self.dynamic_multimask_via_stability and not self.training: + masks, iou_pred = self._dynamic_multimask_via_stability(masks, iou_pred) + else: + masks = masks[:, 0:1, :, :] + iou_pred = iou_pred[:, 0:1] + + if multimask_output and self.use_multimask_token_for_obj_ptr: + sam_tokens_out = mask_tokens_out[:, 1:] # [b, 3, c] shape + else: + # Take the mask output token. Here we *always* use the token for single mask output. + # At test time, even if we track after 1-click (and using multimask_output=True), + # we still take the single mask token here. The rationale is that we always track + # after multiple clicks during training, so the past tokens seen during training + # are always the single mask token (and we'll let it be the object-memory token). + sam_tokens_out = mask_tokens_out[:, 0:1] # [b, 1, c] shape + + # Prepare output + return masks, iou_pred, sam_tokens_out, object_score_logits + + def predict_masks( + self, + image_embeddings: torch.Tensor, + image_pe: torch.Tensor, + sparse_prompt_embeddings: torch.Tensor, + dense_prompt_embeddings: torch.Tensor, + repeat_image: bool, + high_res_features: Optional[List[torch.Tensor]] = None, + ) -> Tuple[torch.Tensor, torch.Tensor]: + """Predicts masks. See 'forward' for more details.""" + # Concatenate output tokens + s = 0 + if self.pred_obj_scores: + output_tokens = torch.cat( + [ + self.obj_score_token.weight, + self.iou_token.weight, + self.mask_tokens.weight, + ], + dim=0, + ) + s = 1 + else: + output_tokens = torch.cat( + [self.iou_token.weight, self.mask_tokens.weight], dim=0 + ) + output_tokens = output_tokens.unsqueeze(0).expand( + sparse_prompt_embeddings.size(0), -1, -1 + ) + tokens = torch.cat((output_tokens, sparse_prompt_embeddings), dim=1) + + # Expand per-image data in batch direction to be per-mask + if repeat_image: + src = torch.repeat_interleave(image_embeddings, tokens.shape[0], dim=0) + else: + assert image_embeddings.shape[0] == tokens.shape[0] + src = image_embeddings + src = src + dense_prompt_embeddings + assert ( + image_pe.size(0) == 1 + ), "image_pe should have size 1 in batch dim (from `get_dense_pe()`)" + pos_src = torch.repeat_interleave(image_pe, tokens.shape[0], dim=0) + b, c, h, w = src.shape + + # Run the transformer + hs, src = self.transformer(src, pos_src, tokens) + iou_token_out = hs[:, s, :] + mask_tokens_out = hs[:, s + 1 : (s + 1 + self.num_mask_tokens), :] + + # Upscale mask embeddings and predict masks using the mask tokens + src = src.transpose(1, 2).view(b, c, h, w) + if not self.use_high_res_features: + upscaled_embedding = self.output_upscaling(src) + else: + dc1, ln1, act1, dc2, act2 = self.output_upscaling + feat_s0, feat_s1 = high_res_features + upscaled_embedding = act1(ln1(dc1(src) + feat_s1)) + upscaled_embedding = act2(dc2(upscaled_embedding) + feat_s0) + + hyper_in_list: List[torch.Tensor] = [] + for i in range(self.num_mask_tokens): + hyper_in_list.append( + self.output_hypernetworks_mlps[i](mask_tokens_out[:, i, :]) + ) + hyper_in = torch.stack(hyper_in_list, dim=1) + b, c, h, w = upscaled_embedding.shape + masks = (hyper_in @ upscaled_embedding.view(b, c, h * w)).view(b, -1, h, w) + + # Generate mask quality predictions + iou_pred = self.iou_prediction_head(iou_token_out) + if self.pred_obj_scores: + assert s == 1 + object_score_logits = self.pred_obj_score_head(hs[:, 0, :]) + else: + # Obj scores logits - default to 10.0, i.e. assuming the object is present, sigmoid(10)=1 + object_score_logits = 10.0 * iou_pred.new_ones(iou_pred.shape[0], 1) + + return masks, iou_pred, mask_tokens_out, object_score_logits + + def _get_stability_scores(self, mask_logits): + """ + Compute stability scores of the mask logits based on the IoU between upper and + lower thresholds. + """ + mask_logits = mask_logits.flatten(-2) + stability_delta = self.dynamic_multimask_stability_delta + area_i = torch.sum(mask_logits > stability_delta, dim=-1).float() + area_u = torch.sum(mask_logits > -stability_delta, dim=-1).float() + stability_scores = torch.where(area_u > 0, area_i / area_u, 1.0) + return stability_scores + + def _dynamic_multimask_via_stability(self, all_mask_logits, all_iou_scores): + """ + When outputting a single mask, if the stability score from the current single-mask + output (based on output token 0) falls below a threshold, we instead select from + multi-mask outputs (based on output token 1~3) the mask with the highest predicted + IoU score. This is intended to ensure a valid mask for both clicking and tracking. + """ + # The best mask from multimask output tokens (1~3) + multimask_logits = all_mask_logits[:, 1:, :, :] + multimask_iou_scores = all_iou_scores[:, 1:] + best_scores_inds = torch.argmax(multimask_iou_scores, dim=-1) + batch_inds = torch.arange( + multimask_iou_scores.size(0), device=all_iou_scores.device + ) + best_multimask_logits = multimask_logits[batch_inds, best_scores_inds] + best_multimask_logits = best_multimask_logits.unsqueeze(1) + best_multimask_iou_scores = multimask_iou_scores[batch_inds, best_scores_inds] + best_multimask_iou_scores = best_multimask_iou_scores.unsqueeze(1) + + # The mask from singlemask output token 0 and its stability score + singlemask_logits = all_mask_logits[:, 0:1, :, :] + singlemask_iou_scores = all_iou_scores[:, 0:1] + stability_scores = self._get_stability_scores(singlemask_logits) + is_stable = stability_scores >= self.dynamic_multimask_stability_thresh + + # Dynamically fall back to best multimask output upon low stability scores. + mask_logits_out = torch.where( + is_stable[..., None, None].expand_as(singlemask_logits), + singlemask_logits, + best_multimask_logits, + ) + iou_scores_out = torch.where( + is_stable.expand_as(singlemask_iou_scores), + singlemask_iou_scores, + best_multimask_iou_scores, + ) + return mask_logits_out, iou_scores_out diff --git a/freevideo_engine/sam2/modeling/sam/prompt_encoder.py b/freevideo_engine/sam2/modeling/sam/prompt_encoder.py new file mode 100644 index 00000000..1b449b75 --- /dev/null +++ b/freevideo_engine/sam2/modeling/sam/prompt_encoder.py @@ -0,0 +1,202 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +from typing import Optional, Tuple, Type + +import torch +from torch import nn + +from freevideo_engine.sam2.modeling.position_encoding import PositionEmbeddingRandom + +from freevideo_engine.sam2.modeling.sam2_utils import LayerNorm2d + + +class PromptEncoder(nn.Module): + def __init__( + self, + embed_dim: int, + image_embedding_size: Tuple[int, int], + input_image_size: Tuple[int, int], + mask_in_chans: int, + activation: Type[nn.Module] = nn.GELU, + ) -> None: + """ + Encodes prompts for input to SAM's mask decoder. + + Arguments: + embed_dim (int): The prompts' embedding dimension + image_embedding_size (tuple(int, int)): The spatial size of the + image embedding, as (H, W). + input_image_size (int): The padded size of the image as input + to the image encoder, as (H, W). + mask_in_chans (int): The number of hidden channels used for + encoding input masks. + activation (nn.Module): The activation to use when encoding + input masks. + """ + super().__init__() + self.embed_dim = embed_dim + self.input_image_size = input_image_size + self.image_embedding_size = image_embedding_size + self.pe_layer = PositionEmbeddingRandom(embed_dim // 2) + + self.num_point_embeddings: int = 4 # pos/neg point + 2 box corners + point_embeddings = [ + nn.Embedding(1, embed_dim) for i in range(self.num_point_embeddings) + ] + self.point_embeddings = nn.ModuleList(point_embeddings) + self.not_a_point_embed = nn.Embedding(1, embed_dim) + + self.mask_input_size = ( + 4 * image_embedding_size[0], + 4 * image_embedding_size[1], + ) + self.mask_downscaling = nn.Sequential( + nn.Conv2d(1, mask_in_chans // 4, kernel_size=2, stride=2), + LayerNorm2d(mask_in_chans // 4), + activation(), + nn.Conv2d(mask_in_chans // 4, mask_in_chans, kernel_size=2, stride=2), + LayerNorm2d(mask_in_chans), + activation(), + nn.Conv2d(mask_in_chans, embed_dim, kernel_size=1), + ) + self.no_mask_embed = nn.Embedding(1, embed_dim) + + def get_dense_pe(self) -> torch.Tensor: + """ + Returns the positional encoding used to encode point prompts, + applied to a dense set of points the shape of the image encoding. + + Returns: + torch.Tensor: Positional encoding with shape + 1x(embed_dim)x(embedding_h)x(embedding_w) + """ + return self.pe_layer(self.image_embedding_size).unsqueeze(0) + + def _embed_points( + self, + points: torch.Tensor, + labels: torch.Tensor, + pad: bool, + ) -> torch.Tensor: + """Embeds point prompts.""" + points = points + 0.5 # Shift to center of pixel + if pad: + padding_point = torch.zeros((points.shape[0], 1, 2), device=points.device) + padding_label = -torch.ones((labels.shape[0], 1), device=labels.device) + points = torch.cat([points, padding_point], dim=1) + labels = torch.cat([labels, padding_label], dim=1) + point_embedding = self.pe_layer.forward_with_coords( + points, self.input_image_size + ) + + point_embedding = torch.where( + (labels == -1).unsqueeze(-1), + torch.zeros_like(point_embedding) + self.not_a_point_embed.weight, + point_embedding, + ) + point_embedding = torch.where( + (labels == 0).unsqueeze(-1), + point_embedding + self.point_embeddings[0].weight, + point_embedding, + ) + point_embedding = torch.where( + (labels == 1).unsqueeze(-1), + point_embedding + self.point_embeddings[1].weight, + point_embedding, + ) + point_embedding = torch.where( + (labels == 2).unsqueeze(-1), + point_embedding + self.point_embeddings[2].weight, + point_embedding, + ) + point_embedding = torch.where( + (labels == 3).unsqueeze(-1), + point_embedding + self.point_embeddings[3].weight, + point_embedding, + ) + return point_embedding + + def _embed_boxes(self, boxes: torch.Tensor) -> torch.Tensor: + """Embeds box prompts.""" + boxes = boxes + 0.5 # Shift to center of pixel + coords = boxes.reshape(-1, 2, 2) + corner_embedding = self.pe_layer.forward_with_coords( + coords, self.input_image_size + ) + corner_embedding[:, 0, :] += self.point_embeddings[2].weight + corner_embedding[:, 1, :] += self.point_embeddings[3].weight + return corner_embedding + + def _embed_masks(self, masks: torch.Tensor) -> torch.Tensor: + """Embeds mask inputs.""" + mask_embedding = self.mask_downscaling(masks) + return mask_embedding + + def _get_batch_size( + self, + points: Optional[Tuple[torch.Tensor, torch.Tensor]], + boxes: Optional[torch.Tensor], + masks: Optional[torch.Tensor], + ) -> int: + """ + Gets the batch size of the output given the batch size of the input prompts. + """ + if points is not None: + return points[0].shape[0] + elif boxes is not None: + return boxes.shape[0] + elif masks is not None: + return masks.shape[0] + else: + return 1 + + def _get_device(self) -> torch.device: + return self.point_embeddings[0].weight.device + + def forward( + self, + points: Optional[Tuple[torch.Tensor, torch.Tensor]], + boxes: Optional[torch.Tensor], + masks: Optional[torch.Tensor], + ) -> Tuple[torch.Tensor, torch.Tensor]: + """ + Embeds different types of prompts, returning both sparse and dense + embeddings. + + Arguments: + points (tuple(torch.Tensor, torch.Tensor) or none): point coordinates + and labels to embed. + boxes (torch.Tensor or none): boxes to embed + masks (torch.Tensor or none): masks to embed + + Returns: + torch.Tensor: sparse embeddings for the points and boxes, with shape + BxNx(embed_dim), where N is determined by the number of input points + and boxes. + torch.Tensor: dense embeddings for the masks, in the shape + Bx(embed_dim)x(embed_H)x(embed_W) + """ + bs = self._get_batch_size(points, boxes, masks) + sparse_embeddings = torch.empty( + (bs, 0, self.embed_dim), device=self._get_device() + ) + if points is not None: + coords, labels = points + point_embeddings = self._embed_points(coords, labels, pad=(boxes is None)) + sparse_embeddings = torch.cat([sparse_embeddings, point_embeddings], dim=1) + if boxes is not None: + box_embeddings = self._embed_boxes(boxes) + sparse_embeddings = torch.cat([sparse_embeddings, box_embeddings], dim=1) + + if masks is not None: + dense_embeddings = self._embed_masks(masks) + else: + dense_embeddings = self.no_mask_embed.weight.reshape(1, -1, 1, 1).expand( + bs, -1, self.image_embedding_size[0], self.image_embedding_size[1] + ) + + return sparse_embeddings, dense_embeddings diff --git a/freevideo_engine/sam2/modeling/sam/transformer.py b/freevideo_engine/sam2/modeling/sam/transformer.py new file mode 100644 index 00000000..3855c1f9 --- /dev/null +++ b/freevideo_engine/sam2/modeling/sam/transformer.py @@ -0,0 +1,310 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +import math +from functools import partial +from typing import Tuple, Type + +import torch +import torch.nn.functional as F +from torch import nn, Tensor + +from freevideo_engine.sam2.modeling.position_encoding import apply_rotary_enc, compute_axial_cis +from freevideo_engine.sam2.modeling.sam2_utils import MLP + + +class TwoWayTransformer(nn.Module): + def __init__( + self, + depth: int, + embedding_dim: int, + num_heads: int, + mlp_dim: int, + activation: Type[nn.Module] = nn.ReLU, + attention_downsample_rate: int = 2, + ) -> None: + """ + A transformer decoder that attends to an input image using + queries whose positional embedding is supplied. + + Args: + depth (int): number of layers in the transformer + embedding_dim (int): the channel dimension for the input embeddings + num_heads (int): the number of heads for multihead attention. Must + divide embedding_dim + mlp_dim (int): the channel dimension internal to the MLP block + activation (nn.Module): the activation to use in the MLP block + """ + super().__init__() + self.depth = depth + self.embedding_dim = embedding_dim + self.num_heads = num_heads + self.mlp_dim = mlp_dim + self.layers = nn.ModuleList() + + for i in range(depth): + self.layers.append( + TwoWayAttentionBlock( + embedding_dim=embedding_dim, + num_heads=num_heads, + mlp_dim=mlp_dim, + activation=activation, + attention_downsample_rate=attention_downsample_rate, + skip_first_layer_pe=(i == 0), + ) + ) + + self.final_attn_token_to_image = Attention( + embedding_dim, num_heads, downsample_rate=attention_downsample_rate + ) + self.norm_final_attn = nn.LayerNorm(embedding_dim) + + def forward( + self, + image_embedding: Tensor, + image_pe: Tensor, + point_embedding: Tensor, + ) -> Tuple[Tensor, Tensor]: + """ + Args: + image_embedding (torch.Tensor): image to attend to. Should be shape + B x embedding_dim x h x w for any h and w. + image_pe (torch.Tensor): the positional encoding to add to the image. Must + have the same shape as image_embedding. + point_embedding (torch.Tensor): the embedding to add to the query points. + Must have shape B x N_points x embedding_dim for any N_points. + + Returns: + torch.Tensor: the processed point_embedding + torch.Tensor: the processed image_embedding + """ + # BxCxHxW -> BxHWxC == B x N_image_tokens x C + bs, c, h, w = image_embedding.shape + image_embedding = image_embedding.flatten(2).permute(0, 2, 1) + image_pe = image_pe.flatten(2).permute(0, 2, 1) + + # Prepare queries + queries = point_embedding + keys = image_embedding + + # Apply transformer blocks and final layernorm + for layer in self.layers: + queries, keys = layer( + queries=queries, + keys=keys, + query_pe=point_embedding, + key_pe=image_pe, + ) + + # Apply the final attention layer from the points to the image + q = queries + point_embedding + k = keys + image_pe + attn_out = self.final_attn_token_to_image(q=q, k=k, v=keys) + queries = queries + attn_out + queries = self.norm_final_attn(queries) + + return queries, keys + + +class TwoWayAttentionBlock(nn.Module): + def __init__( + self, + embedding_dim: int, + num_heads: int, + mlp_dim: int = 2048, + activation: Type[nn.Module] = nn.ReLU, + attention_downsample_rate: int = 2, + skip_first_layer_pe: bool = False, + ) -> None: + """ + A transformer block with four layers: (1) self-attention of sparse + inputs, (2) cross attention of sparse inputs to dense inputs, (3) mlp + block on sparse inputs, and (4) cross attention of dense inputs to sparse + inputs. + + Arguments: + embedding_dim (int): the channel dimension of the embeddings + num_heads (int): the number of heads in the attention layers + mlp_dim (int): the hidden dimension of the mlp block + activation (nn.Module): the activation of the mlp block + skip_first_layer_pe (bool): skip the PE on the first layer + """ + super().__init__() + self.self_attn = Attention(embedding_dim, num_heads) + self.norm1 = nn.LayerNorm(embedding_dim) + + self.cross_attn_token_to_image = Attention( + embedding_dim, num_heads, downsample_rate=attention_downsample_rate + ) + self.norm2 = nn.LayerNorm(embedding_dim) + + self.mlp = MLP( + embedding_dim, mlp_dim, embedding_dim, num_layers=2, activation=activation + ) + self.norm3 = nn.LayerNorm(embedding_dim) + + self.norm4 = nn.LayerNorm(embedding_dim) + self.cross_attn_image_to_token = Attention( + embedding_dim, num_heads, downsample_rate=attention_downsample_rate + ) + + self.skip_first_layer_pe = skip_first_layer_pe + + def forward( + self, queries: Tensor, keys: Tensor, query_pe: Tensor, key_pe: Tensor + ) -> Tuple[Tensor, Tensor]: + # Self attention block + if self.skip_first_layer_pe: + queries = self.self_attn(q=queries, k=queries, v=queries) + else: + q = queries + query_pe + attn_out = self.self_attn(q=q, k=q, v=queries) + queries = queries + attn_out + queries = self.norm1(queries) + + # Cross attention block, tokens attending to image embedding + q = queries + query_pe + k = keys + key_pe + attn_out = self.cross_attn_token_to_image(q=q, k=k, v=keys) + queries = queries + attn_out + queries = self.norm2(queries) + + # MLP block + mlp_out = self.mlp(queries) + queries = queries + mlp_out + queries = self.norm3(queries) + + # Cross attention block, image embedding attending to tokens + q = queries + query_pe + k = keys + key_pe + attn_out = self.cross_attn_image_to_token(q=k, k=q, v=queries) + keys = keys + attn_out + keys = self.norm4(keys) + + return queries, keys + + +class Attention(nn.Module): + """ + An attention layer that allows for downscaling the size of the embedding + after projection to queries, keys, and values. + """ + + def __init__( + self, + embedding_dim: int, + num_heads: int, + downsample_rate: int = 1, + dropout: float = 0.0, + kv_in_dim: int = None, + ) -> None: + super().__init__() + self.embedding_dim = embedding_dim + self.kv_in_dim = kv_in_dim if kv_in_dim is not None else embedding_dim + self.internal_dim = embedding_dim // downsample_rate + self.num_heads = num_heads + assert ( + self.internal_dim % num_heads == 0 + ), "num_heads must divide embedding_dim." + + self.q_proj = nn.Linear(embedding_dim, self.internal_dim) + self.k_proj = nn.Linear(self.kv_in_dim, self.internal_dim) + self.v_proj = nn.Linear(self.kv_in_dim, self.internal_dim) + self.out_proj = nn.Linear(self.internal_dim, embedding_dim) + + self.dropout_p = dropout + + def _separate_heads(self, x: Tensor, num_heads: int) -> Tensor: + b, n, c = x.shape + x = x.reshape(b, n, num_heads, c // num_heads) + return x.transpose(1, 2) # B x N_heads x N_tokens x C_per_head + + def _recombine_heads(self, x: Tensor) -> Tensor: + b, n_heads, n_tokens, c_per_head = x.shape + x = x.transpose(1, 2) + return x.reshape(b, n_tokens, n_heads * c_per_head) # B x N_tokens x C + + def forward(self, q: Tensor, k: Tensor, v: Tensor) -> Tensor: + # Input projections + q = self.q_proj(q) + k = self.k_proj(k) + v = self.v_proj(v) + + # Separate into heads + q = self._separate_heads(q, self.num_heads) + k = self._separate_heads(k, self.num_heads) + v = self._separate_heads(v, self.num_heads) + + dropout_p = self.dropout_p if self.training else 0.0 + # Attention + out = F.scaled_dot_product_attention(q, k, v, dropout_p=dropout_p) + + out = self._recombine_heads(out) + out = self.out_proj(out) + + return out + + +class RoPEAttention(Attention): + """Attention with rotary position encoding.""" + + def __init__( + self, + *args, + rope_theta=10000.0, + # whether to repeat q rope to match k length + # this is needed for cross-attention to memories + rope_k_repeat=False, + feat_sizes=(64, 64), # [w, h] for stride 16 feats at 1024 resolution + **kwargs, + ): + super().__init__(*args, **kwargs) + + self.compute_cis = partial( + compute_axial_cis, dim=self.internal_dim // self.num_heads, theta=rope_theta + ) + freqs_cis = self.compute_cis(end_x=feat_sizes[0], end_y=feat_sizes[1]) + # FreeVideo: this inference snapshot is CPU-only, including construction. + self.freqs_cis = freqs_cis + self.rope_k_repeat = rope_k_repeat + + def forward( + self, q: Tensor, k: Tensor, v: Tensor, num_k_exclude_rope: int = 0 + ) -> Tensor: + # Input projections + q = self.q_proj(q) + k = self.k_proj(k) + v = self.v_proj(v) + + # Separate into heads + q = self._separate_heads(q, self.num_heads) + k = self._separate_heads(k, self.num_heads) + v = self._separate_heads(v, self.num_heads) + + # Apply rotary position encoding + w = h = math.sqrt(q.shape[-2]) + self.freqs_cis = self.freqs_cis.to(q.device) + if self.freqs_cis.shape[0] != q.shape[-2]: + self.freqs_cis = self.compute_cis(end_x=w, end_y=h).to(q.device) + if q.shape[-2] != k.shape[-2]: + assert self.rope_k_repeat + + num_k_rope = k.size(-2) - num_k_exclude_rope + q, k[:, :, :num_k_rope] = apply_rotary_enc( + q, + k[:, :, :num_k_rope], + freqs_cis=self.freqs_cis, + repeat_freqs_k=self.rope_k_repeat, + ) + + dropout_p = self.dropout_p if self.training else 0.0 + # Attention + out = F.scaled_dot_product_attention(q, k, v, dropout_p=dropout_p) + + out = self._recombine_heads(out) + out = self.out_proj(out) + + return out diff --git a/freevideo_engine/sam2/modeling/sam2_base.py b/freevideo_engine/sam2/modeling/sam2_base.py new file mode 100644 index 00000000..8b57dd0a --- /dev/null +++ b/freevideo_engine/sam2/modeling/sam2_base.py @@ -0,0 +1,909 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +import torch +import torch.distributed +import torch.nn.functional as F + +from torch.nn.init import trunc_normal_ + +from freevideo_engine.sam2.modeling.sam.mask_decoder import MaskDecoder +from freevideo_engine.sam2.modeling.sam.prompt_encoder import PromptEncoder +from freevideo_engine.sam2.modeling.sam.transformer import TwoWayTransformer +from freevideo_engine.sam2.modeling.sam2_utils import get_1d_sine_pe, MLP, select_closest_cond_frames + +# a large negative value as a placeholder score for missing objects +NO_OBJ_SCORE = -1024.0 + + +class SAM2Base(torch.nn.Module): + def __init__( + self, + image_encoder, + memory_attention, + memory_encoder, + num_maskmem=7, # default 1 input frame + 6 previous frames + image_size=512, + backbone_stride=16, # stride of the image backbone output + sigmoid_scale_for_mem_enc=1.0, # scale factor for mask sigmoid prob + sigmoid_bias_for_mem_enc=0.0, # bias factor for mask sigmoid prob + # During evaluation, whether to binarize the sigmoid mask logits on interacted frames with clicks + binarize_mask_from_pts_for_mem_enc=False, + use_mask_input_as_output_without_sam=False, # on frames with mask input, whether to directly output the input mask without using a SAM prompt encoder + mask decoder + # The maximum number of conditioning frames to participate in the memory attention (-1 means no limit; if there are more conditioning frames than this limit, + # we only cross-attend to the temporally closest `max_cond_frames_in_attn` conditioning frames in the encoder when tracking each frame). This gives the model + # a temporal locality when handling a large number of annotated frames (since closer frames should be more important) and also avoids GPU OOM. + max_cond_frames_in_attn=-1, + # on the first frame, whether to directly add the no-memory embedding to the image feature + # (instead of using the transformer encoder) + directly_add_no_mem_embed=False, + # whether to use high-resolution feature maps in the SAM mask decoder + use_high_res_features_in_sam=False, + # whether to output multiple (3) masks for the first click on initial conditioning frames + multimask_output_in_sam=False, + # the minimum and maximum number of clicks to use multimask_output_in_sam (only relevant when `multimask_output_in_sam=True`; + # default is 1 for both, meaning that only the first click gives multimask output; also note that a box counts as two points) + multimask_min_pt_num=1, + multimask_max_pt_num=1, + # whether to also use multimask output for tracking (not just for the first click on initial conditioning frames; only relevant when `multimask_output_in_sam=True`) + multimask_output_for_tracking=False, + # Whether to use multimask tokens for obj ptr; Only relevant when both + # use_obj_ptrs_in_encoder=True and multimask_output_for_tracking=True + use_multimask_token_for_obj_ptr: bool = False, + # whether to use sigmoid to restrict ious prediction to [0-1] + iou_prediction_use_sigmoid=False, + # The memory bank's temporal stride during evaluation (i.e. the `r` parameter in XMem and Cutie; XMem and Cutie use r=5). + # For r>1, the (self.num_maskmem - 1) non-conditioning memory frames consist of + # (self.num_maskmem - 2) nearest frames from every r-th frames, plus the last frame. + memory_temporal_stride_for_eval=1, + # whether to apply non-overlapping constraints on the object masks in the memory encoder during evaluation (to avoid/alleviate superposing masks) + non_overlap_masks_for_mem_enc=False, + # whether to cross-attend to object pointers from other frames (based on SAM output tokens) in the encoder + use_obj_ptrs_in_encoder=False, + # the maximum number of object pointers from other frames in encoder cross attention (only relevant when `use_obj_ptrs_in_encoder=True`) + max_obj_ptrs_in_encoder=16, + # whether to add temporal positional encoding to the object pointers in the encoder (only relevant when `use_obj_ptrs_in_encoder=True`) + add_tpos_enc_to_obj_ptrs=True, + # whether to add an extra linear projection layer for the temporal positional encoding in the object pointers to avoid potential interference + # with spatial positional encoding (only relevant when both `use_obj_ptrs_in_encoder=True` and `add_tpos_enc_to_obj_ptrs=True`) + proj_tpos_enc_in_obj_ptrs=False, + # whether to use signed distance (instead of unsigned absolute distance) in the temporal positional encoding in the object pointers + # (only relevant when both `use_obj_ptrs_in_encoder=True` and `add_tpos_enc_to_obj_ptrs=True`) + use_signed_tpos_enc_to_obj_ptrs=False, + # whether to only attend to object pointers in the past (before the current frame) in the encoder during evaluation + # (only relevant when `use_obj_ptrs_in_encoder=True`; this might avoid pointer information too far in the future to distract the initial tracking) + only_obj_ptrs_in_the_past_for_eval=False, + # Whether to predict if there is an object in the frame + pred_obj_scores: bool = False, + # Whether to use an MLP to predict object scores + pred_obj_scores_mlp: bool = False, + # Only relevant if pred_obj_scores=True and use_obj_ptrs_in_encoder=True; + # Whether to have a fixed no obj pointer when there is no object present + # or to use it as an additive embedding with obj_ptr produced by decoder + fixed_no_obj_ptr: bool = False, + # Soft no object, i.e. mix in no_obj_ptr softly, + # hope to make recovery easier if there is a mistake and mitigate accumulation of errors + soft_no_obj_ptr: bool = False, + use_mlp_for_obj_ptr_proj: bool = False, + # add no obj embedding to spatial frames + no_obj_embed_spatial: bool = False, + # extra arguments used to construct the SAM mask decoder; if not None, it should be a dict of kwargs to be passed into `MaskDecoder` class. + sam_mask_decoder_extra_args=None, + compile_image_encoder: bool = False, + ): + super().__init__() + + # Part 1: the image backbone + self.image_encoder = image_encoder + # Use level 0, 1, 2 for high-res setting, or just level 2 for the default setting + self.use_high_res_features_in_sam = use_high_res_features_in_sam + self.num_feature_levels = 3 if use_high_res_features_in_sam else 1 + self.use_obj_ptrs_in_encoder = use_obj_ptrs_in_encoder + self.max_obj_ptrs_in_encoder = max_obj_ptrs_in_encoder + if use_obj_ptrs_in_encoder: + # A conv layer to downsample the mask prompt to stride 4 (the same stride as + # low-res SAM mask logits) and to change its scales from 0~1 to SAM logit scale, + # so that it can be fed into the SAM mask decoder to generate a pointer. + self.mask_downsample = torch.nn.Conv2d(1, 1, kernel_size=4, stride=4) + self.add_tpos_enc_to_obj_ptrs = add_tpos_enc_to_obj_ptrs + if proj_tpos_enc_in_obj_ptrs: + assert add_tpos_enc_to_obj_ptrs # these options need to be used together + self.proj_tpos_enc_in_obj_ptrs = proj_tpos_enc_in_obj_ptrs + self.use_signed_tpos_enc_to_obj_ptrs = use_signed_tpos_enc_to_obj_ptrs + self.only_obj_ptrs_in_the_past_for_eval = only_obj_ptrs_in_the_past_for_eval + + # Part 2: memory attention to condition current frame's visual features + # with memories (and obj ptrs) from past frames + self.memory_attention = memory_attention + self.hidden_dim = image_encoder.neck.d_model + + # Part 3: memory encoder for the previous frame's outputs + self.memory_encoder = memory_encoder + self.mem_dim = self.hidden_dim + if hasattr(self.memory_encoder, "out_proj") and hasattr( + self.memory_encoder.out_proj, "weight" + ): + # if there is compression of memories along channel dim + self.mem_dim = self.memory_encoder.out_proj.weight.shape[0] + self.num_maskmem = num_maskmem # Number of memories accessible + # Temporal encoding of the memories + self.maskmem_tpos_enc = torch.nn.Parameter( + torch.zeros(num_maskmem, 1, 1, self.mem_dim) + ) + trunc_normal_(self.maskmem_tpos_enc, std=0.02) + # a single token to indicate no memory embedding from previous frames + self.no_mem_embed = torch.nn.Parameter(torch.zeros(1, 1, self.hidden_dim)) + self.no_mem_pos_enc = torch.nn.Parameter(torch.zeros(1, 1, self.hidden_dim)) + trunc_normal_(self.no_mem_embed, std=0.02) + trunc_normal_(self.no_mem_pos_enc, std=0.02) + self.directly_add_no_mem_embed = directly_add_no_mem_embed + # Apply sigmoid to the output raw mask logits (to turn them from + # range (-inf, +inf) to range (0, 1)) before feeding them into the memory encoder + self.sigmoid_scale_for_mem_enc = sigmoid_scale_for_mem_enc + self.sigmoid_bias_for_mem_enc = sigmoid_bias_for_mem_enc + self.binarize_mask_from_pts_for_mem_enc = binarize_mask_from_pts_for_mem_enc + self.non_overlap_masks_for_mem_enc = non_overlap_masks_for_mem_enc + self.memory_temporal_stride_for_eval = memory_temporal_stride_for_eval + # On frames with mask input, whether to directly output the input mask without + # using a SAM prompt encoder + mask decoder + self.use_mask_input_as_output_without_sam = use_mask_input_as_output_without_sam + self.multimask_output_in_sam = multimask_output_in_sam + self.multimask_min_pt_num = multimask_min_pt_num + self.multimask_max_pt_num = multimask_max_pt_num + self.multimask_output_for_tracking = multimask_output_for_tracking + self.use_multimask_token_for_obj_ptr = use_multimask_token_for_obj_ptr + self.iou_prediction_use_sigmoid = iou_prediction_use_sigmoid + + # Part 4: SAM-style prompt encoder (for both mask and point inputs) + # and SAM-style mask decoder for the final mask output + self.image_size = image_size + self.backbone_stride = backbone_stride + self.sam_mask_decoder_extra_args = sam_mask_decoder_extra_args + self.pred_obj_scores = pred_obj_scores + self.pred_obj_scores_mlp = pred_obj_scores_mlp + self.fixed_no_obj_ptr = fixed_no_obj_ptr + self.soft_no_obj_ptr = soft_no_obj_ptr + if self.fixed_no_obj_ptr: + assert self.pred_obj_scores + assert self.use_obj_ptrs_in_encoder + if self.pred_obj_scores and self.use_obj_ptrs_in_encoder: + self.no_obj_ptr = torch.nn.Parameter(torch.zeros(1, self.hidden_dim)) + trunc_normal_(self.no_obj_ptr, std=0.02) + self.use_mlp_for_obj_ptr_proj = use_mlp_for_obj_ptr_proj + self.no_obj_embed_spatial = None + if no_obj_embed_spatial: + self.no_obj_embed_spatial = torch.nn.Parameter(torch.zeros(1, self.mem_dim)) + trunc_normal_(self.no_obj_embed_spatial, std=0.02) + + self._build_sam_heads() + self.max_cond_frames_in_attn = max_cond_frames_in_attn + + # Model compilation + if compile_image_encoder: + # Compile the forward function (not the full module) to allow loading checkpoints. + print( + "Image encoder compilation is enabled. First forward pass will be slow." + ) + self.image_encoder.forward = torch.compile( + self.image_encoder.forward, + mode="max-autotune", + fullgraph=True, + dynamic=False, + ) + + @property + def device(self): + return next(self.parameters()).device + + def forward(self, *args, **kwargs): + raise NotImplementedError( + "Please use the corresponding methods in SAM2VideoPredictor for inference or SAM2Train for training/fine-tuning" + "See notebooks/video_predictor_example.ipynb for an inference example." + ) + + def _build_sam_heads(self): + """Build SAM-style prompt encoder and mask decoder.""" + self.sam_prompt_embed_dim = self.hidden_dim + self.sam_image_embedding_size = self.image_size // self.backbone_stride + + # build PromptEncoder and MaskDecoder from SAM + # (their hyperparameters like `mask_in_chans=16` are from SAM code) + self.sam_prompt_encoder = PromptEncoder( + embed_dim=self.sam_prompt_embed_dim, + image_embedding_size=( + self.sam_image_embedding_size, + self.sam_image_embedding_size, + ), + input_image_size=(self.image_size, self.image_size), + mask_in_chans=16, + ) + self.sam_mask_decoder = MaskDecoder( + num_multimask_outputs=3, + transformer=TwoWayTransformer( + depth=2, + embedding_dim=self.sam_prompt_embed_dim, + mlp_dim=2048, + num_heads=8, + ), + transformer_dim=self.sam_prompt_embed_dim, + iou_head_depth=3, + iou_head_hidden_dim=256, + use_high_res_features=self.use_high_res_features_in_sam, + iou_prediction_use_sigmoid=self.iou_prediction_use_sigmoid, + pred_obj_scores=self.pred_obj_scores, + pred_obj_scores_mlp=self.pred_obj_scores_mlp, + use_multimask_token_for_obj_ptr=self.use_multimask_token_for_obj_ptr, + **(self.sam_mask_decoder_extra_args or {}), + ) + if self.use_obj_ptrs_in_encoder: + # a linear projection on SAM output tokens to turn them into object pointers + self.obj_ptr_proj = torch.nn.Linear(self.hidden_dim, self.hidden_dim) + if self.use_mlp_for_obj_ptr_proj: + self.obj_ptr_proj = MLP( + self.hidden_dim, self.hidden_dim, self.hidden_dim, 3 + ) + else: + self.obj_ptr_proj = torch.nn.Identity() + if self.proj_tpos_enc_in_obj_ptrs: + # a linear projection on temporal positional encoding in object pointers to + # avoid potential interference with spatial positional encoding + self.obj_ptr_tpos_proj = torch.nn.Linear(self.hidden_dim, self.mem_dim) + else: + self.obj_ptr_tpos_proj = torch.nn.Identity() + + def _forward_sam_heads( + self, + backbone_features, + point_inputs=None, + mask_inputs=None, + high_res_features=None, + multimask_output=False, + ): + """ + Forward SAM prompt encoders and mask heads. + + Inputs: + - backbone_features: image features of [B, C, H, W] shape + - point_inputs: a dictionary with "point_coords" and "point_labels", where + 1) "point_coords" has [B, P, 2] shape and float32 dtype and contains the + absolute pixel-unit coordinate in (x, y) format of the P input points + 2) "point_labels" has shape [B, P] and int32 dtype, where 1 means + positive clicks, 0 means negative clicks, and -1 means padding + - mask_inputs: a mask of [B, 1, H*16, W*16] shape, float or bool, with the + same spatial size as the image. + - high_res_features: either 1) None or 2) or a list of length 2 containing + two feature maps of [B, C, 4*H, 4*W] and [B, C, 2*H, 2*W] shapes respectively, + which will be used as high-resolution feature maps for SAM decoder. + - multimask_output: if it's True, we output 3 candidate masks and their 3 + corresponding IoU estimates, and if it's False, we output only 1 mask and + its corresponding IoU estimate. + + Outputs: + - low_res_multimasks: [B, M, H*4, W*4] shape (where M = 3 if + `multimask_output=True` and M = 1 if `multimask_output=False`), the SAM + output mask logits (before sigmoid) for the low-resolution masks, with 4x + the resolution (1/4 stride) of the input backbone_features. + - high_res_multimasks: [B, M, H*16, W*16] shape (where M = 3 + if `multimask_output=True` and M = 1 if `multimask_output=False`), + upsampled from the low-resolution masks, with shape size as the image + (stride is 1 pixel). + - ious, [B, M] shape, where (where M = 3 if `multimask_output=True` and M = 1 + if `multimask_output=False`), the estimated IoU of each output mask. + - low_res_masks: [B, 1, H*4, W*4] shape, the best mask in `low_res_multimasks`. + If `multimask_output=True`, it's the mask with the highest IoU estimate. + If `multimask_output=False`, it's the same as `low_res_multimasks`. + - high_res_masks: [B, 1, H*16, W*16] shape, the best mask in `high_res_multimasks`. + If `multimask_output=True`, it's the mask with the highest IoU estimate. + If `multimask_output=False`, it's the same as `high_res_multimasks`. + - obj_ptr: [B, C] shape, the object pointer vector for the output mask, extracted + based on the output token from the SAM mask decoder. + """ + B = backbone_features.size(0) + device = backbone_features.device + assert backbone_features.size(1) == self.sam_prompt_embed_dim + assert backbone_features.size(2) == self.sam_image_embedding_size + assert backbone_features.size(3) == self.sam_image_embedding_size + + # a) Handle point prompts + if point_inputs is not None: + sam_point_coords = point_inputs["point_coords"] + sam_point_labels = point_inputs["point_labels"] + assert sam_point_coords.size(0) == B and sam_point_labels.size(0) == B + else: + # If no points are provide, pad with an empty point (with label -1) + sam_point_coords = torch.zeros(B, 1, 2, device=device) + sam_point_labels = -torch.ones(B, 1, dtype=torch.int32, device=device) + + # b) Handle mask prompts + if mask_inputs is not None: + # If mask_inputs is provided, downsize it into low-res mask input if needed + # and feed it as a dense mask prompt into the SAM mask encoder + assert len(mask_inputs.shape) == 4 and mask_inputs.shape[:2] == (B, 1) + if mask_inputs.shape[-2:] != self.sam_prompt_encoder.mask_input_size: + sam_mask_prompt = F.interpolate( + mask_inputs.float(), + size=self.sam_prompt_encoder.mask_input_size, + align_corners=False, + mode="bilinear", + antialias=True, # use antialias for downsampling + ) + else: + sam_mask_prompt = mask_inputs + else: + # Otherwise, simply feed None (and SAM's prompt encoder will add + # a learned `no_mask_embed` to indicate no mask input in this case). + sam_mask_prompt = None + + sparse_embeddings, dense_embeddings = self.sam_prompt_encoder( + points=(sam_point_coords, sam_point_labels), + boxes=None, + masks=sam_mask_prompt, + ) + ( + low_res_multimasks, + ious, + sam_output_tokens, + object_score_logits, + ) = self.sam_mask_decoder( + image_embeddings=backbone_features, + image_pe=self.sam_prompt_encoder.get_dense_pe(), + sparse_prompt_embeddings=sparse_embeddings, + dense_prompt_embeddings=dense_embeddings, + multimask_output=multimask_output, + repeat_image=False, # the image is already batched + high_res_features=high_res_features, + ) + if self.pred_obj_scores: + is_obj_appearing = object_score_logits > 0 + + # Mask used for spatial memories is always a *hard* choice between obj and no obj, + # consistent with the actual mask prediction + low_res_multimasks = torch.where( + is_obj_appearing[:, None, None], + low_res_multimasks, + NO_OBJ_SCORE, + ) + + # convert masks from possibly bfloat16 (or float16) to float32 + # (older PyTorch versions before 2.1 don't support `interpolate` on bf16) + low_res_multimasks = low_res_multimasks.float() + high_res_multimasks = F.interpolate( + low_res_multimasks, + size=(self.image_size, self.image_size), + mode="bilinear", + align_corners=False, + ) + + sam_output_token = sam_output_tokens[:, 0] + if multimask_output: + # take the best mask prediction (with the highest IoU estimation) + best_iou_inds = torch.argmax(ious, dim=-1) + batch_inds = torch.arange(B, device=device) + low_res_masks = low_res_multimasks[batch_inds, best_iou_inds].unsqueeze(1) + high_res_masks = high_res_multimasks[batch_inds, best_iou_inds].unsqueeze(1) + if sam_output_tokens.size(1) > 1: + sam_output_token = sam_output_tokens[batch_inds, best_iou_inds] + else: + low_res_masks, high_res_masks = low_res_multimasks, high_res_multimasks + + # Extract object pointer from the SAM output token (with occlusion handling) + obj_ptr = self.obj_ptr_proj(sam_output_token) + if self.pred_obj_scores: + # Allow *soft* no obj ptr, unlike for masks + if self.soft_no_obj_ptr: + lambda_is_obj_appearing = object_score_logits.sigmoid() + else: + lambda_is_obj_appearing = is_obj_appearing.float() + + if self.fixed_no_obj_ptr: + obj_ptr = lambda_is_obj_appearing * obj_ptr + obj_ptr = obj_ptr + (1 - lambda_is_obj_appearing) * self.no_obj_ptr + + return ( + low_res_multimasks, + high_res_multimasks, + ious, + low_res_masks, + high_res_masks, + obj_ptr, + object_score_logits, + ) + + def _use_mask_as_output(self, backbone_features, high_res_features, mask_inputs): + """ + Directly turn binary `mask_inputs` into a output mask logits without using SAM. + (same input and output shapes as in _forward_sam_heads above). + """ + # Use -10/+10 as logits for neg/pos pixels (very close to 0/1 in prob after sigmoid). + out_scale, out_bias = 20.0, -10.0 # sigmoid(-10.0)=4.5398e-05 + mask_inputs_float = mask_inputs.float() + high_res_masks = mask_inputs_float * out_scale + out_bias + low_res_masks = F.interpolate( + high_res_masks, + size=(high_res_masks.size(-2) // 4, high_res_masks.size(-1) // 4), + align_corners=False, + mode="bilinear", + antialias=True, # use antialias for downsampling + ) + # a dummy IoU prediction of all 1's under mask input + ious = mask_inputs.new_ones(mask_inputs.size(0), 1).float() + if not self.use_obj_ptrs_in_encoder: + # all zeros as a dummy object pointer (of shape [B, C]) + obj_ptr = torch.zeros( + mask_inputs.size(0), self.hidden_dim, device=mask_inputs.device + ) + else: + # produce an object pointer using the SAM decoder from the mask input + _, _, _, _, _, obj_ptr, _ = self._forward_sam_heads( + backbone_features=backbone_features, + mask_inputs=self.mask_downsample(mask_inputs_float), + high_res_features=high_res_features, + ) + # In this method, we are treating mask_input as output, e.g. using it directly to create spatial mem; + # Below, we follow the same design axiom to use mask_input to decide if obj appears or not instead of relying + # on the object_scores from the SAM decoder. + is_obj_appearing = torch.any(mask_inputs.flatten(1).float() > 0.0, dim=1) + is_obj_appearing = is_obj_appearing[..., None] + lambda_is_obj_appearing = is_obj_appearing.float() + object_score_logits = out_scale * lambda_is_obj_appearing + out_bias + if self.pred_obj_scores: + if self.fixed_no_obj_ptr: + obj_ptr = lambda_is_obj_appearing * obj_ptr + obj_ptr = obj_ptr + (1 - lambda_is_obj_appearing) * self.no_obj_ptr + + return ( + low_res_masks, + high_res_masks, + ious, + low_res_masks, + high_res_masks, + obj_ptr, + object_score_logits, + ) + + def forward_image(self, img_batch: torch.Tensor): + """Get the image feature on the input batch.""" + backbone_out = self.image_encoder(img_batch) + if self.use_high_res_features_in_sam: + # precompute projected level 0 and level 1 features in SAM decoder + # to avoid running it again on every SAM click + backbone_out["backbone_fpn"][0] = self.sam_mask_decoder.conv_s0( + backbone_out["backbone_fpn"][0] + ) + backbone_out["backbone_fpn"][1] = self.sam_mask_decoder.conv_s1( + backbone_out["backbone_fpn"][1] + ) + return backbone_out + + def _prepare_backbone_features(self, backbone_out): + """Prepare and flatten visual features.""" + backbone_out = backbone_out.copy() + assert len(backbone_out["backbone_fpn"]) == len(backbone_out["vision_pos_enc"]) + assert len(backbone_out["backbone_fpn"]) >= self.num_feature_levels + + feature_maps = backbone_out["backbone_fpn"][-self.num_feature_levels :] + vision_pos_embeds = backbone_out["vision_pos_enc"][-self.num_feature_levels :] + + feat_sizes = [(x.shape[-2], x.shape[-1]) for x in vision_pos_embeds] + # flatten NxCxHxW to HWxNxC + vision_feats = [x.flatten(2).permute(2, 0, 1) for x in feature_maps] + vision_pos_embeds = [x.flatten(2).permute(2, 0, 1) for x in vision_pos_embeds] + + return backbone_out, vision_feats, vision_pos_embeds, feat_sizes + + def _prepare_memory_conditioned_features( + self, + frame_idx, + is_init_cond_frame, + current_vision_feats, + current_vision_pos_embeds, + feat_sizes, + output_dict, + num_frames, + track_in_reverse=False, # tracking in reverse time order (for demo usage) + ): + """Fuse the current frame's visual feature map with previous memory.""" + B = current_vision_feats[-1].size(1) # batch size on this frame + C = self.hidden_dim + H, W = feat_sizes[-1] # top-level (lowest-resolution) feature size + device = current_vision_feats[-1].device + # The case of `self.num_maskmem == 0` below is primarily used for reproducing SAM on images. + # In this case, we skip the fusion with any memory. + if self.num_maskmem == 0: # Disable memory and skip fusion + pix_feat = current_vision_feats[-1].permute(1, 2, 0).view(B, C, H, W) + return pix_feat + + num_obj_ptr_tokens = 0 + tpos_sign_mul = -1 if track_in_reverse else 1 + # Step 1: condition the visual features of the current frame on previous memories + if not is_init_cond_frame: + # Retrieve the memories encoded with the maskmem backbone + to_cat_memory, to_cat_memory_pos_embed = [], [] + # Add conditioning frames's output first (all cond frames have t_pos=0 for + # when getting temporal positional embedding below) + assert len(output_dict["cond_frame_outputs"]) > 0 + # Select a maximum number of temporally closest cond frames for cross attention + cond_outputs = output_dict["cond_frame_outputs"] + selected_cond_outputs, unselected_cond_outputs = select_closest_cond_frames( + frame_idx, cond_outputs, self.max_cond_frames_in_attn + ) + t_pos_and_prevs = [(0, out) for out in selected_cond_outputs.values()] + # Add last (self.num_maskmem - 1) frames before current frame for non-conditioning memory + # the earliest one has t_pos=1 and the latest one has t_pos=self.num_maskmem-1 + # We also allow taking the memory frame non-consecutively (with stride>1), in which case + # we take (self.num_maskmem - 2) frames among every stride-th frames plus the last frame. + stride = 1 if self.training else self.memory_temporal_stride_for_eval + for t_pos in range(1, self.num_maskmem): + t_rel = self.num_maskmem - t_pos # how many frames before current frame + if t_rel == 1: + # for t_rel == 1, we take the last frame (regardless of r) + if not track_in_reverse: + # the frame immediately before this frame (i.e. frame_idx - 1) + prev_frame_idx = frame_idx - t_rel + else: + # the frame immediately after this frame (i.e. frame_idx + 1) + prev_frame_idx = frame_idx + t_rel + else: + # for t_rel >= 2, we take the memory frame from every r-th frames + if not track_in_reverse: + # first find the nearest frame among every r-th frames before this frame + # for r=1, this would be (frame_idx - 2) + prev_frame_idx = ((frame_idx - 2) // stride) * stride + # then seek further among every r-th frames + prev_frame_idx = prev_frame_idx - (t_rel - 2) * stride + else: + # first find the nearest frame among every r-th frames after this frame + # for r=1, this would be (frame_idx + 2) + prev_frame_idx = -(-(frame_idx + 2) // stride) * stride + # then seek further among every r-th frames + prev_frame_idx = prev_frame_idx + (t_rel - 2) * stride + out = output_dict["non_cond_frame_outputs"].get(prev_frame_idx, None) + if out is None: + # If an unselected conditioning frame is among the last (self.num_maskmem - 1) + # frames, we still attend to it as if it's a non-conditioning frame. + out = unselected_cond_outputs.get(prev_frame_idx, None) + t_pos_and_prevs.append((t_pos, out)) + + for t_pos, prev in t_pos_and_prevs: + if prev is None: + continue # skip padding frames + # "maskmem_features" might have been offloaded to CPU in demo use cases, + # so we load it back to GPU (it's a no-op if it's already on GPU). + feats = prev["maskmem_features"].to(device, non_blocking=True) + to_cat_memory.append(feats.flatten(2).permute(2, 0, 1)) + # Spatial positional encoding (it might have been offloaded to CPU in eval) + maskmem_enc = prev["maskmem_pos_enc"][-1].to(device) + maskmem_enc = maskmem_enc.flatten(2).permute(2, 0, 1) + # Temporal positional encoding + maskmem_enc = ( + maskmem_enc + self.maskmem_tpos_enc[self.num_maskmem - t_pos - 1] + ) + to_cat_memory_pos_embed.append(maskmem_enc) + + # Construct the list of past object pointers + if self.use_obj_ptrs_in_encoder: + max_obj_ptrs_in_encoder = min(num_frames, self.max_obj_ptrs_in_encoder) + # First add those object pointers from selected conditioning frames + # (optionally, only include object pointers in the past during evaluation) + if not self.training and self.only_obj_ptrs_in_the_past_for_eval: + ptr_cond_outputs = { + t: out + for t, out in selected_cond_outputs.items() + if (t >= frame_idx if track_in_reverse else t <= frame_idx) + } + else: + ptr_cond_outputs = selected_cond_outputs + pos_and_ptrs = [ + # Temporal pos encoding contains how far away each pointer is from current frame + ( + ( + (frame_idx - t) * tpos_sign_mul + if self.use_signed_tpos_enc_to_obj_ptrs + else abs(frame_idx - t) + ), + out["obj_ptr"], + ) + for t, out in ptr_cond_outputs.items() + ] + # Add up to (max_obj_ptrs_in_encoder - 1) non-conditioning frames before current frame + for t_diff in range(1, max_obj_ptrs_in_encoder): + t = frame_idx + t_diff if track_in_reverse else frame_idx - t_diff + if t < 0 or (num_frames is not None and t >= num_frames): + break + out = output_dict["non_cond_frame_outputs"].get( + t, unselected_cond_outputs.get(t, None) + ) + if out is not None: + pos_and_ptrs.append((t_diff, out["obj_ptr"])) + # If we have at least one object pointer, add them to the across attention + if len(pos_and_ptrs) > 0: + pos_list, ptrs_list = zip(*pos_and_ptrs) + # stack object pointers along dim=0 into [ptr_seq_len, B, C] shape + obj_ptrs = torch.stack(ptrs_list, dim=0) + # a temporal positional embedding based on how far each object pointer is from + # the current frame (sine embedding normalized by the max pointer num). + if self.add_tpos_enc_to_obj_ptrs: + t_diff_max = max_obj_ptrs_in_encoder - 1 + tpos_dim = C if self.proj_tpos_enc_in_obj_ptrs else self.mem_dim + obj_pos = torch.tensor(pos_list).to( + device=device, non_blocking=True + ) + obj_pos = get_1d_sine_pe(obj_pos / t_diff_max, dim=tpos_dim) + obj_pos = self.obj_ptr_tpos_proj(obj_pos) + obj_pos = obj_pos.unsqueeze(1).expand(-1, B, self.mem_dim) + else: + obj_pos = obj_ptrs.new_zeros(len(pos_list), B, self.mem_dim) + if self.mem_dim < C: + # split a pointer into (C // self.mem_dim) tokens for self.mem_dim < C + obj_ptrs = obj_ptrs.reshape( + -1, B, C // self.mem_dim, self.mem_dim + ) + obj_ptrs = obj_ptrs.permute(0, 2, 1, 3).flatten(0, 1) + obj_pos = obj_pos.repeat_interleave(C // self.mem_dim, dim=0) + to_cat_memory.append(obj_ptrs) + to_cat_memory_pos_embed.append(obj_pos) + num_obj_ptr_tokens = obj_ptrs.shape[0] + else: + num_obj_ptr_tokens = 0 + else: + # for initial conditioning frames, encode them without using any previous memory + if self.directly_add_no_mem_embed: + # directly add no-mem embedding (instead of using the transformer encoder) + pix_feat_with_mem = current_vision_feats[-1] + self.no_mem_embed + pix_feat_with_mem = pix_feat_with_mem.permute(1, 2, 0).view(B, C, H, W) + return pix_feat_with_mem + + # Use a dummy token on the first frame (to avoid empty memory input to tranformer encoder) + to_cat_memory = [self.no_mem_embed.expand(1, B, self.mem_dim)] + to_cat_memory_pos_embed = [self.no_mem_pos_enc.expand(1, B, self.mem_dim)] + + # Step 2: Concatenate the memories and forward through the transformer encoder + memory = torch.cat(to_cat_memory, dim=0) + memory_pos_embed = torch.cat(to_cat_memory_pos_embed, dim=0) + + pix_feat_with_mem = self.memory_attention( + curr=current_vision_feats, + curr_pos=current_vision_pos_embeds, + memory=memory, + memory_pos=memory_pos_embed, + num_obj_ptr_tokens=num_obj_ptr_tokens, + ) + # reshape the output (HW)BC => BCHW + pix_feat_with_mem = pix_feat_with_mem.permute(1, 2, 0).view(B, C, H, W) + return pix_feat_with_mem + + def _encode_new_memory( + self, + current_vision_feats, + feat_sizes, + pred_masks_high_res, + object_score_logits, + is_mask_from_pts, + ): + """Encode the current image and its prediction into a memory feature.""" + B = current_vision_feats[-1].size(1) # batch size on this frame + C = self.hidden_dim + H, W = feat_sizes[-1] # top-level (lowest-resolution) feature size + # top-level feature, (HW)BC => BCHW + pix_feat = current_vision_feats[-1].permute(1, 2, 0).view(B, C, H, W) + if self.non_overlap_masks_for_mem_enc and not self.training: + # optionally, apply non-overlapping constraints to the masks (it's applied + # in the batch dimension and should only be used during eval, where all + # the objects come from the same video under batch size 1). + pred_masks_high_res = self._apply_non_overlapping_constraints( + pred_masks_high_res + ) + # scale the raw mask logits with a temperature before applying sigmoid + binarize = self.binarize_mask_from_pts_for_mem_enc and is_mask_from_pts + if binarize and not self.training: + mask_for_mem = (pred_masks_high_res > 0).float() + else: + # apply sigmoid on the raw mask logits to turn them into range (0, 1) + mask_for_mem = torch.sigmoid(pred_masks_high_res) + # apply scale and bias terms to the sigmoid probabilities + if self.sigmoid_scale_for_mem_enc != 1.0: + mask_for_mem = mask_for_mem * self.sigmoid_scale_for_mem_enc + if self.sigmoid_bias_for_mem_enc != 0.0: + mask_for_mem = mask_for_mem + self.sigmoid_bias_for_mem_enc + maskmem_out = self.memory_encoder( + pix_feat, mask_for_mem, skip_mask_sigmoid=True # sigmoid already applied + ) + maskmem_features = maskmem_out["vision_features"] + maskmem_pos_enc = maskmem_out["vision_pos_enc"] + # add a no-object embedding to the spatial memory to indicate that the frame + # is predicted to be occluded (i.e. no object is appearing in the frame) + if self.no_obj_embed_spatial is not None: + is_obj_appearing = (object_score_logits > 0).float() + maskmem_features += ( + 1 - is_obj_appearing[..., None, None] + ) * self.no_obj_embed_spatial[..., None, None].expand( + *maskmem_features.shape + ) + + return maskmem_features, maskmem_pos_enc + + def _track_step( + self, + frame_idx, + is_init_cond_frame, + current_vision_feats, + current_vision_pos_embeds, + feat_sizes, + point_inputs, + mask_inputs, + output_dict, + num_frames, + track_in_reverse, + prev_sam_mask_logits, + ): + current_out = {"point_inputs": point_inputs, "mask_inputs": mask_inputs} + # High-resolution feature maps for the SAM head, reshape (HW)BC => BCHW + if len(current_vision_feats) > 1: + high_res_features = [ + x.permute(1, 2, 0).view(x.size(1), x.size(2), *s) + for x, s in zip(current_vision_feats[:-1], feat_sizes[:-1]) + ] + else: + high_res_features = None + if mask_inputs is not None and self.use_mask_input_as_output_without_sam: + # When use_mask_input_as_output_without_sam=True, we directly output the mask input + # (see it as a GT mask) without using a SAM prompt encoder + mask decoder. + pix_feat = current_vision_feats[-1].permute(1, 2, 0) + pix_feat = pix_feat.view(-1, self.hidden_dim, *feat_sizes[-1]) + sam_outputs = self._use_mask_as_output( + pix_feat, high_res_features, mask_inputs + ) + else: + # fused the visual feature with previous memory features in the memory bank + pix_feat = self._prepare_memory_conditioned_features( + frame_idx=frame_idx, + is_init_cond_frame=is_init_cond_frame, + current_vision_feats=current_vision_feats[-1:], + current_vision_pos_embeds=current_vision_pos_embeds[-1:], + feat_sizes=feat_sizes[-1:], + output_dict=output_dict, + num_frames=num_frames, + track_in_reverse=track_in_reverse, + ) + # apply SAM-style segmentation head + # here we might feed previously predicted low-res SAM mask logits into the SAM mask decoder, + # e.g. in demo where such logits come from earlier interaction instead of correction sampling + # (in this case, any `mask_inputs` shouldn't reach here as they are sent to _use_mask_as_output instead) + if prev_sam_mask_logits is not None: + assert point_inputs is not None and mask_inputs is None + mask_inputs = prev_sam_mask_logits + multimask_output = self._use_multimask(is_init_cond_frame, point_inputs) + sam_outputs = self._forward_sam_heads( + backbone_features=pix_feat, + point_inputs=point_inputs, + mask_inputs=mask_inputs, + high_res_features=high_res_features, + multimask_output=multimask_output, + ) + + return current_out, sam_outputs, high_res_features, pix_feat + + def _encode_memory_in_output( + self, + current_vision_feats, + feat_sizes, + point_inputs, + run_mem_encoder, + high_res_masks, + object_score_logits, + current_out, + ): + if run_mem_encoder and self.num_maskmem > 0: + high_res_masks_for_mem_enc = high_res_masks + maskmem_features, maskmem_pos_enc = self._encode_new_memory( + current_vision_feats=current_vision_feats, + feat_sizes=feat_sizes, + pred_masks_high_res=high_res_masks_for_mem_enc, + object_score_logits=object_score_logits, + is_mask_from_pts=(point_inputs is not None), + ) + current_out["maskmem_features"] = maskmem_features + current_out["maskmem_pos_enc"] = maskmem_pos_enc + else: + current_out["maskmem_features"] = None + current_out["maskmem_pos_enc"] = None + + def track_step( + self, + frame_idx, + is_init_cond_frame, + current_vision_feats, + current_vision_pos_embeds, + feat_sizes, + point_inputs, + mask_inputs, + output_dict, + num_frames, + track_in_reverse=False, # tracking in reverse time order (for demo usage) + # Whether to run the memory encoder on the predicted masks. Sometimes we might want + # to skip the memory encoder with `run_mem_encoder=False`. For example, + # in demo we might call `track_step` multiple times for each user click, + # and only encode the memory when the user finalizes their clicks. And in ablation + # settings like SAM training on static images, we don't need the memory encoder. + run_mem_encoder=True, + # The previously predicted SAM mask logits (which can be fed together with new clicks in demo). + prev_sam_mask_logits=None, + ): + current_out, sam_outputs, _, _ = self._track_step( + frame_idx, + is_init_cond_frame, + current_vision_feats, + current_vision_pos_embeds, + feat_sizes, + point_inputs, + mask_inputs, + output_dict, + num_frames, + track_in_reverse, + prev_sam_mask_logits, + ) + + ( + _, + _, + _, + low_res_masks, + high_res_masks, + obj_ptr, + object_score_logits, + ) = sam_outputs + + current_out["pred_masks"] = low_res_masks + current_out["pred_masks_high_res"] = high_res_masks + current_out["obj_ptr"] = obj_ptr + if not self.training: + # Only add this in inference (to avoid unused param in activation checkpointing; + # it's mainly used in the demo to encode spatial memories w/ consolidated masks) + current_out["object_score_logits"] = object_score_logits + + # Finally run the memory encoder on the predicted mask to encode + # it into a new memory feature (that can be used in future frames) + self._encode_memory_in_output( + current_vision_feats, + feat_sizes, + point_inputs, + run_mem_encoder, + high_res_masks, + object_score_logits, + current_out, + ) + + return current_out + + def _use_multimask(self, is_init_cond_frame, point_inputs): + """Whether to use multimask output in the SAM head.""" + num_pts = 0 if point_inputs is None else point_inputs["point_labels"].size(1) + multimask_output = ( + self.multimask_output_in_sam + and (is_init_cond_frame or self.multimask_output_for_tracking) + and (self.multimask_min_pt_num <= num_pts <= self.multimask_max_pt_num) + ) + return multimask_output + + def _apply_non_overlapping_constraints(self, pred_masks): + """ + Apply non-overlapping constraints to the object scores in pred_masks. Here we + keep only the highest scoring object at each spatial location in pred_masks. + """ + batch_size = pred_masks.size(0) + if batch_size == 1: + return pred_masks + + device = pred_masks.device + # "max_obj_inds": object index of the object with the highest score at each location + max_obj_inds = torch.argmax(pred_masks, dim=0, keepdim=True) + # "batch_obj_inds": object index of each object slice (along dim 0) in `pred_masks` + batch_obj_inds = torch.arange(batch_size, device=device)[:, None, None, None] + keep = max_obj_inds == batch_obj_inds + # suppress overlapping regions' scores below -10.0 so that the foreground regions + # don't overlap (here sigmoid(-10.0)=4.5398e-05) + pred_masks = torch.where(keep, pred_masks, torch.clamp(pred_masks, max=-10.0)) + return pred_masks diff --git a/freevideo_engine/sam2/modeling/sam2_utils.py b/freevideo_engine/sam2/modeling/sam2_utils.py new file mode 100644 index 00000000..009e9c1e --- /dev/null +++ b/freevideo_engine/sam2/modeling/sam2_utils.py @@ -0,0 +1,323 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + + +import copy +from typing import Tuple + +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F + +from freevideo_engine.sam2.utils.misc import mask_to_box + + +def select_closest_cond_frames(frame_idx, cond_frame_outputs, max_cond_frame_num): + """ + Select up to `max_cond_frame_num` conditioning frames from `cond_frame_outputs` + that are temporally closest to the current frame at `frame_idx`. Here, we take + - a) the closest conditioning frame before `frame_idx` (if any); + - b) the closest conditioning frame after `frame_idx` (if any); + - c) any other temporally closest conditioning frames until reaching a total + of `max_cond_frame_num` conditioning frames. + + Outputs: + - selected_outputs: selected items (keys & values) from `cond_frame_outputs`. + - unselected_outputs: items (keys & values) not selected in `cond_frame_outputs`. + """ + if max_cond_frame_num == -1 or len(cond_frame_outputs) <= max_cond_frame_num: + selected_outputs = cond_frame_outputs + unselected_outputs = {} + else: + assert max_cond_frame_num >= 2, "we should allow using 2+ conditioning frames" + selected_outputs = {} + + # the closest conditioning frame before `frame_idx` (if any) + idx_before = max((t for t in cond_frame_outputs if t < frame_idx), default=None) + if idx_before is not None: + selected_outputs[idx_before] = cond_frame_outputs[idx_before] + + # the closest conditioning frame after `frame_idx` (if any) + idx_after = min((t for t in cond_frame_outputs if t >= frame_idx), default=None) + if idx_after is not None: + selected_outputs[idx_after] = cond_frame_outputs[idx_after] + + # add other temporally closest conditioning frames until reaching a total + # of `max_cond_frame_num` conditioning frames. + num_remain = max_cond_frame_num - len(selected_outputs) + inds_remain = sorted( + (t for t in cond_frame_outputs if t not in selected_outputs), + key=lambda x: abs(x - frame_idx), + )[:num_remain] + selected_outputs.update((t, cond_frame_outputs[t]) for t in inds_remain) + unselected_outputs = { + t: v for t, v in cond_frame_outputs.items() if t not in selected_outputs + } + + return selected_outputs, unselected_outputs + + +def get_1d_sine_pe(pos_inds, dim, temperature=10000): + """ + Get 1D sine positional embedding as in the original Transformer paper. + """ + pe_dim = dim // 2 + dim_t = torch.arange(pe_dim, dtype=torch.float32, device=pos_inds.device) + dim_t = temperature ** (2 * (dim_t // 2) / pe_dim) + + pos_embed = pos_inds.unsqueeze(-1) / dim_t + pos_embed = torch.cat([pos_embed.sin(), pos_embed.cos()], dim=-1) + return pos_embed + + +def get_activation_fn(activation): + """Return an activation function given a string""" + if activation == "relu": + return F.relu + if activation == "gelu": + return F.gelu + if activation == "glu": + return F.glu + raise RuntimeError(f"activation should be relu/gelu, not {activation}.") + + +def get_clones(module, N): + return nn.ModuleList([copy.deepcopy(module) for i in range(N)]) + + +class DropPath(nn.Module): + # adapted from https://github.com/huggingface/pytorch-image-models/blob/main/timm/layers/drop.py + def __init__(self, drop_prob=0.0, scale_by_keep=True): + super(DropPath, self).__init__() + self.drop_prob = drop_prob + self.scale_by_keep = scale_by_keep + + def forward(self, x): + if self.drop_prob == 0.0 or not self.training: + return x + keep_prob = 1 - self.drop_prob + shape = (x.shape[0],) + (1,) * (x.ndim - 1) + random_tensor = x.new_empty(shape).bernoulli_(keep_prob) + if keep_prob > 0.0 and self.scale_by_keep: + random_tensor.div_(keep_prob) + return x * random_tensor + + +# Lightly adapted from +# https://github.com/facebookresearch/MaskFormer/blob/main/mask_former/modeling/transformer/transformer_predictor.py # noqa +class MLP(nn.Module): + def __init__( + self, + input_dim: int, + hidden_dim: int, + output_dim: int, + num_layers: int, + activation: nn.Module = nn.ReLU, + sigmoid_output: bool = False, + ) -> None: + super().__init__() + self.num_layers = num_layers + h = [hidden_dim] * (num_layers - 1) + self.layers = nn.ModuleList( + nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim]) + ) + self.sigmoid_output = sigmoid_output + self.act = activation() + + def forward(self, x): + for i, layer in enumerate(self.layers): + x = self.act(layer(x)) if i < self.num_layers - 1 else layer(x) + if self.sigmoid_output: + x = F.sigmoid(x) + return x + + +# From https://github.com/facebookresearch/detectron2/blob/main/detectron2/layers/batch_norm.py # noqa +# Itself from https://github.com/facebookresearch/ConvNeXt/blob/d1fa8f6fef0a165b27399986cc2bdacc92777e40/models/convnext.py#L119 # noqa +class LayerNorm2d(nn.Module): + def __init__(self, num_channels: int, eps: float = 1e-6) -> None: + super().__init__() + self.weight = nn.Parameter(torch.ones(num_channels)) + self.bias = nn.Parameter(torch.zeros(num_channels)) + self.eps = eps + + def forward(self, x: torch.Tensor) -> torch.Tensor: + u = x.mean(1, keepdim=True) + s = (x - u).pow(2).mean(1, keepdim=True) + x = (x - u) / torch.sqrt(s + self.eps) + x = self.weight[:, None, None] * x + self.bias[:, None, None] + return x + + +def sample_box_points( + masks: torch.Tensor, + noise: float = 0.1, # SAM default + noise_bound: int = 20, # SAM default + top_left_label: int = 2, + bottom_right_label: int = 3, +) -> Tuple[np.array, np.array]: + """ + Sample a noised version of the top left and bottom right corners of a given `bbox` + + Inputs: + - masks: [B, 1, H,W] boxes, dtype=torch.Tensor + - noise: noise as a fraction of box width and height, dtype=float + - noise_bound: maximum amount of noise (in pure pixesl), dtype=int + + Returns: + - box_coords: [B, num_pt, 2], contains (x, y) coordinates of top left and bottom right box corners, dtype=torch.float + - box_labels: [B, num_pt], label 2 is reserverd for top left and 3 for bottom right corners, dtype=torch.int32 + """ + device = masks.device + box_coords = mask_to_box(masks) + B, _, H, W = masks.shape + box_labels = torch.tensor( + [top_left_label, bottom_right_label], dtype=torch.int, device=device + ).repeat(B) + if noise > 0.0: + if not isinstance(noise_bound, torch.Tensor): + noise_bound = torch.tensor(noise_bound, device=device) + bbox_w = box_coords[..., 2] - box_coords[..., 0] + bbox_h = box_coords[..., 3] - box_coords[..., 1] + max_dx = torch.min(bbox_w * noise, noise_bound) + max_dy = torch.min(bbox_h * noise, noise_bound) + box_noise = 2 * torch.rand(B, 1, 4, device=device) - 1 + box_noise = box_noise * torch.stack((max_dx, max_dy, max_dx, max_dy), dim=-1) + + box_coords = box_coords + box_noise + img_bounds = ( + torch.tensor([W, H, W, H], device=device) - 1 + ) # uncentered pixel coords + box_coords.clamp_(torch.zeros_like(img_bounds), img_bounds) # In place clamping + + box_coords = box_coords.reshape(-1, 2, 2) # always 2 points + box_labels = box_labels.reshape(-1, 2) + return box_coords, box_labels + + +def sample_random_points_from_errors(gt_masks, pred_masks, num_pt=1): + """ + Sample `num_pt` random points (along with their labels) independently from the error regions. + + Inputs: + - gt_masks: [B, 1, H_im, W_im] masks, dtype=torch.bool + - pred_masks: [B, 1, H_im, W_im] masks, dtype=torch.bool or None + - num_pt: int, number of points to sample independently for each of the B error maps + + Outputs: + - points: [B, num_pt, 2], dtype=torch.float, contains (x, y) coordinates of each sampled point + - labels: [B, num_pt], dtype=torch.int32, where 1 means positive clicks and 0 means + negative clicks + """ + if pred_masks is None: # if pred_masks is not provided, treat it as empty + pred_masks = torch.zeros_like(gt_masks) + assert gt_masks.dtype == torch.bool and gt_masks.size(1) == 1 + assert pred_masks.dtype == torch.bool and pred_masks.shape == gt_masks.shape + assert num_pt >= 0 + + B, _, H_im, W_im = gt_masks.shape + device = gt_masks.device + + # false positive region, a new point sampled in this region should have + # negative label to correct the FP error + fp_masks = ~gt_masks & pred_masks + # false negative region, a new point sampled in this region should have + # positive label to correct the FN error + fn_masks = gt_masks & ~pred_masks + # whether the prediction completely match the ground-truth on each mask + all_correct = torch.all((gt_masks == pred_masks).flatten(2), dim=2) + all_correct = all_correct[..., None, None] + + # channel 0 is FP map, while channel 1 is FN map + pts_noise = torch.rand(B, num_pt, H_im, W_im, 2, device=device) + # sample a negative new click from FP region or a positive new click + # from FN region, depend on where the maximum falls, + # and in case the predictions are all correct (no FP or FN), we just + # sample a negative click from the background region + pts_noise[..., 0] *= fp_masks | (all_correct & ~gt_masks) + pts_noise[..., 1] *= fn_masks + pts_idx = pts_noise.flatten(2).argmax(dim=2) + labels = (pts_idx % 2).to(torch.int32) + pts_idx = pts_idx // 2 + pts_x = pts_idx % W_im + pts_y = pts_idx // W_im + points = torch.stack([pts_x, pts_y], dim=2).to(torch.float) + return points, labels + + +def sample_one_point_from_error_center(gt_masks, pred_masks, padding=True): + """ + Sample 1 random point (along with its label) from the center of each error region, + that is, the point with the largest distance to the boundary of each error region. + This is the RITM sampling method from https://github.com/saic-vul/ritm_interactive_segmentation/blob/master/isegm/inference/clicker.py + + Inputs: + - gt_masks: [B, 1, H_im, W_im] masks, dtype=torch.bool + - pred_masks: [B, 1, H_im, W_im] masks, dtype=torch.bool or None + - padding: if True, pad with boundary of 1 px for distance transform + + Outputs: + - points: [B, 1, 2], dtype=torch.float, contains (x, y) coordinates of each sampled point + - labels: [B, 1], dtype=torch.int32, where 1 means positive clicks and 0 means negative clicks + """ + import cv2 + + if pred_masks is None: + pred_masks = torch.zeros_like(gt_masks) + assert gt_masks.dtype == torch.bool and gt_masks.size(1) == 1 + assert pred_masks.dtype == torch.bool and pred_masks.shape == gt_masks.shape + + B, _, _, W_im = gt_masks.shape + device = gt_masks.device + + # false positive region, a new point sampled in this region should have + # negative label to correct the FP error + fp_masks = ~gt_masks & pred_masks + # false negative region, a new point sampled in this region should have + # positive label to correct the FN error + fn_masks = gt_masks & ~pred_masks + + fp_masks = fp_masks.cpu().numpy() + fn_masks = fn_masks.cpu().numpy() + points = torch.zeros(B, 1, 2, dtype=torch.float) + labels = torch.ones(B, 1, dtype=torch.int32) + for b in range(B): + fn_mask = fn_masks[b, 0] + fp_mask = fp_masks[b, 0] + if padding: + fn_mask = np.pad(fn_mask, ((1, 1), (1, 1)), "constant") + fp_mask = np.pad(fp_mask, ((1, 1), (1, 1)), "constant") + # compute the distance of each point in FN/FP region to its boundary + fn_mask_dt = cv2.distanceTransform(fn_mask.astype(np.uint8), cv2.DIST_L2, 0) + fp_mask_dt = cv2.distanceTransform(fp_mask.astype(np.uint8), cv2.DIST_L2, 0) + if padding: + fn_mask_dt = fn_mask_dt[1:-1, 1:-1] + fp_mask_dt = fp_mask_dt[1:-1, 1:-1] + + # take the point in FN/FP region with the largest distance to its boundary + fn_mask_dt_flat = fn_mask_dt.reshape(-1) + fp_mask_dt_flat = fp_mask_dt.reshape(-1) + fn_argmax = np.argmax(fn_mask_dt_flat) + fp_argmax = np.argmax(fp_mask_dt_flat) + is_positive = fn_mask_dt_flat[fn_argmax] > fp_mask_dt_flat[fp_argmax] + pt_idx = fn_argmax if is_positive else fp_argmax + points[b, 0, 0] = pt_idx % W_im # x + points[b, 0, 1] = pt_idx // W_im # y + labels[b, 0] = int(is_positive) + + points = points.to(device) + labels = labels.to(device) + return points, labels + + +def get_next_point(gt_masks, pred_masks, method): + if method == "uniform": + return sample_random_points_from_errors(gt_masks, pred_masks) + elif method == "center": + return sample_one_point_from_error_center(gt_masks, pred_masks) + else: + raise ValueError(f"unknown sampling method {method}") diff --git a/freevideo_engine/sam2/sam2_image_predictor.py b/freevideo_engine/sam2/sam2_image_predictor.py new file mode 100644 index 00000000..74809ec5 --- /dev/null +++ b/freevideo_engine/sam2/sam2_image_predictor.py @@ -0,0 +1,449 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +import logging + +from typing import List, Optional, Tuple, Union + +import numpy as np +import torch +from PIL.Image import Image + +from freevideo_engine.sam2.modeling.sam2_base import SAM2Base + +from freevideo_engine.sam2.utils.transforms import SAM2Transforms + + +class SAM2ImagePredictor: + def __init__( + self, + sam_model: SAM2Base, + mask_threshold=0.0, + max_hole_area=0.0, + max_sprinkle_area=0.0, + **kwargs, + ) -> None: + """ + Uses SAM-2 to calculate the image embedding for an image, and then + allow repeated, efficient mask prediction given prompts. + + Arguments: + sam_model (Sam-2): The model to use for mask prediction. + mask_threshold (float): The threshold to use when converting mask logits + to binary masks. Masks are thresholded at 0 by default. + max_hole_area (int): If max_hole_area > 0, we fill small holes in up to + the maximum area of max_hole_area in low_res_masks. + max_sprinkle_area (int): If max_sprinkle_area > 0, we remove small sprinkles up to + the maximum area of max_sprinkle_area in low_res_masks. + """ + super().__init__() + self.model = sam_model + self._transforms = SAM2Transforms( + resolution=self.model.image_size, + mask_threshold=mask_threshold, + max_hole_area=max_hole_area, + max_sprinkle_area=max_sprinkle_area, + ) + + # Predictor state + self._is_image_set = False + self._features = None + self._orig_hw = None + # Whether the predictor is set for single image or a batch of images + self._is_batch = False + + # Predictor config + self.mask_threshold = mask_threshold + + # Spatial dim for backbone feature maps + self._bb_feat_sizes = [ + (256, 256), + (128, 128), + (64, 64), + ] + + @torch.no_grad() + def set_image( + self, + image: Union[np.ndarray, Image], + ) -> None: + """ + Calculates the image embeddings for the provided image, allowing + masks to be predicted with the 'predict' method. + + Arguments: + image (np.ndarray or PIL Image): The input image to embed in RGB format. The image should be in HWC format if np.ndarray, or WHC format if PIL Image + with pixel values in [0, 255]. + image_format (str): The color format of the image, in ['RGB', 'BGR']. + """ + self.reset_predictor() + # Transform the image to the form expected by the model + if isinstance(image, np.ndarray): + logging.info("For numpy array image, we assume (HxWxC) format") + self._orig_hw = [image.shape[:2]] + elif isinstance(image, Image): + w, h = image.size + self._orig_hw = [(h, w)] + else: + raise NotImplementedError("Image format not supported") + + input_image = self._transforms(image) + input_image = input_image[None, ...].to(self.device) + + assert ( + len(input_image.shape) == 4 and input_image.shape[1] == 3 + ), f"input_image must be of size 1x3xHxW, got {input_image.shape}" + logging.info("Computing image embeddings for the provided image...") + backbone_out = self.model.forward_image(input_image) + _, vision_feats, _, _ = self.model._prepare_backbone_features(backbone_out) + # Add no_mem_embed, which is added to the lowest rest feat. map during training on videos + if self.model.directly_add_no_mem_embed: + vision_feats[-1] = vision_feats[-1] + self.model.no_mem_embed + + feats = [ + feat.permute(1, 2, 0).view(1, -1, *feat_size) + for feat, feat_size in zip(vision_feats[::-1], self._bb_feat_sizes[::-1]) + ][::-1] + self._features = {"image_embed": feats[-1], "high_res_feats": feats[:-1]} + self._is_image_set = True + logging.info("Image embeddings computed.") + + @torch.no_grad() + def set_image_batch( + self, + image_list: List[Union[np.ndarray]], + ) -> None: + """ + Calculates the image embeddings for the provided image batch, allowing + masks to be predicted with the 'predict_batch' method. + + Arguments: + image_list (List[np.ndarray]): The input images to embed in RGB format. The image should be in HWC format if np.ndarray + with pixel values in [0, 255]. + """ + self.reset_predictor() + assert isinstance(image_list, list) + self._orig_hw = [] + for image in image_list: + assert isinstance( + image, np.ndarray + ), "Images are expected to be an np.ndarray in RGB format, and of shape HWC" + self._orig_hw.append(image.shape[:2]) + # Transform the image to the form expected by the model + img_batch = self._transforms.forward_batch(image_list) + img_batch = img_batch.to(self.device) + batch_size = img_batch.shape[0] + assert ( + len(img_batch.shape) == 4 and img_batch.shape[1] == 3 + ), f"img_batch must be of size Bx3xHxW, got {img_batch.shape}" + logging.info("Computing image embeddings for the provided images...") + backbone_out = self.model.forward_image(img_batch) + _, vision_feats, _, _ = self.model._prepare_backbone_features(backbone_out) + # Add no_mem_embed, which is added to the lowest rest feat. map during training on videos + if self.model.directly_add_no_mem_embed: + vision_feats[-1] = vision_feats[-1] + self.model.no_mem_embed + + feats = [ + feat.permute(1, 2, 0).view(batch_size, -1, *feat_size) + for feat, feat_size in zip(vision_feats[::-1], self._bb_feat_sizes[::-1]) + ][::-1] + self._features = {"image_embed": feats[-1], "high_res_feats": feats[:-1]} + self._is_image_set = True + self._is_batch = True + logging.info("Image embeddings computed.") + + def predict_batch( + self, + point_coords_batch: List[np.ndarray] = None, + point_labels_batch: List[np.ndarray] = None, + box_batch: List[np.ndarray] = None, + mask_input_batch: List[np.ndarray] = None, + multimask_output: bool = True, + return_logits: bool = False, + normalize_coords=True, + ) -> Tuple[List[np.ndarray], List[np.ndarray], List[np.ndarray]]: + """This function is very similar to predict(...), however it is used for batched mode, when the model is expected to generate predictions on multiple images. + It returns a tuple of lists of masks, ious, and low_res_masks_logits. + """ + assert self._is_batch, "This function should only be used when in batched mode" + if not self._is_image_set: + raise RuntimeError( + "An image must be set with .set_image_batch(...) before mask prediction." + ) + num_images = len(self._features["image_embed"]) + all_masks = [] + all_ious = [] + all_low_res_masks = [] + for img_idx in range(num_images): + # Transform input prompts + point_coords = ( + point_coords_batch[img_idx] if point_coords_batch is not None else None + ) + point_labels = ( + point_labels_batch[img_idx] if point_labels_batch is not None else None + ) + box = box_batch[img_idx] if box_batch is not None else None + mask_input = ( + mask_input_batch[img_idx] if mask_input_batch is not None else None + ) + mask_input, unnorm_coords, labels, unnorm_box = self._prep_prompts( + point_coords, + point_labels, + box, + mask_input, + normalize_coords, + img_idx=img_idx, + ) + masks, iou_predictions, low_res_masks = self._predict( + unnorm_coords, + labels, + unnorm_box, + mask_input, + multimask_output, + return_logits=return_logits, + img_idx=img_idx, + ) + masks_np = masks.squeeze(0).float().detach().cpu().numpy() + iou_predictions_np = ( + iou_predictions.squeeze(0).float().detach().cpu().numpy() + ) + low_res_masks_np = low_res_masks.squeeze(0).float().detach().cpu().numpy() + all_masks.append(masks_np) + all_ious.append(iou_predictions_np) + all_low_res_masks.append(low_res_masks_np) + + return all_masks, all_ious, all_low_res_masks + + def predict( + self, + point_coords: Optional[np.ndarray] = None, + point_labels: Optional[np.ndarray] = None, + box: Optional[np.ndarray] = None, + mask_input: Optional[np.ndarray] = None, + multimask_output: bool = True, + return_logits: bool = False, + normalize_coords=True, + ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: + """ + Predict masks for the given input prompts, using the currently set image. + + Arguments: + point_coords (np.ndarray or None): A Nx2 array of point prompts to the + model. Each point is in (X,Y) in pixels. + point_labels (np.ndarray or None): A length N array of labels for the + point prompts. 1 indicates a foreground point and 0 indicates a + background point. + box (np.ndarray or None): A length 4 array given a box prompt to the + model, in XYXY format. + mask_input (np.ndarray): A low resolution mask input to the model, typically + coming from a previous prediction iteration. Has form 1xHxW, where + for SAM, H=W=256. + multimask_output (bool): If true, the model will return three masks. + For ambiguous input prompts (such as a single click), this will often + produce better masks than a single prediction. If only a single + mask is needed, the model's predicted quality score can be used + to select the best mask. For non-ambiguous prompts, such as multiple + input prompts, multimask_output=False can give better results. + return_logits (bool): If true, returns un-thresholded masks logits + instead of a binary mask. + normalize_coords (bool): If true, the point coordinates will be normalized to the range [0,1] and point_coords is expected to be wrt. image dimensions. + + Returns: + (np.ndarray): The output masks in CxHxW format, where C is the + number of masks, and (H, W) is the original image size. + (np.ndarray): An array of length C containing the model's + predictions for the quality of each mask. + (np.ndarray): An array of shape CxHxW, where C is the number + of masks and H=W=256. These low resolution logits can be passed to + a subsequent iteration as mask input. + """ + if not self._is_image_set: + raise RuntimeError( + "An image must be set with .set_image(...) before mask prediction." + ) + + # Transform input prompts + + mask_input, unnorm_coords, labels, unnorm_box = self._prep_prompts( + point_coords, point_labels, box, mask_input, normalize_coords + ) + + masks, iou_predictions, low_res_masks = self._predict( + unnorm_coords, + labels, + unnorm_box, + mask_input, + multimask_output, + return_logits=return_logits, + ) + + masks_np = masks.squeeze(0).float().detach().cpu().numpy() + iou_predictions_np = iou_predictions.squeeze(0).float().detach().cpu().numpy() + low_res_masks_np = low_res_masks.squeeze(0).float().detach().cpu().numpy() + return masks_np, iou_predictions_np, low_res_masks_np + + def _prep_prompts( + self, point_coords, point_labels, box, mask_logits, normalize_coords, img_idx=-1 + ): + + unnorm_coords, labels, unnorm_box, mask_input = None, None, None, None + if point_coords is not None: + assert ( + point_labels is not None + ), "point_labels must be supplied if point_coords is supplied." + point_coords = torch.as_tensor( + point_coords, dtype=torch.float, device=self.device + ) + unnorm_coords = self._transforms.transform_coords( + point_coords, normalize=normalize_coords, orig_hw=self._orig_hw[img_idx] + ) + labels = torch.as_tensor(point_labels, dtype=torch.int, device=self.device) + if len(unnorm_coords.shape) == 2: + unnorm_coords, labels = unnorm_coords[None, ...], labels[None, ...] + if box is not None: + box = torch.as_tensor(box, dtype=torch.float, device=self.device) + unnorm_box = self._transforms.transform_boxes( + box, normalize=normalize_coords, orig_hw=self._orig_hw[img_idx] + ) # Bx2x2 + if mask_logits is not None: + mask_input = torch.as_tensor( + mask_logits, dtype=torch.float, device=self.device + ) + if len(mask_input.shape) == 3: + mask_input = mask_input[None, :, :, :] + return mask_input, unnorm_coords, labels, unnorm_box + + @torch.no_grad() + def _predict( + self, + point_coords: Optional[torch.Tensor], + point_labels: Optional[torch.Tensor], + boxes: Optional[torch.Tensor] = None, + mask_input: Optional[torch.Tensor] = None, + multimask_output: bool = True, + return_logits: bool = False, + img_idx: int = -1, + ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: + """ + Predict masks for the given input prompts, using the currently set image. + Input prompts are batched torch tensors and are expected to already be + transformed to the input frame using SAM2Transforms. + + Arguments: + point_coords (torch.Tensor or None): A BxNx2 array of point prompts to the + model. Each point is in (X,Y) in pixels. + point_labels (torch.Tensor or None): A BxN array of labels for the + point prompts. 1 indicates a foreground point and 0 indicates a + background point. + boxes (np.ndarray or None): A Bx4 array given a box prompt to the + model, in XYXY format. + mask_input (np.ndarray): A low resolution mask input to the model, typically + coming from a previous prediction iteration. Has form Bx1xHxW, where + for SAM, H=W=256. Masks returned by a previous iteration of the + predict method do not need further transformation. + multimask_output (bool): If true, the model will return three masks. + For ambiguous input prompts (such as a single click), this will often + produce better masks than a single prediction. If only a single + mask is needed, the model's predicted quality score can be used + to select the best mask. For non-ambiguous prompts, such as multiple + input prompts, multimask_output=False can give better results. + return_logits (bool): If true, returns un-thresholded masks logits + instead of a binary mask. + + Returns: + (torch.Tensor): The output masks in BxCxHxW format, where C is the + number of masks, and (H, W) is the original image size. + (torch.Tensor): An array of shape BxC containing the model's + predictions for the quality of each mask. + (torch.Tensor): An array of shape BxCxHxW, where C is the number + of masks and H=W=256. These low res logits can be passed to + a subsequent iteration as mask input. + """ + if not self._is_image_set: + raise RuntimeError( + "An image must be set with .set_image(...) before mask prediction." + ) + + if point_coords is not None: + concat_points = (point_coords, point_labels) + else: + concat_points = None + + # Embed prompts + if boxes is not None: + box_coords = boxes.reshape(-1, 2, 2) + box_labels = torch.tensor([[2, 3]], dtype=torch.int, device=boxes.device) + box_labels = box_labels.repeat(boxes.size(0), 1) + # we merge "boxes" and "points" into a single "concat_points" input (where + # boxes are added at the beginning) to sam_prompt_encoder + if concat_points is not None: + concat_coords = torch.cat([box_coords, concat_points[0]], dim=1) + concat_labels = torch.cat([box_labels, concat_points[1]], dim=1) + concat_points = (concat_coords, concat_labels) + else: + concat_points = (box_coords, box_labels) + + sparse_embeddings, dense_embeddings = self.model.sam_prompt_encoder( + points=concat_points, + boxes=None, + masks=mask_input, + ) + + # Predict masks + batched_mode = ( + concat_points is not None and concat_points[0].shape[0] > 1 + ) # multi object prediction + high_res_features = [ + feat_level[img_idx].unsqueeze(0) + for feat_level in self._features["high_res_feats"] + ] + low_res_masks, iou_predictions, _, _ = self.model.sam_mask_decoder( + image_embeddings=self._features["image_embed"][img_idx].unsqueeze(0), + image_pe=self.model.sam_prompt_encoder.get_dense_pe(), + sparse_prompt_embeddings=sparse_embeddings, + dense_prompt_embeddings=dense_embeddings, + multimask_output=multimask_output, + repeat_image=batched_mode, + high_res_features=high_res_features, + ) + + # Upscale the masks to the original image resolution + masks = self._transforms.postprocess_masks( + low_res_masks, self._orig_hw[img_idx] + ) + low_res_masks = torch.clamp(low_res_masks, -32.0, 32.0) + if not return_logits: + masks = masks > self.mask_threshold + + return masks, iou_predictions, low_res_masks + + def get_image_embedding(self) -> torch.Tensor: + """ + Returns the image embeddings for the currently set image, with + shape 1xCxHxW, where C is the embedding dimension and (H,W) are + the embedding spatial dimension of SAM (typically C=256, H=W=64). + """ + if not self._is_image_set: + raise RuntimeError( + "An image must be set with .set_image(...) to generate an embedding." + ) + assert ( + self._features is not None + ), "Features must exist if an image has been set." + return self._features["image_embed"] + + @property + def device(self) -> torch.device: + return self.model.device + + def reset_predictor(self) -> None: + """ + Resets the image embeddings and other state variables. + """ + self._is_image_set = False + self._features = None + self._orig_hw = None + self._is_batch = False diff --git a/freevideo_engine/sam2/utils/__init__.py b/freevideo_engine/sam2/utils/__init__.py new file mode 100644 index 00000000..5277f461 --- /dev/null +++ b/freevideo_engine/sam2/utils/__init__.py @@ -0,0 +1,5 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. diff --git a/freevideo_engine/sam2/utils/amg.py b/freevideo_engine/sam2/utils/amg.py new file mode 100644 index 00000000..98684296 --- /dev/null +++ b/freevideo_engine/sam2/utils/amg.py @@ -0,0 +1,348 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +import math +from copy import deepcopy +from itertools import product +from typing import Any, Dict, Generator, ItemsView, List, Tuple + +import numpy as np +import torch + +# Very lightly adapted from https://github.com/facebookresearch/segment-anything/blob/main/segment_anything/utils/amg.py + + +class MaskData: + """ + A structure for storing masks and their related data in batched format. + Implements basic filtering and concatenation. + """ + + def __init__(self, **kwargs) -> None: + for v in kwargs.values(): + assert isinstance( + v, (list, np.ndarray, torch.Tensor) + ), "MaskData only supports list, numpy arrays, and torch tensors." + self._stats = dict(**kwargs) + + def __setitem__(self, key: str, item: Any) -> None: + assert isinstance( + item, (list, np.ndarray, torch.Tensor) + ), "MaskData only supports list, numpy arrays, and torch tensors." + self._stats[key] = item + + def __delitem__(self, key: str) -> None: + del self._stats[key] + + def __getitem__(self, key: str) -> Any: + return self._stats[key] + + def items(self) -> ItemsView[str, Any]: + return self._stats.items() + + def filter(self, keep: torch.Tensor) -> None: + for k, v in self._stats.items(): + if v is None: + self._stats[k] = None + elif isinstance(v, torch.Tensor): + self._stats[k] = v[torch.as_tensor(keep, device=v.device)] + elif isinstance(v, np.ndarray): + self._stats[k] = v[keep.detach().cpu().numpy()] + elif isinstance(v, list) and keep.dtype == torch.bool: + self._stats[k] = [a for i, a in enumerate(v) if keep[i]] + elif isinstance(v, list): + self._stats[k] = [v[i] for i in keep] + else: + raise TypeError(f"MaskData key {k} has an unsupported type {type(v)}.") + + def cat(self, new_stats: "MaskData") -> None: + for k, v in new_stats.items(): + if k not in self._stats or self._stats[k] is None: + self._stats[k] = deepcopy(v) + elif isinstance(v, torch.Tensor): + self._stats[k] = torch.cat([self._stats[k], v], dim=0) + elif isinstance(v, np.ndarray): + self._stats[k] = np.concatenate([self._stats[k], v], axis=0) + elif isinstance(v, list): + self._stats[k] = self._stats[k] + deepcopy(v) + else: + raise TypeError(f"MaskData key {k} has an unsupported type {type(v)}.") + + def to_numpy(self) -> None: + for k, v in self._stats.items(): + if isinstance(v, torch.Tensor): + self._stats[k] = v.float().detach().cpu().numpy() + + +def is_box_near_crop_edge( + boxes: torch.Tensor, crop_box: List[int], orig_box: List[int], atol: float = 20.0 +) -> torch.Tensor: + """Filter masks at the edge of a crop, but not at the edge of the original image.""" + crop_box_torch = torch.as_tensor(crop_box, dtype=torch.float, device=boxes.device) + orig_box_torch = torch.as_tensor(orig_box, dtype=torch.float, device=boxes.device) + boxes = uncrop_boxes_xyxy(boxes, crop_box).float() + near_crop_edge = torch.isclose(boxes, crop_box_torch[None, :], atol=atol, rtol=0) + near_image_edge = torch.isclose(boxes, orig_box_torch[None, :], atol=atol, rtol=0) + near_crop_edge = torch.logical_and(near_crop_edge, ~near_image_edge) + return torch.any(near_crop_edge, dim=1) + + +def box_xyxy_to_xywh(box_xyxy: torch.Tensor) -> torch.Tensor: + box_xywh = deepcopy(box_xyxy) + box_xywh[2] = box_xywh[2] - box_xywh[0] + box_xywh[3] = box_xywh[3] - box_xywh[1] + return box_xywh + + +def batch_iterator(batch_size: int, *args) -> Generator[List[Any], None, None]: + assert len(args) > 0 and all( + len(a) == len(args[0]) for a in args + ), "Batched iteration must have inputs of all the same size." + n_batches = len(args[0]) // batch_size + int(len(args[0]) % batch_size != 0) + for b in range(n_batches): + yield [arg[b * batch_size : (b + 1) * batch_size] for arg in args] + + +def mask_to_rle_pytorch(tensor: torch.Tensor) -> List[Dict[str, Any]]: + """ + Encodes masks to an uncompressed RLE, in the format expected by + pycoco tools. + """ + # Put in fortran order and flatten h,w + b, h, w = tensor.shape + tensor = tensor.permute(0, 2, 1).flatten(1) + + # Compute change indices + diff = tensor[:, 1:] ^ tensor[:, :-1] + change_indices = diff.nonzero() + + # Encode run length + out = [] + for i in range(b): + cur_idxs = change_indices[change_indices[:, 0] == i, 1] + cur_idxs = torch.cat( + [ + torch.tensor([0], dtype=cur_idxs.dtype, device=cur_idxs.device), + cur_idxs + 1, + torch.tensor([h * w], dtype=cur_idxs.dtype, device=cur_idxs.device), + ] + ) + btw_idxs = cur_idxs[1:] - cur_idxs[:-1] + counts = [] if tensor[i, 0] == 0 else [0] + counts.extend(btw_idxs.detach().cpu().tolist()) + out.append({"size": [h, w], "counts": counts}) + return out + + +def rle_to_mask(rle: Dict[str, Any]) -> np.ndarray: + """Compute a binary mask from an uncompressed RLE.""" + h, w = rle["size"] + mask = np.empty(h * w, dtype=bool) + idx = 0 + parity = False + for count in rle["counts"]: + mask[idx : idx + count] = parity + idx += count + parity ^= True + mask = mask.reshape(w, h) + return mask.transpose() # Put in C order + + +def area_from_rle(rle: Dict[str, Any]) -> int: + return sum(rle["counts"][1::2]) + + +def calculate_stability_score( + masks: torch.Tensor, mask_threshold: float, threshold_offset: float +) -> torch.Tensor: + """ + Computes the stability score for a batch of masks. The stability + score is the IoU between the binary masks obtained by thresholding + the predicted mask logits at high and low values. + """ + # One mask is always contained inside the other. + # Save memory by preventing unnecessary cast to torch.int64 + intersections = ( + (masks > (mask_threshold + threshold_offset)) + .sum(-1, dtype=torch.int16) + .sum(-1, dtype=torch.int32) + ) + unions = ( + (masks > (mask_threshold - threshold_offset)) + .sum(-1, dtype=torch.int16) + .sum(-1, dtype=torch.int32) + ) + return intersections / unions + + +def build_point_grid(n_per_side: int) -> np.ndarray: + """Generates a 2D grid of points evenly spaced in [0,1]x[0,1].""" + offset = 1 / (2 * n_per_side) + points_one_side = np.linspace(offset, 1 - offset, n_per_side) + points_x = np.tile(points_one_side[None, :], (n_per_side, 1)) + points_y = np.tile(points_one_side[:, None], (1, n_per_side)) + points = np.stack([points_x, points_y], axis=-1).reshape(-1, 2) + return points + + +def build_all_layer_point_grids( + n_per_side: int, n_layers: int, scale_per_layer: int +) -> List[np.ndarray]: + """Generates point grids for all crop layers.""" + points_by_layer = [] + for i in range(n_layers + 1): + n_points = int(n_per_side / (scale_per_layer**i)) + points_by_layer.append(build_point_grid(n_points)) + return points_by_layer + + +def generate_crop_boxes( + im_size: Tuple[int, ...], n_layers: int, overlap_ratio: float +) -> Tuple[List[List[int]], List[int]]: + """ + Generates a list of crop boxes of different sizes. Each layer + has (2**i)**2 boxes for the ith layer. + """ + crop_boxes, layer_idxs = [], [] + im_h, im_w = im_size + short_side = min(im_h, im_w) + + # Original image + crop_boxes.append([0, 0, im_w, im_h]) + layer_idxs.append(0) + + def crop_len(orig_len, n_crops, overlap): + return int(math.ceil((overlap * (n_crops - 1) + orig_len) / n_crops)) + + for i_layer in range(n_layers): + n_crops_per_side = 2 ** (i_layer + 1) + overlap = int(overlap_ratio * short_side * (2 / n_crops_per_side)) + + crop_w = crop_len(im_w, n_crops_per_side, overlap) + crop_h = crop_len(im_h, n_crops_per_side, overlap) + + crop_box_x0 = [int((crop_w - overlap) * i) for i in range(n_crops_per_side)] + crop_box_y0 = [int((crop_h - overlap) * i) for i in range(n_crops_per_side)] + + # Crops in XYWH format + for x0, y0 in product(crop_box_x0, crop_box_y0): + box = [x0, y0, min(x0 + crop_w, im_w), min(y0 + crop_h, im_h)] + crop_boxes.append(box) + layer_idxs.append(i_layer + 1) + + return crop_boxes, layer_idxs + + +def uncrop_boxes_xyxy(boxes: torch.Tensor, crop_box: List[int]) -> torch.Tensor: + x0, y0, _, _ = crop_box + offset = torch.tensor([[x0, y0, x0, y0]], device=boxes.device) + # Check if boxes has a channel dimension + if len(boxes.shape) == 3: + offset = offset.unsqueeze(1) + return boxes + offset + + +def uncrop_points(points: torch.Tensor, crop_box: List[int]) -> torch.Tensor: + x0, y0, _, _ = crop_box + offset = torch.tensor([[x0, y0]], device=points.device) + # Check if points has a channel dimension + if len(points.shape) == 3: + offset = offset.unsqueeze(1) + return points + offset + + +def uncrop_masks( + masks: torch.Tensor, crop_box: List[int], orig_h: int, orig_w: int +) -> torch.Tensor: + x0, y0, x1, y1 = crop_box + if x0 == 0 and y0 == 0 and x1 == orig_w and y1 == orig_h: + return masks + # Coordinate transform masks + pad_x, pad_y = orig_w - (x1 - x0), orig_h - (y1 - y0) + pad = (x0, pad_x - x0, y0, pad_y - y0) + return torch.nn.functional.pad(masks, pad, value=0) + + +def remove_small_regions( + mask: np.ndarray, area_thresh: float, mode: str +) -> Tuple[np.ndarray, bool]: + """ + Removes small disconnected regions and holes in a mask. Returns the + mask and an indicator of if the mask has been modified. + """ + import cv2 # type: ignore + + assert mode in ["holes", "islands"] + correct_holes = mode == "holes" + working_mask = (correct_holes ^ mask).astype(np.uint8) + n_labels, regions, stats, _ = cv2.connectedComponentsWithStats(working_mask, 8) + sizes = stats[:, -1][1:] # Row 0 is background label + small_regions = [i + 1 for i, s in enumerate(sizes) if s < area_thresh] + if len(small_regions) == 0: + return mask, False + fill_labels = [0] + small_regions + if not correct_holes: + fill_labels = [i for i in range(n_labels) if i not in fill_labels] + # If every region is below threshold, keep largest + if len(fill_labels) == 0: + fill_labels = [int(np.argmax(sizes)) + 1] + mask = np.isin(regions, fill_labels) + return mask, True + + +def coco_encode_rle(uncompressed_rle: Dict[str, Any]) -> Dict[str, Any]: + from pycocotools import mask as mask_utils # type: ignore + + h, w = uncompressed_rle["size"] + rle = mask_utils.frPyObjects(uncompressed_rle, h, w) + rle["counts"] = rle["counts"].decode("utf-8") # Necessary to serialize with json + return rle + + +def batched_mask_to_box(masks: torch.Tensor) -> torch.Tensor: + """ + Calculates boxes in XYXY format around masks. Return [0,0,0,0] for + an empty mask. For input shape C1xC2x...xHxW, the output shape is C1xC2x...x4. + """ + # torch.max below raises an error on empty inputs, just skip in this case + if torch.numel(masks) == 0: + return torch.zeros(*masks.shape[:-2], 4, device=masks.device) + + # Normalize shape to CxHxW + shape = masks.shape + h, w = shape[-2:] + if len(shape) > 2: + masks = masks.flatten(0, -3) + else: + masks = masks.unsqueeze(0) + + # Get top and bottom edges + in_height, _ = torch.max(masks, dim=-1) + in_height_coords = in_height * torch.arange(h, device=in_height.device)[None, :] + bottom_edges, _ = torch.max(in_height_coords, dim=-1) + in_height_coords = in_height_coords + h * (~in_height) + top_edges, _ = torch.min(in_height_coords, dim=-1) + + # Get left and right edges + in_width, _ = torch.max(masks, dim=-2) + in_width_coords = in_width * torch.arange(w, device=in_width.device)[None, :] + right_edges, _ = torch.max(in_width_coords, dim=-1) + in_width_coords = in_width_coords + w * (~in_width) + left_edges, _ = torch.min(in_width_coords, dim=-1) + + # If the mask is empty the right edge will be to the left of the left edge. + # Replace these boxes with [0, 0, 0, 0] + empty_filter = (right_edges < left_edges) | (bottom_edges < top_edges) + out = torch.stack([left_edges, top_edges, right_edges, bottom_edges], dim=-1) + out = out * (~empty_filter).unsqueeze(-1) + + # Return to original shape + if len(shape) > 2: + out = out.reshape(*shape[:-2], 4) + else: + out = out[0] + + return out diff --git a/freevideo_engine/sam2/utils/misc.py b/freevideo_engine/sam2/utils/misc.py new file mode 100644 index 00000000..08e69546 --- /dev/null +++ b/freevideo_engine/sam2/utils/misc.py @@ -0,0 +1,349 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +import os +import warnings +from threading import Thread + +import numpy as np +import torch +from PIL import Image +from tqdm import tqdm + + +def get_sdpa_settings(): + if torch.cuda.is_available(): + old_gpu = torch.cuda.get_device_properties(0).major < 7 + # only use Flash Attention on Ampere (8.0) or newer GPUs + use_flash_attn = torch.cuda.get_device_properties(0).major >= 8 + if not use_flash_attn: + warnings.warn( + "Flash Attention is disabled as it requires a GPU with Ampere (8.0) CUDA capability.", + category=UserWarning, + stacklevel=2, + ) + # keep math kernel for PyTorch versions before 2.2 (Flash Attention v2 is only + # available on PyTorch 2.2+, while Flash Attention v1 cannot handle all cases) + pytorch_version = tuple(int(v) for v in torch.__version__.split(".")[:2]) + if pytorch_version < (2, 2): + warnings.warn( + f"You are using PyTorch {torch.__version__} without Flash Attention v2 support. " + "Consider upgrading to PyTorch 2.2+ for Flash Attention v2 (which could be faster).", + category=UserWarning, + stacklevel=2, + ) + math_kernel_on = pytorch_version < (2, 2) or not use_flash_attn + else: + old_gpu = True + use_flash_attn = False + math_kernel_on = True + + return old_gpu, use_flash_attn, math_kernel_on + + +def get_connected_components(mask): + """ + Get the connected components (8-connectivity) of binary masks of shape (N, 1, H, W). + + Inputs: + - mask: A binary mask tensor of shape (N, 1, H, W), where 1 is foreground and 0 is + background. + + Outputs: + - labels: A tensor of shape (N, 1, H, W) containing the connected component labels + for foreground pixels and 0 for background pixels. + - counts: A tensor of shape (N, 1, H, W) containing the area of the connected + components for foreground pixels and 0 for background pixels. + """ + from freevideo_engine.sam2 import _C + + return _C.get_connected_componnets(mask.to(torch.uint8).contiguous()) + + +def mask_to_box(masks: torch.Tensor): + """ + compute bounding box given an input mask + + Inputs: + - masks: [B, 1, H, W] masks, dtype=torch.Tensor + + Returns: + - box_coords: [B, 1, 4], contains (x, y) coordinates of top left and bottom right box corners, dtype=torch.Tensor + """ + B, _, h, w = masks.shape + device = masks.device + xs = torch.arange(w, device=device, dtype=torch.int32) + ys = torch.arange(h, device=device, dtype=torch.int32) + grid_xs, grid_ys = torch.meshgrid(xs, ys, indexing="xy") + grid_xs = grid_xs[None, None, ...].expand(B, 1, h, w) + grid_ys = grid_ys[None, None, ...].expand(B, 1, h, w) + min_xs, _ = torch.min(torch.where(masks, grid_xs, w).flatten(-2), dim=-1) + max_xs, _ = torch.max(torch.where(masks, grid_xs, -1).flatten(-2), dim=-1) + min_ys, _ = torch.min(torch.where(masks, grid_ys, h).flatten(-2), dim=-1) + max_ys, _ = torch.max(torch.where(masks, grid_ys, -1).flatten(-2), dim=-1) + bbox_coords = torch.stack((min_xs, min_ys, max_xs, max_ys), dim=-1) + + return bbox_coords + + +def _load_img_as_tensor(img_path, image_size): + img_pil = Image.open(img_path) + img_np = np.array(img_pil.convert("RGB").resize((image_size, image_size))) + if img_np.dtype == np.uint8: # np.uint8 is expected for JPEG images + img_np = img_np / 255.0 + else: + raise RuntimeError(f"Unknown image dtype: {img_np.dtype} on {img_path}") + img = torch.from_numpy(img_np).permute(2, 0, 1) + video_width, video_height = img_pil.size # the original video size + return img, video_height, video_width + + +class AsyncVideoFrameLoader: + """ + A list of video frames to be load asynchronously without blocking session start. + """ + + def __init__( + self, + img_paths, + image_size, + offload_video_to_cpu, + img_mean, + img_std, + compute_device, + ): + self.img_paths = img_paths + self.image_size = image_size + self.offload_video_to_cpu = offload_video_to_cpu + self.img_mean = img_mean + self.img_std = img_std + # items in `self.images` will be loaded asynchronously + self.images = [None] * len(img_paths) + # catch and raise any exceptions in the async loading thread + self.exception = None + # video_height and video_width be filled when loading the first image + self.video_height = None + self.video_width = None + self.compute_device = compute_device + + # load the first frame to fill video_height and video_width and also + # to cache it (since it's most likely where the user will click) + self.__getitem__(0) + + # load the rest of frames asynchronously without blocking the session start + def _load_frames(): + try: + for n in tqdm(range(len(self.images)), desc="frame loading (JPEG)"): + self.__getitem__(n) + except Exception as e: + self.exception = e + + self.thread = Thread(target=_load_frames, daemon=True) + self.thread.start() + + def __getitem__(self, index): + if self.exception is not None: + raise RuntimeError("Failure in frame loading thread") from self.exception + + img = self.images[index] + if img is not None: + return img + + img, video_height, video_width = _load_img_as_tensor( + self.img_paths[index], self.image_size + ) + self.video_height = video_height + self.video_width = video_width + # normalize by mean and std + img -= self.img_mean + img /= self.img_std + if not self.offload_video_to_cpu: + img = img.to(self.compute_device, non_blocking=True) + self.images[index] = img + return img + + def __len__(self): + return len(self.images) + + +def load_video_frames( + video_path, + image_size, + offload_video_to_cpu, + img_mean=(0.485, 0.456, 0.406), + img_std=(0.229, 0.224, 0.225), + async_loading_frames=False, + compute_device=torch.device("cuda"), +): + """ + Load the video frames from video_path. The frames are resized to image_size as in + the model and are loaded to GPU if offload_video_to_cpu=False. This is used by the demo. + """ + is_bytes = isinstance(video_path, bytes) + is_str = isinstance(video_path, str) + is_mp4_path = is_str and os.path.splitext(video_path)[-1] in [".mp4", ".MP4"] + if is_bytes or is_mp4_path: + return load_video_frames_from_video_file( + video_path=video_path, + image_size=image_size, + offload_video_to_cpu=offload_video_to_cpu, + img_mean=img_mean, + img_std=img_std, + compute_device=compute_device, + ) + elif is_str and os.path.isdir(video_path): + return load_video_frames_from_jpg_images( + video_path=video_path, + image_size=image_size, + offload_video_to_cpu=offload_video_to_cpu, + img_mean=img_mean, + img_std=img_std, + async_loading_frames=async_loading_frames, + compute_device=compute_device, + ) + else: + raise NotImplementedError( + "Only MP4 video and JPEG folder are supported at this moment" + ) + + +def load_video_frames_from_jpg_images( + video_path, + image_size, + offload_video_to_cpu, + img_mean=(0.485, 0.456, 0.406), + img_std=(0.229, 0.224, 0.225), + async_loading_frames=False, + compute_device=torch.device("cuda"), +): + """ + Load the video frames from a directory of JPEG files (".jpg" format). + + The frames are resized to image_size x image_size and are loaded to GPU if + `offload_video_to_cpu` is `False` and to CPU if `offload_video_to_cpu` is `True`. + + You can load a frame asynchronously by setting `async_loading_frames` to `True`. + """ + if isinstance(video_path, str) and os.path.isdir(video_path): + jpg_folder = video_path + else: + raise NotImplementedError( + "Only JPEG frames are supported at this moment. For video files, you may use " + "ffmpeg (https://ffmpeg.org/) to extract frames into a folder of JPEG files, such as \n" + "```\n" + "ffmpeg -i .mp4 -q:v 2 -start_number 0 /'%05d.jpg'\n" + "```\n" + "where `-q:v` generates high-quality JPEG frames and `-start_number 0` asks " + "ffmpeg to start the JPEG file from 00000.jpg." + ) + + frame_names = [ + p + for p in os.listdir(jpg_folder) + if os.path.splitext(p)[-1] in [".jpg", ".jpeg", ".JPG", ".JPEG"] + ] + frame_names.sort(key=lambda p: int(os.path.splitext(p)[0])) + num_frames = len(frame_names) + if num_frames == 0: + raise RuntimeError(f"no images found in {jpg_folder}") + img_paths = [os.path.join(jpg_folder, frame_name) for frame_name in frame_names] + img_mean = torch.tensor(img_mean, dtype=torch.float32)[:, None, None] + img_std = torch.tensor(img_std, dtype=torch.float32)[:, None, None] + + if async_loading_frames: + lazy_images = AsyncVideoFrameLoader( + img_paths, + image_size, + offload_video_to_cpu, + img_mean, + img_std, + compute_device, + ) + return lazy_images, lazy_images.video_height, lazy_images.video_width + + images = torch.zeros(num_frames, 3, image_size, image_size, dtype=torch.float32) + for n, img_path in enumerate(tqdm(img_paths, desc="frame loading (JPEG)")): + images[n], video_height, video_width = _load_img_as_tensor(img_path, image_size) + if not offload_video_to_cpu: + images = images.to(compute_device) + img_mean = img_mean.to(compute_device) + img_std = img_std.to(compute_device) + # normalize by mean and std + images -= img_mean + images /= img_std + return images, video_height, video_width + + +def load_video_frames_from_video_file( + video_path, + image_size, + offload_video_to_cpu, + img_mean=(0.485, 0.456, 0.406), + img_std=(0.229, 0.224, 0.225), + compute_device=torch.device("cuda"), +): + """Load the video frames from a video file.""" + import decord + + img_mean = torch.tensor(img_mean, dtype=torch.float32)[:, None, None] + img_std = torch.tensor(img_std, dtype=torch.float32)[:, None, None] + # Get the original video height and width + decord.bridge.set_bridge("torch") + video_height, video_width, _ = decord.VideoReader(video_path).next().shape + # Iterate over all frames in the video + images = [] + for frame in decord.VideoReader(video_path, width=image_size, height=image_size): + images.append(frame.permute(2, 0, 1)) + + images = torch.stack(images, dim=0).float() / 255.0 + if not offload_video_to_cpu: + images = images.to(compute_device) + img_mean = img_mean.to(compute_device) + img_std = img_std.to(compute_device) + # normalize by mean and std + images -= img_mean + images /= img_std + return images, video_height, video_width + + +def fill_holes_in_mask_scores(mask, max_area): + """ + A post processor to fill small holes in mask scores with area under `max_area`. + """ + # Holes are those connected components in background with area <= self.max_area + # (background regions are those with mask scores <= 0) + assert max_area > 0, "max_area must be positive" + + input_mask = mask + try: + labels, areas = get_connected_components(mask <= 0) + is_hole = (labels > 0) & (areas <= max_area) + # We fill holes with a small positive mask score (0.1) to change them to foreground. + mask = torch.where(is_hole, 0.1, mask) + except Exception as e: + # Skip the post-processing step on removing small holes if the CUDA kernel fails + warnings.warn( + f"{e}\n\nSkipping the post-processing step due to the error above. You can " + "still use SAM 2 and it's OK to ignore the error above, although some post-processing " + "functionality may be limited (which doesn't affect the results in most cases; see " + "https://github.com/facebookresearch/sam2/blob/main/INSTALL.md).", + category=UserWarning, + stacklevel=2, + ) + mask = input_mask + + return mask + + +def concat_points(old_point_inputs, new_points, new_labels): + """Add new points and labels to previous point inputs (add at the end).""" + if old_point_inputs is None: + points, labels = new_points, new_labels + else: + points = torch.cat([old_point_inputs["point_coords"], new_points], dim=1) + labels = torch.cat([old_point_inputs["point_labels"], new_labels], dim=1) + + return {"point_coords": points, "point_labels": labels} diff --git a/freevideo_engine/sam2/utils/transforms.py b/freevideo_engine/sam2/utils/transforms.py new file mode 100644 index 00000000..04ccdf70 --- /dev/null +++ b/freevideo_engine/sam2/utils/transforms.py @@ -0,0 +1,118 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +import warnings + +import torch +import torch.nn as nn +import torch.nn.functional as F +from torchvision.transforms import Normalize, Resize, ToTensor + + +class SAM2Transforms(nn.Module): + def __init__( + self, resolution, mask_threshold, max_hole_area=0.0, max_sprinkle_area=0.0 + ): + """ + Transforms for SAM2. + """ + super().__init__() + self.resolution = resolution + self.mask_threshold = mask_threshold + self.max_hole_area = max_hole_area + self.max_sprinkle_area = max_sprinkle_area + self.mean = [0.485, 0.456, 0.406] + self.std = [0.229, 0.224, 0.225] + self.to_tensor = ToTensor() + self.transforms = torch.jit.script( + nn.Sequential( + Resize((self.resolution, self.resolution)), + Normalize(self.mean, self.std), + ) + ) + + def __call__(self, x): + x = self.to_tensor(x) + return self.transforms(x) + + def forward_batch(self, img_list): + img_batch = [self.transforms(self.to_tensor(img)) for img in img_list] + img_batch = torch.stack(img_batch, dim=0) + return img_batch + + def transform_coords( + self, coords: torch.Tensor, normalize=False, orig_hw=None + ) -> torch.Tensor: + """ + Expects a torch tensor with length 2 in the last dimension. The coordinates can be in absolute image or normalized coordinates, + If the coords are in absolute image coordinates, normalize should be set to True and original image size is required. + + Returns + Un-normalized coordinates in the range of [0, 1] which is expected by the SAM2 model. + """ + if normalize: + assert orig_hw is not None + h, w = orig_hw + coords = coords.clone() + coords[..., 0] = coords[..., 0] / w + coords[..., 1] = coords[..., 1] / h + + coords = coords * self.resolution # unnormalize coords + return coords + + def transform_boxes( + self, boxes: torch.Tensor, normalize=False, orig_hw=None + ) -> torch.Tensor: + """ + Expects a tensor of shape Bx4. The coordinates can be in absolute image or normalized coordinates, + if the coords are in absolute image coordinates, normalize should be set to True and original image size is required. + """ + boxes = self.transform_coords(boxes.reshape(-1, 2, 2), normalize, orig_hw) + return boxes + + def postprocess_masks(self, masks: torch.Tensor, orig_hw) -> torch.Tensor: + """ + Perform PostProcessing on output masks. + """ + from freevideo_engine.sam2.utils.misc import get_connected_components + + masks = masks.float() + input_masks = masks + mask_flat = masks.flatten(0, 1).unsqueeze(1) # flatten as 1-channel image + try: + if self.max_hole_area > 0: + # Holes are those connected components in background with area <= self.fill_hole_area + # (background regions are those with mask scores <= self.mask_threshold) + labels, areas = get_connected_components( + mask_flat <= self.mask_threshold + ) + is_hole = (labels > 0) & (areas <= self.max_hole_area) + is_hole = is_hole.reshape_as(masks) + # We fill holes with a small positive mask score (10.0) to change them to foreground. + masks = torch.where(is_hole, self.mask_threshold + 10.0, masks) + + if self.max_sprinkle_area > 0: + labels, areas = get_connected_components( + mask_flat > self.mask_threshold + ) + is_hole = (labels > 0) & (areas <= self.max_sprinkle_area) + is_hole = is_hole.reshape_as(masks) + # We fill holes with negative mask score (-10.0) to change them to background. + masks = torch.where(is_hole, self.mask_threshold - 10.0, masks) + except Exception as e: + # Skip the post-processing step if the CUDA kernel fails + warnings.warn( + f"{e}\n\nSkipping the post-processing step due to the error above. You can " + "still use SAM 2 and it's OK to ignore the error above, although some post-processing " + "functionality may be limited (which doesn't affect the results in most cases; see " + "https://github.com/facebookresearch/sam2/blob/main/INSTALL.md).", + category=UserWarning, + stacklevel=2, + ) + masks = input_masks + + masks = F.interpolate(masks, orig_hw, mode="bilinear", align_corners=False) + return masks diff --git a/web/image_editor.css b/web/image_editor.css index 40d9d1a1..013cf4ea 100644 --- a/web/image_editor.css +++ b/web/image_editor.css @@ -135,7 +135,7 @@ button.fv-ie-size:hover{background:var(--fv-hover);color:var(--fv-ink)} .fv-ie-view,.fv-ie-ants,.fv-ie-overlay{position:absolute;inset:0;width:100%;height:100%} .fv-ie-ants{pointer-events:none} .fv-ie-overlay{overflow:visible} -.fv-ie-stage[data-tool=move]{cursor:default}.fv-ie-stage[data-tool=crop],.fv-ie-stage[data-tool=marquee],.fv-ie-stage[data-tool=lasso],.fv-ie-stage[data-tool=wand],.fv-ie-stage[data-tool=gradient],.fv-ie-stage[data-tool=shape]{cursor:crosshair} +.fv-ie-stage[data-tool=move]{cursor:default}.fv-ie-stage[data-tool=crop],.fv-ie-stage[data-tool=marquee],.fv-ie-stage[data-tool=lasso],.fv-ie-stage[data-tool=wand],.fv-ie-stage[data-tool=point],.fv-ie-stage[data-pick=true],.fv-ie-stage[data-tool=gradient],.fv-ie-stage[data-tool=shape]{cursor:crosshair} .fv-ie-stage[data-tool=brush],.fv-ie-stage[data-tool=eraser],.fv-ie-stage[data-tool=heal],.fv-ie-stage[data-tool=clone],.fv-ie-stage[data-tool=blur]{cursor:none} .fv-ie-stage[data-tool=text]{cursor:text}.fv-ie-stage[data-tool=eyedropper]{cursor:copy} .fv-ie-stage[data-tool=hand],.fv-ie-stage[data-pan=true]{cursor:grab}.fv-ie-stage[data-pan=true]:active{cursor:grabbing} @@ -239,7 +239,7 @@ button.fv-ie-size:hover{background:var(--fv-hover);color:var(--fv-ink)} .fv-ie-confirm span{flex:1 1 220px} .fv-ie-status{padding:0 16px;color:var(--fv-muted);font-size:var(--fv-micro)} .fv-ie-status:empty{display:none} -.fv-ie-status:not(:empty){padding:7px 16px;border-top:1px solid var(--fv-border)} +.fv-ie-status:not(:empty){position:absolute;left:0;right:0;bottom:0;padding:7px 16px;border-top:1px solid var(--fv-border);background:var(--fv-panel,#0f1620);z-index:3;pointer-events:none} @media (max-width:900px){ .fv-image-editor{width:100vw;height:100dvh;border:0;border-radius:0} diff --git a/web/image_editor.js b/web/image_editor.js index 5a00f216..c15efc3d 100644 --- a/web/image_editor.js +++ b/web/image_editor.js @@ -4,11 +4,11 @@ // new image and keeps the document, so the next visit starts from the original // with every layer and step in place. Closing frees every canvas it made. import {BLENDS, emptyAdjust, migrate, blankDocument, orientedSize, orientMatrix, canvasRect, layerMatrix, scaleSelection, - rasterKinds, measureText, Renderer} from './image_editor_engine.js'; + rasterKinds, measureText, Renderer, traceOutline, simplifyLoop} from './image_editor_engine.js'; import * as commands from './image_commands.js'; import {FONT_KEYS, fontStack, fontLoaded, loadFont, loadFonts} from './fonts.js'; import {api} from '../../scripts/api.js'; -import {createImageGenClient, createImageGeneration, imageGenerationSupported, blankCanvasSize, blankCanvasRatio} from './image_generation.js'; +import {createImageGenClient, createImageGeneration, imageGenerationSupported, blankCanvasSize, blankCanvasRatio, segmentAt} from './image_generation.js'; import {productVersion} from './updates.js'; const css = document.createElement('link'); @@ -29,6 +29,7 @@ export const ICONS = { lasso: '', polygon: '', wand: '', + point: '', brush: '', eraser: '', heal: '', @@ -166,7 +167,7 @@ export async function openImageEditor({source = null, name = source || '', targe let tool = 'move'; const opts = { marquee: {shape: 'rect', mode: 'replace', feather: 0}, lasso: {type: 'free', mode: 'replace', feather: 0}, - wand: {tolerance: 24, contiguous: true, mode: 'replace'}, + wand: {tolerance: 24, contiguous: true, mode: 'replace'}, point: {mode: 'replace'}, brush: {size: .02, hardness: .85, opacity: 1}, eraser: {size: .035, hardness: .7, opacity: 1}, heal: {size: .025, hardness: .6, text: false}, clone: {size: .035, hardness: .6, opacity: 1, source: null, offset: null, picking: false}, blur: {size: .05, hardness: .4, strength: .6}, gradient: {shape: 'linear', end: 'bg'}, @@ -225,7 +226,8 @@ export async function openImageEditor({source = null, name = source || '', targe const filePicker = el('input'); filePicker.type = 'file'; filePicker.accept = 'image/*'; filePicker.hidden = true; dialog.append(header, main, confirmBar, status, filePicker); document.body.append(dialog); - const generation = createImageGeneration({client: imageGenClient || createImageGenClient(api.fetchApi.bind(api)), + const genClient = imageGenClient || createImageGenClient(api.fetchApi.bind(api)); + const generation = createImageGeneration({client: genClient, renderer, t, getDoc: () => doc, getSelection: () => selection, commit: commitInserted, el, button, segmented, library, resolve, icon, onRatioChange: setBlankCanvasRatio, productVersion, fetchApi: (path, options) => api.fetchApi(path, options), resumeKey: `${role}|${source || ''}|${name}`}); @@ -234,7 +236,7 @@ export async function openImageEditor({source = null, name = source || '', targe const TOOLS = [ ['generate', t('Generate with AI', 'AI 生成'), null], null, ['move', t('Move', '移动'), 'V'], ['crop', t('Crop and canvas', '裁剪与画布'), 'C'], null, - ['marquee', t('Marquee', '选框'), 'M'], ['lasso', t('Lasso', '套索'), 'L'], ['wand', t('Magic wand', '魔棒'), 'W'], null, + ['marquee', t('Marquee', '选框'), 'M'], ['lasso', t('Lasso', '套索'), 'L'], ['wand', t('Magic wand', '魔棒'), 'W'], ['point', t('Click select', '点选'), 'P'], null, ['brush', t('Brush', '画笔'), 'B'], ['eraser', t('Eraser', '橡皮擦'), 'E'], ['heal', t('Spot healing', '污点修复'), 'J'], ['clone', t('Clone stamp', '仿制图章'), 'S'], ['blur', t('Blur', '模糊'), 'R'], ['gradient', t('Gradient', '渐变'), 'G'], null, ['text', t('Text', '文字'), 'T'], ['shape', t('Shape', '形状'), 'U'], ['eyedropper', t('Eyedropper', '吸管'), 'I'], ['hand', t('Hand', '抓手'), 'H'], @@ -243,9 +245,27 @@ export async function openImageEditor({source = null, name = source || '', targe for (const entry of TOOLS) { if (!entry) { toolbar.append(el('span', null, 'fv-ie-tool-gap')); continue; } const [id, label, key] = entry; - if (id === 'generate' && !imageGenerationSupported()) continue; + if ((id === 'generate' || id === 'point') && !imageGenerationSupported()) continue; const b = iconButton(id === 'marquee' ? 'marquee' : id, key ? `${label} (${key})` : label, () => select(id), 'fv-ie-tool'); b.dataset.tool = id; toolButtons[id] = b; toolbar.append(b); + if (id === 'point') b.hidden = true; + } + // Click select needs the engine's selection pack; the tool appears once the engine says it offers it. + let pointInfo = null, pointBusy = false, pointTimer = null; + async function refreshPoint() { + try { pointInfo = (await genClient.info()).segment || null; } catch { pointInfo = null; } + if (toolButtons.point) toolButtons.point.hidden = !pointInfo; + if (tool === 'point') { if (!pointInfo) select('move'); else renderOptions(); } + clearTimeout(pointTimer); pointTimer = null; + if (pointInfo?.install?.state === 'running') pointTimer = setTimeout(refreshPoint, 1500); + } + if (toolButtons.point) void refreshPoint(); + // A click before the model is here answers with the one thing to do, not with a line of text. + function flashPointDownload() { + const b = optionsBar.querySelector('.fv-ie-point-download'); + if (!b) return; + b.classList.add('fv-ie-active'); + setTimeout(() => b.classList.remove('fv-ie-active'), 700); } const colors = el('div', null, 'fv-ie-colors'); const fgInput = el('input'); fgInput.type = 'color'; fgInput.className = 'fv-ie-fg'; fgInput.value = fg; @@ -447,15 +467,22 @@ export async function openImageEditor({source = null, name = source || '', targe } // Marching ants: the selection's edge, striped, moving. let antsEdge = null; + const exactEdge = () => layout.k * layout.dpr < 1 && !selection?.parts.some(p => p.shape === 'wand' || p.shape === 'mask'); + const edgeScale = () => exactEdge() ? layout.k * layout.dpr : previewScale(); function selectionEdge() { - const s = previewScale(), key = JSON.stringify([selection, s]) + (selection?.parts.some(p => p.shape === 'wand') ? composited?.doc === doc : ''); - if (antsEdge?.key === key && antsEdge.doc === doc) return antsEdge.canvas; - const mask = renderer.selectionMask(doc, selection, {layer: canvasLayer(), scale: s}); - const shifted = (dx, dy) => { const c = document.createElement('canvas'); c.width = mask.width; c.height = mask.height; const x = c.getContext('2d'); - x.drawImage(mask, 0, 0); x.globalCompositeOperation = 'xor'; x.drawImage(mask, dx, dy); return c; }; - const edge = shifted(1, 0); edge.getContext('2d').drawImage(shifted(0, 1), 0, 0); - antsEdge = {key, doc, canvas: edge}; - return edge; + // Zoomed out, the edge is made at the screen's own pixel size so every side stays one whole line. + const s = edgeScale(), key = JSON.stringify([selection, s]) + (selection?.parts.some(p => p.shape === 'wand' || p.shape === 'mask') ? composited?.doc === doc : ''); + if (antsEdge?.key === key && antsEdge.doc === doc) return antsEdge; + const soft = renderer.selectionMask(doc, selection, {layer: canvasLayer(), scale: s}); + // The outline follows the half-way line of the selection; feathering shows only in the result. + const mask = document.createElement('canvas'); mask.width = soft.width; mask.height = soft.height; + const m = mask.getContext('2d', {willReadFrequently: true}); m.drawImage(soft, 0, 0); + const bits = m.getImageData(0, 0, mask.width, mask.height); + for (let i = 3; i < bits.data.length; i += 4) bits.data[i] = bits.data[i] >= 128 ? 255 : 0; + m.putImageData(bits, 0, 0); + const loops = traceOutline(bits.data, mask.width, mask.height).map(loop => simplifyLoop(loop, 0.75)); + antsEdge = {key, doc, loops, w: mask.width, h: mask.height}; + return antsEdge; } function drawAnts() { const ctx = ants.getContext('2d'); @@ -463,15 +490,17 @@ export async function openImageEditor({source = null, name = source || '', targe if (!selection) return; const edge = selectionEdge(), r = rect(), [x0, y0] = fromO(r.x, r.y), dpr = layout.dpr; ctx.setTransform(dpr, 0, 0, dpr, 0, 0); - ctx.imageSmoothingEnabled = false; - ctx.drawImage(edge, x0, y0, r.w * layout.k, r.h * layout.k); - ctx.globalCompositeOperation = 'source-in'; - const stripe = document.createElement('canvas'); stripe.width = stripe.height = 8; const st = stripe.getContext('2d'); - st.fillStyle = '#fff'; st.fillRect(0, 0, 8, 8); st.fillStyle = '#0b0f15'; st.fillRect(0, 0, 4, 8); - const pattern = ctx.createPattern(stripe, 'repeat'); - pattern.setTransform?.(new DOMMatrix().translateSelf(antsPhase, 0).rotateSelf(45)); - ctx.fillStyle = pattern; ctx.fillRect(0, 0, layout.w, layout.h); - ctx.globalCompositeOperation = 'source-over'; + // One closed polyline per border, every side drawn with the same dash phase. + const sx = (exactEdge() ? edge.w / dpr : r.w * layout.k) / edge.w, sy = (exactEdge() ? edge.h / dpr : r.h * layout.k) / edge.h; + const path = new Path2D(); + for (const loop of edge.loops) { + loop.forEach(([x, y], i) => (i ? path.lineTo(x0 + x * sx, y0 + y * sy) : path.moveTo(x0 + x * sx, y0 + y * sy))); + path.closePath(); + } + ctx.lineWidth = 1.5; ctx.lineJoin = 'round'; ctx.lineCap = 'butt'; + ctx.setLineDash([]); ctx.strokeStyle = '#fff'; ctx.stroke(path); + ctx.setLineDash([4, 4]); ctx.lineDashOffset = -antsPhase; ctx.strokeStyle = '#0b0f15'; ctx.stroke(path); + ctx.setLineDash([]); } function canvasLayer() { const r = rect(), centre = toD([r.x + r.w / 2, r.y + r.h / 2]); @@ -490,6 +519,7 @@ export async function openImageEditor({source = null, name = source || '', targe b.setAttribute('aria-pressed', String(id === tool)); } stage.dataset.tool = tool; + stage.dataset.pick = String(tool === 'generate' && generation.drawsSelection()); } function select(id) { if (!doc.layers.length && !['generate', 'hand'].includes(id)) { message(emptyCanvasReason()); return; } @@ -562,6 +592,20 @@ export async function openImageEditor({source = null, name = source || '', targe add(sep(), segmented([['replace', t('New', '新选区')], ['add', t('Add · Shift', '添加 · Shift')], ['subtract', t('Subtract · Alt', '减去 · Alt')]], o.mode, v => { o.mode = v; }, t('Mode', '方式')).group); if (tool !== 'wand') add(slider(`fv-ie-${tool}-feather`, t('Feather', '羽化'), 0, 80, 1, o.feather, v => { o.feather = v; }, null, ' px').row); add(sep(), ...selectionActions()); + } else if (tool === 'point') { + const o = opts.point, install = pointInfo?.install; + if (pointInfo && !pointInfo.ready) { + const running = install?.state === 'running'; + const share = install?.total > 0 ? Math.min(100, Math.round(100 * (install.done || 0) / install.total)) : 0; + const b = running ? button(t(`Downloading ${share}%`, `正在下载 ${share}%`), null, () => {}, 'fv-ie-button fv-ie-point-download') + : button(t('Download click-select model', '下载点选模型'), install?.state === 'failed' ? t(install.message_en, install.message_zh) : null, + async () => { try { pointInfo = {...pointInfo, install: (await genClient.segmentInstall()).install}; } catch { /* the next refresh shows it */ } void refreshPoint(); renderOptions(); }, 'fv-ie-button fv-ie-point-download'); + if (running) b.disabled = true; + add(b); + } else { + add(segmented([['replace', t('New', '新选区')], ['add', t('Add · Shift', '添加 · Shift')], ['subtract', t('Subtract · Alt', '减去 · Alt')]], o.mode, v => { o.mode = v; }, t('Mode', '方式')).group); + } + add(sep(), ...selectionActions()); } else if (tool === 'brush' || tool === 'eraser') { const o = opts[tool]; add(sizeSlider(o), pct(o, 'hardness', t('Hardness', '硬度')), pct(o, 'opacity', t('Opacity', '不透明度'))); @@ -1171,12 +1215,15 @@ export async function openImageEditor({source = null, name = source || '', targe return null; } function startGesture(event, p) { - if (!doc.layers.length || tool === 'generate') return null; + // In "Edit this" dragging on the picture selects the part to change, as the marquee does. + const choosing = tool === 'generate' && generation.drawsSelection(); + if (!doc.layers.length || tool === 'generate' && !choosing) return null; + const use = choosing ? 'marquee' : tool; const o = toO(...p), d = toD(o), layer = active(); const mode = event.shiftKey ? 'add' : event.altKey ? 'subtract' : null; - if (tool === 'crop') return cropGesture(event, o); - if (tool === 'move') return moveGesture(event, p, d); - if (tool === 'marquee') { + if (use === 'crop') return cropGesture(event, o); + if (use === 'move') return moveGesture(event, p, d); + if (use === 'marquee') { const om = opts.marquee; return dragBox(o, (a, b) => { const [x1, y1] = toD(a), [x2, y2] = toD(b); @@ -1185,15 +1232,32 @@ export async function openImageEditor({source = null, name = source || '', targe addPart(part, mode || om.mode); }, om.shape === 'ellipse'); } - if (tool === 'lasso') return lassoGesture(o, mode || opts.lasso.mode); - if (tool === 'wand') { + if (use === 'lasso') return lassoGesture(o, mode || opts.lasso.mode); + if (use === 'wand') { const src = rasterKinds.has(layer.kind) ? layer : doc.layers[0]; const [u, v] = toLocal(src, d); if (u < 0 || v < 0 || u > 1 || v > 1) { message(t('Click on an image layer.', '请点在图片图层上。')); return null; } addPart({shape: 'wand', layer: src.id, u, v, tolerance: opts.wand.tolerance, contiguous: opts.wand.contiguous, upto: src.ops.length}, mode || opts.wand.mode); return null; } - if (tool === 'eyedropper') { + if (use === 'point') { + const src = rasterKinds.has(layer.kind) ? layer : doc.layers[0]; + const [u, v] = toLocal(src, d); + if (u < 0 || v < 0 || u > 1 || v > 1) { message(t('Click on an image layer.', '请点在图片图层上。')); return null; } + if (!pointInfo?.ready) { flashPointDownload(); return null; } + if (pointBusy) return null; + const how = mode || opts.point.mode; + pointBusy = true; message(t('Finding the object…', '正在找出物体……')); + segmentAt(renderer, genClient, doc, src, [u, v]).then(file => { + if (doc.layers.indexOf(src) < 0) return; + addPart({shape: 'mask', layer: src.id, file, upto: src.ops.length}, how); message(''); + }).catch(error => { + message(error?.code === 'busy_video' ? t('A video is generating. Try again when it finishes.', '视频正在生成,完成后再试。') + : t('Could not find an object here. Try again.', '没能在这里找出物体,请再试一次。')); + }).finally(() => { pointBusy = false; }); + return null; + } + if (use === 'eyedropper') { const {canvas: pic, scale} = picture(), r = rect(); const x = Math.floor((o[0] - r.x) * scale), y = Math.floor((o[1] - r.y) * scale); if (x < 0 || y < 0 || x >= pic.width || y >= pic.height) { message(t('Click on the canvas to pick a color.', '请点在画布上取色。')); return null; } @@ -1204,35 +1268,35 @@ export async function openImageEditor({source = null, name = source || '', targe message(t(`Picked ${hex}.`, `已吸取 ${hex}。`)); return null; } - if (tool === 'text') { + if (use === 'text') { const hit = hitLayer(p); if (hit?.kind === 'text') { setActive(hit.id); renderPanels(); textArea?.focus(); return null; } addText(d); return null; } - if (tool === 'shape') return shapeGesture(o); + if (use === 'shape') return shapeGesture(o); // Pixel tools. let target = layer, base = doc; - if ((tool === 'brush' || tool === 'gradient') && (!rasterKinds.has(layer.kind) || (layer.locked && !maskTarget))) { + if ((use === 'brush' || use === 'gradient') && (!rasterKinds.has(layer.kind) || (layer.locked && !maskTarget))) { // Paint goes on a layer of its own above the picture, so it can be erased or hidden alone. - const reuse = tool === 'brush' && [...doc.layers].reverse().find(l => l.kind === 'paint' && l.visible); + const reuse = use === 'brush' && [...doc.layers].reverse().find(l => l.kind === 'paint' && l.visible); if (reuse) { target = reuse; base = commands.setActive(doc, reuse.id); } else { const n = doc.layers.filter(l => l.kind === 'paint').length + 1; - base = commands.addPaintLayer(doc, tool === 'gradient' ? t('Gradient', '渐变') : t(`Paint ${n}`, `绘画 ${n}`)); + base = commands.addPaintLayer(doc, use === 'gradient' ? t('Gradient', '渐变') : t(`Paint ${n}`, `绘画 ${n}`)); target = base.layers.find(l => l.id === base.active); } } else if (!rasterKinds.has(layer.kind)) { message(t('Pick an image or paint layer to work on its pixels.', '请选择图片图层或绘画图层再处理像素。')); return null; } - if (tool === 'gradient') { + if (use === 'gradient') { return dragLine(o, (a, b) => { const from = toLocal(target, toD(a)), to = toLocal(target, toD(b)); pushOp(target, {type: 'gradient', shape: opts.gradient.shape, from, to, c1: fg, c2: opts.gradient.end === 'bg' ? bg : 'transparent', selection}, base); }); } - if (tool === 'clone' && (event.altKey || opts.clone.picking)) { + if (use === 'clone' && (event.altKey || opts.clone.picking)) { opts.clone.source = d; opts.clone.picking = false; opts.clone.offset = null; renderOptions(); showHint(); drawOverlay(); return null; } - if (tool === 'clone' && !opts.clone.source) { message(t('Alt-click to set the source first.', '请先按住 Alt 点击设置取样点。')); return null; } + if (use === 'clone' && !opts.clone.source) { message(t('Alt-click to set the source first.', '请先按住 Alt 点击设置取样点。')); return null; } return strokeGesture(target, d, base); } function strokeGesture(layer, d, base) { @@ -1477,7 +1541,7 @@ export async function openImageEditor({source = null, name = source || '', targe function actualSize() { viewState = {zoom: 1 / layout.fitK, panX: 0, panY: 0}; computeLayout(); draw(); controls(); } // ----- keys ---------------------------------------------------------------------------------- - const KEYS = {v: 'move', c: 'crop', m: 'marquee', l: 'lasso', w: 'wand', b: 'brush', e: 'eraser', j: 'heal', s: 'clone', r: 'blur', g: 'gradient', t: 'text', u: 'shape', i: 'eyedropper', h: 'hand'}; + const KEYS = {v: 'move', c: 'crop', m: 'marquee', l: 'lasso', w: 'wand', p: 'point', b: 'brush', e: 'eraser', j: 'heal', s: 'clone', r: 'blur', g: 'gradient', t: 'text', u: 'shape', i: 'eyedropper', h: 'hand'}; function keys(event) { const typing = /^(INPUT|TEXTAREA|SELECT)$/.test(event.target.tagName) && !['range', 'checkbox', 'color', 'radio'].includes(event.target.type); const mod = event.ctrlKey || event.metaKey, key = event.key.toLowerCase(); diff --git a/web/image_editor_engine.js b/web/image_editor_engine.js index 896451c8..15ea93cd 100644 --- a/web/image_editor_engine.js +++ b/web/image_editor_engine.js @@ -972,6 +972,23 @@ export class Renderer { return this.images.get(file); } loaded(file) { return this.images.get(file)?.value; } + // A black and white picture as transparent pixels (white kept), made once it has loaded. + maskShape(file) { + const image = this.loaded(file); + if (!image) return null; + this.masks ||= new Map(); + let shape = this.masks.get(file); + if (!shape) { + shape = canvas(image.naturalWidth, image.naturalHeight); + const ctx = context(shape); + ctx.drawImage(image, 0, 0); + const data = ctx.getImageData(0, 0, shape.width, shape.height); + for (let i = 0; i < data.data.length; i += 4) { data.data[i + 3] = data.data[i] >= 128 ? 255 : 0; data.data[i] = data.data[i + 1] = data.data[i + 2] = 255; } + ctx.putImageData(data, 0, 0); + this.masks.set(file, shape); + } + return shape; + } async preload(doc) { for (const l of doc.layers) if (l.src) { const img = await this.image(l.src); this.images.get(l.src).value = img; } await loadFonts(textFonts(doc)).catch(error => console.warn('FreeVideo image editor fonts unavailable; using fallback fonts.', error)); @@ -1103,6 +1120,14 @@ export class Renderer { const toSrc = new DOMMatrix().scaleSelf(scale, scale).multiplySelf(layerMatrix(layer).inverse()).multiplySelf(layerMatrix(src)).scaleSelf(1 / scale, 1 / scale); ctx.setTransform(toSrc); ctx.drawImage(m, 0, 0); } + } else if (part.shape === 'mask') { + // A picture the service made from a click: white where the object is, the size of its layer's pixels. + const src = doc.layers.find(l => l.id === part.layer), shape = this.maskShape(part.file); + if (src && shape) { + const toSrc = new DOMMatrix().scaleSelf(scale, scale).multiplySelf(layerMatrix(layer).inverse()).multiplySelf(layerMatrix(src)) + .scaleSelf(src.nw / shape.width, src.nh / shape.height); + ctx.setTransform(toSrc); ctx.imageSmoothingEnabled = false; ctx.drawImage(shape, 0, 0); + } } else { ctx.setTransform(toLocal); ctx.fillStyle = '#fff'; @@ -1220,3 +1245,57 @@ export class Renderer { this.layers.clear(); this.images.clear(); } } + +// The outline of a black and white picture as closed polylines of its pixel corners, one loop per border +// (inside kept clockwise), with runs along one direction joined. Used to draw the selection's ants as one line. +export function traceOutline(alpha, w, h) { + const on = (x, y) => x >= 0 && y >= 0 && x < w && y < h && alpha[(y * w + x) * 4 + 3] >= 128; + const stride = w + 1, next = new Map(); + const add = (x1, y1, x2, y2) => { const k = y1 * stride + x1; (next.get(k) || next.set(k, []).get(k)).push(y2 * stride + x2); }; + for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) { + if (!on(x, y)) continue; + if (!on(x, y - 1)) add(x, y, x + 1, y); + if (!on(x + 1, y)) add(x + 1, y, x + 1, y + 1); + if (!on(x, y + 1)) add(x + 1, y + 1, x, y + 1); + if (!on(x - 1, y)) add(x, y + 1, x, y); + } + const loops = []; + for (const [start, list] of next) { + while (list.length) { + const loop = [start]; + let at = list.pop(); + while (at !== start) { + loop.push(at); + const out = next.get(at); + if (!out?.length) break; + at = out.pop(); + } + const pts = loop.map(v => [v % stride, Math.floor(v / stride)]), kept = []; + for (let i = 0; i < pts.length; i++) { + const a = pts[(i + pts.length - 1) % pts.length], b = pts[i], c = pts[(i + 1) % pts.length]; + if ((b[0] - a[0]) * (c[1] - b[1]) !== (b[1] - a[1]) * (c[0] - b[0])) kept.push(b); + } + if (kept.length > 1) loops.push(kept); + } + } + return loops; +} + +// Douglas-Peucker on a closed loop: staircase borders become straight runs, within eps pixels of the 0.5 border. +export function simplifyLoop(loop, eps) { + if (loop.length < 4) return loop; + let far = 0, best = -1; + for (let i = 1; i < loop.length; i++) { const d = Math.hypot(loop[i][0] - loop[0][0], loop[i][1] - loop[0][1]); if (d > best) { best = d; far = i; } } + const keep = new Array(loop.length).fill(false); keep[0] = keep[far] = true; + const run = (a, b) => { + const pt = i => loop[i % loop.length], [ax, ay] = pt(a), [bx, by] = pt(b), len = Math.hypot(bx - ax, by - ay) || 1; + let at = -1, worst = eps; + for (let i = a + 1; i < b; i++) { + const [x, y] = pt(i), d = Math.abs((bx - ax) * (ay - y) - (ax - x) * (by - ay)) / len; + if (d > worst) { worst = d; at = i; } + } + if (at >= 0) { keep[at % loop.length] = true; run(a, at); run(at, b); } + }; + run(0, far); run(far, loop.length); + return loop.filter((_, i) => keep[i]); +} diff --git a/web/image_generation.js b/web/image_generation.js index 96bb73aa..811f5344 100644 --- a/web/image_generation.js +++ b/web/image_generation.js @@ -8,7 +8,7 @@ import {about} from './request_assets.js'; export const IMAGE_GEN_PROTOCOL = Object.freeze({ root: '/freevideo/image-gen', header: 'X-FreeVideo-Image', upload: '/upload/image', installed: 'ready', phase: 'phase', bytes: 'bytes', downloading: 'downloading', checking: 'checking', - token: 'token', job: 'job', prompt: 'prompt', width: 'width', height: 'height', images: 'images', seed: 'seed', + token: 'token', job: 'job', prompt: 'prompt', width: 'width', height: 'height', images: 'images', mask: 'mask', seed: 'seed', stage: 'stage', fraction: 'fraction', file: 'file', error: 'error', name: 'name', subfolder: 'subfolder', states: {queued: 'waiting', starting: 'queued', progress: 'running', complete: 'done', failed: 'error', cancelling: 'running', cancelled: 'error'}, @@ -69,9 +69,9 @@ export function createImageGenClient(fetchImpl = globalThis.fetch.bind(globalThi } return { info, - async generate({prompt, width, height, images = [], seed}) { + async generate({prompt, width, height, images = [], mask, seed}) { const value = await post('generate', {[p.prompt]: prompt, [p.width]: width, [p.height]: height, - [p.images]: images, ...(seed === undefined ? {} : {[p.seed]: seed})}); + [p.images]: images, ...(mask ? {[p.mask]: mask} : {}), ...(seed === undefined ? {} : {[p.seed]: seed})}); return {...value, job: value[p.job]}; }, async status(job) { @@ -87,6 +87,10 @@ export function createImageGenClient(fetchImpl = globalThis.fetch.bind(globalThi // The image models are fetched by this page's own engine; the reply is the new info. async packInstall() { const value = await post('pack-install', {}); return {...value, installed: value.installed ?? value[p.installed] ?? false}; }, async packCancel() { const value = await post('pack-cancel', {}); return {...value, installed: value.installed ?? value[p.installed] ?? false}; }, + // Click select: the engine finds the object under a point; the pack it needs is fetched on demand like the image models. + async segment({image, points}) { return post('segment', {image, points}); }, + segmentInstall: () => post('segment-install', {}), + segmentCancel: () => post('segment-cancel', {}), // The prompts and sizes of a new character's five pictures (the Agent's cards use the same ones). castViews: async description => (await post('cast-views', {description})).views, async upload(file) { @@ -264,6 +268,46 @@ export async function uploadGenerationReference(renderer, client, context, alive return client.upload(file); } +// The selection as a black and white picture the size of the layer being edited, uploaded beside it. +// Nothing is sent when nothing is selected, so the whole picture is edited as before. +export async function uploadGenerationMask(renderer, client, context, alive = () => true) { + if (!context.layer || !context.selection) return null; + const shape = renderer.selectionMask(context.doc, context.selection, {layer: context.layer, scale: 1}); + const mask = globalThis.document.createElement('canvas'); + mask.width = shape.width; mask.height = shape.height; + const draw = mask.getContext('2d', {willReadFrequently: true}); + draw.fillStyle = '#000'; draw.fillRect(0, 0, mask.width, mask.height); + draw.drawImage(shape, 0, 0); + const pixels = draw.getImageData(0, 0, mask.width, mask.height).data; + let any = false; + for (let i = 0; i < pixels.length; i += 4) if (pixels[i] >= 128) { any = true; break; } + if (!any) return null; + const blob = await new Promise((resolve, reject) => mask.toBlob(b => b ? resolve(b) : reject(failure()), 'image/png')); + if (!alive()) throw failure('cancelled'); + return client.upload(new File([blob], `freevideo-image-mask-${crypto.randomUUID()}.png`, {type: 'image/png'})); +} + +// The object under a click, as the name of a black and white picture the size of the layer's pixels. +// The layer is uploaded once for as long as it looks the same. +const segmentUploads = new WeakMap(); +export async function segmentAt(renderer, client, doc, layer, point) { + const look = JSON.stringify([layer.ops.map(o => o.id), layer.adjust, layer.src, layer.mask?.ops.map(o => o.id)]); + let known = segmentUploads.get(layer); + if (known?.look !== look) { + await renderer.preload(doc); + const raster = renderer.layerImage(doc, layer, 1, true); + const blob = await new Promise((resolve, reject) => raster.toBlob(b => b ? resolve(b) : reject(failure()), 'image/png')); + known = {look, name: await client.upload(new File([blob], `freevideo-image-reference-${crypto.randomUUID()}.png`, {type: 'image/png'})), width: raster.width, height: raster.height}; + segmentUploads.set(layer, known); + } + const x = Math.min(known.width - 1, Math.max(0, Math.floor(point[0] * known.width))), y = Math.min(known.height - 1, Math.max(0, Math.floor(point[1] * known.height))); + const value = await client.segment({image: known.name, points: [[x, y, 1]]}); + if (typeof value?.mask !== 'string') throw failure(); + const image = await renderer.image(value.mask); + renderer.images.get(value.mask).value = image; + return value.mask; +} + // "Edit this" can take more pictures beside the layer being edited: that layer is always image 1 and // the others follow in the order they were added. The page offers fewer than the service accepts. export const PAGE_REFERENCE_LIMIT = 3; @@ -308,7 +352,7 @@ export function insertGenerationResult(doc, result, context, t) { geometry = {cx: point.x, cy: point.y, w: c.w, h: c.h, rotation: -doc.rotate, flipX: doc.flipX, flipY: doc.flipY}; } next = {...next, layers: next.layers.map(l => l.id === next.active ? {...l, ...geometry} : l)}; - if (context.selection) next = commands.maskFromSelection(next, next.active, scaleSelection(context.selection, sx, sy)); + if (context.selection && !context.region) next = commands.maskFromSelection(next, next.active, scaleSelection(context.selection, sx, sy)); return next; } @@ -399,10 +443,10 @@ export function createImageGenSession({client, prepare, apply, onChange = () => emit({running: true, job: null, fraction: 0, stage: '', error: '', report_id: null, waiting: '', fitted: null}); const alive = () => current === epoch && !disposed; try { - const {context, images = []} = await prepare(request, alive); + const {context, images = [], mask} = await prepare(request, alive); if (!alive()) return; const withImages = images.length > 0; - const row = await client.generate({prompt: request.prompt, width: context.width, height: context.height, images}); + const row = await client.generate({prompt: request.prompt, width: context.width, height: context.height, images, mask}); const {job} = row; if (!job) throw failure(row.error, row); if (row.fitted) emit({fitted: row.fitted}); @@ -492,7 +536,9 @@ export function createImageGeneration({client, renderer, t, getDoc, getSelection const context = generationContext(getDoc(), getSelection(), request.mode); const images = request.mode === 'edit' ? [await uploadGenerationReference(renderer, client, context, alive), ...await uploadExtraReferences(client, request.references || [], referencePNG, copies, alive)] : []; - return {context, images}; + // Only the selected part of the edited picture (the first) is changed. + const mask = images.length ? await uploadGenerationMask(renderer, client, context, alive) : null; + return {context: mask ? {...context, region: true} : context, images, mask}; }, apply: async (result, context, alive) => { const image = await renderer.image(result.file); @@ -587,7 +633,7 @@ export function createImageGeneration({client, renderer, t, getDoc, getSelection b.setAttribute('aria-pressed', String(b.dataset.value === mode)); }); input.disabled = disabled; renderReferences(refs, disabled); - input.placeholder = mode === 'edit' ? t('What to change', '要改什么') : t('Describe the picture', '描述画面'); + input.placeholder = mode === 'edit' ? getSelection() ? t('What to change in the selection', '要改选区里的什么') : t('What to change', '要改什么') : t('Describe the picture', '描述画面'); input.setAttribute('aria-label', input.placeholder); const pack = missing ? packView(state.info, t) : null; action.textContent = pack ? pack.button : state.running ? t('Stop', '停止') : t('Generate', '生成'); @@ -674,7 +720,7 @@ export function createImageGeneration({client, renderer, t, getDoc, getSelection }; grow(); update(); } - return {mount, unmount() { clearAttention(); promptRequired = false; mounted = null; }, + return {mount, drawsSelection: () => mode === 'edit' && getDoc().layers.length > 0, unmount() { clearAttention(); promptRequired = false; mounted = null; }, selected: () => session.check(), cancel: session.cancel, // The blank canvas a reloaded generation was started on, to be set again by the editor. resumedCanvas: resumed?.context?.mode === 'new' From c47b25af7013b48fdacf400461d6def5a8e22a2f Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:47 +0000 Subject: [PATCH 14/21] Read cuDNN and package metadata files through extended paths in the library check --- freevideo_engine/runtime_libraries.py | 14 +++++++------- freevideo_engine/torch_download.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/freevideo_engine/runtime_libraries.py b/freevideo_engine/runtime_libraries.py index 19571ea1..2fc9e804 100644 --- a/freevideo_engine/runtime_libraries.py +++ b/freevideo_engine/runtime_libraries.py @@ -57,7 +57,7 @@ def site_packages(environment): def _digest(path, algorithm): digest = hashlib.new(algorithm) - with open(path, 'rb') as handle: + with open(io_path(path), 'rb') as handle: for chunk in iter(lambda: handle.read(1 << 20), b''): digest.update(chunk) return algorithm + '=' + base64.urlsafe_b64encode(digest.digest()).rstrip(b'=').decode('ascii') @@ -83,7 +83,7 @@ def check(site, progress=None): root = os.path.normcase(os.path.normpath(str(site))) result = dict(owners=[], checked=0, changed=[], unrecorded=[], unreadable=[], directories=[]) expected = {} - for distribution in importlib.metadata.distributions(path=[str(site)]): + for distribution in importlib.metadata.distributions(path=[str(io_path(site))]): try: rows = list(csv.reader(io.StringIO(distribution.read_text('RECORD') or ''))) name = distribution.metadata['Name'] @@ -108,10 +108,10 @@ def check(site, progress=None): directories.add(os.path.dirname(path)) result['checked'] += 1 try: - if not os.path.isfile(path): + if not os.path.isfile(io_path(path)): result['changed'].append(dict(entry, state='missing')) continue - size = os.path.getsize(path) + size = os.path.getsize(io_path(path)) matching = [(value, length) for _, value, length in records if length is None or length == size] hashed = {} def matches(value): @@ -133,7 +133,7 @@ def matches(value): recorded = {_canonical(path) for path, _ in expected.values()} for directory in sorted(directories): try: - names = sorted(os.listdir(directory)) + names = sorted(os.listdir(io_path(directory))) except OSError: continue for name in names: @@ -266,7 +266,7 @@ def dependency_closure(python, requirements, additional=()): dependencies = {} site = site_for(python) if site is not None: - for distribution in importlib.metadata.distributions(path=[str(site)]): + for distribution in importlib.metadata.distributions(path=[str(io_path(site))]): try: name = distribution.metadata['Name'] if name: @@ -367,7 +367,7 @@ def installed_bytes(python, name): """Installed size of one distribution in this Python's environment, from its RECORD.""" try: site = site_for(python) - for distribution in importlib.metadata.distributions(path=[str(site)] if site else []): + for distribution in importlib.metadata.distributions(path=[str(io_path(site))] if site else []): if (distribution.metadata['Name'] or '').lower() == name.lower(): rows = csv.reader(io.StringIO(distribution.read_text('RECORD') or '')) return sum(int(row[2]) for row in rows if len(row) > 2 and row[2].isdigit()) diff --git a/freevideo_engine/torch_download.py b/freevideo_engine/torch_download.py index 5bd5bdd0..724b2e93 100644 --- a/freevideo_engine/torch_download.py +++ b/freevideo_engine/torch_download.py @@ -28,7 +28,7 @@ def installed_versions(python): # an isolated venv with the standard Lib/site-packages layout. directory = Path(python).parent.parent / 'Lib' / 'site-packages' return {dist.metadata['Name'].lower(): dist.version - for dist in importlib.metadata.distributions(path=[str(directory)]) + for dist in importlib.metadata.distributions(path=[str(io_path(directory))]) if dist.metadata['Name']} From b91f58704aa1a2f2cf3b463280c2bf6859590d74 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:48 +0000 Subject: [PATCH 15/21] Record decoded audio level in the diagnostic report --- freevideo_engine/decode.py | 4 ++++ freevideo_engine/diagnostic_resources.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/freevideo_engine/decode.py b/freevideo_engine/decode.py index 2c6d79f4..7ed5a3e5 100644 --- a/freevideo_engine/decode.py +++ b/freevideo_engine/decode.py @@ -227,6 +227,9 @@ def decoded(done, total, elapsed): audio = audio[:, :round(kept_frames * 40 / 24) * 800] if continuation is not None: audio = audio[:, continuation['audio_latents'] * 800:] + audio_level = {'audio_rms': float(audio.square().mean().sqrt()) if audio.numel() else 0., + 'audio_peak': float(audio.abs().max()) if audio.numel() else 0., + 'audio_samples': int(audio.shape[-1])} del audio_vae, audio_mean, audio_std gc.collect() torch.cuda.empty_cache() @@ -269,6 +272,7 @@ def decoded(done, total, elapsed): 'vae_linear_compute_cache': linear_compute_cache, 'vae_compute_cache_preparation': compute_cache_metrics, 'resident_vae_cache_hit': vae_cache_hit, 'resident_audio_vae_cache_hit': audio_cache_hit, 'vae_preload_seconds': preload_seconds, + **audio_level, 'audio_load_decode_seconds': audio_seconds, 'encode_seconds': time.perf_counter() - encode_started, 'decoded_artifact_save_seconds': artifact_seconds, 'streamed_video_output': stream_output, 'streamed_vae_weights': stream_weights, diff --git a/freevideo_engine/diagnostic_resources.py b/freevideo_engine/diagnostic_resources.py index cf4ed692..6738492f 100644 --- a/freevideo_engine/diagnostic_resources.py +++ b/freevideo_engine/diagnostic_resources.py @@ -243,7 +243,7 @@ def decoder_measurements(value): result = numbers(value, ('vae_load_seconds', 'video_decode_seconds', 'audio_load_decode_seconds', 'video_postprocess_seconds', 'encode_seconds', 'decoded_artifact_save_seconds', 'decode_save_seconds', 'vae_resident_blocks', - 'vae_pinned_weight_bytes')) + 'vae_pinned_weight_bytes', 'audio_rms', 'audio_peak', 'audio_samples')) for key in ('vae_linear_compute_cache', 'resident_vae_cache_hit', 'resident_audio_vae_cache_hit', 'streamed_video_output', 'streamed_vae_weights'): if type(value.get(key)) is bool: From 497aa7cb74770ef217f6e7a04b0930ed9cc338c3 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:49 +0000 Subject: [PATCH 16/21] Prompt model check: no new download when only file times changed --- freevideo_engine/agent/routes.py | 2 +- freevideo_engine/launcher/Main.qml | 9 ++- freevideo_engine/launcher_session.py | 8 +- freevideo_engine/prompt_vlm/assets.py | 101 ++++++++++++++++++++++++- freevideo_engine/prompt_vlm/service.py | 18 +++-- freevideo_engine/request_assets.py | 2 +- 6 files changed, 122 insertions(+), 18 deletions(-) diff --git a/freevideo_engine/agent/routes.py b/freevideo_engine/agent/routes.py index 4def1fbd..74f7eb73 100644 --- a/freevideo_engine/agent/routes.py +++ b/freevideo_engine/agent/routes.py @@ -197,7 +197,7 @@ def capabilities(port, jobs): service = getattr(port.server, '_freevideo_prompt_vlm', None) if service is not None: try: - vlm = {k: v for k, v in service.info().items() if k in ('ready', 'model', 'license', 'bytes', 'busy')} + vlm = {k: v for k, v in service.info(wait=False).items() if k in ('ready', 'model', 'license', 'bytes', 'busy')} except (OSError, ValueError): vlm = dict(ready=False) running, pending = port.snapshot() diff --git a/freevideo_engine/launcher/Main.qml b/freevideo_engine/launcher/Main.qml index dee2e399..e8578e28 100644 --- a/freevideo_engine/launcher/Main.qml +++ b/freevideo_engine/launcher/Main.qml @@ -82,6 +82,7 @@ ApplicationWindow { var more = rate > 0 || s.bytes_per_second > 0 ? sizeAndTime(left, rate).split(" · ")[1] : "" return t("Downloading the prompt model · ", "正在下载提示词模型 · ") + gb(m.install.done) + " / " + total + (more ? " · " + more : "") } + if (m.checking) return t("Checking the prompt model…", "正在检查提示词模型…") if (m.failure) return m.failure if (m.install.state === "cancelled") return t("Prompt model download paused · ", "提示词模型下载已暂停 · ") + done + " / " + total return t("You can also download the prompt model (", "可以再下载提示词模型(") + sizeAndTime(m.total_bytes).replace(" · ", t(", ", ",")) @@ -670,7 +671,7 @@ ApplicationWindow { } RowLayout { objectName: "promptModelRow" - visible: !!s.prompt_model && !s.prompt_model.ready + visible: !!s.prompt_model && !s.prompt_model.ready && !s.prompt_model.checking Layout.fillWidth: true; spacing: 14 FCheck { objectName: "promptModelSwitch"; Layout.fillWidth: true @@ -962,7 +963,7 @@ ApplicationWindow { } FCard { objectName: "promptModelCard" - visible: !!s.prompt_model && !s.prompt_model.ready && (s.prompt_model.suggest || s.prompt_model.busy + visible: !!s.prompt_model && !s.prompt_model.ready && (s.prompt_model.suggest || s.prompt_model.busy || s.prompt_model.checking || ["failed", "cancelled"].indexOf(s.prompt_model.install.state) >= 0) Layout.fillWidth: true; padding: 16; spacing: 10 FText { @@ -974,8 +975,8 @@ ApplicationWindow { fraction: s.prompt_model.install.total > 0 ? s.prompt_model.install.done / s.prompt_model.install.total : -1 } Flow { - Layout.fillWidth: true; spacing: 8 - FButton { objectName: "promptModelDownload"; visible: !s.prompt_model.busy + visible: !s.prompt_model.checking; Layout.fillWidth: true; spacing: 8 + FButton { objectName: "promptModelDownload"; visible: !s.prompt_model.busy && !s.prompt_model.checking text: s.prompt_model.suggest ? t("Download", "下载") : t("Resume", "继续"); enabled: !s.busy; onClicked: backend.promptModelAction("install") } FButton { objectName: "promptModelPause"; visible: s.prompt_model.busy; text: t("Pause", "暂停"); onClicked: backend.promptModelAction("cancel") } FButton { objectName: "promptModelDismiss"; visible: s.prompt_model.suggest; text: t("Don't ask again", "不再提示"); flat: true; onClicked: backend.dismissPromptHint() } diff --git a/freevideo_engine/launcher_session.py b/freevideo_engine/launcher_session.py index 3856bf52..15f24273 100644 --- a/freevideo_engine/launcher_session.py +++ b/freevideo_engine/launcher_session.py @@ -815,6 +815,9 @@ def prompt_model_action(self, action): engine = self._image_location()[1] if self.prompt_installer and self.prompt_installer.busy: return + from .prompt_vlm import assets + if assets.checking(engine): + return if not (self.prompt_installer and self.prompt_installer.root == engine): self.prompt_installer = prompt_installer.Installer(engine, busy=self.generating) self.prompt_installer.start() @@ -826,6 +829,7 @@ def prompt_model_view(self): total = sum(row['bytes'] for row in spec['files']) engine = self._image_location()[1] if self.installation_engine() else None ready = bool(engine) and assets.ready(engine) + checking = bool(engine) and not ready and assets.checking(engine) installer = self.prompt_installer active = installer.state() if installer and engine and installer.root == engine else {} busy = bool(active and installer.busy) @@ -841,9 +845,9 @@ def prompt_model_view(self): failure = {'disk_space': self.t('Not enough disk space.', '磁盘空间不足。'), 'busy': self.t('Another download of this model is running.', '这个模型正在被另一处下载。')}.get( active.get('reason'), self.t('The download stopped. Resume to continue.', '下载中断了,点继续可接着下载。')) - return dict(ready=ready, total_bytes=total, enough_disk=enough, busy=busy, install=active, failure=failure, + return dict(ready=ready, checking=checking, total_bytes=total, enough_disk=enough, busy=busy, install=active, failure=failure, downloaded_bytes=active.get('done', 0), title=self.t(*NAMES['text']), - suggest=bool(engine) and not ready and not busy and enough and not self.form['prompt_hint_dismissed'] + suggest=bool(engine) and not ready and not checking and not busy and enough and not self.form['prompt_hint_dismissed'] and active.get('state') not in ('failed', 'cancelled')) def dismiss_prompt_hint(self): diff --git a/freevideo_engine/prompt_vlm/assets.py b/freevideo_engine/prompt_vlm/assets.py index 408906d0..a2f3177e 100644 --- a/freevideo_engine/prompt_vlm/assets.py +++ b/freevideo_engine/prompt_vlm/assets.py @@ -2,6 +2,7 @@ import json from pathlib import Path import shutil +import threading from .. import disk_space FAMILY = 'image-models' @@ -17,15 +18,107 @@ def directory(root): def ready(root): + """Cheap, safe on the launcher's UI thread: version, sizes and modified times only. + + Files whose modified time moved are checked by content once, in the + background; this returns False until that check has accepted them.""" + return _state(root, wait=False) + + +def settle(root): + """Same answer, but a moved modified time is checked by content in the + calling thread. For request handlers, never for a UI thread or under a lock.""" + return ready(root) or _state(root, wait=True) + + +_RECHECK = threading.Lock() +_BOOKKEEPING = threading.Lock() +_OUTCOME = {} +_RUNNING = set() + + +def _state(root, wait): + spec, folder = catalog(), directory(root) + try: + receipt = json.loads((folder / 'verified.json').read_text(encoding='utf-8')) + if receipt.get('revision') != spec['revision']: + return False + stats = {row['file']: (folder / row['file']).stat() for row in spec['files']} + if any(stats[row['file']].st_size != row['bytes'] for row in spec['files']): + return False + moved = [row for row in spec['files'] + if receipt['files'].get(row['file']) != stats[row['file']].st_mtime_ns] + if not moved: + return True + key = (str(folder), spec['revision'], + tuple((row['file'], stats[row['file']].st_size, stats[row['file']].st_mtime_ns) for row in moved)) + known = _OUTCOME.get(key) + if known is not None: + return known + if wait: + return _recheck(folder, spec, moved, key) + with _BOOKKEEPING: + if key in _RUNNING: + return False + _RUNNING.add(key) + threading.Thread(target=_recheck, args=(folder, spec, moved, key), daemon=True, + name='prompt-model-recheck').start() + return False + except (OSError, ValueError, KeyError, TypeError): + return False + + +def checking(root): + """True while the files' content is being checked after a modified time moved. + + A cheap look at the same file identity ready() uses, for a page that must not + call the model missing, or offer its download, in the meantime.""" spec, folder = catalog(), directory(root) try: receipt = json.loads((folder / 'verified.json').read_text(encoding='utf-8')) - return receipt.get('revision') == spec['revision'] and all( - (folder / row['file']).stat().st_size == row['bytes'] and - receipt['files'].get(row['file']) == (folder / row['file']).stat().st_mtime_ns - for row in spec['files']) + if receipt.get('revision') != spec['revision']: + return False + stats = {row['file']: (folder / row['file']).stat() for row in spec['files']} + if any(stats[row['file']].st_size != row['bytes'] for row in spec['files']): + return False + key = (str(folder), spec['revision'], tuple( + (row['file'], stats[row['file']].st_size, stats[row['file']].st_mtime_ns) + for row in spec['files'] if receipt['files'].get(row['file']) != stats[row['file']].st_mtime_ns)) except (OSError, ValueError, KeyError, TypeError): return False + with _BOOKKEEPING: + return key in _RUNNING and key not in _OUTCOME + + +def _recheck(folder, spec, moved, key): + """Accept files whose modified time changed (copied folder, unpacked archive, + antivirus) when their content still matches the catalog, then refresh the + receipt. The outcome is remembered per file identity, so one set of files is + hashed once whatever the answer.""" + from .. import provision + from ..monitoring import save + ledger_path = folder / 'download-verified.json' + try: + with _RECHECK: + if key in _OUTCOME: + return _OUTCOME[key] + try: + ledger = json.loads(ledger_path.read_text(encoding='utf-8')) + except (OSError, ValueError): + ledger = {} + ok = all(provision.verified(folder / row['file'], row, ledger) for row in moved) + if ok: + save(ledger_path, ledger) + save(folder / 'verified.json', dict(revision=spec['revision'], files={ + row['file']: (folder / row['file']).stat().st_mtime_ns for row in spec['files']})) + _OUTCOME[key] = ok + return ok + except Exception: + _OUTCOME[key] = False + return False + finally: + with _BOOKKEEPING: + _RUNNING.discard(key) def remote(spec, row): diff --git a/freevideo_engine/prompt_vlm/service.py b/freevideo_engine/prompt_vlm/service.py index d82ff367..e512ec44 100644 --- a/freevideo_engine/prompt_vlm/service.py +++ b/freevideo_engine/prompt_vlm/service.py @@ -217,10 +217,11 @@ def spawn(root, machine, env, descriptor=None): pass_fds=() if descriptor is None else (descriptor,), supervise=True, start_new_session=True) - def info(self): + def info(self, wait=True): + """wait=False answers from the cheap check, for callers on an event loop or UI thread.""" root, machine = self.installation() spec = assets.catalog() - return dict(ready=assets.ready(root), model=spec['repo'], license=spec['license'], + return dict(ready=assets.settle(root) if wait else assets.ready(root), model=spec['repo'], license=spec['license'], bytes=sum(row['bytes'] for row in spec['files']), busy=self.busy(), ram_bytes=self.ram_bytes(machine)) @@ -271,15 +272,15 @@ def start(self, action, value): if value.get('accept_download') is not True: raise ValueError('consent_required') elif action == 'ask': - if not assets.ready(root): + if not assets.settle(root): raise ValueError('model_missing') value = self.ask_images(rules.ask_request(value)) elif action == 'split': - if not assets.ready(root): + if not assets.settle(root): raise ValueError('model_missing') value = rules.split_request(value) else: - if not assets.ready(root): + if not assets.settle(root): raise ValueError('model_missing') value = rules.request(value) from ..comfy_assets import resolve_assets @@ -627,6 +628,7 @@ def stop_prestart_for_generation(server): def register(): + import asyncio from aiohttp import web from server import PromptServer import folder_paths @@ -641,7 +643,7 @@ def register(): @server.routes.get('/freevideo/prompt-vlm') async def info(request): try: - return web.json_response(dict(service.info(), token=token)) + return web.json_response(dict(await asyncio.to_thread(service.info), token=token)) except (OSError, ValueError): return web.json_response(dict(error='setup_required'), status=400) @@ -670,6 +672,10 @@ async def action(request): running, pending = server.prompt_queue.get_current_queue() if running or pending: raise ValueError('busy') + if name in ('ask', 'split', 'rewrite'): + # A moved modified time is checked by content here, off the event loop; + # start() then finds the remembered answer. + await asyncio.to_thread(assets.settle, service.installation()[0]) result = service.start(name, value) return web.json_response(result) except (ValueError, OSError) as error: diff --git a/freevideo_engine/request_assets.py b/freevideo_engine/request_assets.py index 82e8ddbd..85136b13 100644 --- a/freevideo_engine/request_assets.py +++ b/freevideo_engine/request_assets.py @@ -59,7 +59,7 @@ def _upscaler(root, sampled): def _prompt_vlm(root): from .prompt_vlm import assets - if assets.ready(root): + if assets.settle(root): return [] spec = assets.catalog() return [dict(id='prompt-vlm', kind='prompt-vlm', files=len(spec['files']), From 7d67692820482d0f706137eab8d762fc21b58341 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:50 +0000 Subject: [PATCH 17/21] Add a one-line introduction to the unconnected autopilot page --- web/agent_connect.css | 1 + web/agent_connect.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/web/agent_connect.css b/web/agent_connect.css index d5722ec3..5e78fdc5 100644 --- a/web/agent_connect.css +++ b/web/agent_connect.css @@ -5,6 +5,7 @@ .fv-agent-connect-icon{width:44px;height:44px;border-radius:11px;display:grid;place-items:center;background:var(--fv-selected);color:var(--fv-accent-hover)} .fv-agent-connect-body svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round} .fv-agent-connect-body>h2{font-size:19px;line-height:1.3;font-weight:700;color:var(--fv-ink)} +.fv-agent-connect-body>.fv-agent-connect-intro{margin-top:-10px;font-size:13px;line-height:1.5;color:#a5b3c6} .fv-agent-connect-body>.fv-muted{margin-top:-10px;font-size:13.5px;color:var(--fv-muted)} .fv-agent-connect-actions{display:flex;align-items:center;gap:12px;margin-top:10px;flex-wrap:wrap} .fv-studio .fv-agent-connect-actions button{padding:9px 20px;font-size:14px}.fv-agent-connect-actions button svg{width:16px;height:16px} diff --git a/web/agent_connect.js b/web/agent_connect.js index 65bf2cd0..085c7133 100644 --- a/web/agent_connect.js +++ b/web/agent_connect.js @@ -36,6 +36,7 @@ export function agentConnectCard(t, api, shown = () => true) { const body = el('section', 'fv-agent-connect-body'); const mark = el('span', 'fv-agent-connect-icon'); mark.append(icon('plug')); const title = el('h2', null, t('Connect an agent', '连接 Agent')); + const intro = el('p', 'fv-agent-connect-intro', t('Once connected, describe the video you want. It generates and edits it for you.', '连上后,说想做什么视频,它来生成和剪辑。')); const subtitle = el('p', 'fv-muted', t('Claude Code, Codex, FreeToken and others', 'Claude Code、Codex、FreeToken 等')); const actions = el('div', 'fv-agent-connect-actions'); const button = el('button', 'fv-primary'); button.type = 'button'; button.disabled = true; @@ -44,7 +45,7 @@ export function agentConnectCard(t, api, shown = () => true) { actions.append(button, arrow, el('span', 'fv-agent-connect-hint', t('Paste to your agent', '粘贴给 Agent'))); const sentence = el('p', 'fv-agent-sentence'); sentence.hidden = true; const status = el('p', 'fv-agent-connect-status', t('Getting the connection address…', '正在获取连接地址…')); status.setAttribute('role', 'status'); - body.append(mark, title, subtitle, actions, sentence, status); + body.append(mark, title, intro, subtitle, actions, sentence, status); let feedback = false, text = '', failures = 0; let timer, feedbackTimer, controller, generation = 0; From 2dec3894990780f83cf74321aa9f0cf67e61a45a Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:51 +0000 Subject: [PATCH 18/21] Feedback for a failed generation carries the engine's error text --- web/failure_issue.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/web/failure_issue.js b/web/failure_issue.js index 66d3820f..069d5a49 100644 --- a/web/failure_issue.js +++ b/web/failure_issue.js @@ -20,6 +20,18 @@ export function failureStage(report) { return null; } +const TAIL = 1500, TAIL_HEAD = 500; + +// The engine's failure text, not ComfyUI's traceback after it: details end with +// the bridge's own frames. The error and stage lead that text and the child +// log's error ends it, so a long one gives up its middle. +function cause(report) { + const message = String(report?.message || ''); + const text = message.includes('\n') ? message : String(report?.details || ''); + if (text.length <= TAIL) return text; + return text.slice(0, TAIL_HEAD) + '\n...\n' + text.slice(-(TAIL - TAIL_HEAD - 5)); +} + /** Title, text and summary for the prefilled issue. `lora` marks a LoRA the check judged wrongly. */ export function failureIssue(report, kind, {lora = false, t = en => en} = {}) { const stage = failureStage(report); @@ -32,7 +44,7 @@ export function failureIssue(report, kind, {lora = false, t = en => en} = {}) { const types = (report?.nodes || []).map(node => node.type).filter(Boolean); const summary = JSON.stringify({kind: kind || 'unknown', stage: report?.stage, exception_type: report?.exception_type, known_error: report?.known_error, nodes: types, settings: report?.settings, progress: report?.progress, - tail: String(report?.details || '').slice(-1500)}); + tail: cause(report)}); const title = lora ? t('[Feedback] LoRA compatibility misjudged', '[Feedback] LoRA 兼容判断有误') : t('[Feedback] Generation did not finish', '[Feedback] 生成未完成') + (stage ? t(`: ${stage[0]}`, `:${stage[1]}`) : ''); return {title, text, summary}; From 5e22993fef920947db5f164987528fe889936bb3 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 05:54:52 +0000 Subject: [PATCH 19/21] Showcase: a cat jumping up a bookshelf replaces the race car example --- freevideo_engine/release_notes.json | 4 ++-- web/assets/entry-showcase.webp | Bin 485848 -> 405938 bytes web/entry_showcase.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/freevideo_engine/release_notes.json b/freevideo_engine/release_notes.json index 65ad725f..72175e48 100644 --- a/freevideo_engine/release_notes.json +++ b/freevideo_engine/release_notes.json @@ -33,7 +33,7 @@ "en": { "summary": "Preview white-model scenes for Autopilot, LoRA compatibility checks and drag-to-reorder, clearer failure messages, deleting edits, a faster start for a busy machine, and a Medium level that samples two passes.", "changes": [ - "Autopilot: an optional white-model preview, with ready-made scenes, shows the scene before the video is made; the entry showcase has an official race-car example.", + "Autopilot: an optional white-model preview, with ready-made scenes, shows the scene before the video is made; the entry showcase has an example.", "LoRA: a compatibility check before generating, and LoRAs can be reordered by dragging.", "Failure messages: submission, queue and browser-extension failures share one layout and say what to do next; failed requests can be packaged with Export report or Submit to GitHub.", "Editor: an edit can be deleted, an empty untouched edit is discarded, and reopening an edit restores its cover and shows its finishing stage; continuations are queued on the server.", @@ -50,7 +50,7 @@ "zh": { "summary": "AI 全自动新增白模预览场景,LoRA 兼容性检查和拖动排序,失败提示更清楚,可以删除剪辑,繁忙的机器上启动更快,标准档改为两遍采样。", "changes": [ - "AI 全自动:可选的白模预览和现成场景,在生成视频前先看到场景;入口展示里有官方赛车示例。", + "AI 全自动:可选的白模预览和现成场景,在生成视频前先看到场景;入口展示里有示例。", "LoRA:生成前做兼容性检查,LoRA 可以拖动排序。", "失败提示:提交、排队和浏览器扩展的失败用同一种版式,并说明下一步该做什么;失败的请求可以打包为导出报告或提交到 GitHub。", "编辑器:可以删除剪辑,没改动的空剪辑自动丢弃;重新打开剪辑会恢复封面并显示收尾阶段;续接在服务端排队。", diff --git a/web/assets/entry-showcase.webp b/web/assets/entry-showcase.webp index 095933858d49cd714471f0ec974ab4463b5e509f..4d56b0a1689b9628f458995d5a06a376bf3b8393 100644 GIT binary patch literal 405938 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\zvBatM`RWh!!*_R__r=(-@wL(B$(ygN)%W0|K6s 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.SV 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 N0t0ZTAS^Kg002aP+LizS literal 485848 zcmZ7d1CTB-(=7@=W7{_O*ybMFwv9cuZQHhO+qP|c{`WoKch6txwQ&1-Qb^gr33V@>gsu(CXJ=|$ znBk;jibMxKKyQ}e{81rVT$(VMczIZd>_;`ZC9&nd z#`=xcJO+0x)yc@4!ha2~*VZ6M*#@cJ@^QAs@T{?={!)XO?{S>uF%ELt-zzF=$Wt;pCmfa*8?80)J(CGNwTMOY=~ zPADHuQ&SO7Uk(|Cmw*3sYB_rXO=Nn2VPY6#t$(3qPLdGu<0a$9q>$Gw4K@^pxb#Bh zwe@?Gth~p1eudw;n9ZGNuZ(sU0BRr~n8w;I zoTrM4KY)Ck^nGx9w3x;vLH*WE(>zuLQea^p0yUE_9DVxwQhI9ZVy0Tf`&F6CeV{O< zB#7OkkO5bm{^XUaNfQ#`g zYWs=hsWB0yM7?sG-Jx$!7`McqYYiG-L_*^LYbk=+jlBRnK@cL~!K6naL>$Q9TAzu# zK*JHzd1QvX~q$?6tD}g3dv>J!VF6DFv0tfSjNpOk(v&JA-We8gbMhxL3CKJo0h+ zA;;nHL^bpL&ziMCtPWOwm;dn~hN%%tJ)y{VG;MeHN5A#(VTbD%hK3R;XL;COH$zxCqIL~uM_U^O_e~SdU!u3?Dtr@y6D+w(KfTHV`HfX z7lj-8r=4}By>U(})`YnQdNIt(K^|#_YE{yB z(I+biy|Jl1OXJgX%;)HKr#-zs^E=e@+-T>|1Y+%Qc!Ebeg4hk^PGQ`XtllA&NCsL9 z8{Mr&nF|%>A1a%0AX=M%fFW9*LW?vvE)nb$? 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 z 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

N+R!c^I6;APrimcfMzz#f+8%L0`Qi8%u~T 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�>Q!qCd$UP<0i#Bkh0H5wjE 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 diff --git a/web/entry_showcase.js b/web/entry_showcase.js index e4202e11..fdfd7896 100644 --- a/web/entry_showcase.js +++ b/web/entry_showcase.js @@ -2,15 +2,15 @@ // Each eligible product version gets one chapter in the existing guide.json seen list. export const SHOWCASE_START_VERSION = '0.4.10'; // The ready-made white-model scene the showcase's button starts. -export const SHOWCASE_SCENE = 'car'; +export const SHOWCASE_SCENE = 'cat'; export const SHOWCASE_ASSET = new URL('./assets/entry-showcase.webp', import.meta.url).href; export const SHOWCASE_TEXT = { title: ['From whitebox animation to finished video', '从白模动画到写实视频'], try: ['Get started', '开始使用'], close: ['Close', '关闭'], example: [ - "A red race car hits the end of a straight at full speed and throws itself into a corner, the rear sliding out in a controlled drift with a little tyre smoke, while the camera orbits half a circle around the car and then follows it out of the bend. Sunny circuit with red and white kerbs, grandstands and green grass, realistic paint and tarmac, strong sense of speed, smooth camera. Roaring engine and the squeal of tyres.", - "一辆红色赛车在直道尽头全速冲入弯道,车尾受控地甩出,带起少许轮胎烟,镜头绕车半圈后跟着它驶出弯道。晴天的赛道,红白相间的路缘石、看台和绿草地,写实的漆面和柏油路,速度感强,镜头平滑。引擎轰鸣,轮胎尖啸。", + "A ginger cat crouches on a living room floor, gathers itself and leaps up a staggered wooden bookshelf, jumping from one shelf to the next between rows of books, and finally settles on the top shelf, while the camera pans sideways and tilts up slightly to follow. Warm indoor daylight, realistic fur and wood, soft shadows, smooth camera motion. Soft room tone and the light thud of paws on wood.", + "一只橘猫在客厅地板上蹲下蓄力,跳上错落的木书架,在成排的书之间一层一层往上跳,最后稳稳落在最高一层,镜头向侧面平移并略微上摇跟随。温暖的室内日光,写实的毛发和木纹,柔和的阴影,镜头平滑。安静的室内环境声,爪子落在木头上的轻响。", ], }; From 088c00b75c02883994a4320787cd7aa4ae2202ff Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 06:19:57 +0000 Subject: [PATCH 20/21] Prompt enhancement on 6 GB cards: keep int8 layers on the GPU and stream the rest from host memory --- freevideo_engine/prompt_vlm/int8.py | 94 ++++++++++++++++++++++++++ freevideo_engine/prompt_vlm/load.py | 12 +++- freevideo_engine/prompt_vlm/service.py | 7 +- freevideo_engine/prompt_vlm/worker.py | 21 +++++- 4 files changed, 127 insertions(+), 7 deletions(-) diff --git a/freevideo_engine/prompt_vlm/int8.py b/freevideo_engine/prompt_vlm/int8.py index 4da67f83..0ba3205a 100644 --- a/freevideo_engine/prompt_vlm/int8.py +++ b/freevideo_engine/prompt_vlm/int8.py @@ -38,6 +38,16 @@ def __init__(self, source, device): bias = source.bias self.register_buffer('bias', None if bias is None else bias.detach().to(device)) + def offload(self): + """Keep the int8 rows in (pinned, when possible) host memory; a Streamer lends them to the GPU.""" + host = self.weight_int8.cpu() + try: + host = host.pin_memory() + except RuntimeError: + pass # Pageable memory copies slower but works. + self.host = host + self.weight_int8 = None + def forward(self, x): shape = x.shape rows = x.reshape(-1, self.in_features) @@ -121,3 +131,87 @@ def install(layer, device): source = getattr(parent, name) setattr(parent, name, Int8Linear(source, device)) del source + + +def layer_bytes(stored): + """{layer index: GPU bytes of its int8 projections and their scales}.""" + import re + projection = re.compile(r'model\.language_model\.layers\.(\d+)\.(self_attn\.[qkvo]_proj|mlp\.(gate|up|down)_proj)\.weight$') + rows = {} + for name, row in stored.items(): + match = projection.match(name) + if match: + index = int(match.group(1)) + rows[index] = rows.get(index, 0) + row['bytes'] // 2 + 4 * row['shape'][0] + return rows + + +PREFETCH = 2 # Layers copied ahead of the one running. + + +def resident_layers(weights, stored, room): + """How many leading layers stay on the GPU as int8 when the rest are streamed + from host memory one layer at a time; None when even the fixed part and the + staging buffers do not fit `room`. Returns (layers, host_bytes).""" + sizes = layer_bytes(stored) + count = len(sizes) + if not count: + return None + projections = sum(row['bytes'] for name, row in stored.items() if name.startswith('model.language_model.layers.') + and name.endswith('_proj.weight')) + fixed = weights - projections + largest = max(sizes.values()) + free = room - fixed - (PREFETCH + 1) * largest + kept, used = 0, 0 + while kept < count and used + sizes[kept] <= free: + used += sizes[kept] + kept += 1 + if free < 0: + return None + return kept, sum(sizes[i] for i in range(kept, count)) + + +class Streamer: + """Lends host-held int8 rows to the GPU one layer ahead of use. + + The copies run on their own stream into pinned memory; a layer's + forward waits only for its own copy and drops the GPU rows afterwards. + """ + + def __init__(self, torch, layers): + self.torch = torch + self.layers = layers + self.linears = [[getattr(parent, name) for parent, name in projections(layer)] for layer in layers] + self.stream = torch.cuda.Stream() + self.pending = {} + for position, layer in enumerate(layers): + layer.register_forward_pre_hook(lambda module, args, kwargs, p=position: self.before(p), with_kwargs=True) + layer.register_forward_hook(lambda module, args, output, p=position: self.after(p)) + + def fetch(self, position): + if position in self.pending: + return + torch = self.torch + with torch.cuda.stream(self.stream): + tensors = [linear.host.to('cuda', non_blocking=True) for linear in self.linears[position]] + event = torch.cuda.Event() + event.record(self.stream) + self.pending[position] = (event, tensors) + + def before(self, position): + torch = self.torch + self.fetch(position) + event, tensors = self.pending.pop(position) + current = torch.cuda.current_stream() + current.wait_event(event) + for linear, tensor in zip(self.linears[position], tensors): + tensor.record_stream(current) + linear.weight_int8 = tensor + count = len(self.layers) + for ahead in range(1, PREFETCH + 1): + self.fetch((position + ahead) % count) # The next token starts at the first streamed layer. + return None + + def after(self, position): + for linear in self.linears[position]: + linear.weight_int8 = None diff --git a/freevideo_engine/prompt_vlm/load.py b/freevideo_engine/prompt_vlm/load.py index 8d299d0e..9119c961 100644 --- a/freevideo_engine/prompt_vlm/load.py +++ b/freevideo_engine/prompt_vlm/load.py @@ -36,8 +36,11 @@ def stored(folder): return rows -def resident(folder, torch, device, precision): - """Returns the model on `device`, with int8 projections if precision == 'int8'.""" +def resident(folder, torch, device, precision, keep=None): + """Returns the model on `device`, with int8 projections if precision == 'int8'. + + With `keep`, layers from that index on hold their int8 rows in host memory + and are streamed to the GPU as they run.""" from accelerate import init_empty_weights from torch import nn from transformers import AutoConfig, GenerationConfig, Qwen3VLForConditionalGeneration @@ -89,6 +92,9 @@ def each_layer(layer, merge): merge(layer) if precision == 'int8': int8.install(layer, device) + if keep is not None and layer.self_attn.layer_idx >= keep: + for parent, name in int8.projections(layer): + getattr(parent, name).offload() core.prepare(model, each_layer) finally: for reader in readers.values(): @@ -96,5 +102,7 @@ def each_layer(layer, merge): if tied: model.lm_head.weight = model.model.language_model.embed_tokens.weight model = model.to(device) + if keep is not None: + model.streamer = int8.Streamer(torch, list(model.model.language_model.layers)[keep:]) torch.cuda.empty_cache() # Merge and quantize temporaries; KV space comes next. return model diff --git a/freevideo_engine/prompt_vlm/service.py b/freevideo_engine/prompt_vlm/service.py index e512ec44..1a8acbff 100644 --- a/freevideo_engine/prompt_vlm/service.py +++ b/freevideo_engine/prompt_vlm/service.py @@ -229,11 +229,12 @@ def ram_bytes(self, machine): """Available RAM the model usually needs on this computer, for the download card. The worker decides from free VRAM when it loads: 8 GB and larger NVIDIA - cards hold the whole model. Asks the driver once, without CUDA; anything + cards keep their layers on the GPU; 6 GB cards stream from RAM the layers + that do not fit, which needs more of it. Asks the driver once, without CUDA; anything unknown states the larger figure. """ if self.ram is None: - from .worker import MAPPED_RAM, RESIDENT_RAM + from .worker import MAPPED_RAM, RESIDENT_RAM, STREAMED_RAM self.ram = MAPPED_RAM if machine.get('device_backend', 'cuda') == 'cuda': from .. import processes @@ -246,6 +247,8 @@ def ram_bytes(self, machine): total = totals.get(machine.get('gpu_uuid')) or (len(totals) == 1 and next(iter(totals.values()))) if total and total >= 7.5 * 1024: self.ram = RESIDENT_RAM + elif total and total >= 5.5 * 1024: + self.ram = STREAMED_RAM except (OSError, RuntimeError, ValueError, subprocess.SubprocessError): pass return self.ram diff --git a/freevideo_engine/prompt_vlm/worker.py b/freevideo_engine/prompt_vlm/worker.py index 34595365..3a2b8162 100644 --- a/freevideo_engine/prompt_vlm/worker.py +++ b/freevideo_engine/prompt_vlm/worker.py @@ -150,7 +150,7 @@ def failure(error, mode='rewrite'): Tokenizers may quote only a fragment of either draft: replacing the full prompt in an exception is not sufficient to make that exception private. """ - allowed = {'ram_space', 'image_size', 'context_length', 'invalid_output'} + allowed = {'ram_space', 'image_size', 'context_length', 'invalid_output', 'out_of_memory'} message = str(error) fallback = 'ask_failed' if mode == 'ask' else 'rewrite_failed' code = message if message in allowed else 'out_of_memory' if 'out of memory' in message.lower() else fallback @@ -205,6 +205,7 @@ def tokenize(processor, messages, max_pixels=512 * 32 * 32): # CUDA context alone take about 2.5 GB of commit). Other placements map and # merge the whole model in RAM; theirs is checked after the imports. RESIDENT_RAM = 4 * 2**30 +STREAMED_RAM = 6 * 2**30 # download-card figure for 6 GB cards: resident part plus the streamed layers' host copy MAPPED_RAM = 11 * 2**30 @@ -263,6 +264,8 @@ def load_model(folder, torch, stats, checkpoint): shapes = stored(folder) weights = sum(row['bytes'] for row in shapes.values()) resident = None + keep = None + host_bytes = 0 weight_budget = 0 if torch.cuda.is_available(): from .. import gpu_budget @@ -277,7 +280,19 @@ def load_model(folder, torch, stats, checkpoint): kv = kv_bytes(shapes, reserved_tokens(stats)) stats.update(gpu_allocator_budget_bytes=free, gpu_weight_budget_bytes=weight_budget, gpu_kv_reserve_bytes=kv) resident = placement(weights, int8.saved_bytes(shapes), kv, free) - stats['ram_required_bytes'] = RESIDENT_RAM if resident else MAPPED_RAM + if not resident: + # Too big even as int8: keep what fits on the GPU and stream the other + # layers' int8 rows from host memory, a layer ahead of use. + plan = int8.resident_layers(weights, shapes, free - kv - WORKING_VRAM) + if plan: + resident, (keep, host_bytes) = 'int8', plan + stats.update(streamed_layers=len(int8.layer_bytes(shapes)) - keep if keep is not None else 0, + streamed_host_bytes=host_bytes) + if not resident and weight_budget <= 2 * 2**30: + # Not even the streaming tier fits: the model would run on the CPU at + # about 0.2 tokens/s and hit the request deadline, so say so at once. + raise ValueError('out_of_memory') + stats['ram_required_bytes'] = (RESIDENT_RAM + host_bytes) if resident else MAPPED_RAM available = stats['available_memory_at_start_bytes' if resident else 'available_memory_before_load_bytes'] if available < stats['ram_required_bytes']: raise ValueError('ram_space') @@ -285,7 +300,7 @@ def load_model(folder, torch, stats, checkpoint): loading = time.monotonic() if resident: from .load import resident as load_resident - model = load_resident(folder, torch, 'cuda:0', resident) + model = load_resident(folder, torch, 'cuda:0', resident, keep) mapping, device = {'': 0}, 'cuda:0' stats.update(weights=resident, kv_positions=kv_positions(reserved_tokens(stats))) else: From 36789f9586e66ebd111cac1617160aeca7330501 Mon Sep 17 00:00:00 2001 From: Bowen Xue Date: Sun, 18 Oct 2026 07:21:05 +0000 Subject: [PATCH 21/21] Release 0.4.14 --- freevideo_engine/release_notes.json | 71 +++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/freevideo_engine/release_notes.json b/freevideo_engine/release_notes.json index 72175e48..66aca191 100644 --- a/freevideo_engine/release_notes.json +++ b/freevideo_engine/release_notes.json @@ -1,33 +1,66 @@ { "schema": 1, - "product_version": "0.4.13", + "product_version": "0.4.14", "en": { - "summary": "High is faster than Max again, videos at another size of the same shape can be continued, LoRAs on int8 models apply what they can, Settings adds step-by-step how-tos and an offline tutorial, and the installers are smaller.", + "summary": "Max is faster, a picture can now be changed only inside a region you select, agents can import their own clips into the timeline, and long videos can take more requests into the queue while they generate.", "changes": [ - "High: the step cache is back with added checks, so High runs faster than Max again.", - "Long videos: parts of a long video and continued parts use 8 + 3 steps, so a second part is no longer refused.", - "Continue: a video at another size of the same shape now continues from its own ending. Videos that are too short or have too low a frame rate show a clear message.", - "LoRA: on int8 models, the parts of a LoRA that cannot be applied are skipped and the rest takes effect, instead of the whole LoRA being refused.", - "Help: \"User guide\" in Settings shows three how-tos on the real interface, and the new \"Tutorial\" opens an offline illustrated manual in English and Chinese.", - "Upgrade: a FreeVideo tab left open from an older version switches to the current workflow and keeps the prompt, size, length, seed, assets and LoRAs.", - "Agent: assembled videos are saved to \"Your creations\", and their task cards can be opened.", - "Install: the Windows and Linux installers are smaller, the prompt enhancement model can also download from ModelScope, and the GPU acceleration step shows one steady name and description while it builds." + "Quality levels: Max now uses 20 steps with a guarded step cache and finishes sooner; High uses 16 steps with the step cache. The level names stay the same.", + "Picture editing: when changing a picture, drag a box, click an object, or draw a closed outline to select a region. Shift adds to the selection and Alt removes from it. Only the selected region changes, and everything outside it stays exactly the same. Click selection downloads a 184 MB model from ModelScope the first time it is used.", + "Studio: while a long or multi-part video is generating, the button stays available as \"Add to queue\". Up to five requests can wait, and each starts when the current video finishes or is stopped.", + "Agent: agents can import clips they rendered through HTTP, MCP and the command line, place them on the timeline by frame, and export. Before an agent is connected, the autopilot page says what connecting one is for.", + "Editing view: a reference picture that cannot be read is flagged right away so another one can be chosen.", + "Upgrade: when an old FreeVideo tab is replaced, two-pass sampling, first- and second-pass steps, the step cache and the upscale factor are carried over.", + "Prompt enhancement: after the model folder is copied, an offline package is unpacked, or antivirus software scans the files, FreeVideo no longer asks to download 8.9 GB again when the files are unchanged. It now also works on 6 GB graphics cards, finishing in under a minute instead of timing out.", + "Chinese interface: browser translation no longer changes FreeVideo's own labels, so the size menu keeps showing MP.", + "Feedback: feedback sent for a failed generation now includes the engine's error message.", + "Install: the Windows library checks also handle files in deeply nested folders." ] }, "zh": { - "summary": "精细档重新比极致档快;同比例、不同尺寸的视频可以接着生成;int8 模型上的 LoRA 能用的部分照常生效;设置中新增分步演示和离线教程;安装包变小。", + "summary": "极致档更快;改图时可以只改选中的区域;Agent 可以把自己渲染的片段导入时间线;长视频生成中可以继续加入队列。", "changes": [ - "精细档:重新启用步缓存,并加上检查,精细档重新比极致档快。", - "长视频:长视频的分段和接着生成的分段统一使用 8 + 3 步,第二段不再被拒绝。", - "接着生成:同比例、不同尺寸的视频改为从它自己的结尾接着生成;太短或帧率太低的视频会给出明确提示。", - "LoRA:在 int8 模型上,LoRA 中无法应用的部分会跳过,其余照常生效,不再整个拒绝。", - "帮助:设置中的“使用说明”改为在真实界面上演示三项操作;新增“教程”,可打开中英文离线图文手册。", - "升级:旧版本留在标签页中的 FreeVideo 工作流会换成当前版本,并保留提示词、尺寸、时长、种子、素材和 LoRA。", - "Agent:拼接的成片保存到“我的作品”,任务卡可以打开。", - "安装:Windows 和 Linux 安装包变小;提示词增强模型也可以从魔搭下载;GPU 加速组件构建时,名称和说明保持不变。" + "质量档位:极致档改为 20 步加带检查的步缓存,更快完成;精细档改为 16 步加步缓存。档位名称不变。", + "改图:改一张图时,可以拖框、点选物体或画闭合曲线来选区;按住 Shift 添加,按住 Alt 减去。只改选区里的内容,选区外完全不变。点选第一次使用时从魔搭下载 184 MB 的模型。", + "创作面板:长视频或分段视频生成中,按钮保持可用,显示“加入队列”。最多排 5 条,当前视频完成或停止后自动开始下一条。", + "Agent:Agent 可以通过 HTTP、MCP 和命令行导入自己渲染的片段,按帧放上时间线并导出。未连接时,自动页说明连上之后能做什么。", + "剪辑视图:参考图读不出来时会当场提示,可以换一张。", + "升级:替换旧版本的 FreeVideo 标签页时,二次采样、第一遍和第二遍步数、步缓存和放大倍数都会带过来。", + "提示词增强:复制模型文件夹、解压离线包或被杀毒软件扫描之后,只要文件内容没变,就不再要求重新下载 8.9 GB。6 GB 显卡上现在也能用,一分钟内完成,不再超时。", + "中文界面:浏览器翻译不再改动 FreeVideo 自己的文字,尺寸菜单保持显示 MP。", + "反馈:为失败的生成发送反馈时,会附上引擎给出的报错信息。", + "安装:Windows 上的库文件检查也支持层级很深的文件夹。" ] }, "history": [ + { + "product_version": "0.4.13", + "en": { + "summary": "High is faster than Max again, videos at another size of the same shape can be continued, LoRAs on int8 models apply what they can, Settings adds step-by-step how-tos and an offline tutorial, and the installers are smaller.", + "changes": [ + "High: the step cache is back with added checks, so High runs faster than Max again.", + "Long videos: parts of a long video and continued parts use 8 + 3 steps, so a second part is no longer refused.", + "Continue: a video at another size of the same shape now continues from its own ending. Videos that are too short or have too low a frame rate show a clear message.", + "LoRA: on int8 models, the parts of a LoRA that cannot be applied are skipped and the rest takes effect, instead of the whole LoRA being refused.", + "Help: \"User guide\" in Settings shows three how-tos on the real interface, and the new \"Tutorial\" opens an offline illustrated manual in English and Chinese.", + "Upgrade: a FreeVideo tab left open from an older version switches to the current workflow and keeps the prompt, size, length, seed, assets and LoRAs.", + "Agent: assembled videos are saved to \"Your creations\", and their task cards can be opened.", + "Install: the Windows and Linux installers are smaller, the prompt enhancement model can also download from ModelScope, and the GPU acceleration step shows one steady name and description while it builds." + ] + }, + "zh": { + "summary": "精细档重新比极致档快;同比例、不同尺寸的视频可以接着生成;int8 模型上的 LoRA 能用的部分照常生效;设置中新增分步演示和离线教程;安装包变小。", + "changes": [ + "精细档:重新启用步缓存,并加上检查,精细档重新比极致档快。", + "长视频:长视频的分段和接着生成的分段统一使用 8 + 3 步,第二段不再被拒绝。", + "接着生成:同比例、不同尺寸的视频改为从它自己的结尾接着生成;太短或帧率太低的视频会给出明确提示。", + "LoRA:在 int8 模型上,LoRA 中无法应用的部分会跳过,其余照常生效,不再整个拒绝。", + "帮助:设置中的“使用说明”改为在真实界面上演示三项操作;新增“教程”,可打开中英文离线图文手册。", + "升级:旧版本留在标签页中的 FreeVideo 工作流会换成当前版本,并保留提示词、尺寸、时长、种子、素材和 LoRA。", + "Agent:拼接的成片保存到“我的作品”,任务卡可以打开。", + "安装:Windows 和 Linux 安装包变小;提示词增强模型也可以从魔搭下载;GPU 加速组件构建时,名称和说明保持不变。" + ] + } + }, { "product_version": "0.4.12", "en": {