lllyasviel/Fooocus · error · RuntimeError

Not enough memory, use lower resolution (max approx. {max_re

Error message

Not enough memory, use lower resolution (max approx. {max_res}x{max_res}). Need: {mem_required/64/gb:0.1f}GB free, Have:{mem_free_total/gb:0.1f}GB free

What it means

Raised inside the sliced attention forward (pytorch_attention) when computing attention would need more than 64 slice steps to fit in free VRAM/RAI memory. The code estimates the output tensor size (modifier 3), computes a power-of-two step count against currently free memory (cuda free + torch cached), and if steps > 64 it gives up and reports the largest approx. square resolution the free memory could support. It is a hard out-of-memory guard for cross/self-attention in the diffusion UNet, not a generic torch OOM.

Source

Thrown at ldm_patched/ldm/modules/attention.py:223

        element_size = 4
    else:
        element_size = q.element_size()

    gb = 1024 ** 3
    tensor_size = q.shape[0] * q.shape[1] * k.shape[1] * element_size
    modifier = 3
    mem_required = tensor_size * modifier
    steps = 1


    if mem_required > mem_free_total:
        steps = 2**(math.ceil(math.log(mem_required / mem_free_total, 2)))
        # print(f"Expected tensor size:{tensor_size/gb:0.1f}GB, cuda free:{mem_free_cuda/gb:0.1f}GB "
        #      f"torch free:{mem_free_torch/gb:0.1f} total:{mem_free_total/gb:0.1f} steps:{steps}")

    if steps > 64:
        max_res = math.floor(math.sqrt(math.sqrt(mem_free_total / 2.5)) / 8) * 64
        raise RuntimeError(f'Not enough memory, use lower resolution (max approx. {max_res}x{max_res}). '
                            f'Need: {mem_required/64/gb:0.1f}GB free, Have:{mem_free_total/gb:0.1f}GB free')

    # print("steps", steps, mem_required, mem_free_total, modifier, q.element_size(), tensor_size)
    first_op_done = False
    cleared_cache = False
    while True:
        try:
            slice_size = q.shape[1] // steps if (q.shape[1] % steps) == 0 else q.shape[1]
            for i in range(0, q.shape[1], slice_size):
                end = i + slice_size
                if _ATTN_PRECISION =="fp32":
                    with torch.autocast(enabled=False, device_type = 'cuda'):
                        s1 = einsum('b i d, b j d -> b i j', q[:, i:end].float(), k.float()) * scale
                else:
                    s1 = einsum('b i d, b j d -> b i j', q[:, i:end], k) * scale

                if mask is not None:
                    if len(mask.shape) == 2:

View on GitHub (pinned to ae05379cc9)

Solutions

  1. Lower the output resolution to at or below the max_res value printed in the message, then retry
  2. Free VRAM: close other GPU processes/tabs, then restart the app (clears torch cache fragmentation)
  3. Pick a lighter performance mode (Fooocus: Performance -> Llama/Lightning or use 'Low VRAM' style preset; CLI: --lowvram / --novram) so less memory is held by weights
  4. Reduce upscaling multiplier or upscale in two passes instead of one huge pass
  5. If it persists on spec hardware, update GPU drivers / use a smaller checkpoint variant

Example fix

// before
shared.job_prepare()  // generating at 3072x3072 on 8GB -> RuntimeError: Not enough memory
// after
// lower resolution to the suggested max_res, e.g.:
shared.results = process(resolution=1536)  // within printed max approx. 1536x1536
Defensive patterns

Strategy: validation

Validate before calling

import torch, math

def max_safe_attention_res(q_len_hint=None):
    gb = 1024 ** 3
    free_cuda, _ = torch.cuda.mem_get_info()
    free_torch = torch.cuda.memory_reserved() - torch.cuda.memory_allocated()
    mem_free_total = free_cuda + free_torch
    return math.floor(math.sqrt(math.sqrt(mem_free_total / 2.5)) / 8) * 64

res = max_safe_attention_res()
if my_target_res > res:
    my_target_res = res  # clamp instead of crashing

Try / catch

try:
    out = model(x)
except RuntimeError as e:
    if 'Not enough memory' in str(e):
        # message contains the max supported square resolution - parse and retry
        import re
        m = re.search(r'max approx\. (\d+)x', str(e))
        if m:
            target = int(m.group(1))
            retry_with_resolution(min(target, current_res))
        else:
            raise
    else:
        raise

Prevention

When it happens

Trigger: Running SDXL/SD generation or upscaling at a resolution whose attention matrices (q.shape[1] tokens x dim) exceed free GPU memory by more than 64x. Typical: 2048px+ base generation on 6-8GB GPUs, extreme hires/img2img scales, or when another process (or an unclosed previous model) holds most VRAM. Also triggered in lowvram mode where mem_free_total is small after offloading other models.

Common situations: Fooocus 'Performance' set to Speed with very high resolution presets; running two UIs/tabs sharing one GPU; VRAM fragmented by earlier long sessions (torch cache not freed); using --always-gpu on cards near the minimum spec; upscaling with a 4x model on top of an already large image.

Related errors


AI-assisted analysis of lllyasviel/Fooocus@ae05379cc9 (2026-08-15). Data as JSON: /api/errors/4d28172293ad8ad7. Report an issue: GitHub.