Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/node_replace_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ def apply_replacements(self, prompt: dict[str, NodeStruct]):
connections: dict[str, list[tuple[str, str, int]]] = {}
need_replacement: set[str] = set()
for node_number, node_struct in prompt.items():
if "class_type" not in node_struct or "inputs" not in node_struct:
continue
class_type = node_struct["class_type"]
# need replacement if not in NODE_CLASS_MAPPINGS and has replacement
if class_type not in nodes.NODE_CLASS_MAPPINGS.keys() and self.has_replacement(class_type):
Expand Down
4 changes: 4 additions & 0 deletions comfy/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,10 @@ def state_dict(self, *args, destination=None, prefix="", **kwargs):
else:
sd = {}

if not hasattr(self, 'weight'):
logging.warning("Warning: state dict on uninitialized op {}".format(prefix))
return sd

if self.bias is not None:
sd["{}bias".format(prefix)] = self.bias

Expand Down
2 changes: 2 additions & 0 deletions comfy_api_nodes/apis/bytedance.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Seedream4TaskCreationRequest(BaseModel):
sequential_image_generation: str = Field("disabled")
sequential_image_generation_options: Seedream4Options = Field(Seedream4Options(max_images=15))
watermark: bool = Field(False)
output_format: str | None = None


class ImageTaskCreationResponse(BaseModel):
Expand Down Expand Up @@ -106,6 +107,7 @@ class TaskStatusResponse(BaseModel):
("2496x1664 (3:2)", 2496, 1664),
("1664x2496 (2:3)", 1664, 2496),
("3024x1296 (21:9)", 3024, 1296),
("3072x3072 (1:1)", 3072, 3072),
("4096x4096 (1:1)", 4096, 4096),
("Custom", None, None),
]
Expand Down
48 changes: 31 additions & 17 deletions comfy_api_nodes/nodes_bytedance.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@

BYTEPLUS_IMAGE_ENDPOINT = "/proxy/byteplus/api/v3/images/generations"

SEEDREAM_MODELS = {
"seedream 5.0 lite": "seedream-5-0-260128",
"seedream-4-5-251128": "seedream-4-5-251128",
"seedream-4-0-250828": "seedream-4-0-250828",
}

