mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-05-07 07:42:32 +08:00
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
Python Linting / Run Pylint (push) Waiting to run
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.10, [self-hosted Linux], stable) (push) Waiting to run
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.11, [self-hosted Linux], stable) (push) Waiting to run
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.12, [self-hosted Linux], stable) (push) Waiting to run
Full Comfy CI Workflow Runs / test-unix-nightly (12.1, , linux, 3.11, [self-hosted Linux], nightly) (push) Waiting to run
Execution Tests / test (macos-latest) (push) Waiting to run
Execution Tests / test (ubuntu-latest) (push) Waiting to run
Execution Tests / test (windows-latest) (push) Waiting to run
Test server launches without errors / test (push) Waiting to run
Unit Tests / test (macos-latest) (push) Waiting to run
Unit Tests / test (ubuntu-latest) (push) Waiting to run
Unit Tests / test (windows-2022) (push) Waiting to run
85 lines
2.7 KiB
Python
85 lines
2.7 KiB
Python
"""
|
|
ComfyUI nodes for autoregressive video generation (Causal Forcing, Self-Forcing, etc.).
|
|
- EmptyARVideoLatent: create 5D [B, C, T, H, W] video latent tensors
|
|
- SamplerARVideo: SAMPLER for the block-by-block autoregressive denoising loop
|
|
"""
|
|
|
|
import torch
|
|
from typing_extensions import override
|
|
|
|
import comfy.model_management
|
|
import comfy.samplers
|
|
from comfy_api.latest import ComfyExtension, io
|
|
|
|
|
|
class EmptyARVideoLatent(io.ComfyNode):
|
|
@classmethod
|
|
def define_schema(cls):
|
|
return io.Schema(
|
|
node_id="EmptyARVideoLatent",
|
|
category="latent/video",
|
|
inputs=[
|
|
io.Int.Input("width", default=832, min=16, max=8192, step=16),
|
|
io.Int.Input("height", default=480, min=16, max=8192, step=16),
|
|
io.Int.Input("length", default=81, min=1, max=1024, step=4),
|
|
io.Int.Input("batch_size", default=1, min=1, max=64),
|
|
],
|
|
outputs=[
|
|
io.Latent.Output(display_name="LATENT"),
|
|
],
|
|
)
|
|
|
|
@classmethod
|
|
def execute(cls, width, height, length, batch_size) -> io.NodeOutput:
|
|
lat_t = ((length - 1) // 4) + 1
|
|
latent = torch.zeros(
|
|
[batch_size, 16, lat_t, height // 8, width // 8],
|
|
device=comfy.model_management.intermediate_device(),
|
|
)
|
|
return io.NodeOutput({"samples": latent})
|
|
|
|
|
|
class SamplerARVideo(io.ComfyNode):
|
|
"""Sampler for autoregressive video models (Causal Forcing, Self-Forcing).
|
|
|
|
All AR-loop parameters are owned by this node so they live in the workflow.
|
|
Add new widgets here as the AR sampler grows new options.
|
|
"""
|
|
|
|
@classmethod
|
|
def define_schema(cls):
|
|
return io.Schema(
|
|
node_id="SamplerARVideo",
|
|
display_name="Sampler AR Video",
|
|
category="sampling/custom_sampling/samplers",
|
|
inputs=[
|
|
io.Int.Input(
|
|
"num_frame_per_block",
|
|
default=1, min=1, max=64,
|
|
tooltip="Frames per autoregressive block. 1 = framewise, "
|
|
"3 = chunkwise. Must match the checkpoint's training mode.",
|
|
),
|
|
],
|
|
outputs=[io.Sampler.Output()],
|
|
)
|
|
|
|
@classmethod
|
|
def execute(cls, num_frame_per_block) -> io.NodeOutput:
|
|
extra_options = {
|
|
"num_frame_per_block": num_frame_per_block,
|
|
}
|
|
return io.NodeOutput(comfy.samplers.ksampler("ar_video", extra_options))
|
|
|
|
|
|
class ARVideoExtension(ComfyExtension):
|
|
@override
|
|
async def get_node_list(self) -> list[type[io.ComfyNode]]:
|
|
return [
|
|
EmptyARVideoLatent,
|
|
SamplerARVideo,
|
|
]
|
|
|
|
|
|
async def comfy_entrypoint() -> ARVideoExtension:
|
|
return ARVideoExtension()
|