Skip to content

SeedVR2 native: drop disk-load prompt embeddings, restore checkpoint buffer access#53

Closed
pollockjj wants to merge 1 commit into
issue_101from
issue_224_seedvr2_drop_disk_load
Closed

SeedVR2 native: drop disk-load prompt embeddings, restore checkpoint buffer access#53
pollockjj wants to merge 1 commit into
issue_101from
issue_224_seedvr2_drop_disk_load

Conversation

@pollockjj
Copy link
Copy Markdown
Owner

Summary

PR #51 (merged into issue_101) introduced _load_seedvr2_prompt_embed[s] and _SEEDVR2_PROMPT_EMBED_CANDIDATES in comfy_extras/nodes_seedvr.py, making SeedVR2Conditioning.execute load pos_emb.pt / neg_emb.pt from one of four search paths via folder_paths.get_full_path:

embeddings:SEEDVR2/{pos,neg}_emb.pt
embeddings:{pos,neg}_emb.pt
custom_nodes:ComfyUI-SeedVR2-Canonical/vendor/SeedVR/{pos,neg}_emb.pt
custom_nodes:ComfyUI-SeedVR2_VideoUpscaler/{pos,neg}_emb.pt

The native SeedVR2 pipeline was silently dependent on third-party custom_nodes being present on disk. Disabling the numz pack made SeedVR2Conditioning raise FileNotFoundError.

This PR removes that dependency by restoring Yusef's upstream pattern: read model.positive_conditioning and model.negative_conditioning directly off the diffusion model.

Why this works

The official seedvr2_3b_fp16vae.safetensors checkpoint bundles both prompt embeddings as model-level buffers:

$ safetensors keys for seedvr2_3b_fp16vae.safetensors
  model.positive_conditioning: shape=(58, 5120) dtype=torch.bfloat16
  model.negative_conditioning: shape=(64, 5120) dtype=torch.bfloat16

comfy/ldm/seedvr/model.py already registers both buffers in the diffusion model via register_buffer. The state-dict load populates them. Yusef's upstream PR (Comfy-Org#11294) reads them directly off model — no filesystem lookup, no custom-node dependency.

Changes

comfy_extras/nodes_seedvr.py

  • Remove import folder_paths.
  • Remove _SEEDVR2_PROMPT_EMBED_CANDIDATES.
  • Remove _load_seedvr2_prompt_embed and _load_seedvr2_prompt_embeds.
  • SeedVR2Conditioning.execute reads pos_cond = model.positive_conditioning and neg_cond = model.negative_conditioning.

