ComfyUI custom node for ComfyUI_WolfSigmas
  • Python 99.5%
  • JavaScript 0.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Balazs Horvath 9f6836dbda Add Bevy 0.18.1 WASM integration with strawberry theme
- Implement complete Bevy 0.18.1 WASM vendor directory
- Add strawberry-themed pink background with 3D white text effects
- Create user-editable text configuration system
- Add comprehensive Python pytest suite (18 tests passing)
- Add Rust test framework for core functionality
- Fix all Bevy 0.18.1 API compatibility issues
- Implement cosmic text effects (Plasma, Nebula, Quantum, Stellar)
- Add particle systems and 3D projection effects
- Create JavaScript bridge for ComfyUI communication
- Add automated WASM build pipeline with wasm-bindgen
- Include web interface with interactive configuration panel

Features:
- Pink strawberry theme with animated glow effects
- 3D white text with cosmic particle systems
- Real-time user-editable configuration
- WebGL2 rendering with WASM optimization
- Comprehensive test coverage
- Modular effect system architecture
2026-05-12 20:39:41 +02:00
build yep 2026-04-11 18:11:32 +02:00
docs ? 2026-03-03 16:20:21 +01:00
nodes fix: _process_chunk method signature and frame_idx context 2026-05-12 19:58:01 +02:00
scripts Add Bevy 0.18.1 WASM integration with strawberry theme 2026-05-12 20:39:41 +02:00
vendor/bevy Add Bevy 0.18.1 WASM integration with strawberry theme 2026-05-12 20:39:41 +02:00
web yep 2026-04-11 18:11:32 +02:00
.gitignore yep 2026-04-11 18:11:32 +02:00
__init__.py some stuff 2026-05-12 19:45:28 +02:00
CHANGELOG.md yep 2026-04-11 18:11:32 +02:00
config.yaml ? 2026-03-03 16:20:21 +01:00
EULER_ANCESTRAL_WOLF.md simple sampler 2025-05-16 17:42:37 +02:00
package-lock.json yep 2026-04-11 18:11:32 +02:00
package.json yep 2026-04-11 18:11:32 +02:00
pytest.ini Add Bevy 0.18.1 WASM integration with strawberry theme 2026-05-12 20:39:41 +02:00
README.md yep 2026-04-11 18:11:32 +02:00
README_STREAMSCRIPTABLE.md some stuff 2026-05-12 19:45:28 +02:00
requirements.txt yep 2026-04-11 18:11:32 +02:00
SAMPLER_EVALUATOR.md awoo 2025-05-15 22:58:10 +02:00
SIGMA_EVALUATOR.md initial commit 2025-05-15 21:07:21 +02:00
SIMPLE_SAMPLER_EVALUATOR.md append more fun 2025-05-16 21:11:45 +02:00
test_bevy_wasm_standalone.py Add Bevy 0.18.1 WASM integration with strawberry theme 2026-05-12 20:39:41 +02:00
wolf_sigmas.py crazy 2025-05-17 15:03:19 +02:00

ComfyUI Wolf Sigmas

⚠️ Security Warning: Remote Code Execution ⚠️

This custom node pack includes nodes that can execute arbitrary Python code provided by the user or embedded within imported workflows/scripts. Specifically, the following nodes pose a risk if you load untrusted content:

  • Wolf Sigma Script Evaluator (🐺)
  • Wolf Sampler Script Evaluator (🐺)
  • Wolf Simple Sampler Script (🐺)
  • Scriptable Empty Latent (🐺)
  • Wolf Simple Sampler Script (🐺)

Executing scripts from untrusted sources can lead to security vulnerabilities, including remote code execution on your machine.

Please exercise extreme caution:

  • NEVER load or run workflows, scripts, or JSON files containing these nodes from sources you do not fully trust.
  • Always review any Python code within these nodes before execution if you are unsure of its origin or purpose.

The authors of this node pack are not responsible for any damage or security incidents that may occur from the misuse of these script evaluation features.

Configuration

Edit config.yaml in this folder (or set env vars) to change behavior:

  • disable_scriptable_nodes (default: false): If true, all nodes that execute user Python (scriptable nodes and script evaluators) are not registered. Use in locked-down environments to disable remote code execution.
  • Env override: COMFYUI_WOLFSIGMAS_DISABLE_SCRIPTABLE_NODES=1 forces scriptable nodes off.

This custom node pack for ComfyUI provides a suite of tools for generating and manipulating sigma schedules for diffusion models. These nodes are particularly useful for fine-tuning the sampling process, experimenting with different step counts, and adapting schedules for specific models.

Node overview

flowchart TB
  subgraph sigma_utils [Sigma utilities]
    Get[Get Sigmas]
    Set[Set from JSON]
    ToJSON[To JSON]
  end
  subgraph transforms [Sigma transforms]
    Power[Power Transform]
    ClampT0[Clamp T0]
    ShiftScale[Shift and Scale]
    Normalize[Normalize Range]
    Quantize[Quantize]
    RespaceLogCos[Respace Log-Cosine]
    Clip[Clip Values]
    Reverse[Reverse]
    ReverseRescale[Reverse and Rescale]
    Slice[Slice]
    Insert[Insert Value]
    AddNoise[Add Noise]
  end
  subgraph generators [Sigma generators]
    Geometric[Geometric Progression]
    Polynomial[Polynomial]
    Tanh[Tanh Generator]
  end
  subgraph script_eval [Script evaluators]
    SigmaScript[Sigma Script Evaluator]
    SamplerScript[Sampler Script Evaluator]
    SimpleSampler[Simple Sampler Script]
  end
  subgraph scriptable [Scriptable nodes]
    EmptyLatent[Scriptable Empty Latent]
    ScriptableImage[Scriptable Image]
    ScriptableMask[Scriptable Mask]
    ScriptableLatent[Scriptable Latent]
    ScriptableLatentFlux2[Scriptable Latent Flux2]
    FractalImage[Fractal Image]
    TextProj[Text Projection 3D]
    ScriptText[Scriptable Text]
    MdText[Markdown Text]
  end
  subgraph inspection [Model inspection]
    Structure[Structure Explorer]
    Activation[Activation Inspector]
    Depatchify[Depatchify]
  end
  sigma_utils --> transforms
  sigma_utils --> generators
  script_eval --> SIGMAS[SIGMAS]
  script_eval --> SAMPLER[SAMPLER]
  ScriptableImage --> SHADER_GALLERY[Shader gallery]
  FractalImage --> SHADER_GALLERY

Scriptable Image (🐺) has a dedicated Scriptable Image API and Shader Gallery with copy-paste scripts for: underwater, water caustics, fire/heat, smoke/fog, vignette, film grain, chromatic aberration, lens distortion, scanlines, and simple bloom.

For deeper math-heavy implementations, see Advanced PyTorch Shaders (refraction-density caustics, flow-band caustics, multi-light torch shading, chromatic refraction, edge-aware bloom, filmic split-tone).

Advanced image ops for edit models and IP-Adapter: Edge and structure, Style and color, Composition and layout, Lighting and depth — each doc has math and runnable Scriptable Image scripts.

