This commit is contained in:
parent
b41e31155a
commit
a7310897b2
83
bridges/wegb-2026-07-22/cdp.py
Normal file
83
bridges/wegb-2026-07-22/cdp.py
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
"""Weg B — CDPBridge: an das BEREITS eingeloggte Chrome auf gpu-pc (CDP :9223) andocken,
|
||||||
|
statt einen eigenen Browser (launch_persistent_context) mit injizierten Cookies zu starten.
|
||||||
|
|
||||||
|
suno.py macht das bereits (eigenes get_page() mit connect_over_cdp). Dieses Modul verallgemeinert
|
||||||
|
exakt dieses erprobte Muster, damit gemini.py und qolaba.py denselben Weg nutzen, ohne ihre
|
||||||
|
Selector-/Ablauf-Logik anzufassen.
|
||||||
|
|
||||||
|
Die Session MUSS auf gpu-pc eingeloggt sein (sonst [BAER - PWA-Login]). Auto-Relogin aus dem
|
||||||
|
Bridge-Prozess ist bei geteiltem CDP-Context nicht moeglich (relogin_supported=False).
|
||||||
|
"""
|
||||||
|
import asyncio, os, socket
|
||||||
|
from urllib.parse import urlparse, urlunparse
|
||||||
|
from patchright.async_api import async_playwright as _patchright_async_playwright
|
||||||
|
from .base import PWABridge
|
||||||
|
|
||||||
|
CDP_URL = os.environ.get("PWA_CDP_URL") or os.environ.get("SUNO_CDP_URL") \
|
||||||
|
or "http://host.docker.internal:9223"
|
||||||
|
|
||||||
|
_cdp_pw = None
|
||||||
|
_cdp_browser = None
|
||||||
|
|
||||||
|
|
||||||
|
def _resolve_cdp_url(url: str) -> str:
|
||||||
|
try:
|
||||||
|
parsed = urlparse(url)
|
||||||
|
if parsed.hostname in ("host.docker.internal", "localhost"):
|
||||||
|
ip = socket.gethostbyname(parsed.hostname)
|
||||||
|
netloc = f"{ip}:{parsed.port}" if parsed.port else ip
|
||||||
|
return urlunparse(parsed._replace(netloc=netloc))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[cdp] _resolve_cdp_url err ({e}), using raw CDP_URL", flush=True)
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
|
async def _cdp_connect():
|
||||||
|
global _cdp_pw, _cdp_browser
|
||||||
|
if _cdp_pw is None:
|
||||||
|
_cdp_pw = await _patchright_async_playwright().start()
|
||||||
|
if _cdp_browser is not None:
|
||||||
|
try:
|
||||||
|
_ = _cdp_browser.contexts
|
||||||
|
except Exception:
|
||||||
|
_cdp_browser = None
|
||||||
|
if _cdp_browser is None:
|
||||||
|
resolved = _resolve_cdp_url(CDP_URL)
|
||||||
|
_cdp_browser = await asyncio.wait_for(
|
||||||
|
_cdp_pw.chromium.connect_over_cdp(resolved), timeout=12)
|
||||||
|
return _cdp_browser
|
||||||
|
|
||||||
|
|
||||||
|
class CDPBridge(PWABridge):
|
||||||
|
match_host: str = ""
|
||||||
|
relogin_supported = False
|
||||||
|
|
||||||
|
async def get_ctx(self):
|
||||||
|
b = await _cdp_connect()
|
||||||
|
return b.contexts[0] if b.contexts else await b.new_context()
|
||||||
|
|
||||||
|
async def get_page(self):
|
||||||
|
global _cdp_browser
|
||||||
|
try:
|
||||||
|
b = await _cdp_connect()
|
||||||
|
ctx = b.contexts[0] if b.contexts else await b.new_context()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[{self.name}] CDP stale handle ({e}), forcing reconnect", flush=True)
|
||||||
|
_cdp_browser = None
|
||||||
|
b = await _cdp_connect()
|
||||||
|
ctx = b.contexts[0] if b.contexts else await b.new_context()
|
||||||
|
|
||||||
|
host = self.match_host or (urlparse(self.url).hostname or "")
|
||||||
|
for p in ctx.pages:
|
||||||
|
try:
|
||||||
|
if host and host in (p.url or ""):
|
||||||
|
return p
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
p = await ctx.new_page()
|
||||||
|
if self.url:
|
||||||
|
try:
|
||||||
|
await p.goto(self.url, wait_until="domcontentloaded", timeout=30000)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[{self.name}] CDP initial goto err: {e}", flush=True)
|
||||||
|
return p
|
||||||
80
nachtplan-2026-07-22/wan22-beweis.csv
Normal file
80
nachtplan-2026-07-22/wan22-beweis.csv
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
ts,gpu_util_pct,gpu_mem_used_mib,cpu_load_pct
|
||||||
|
21:26:52,33,10718,79
|
||||||
|
21:26:56,0,10718,100
|
||||||
|
21:26:59,0,10718,100
|
||||||
|
21:27:03,0,10718,100
|
||||||
|
21:27:06,0,10718,100
|
||||||
|
21:27:10,0,10718,97
|
||||||
|
21:27:27,0,10718,87
|
||||||
|
21:27:31,6,12766,80
|
||||||
|
21:27:36,6,13310,79
|
||||||
|
21:27:40,5,13790,89
|
||||||
|
21:27:45,4,14270,88
|
||||||
|
21:27:49,4,14750,87
|
||||||
|
21:27:53,3,15262,79
|
||||||
|
21:27:58,5,15774,78
|
||||||
|
21:28:02,6,16254,85
|
||||||
|
21:28:07,6,16798,87
|
||||||
|
21:28:11,0,17086,87
|
||||||
|
21:28:15,20,17758,81
|
||||||
|
21:28:20,4,17854,93
|
||||||
|
21:28:24,10,19168,73
|
||||||
|
21:28:28,100,23872,82
|
||||||
|
21:28:32,99,24128,71
|
||||||
|
21:28:37,0,24128,82
|
||||||
|
21:28:42,4,24128,73
|
||||||
|
21:28:46,0,24128,66
|
||||||
|
21:28:51,0,24128,68
|
||||||
|
21:28:55,1,24128,84
|
||||||
|
21:29:00,0,15488,76
|
||||||
|
21:29:04,5,16064,85
|
||||||
|
21:29:09,5,16640,81
|
||||||
|
21:29:13,6,17152,90
|
||||||
|
21:29:18,5,17728,84
|
||||||
|
21:29:22,6,18240,85
|
||||||
|
21:29:27,4,18752,84
|
||||||
|
21:29:31,5,19200,97
|
||||||
|
21:29:36,6,19744,81
|
||||||
|
21:29:40,4,20128,91
|
||||||
|
21:29:45,0,20512,88
|
||||||
|
21:29:49,6,20928,91
|
||||||
|
21:29:54,6,21344,93
|
||||||
|
21:29:59,6,21760,90
|
||||||
|
21:30:03,6,22176,82
|
||||||
|
21:30:08,3,22688,97
|
||||||
|
21:30:12,6,23168,88
|
||||||
|
21:30:16,5,23680,93
|
||||||
|
21:30:21,5,24128,84
|
||||||
|
21:30:25,5,24544,91
|
||||||
|
21:30:29,6,24992,91
|
||||||
|
21:30:34,6,25472,80
|
||||||
|
21:30:39,0,25664,79
|
||||||
|
21:30:43,0,25856,85
|
||||||
|
21:30:48,0,31234,91
|
||||||
|
21:30:52,0,31234,91
|
||||||
|
21:30:57,9,31234,93
|
||||||
|
21:31:01,100,31234,92
|
||||||
|
21:31:06,100,31234,93
|
||||||
|
21:31:10,41,31234,89
|
||||||
|
21:31:14,17,31234,91
|
||||||
|
21:31:19,52,31234,87
|
||||||
|
21:31:23,1,31234,87
|
||||||
|
21:31:28,100,31234,81
|
||||||
|
21:31:33,0,31234,93
|
||||||
|
21:31:37,100,31234,90
|
||||||
|
21:31:42,100,31234,94
|
||||||
|
21:31:46,84,31234,87
|
||||||
|
21:31:51,24,31234,84
|
||||||
|
21:31:55,45,31234,78
|
||||||
|
21:32:00,1,31234,92
|
||||||
|
21:32:04,11,31234,87
|
||||||
|
21:32:08,44,31234,90
|
||||||
|
21:32:13,0,31234,90
|
||||||
|
21:32:17,4,31234,84
|
||||||
|
21:32:22,7,31234,94
|
||||||
|
21:32:26,0,31234,86
|
||||||
|
21:32:31,7,31234,84
|
||||||
|
21:32:36,2,31234,93
|
||||||
|
21:32:40,0,31234,91
|
||||||
|
21:32:45,3,31234,88
|
||||||
|
21:32:49,55,31234,79
|
||||||
|
39
nachtplan-2026-07-22/wan22-cpu-gpu-beweislauf.md
Normal file
39
nachtplan-2026-07-22/wan22-cpu-gpu-beweislauf.md
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Wan2.2 CPU+GPU-Beweislauf (lokal, A40) — Nachtplan #6
|
||||||
|
|
||||||
|
**Datum:** 2026-07-22 ~21:32 CEST · **Host:** VM302 (A40, Kansas City) · **Engine:** lokal, keine Cloud
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
Nachweisen, dass die Video-Generierung (Wan2.2 I2V) tatsaechlich **lokal auf der A40** laeuft und
|
||||||
|
dabei **CPU und GPU gleichzeitig** ausgelastet werden — nicht Cloud, nicht nur CPU, nicht nur GPU.
|
||||||
|
|
||||||
|
## Aufbau
|
||||||
|
- Orchestrator VM302:8197 (`main_v3_portal.py`), Endpoint `POST /generate`
|
||||||
|
- Request: `{"prompt":"Christina Fischer ... Ganzkoerper","typ":"video","video_dauer_sekunden":3,"seed":424242}`
|
||||||
|
- Job `df788e2dac`, Plan: 4x text2img (realisticVision) -> 1 Wan2.2-I2V-Segment, 49 Frames @ 16fps
|
||||||
|
- Modell: **Wan2.2-I2V-A14B** High+LowNoise **Q5_K_M GGUF** (je 10 GB) aus `M:\ComfyUI\models\unet`, VAE `wan_2.1_vae` (MoE-2-Experten)
|
||||||
|
- Sampler: alle 2s parallel `nvidia-smi`(util+mem) UND `Win32_Processor.LoadPercentage` -> CSV (als SYSTEM-Scheduled-Task, session-fest)
|
||||||
|
|
||||||
|
## Ergebnis (Beleg)
|
||||||
|
71 Messpunkte ueber 180s. **Peak: GPU 100% / VRAM 31234 MiB / CPU 100% — beide gleichzeitig unter Volllast.**
|
||||||
|
|
||||||
|
Kurvenverlauf (dreiphasig, typisch fuer die Kette):
|
||||||
|
1. **text2img (4 Bilder):** GPU-Spikes bis 33%, CPU 87-100% (VAE-Decode CPU-lastig)
|
||||||
|
2. **Wan-Modell-Load:** VRAM steigt 10,7 -> 24 -> 31 GB (beide GGUF-Experten resident), CPU 73-93%
|
||||||
|
3. **Wan2.2-Sampling:** GPU-Peaks 100% (21:28:28, 21:31:01-42 mehrfach), CPU durchgehend 78-97%
|
||||||
|
|
||||||
|
CPU faellt ueber den gesamten Lauf nie unter ~66%, meist 80-97%; GPU erreicht wiederholt 100% bei
|
||||||
|
31 GB residentem Modell. **-> CPU+GPU nachweislich parallel, Lauf vollstaendig lokal auf der A40.**
|
||||||
|
|
||||||
|
Rohdaten: `wan22-beweis.csv` (dieses Verzeichnis).
|
||||||
|
|
||||||
|
## Reproduktion
|
||||||
|
```
|
||||||
|
POST http://127.0.0.1:8197/generate (VM302)
|
||||||
|
Body: {"prompt":"...","typ":"video","video_dauer_sekunden":3,"seed":424242}
|
||||||
|
Sampler: M:\wan22-sampler.ps1 (nvidia-smi + Win32_Processor alle 2s -> CSV)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hinweise
|
||||||
|
- Erster detached Sampler (`Start-Process`) wurde beim WinRM-Session-Ende gekillt (nur 1 Zeile) ->
|
||||||
|
Lehre: Langlaeufer als **Scheduled Task** (SYSTEM), nicht als WinRM-Kindprozess.
|
||||||
|
- Kein Reboot durchgefuehrt (Nachtplan-Regel).
|
||||||
41
nachtplan-2026-07-22/weg-b-cdp-umbiegung.md
Normal file
41
nachtplan-2026-07-22/weg-b-cdp-umbiegung.md
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Weg B — Bridge-Adapter auf gpu-pc-CDP :9223 umbiegen (Nachtplan #5)
|
||||||
|
|
||||||
|
**Datum:** 2026-07-22 · **Status:** Code fertig + py_compile-sauber · **Nutzbarkeit:** [BÄR — PWA-Login gpu-pc]
|
||||||
|
|
||||||
|
## Kontext
|
||||||
|
Der dedizierte Bridge-Server `bridge.ki1.it` wurde am 2026-07-22 abgebaut. Einzige Quelle dauerhaft
|
||||||
|
eingeloggter PWA-Sessions = **gpu-pc (100.109.177.88)**, dort Chrome mit remote-debugging **:9223**
|
||||||
|
(Suno/Gemini/Qolaba live). "Weg B" = Adapter greifen diese Tabs per CDP ab, statt einen zweiten
|
||||||
|
Browser mit kopierten Cookies zu betreiben (bei Google-OAuth ohnehin fragil).
|
||||||
|
|
||||||
|
## Befund
|
||||||
|
- **suno.py macht Weg B bereits** — eigenes `get_page()` mit `connect_over_cdp` (host.docker.internal:9223
|
||||||
|
via SSH-Tunnel, Hostname->IP wegen Chrome-CDP-Host-Header-Check).
|
||||||
|
- **gemini.py / qolaba.py** nutzten bisher `base.get_page()` = `launch_persistent_context` (eigenes Chrome
|
||||||
|
+ injizierte Cookies). Diese sind auf CDP umgestellt.
|
||||||
|
- **mammouth.py** = Firefox + SOCKS5 (gpu-pc-Egress). Firefox hat kein Chromium-CDP -> `connect_over_cdp`
|
||||||
|
nicht anwendbar. Zusaetzlich Session aktuell ausgeloggt. **Bleibt Firefox-Sonderfall.**
|
||||||
|
|
||||||
|
## Umsetzung
|
||||||
|
Neues Modul `app/bridges/cdp.py` mit `CDPBridge(PWABridge)` — verallgemeinert exakt suno's erprobtes
|
||||||
|
Muster (gemeinsamer CDP-Browser-Handle mit Reconnect, Hostname->IP-Aufloesung, Tab-Wiederverwendung
|
||||||
|
nach Domain). Aenderungen an gemini.py/qolaba.py minimal:
|
||||||
|
- `class Gemini(CDPBridge)` + `match_host="gemini.google.com"`, `relogin_supported=True` entfernt
|
||||||
|
- `class Qolaba(CDPBridge)` + `match_host="qolaba.ai"`, `relogin_supported=True` entfernt
|
||||||
|
- Die gesamte Selector-/Ablauf-Logik (chat/image/audio/video/veo3) **unveraendert**.
|
||||||
|
|
||||||
|
Sicherheit: `CDPBridge.get_page()` oeffnet bei fehlendem Domain-Tab einen **eigenen neuen Tab**
|
||||||
|
(kein Hijack von `pages[0]` eines fremden Dienstes). `relogin_supported=False` (geteilter CDP-Context).
|
||||||
|
|
||||||
|
## Nutzbarkeit (ehrlich)
|
||||||
|
Rein technische Umbiegung. Die Session MUSS auf gpu-pc eingeloggt sein. Am 2026-07-22 ist
|
||||||
|
**Mammouth ausgeloggt** (rigoros geprueft: /login-Redirect, kein Auth-Cookie); Gemini-Google-OAuth
|
||||||
|
kann ebenfalls ablaufen. Dann meldet `login_status()` ehrlich `logged_in=False` und die Methoden
|
||||||
|
liefern eine Login-Wall. **-> einmaliger Human-Login auf gpu-pc noetig ([BÄR — PWA-Login gpu-pc]).**
|
||||||
|
Auto-Relogin aus dem Bridge-Prozess ist bei geteiltem CDP nicht moeglich.
|
||||||
|
|
||||||
|
## Deployment (offen, [BÄR]/Folgeschritt)
|
||||||
|
bridge.ki1.it ist weg — der Bridge-Prozess braucht einen neuen Host MIT SSH-Tunnel zu gpu-pc:9223
|
||||||
|
(oder Betrieb direkt auf gpu-pc gegen localhost:9223). Env: `PWA_CDP_URL=http://host.docker.internal:9223`.
|
||||||
|
|
||||||
|
Code: `bridges/cdp.py` (dieses Repo), Adapter-Backup `D:\claude\backups\bridges-adapter-code-2026-07-22.tgz`.
|
||||||
Loading…
Reference in a new issue