From b44a6156253857c62447580c4c502f0adbdee5bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zeyu=20Huang=20=7C=20=E9=BB=83=E6=BE=A4=E5=AE=87?=
<11222265+fhfuih@users.noreply.github.com>
Date: Thu, 26 Feb 2026 21:03:54 +0800
Subject: [PATCH] [Doc][Test][Misc] ComfyUI test, more screenshot, and code
cleaning (#1435)
Signed-off-by: Huang, Zeyu <11222265+fhfuih@users.noreply.github.com>
Signed-off-by: Samit <285365963@qq.com>
Co-authored-by: Samit <285365963@qq.com>
---
.github/workflows/comfyui-publish.yml | 27 -
.github/workflows/comfyui-validate.yml | 40 -
apps/ComfyUI-vLLM-Omni/README.md | 41 +-
apps/ComfyUI-vLLM-Omni/__init__.py | 10 +-
.../comfyui_vllm_omni/nodes.py | 47 +-
.../comfyui_vllm_omni/utils/api_client.py | 46 +-
.../comfyui_vllm_omni/utils/models.py | 9 +-
.../comfyui_vllm_omni/utils/types.py | 14 +-
.../comfyui_vllm_omni/utils/validators.py | 31 +-
.../docs/images/comfyui-chaining-services.jpg | Bin 0 -> 265984 bytes
...ehension.jpg => comfyui-understanding.jpg} | Bin
.../vLLM-Omni Annotated Example.json | 1 -
.../vLLM-Omni Chaining Services.json | 552 +++++++++++++
.../vLLM-Omni Image Generation.json | 2 +-
.../vLLM-Omni Multimodal Understanding.json | 761 ++++++++++++++++++
pyproject.toml | 3 +-
tests/comfyui/conftest.py | 82 ++
tests/comfyui/test_comfyui_integration.py | 567 +++++++++++++
18 files changed, 2067 insertions(+), 166 deletions(-)
delete mode 100644 .github/workflows/comfyui-publish.yml
delete mode 100644 .github/workflows/comfyui-validate.yml
create mode 100644 apps/ComfyUI-vLLM-Omni/docs/images/comfyui-chaining-services.jpg
rename apps/ComfyUI-vLLM-Omni/docs/images/{comfyui-comprehension.jpg => comfyui-understanding.jpg} (100%)
delete mode 100644 apps/ComfyUI-vLLM-Omni/example_workflows/vLLM-Omni Annotated Example.json
create mode 100644 apps/ComfyUI-vLLM-Omni/example_workflows/vLLM-Omni Chaining Services.json
create mode 100644 apps/ComfyUI-vLLM-Omni/example_workflows/vLLM-Omni Multimodal Understanding.json
create mode 100644 tests/comfyui/conftest.py
create mode 100644 tests/comfyui/test_comfyui_integration.py
diff --git a/.github/workflows/comfyui-publish.yml b/.github/workflows/comfyui-publish.yml
deleted file mode 100644
index c282bcada..000000000
--- a/.github/workflows/comfyui-publish.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-name: ComfyUI Integration -- Publish to Comfy registry
-on:
- workflow_dispatch:
- push:
- tags:
- - "*"
- paths:
- - "apps/ComfyUI-vLLM-Omni/**"
-
-permissions:
- issues: write
-
-defaults:
- run:
- working-directory: apps/ComfyUI-vLLM-Omni
-
-jobs:
- publish-node:
- name: Publish Custom Node to registry
- runs-on: ubuntu-latest
- steps:
- - name: ♻️ Check out code
- uses: actions/checkout@v4
- - name: 📦 Publish Custom Node
- uses: Comfy-Org/publish-node-action@main
- with:
- personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
diff --git a/.github/workflows/comfyui-validate.yml b/.github/workflows/comfyui-validate.yml
deleted file mode 100644
index 06b9b1f91..000000000
--- a/.github/workflows/comfyui-validate.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: ComfyUI Integration -- Validate backwards compatibility
-
-on:
- pull_request:
- branches:
- - master
- - main
- paths:
- - "apps/ComfyUI-vLLM-Omni/**"
-
-defaults:
- run:
- working-directory: apps/ComfyUI-vLLM-Omni
-
-jobs:
- check-base-path:
- runs-on: ubuntu-latest
- outputs:
- exists: ${{ steps.check.outputs.exists }}
- defaults:
- run:
- working-directory: .
- steps:
- - uses: actions/checkout@v4
- with:
- ref: ${{ github.event.pull_request.base.sha }}
- fetch-depth: 1
- - id: check
- run: |
- if [ -d "apps/ComfyUI-vLLM-Omni" ]; then
- echo "exists=true" >> "$GITHUB_OUTPUT"
- else
- echo "exists=false" >> "$GITHUB_OUTPUT"
- fi
- validate:
- needs: check-base-path
- if: needs.check-base-path.outputs.exists == 'true'
- runs-on: ubuntu-latest
- steps:
- - uses: comfy-org/node-diff@main
diff --git a/apps/ComfyUI-vLLM-Omni/README.md b/apps/ComfyUI-vLLM-Omni/README.md
index dd530174f..23bbe5b72 100644
--- a/apps/ComfyUI-vLLM-Omni/README.md
+++ b/apps/ComfyUI-vLLM-Omni/README.md
@@ -47,12 +47,12 @@ If no, check your shell running the ComfyUI process. There may be some error mes
This extension offers the following nodes based on the output modalities (at **ComfyUI sidebar -> Node Library**):
- **Generate Image** for text-to-image and image-to-image tasks
-- **Multimodality Comprehension** for multimodality-to-text and multimodality-to-audio tasks
+- **Multimodality Understanding** for multimodality-to-text and multimodality-to-audio tasks
- **TTS** and **TTS Voice Clone** for TTS tasks
This extension also offers example workflows (at **ComfyUI sidebar -> Templates -> vLLM-Omni**)
-> [!INFO]
+> [!NOTE]
> The node UI and feature designs are intended to match vLLM-Omni online serving interfaces. It cannot offer more than what the interfaces support.
To build a simple workflow yourself,
@@ -65,28 +65,16 @@ To build a simple workflow yourself,
- For some multi-stage models like BAGEL, [only one stage's sampling parameters are exposed and tunable via vLLM-Omni's online serving API](https://docs.vllm.ai/projects/vllm-omni/en/latest/user_guide/examples/online_serving/bagel/). Thus, these models are treated as single-stage ones. Please check the vLLM-Omni documentation on how to correctly set each model's sampling parameters.
- For multi-stage models where all stages are either autoregression or diffusion, you can also connect only a single Sampling Params node, indicating that this set of sampling parameters will be used for all stages.
-**The following features are tested**:
-
-- Single-node workflows for
- - Multimodal Comprehension (e.g., Qwen Omni, BAGEL)
- - Text-to-Image Generation (e.g., Qwen-Image)
- - Image-to-Image Generation (e.g., Qwen-Image-Edit)
- - TTS (e.g., Qwen TTS, including VoiceDesign, VoiceClone, CustomVoice)
-
-**The following features are not currently tested**. They may work or break. You are welcomed to test it out and offer comments.
-
-- Multi-node workflow that connects multiple model services together.
-
## Screenshots and Examples
-### Multimodal comprehension (e.g., Qwen Omni series, BAGEL)
+### Multimodal understanding (e.g., Qwen Omni series, BAGEL)
-(Also available at **ComfyUI sidebar->Template->vLLM-Omni->vLLM-Omni Annotated Example**)
+(Also available at **ComfyUI sidebar->Template->vLLM-Omni->vLLM-Omni Multimodal Understanding**)
-
-
+
+
@@ -98,7 +86,7 @@ You can configure per-stage sampling parameters for multi-stage models.
-
+
@@ -109,7 +97,7 @@ You can configure per-stage sampling parameters for multi-stage models.
-
+
@@ -123,13 +111,24 @@ You can configure per-stage sampling parameters for multi-stage models.
-
+
> [!TIP]
> There is a dedicated node for VoiceClone tasks with reference audio input. Other simple text-to-speech tasks should use the regular TTS node.
+### Chaining multiple model services
+
+(Also available at **ComfyUI sidebar->Template->vLLM-Omni->vLLM-Omni Chaining Services**)
+
+
+
+
+
+
+
+
## Develop
Follow the [development convention and rules of vLLM-Omni](https://docs.vllm.ai/projects/vllm-omni/en/latest/contributing/).
diff --git a/apps/ComfyUI-vLLM-Omni/__init__.py b/apps/ComfyUI-vLLM-Omni/__init__.py
index ffb86ddb3..641824add 100644
--- a/apps/ComfyUI-vLLM-Omni/__init__.py
+++ b/apps/ComfyUI-vLLM-Omni/__init__.py
@@ -6,18 +6,18 @@ __all__ = [
"WEB_DIRECTORY",
]
-__author__ = """Zeyu Huang"""
-__email__ = "11222265+fhfuih@users.noreply.github.com"
+__author__ = """vLLM-Omni Team"""
+__email__ = "vllm-omni@vllm.ai"
__version__ = "0.0.1"
from .comfyui_vllm_omni.nodes import (
VLLMOmniARSampling,
- VLLMOmniComprehension,
VLLMOmniDiffusionSampling,
VLLMOmniGenerateImage,
VLLMOmniQwenTTSParams,
VLLMOmniSamplingParamsList,
VLLMOmniTTS,
+ VLLMOmniUnderstanding,
VLLMOmniVoiceClone,
)
@@ -25,7 +25,7 @@ from .comfyui_vllm_omni.nodes import (
NODE_CLASS_MAPPINGS = {
# === Generation ===
"VLLMOmniGenerateImage": VLLMOmniGenerateImage,
- "VLLMOmniComprehension": VLLMOmniComprehension,
+ "VLLMOmniUnderstanding": VLLMOmniUnderstanding,
"VLLMOmniTTS": VLLMOmniTTS,
"VLLMOmniVoiceClone": VLLMOmniVoiceClone,
# === Params ===
@@ -39,7 +39,7 @@ NODE_CLASS_MAPPINGS = {
NODE_DISPLAY_NAME_MAPPINGS = {
# === Generation ===
"VLLMOmniGenerateImage": "Generate Image",
- "VLLMOmniComprehension": "Multimodality Comprehension",
+ "VLLMOmniUnderstanding": "Multimodality Understanding",
"VLLMOmniTTS": "TTS (Text to Speech)",
"VLLMOmniVoiceClone": "TTS Voice Cloning",
# === Params ===
diff --git a/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/nodes.py b/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/nodes.py
index ebc2822df..5caa3869e 100644
--- a/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/nodes.py
+++ b/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/nodes.py
@@ -1,4 +1,4 @@
-from typing import Literal, cast
+from typing import Literal
import torch
from comfy_api.input import AudioInput, VideoInput
@@ -6,7 +6,12 @@ from comfy_api.input import AudioInput, VideoInput
from .utils.api_client import VLLMOmniClient
from .utils.logger import get_logger
from .utils.models import lookup_model_spec
-from .utils.types import AudioFormat
+from .utils.types import (
+ AudioFormat,
+ AutoregressionSamplingParams,
+ DiffusionSamplingParams,
+ QwenTTSModelSpecificParams,
+)
from .utils.validators import (
add_sampling_parameters_to_stage,
validate_model_and_sampling_params_types,
@@ -86,7 +91,10 @@ class VLLMOmniGenerateImage(_VLLMOmniGenerateBase):
# Prefer DALL-E compatible API for simple (one-stage) diffusion models
if (spec is None or spec["stages"] == ["diffusion"]) and not is_bagel:
- sampling_params = cast(dict | None, sampling_params)
+ # The number of sampling parameter groups should have been validated.
+ # Now, simply convert single-item list to dict.
+ if isinstance(sampling_params, list):
+ sampling_params = sampling_params[0]
if audio is None and image is None and video is None:
# No multimodal input --- use DALL-E image generation
logger.info("Using DALL-E image generation endpoint")
@@ -133,7 +141,7 @@ class VLLMOmniGenerateImage(_VLLMOmniGenerateBase):
return (output,)
-class VLLMOmniComprehension(_VLLMOmniGenerateBase):
+class VLLMOmniUnderstanding(_VLLMOmniGenerateBase):
@classmethod
def INPUT_TYPES(cls):
return {
@@ -197,7 +205,7 @@ class VLLMOmniComprehension(_VLLMOmniGenerateBase):
(
text_response,
_,
- ) = await client.generate_comprehension_chat_completion(
+ ) = await client.generate_understanding_chat_completion(
model=model,
prompt=prompt,
image=image,
@@ -221,7 +229,7 @@ class VLLMOmniComprehension(_VLLMOmniGenerateBase):
(
text_response,
audio,
- ) = await client.generate_comprehension_chat_completion(
+ ) = await client.generate_understanding_chat_completion(
model=model,
prompt=prompt,
image=image,
@@ -287,15 +295,13 @@ class VLLMOmniTTS(_VLLMOmniGenerateBase):
logger.info("Got extra kwargs in TTS: %s", kwargs)
is_qwen_tts = "qwen3-tts" in model.lower()
- extra_params_type = None if model_specific_params is None else model_specific_params["type"]
- if not is_qwen_tts and extra_params_type == "qwen-tts":
+ if not is_qwen_tts and isinstance(model_specific_params, QwenTTSModelSpecificParams):
raise ValueError(
"You have provided Qwen-specific TTS params."
"However, the model appears to not be a Qwen TTS model (no 'Qwen3-TTS' in model name)."
)
combined_params = {**kwargs, **(model_specific_params or {})}
- combined_params.pop("type", None) # Internal fields in model_specific_params
client = VLLMOmniClient(url)
@@ -352,8 +358,7 @@ class VLLMOmniVoiceClone(_VLLMOmniGenerateBase):
**kwargs,
):
is_qwen_tts = "qwen3-tts" in model.lower()
- extra_params_type = None if model_specific_params is None else model_specific_params["type"]
- if not is_qwen_tts and extra_params_type == "qwen-tts":
+ if not is_qwen_tts and isinstance(model_specific_params, QwenTTSModelSpecificParams):
raise ValueError(
"You have provided Qwen-specific TTS params."
"However, the model appears to not be a Qwen TTS model (no 'Qwen3-TTS' in model name)."
@@ -366,7 +371,6 @@ class VLLMOmniVoiceClone(_VLLMOmniGenerateBase):
**kwargs,
**(model_specific_params or {}),
}
- combined_params.pop("type", None) # Internal fields in model_specific_params
client = VLLMOmniClient(url)
@@ -419,10 +423,7 @@ class VLLMOmniARSampling:
CATEGORY = "vLLM-Omni/Sampling Params"
def get_params(self, seed, **kwargs):
- params = {
- "type": "autoregression", # for internal use, removed before sending the request
- **kwargs,
- }
+ params = AutoregressionSamplingParams(kwargs)
if seed >= 0:
params["seed"] = seed
return (params,)
@@ -479,6 +480,13 @@ class VLLMOmniDiffusionSampling:
"tooltip": "Enable VAE slicing for reduced memory usage (slight quality trade-off)",
},
),
+ "vae_use_tiling": (
+ "BOOLEAN",
+ {
+ "default": False,
+ "tooltip": "Enable VAE tiling for reduced memory usage (slight quality trade-off)",
+ },
+ ),
# === Put seed at last. ===
# Whenever a field named "seed" is present, ComfyUI adds another field called "control after generate"
"seed": (
@@ -499,10 +507,7 @@ class VLLMOmniDiffusionSampling:
CATEGORY = "vLLM-Omni/Sampling Params"
def get_params(self, seed, **kwargs):
- params = {
- "type": "diffusion", # for internal use, removed before sending the request
- **kwargs,
- }
+ params = DiffusionSamplingParams(kwargs)
if seed >= 0:
params["seed"] = seed
return (params,)
@@ -566,4 +571,4 @@ class VLLMOmniQwenTTSParams:
CATEGORY = "vLLM-Omni/TTS Params"
def get_params(self, **kwargs):
- return ({"type": "qwen-tts", **kwargs},)
+ return (QwenTTSModelSpecificParams(kwargs),)
diff --git a/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/api_client.py b/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/api_client.py
index c5372641f..d340073bc 100644
--- a/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/api_client.py
+++ b/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/api_client.py
@@ -57,16 +57,7 @@ class VLLMOmniClient:
if negative_prompt:
payload["negative_prompt"] = negative_prompt
if sampling_params is not None:
- # Only select specific sampling params
- for k in (
- "n",
- "num_inference_steps",
- "guidance_scale",
- "true_cfg_scale",
- "vae_use_slicing",
- ):
- if k in sampling_params and sampling_params[k] is not None:
- payload[k] = sampling_params[k]
+ payload.update(sampling_params)
logger.debug("img gen payload: %s", payload)
url = self.base_url + "/images/generations"
@@ -138,10 +129,8 @@ class VLLMOmniClient:
if negative_prompt:
form.add_field("negative_prompt", negative_prompt)
if sampling_params is not None:
- # Only select specific sampling params
- for k in ("n", "num_inference_steps", "guidance_scale", "true_cfg_scale"):
- if k in sampling_params and sampling_params[k] is not None:
- form.add_field(k, str(sampling_params[k]))
+ for k, v in sampling_params.items():
+ form.add_field(k, str(v))
if mask is not None:
mask_filename = "mask.png"
form.add_field(
@@ -217,7 +206,7 @@ class VLLMOmniClient:
return torch.stack(image_tensors, dim=0)
- async def generate_comprehension_chat_completion(
+ async def generate_understanding_chat_completion(
self,
*,
model: str,
@@ -427,30 +416,28 @@ class VLLMOmniClient:
message_content.append({"type": "video_url", "video_url": {"url": video_to_base64(video)}})
messages = [{"role": "user", "content": message_content}]
+ payload: dict[str, Any] = {"messages": messages, "model": model}
+ if modalities:
+ payload["modalities"] = modalities
+
combined_extra_body: dict[str, Any] = {}
if sampling_params is not None:
spec, _ = lookup_model_spec(model)
is_single_sampling_param = isinstance(sampling_params, dict) or len(sampling_params) == 1
- # Exclude internal key
- if isinstance(sampling_params, dict):
- sampling_params = {k: v for k, v in sampling_params.items() if k != "type"}
- else:
- sampling_params = [{k: v for k, v in sp.items() if k != "type"} for sp in sampling_params]
-
if (spec is None and is_single_sampling_param) or (spec is not None and spec["stages"] == ["diffusion"]):
# Diffusion format: extra_body directly contains sampling params.
- # Validation should have taken care of matching sampling params' types.
+ # Validation has already taken care of matching sampling params' types and length. Safe to take [0].
# * Use this mode if the model is a simple one-stage diffusion model.
# * Fallback to this mode if model is not registered and a single sampling param is provided.
sampling_params = sampling_params if isinstance(sampling_params, dict) else sampling_params[0]
- combined_extra_body: dict[str, Any] = {**sampling_params}
+ combined_extra_body: dict[str, Any] = sampling_params.copy()
if "n" in combined_extra_body:
- combined_extra_body["num_outputs_per_prompt"] = combined_extra_body["n"]
- del combined_extra_body["n"]
+ combined_extra_body["num_outputs_per_prompt"] = combined_extra_body.pop("n")
else:
- # Use AR style payload, extra_body has a sampling_params_list field
- combined_extra_body: dict[str, Any] = {"sampling_params_list": sampling_params}
+ # AR format: the payload has a sampling_params_list field, containing a list.
+ sampling_params_list = sampling_params if isinstance(sampling_params, list) else [sampling_params]
+ payload["sampling_params_list"] = sampling_params_list
if negative_prompt:
combined_extra_body["negative_prompt"] = negative_prompt
@@ -458,12 +445,11 @@ class VLLMOmniClient:
if extra_body:
combined_extra_body.update(extra_body)
- payload: dict[str, Any] = {"messages": messages, "model": model}
+ # Add extra_body only if it has any content.
if combined_extra_body:
payload["extra_body"] = combined_extra_body
- if modalities:
- payload["modalities"] = modalities
+ # Place to inject any model-specific payload adjustment
spec, _ = lookup_model_spec(model)
if spec:
preprocessor = spec.get("payload_preprocessor", None)
diff --git a/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/models.py b/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/models.py
index 83bf64fe7..bfeddd82b 100644
--- a/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/models.py
+++ b/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/models.py
@@ -11,8 +11,7 @@ def _bagel_payload_preprocessor(payload: dict) -> dict:
content["text"] = "<|im_start|>" + content["text"] + "<|im_end|>"
except (KeyError, TypeError):
raise RuntimeError("Internal Error: malformatted BAGEL payload")
- extra_body = payload.pop("extra_body", {})
- return {**payload, **extra_body}
+ return payload
def _qwen25_payload_preprocessor(payload: dict) -> dict:
@@ -37,7 +36,7 @@ _MODEL_PIPELINE_SPECS: dict[str, Spec] = {
],
"modes": [
{
- "mode": ModelMode.COMPREHENSION,
+ "mode": ModelMode.UNDERSTANDING,
"input_modalities": [Modality.TEXT, Modality.IMAGE],
}
],
@@ -48,7 +47,7 @@ _MODEL_PIPELINE_SPECS: dict[str, Spec] = {
"payload_preprocessor": _qwen25_payload_preprocessor,
"modes": [
{
- "mode": ModelMode.COMPREHENSION,
+ "mode": ModelMode.UNDERSTANDING,
"input_modalities": [
Modality.TEXT,
Modality.IMAGE,
@@ -62,7 +61,7 @@ _MODEL_PIPELINE_SPECS: dict[str, Spec] = {
"stages": ["autoregression", "autoregression", "autoregression"],
"modes": [
{
- "mode": ModelMode.COMPREHENSION,
+ "mode": ModelMode.UNDERSTANDING,
"input_modalities": [
Modality.TEXT,
Modality.IMAGE,
diff --git a/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/types.py b/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/types.py
index 29be9648c..6cc79f3ed 100644
--- a/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/types.py
+++ b/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/types.py
@@ -11,11 +11,23 @@ from typing import (
AudioFormat: TypeAlias = Literal["mp3", "opus", "aac", "flac", "wav", "pcm"]
+class AutoregressionSamplingParams(dict):
+ pass
+
+
+class DiffusionSamplingParams(dict):
+ pass
+
+
+class QwenTTSModelSpecificParams(dict):
+ pass
+
+
class ModelMode(Enum):
IMAGE_GENERATION = auto()
VIDEO_GENERATION = auto()
AUDIO_GENERATION = auto()
- COMPREHENSION = auto()
+ UNDERSTANDING = auto()
class Modality(Enum):
diff --git a/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/validators.py b/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/validators.py
index f1af7b2e9..2abdd2100 100644
--- a/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/validators.py
+++ b/apps/ComfyUI-vLLM-Omni/comfyui_vllm_omni/utils/validators.py
@@ -1,5 +1,6 @@
from .logger import get_logger
from .models import lookup_model_spec
+from .types import AutoregressionSamplingParams, DiffusionSamplingParams
logger = get_logger(__name__)
@@ -31,24 +32,20 @@ def validate_model_and_sampling_params_types(
)
# Check that each stage's type match
for i, sp in enumerate(sampling_param_list):
- if "type" not in sp:
- raise RuntimeError("Internal error: unknown sampling parameter type")
- if sp["type"] != stages[i]:
+ if not _check_sampling_param_matches_stage(sp, stages[i]):
raise ValueError(
- f"Sampling parameter type ({sp['type']}) does not match "
+ f"Sampling parameter type ({sp.__class__.__name__}) does not match "
f"stage type ({stages[i]}) at index {i} for model {model_name}."
)
elif isinstance(sampling_param_list, dict):
- if "type" not in sampling_param_list:
- raise RuntimeError("Internal error: unknown sampling parameter type")
# Check that the provided single sampling param matches all stages
- elif any(stage != sampling_param_list["type"] for stage in stages):
- raise ValueError(
- f"When passing a single sampling parameter node, all stages of the model must match "
- f"the provided sampling parameter's type. "
- f"However, the stages of model {model_name} are: {stages}. "
- f"The provided sampling parameter is {sampling_param_list['type']}"
- )
+ for i, stage in enumerate(stages):
+ if not _check_sampling_param_matches_stage(sampling_param_list, stage):
+ raise ValueError(
+ f"Provided single sampling parameter type ({sampling_param_list.__class__.__name__}) must match "
+ f"the types of all stages of the model. "
+ f"However, stage {i} of model {model_name} is of type {stage}."
+ )
def add_sampling_parameters_to_stage(
@@ -82,3 +79,11 @@ def add_sampling_parameters_to_stage(
sampling_param_list[i].update(params_to_add)
return sampling_param_list
+
+
+def _check_sampling_param_matches_stage(sampling_param: dict, stage_type: str) -> bool:
+ if stage_type == "autoregression":
+ return isinstance(sampling_param, AutoregressionSamplingParams)
+ if stage_type == "diffusion":
+ return isinstance(sampling_param, DiffusionSamplingParams)
+ raise RuntimeError(f"Internal error: unknown stage type {stage_type}.")
diff --git a/apps/ComfyUI-vLLM-Omni/docs/images/comfyui-chaining-services.jpg b/apps/ComfyUI-vLLM-Omni/docs/images/comfyui-chaining-services.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..20d9d077938df094011562435b194a415e837d23
GIT binary patch
literal 265984
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