Text Projection (3D, Mask) (🐺) renders 2D/3D-style text onto an image and outputs a mask for inpainting/guidance. See Text Projection (IMAGE_OPS_TEXT_PROJECTION.md) for styles, parameters, and the optional draggable position UI (WolfBypass).

Table of Contents


Advanced

Scriptable Sigma Generator

For advanced users who need maximum flexibility, the Wolf Sigma Script Evaluator (🐺) node allows for the creation of custom sigma schedules by executing a user-provided Python script. This provides a powerful way to define complex or experimental schedules.

For detailed information on how to use the script evaluator, its inputs, outputs, scripting capabilities, and example scripts, please see the Wolf Sigma Script Evaluator Documentation.

Scriptable Sampler Generator

Similarly, for users wishing to implement entirely custom sampling algorithms, the Wolf Sampler Script Evaluator (🐺) node enables the definition of new samplers through Python scripts. This node integrates with ComfyUI's KSampler system, allowing custom samplers to be used like any built-in sampler.

For detailed information on how to use the sampler script evaluator, its scripting requirements, parameters, and example sampler implementations (like Euler and Euler Ancestral), please see the Wolf Sampler Script Evaluator Documentation.

Simple Scriptable Sampler

The Wolf Simple Sampler Script (🐺) node offers a streamlined way to define custom sampling logic by executing a user-provided Python script for the core denoising loop. This is simpler than implementing a full KSampler-compatible class and is well-suited for direct experimentation with sampling algorithms. The provided script is given access to necessary variables like the model, initial latents, and the sigma schedule, and is expected to return the final denoised latents.

  • Class: WolfSimpleSamplerScriptEvaluator
  • Display Name: Wolf Simple Sampler Script (🐺)
  • Category: sampling/ksampler_wolf
  • Description: Executes a user-provided Python script that defines the core sampling loop. The script receives variables like the model, initial latents (x_initial), and the sigma schedule (sigmas_schedule), and must assign the final denoised latents to a variable named latents. A default script implementing a basic Euler sampler is provided as a template.
  • Inputs:
    • script: STRING (multiline, default: Python script for basic Euler sampling) - The Python script implementing the sampling loop.
  • Outputs:
    • SAMPLER: SAMPLER - A ComfyUI compatible sampler object that can be directly used with KSampler nodes.

For detailed information on the scripting environment, available variables, requirements, and example scripts, please refer to the Wolf Simple Sampler Script Evaluator Documentation.

Flux2 / Flux2-Klein image and latent nodes

The pack includes scriptable image and latent nodes that work with Flux2 and Flux2-Klein (128-channel latent, H/16×W/16):

  • Scriptable Image (🐺) — Run Python on IMAGE with Pillow, OpenCV, numpy; set output_image. API and Shader Gallery (underwater, caustics, fire, smoke, vignette, grain, chromatic aberration, lens distortion, scanlines, bloom).
  • Scriptable Latent (🐺) — Model-aware scriptable latent (SDXL/FLUX/Flux2); set output_latent_samples.
  • Scriptable Latent Flux2 (🐺) — Flux2/Flux2-Klein only: 128ch, optional reference latent and Klein helpers (channel mask, spatial fade).
  • Image Expression (🐺) — Single expression on IMAGE (e.g. torch.clamp(image * a + b, 0, 1)).
  • Flux2 Latent Batch Ops (🐺) — Concat, slice, blend, or mask Flux2 latents without scripting.

For detailed documentation, injected variables, and copy-paste example scripts for Flux2 and Flux2-Klein edit/diffusion workflows, see Flux2-Klein nodes documentation (docs/FLUX2_KLEIN_NODES.md). The Scriptable Image node can optionally output a MASK (set output_mask in the script); see the same doc for simple and advanced mask-operation examples. Scriptable Latent Flux2 (🐺) has a detailed guide (Flux2-Klein latent format, channel layout, Klein helpers, and many effects: half-and-half ref, radial blend, channel bands, invert, tile, edge-only ref, low-freq, per-quadrant, gradient strength) in docs/SCRIPTABLE_LATENT_FLUX2.md. Scriptable Conditioning (🐺) has full documentation (contract, meta keys, beginner/intermediate/advanced examples, Flux2-Klein reference latents) in docs/SCRIPTABLE_CONDITIONING.md. A plan for additional scriptable nodes (Scriptable Mask, Scriptable String, Scriptable Conditioning, Comfy I/O utilities) is in docs/SCRIPTABLE_NODES_AND_IO_PLAN.md.

Text Projection (3D, Mask) (🐺)

  • Class: WolfTextProjection
  • Display Name: Text Projection (3D, Mask) (🐺)
  • Category: image/text
  • Description: Renders text onto an input image with optional 3D-like styles (flat, shadow, bevel, perspective, extrude, outline, glow, emboss, sticker) and outputs the composited IMAGE and a MASK (text + effects alpha) for inpainting or control.

Styles: Flat, Shadow, Bevel, Perspective, Extrude (fake depth), Outline (stroke), Glow (soft halo), Emboss (light/dark edge), Sticker (border + drop shadow). Optional parameters per style: shadow offset/blur, depth steps/offset (Extrude), outline width/color (Outline/Sticker), glow radius/intensity (Glow), bevel strength (Bevel/Emboss).

UI (ComfyUI WolfBypass): If the WolfBypass extension is installed, the node gets an extra widget: a small preview with draggable anchors for text position (x, y) and shadow offset (shadow_dx, shadow_dy), and style-specific sliders that show/hide based on the selected style.

See docs/IMAGE_OPS_TEXT_PROJECTION.md for data flow and usage.

Text 3D Projection (Blender) (🐺)

  • Class: WolfText3DProjection
  • Display Name: Text 3D Projection (Blender) (🐺)
  • Category: image/text
  • Description: Renders 3D text to IMAGE and MASK via Blender (headless subprocess). Full TrueType/OpenType support, extrude, bevel, Cycles or Eevee, GPU-accelerated. No EGL/GLX/Node.js; works in Docker with apt install blender.

Inputs: text (optional STRING, CodeMirror via PYTHON_SCRIPT when WolfBypass is installed; connect any STRING to override), width/height, font (Built-in or system fonts), size_scale, extrude, bevel_depth, bevel_resolution, color, camera/samples/render_engine, optional background image to composite onto.

Font list: "Built-in" (Blender default) or system fonts from fontconfig (Linux), Windows Fonts, or macOS font directories; path is passed to Blender.

Blender script: scripts/blender_render_text.py is invoked as blender -b -P blender_render_text.py -- params.json out.png. The node writes params JSON and reads the rendered PNG (RGBA to image + mask).

Docker: The ComfyUI Dockerfile includes blender (apt). No Node.js or npm is required for this node. For custom fonts, mount a directory (e.g. -v /host/fonts:/fonts) and use a font path like /fonts/MyFont.ttf (or select a system font discovered from that path).

Scriptable Empty Latent (🐺)

