# How to Use Composable Diffusion in AUTOMATIC1111: Mastering the AND Syntax for Multi-Prompt Generation

> Learn Composable Diffusion in AUTOMATIC1111 using the AND syntax to combine independent text prompts for multi prompt image generation. Control results with optional weights.

- Repository: [AUTOMATIC1111/stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui)
- Tags: how-to-guide
- Published: 2026-02-24

---

**Composable Diffusion allows you to condition a single image generation on multiple independent text prompts by separating them with the `AND` keyword, with optional per-prompt weights specified via `:weight` syntax.**

Composable Diffusion is a core feature of the AUTOMATIC1111/stable-diffusion-webui that enables complex image synthesis by treating each `AND`-separated clause as an independent conditioning tensor. Instead of merging concepts into a single prompt embedding, the system computes separate embeddings for each sub-prompt and combines them through weighted summation during the diffusion sampling loop. This architecture is implemented primarily in [`modules/prompt_parser.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/prompt_parser.py) and integrated into the sampling pipeline through [`modules/sd_samplers_cfg_denoiser.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/sd_samplers_cfg_denoiser.py).

## What is Composable Diffusion?

Composable Diffusion refers to the method of constructing a final conditioning vector by linearly combining multiple independent prompt conditionings. In the AUTOMATIC1111 implementation, each sub-prompt separated by `AND` is parsed, encoded by the text encoder, and stored as a `ComposableScheduledPromptConditioning` object. During sampling, these are assembled into a `MulticondLearnedConditioning` batch, where the sampler applies user-specified weights and sums the tensors before feeding them to the UNet.

## The Internal Pipeline: How AND Syntax is Parsed

The parsing pipeline resides in [`modules/prompt_parser.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/prompt_parser.py) and executes the following sequence:

**Step 1: Detection**
The regex `re_AND = re.compile(r"\bAND\b")` splits the user prompt on the literal word `AND` at line 205.

**Step 2: Weight Extraction**
Each sub-prompt can carry a `:weight` suffix. The regex `re_weight` extracts the text and numeric weight (defaulting to 1.0) at lines 206-207.

**Step 3: Flat List Construction**
The function `get_multicond_prompt_list` (lines 209-237) creates three critical data structures:
- `prompt_flat_list`: unique prompt strings
- `res_indexes`: per-prompt lists of `(index, weight)` tuples
- `prompt_indexes`: a lookup mapping

**Step 4: Conditioning Schedule Generation**
`get_learned_conditioning` produces a list of `ScheduledPromptConditioning` objects for every unique prompt in the flat list.

**Step 5: Weight Wrapping**
`ComposableScheduledPromptConditioning` stores each schedule alongside its user-specified weight (lines 240-244).

**Step 6: Batch Assembly**
`get_multicond_learned_conditioning` (lines 252-267) assembles a `MulticondLearnedConditioning` object whose `batch` field contains a list-of-lists: one outer list per full prompt, inner lists per sub-prompt.

**Step 7: Step-wise Reconstruction**
During sampling, `reconstruct_multicond_batch` (lines 221-240) iterates through sub-prompts, selects the appropriate schedule entry for the current diffusion step, stacks the tensors, and records `(tensor_index, weight)` pairs.

**Step 8: Weighted Summation**
The sampler receives the stacked tensor and weight list, multiplies each conditioning by its weight, and sums them to produce the final composed conditioning fed to the UNet.

## Using Composable Diffusion in Practice

### Basic Prompt Syntax in the Web UI

Open **txt2img** or **img2img** and enter:

```text
a cat :1.2 AND a dog AND a penguin :2.2

```

- `a cat` receives weight **1.2**
- `a dog` uses the default weight **1.0**
- `a penguin` receives weight **2.2**

The UI processes this single line as three independent conditioning streams internally.

### Programmatic API Usage

To leverage Composable Diffusion programmatically:

```python
from modules import prompt_parser, shared

# Reference to the loaded diffusion model

model = shared.sd_model
prompts = ["a cat :1.2 AND a dog AND a penguin :2.2"]
steps = 50

# Build the composable conditioning object

cond = prompt_parser.get_multicond_learned_conditioning(
    model, prompts, steps, hires_steps=None, use_old_scheduling=False
)

# Inspect the structure

print(cond.shape)          # (1,)

print(len(cond.batch))     # 1 outer list (one full prompt)

print(len(cond.batch[0]))  # 3 inner items (three sub-prompts)

```

### Sampler Integration Details

Inside the diffusion loop, the sampler calls:

```python

# Reconstruct batch for current step

conds_list, stacked = prompt_parser.reconstruct_multicond_batch(cond, current_step)

# conds_list contains: [(0, 1.2), (1, 1.0), (2, 2.2)]

# stacked tensor shape: (3, C, H, W)

# The sampler computes the weighted combination

combined_conditioning = sum(w * stacked[i] for i, w in conds_list)

```

This `combined_conditioning` is what the UNet receives to predict noise during that sampling step.

## Summary

- **Composable Diffusion** enables multi-prompt generation by splitting on the `AND` keyword in AUTOMATIC1111.
- The parser in [`modules/prompt_parser.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/prompt_parser.py) handles splitting, weight extraction, and batch construction via `get_multicond_learned_conditioning`.
- Each sub-prompt becomes a separate conditioning tensor wrapped in `ComposableScheduledPromptConditioning`.
- `reconstruct_multicond_batch` manages the per-step assembly and stacking of tensors during sampling.
- Weights are applied as a linear combination before the UNet forward pass, allowing precise control over multiple concepts.

## Frequently Asked Questions

### What is the difference between AND syntax and attention brackets?

Attention brackets `(prompt:weight)` modify the emphasis of specific tokens within a single conditioning vector, while `AND` creates entirely separate conditioning tensors that are summed together. Use `AND` when you want distinct conceptual regions or separate objects, and use attention brackets for adjusting emphasis within a single concept.

### Can I use negative weights with the AND syntax?

Yes, you can specify negative weights such as `night :-1.0 AND day :1.0` to subtract concepts from the generation. The weighted summation logic in `reconstruct_multicond_batch` correctly handles negative values, reducing the influence of that conditioning vector during the diffusion process.

### Does Composable Diffusion work with all samplers?

Composable Diffusion is compatible with most standard samplers in AUTOMATIC1111, as implemented in [`modules/sd_samplers_cfg_denoiser.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/sd_samplers_cfg_denoiser.py). However, some specialized samplers may have specific limitations regarding batch composition. The feature operates at the conditioning level, making it broadly supported across the sampling ecosystem.

### How does performance compare to single-prompt generation?

Using `AND` syntax requires computing text embeddings for each sub-prompt separately, increasing memory usage proportionally to the number of `AND` clauses. However, the actual diffusion sampling speed remains comparable because the weighted summation occurs after text encoding, and the UNet processes only the final combined conditioning vector rather than multiple separate batches.