# Long-running tasks endpoints(e.g., video)
BYTEPLUS_TASK_ENDPOINT = "/proxy/byteplus/api/v3/contents/generations/tasks"
BYTEPLUS_TASK_STATUS_ENDPOINT = "/proxy/byteplus/api/v3/contents/generations/tasks" # + /{task_id}
Expand Down Expand Up @@ -180,14 +186,13 @@ class ByteDanceSeedreamNode(IO.ComfyNode):
def define_schema(cls):
return IO.Schema(
node_id="ByteDanceSeedreamNode",
display_name="ByteDance Seedream 4.5",
display_name="ByteDance Seedream 5.0",
category="api node/image/ByteDance",
description="Unified text-to-image generation and precise single-sentence editing at up to 4K resolution.",
inputs=[
IO.Combo.Input(
"model",
options=["seedream-4-5-251128", "seedream-4-0-250828"],
tooltip="Model name",
options=list(SEEDREAM_MODELS.keys()),
),
IO.String.Input(
"prompt",
Expand All @@ -198,7 +203,7 @@ def define_schema(cls):
IO.Image.Input(
"image",
tooltip="Input image(s) for image-to-image generation. "
"List of 1-10 images for single or multi-reference generation.",
"Reference image(s) for single or multi-reference generation.",
optional=True,
),
IO.Combo.Input(
Expand All @@ -210,17 +215,17 @@ def define_schema(cls):
"width",
default=2048,
min=1024,
max=4096,
step=8,
max=6240,
step=2,
tooltip="Custom width for image. Value is working only if `size_preset` is set to `Custom`",
optional=True,
),
IO.Int.Input(
"height",
default=2048,
min=1024,
max=4096,
step=8,
max=4992,
step=2,
tooltip="Custom height for image. Value is working only if `size_preset` is set to `Custom`",
optional=True,
),
Expand Down Expand Up @@ -283,7 +288,8 @@ def define_schema(cls):
depends_on=IO.PriceBadgeDepends(widgets=["model"]),
expr="""
(
$price := $contains(widgets.model, "seedream-4-5-251128") ? 0.04 : 0.03;
$price := $contains(widgets.model, "5.0 lite") ? 0.035 :
$contains(widgets.model, "4-5") ? 0.04 : 0.03;
{
"type":"usd",
"usd": $price,
Expand All @@ -309,6 +315,7 @@ async def execute(
watermark: bool = False,
fail_on_partial: bool = True,
) -> IO.NodeOutput:
model = SEEDREAM_MODELS[model]
validate_string(prompt, strip_whitespace=True, min_length=1)
w = h = None
for label, tw, th in RECOMMENDED_PRESETS_SEEDREAM_4:
Expand All @@ -318,25 +325,31 @@ async def execute(

if w is None or h is None:
w, h = width, height
if not (1024 <= w <= 4096) or not (1024 <= h <= 4096):
raise ValueError(
f"Custom size out of range: {w}x{h}. " "Both width and height must be between 1024 and 4096 pixels."
)

out_num_pixels = w * h
mp_provided = out_num_pixels / 1_000_000.0
if "seedream-4-5" in model and out_num_pixels < 3686400:
if ("seedream-4-5" in model or "seedream-5-0" in model) and out_num_pixels < 3686400:
raise ValueError(
f"Minimum image resolution that Seedream 4.5 can generate is 3.68MP, "
f"Minimum image resolution for the selected model is 3.68MP, "
f"but {mp_provided:.2f}MP provided."
)
if "seedream-4-0" in model and out_num_pixels < 921600:
raise ValueError(
f"Minimum image resolution that the selected model can generate is 0.92MP, "
f"but {mp_provided:.2f}MP provided."
)
max_pixels = 10_404_496 if "seedream-5-0" in model else 16_777_216
if out_num_pixels > max_pixels:
raise ValueError(
f"Maximum image resolution for the selected model is {max_pixels / 1_000_000:.2f}MP, "
f"but {mp_provided:.2f}MP provided."
)
n_input_images = get_number_of_images(image) if image is not None else 0
if n_input_images > 10:
raise ValueError(f"Maximum of 10 reference images are supported, but {n_input_images} received.")
max_num_of_images = 14 if model == "seedream-5-0-260128" else 10
if n_input_images > max_num_of_images:
raise ValueError(
f"Maximum of {max_num_of_images} reference images are supported, but {n_input_images} received."
)
if sequential_image_generation == "auto" and n_input_images + max_images > 15:
raise ValueError(
"The maximum number of generated images plus the number of reference images cannot exceed 15."
Expand Down Expand Up @@ -364,6 +377,7 @@ async def execute(
sequential_image_generation=sequential_image_generation,
sequential_image_generation_options=Seedream4Options(max_images=max_images),
watermark=watermark,
output_format="png" if model == "seedream-5-0-260128" else None,
),
)
if len(response.data) == 1:
Expand Down
2 changes: 1 addition & 1 deletion comfyui_version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# This file is automatically generated by the build process when version is
# updated in pyproject.toml.
__version__ = "0.14.1"
__version__ = "0.15.0"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "ComfyUI"
version = "0.14.1"
version = "0.15.0"
readme = "README.md"
license = { file = "LICENSE" }
requires-python = ">=3.10"
Expand Down
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
comfyui-frontend-package==1.39.16
comfyui-workflow-templates==0.9.2
comfyui-embedded-docs==0.4.1
comfyui-workflow-templates==0.9.3
comfyui-embedded-docs==0.4.3
torch
torchsde
torchvision
Expand All @@ -22,7 +22,7 @@ alembic
SQLAlchemy
av>=14.2.0
comfy-kitchen>=0.2.7
comfy-aimdo>=0.2.0
comfy-aimdo>=0.2.1
requests

#non essential dependencies:
Expand Down
Loading