# Documentation - Class name: ttN pipeKSampler - Category: ttN/legacy - Output node: True - Repo Ref: https://github.com/comfyanonymous/ComfyUI ttN_pipeKSampler节点旨在简化高级采样技术的应用,用于图像生成。它整合了模型输入、采样配置和图像处理参数,为用户提供了一个简洁的界面,以生成具有特定属性或修改的图像。该节点通过抽象化复杂的采样过程配置和执行,大大简化了用户的操作流程。 # Input types ## Required - pipe - 包含采样过程所需的各种配置设置和模型参数的结构化输入。 - Comfy dtype: PIPE_LINE - Python dtype: dict - lora_name - 指定要使用的LoRA模型,影响生成模型的适应性和微调效果。 - Comfy dtype: COMBO[STRING] - Python dtype: str - lora_model_strength - 决定LoRA模型对生成模型的影响强度,调整适应程度。 - Comfy dtype: FLOAT - Python dtype: float - lora_clip_strength - 控制LoRA模型对CLIP模型的影响强度,调整语义理解能力。 - Comfy dtype: FLOAT - Python dtype: float - upscale_method - 定义用于放大生成图像的方法,影响图像分辨率和质量。 - Comfy dtype: COMBO[STRING] - Python dtype: str - factor - 图像放大的倍数,直接影响最终图像大小。 - Comfy dtype: FLOAT - Python dtype: float - crop - 指定生成图像的裁剪参数,影响最终图像构图。 - Comfy dtype: COMBO[STRING] - Python dtype: dict - sampler_state - 图像生成过程中使用的采样器状态,影响采样行为。 - Comfy dtype: COMBO[STRING] - Python dtype: dict - steps - 运行采样过程的步骤数,影响生成图像的细节和质量。 - Comfy dtype: INT - Python dtype: int - cfg - 配置引导因子,影响生成图像的连贯性和质量。 - Comfy dtype: FLOAT - Python dtype: float - sampler_name - 使用的采样器算法名称,决定采样技术。 - Comfy dtype: COMBO[STRING] - Python dtype: str - scheduler - 指定用于控制采样过程的调度器,影响图像生成的进程。 - Comfy dtype: COMBO[STRING] - Python dtype: str - denoise - 图像生成过程中应用的去噪因子,影响图像清晰度和噪声水平。 - Comfy dtype: FLOAT - Python dtype: float - image_output - 生成图像的输出路径,决定图像保存位置。 - Comfy dtype: COMBO[STRING] - Python dtype: str - save_prefix - 添加到保存图像名称前的前缀,辅助图像组织和识别。 - Comfy dtype: STRING - Python dtype: str ## Optional - seed - 用于采样过程的随机种子,确保生成图像的可重复性。 - Comfy dtype: INT - Python dtype: int - optional_model - 可选的模型参数,允许指定替代生成模型。 - Comfy dtype: MODEL - Python dtype: str - optional_positive - 可选的正面提示,引导图像生成朝向特定主题或元素。 - Comfy dtype: CONDITIONING - Python dtype: List[str] - optional_negative - 可选的负面提示,引导图像生成远离特定主题或元素。 - Comfy dtype: CONDITIONING - Python dtype: List[str] - optional_latent - 可选的初始潜在空间输入,作为图像生成过程的起点。 - Comfy dtype: LATENT - Python dtype: torch.Tensor - optional_vae - 可选的变分自编码器,用于增强图像生成过程。 - Comfy dtype: VAE - Python dtype: torch.nn.Module - optional_clip - 可选的CLIP模型,用于图像和文本的语义理解,帮助生成的图像与提供的提示保持一致。 - Comfy dtype: CLIP - Python dtype: torch.nn.Module - xyPlot - 指定生成XY图的参数,可能用于可视化采样过程的某些方面。 - Comfy dtype: XYPLOT - Python dtype: dict # Output types - pipe - 包含采样过程结果的更新后的pipe结构,包括配置和生成的图像。 - Comfy dtype: PIPE_LINE - Python dtype: dict - model - 采样过程中使用的生成模型,可能经过LoRA或其他参数的修改。 - Comfy dtype: MODEL - Python dtype: str - positive - 用于引导图像生成过程的正面提示列表。 - Comfy dtype: CONDITIONING - Python dtype: List[str] - negative - 用于细化图像生成过程的负面提示列表。 - Comfy dtype: CONDITIONING - Python dtype: List[str] - latent - 采样过程产生的潜在空间表示。 - Comfy dtype: LATENT - Python dtype: torch.Tensor - vae - 图像生成过程中涉及的变分自编码器。 - Comfy dtype: VAE - Python dtype: torch.nn.Module - clip - 采样过程中用于语义理解的CLIP模型。 - Comfy dtype: CLIP - Python dtype: torch.nn.Module - image - 采样过程最终生成的图像或图像集。 - Comfy dtype: IMAGE - Python dtype: torch.Tensor - seed - 采样过程中使用的种子值,影响结果的随机性和可重复性。 - Comfy dtype: INT - Python dtype: int ## Usage tips - Infra type: `GPU` - Common nodes: - [ImageUpscaleWithModel](../../Comfy/Nodes/ImageUpscaleWithModel.md) ## Source code ```python class ttN_TSC_pipeKSampler: version = '1.0.5' upscale_methods = ["None", "nearest-exact", "bilinear", "area", "bicubic", "lanczos", "bislerp"] crop_methods = ["disabled", "center"] def __init__(self): pass @classmethod def INPUT_TYPES(cls): return {"required": {"pipe": ("PIPE_LINE",), "lora_name": (["None"] + folder_paths.get_filename_list("loras"),), "lora_model_strength": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}), "lora_clip_strength": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}), "upscale_method": (cls.upscale_methods,), "factor": ("FLOAT", {"default": 2, "min": 0.0, "max": 10.0, "step": 0.25}), "crop": (cls.crop_methods,), "sampler_state": (["Sample", "Hold"], ), "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), "cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}), "sampler_name": (comfy.samplers.KSampler.SAMPLERS,), "scheduler": (comfy.samplers.KSampler.SCHEDULERS,), "denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}), "image_output": (["Hide", "Preview", "Save", "Hide/Save"],), "save_prefix": ("STRING", {"default": "ComfyUI"}) }, "optional": {"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), "optional_model": ("MODEL",), "optional_positive": ("CONDITIONING",), "optional_negative": ("CONDITIONING",), "optional_latent": ("LATENT",), "optional_vae": ("VAE",), "optional_clip": ("CLIP",), "xyPlot": ("XYPLOT",), }, "hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "my_unique_id": "UNIQUE_ID", "embeddingsList": (folder_paths.get_filename_list("embeddings"),), "ttNnodeVersion": ttN_TSC_pipeKSampler.version}, } RETURN_TYPES = ("PIPE_LINE", "MODEL", "CONDITIONING", "CONDITIONING", "LATENT", "VAE", "CLIP", "IMAGE", "INT",) RETURN_NAMES = ("pipe", "model", "positive", "negative", "latent","vae", "clip", "image", "seed", ) OUTPUT_NODE = True FUNCTION = "sample" CATEGORY = "ttN/legacy" def sample(self, pipe, lora_name, lora_model_strength, lora_clip_strength, sampler_state, steps, cfg, sampler_name, scheduler, image_output, save_prefix, denoise=1.0, optional_model=None, optional_positive=None, optional_negative=None, optional_latent=None, optional_vae=None, optional_clip=None, seed=None, xyPlot=None, upscale_method=None, factor=None, crop=None, prompt=None, extra_pnginfo=None, my_unique_id=None, start_step=None, last_step=None, force_full_denoise=False, disable_noise=False): # Clean Loader Models from Global loader.update_loaded_objects(prompt) my_unique_id = int(my_unique_id) ttN_save = ttNsave(my_unique_id, prompt, extra_pnginfo) samp_model = optional_model if optional_model is not None else pipe["model"] samp_positive = optional_positive if optional_positive is not None else pipe["positive"] samp_negative = optional_negative if optional_negative is not None else pipe["negative"] samp_samples = optional_latent if optional_latent is not None else pipe["samples"] samp_vae = optional_vae if optional_vae is not None else pipe["vae"] samp_clip = optional_clip if optional_clip is not None else pipe["clip"] if seed in (None, 'undefined'): samp_seed = pipe["seed"] else: samp_seed = seed def process_sample_state(pipe, samp_model, samp_clip, samp_samples, samp_vae, samp_seed, samp_positive, samp_negative, lora_name, lora_model_strength, lora_clip_strength, steps, cfg, sampler_name, scheduler, denoise, image_output, save_prefix, prompt, extra_pnginfo, my_unique_id, preview_latent, disable_noise=disable_noise): # Load Lora if lora_name not in (None, "None"): samp_model, samp_clip = loader.load_lora(lora_name, samp_model, samp_clip, lora_model_strength, lora_clip_strength) # Upscale samples if enabled samp_samples = sampler.handle_upscale(samp_samples, upscale_method, factor, crop) samp_samples = sampler.common_ksampler(samp_model, samp_seed, steps, cfg, sampler_name, scheduler, samp_positive, samp_negative, samp_samples, denoise=denoise, preview_latent=preview_latent, start_step=start_step, last_step=last_step, force_full_denoise=force_full_denoise, disable_noise=disable_noise) latent = samp_samples["samples"] samp_images = samp_vae.decode(latent) results = ttN_save.images(samp_images, save_prefix, image_output) sampler.update_value_by_id("results", my_unique_id, results) # Clean loaded_objects loader.update_loaded_objects(prompt) new_pipe = { "model": samp_model, "positive": samp_positive, "negative": samp_negative, "vae": samp_vae, "clip": samp_clip, "samples": samp_samples, "images": samp_images, "seed": samp_seed, "loader_settings": pipe["loader_settings"], } sampler.update_value_by_id("pipe_line", my_unique_id, new_pipe) del pipe if image_output in ("Hide", "Hide/Save"): return sampler.get_output(new_pipe) return {"ui": {"images": results}, "result": sampler.get_output(new_pipe)} def process_hold_state(pipe, image_output, my_unique_id): last_pipe = sampler.init_state(my_unique_id, "pipe_line", pipe) last_results = sampler.init_state(my_unique_id, "results", list()) if image_output in ("Hide", "Hide/Save"): return sampler.get_output(last_pipe) return {"ui": {"images": last_results}, "result": sampler.get_output(last_pipe)} def process_xyPlot(pipe, samp_model, samp_clip, samp_samples, samp_vae, samp_seed, samp_positive, samp_negative, lora_name, lora_model_strength, lora_clip_strength, steps, cfg, sampler_name, scheduler, denoise, image_output, save_prefix, prompt, extra_pnginfo, my_unique_id, preview_latent, xyPlot): random.seed(seed) sampleXYplot = ttNxyPlot(xyPlot, save_prefix, image_output, prompt, extra_pnginfo, my_unique_id) if not sampleXYplot.validate_xy_plot(): return process_sample_state(pipe, lora_name, lora_model_strength, lora_clip_strength, steps, cfg, sampler_name, scheduler, denoise, image_output, save_prefix, prompt, extra_pnginfo, my_unique_id, preview_latent) plot_image_vars = { "x_node_type": sampleXYplot.x_node_type, "y_node_type": sampleXYplot.y_node_type, "lora_name": lora_name, "lora_model_strength": lora_model_strength, "lora_clip_strength": lora_clip_strength, "steps": steps, "cfg": cfg, "sampler_name": sampler_name, "scheduler": scheduler, "denoise": denoise, "seed": samp_seed, "model": samp_model, "vae": samp_vae, "clip": samp_clip, "positive_cond": samp_positive, "negative_cond": samp_negative, "ckpt_name": pipe['loader_settings']['ckpt_name'], "vae_name": pipe['loader_settings']['vae_name'], "clip_skip": pipe['loader_settings']['clip_skip'], "lora1_name": pipe['loader_settings']['lora1_name'], "lora1_model_strength": pipe['loader_settings']['lora1_model_strength'], "lora1_clip_strength": pipe['loader_settings']['lora1_clip_strength'], "lora2_name": pipe['loader_settings']['lora2_name'], "lora2_model_strength": pipe['loader_settings']['lora2_model_strength'], "lora2_clip_strength": pipe['loader_settings']['lora2_clip_strength'], "lora3_name": pipe['loader_settings']['lora3_name'], "lora3_model_strength": pipe['loader_settings']['lora3_model_strength'], "lora3_clip_strength": pipe['loader_settings']['lora3_clip_strength'], "positive": pipe['loader_settings']['positive'], "positive_token_normalization": pipe['loader_settings']['positive_token_normalization'], "positive_weight_interpretation": pipe['loader_settings']['positive_weight_interpretation'], "negative": pipe['loader_settings']['negative'], "negative_token_normalization": pipe['loader_settings']['negative_token_normalization'], "negative_weight_interpretation": pipe['loader_settings']['negative_weight_interpretation'], } latent_image = sampleXYplot.get_latent(pipe["samples"]) latents_plot = sampleXYplot.get_labels_and_sample(plot_image_vars, latent_image, preview_latent, start_step, last_step, force_full_denoise, disable_noise) samp_samples = {"samples": latents_plot} images = sampleXYplot.plot_images_and_labels() if xyPlot["output_individuals"]: results = ttN_save.images(images, save_prefix, image_output) else: results = ttN_save.images(images[-1], save_prefix, image_output) sampler.update_value_by_id("results", my_unique_id, results) # Clean loaded_objects loader.update_loaded_objects(prompt) new_pipe = { "model": samp_model, "positive": samp_positive, "negative": samp_negative, "vae": samp_vae, "clip": samp_clip, "samples": samp_samples, "images": images, "seed": samp_seed, "loader_settings": pipe["loader_settings"], } sampler.update_value_by_id("pipe_line", my_unique_id, new_pipe) del pipe if image_output in ("Hide", "Hide/Save"): return sampler.get_output(new_pipe) return {"ui": {"images": results}, "result": sampler.get_output(new_pipe)} preview_latent = True if image_output in ("Hide", "Hide/Save"): preview_latent = False if sampler_state == "Sample" and xyPlot is None: return process_sample_state(pipe, samp_model, samp_clip, samp_samples, samp_vae, samp_seed, samp_positive, samp_negative, lora_name, lora_model_strength, lora_clip_strength, steps, cfg, sampler_name, scheduler, denoise, image_output, save_prefix, prompt, extra_pnginfo, my_unique_id, preview_latent) elif sampler_state == "Sample" and xyPlot is not None: return process_xyPlot(pipe, samp_model, samp_clip, samp_samples, samp_vae, samp_seed, samp_positive, samp_negative, lora_name, lora_model_strength, lora_clip_strength, steps, cfg, sampler_name, scheduler, denoise, image_output, save_prefix, prompt, extra_pnginfo, my_unique_id, preview_latent, xyPlot) elif sampler_state == "Hold": return process_hold_state(pipe, image_output, my_unique_id) ```