Commit Graph
7 Commits
Author SHA1 Message Date
WildAi 3af08f4357 perf(keep): stream the clip through detection/restore and place the face nets on the pack device
- R1: the face helper is constructed on the pack device (was the offload
  device); load_device() explicitly places the detector and the parser with
  a logged CPU fallback, offload() mirrors the restore, the YOLO .device
  skew is closed (P-D1..P-D5).
- R2: detection streams per max_clip_length group (no full-clip convert-in
  retention), crop is fused into a chunk-bounded restore loop with
  preallocated staging, the paste tail keeps one contractual float32
  buffer, the helper is released after every run; golden fixtures pin the
  outputs bitwise (P-M1..P-M7).
- The diagnosis: the OOM was O(frames) whole-clip host buffers, not the
  faces (the detector/landmark path was already GPU-placed);
  max_clip_length never bounded convert-in or the paste tail.
- Gate: 523 passed, 6 skipped, 7 deselected, 0 failed (baseline 505).
2026-10-28 23:39:53 +03:00
WildAi 508439622a feat(models): download only the selected face detector
The loader resolved every facedetection entry of the manifest, so all four detectors were fetched. The selection now drives the download set: the chosen detector and the parsing net the helper needs, co-located in one root because the vendored helper builds its weight paths from a single root.
2026-10-25 17:32:48 +03:00
WildAi 01a4924489 plan(P5): address review findings
The five review findings of 2026-10-23 for phase P5:

1. The P5.5 fallback branch (a checkpoint without flownet.* keys) died with
   a bare RuntimeError at the strict load: the arch always owns the flownet
   (keep_arch.py:882), so the state dict of the net always carries the
   flownet.* keys - and the GMFlow weights the arch had just loaded were
   discarded.  The flownet tensors of the built net (the trained ones - the
   arch was built with flownet_path) are now merged into the checkpoint
   state dict before load_state_dict(..., strict=True).  The load stays
   strict (an unexpected key still raises) and the trained flow weights
   survive.  The stub arches of the tests behave like nn.Module now - a
   no-op recorder had hidden the defect.

2. P5.4's acceptance is no longer unmet: the GPU acceptance run was
   executed (real weights, real ComfyUI modules, RTX 4070 Ti SUPER) and is
   green (5 passed, exit code 0; the run log is in the audit doc section 5).
   KEEP_MODEL_DIR now really decides where the weights come from - it is the
   models root of the run (folder_paths.models_dir), the harness fixture
   no longer isolates the gpu_acceptance tier, and the run needs
   KEEP_NO_COMFY_MOCKS=1 so the real ComfyUI modules are in charge.

3. The "the flow weights are not random" assertion of the acceptance test
   could not distinguish random weights from trained ones.  It now compares
   the flownet tensors with the tensors of their source (the KEEP checkpoint
   or the GMFlow file) bit for bit.

4. The superseded download helper load_file_from_url_comfy is gone
   (src/keep_paths.py only resolves paths; the download lives in
   src/keep_download.py since P5.2).  The stale docstrings, the stale
   comment in the vendored facelib and the two tests that called the dead
   helper are fixed.

5. The risk list mentioned a pending deletion of assets/keep-preview.png
   that does not exist - the asset is committed and present (93279 bytes).
   The rule in the implementation workflow now states the truth.

Checks: the gate (pytest -q -m "unit or mock_integration") is green (234
passed, 1 skipped, 1 xfailed); the opt-in acceptance run is green (5 passed);
the acceptance tier still skips cleanly without its environment variables.
2026-10-24 00:01:48 +03:00
WildAi 31da3b23e5 plan(P5.5): wire the flownet into the arch and close B3 2026-10-23 23:11:57 +03:00
WildAi 3d93cc5625 plan(P5.3): fail fast on the weights that the pack needs 2026-10-23 23:07:17 +03:00
WildAi 93ae504df5 plan(P4): address review findings
Two review findings of the P4 phase, both fixed at their root:

1. (medium) Structure guard (g) did not scan the node layer. Its file set
   came from the import closure of tools/scan_compat.py (the three src/
   entry points) plus src/** - the node layer (nodes/**) and the root
   __init__.py were invisible, although guard (h) of the same phase scans
   them. A torch.cuda.empty_cache() added to the shipped node code passed
   the guard silently.
   tests/test_structure.py: new PACKAGE_OWN_SOURCE_ROOTS (the pack's own
   code without the vendored tree), _package_files() takes the trees to
   walk (the default is unchanged, so guards (d) and (h) are untouched),
   and guard (g) now scans the own code (13 files) plus the vendored
   modules/deps closure (139 files - the vendored part stays
   closure-scoped as the plan and D8 require). Two new self-tests cover
   the node layer and the entry point.
   Proof (old guard vs new guard on the same injected copy):
     OLD guard (HEAD)  -> []
     NEW guard (fixed) -> ['__init__.py: 1 occurrence(s) of
       torch.cuda.empty_cache() (allowlisted: 0)', 'nodes/
       keep_process_image_sequence.py: 1 occurrence(s) of
       torch.cuda.empty_cache() (allowlisted: 0)']

2. (low) The P4.5 "CPU-mode variant" residency test was vacuous: the
   conftest mock already answers torch.device("cpu") for
   get_torch_device(), so the monkeypatch was a no-op and the variant
   exercised the default path.
   tests/test_keep_model_loader.py: the test now runs a GPU leg and a CPU
   leg - both must produce the same residency calls (load_models_gpu,
   unload_all_models, soft_empty_cache, once each) and the patched device
   must really reach the pack.
   Proof (mutation probes against the production code):
     mutation A (the pack hardcodes the cpu device and ignores ComfyUI):
       the old test (from HEAD) passes (10 passed), the new test fails
       (assert device(type='cpu') == device(type='cuda')).
     mutation B (the pack skips load_models_gpu on a cpu device): the new
       test fails (the two legs no longer match).

Docs: the plan's P4 progress row, the guard table of the P4 audit and the
P4 working state are current; the round is recorded in
docs/2026-10-23-p4-review-findings.md.

Verification (run in this round):
  python_embeded/python.exe -m pytest -q -m "unit or mock_integration"
      -> 189 passed, 1 skipped, 5 deselected, 2 xfailed
         (baseline before the round: 187 passed)
  COMFYUI_ROOT=... python_embeded/python.exe -m pytest -q -m headless
      -> 5 passed, 192 deselected
  ruff check . -> All checks passed!
2026-10-23 22:29:47 +03:00
WildAi e31cae3c4e plan(P4.5): arbitrate the model residency through ModelPatcher 2026-10-23 21:23:07 +03:00