* bump requires-python * model patcher now implements everything it needs for comfyui * index * Support LTS and Vanilla ComfyUI * Fix version string when installed as package (not material) * style: make linter happy * update init.py * Update nunchaku index * Bump dependencies, include config and workflows when installed using pip/uv * Update installation instructions to include ComfyUI LTS * Update requirements for nunchaku>=1.0.1 * Fix torch210 key * Fix pep 508 spec * Improve tests (still more to go) * Fix comfyui_controlnet_aux flaws * Update tests (all should pass) * Organize the tests in this runner * Update contribution guide * Install uv * Dependencies now resolve with correct conflicts with uv's most stringent resolution * Mediapipe hasn't been built for 3.13 yet, so we can't use it here * Remove controlnet-aux dep * make linter happy * make the linter happy * optimize the loading * update installation * update * update contribution guide * update qwenimage * need to figure out why the toml parsing doesn't owk * update * update * update * style: make linter happy * update * add pulid requirement * update docs * update * update * update * update * update * organize the pyproject.toml * update * update * update * passing all tests * update * update * update * update * update * remove a useless class * update * update * fix a typo --------- Co-authored-by: doctorpangloss <@hiddenswitch.com> Co-authored-by: doctorpangloss <2229300+doctorpangloss@users.noreply.github.com>
58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
import json
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
import pytest_asyncio
|
|
import torch
|
|
from comfy.api.components.schema.prompt import Prompt
|
|
from comfy.cli_args_types import Configuration
|
|
from comfy.client.embedded_comfy_client import Comfy
|
|
|
|
from nunchaku.utils import get_precision, is_turing
|
|
|
|
from .case import Case, cases, ids
|
|
from .utils import compute_metrics, prepare_inputs, prepare_models, set_nested_value
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
precision = get_precision()
|
|
torch_dtype = torch.float16 if is_turing() else torch.bfloat16
|
|
dtype_str = "fp16" if torch_dtype == torch.float16 else "bf16"
|
|
|
|
|
|
@pytest_asyncio.fixture(scope="module", autouse=False)
|
|
async def inputs(tmp_path_factory):
|
|
config = Configuration()
|
|
input_path = config.input_directory = str(tmp_path_factory.mktemp("nunchaku_input"))
|
|
prepare_inputs(input_path)
|
|
yield config
|
|
|
|
|
|
@pytest_asyncio.fixture(scope="function", autouse=False)
|
|
async def client(tmp_path_factory, inputs) -> Comfy:
|
|
async with Comfy(inputs) as client_instance:
|
|
prepare_models()
|
|
yield client_instance
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("case", cases, ids=ids)
|
|
async def test(case: Case, client: Comfy):
|
|
api_file = Path(__file__).parent / "workflows" / case.workflow_name / "api.json"
|
|
# Read and parse the workflow file
|
|
workflow = json.loads(api_file.read_text(encoding="utf8"))
|
|
for key, value in case.inputs.items():
|
|
set_nested_value(workflow, key, value)
|
|
prompt = Prompt.validate(workflow)
|
|
outputs = await client.queue_prompt(prompt)
|
|
save_image_node_id = next(key for key in prompt if prompt[key].class_type == "SaveImage")
|
|
path = outputs[save_image_node_id]["images"][0]["abs_path"]
|
|
logger.info("Generated image path: %s", path)
|
|
|
|
clip_iqa, lpips, psnr = compute_metrics(path, case.ref_image_url)
|
|
|
|
assert clip_iqa >= min(case.expected_clip_iqa[f"{precision}-{dtype_str}"], 1) * 0.9
|
|
assert lpips <= max(case.expected_lpips[f"{precision}-{dtype_str}"], 0.1) * 1.15
|
|
assert psnr >= min(case.expected_psnr[f"{precision}-{dtype_str}"], 24) * 0.85
|