The WolfScriptableEmptyLatent node provides a highly flexible way to generate initial latent noise for the diffusion process. It allows users to define the generation logic using a Python script, enabling complex noise patterns, structured noise, or any custom initialization beyond simple Gaussian noise or zeros. The default script implements a sophisticated "Calibrated Structured Noise" combining Perlin and Gaussian noise, scaled by the initial sigma of a provided schedule and the VAE's scaling factor.

  • Class: WolfScriptableEmptyLatent
  • Display Name: Scriptable Empty Latent (🐺)
  • Category: latent/noise (or your preferred category like Wolf Custom Nodes/Latent)
  • Description: Executes a user-provided Python script to generate an initial latent tensor. The script has access to various parameters like dimensions, seed, the VAE model, a sigma schedule, and Perlin noise configuration. It must produce a latent tensor of the correct NCHW shape.

⚠️ Security Warning

This node executes arbitrary Python code. Only use scripts from trusted sources. Review any script before execution if you are unsure of its origin.

Inputs

  • model: MODEL - The main diffusion model, used primarily to access VAE properties like latent_format.scale_factor.
  • width: INT (default: 1024, min: 64, step: 8) - Target width of the image (latent width will be width // 8).
  • height: INT (default: 1024, min: 64, step: 8) - Target height of the image (latent height will be height // 8).
  • batch_size: INT (default: 1, min: 1, max: 64) - Number of latent images to generate in the batch.
  • seed: INT (default: 0, control_after_generate: True) - Seed for random number generation within the script.
  • sigmas: SIGMAS - An input sigma schedule (tensor). The default script uses the first sigma (sigmas[0]) for calibration.
  • perlin_blend_factor: FLOAT (default: 0.5, min: 0.0, max: 1.0) - Blend factor between Gaussian and Perlin noise in the default script. 0.0 for pure Gaussian, 1.0 for pure Perlin.
  • perlin_res_factor_h: INT (default: 8, min: 1, max: 128) - Resolution factor for Perlin noise height. Higher values mean lower frequency / larger features. Latent height is divided by this.
  • perlin_res_factor_w: INT (default: 8, min: 1, max: 128) - Resolution factor for Perlin noise width.
  • perlin_frequency_factor: FLOAT (default: 2.0, min: 1.01, max: 4.0) - Frequency multiplier for each Perlin octave.
  • perlin_octaves: INT (default: 4, min: 1, max: 10) - Number of Perlin noise octaves to sum.
  • perlin_persistence: FLOAT (default: 0.5, min: 0.01, max: 1.0) - Amplitude persistence factor between Perlin octaves.
  • perlin_contrast_scale: FLOAT (default: 1.0, min: 0.1, max: 20.0, step: 0.1, tooltip: "Scales Perlin noise before normalization to enhance its features.") - Multiplies the raw Perlin noise before it's normalized, to amplify its structural features.
  • script: STRING (multiline, default: Python script for calibrated structured noise) - The Python script to execute for latent generation.

Outputs

  • LATENT: LATENT - A dictionary containing the generated latent tensor under the key "samples".

Scripting Environment

The Python script executed by this node has access to the following:

Local Variables:

  • width, height, batch_size, seed: Integers as provided to the node.
  • sigmas: A torch.Tensor of sigma values, moved to the execution device.
  • model: The MODEL object passed to the node.
  • device: A string representing the torch device for execution (e.g., "cuda:0", "cpu").
  • perlin_params: A dictionary containing all perlin_* input values: {'blend_factor', 'res_factor_h', 'res_factor_w', 'frequency_factor', 'octaves', 'persistence', 'perlin_contrast_scale'}.
  • output_latent_samples: Initially None. The script must assign the final generated latent tensor (NCHW float32 tensor on device) to this variable.

Global Helper Modules & Functions:

  • torch: The PyTorch module.
  • math: The Python math module.
  • F: torch.nn.functional.
  • rand_perlin_2d_octaves_fn(shape, res, octaves, persistence, frequency_factor, device): Function to generate multi-octave 2D Perlin noise. device argument should be the string from script_locals.
  • rand_perlin_2d_fn(shape, res, fade_func, device): Function to generate single-octave 2D Perlin noise.
  • _fade_fn(t): The quintic fade function 6t^5 - 15t^4 + 10t^3 used in Perlin noise.

Default Script: Calibrated Structured Noise Mathematics

The default script generates initial noise by blending Perlin noise with Gaussian noise and then calibrates its magnitude using the provided sigmas and VAE properties.

  1. Parameter Setup:

    • Latent dimensions: H_L = \text{height} // 8, W_L = \text{width} // 8. (Note: For FLUX models, the script uses H_L = \text{height} // 8, W_L = \text{width} // 8 as well, but with 16 channels).
    • Target sigma \sigma_{target} is taken as the first value from the input sigmas tensor.
    • VAE scaling factor s_{VAE} is determined based on the model type (e.g., 0.18215 for typical SDXL, 1.0 for FLUX). This value is logged for informational purposes.
    • The effective sigma for scaling the final \mathcal{N}(0, 1) noise is:
      $$ \sigma_{eff} = \sigma_{target

    This means the standard deviation of the final output noise tensor is intended to match the target_sigma from the input schedule.

  2. Gaussian Noise Generation (G):

    • Standard Gaussian noise is generated for each element in the latent tensor (B, C, H_L, W_L), where B is batch size and C=4 channels.
    • G_{b,c,h,w} \sim \mathcal{N}(0, 1)
  3. Perlin Noise Generation (P):

    • Generated independently for each batch item and channel, using rand_perlin_2d_octaves_fn.
    • Base Perlin Noise (rand_perlin_2d_fn):
      • A grid of random 2D gradient vectors is created. For a point (x,y) in the latent space, its position within a grid cell (u,v) (where u,v \in [0,1]) is determined.
      • Dot products are computed between the gradient vectors at the cell's four corners (g_{00}, g_{10}, g_{01}, g_{11}) and the displacement vectors from the point to these corners.
        • dp_{00} = g_{00} \cdot (u, v)
        • dp_{10} = g_{10} \cdot (u-1, v)
        • dp_{01} = g_{01} \cdot (u, v-1)
        • dp_{11} = g_{11} \cdot (u-1, v-1)
      • These dot products are interpolated using a fade function \text{fade}(t) = 6t^5 - 15t^4 + 10t^3 to ensure smooth transitions. Let t_u = \text{fade}(u) and t_v = \text{fade}(v).
      • Lerp (Linear Interpolation): \text{lerp}(a, b, w) = a + w(b-a).
        • v_0 = \text{lerp}(dp_{00}, dp_{10}, t_u)
        • v_1 = \text{lerp}(dp_{01}, dp_{11}, t_u)
      • The final Perlin value for that point is \text{lerp}(v_0, v_1, t_v), typically scaled by \sqrt{2}.
    • Octaves: Multiple layers (octaves) of Perlin noise are summed. For each octave i:
      • Frequency f_i = \text{frequency\_factor}^i. The resolution res for rand_perlin_2d_fn is scaled by f_i.
      • Amplitude A_i = \text{persistence}^i.
      • The total Perlin noise is P_{raw} = \sum_{i=0}^{\text{octaves}-1} A_i \times \text{Perlin}_i(\text{shape}, \text{res} \times f_i).
    • The base resolution for Perlin noise is determined by perlin_res_factor_h and perlin_res_factor_w:
      • \text{res}_h = \max(1, H_L // \text{perlin\_res\_factor\_h})
      • \text{res}_w = \max(1, W_L // \text{perlin\_res\_factor\_w})
  4. Perlin Contrast Scaling:

    • Let c_{scale} be the perlin_contrast_scale input parameter.
    • The raw Perlin noise P_{raw} (generated in step 3) is multiplied by c_{scale} to enhance its features before normalization:
      $$ P_{scaled} = P_{raw} \times c_{scale
  5. Normalization:

    • Both the Gaussian noise G and the contrast-scaled Perlin noise P_{scaled} are independently normalized to have zero mean and unit standard deviation across their spatial dimensions (height and width) for each channel and batch item. For any noise tensor X (here X would be G or P_{scaled}):
      $$ X_{norm} = \frac{X - \mu_X}{\sigma_X + \epsilon
      where \mu_X is the mean of X, \sigma_X is its standard deviation, and \epsilon is a small constant (e.g., 10^{-5}) to prevent division by zero. So, we get G_{norm} from G, and P_{norm} from P_{scaled}.
  6. Blending:

    • The normalized Gaussian noise G_{norm} and normalized (contrast-enhanced) Perlin noise P_{norm} are blended using the perlin_blend_factor (\alpha_{blend}):
      $$ N_{blend} = (1 - \alpha_{blend}) \cdot G_{norm} + \alpha_{blend} \cdot P_{norm
      This is equivalent to torch.lerp(G_norm, P_norm, perlin_blend_factor).
  7. Re-Normalization of Blended Noise:

    • The blended noise N_{blend} is normalized again to ensure it has zero mean and unit standard deviation:
      $$ N_{blend, norm} = \frac{N_{blend} - \mu_{N_{blend}}}{\sigma_{N_{blend}} + \epsilon
  8. Final Scaling:

    • The re-normalized blended noise N_{blend, norm} (which is \mathcal{N}(0, 1)) is scaled by the effective_sigma (which is \sigma_{target}) calculated in step 1:
      $$ \text{Output Latent} = N_{blend, norm} \times \sigma_{eff

    This ensures the initial latent noise has a standard deviation equal to \sigma_{target}, which is typically expected by samplers using schedules like Karras.

Simple Scriptable Empty Latent (🐺)

The WolfSimpleScriptableEmptyLatent node provides a straightforward way to generate initial latent noise using a Python script. It is simpler than the Scriptable Empty Latent (🐺) node and is well-suited for basic latent generation or when custom logic is needed for channel count or initial values, especially with models like FLUX. The default script generates a zero-filled latent tensor, automatically adjusting the number of channels based on the connected model.

  • Class: WolfSimpleScriptableEmptyLatent
  • Display Name: Simple Scriptable Empty Latent (🐺)
  • Category: latent/noise
  • Description: Executes a user-provided Python script to generate an initial latent tensor. The script has access to parameters like dimensions and an optional model connection. It must produce a latent tensor of the correct NCHW shape.

⚠️ Simple Security Warning

This node executes arbitrary Python code. Only use scripts from trusted sources. Review any script before execution if you are unsure of its origin.

Simple Inputs

  • width: INT (default: 1024, min: 64, step: 8) - Target width of the image (latent width will be width // 8).
  • height: INT (default: 1024, min: 64, step: 8) - Target height of the image (latent height will be height // 8).
  • batch_size: INT (default: 1, min: 1, max: 64) - Number of latent images to generate in the batch.
  • device_selection: COMBO["AUTO", "CPU", "GPU"] (default: "AUTO") - Specifies the target device for the script execution and the final latent tensor. "AUTO" attempts to use the model's device or falls back to an intermediate device.
  • script: STRING (multiline, default: Python script for model-aware zero latent) - The Python script to execute for latent generation.
  • model: MODEL (optional) - An optional model input. The default script uses this to determine if the model is FLUX-based to set the latent channel count to 16 (otherwise 4).

Simple Outputs

  • LATENT: LATENT - A dictionary containing the generated latent tensor under the key "samples".

Simple Scripting Environment

The Python script executed by this node has access to the following:

Local Variables:

  • width, height, batch_size: Integers as provided to the node.
  • model: The MODEL object passed to the node (can be None).
  • device: A string representing the torch device for execution (e.g., "cuda:0", "cpu"), determined by the device_selection input and available hardware/model.
  • output_latent_samples: Initially None. The script must assign the final generated latent tensor (NCHW float32 tensor on device) to this variable.

Global Helper Modules & Functions:

  • torch: The PyTorch module.
  • math: The Python math module.

Default Script: Model-Aware Zero Latent

The default script generates a zero-filled latent tensor with dimensions appropriate for the specified width, height, and batch_size.

  1. Channel Determination:

    • It inspects the connected model (if any).
    • If the model is identified as a FLUX model (by checking model.model_type or class name), num_latent_channels is set to 16.
    • Otherwise, num_latent_channels defaults to 4 (standard for SD, SDXL, etc.).
    • If no model is connected, it defaults to 4 channels.
    • Prints the detected model type and chosen channel count.
  2. Latent Dimensions:

    • Latent height: H_L = \text{height} // 8.
    • Latent width: W_L = \text{width} // 8.
  3. Tensor Generation:

    • The target shape is (B, C, H_L, W_L), where B is batch_size and C is the determined num_latent_channels.
    • A torch.zeros tensor of this shape is created with dtype=torch.float32 on the specified device.
    • This tensor is assigned to output_latent_samples.
    • Prints the generation parameters and target shape.

This provides a basic, flexible starting point for latent generation, particularly useful for ensuring compatibility with models requiring different latent channel depths.


General Sigma Utilities

Get Sigmas (🐺)

  • Class: WolfSigmasGet
  • Display Name: Get Sigmas (🐺)
  • Category: sampling/sigmas_wolf
  • Description: Retrieves the sigma schedule from a given model based on the specified sampler settings (steps, denoise, scheduler type). This is a utility to extract the sigmas that ComfyUI would normally calculate internally.
  • Inputs:
    • model: MODEL - The diffusion model.
    • steps: INT (default: 20, min: 1, max: 10000) - The total number of sampling steps.
    • denoise: FLOAT (default: 1.0, min: 0.0, max: 1.0, step: 0.01) - The denoising strength. A value of 1.0 uses all steps, while a smaller value uses a fraction of the steps from the end of the schedule.
    • scheduler: COMBO[comfy.samplers.KSampler.SCHEDULERS] - The ComfyUI native scheduler type to use for sigma calculation.
  • Outputs:
    • SIGMAS: SIGMAS - The calculated sigma tensor.
    • sigmas_json: STRING - A JSON string representation of the sigmas list.

Set Sigmas from JSON (🐺)

  • Class: WolfSigmasSet
  • Display Name: Set Sigmas from JSON (🐺)
  • Category: sampling/sigmas_wolf
  • Description: Converts a JSON string representing a list of sigma values into a SIGMAS tensor that can be used by samplers. Useful for manually defining or importing custom sigma schedules.
  • Inputs:
    • sigmas_json: STRING (multiline, default: "[14.61, ..., 0.0]") - A JSON string representing a list of numbers (e.g., [14.615, 8.0, 0.029, 0.0]).
  • Outputs:
    • SIGMAS: SIGMAS - The sigma tensor created from the JSON input.

Wolf Sigmas to JSON

  • Class: WolfSigmasToJSON
  • Display Name: Wolf Sigmas to JSON
  • Category: sampling/sigmas_wolf/util
  • Description: Converts an input SIGMAS object to its JSON string representation. Useful for debugging or exporting sigma schedules.
  • Inputs:
    • sigmas: SIGMAS - The input SIGMAS object.
  • Outputs:
    • sigmas_json: STRING - A JSON string representation of the sigmas list.

Sigma Transformation

Formulas (reference):

  • Power: s_{\mathrm{norm}} = (s - s_{\min})/(s_{\max} - s_{\min}), s_{\mathrm{new}} = s_{\min} + s_{\mathrm{norm}}^{\mathrm{power}}(s_{\max} - s_{\min}).
  • Shift & scale: \sigma_{\mathrm{new}} = (\sigma + \mathrm{shift}) \cdot \mathrm{scale} (final 0 unchanged).
  • Respace log-cosine: t \in [0,1], \mathrm{cos\_t} = 0.5(1 - \cos(\pi t)), \log\sigma = \log\sigma_{\min} + (1 - \mathrm{cos\_t})(\log\sigma_{\max} - \log\sigma_{\min}), \sigma = \exp(\log\sigma).
  • Geometric: \sigma_0 = \sigma_{\mathrm{start}}, \sigma_{i+1} = \sigma_i \cdot r (clamped by \sigma_{\min}), last step 0.
  • Polynomial: t_{\mathrm{norm}} = i/(n-1), \sigma_i = \sigma_{\min} + (\sigma_{\max} - \sigma_{\min})(1 - t_{\mathrm{norm}}^p); last sigma 0.
  • Tanh: t from scale to -\mathrm{scale}, \mathrm{tanh\_vals} = \tanh(t) normalized to [0,1], linearly mapped to [\sigma_{\min}, \sigma_{\max}]; last sigma 0.

Example sigma chain: Get Sigmas → Power Transform → Respace Log-Cosine → use in KSampler (or Set from JSON if you need to round-trip).

flowchart LR
  Model[MODEL] --> Get[Get Sigmas]
  Get --> Power[Power Transform]
  Power --> Respace[Respace Log-Cosine]
  Respace --> KSampler[KSampler]

Wolf Sigma Power Transform

  • Class: WolfSigmaPowerTransform
  • Display Name: Wolf Sigma Power Transform
  • Category: sampling/sigmas_wolf/transform
  • Description: Applies a power transformation to an existing sigma schedule. The active sigmas (excluding a potential final 0.0) are normalized to the range [0,1]. Let s be an active sigma, s_{min} and s_{max} be the min/max of the active range. Normalized sigma: s_{norm} = (s - s_{min}) / (s_{max} - s_{min}). Powered sigma: s_{powered} = s_{norm}^{\text{power}}. Denormalized sigma: s_{new} = s_{min} + s_{powered} \times (s_{max} - s_{min}). power > 1.0: concentrates steps towards the minimum of the schedule range (smaller steps later). power < 1.0: concentrates steps towards the maximum of the schedule range (smaller steps earlier).
  • Inputs:
    • sigmas_in: SIGMAS - The input sigma schedule.
    • power: FLOAT (default: 1.0, min: 0.1, max: 10.0) - The power exponent.
    • override_input_min: FLOAT (default: -1.0) - If >= 0, overrides auto-detected min sigma for normalization.
    • override_input_max: FLOAT (default: -1.0) - If >= 0, overrides auto-detected max sigma for normalization.
  • Outputs:
    • SIGMAS: SIGMAS - The transformed sigma schedule.

Wolf Sigma Transform (Clamp T0)

  • Class: WolfSigmaClampT0
  • Display Name: Wolf Sigma Transform (Clamp T0)
  • Category: sampling/sigmas_wolf/transform
  • Description: Clamps the first sigma (t0) of an incoming schedule to a specified value. Other sigmas are adjusted proportionally if they would exceed t0 or become non-monotonic. The final 0.0 sigma, if present, remains unchanged.
  • Inputs:
    • sigmas_in: SIGMAS - The input sigma schedule.
    • target_t0: FLOAT (default: 1.0, min: 0.0001, max: 1000.0, step: 0.001) - The target value for the first sigma.
    • min_epsilon_spacing: FLOAT (default: 1e-7, min: 1e-9, max: 0.1, step: 1e-7) - Minimum spacing to maintain between sigmas if adjustments are needed.
  • Outputs:
    • SIGMAS: SIGMAS - The transformed sigma schedule with t0 clamped.

Wolf Sigma Transform (Shift & Scale)

  • Class: WolfSigmaShiftAndScale
  • Display Name: Wolf Sigma Transform (Shift & Scale)
  • Category: sampling/sigmas_wolf/transform
  • Description: Applies a global shift and scale to all sigmas in a schedule: Sigmas = (Sigmas + shift) * scale. The final 0.0 sigma, if present, remains unchanged. Monotonicity (decreasing order) and non-negativity are enforced.
  • Inputs:
    • sigmas_in: SIGMAS - The input sigma schedule.
    • shift: FLOAT (default: 0.0, min: -100.0, max: 100.0, step: 0.01) - Value to add to each sigma before scaling.
    • scale: FLOAT (default: 1.0, min: 0.01, max: 100.0, step: 0.01) - Value to multiply each shifted sigma by.
    • min_epsilon_spacing: FLOAT (default: 1e-7, min: 1e-9, max: 0.1, step: 1e-7) - Minimum spacing for monotonicity enforcement.
  • Outputs:
    • SIGMAS: SIGMAS - The transformed sigma schedule.

Wolf Sigma Transform (Normalize Range)

  • Class: WolfSigmaNormalizeRange
  • Display Name: Wolf Sigma Transform (Normalize Range)
  • Category: sampling/sigmas_wolf/transform
  • Description: Normalizes an existing sigma schedule to a new min/max range. The relative spacing of sigmas is preserved as much as possible. The final 0.0 sigma, if present, remains 0.0.
  • Inputs:
    • sigmas_in: SIGMAS - The input sigma schedule.
    • new_max: FLOAT (default: 1.0, min: 0.0001, max: 1000.0, step: 0.001) - The target maximum sigma value (first sigma).
    • new_min_positive: FLOAT (default: 0.002, min: 0.0001, max: 100.0, step: 0.0001) - The target minimum positive sigma value (last active sigma).
    • min_epsilon_spacing: FLOAT (default: 1e-7, min: 1e-9, max: 0.1, step: 1e-7) - Minimum spacing for monotonicity enforcement.
  • Outputs:
    • SIGMAS: SIGMAS - The normalized sigma schedule.

Wolf Sigma Transform (Quantize)

  • Class: WolfSigmaQuantize
  • Display Name: Wolf Sigma Transform (Quantize)
  • Category: sampling/sigmas_wolf/transform
  • Description: Quantizes sigmas in a schedule to a specific number of decimal places or to the nearest multiple of a quantization step. The final 0.0 sigma, if present, remains unchanged.
  • Inputs:
    • sigmas_in: SIGMAS - The input sigma schedule.
    • quantization_method: COMBO["decimal_places", "step_multiple"] (default: "decimal_places") - Method for quantization.
    • decimal_places: INT (default: 3, min: 0, max: 10) - Number of decimal places if method is decimal_places.
    • quantization_step: FLOAT (default: 0.001, min: 1e-7, max: 10.0, step: 0.0001) - Step multiple if method is step_multiple.
    • rounding_mode: COMBO["round", "floor", "ceil"] (default: "round") - Rounding method to use.
    • min_epsilon_spacing: FLOAT (default: 1e-7, min: 1e-9, max: 0.1, step: 1e-7) - Minimum spacing for post-quantization monotonicity enforcement.
  • Outputs:
    • SIGMAS: SIGMAS - The quantized sigma schedule.

Wolf Sigma Transform (Respace Log-Cosine)

  • Class: WolfSigmaRespaceLogCosine
  • Display Name: Wolf Sigma Transform (Respace Log-Cosine)
  • Category: sampling/sigmas_wolf/transform
  • Description: Respaces an existing N-step sigma schedule (N+1 sigmas) to have its active points (sigma_max to sigma_min_positive) follow a cosine curve in the log-sigma domain. The number of steps in the output matches the input. The final 0.0 sigma, if present, remains unchanged.
  • Inputs:
    • sigmas_in: SIGMAS - The input sigma schedule.
    • override_sigma_max: FLOAT (default: -1.0) - If >= 0, overrides auto-detected max sigma for spacing. -1 uses max from sigmas_in.
    • override_sigma_min_positive: FLOAT (default: -1.0) - If >= 0, overrides auto-detected min positive sigma. -1 uses min from sigmas_in.
    • min_epsilon_spacing: FLOAT (default: 1e-7, min: 1e-9, max: 0.1, step: 1e-7) - Minimum spacing for monotonicity enforcement.
  • Outputs:
    • SIGMAS: SIGMAS - The respaced sigma schedule.

Sigma Clip Values (🐺)

  • Class: WolfSigmaClipValues
  • Display Name: Sigma Clip Values (🐺)
  • Category: sampling/sigmas_wolf/transformations
  • Description: Clips individual active sigma values in a schedule to a specified minimum and maximum. The final 0.0 sigma, if present, remains unchanged. Optionally re-ensures strictly decreasing order after clipping.
  • Inputs:
    • sigmas: SIGMAS - The input sigma schedule.
    • min_clip_value: FLOAT (default: 0.001, min: 0.0, max: 1000.0, step: 0.001) - Minimum value to clip sigmas to.
    • max_clip_value: FLOAT (default: 150.0, min: 0.0, max: 1000.0, step: 0.01) - Maximum value to clip sigmas to.
    • ensure_strictly_decreasing: BOOLEAN (default: True) - Whether to enforce strictly decreasing order after clipping.
    • min_epsilon_spacing: FLOAT (default: 1e-5, min: 1e-7, max: 1e-2, step: 1e-7) - Minimum spacing if order is re-enforced.
  • Outputs:
    • SIGMAS: SIGMAS - The sigma schedule with values clipped.

Sigma Schedule Reverser (🐺)

  • Class: WolfSigmaReverse
  • Display Name: Sigma Schedule Reverser (🐺)
  • Category: sampling/sigmas_wolf/transformations
  • Description: Reverses the order of active sigmas in a schedule. The final 0.0 sigma, if present, remains unchanged.
  • Inputs:
    • sigmas: SIGMAS - The input sigma schedule.
  • Outputs:
    • SIGMAS: SIGMAS - The reversed sigma schedule.

Wolf Sigma Reverse and Rescale

  • Class: WolfSigmaReverseAndRescale
  • Display Name: Wolf Sigma Reverse and Rescale
  • Category: sampling/sigmas_wolf/transformations
  • Description: Takes an existing SIGMAS tensor, reverses the order of its active steps, and then rescales them to a new target sigma_max and sigma_min_positive. The last sigma (0.0) remains in place.
  • Inputs:
    • sigmas: SIGMAS - The input sigma schedule.
    • new_sigma_max: FLOAT (default: 1.0, min: 0.01, max: 1000.0, step: 0.1) - The target maximum sigma for the reversed and rescaled schedule.
    • new_sigma_min_positive: FLOAT (default: 0.002, min: 0.0001, max: 10.0, step: 0.0001) - The target minimum positive sigma.
    • min_epsilon_spacing: FLOAT (default: 1e-5, min: 1e-7, max: 1e-2, step: 1e-7) - Minimum spacing for monotonicity enforcement.
  • Outputs:
    • SIGMAS: SIGMAS - The reversed and rescaled sigma schedule.

Sigma Slice (🐺)

  • Class: WolfSigmaSlice
  • Display Name: Sigma Slice (🐺)
  • Category: sampling/sigmas_wolf/transformations
  • Description: Slices an existing sigma schedule, selecting a sub-sequence of active sigmas. The final 0.0 sigma, if present, is re-appended. Optionally re-ensures strictly decreasing order after slicing.
  • Inputs:
    • sigmas: SIGMAS - The input sigma schedule.
    • start_index: INT (default: 0, min: 0, max: 10000) - Start index for slicing active sigmas.
    • end_index: INT (default: -1, min: -1, max: 10000) - End index for slicing active sigmas (-1 means to the end).
    • step_size: INT (default: 1, min: 1, max: 1000) - Step size for slicing.
    • ensure_strictly_decreasing: BOOLEAN (default: True) - Whether to enforce strictly decreasing order after slicing.
    • min_epsilon_spacing: FLOAT (default: 1e-5, min: 1e-7, max: 1e-2, step: 1e-7) - Minimum spacing if order is re-enforced.
  • Outputs:
    • SIGMAS: SIGMAS - The sliced sigma schedule.

Sigma Insert Value (🐺)

  • Class: WolfSigmaInsertValue
  • Display Name: Sigma Insert Value (🐺)
  • Category: sampling/sigmas_wolf/transformations
  • Description: Inserts a custom sigma value into an existing schedule at a specified index. Optionally re-sorts the schedule afterwards to maintain strictly decreasing order and ensures the final 0.0 sigma (if present) remains last.
  • Inputs:
    • sigmas: SIGMAS - The input sigma schedule.
    • sigma_value: FLOAT (default: 1.0, min: 0.0001, max: 1000.0, step: 0.01) - The sigma value to insert.
    • index: INT (default: 0, min: 0, max: 1000) - Index in the active sigmas list where the value should be inserted.
    • sort_after_insert: BOOLEAN (default: True) - Whether to sort the schedule (descending) after insertion.
    • min_epsilon_spacing: FLOAT (default: 1e-5, min: 1e-7, max: 1e-2, step: 1e-7) - Minimum spacing if sorted.
  • Outputs:
    • SIGMAS: SIGMAS - The sigma schedule with the value inserted.

Sigma Add Noise (🐺)

  • Class: WolfSigmaAddNoise
  • Display Name: Sigma Add Noise (🐺)
  • Category: sampling/sigmas_wolf/transformations
  • Description: Adds random noise to an existing sigma schedule. Ensures sigmas remain positive and optionally re-sorts them. The final 0.0 sigma (if present) remains unchanged by noise.
  • Inputs:
    • sigmas: SIGMAS - The input sigma schedule.
    • noise_strength: FLOAT (default: 0.1, min: 0.0, max: 10.0, step: 0.01) - Strength of the noise to add.
    • noise_type: COMBO["gaussian", "uniform"] (default: "gaussian") - Type of noise distribution.
    • seed: INT (default: 0, min: 0, max: 0xFFFFFFFFFFFFFFFF) - Seed for the random noise generation.
    • ensure_strictly_decreasing: BOOLEAN (default: True) - Whether to sort the schedule (descending) and enforce spacing after adding noise.
    • min_epsilon_spacing: FLOAT (default: 1e-5, min: 1e-7, max: 1e-2, step: 1e-7) - Minimum spacing if sorted.
  • Outputs:
    • SIGMAS: SIGMAS - The sigma schedule with noise added.

General Purpose Sigma Generators

These nodes provide flexible ways to generate sigma schedules based on mathematical functions.

Wolf Sigma Geometric Progression

  • Class: WolfSigmaGeometricProgression
  • Display Name: Wolf Sigma Geometric Progression
  • Category: sampling/sigmas_wolf/transformations (Note: Category in code is transformations, seems more like a generator. Using code value.)
  • Description: Generates N_steps + 1 sigmas forming a geometric progression. Each active sigma is the previous one multiplied by a common_ratio. Sigmas are bounded by sigma_start (max) and sigma_min_positive. Last sigma is 0.0.
  • Inputs:
    • num_steps: INT (default: 12, min: 1, max: 1000) - Number of active sigmas to generate.
    • sigma_start: FLOAT (default: 1.0, min: 0.01, max: 1000.0, step: 0.1) - Starting sigma value (sigma_max).
    • sigma_min_positive: FLOAT (default: 0.002, min: 0.0001, max: 10.0, step: 0.0001) - Smallest positive sigma allowed.
    • common_ratio: FLOAT (default: 0.75, min: 0.01, max: 2.0, step: 0.01) - Multiplier for each step. <1 for decreasing sigmas.
    • min_epsilon_spacing: FLOAT (default: 1e-5, min: 1e-7, max: 1e-2, step: 1e-7) - Minimum spacing.
  • Outputs:
    • SIGMAS: SIGMAS - Tensor with N+1 geometrically spaced sigmas.

Wolf Sigma Polynomial

  • Class: WolfSigmaPolynomial
  • Display Name: Wolf Sigma Polynomial
  • Category: sampling/sigmas_wolf/transformations (Note: Category in code is transformations, seems more like a generator. Using code value.)
  • Description: Generates N_steps + 1 sigmas based on a polynomial function of normalized time: sigma = sigma_min_positive + (sigma_max - sigma_min_positive) * (1 - t_norm^power). Last sigma is 0.0.
  • Inputs:
    • num_steps: INT (default: 12, min: 1, max: 1000) - Number of active sigmas.
    • sigma_max: FLOAT (default: 1.0, min: 0.01, max: 1000.0, step: 0.1) - Maximum sigma.
    • sigma_min_positive: FLOAT (default: 0.002, min: 0.0001, max: 10.0, step: 0.0001) - Smallest positive sigma.
    • power: FLOAT (default: 1.0, min: 0.1, max: 10.0, step: 0.05) - Power for the polynomial. 1.0=linear, >1.0 denser near sigma_max, <1.0 denser near sigma_min_positive.
    • min_epsilon_spacing: FLOAT (default: 1e-5, min: 1e-7, max: 1e-2, step: 1e-7) - Minimum spacing.
  • Outputs:
    • SIGMAS: SIGMAS - Tensor with N+1 polynomially spaced sigmas.

Sigma Tanh Generator (🐺)

  • Class: WolfSigmaTanhGenerator
  • Display Name: Sigma Tanh Generator (🐺)
  • Category: sampling/sigmas_wolf/generate
  • Description: Generates N_steps + 1 sigmas based on a scaled and shifted tanh function of normalized time. Sigmas range from sigma_max to sigma_min_positive. The tanh function provides an S-shaped curve. Last sigma is 0.0.
  • Inputs:
    • num_steps: INT (default: 12, min: 1, max: 1000) - Number of active sigmas.
    • sigma_max: FLOAT (default: 1.0, min: 0.01, max: 1000.0, step: 0.1) - Maximum sigma.
    • sigma_min_positive: FLOAT (default: 0.002, min: 0.0001, max: 10.0, step: 0.0001) - Smallest positive sigma.
    • tanh_scale: FLOAT (default: 3.0, min: 0.1, max: 10.0, step: 0.1) - Scales the input to tanh, controlling steepness. Higher values = steeper.
    • min_epsilon_spacing: FLOAT (default: 1e-5, min: 1e-7, max: 1e-2, step: 1e-7) - Minimum spacing.
  • Outputs:
    • SIGMAS: SIGMAS - Tensor with N+1 tanh-spaced sigmas.

Model Inspection API and Usage (WolfSigmas)

This section documents the model inspection nodes provided in this package, how to use them, expected inputs/outputs, and troubleshooting steps for common failure modes (missing forward, dict outputs from hooks, black images). It also includes small mermaid workflow diagrams illustrating common setups.

Nodes covered

  • Wolf Model Structure Explorer (helper): enumerate module paths, types, parameters; use to copy exact layer_name for hooks.
  • Wolf Model Activation Inspector (🐺): attach hooks, capture activations, convert to a ComfyUI IMAGE.
  • Wolf Model Depatchify (🐺): dedicated node to convert patch/token activations into pixel-like images (tiles, upsampling, projection).
  • Wolf Model Key Inspector: lists state_dict keys and parameter shapes for debugging parameter-based inspection.

Important quick notes

  • Always pass the same MODEL output from ComfyUI to the Structure Explorer and Inspector nodes to ensure path resolution is consistent.
  • Use the Structure Explorer first to obtain exact module names for layer_name. The inspector accepts endswith fallback but the exact path is more reliable.
  • Activation Inspector returns two outputs:
    • IMAGE: torch tensor [1, H, W, 3], dtype float32, values in range [0,1].
    • STRING (JSON): diagnostic metadata including which executor was used, captured key, activation shape and basic statistics (min, max, mean, std), and method used for depatchifying/visualizing.
  • If the JSON activation_info contains "error", use its available_methods_sample and available_attrs_sample fields (if present) to guide which executor to try next.

Execution/Executor strategies (inspector executor input)

  • auto (default): prefer wrapper apply_model if present (this integrates with ComfyUI patcher), then falls back to model.model.apply_model, traversal.apply_model, then direct forward-like calls on the traversal module (forward, _forward, forward_orig, etc.).
  • apply_model: force explicit use of apply_model on the wrapper/inner wrapper. Use when your MODEL exposes apply_model (ComfyUI models often do).
  • direct_forward: attempt to call forward-like methods on the traversal module directly. Use only when you know the inner module exposes standard forward entrypoints.

What the inspector collects (activation_info keys)

  • executor: which executor path was used (e.g. "apply_model", "traversal.apply_model", "forward", etc.)
  • captured_key: the module name resolved in the traversal where activation was captured
  • orig_shape: original activation shape (tuple)
  • activation_stats: object with min, max, mean, std, nan_count, inf_count, dtype — helps diagnose black/constant images
  • method: which conversion was used (e.g., tokens_to_grid, spatial_direct_project, heatmap_fallback)
  • token_grid/patch_grid/patch_size_used: details used for depatchification if applicable
  • error: present when something failed; may include available_methods_sample and available_attrs_sample for the traversal module

Typical workflows

  1. Inspect a block activation and visualize as image (recommended)
  • Connect MODEL -> Wolf Model Structure Explorer to locate the exact module path (copy it)
  • Connect MODEL, layer_name (copied path), and input_latent (LATENT) -> Wolf Model Activation Inspector (executor: auto or apply_model)
  • Inspect activation_info JSON; if stats indicate near-zero range (min == max), choose per-channel visualization or try a different layer.

```mermaid` flowchart TD A[ComfyUI MODEL output] --> B[Wolf Model Structure Explorer] B --> C{Copy exact module path} A --> D[Wolf Model Activation Inspector] D -->|layer_name| C D --> E[Activation Image (IMAGE)] D --> F[Activation Info (STRING JSON)] click B "#" click D "#"


2) Capture tokens and depatchify to pixels
- If a captured activation is token-shaped `(B, L, C)`, the `depatchify` logic will:
  - Attempt to reshape tokens into a grid `(B, gh, gw, C)` (prefer square or nearest factorization).
  - Project channels to RGB using `model.latent_rgb_factors` if present, otherwise PCA-lite or channel selection.
  - Upsample patches by detected `patch_size` (or `1` as fallback) to produce pixel-sized image.
- If reshape fails (e.g., token count not factorizable), the inspector will fall back to a heatmap matrix visualization and include `tokens_error` in `activation_info`.

```mermaid
flowchart LR
  A[Captured Activation] --> B{Shape check}
  B --> |B,L,C tokens| C[Token -> Grid reshape]
  C --> D[Project channels -> RGB]
  D --> E[Upsample patches by patch_size]
  E --> F[IMAGE out]
  B --> |B,C,H,W spatial| G[Spatial channel projection]
  G --> F
  B --> |Other| H[Heatmap fallback]
  H --> F

Practical tips for diagnosing the two errors you reported

  • Error: {"error": "Error inspecting activations: Module [Flux2] is missing the required "forward" function"}
    • Diagnosis:
      • The traversal module returned by get_traversal_module(model) may be a Flux2 wrapper that doesn't implement a typical .forward but expects apply_model on the outer wrapper.
    • Fix:
      • Use Wolf Model Structure Explorer on the same MODEL object to confirm the wrapper exposes apply_model. If it does, set inspector executor to apply_model.
      • If apply_model is not present on the object you passed, pass the outer wrapper (the actual ComfyUI MODEL output) rather than the inner module. The inspector's auto mode should prefer apply_model when the wrapper is passed.
      • If you still see missing-forward diagnostics, paste the activation_info JSON available_methods_sample and available_attrs_sample and I will recommend a precise executor path or add a small special-case call.
  • Error: {"error": "Error depatchifying: 'dict' object has no attribute 'ndim'"} (or "'dict' object has no attribute 'ndim'"/black image)
    • Root cause:
      • Some modules return a dict-like output rather than a raw Tensor. Earlier hook implementations could store the raw dict into collector.activations, and downstream depatchify/visualization code attempted to treat it as a Tensor.
    • Fix (already implemented in utilities):
      • HookCollector now attempts to extract the best tensor candidate from dict/list/tuple outputs (sample, samples, out, hidden_states, x, etc.) before storing activations.
      • If no tensor is found, the hook stores a lightweight diagnostic (a dict of shapes/types) and the inspector returns an informative error JSON rather than crashing.
    • How to use:
      • Re-run the inspector (after selecting exact layer_name from the Structure Explorer). Check activation_info — if you see a dict diagnostic, inspect its keys to know which element actually contains tensors and update layer_name accordingly (or provide a slice_expr to target a field if your node supports parameter attribute capture).

Examples (copy-and-run patterns)

  • Exact module activation visualization (recommended)

    • Use Wolf Model Structure Explorer -> copy diffusion_model.double_blocks.3.img_norm1
    • Plugin into inspector:
      • layer_name: diffusion_model.double_blocks.3.img_norm1 (or the exact path shown)
      • executor: auto (if the MODEL wrapper exposes apply_model) else direct_forward only if you know the inner traversal exposes forward.
      • input_latent: connect a latent (from VAE or initial seed)
    • Inspect activation_info. If activation_info.activation_stats.max - activation_info.activation_stats.min < 1e-8 then the visualization will be essentially constant/black — try another layer or enable per-channel visualization (future feature) or increase instrumentation.
  • Parameter/weight visualization

    • Provide layer_name pointing to a parameter path (e.g., diffusion_model.xxx.proj.weight[0:64,0:64]).
    • The inspector will coerce the parameter to a tensor, optionally apply the slice_expr, and visualize the slice as a matrix image with statistics in activation_info.

Advanced notes (for maintainers)

  • Use Wolf Model Structure Explorer output to build stable UI elements (dropdowns) if you want to make layer_name selection easier in the ComfyUI interface.
  • The utilities provide safe_as_tensor which aggressively coerces numpy-object arrays, nested lists, and lazy parameter placeholders into Tensor objects — prefer using that when handling arbitrary framework outputs.

Appendix: Example activation_info (informative) { "executor": "apply_model", "captured_key": "diffusion_model.double_blocks.3.img_norm1", "orig_shape": [1, 512, 64, 64], "activation_stats": {"min": -0.0023, "max": 0.003, "mean": -2.1e-05, "std": 0.0009, "nan_count": 0, "inf_count": 0, "dtype": "float32"}, "method": "spatial_direct_project", "img_stats": {"min": 0.0, "max": 1.0, "mean": 0.45, "std": 0.12} }

If you want me to proceed

  • Option A (recommended): Run Wolf Model Structure Explorer on the exact MODEL used in the failing flow and paste the top ~40 lines of its JSON output (module names and types) here. I'll:
    • Pick the exact layer_name to hook,
    • Recommend the precise executor option,
    • If necessary, add a tiny special-case call for Flux2 wrappers so hooks always fire.
  • Option B: Re-run the Inspector with executor="apply_model" and attach the returned activation_info JSON — I'll interpret it and suggest next debugging steps.

Closing summary

  • I added this Model Inspection API and usage guide to the README describing node inputs/outputs, executor strategies, diagnostics to expect in activation_info, and mermaid workflow diagrams to clarify typical flows.
  • Next steps I can take for you: pick Option A or B above and I'll continue debugging the Flux2 forward/apply integration and the depatchify fallbacks.