Table of Contents
- ScriptableEmptyLatent Node
- Overview
- What is an Empty Latent?
- Inputs
- Outputs
- Default Script
- How the Default Script Works
- Available Variables
- Example: Empty Latent (Default)
- Example: Small Random Noise Latent
- Example: Latent with Specific Pattern
- Example: Conditional Empty Latent
- Example: Batch with Different Patterns
- Comparison with ScriptableLatent
- Common Patterns
- Pattern 1: Pure Zero Latent
- Pattern 2: Reproducible Random Latent
- Pattern 3: Structured Starting Point
- Error Handling
- When to Use ScriptableEmptyLatent vs ScriptableLatent
- Security Considerations
- Related Nodes
ScriptableEmptyLatent Node
Overview
The ScriptableEmptyLatent node allows you to write Python scripts that generate empty latents for diffusion models. It is nearly identical to ScriptableLatent, with the same purpose and functionality. The distinction is mostly organizational - ScriptableEmptyLatent is specifically for creating empty (zero or near-zero) latents as a starting point for generation.
What is an Empty Latent?
An empty latent is a latent representation filled with zeros (or small random values). This serves as a blank canvas for the diffusion process. When you start with an empty latent and apply the diffusion reverse process, the model generates an image from pure noise.
Think of it like a blank piece of paper:
- Empty latent = blank paper
- Diffusion process = drawing on the paper
- Final result = a complete image
Inputs
| Parameter | Type | Default | Range | Description |
|---|---|---|---|---|
| width | INT | 512 | 64-8192 | Width of the latent in pixels |
| height | INT | 512 | 64-8192 | Height of the latent in pixels |
| batch_size | INT | 1 | 1-64 | Number of latents to generate (for batching) |
| seed | INT | 0 | 0-4294967295 | Random seed for reproducibility |
| enable_io_helpers | BOOLEAN | False | - | Enable file I/O helper functions |
| script | STRING | (see below) | - | Python script to execute |
Outputs
- latent: A dictionary with key
"samples"containing a tensor of shape[batch_size, 4, height, width]with dtypefloat32
Default Script
# Scriptable Empty Latent: set 'output_latent' (dict with 'samples' tensor [B,C,H,W]).
# Injected: width, height, batch_size, seed, torch, np.
# Example - empty latent:
# output_latent = {'samples': torch.zeros((batch_size, 4, height, width), dtype=torch.float32)}
output_latent = {'samples': torch.zeros((batch_size, 4, height, width), dtype=torch.float32)}
How the Default Script Works
output_latent = {'samples': torch.zeros((batch_size, 4, height, width), dtype=torch.float32)}
torch.zeros(): Creates a tensor filled with zeros(batch_size, 4, height, width): The shape of the tensorbatch_size: Number of latents in the batch4: Number of channels (standard for stable diffusion)height: Height of the latentwidth: Width of the latent
dtype=torch.float32: Uses 32-bit floating point numbers{'samples': ...}: Wraps the tensor in a dictionary with the key"samples"(ComfyUI's expected format)
This creates a completely empty (zero) latent.
Available Variables
Your script has access to these variables:
width(int): The width parameterheight(int): The height parameterbatch_size(int): The batch_size parameterseed(int): The seed parametertorch: The PyTorch librarynp: The NumPy library
If enable_io_helpers is True, you also get:
get_output_dir(): Returns ComfyUI's output directory pathget_input_dir(): Returns ComfyUI's input directory pathget_temp_dir(): Returns ComfyUI's temporary directory path
Example: Empty Latent (Default)
output_latent = {'samples': torch.zeros((batch_size, 4, height, width), dtype=torch.float32)}
This is the default behavior - creates a completely zero latent.
Example: Small Random Noise Latent
import torch
# Create a latent with very small random noise
torch.manual_seed(seed)
noise = torch.randn(batch_size, 4, height, width) * 0.01
output_latent = {'samples': noise}
Explanation:
torch.randn(): Generates random numbers from normal distribution* 0.01: Scales to very small values (standard deviation 0.01)- This creates a nearly-empty latent with tiny variations
- Sometimes used instead of pure zeros for numerical stability
Example: Latent with Specific Pattern
import torch
# Create a latent with a specific pattern (e.g., gradient)
x_coords = torch.linspace(-1, 1, width).view(1, 1, 1, width)
gradient = x_coords.expand(batch_size, 4, height, width)
output_latent = {'samples': gradient}
Explanation:
- Creates a horizontal gradient in the latent
- Values range from -1 to 1
- This can influence the generation process
- The diffusion model will start from this pattern instead of pure noise
Example: Conditional Empty Latent
import torch
# Create different empty latents based on seed
torch.manual_seed(seed)
# Use seed to determine a simple pattern
pattern_type = seed % 3
if pattern_type == 0:
# Pure zero
latent = torch.zeros(batch_size, 4, height, width)
elif pattern_type == 1:
# Small noise
latent = torch.randn(batch_size, 4, height, width) * 0.01
else:
# Gradient
x_coords = torch.linspace(-1, 1, width).view(1, 1, 1, width)
latent = x_coords.expand(batch_size, 4, height, width)
output_latent = {'samples': latent}
Explanation:
- Uses seed to determine which pattern to create
- Three different patterns based on seed modulo 3
- This allows for variation while still being deterministic
Example: Batch with Different Patterns
import torch
# Create a batch where each item has a different pattern
batch_latents = []
for i in range(batch_size):
# Each batch item gets a different pattern based on its index
pattern_type = i % 3
if pattern_type == 0:
latent = torch.zeros(4, height, width)
elif pattern_type == 1:
latent = torch.randn(4, height, width) * 0.01
else:
x_coords = torch.linspace(-1, 1, width).view(1, 1, width)
latent = x_coords.expand(4, height, width)
batch_latents.append(latent)
# Stack into batch tensor
output_latent = {'samples': torch.stack(batch_latents, dim=0)}
Explanation:
- Creates different patterns for each batch item
- Cycles through three patterns based on index
- Result: batch with varied starting conditions
Comparison with ScriptableLatent
ScriptableEmptyLatent and ScriptableLatent are nearly identical:
Similarities:
- Same inputs (width, height, batch_size, seed, script)
- Same output format (latent dictionary)
- Same available variables (torch, np, etc.)
- Same error handling
Differences:
- ScriptableEmptyLatent is specifically for empty/near-empty latents
- ScriptableLatent can be used for any latent generation
- The distinction is organizational/conventional
In practice, you can use either for the same purpose. ScriptableEmptyLatent exists to make workflows clearer when you're specifically creating empty latents.
Common Patterns
Pattern 1: Pure Zero Latent
output_latent = {'samples': torch.zeros((batch_size, 4, height, width), dtype=torch.float32)}
The most common use case - a completely blank starting point.
Pattern 2: Reproducible Random Latent
import torch
torch.manual_seed(seed)
noise = torch.randn(batch_size, 4, height, width) * 0.02
output_latent = {'samples': noise}
Reproducible small noise for consistent starting conditions.
Pattern 3: Structured Starting Point
import torch
# Create a radial gradient as starting point
y_coords = torch.linspace(-1, 1, height)
x_coords = torch.linspace(-1, 1, width)
Y, X = torch.meshgrid(y_coords, x_coords, indexing='ij')
distance = torch.sqrt(X**2 + Y**2)
gradient = 1 - distance
gradient = torch.clamp(gradient, 0, 1)
# Expand to latent shape
latent = gradient.unsqueeze(0).unsqueeze(0).expand(batch_size, 4, height, width)
output_latent = {'samples': latent}
Creates a structured starting point that can influence generation.
Error Handling
The node includes error handling:
- If the script fails to execute, it returns a zero latent
- If the script doesn't set
output_latent, it returns a zero latent - If the output format is invalid, it returns a zero latent
This ensures your workflow won't crash if there's a script error.
When to Use ScriptableEmptyLatent vs ScriptableLatent
Use ScriptableEmptyLatent when:
- You want to create empty/near-empty latents
- You want to make your workflow intent clear
- You're starting generation from scratch
Use ScriptableLatent when:
- You want to generate arbitrary latents
- You might create non-empty latents
- You want more flexibility
In practice, both nodes can do the same thing. The choice is about workflow clarity and organization.
Security Considerations
This node uses exec() to run your script. This is intentionally powerful for local development but should not be used in production or exposed to untrusted users.
Related Nodes
- ScriptableLatent: Nearly identical node for general latent generation
- Empty Latent Image: ComfyUI's built-in empty latent node
- KSampler: Sampler that uses latents for generation