The disable_model_cfg1_optimization() call (also added by PR #51) is preserved — that part of PR #51 is correct (the SeedVR2 DiT requires the [neg, pos] chunk concat that Comfy's CFG=1 short-circuit otherwise strips).

tests-unit/comfy_extras_test/test_seedvr_conditioning_hardening.py

  • Drop the four _load_seedvr2_prompt_embed* unit tests (lines 337-528).
  • test_seedvr2_conditioning_disables_cfg1_optimization no longer monkey-patches _load_seedvr2_prompt_embeds — the existing _DiffusionModel test fixture already registers the conditioning buffers via register_buffer, which is exactly the contract SeedVR2Conditioning.execute consumes post-revert.

tests-unit/comfy_extras_test/test_seedvr_input_processing_temporal_overlap.py + test_seedvr_temporal_overlap.py

Net diff

4 files changed, 20 insertions(+), 256 deletions(-)

Verification

  • ruff check clean on all four files.
  • 94 tests passed, 0 failed across the seedvr2 test surface (18 test files exercising comfy/ldm/seedvr/, comfy_extras/nodes_seedvr.py, related VAE wrappers, RoPE delegation, and conditioning hardening).

Test plan

  • Disk-load helpers (_load_seedvr2_prompt_embed, _load_seedvr2_prompt_embeds, _SEEDVR2_PROMPT_EMBED_CANDIDATES, import folder_paths) absent from comfy_extras/nodes_seedvr.py post-merge.
  • SeedVR2Conditioning.execute reads buffers directly from the resolved diffusion model.
  • test_seedvr2_conditioning_disables_cfg1_optimization passes without the _load_seedvr2_prompt_embeds monkeypatch.
  • Native SeedVR2 inference does not require any custom_node pack on disk.

Linked

…buffer access

PR #51 introduced _load_seedvr2_prompt_embed[s] + _SEEDVR2_PROMPT_EMBED_CANDIDATES which made comfy_extras/nodes_seedvr.py:SeedVR2Conditioning load pos_emb.pt / neg_emb.pt from one of four search paths inside the numz and canonical custom_node directories. That made the native SeedVR2 pipeline silently dependent on third-party custom_nodes being present on disk.

Yusef's upstream PR (Comfy-Org#11294) reads model.positive_conditioning and model.negative_conditioning as buffers. The official seedvr2_3b_fp16vae.safetensors checkpoint ships both buffers (positive 58x5120 bf16, negative 64x5120 bf16). Direct buffer access removes the filesystem dependency.

Changes:

  comfy_extras/nodes_seedvr.py

    - Remove import folder_paths.

    - Remove _SEEDVR2_PROMPT_EMBED_CANDIDATES table.

    - Remove _load_seedvr2_prompt_embed and _load_seedvr2_prompt_embeds.

    - SeedVR2Conditioning.execute reads pos_cond and neg_cond off model directly.

  tests-unit/comfy_extras_test/test_seedvr_conditioning_hardening.py

    - Drop the four _load_seedvr2_prompt_embed* unit tests (lines 337-528).

    - test_seedvr2_conditioning_disables_cfg1_optimization no longer monkeypatches _load_seedvr2_prompt_embeds (the test fixture _DiffusionModel already registers buffers via register_buffer).

  tests-unit/comfy_extras_test/test_seedvr_input_processing_temporal_overlap.py

  tests-unit/comfy_extras_test/test_seedvr_temporal_overlap.py

    - Add parameters() to _FakeFirstStage to satisfy tiled_vae's next(vae_model.parameters()).dtype call.

    - Patch nodes_seedvr.tiled_vae to capture encode kwargs (the dispatch site moved off vae.encode_tiled in PR #51).

Verification: 94 passed, 0 failed across the seedvr2 test surface; ruff clean.

Tracking: pollockjj/mydevelopment#224
Copilot AI review requested due to automatic review settings May 8, 2026 05:04
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Removes SeedVR2’s on-disk prompt-embedding lookup from SeedVR2Conditioning and restores the native behavior of reading positive/negative conditioning directly from buffers registered on the diffusion model, eliminating an implicit dependency on third-party custom_nodes packs.

Changes:

  • Drop folder_paths-based prompt-embedding search and disk loading helpers in comfy_extras/nodes_seedvr.py.
  • Update SeedVR2Conditioning.execute to use model.positive_conditioning / model.negative_conditioning buffers.
  • Adjust SeedVR2 temporal-overlap tests to reflect the tiled_vae(..., encode=True) encode dispatch and add minimal stubs needed by the refactor.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
comfy_extras/nodes_seedvr.py Removes filesystem dependency for prompt embeddings; uses model buffers for SeedVR2 conditioning.
tests-unit/comfy_extras_test/test_seedvr_conditioning_hardening.py Removes tests for deleted disk-load helpers; keeps CFG=1 optimization-disable test aligned with buffer-based conditioning.
tests-unit/comfy_extras_test/test_seedvr_temporal_overlap.py Updates mocks to intercept tiled_vae encode dispatch; adds parameters() stub for VAE wrapper behavior.
tests-unit/comfy_extras_test/test_seedvr_input_processing_temporal_overlap.py Same as above for the parallel temporal-overlap wiring test.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 314 to +318
model_patcher = model
model = _resolve_seedvr2_diffusion_model(model_patcher)
model_patcher.disable_model_cfg1_optimization()
pos_cond, neg_cond = _load_seedvr2_prompt_embeds(device, model.positive_conditioning.dtype)
pos_cond = model.positive_conditioning
neg_cond = model.negative_conditioning
assert captured["encode_tiled"]["tile_t"] == 16
assert captured["encode_tiled"]["overlap_t"] == 4
assert captured["tiled_vae"]["temporal_size"] == 16
assert captured["tiled_vae"]["encode"] is True
assert captured["encode_tiled"]["tile_t"] == 16
assert captured["encode_tiled"]["overlap_t"] == 4
assert captured["tiled_vae"]["temporal_size"] == 16
assert captured["tiled_vae"]["encode"] is True
@pollockjj
Copy link
Copy Markdown
Owner Author

Closing per direction: PR scope creep. Will resubmit with only the disk-load reversion (nodes_seedvr.py + test_seedvr_conditioning_hardening.py deletions). The temporal_overlap test edits in this PR don't belong in a reversion.

@pollockjj pollockjj closed this May 8, 2026
@pollockjj pollockjj deleted the issue_224_seedvr2_drop_disk_load branch May 8, 2026 05:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants