{"record":{"id":"f7e9ec2db40adb69","repo":"AUTOMATIC1111/stable-diffusion-webui","slug":"not-enough-memory-use-lower-resolution-max-appro","errorCode":null,"errorMessage":"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","messagePattern":"Not enough memory, use lower resolution \\(max approx\\. (.+?)x(.+?)\\)\\. Need: (.+?)GB free, Have:(.+?)GB free","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"modules/sd_hijack_optimizations.py","lineNumber":260,"sourceCode":"\r\n        r1 = torch.zeros(q.shape[0], q.shape[1], v.shape[2], device=q.device, dtype=q.dtype)\r\n\r\n        mem_free_total = get_available_vram()\r\n\r\n        gb = 1024 ** 3\r\n        tensor_size = q.shape[0] * q.shape[1] * k.shape[1] * q.element_size()\r\n        modifier = 3 if q.element_size() == 2 else 2.5\r\n        mem_required = tensor_size * modifier\r\n        steps = 1\r\n\r\n        if mem_required > mem_free_total:\r\n            steps = 2 ** (math.ceil(math.log(mem_required / mem_free_total, 2)))\r\n            # print(f\"Expected tensor size:{tensor_size/gb:0.1f}GB, cuda free:{mem_free_cuda/gb:0.1f}GB \"\r\n            #       f\"torch free:{mem_free_torch/gb:0.1f} total:{mem_free_total/gb:0.1f} steps:{steps}\")\r\n\r\n        if steps > 64:\r\n            max_res = math.floor(math.sqrt(math.sqrt(mem_free_total / 2.5)) / 8) * 64\r\n            raise RuntimeError(f'Not enough memory, use lower resolution (max approx. {max_res}x{max_res}). '\r\n                               f'Need: {mem_required / 64 / gb:0.1f}GB free, Have:{mem_free_total / gb:0.1f}GB free')\r\n\r\n        slice_size = q.shape[1] // steps\r\n        for i in range(0, q.shape[1], slice_size):\r\n            end = min(i + slice_size, q.shape[1])\r\n            s1 = einsum('b i d, b j d -> b i j', q[:, i:end], k)\r\n\r\n            s2 = s1.softmax(dim=-1, dtype=q.dtype)\r\n            del s1\r\n\r\n            r1[:, i:end] = einsum('b i j, b j d -> b i d', s2, v)\r\n            del s2\r\n\r\n        del q, k, v\r\n\r\n    r1 = r1.to(dtype)\r\n\r\n    r2 = rearrange(r1, '(b h) n d -> b n (h d)', h=h)\r","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/82a973c04367123ae98bd9abdf80d9eda9b910e2/modules/sd_hijack_optimizations.py#L242-L278","documentation":"Raised from the memory-efficient cross-attention implementation in sd_hijack_optimizations.py. It splits the attention einsum into slices when the required tensor (q*k sizes times a 2.5-3x modifier) exceeds free VRAM; if more than 64 slices would still be needed, it computes the maximum feasible resolution from free memory and aborts. It is effectively an out-of-memory pre-check for the attention layer, not a CUDA OOM.","triggerScenarios":"Generating at a resolution whose attention tensor needs mem_required such that 2**ceil(log2(mem_required/mem_free_total)) > 64 — i.e. the batch-size-times-resolution product is far larger than current free GPU memory (e.g. 2048x2048 on an 8GB card with other models resident in VRAM).","commonSituations":"High-res txt2img or img2img on low-VRAM GPUs; VRAM already consumed by the VAE, TAESD, or a previous generation not freed; running with --use-cpu all disabled and no attention optimization (--xformers / sdp) active.","solutions":["Lower the generation resolution to the max_res suggested in the message (or below it)","Enable a cheaper attention backend: launch with --xformers or set attention optimization to SDPA in Settings > Optimizations","Free VRAM: restart the WebUI or use --lowvram so model weights are offloaded and more memory stays free for activations","Reduce batch count/batch size so the q/k tensor shrinks"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"import math, torch\ndef estimate_max_res(modifier=2.5, elem_bytes=4):\n    free = torch.cuda.mem_get_info()[0] if torch.cuda.is_available() else 32 * 1024**3\n    # attention tensor ~ (res/8)^2 * (res/8) * batch * elem * 2 (q and k) -> conservative cube-root estimate\n    return int(math.floor(math.sqrt(math.sqrt(free / modifier)) / 8) * 64)","typeGuard":null,"tryCatchPattern":"try:\n    processing.run(p)\nexcept RuntimeError as e:\n    if 'Not enough memory' in str(e):\n        p.width = p.height = min(p.width, suggested_max_res)\n        processing.run(p)\n    else:\n        raise","preventionTips":["Run with --xformers or SDPA attention to shrink the attention memory multiplier","Use --lowvram on cards under 8 GB when generating above 1024x1024","Scale resolution up gradually (hires fix from a 512-768 base) instead of one huge pass"],"tags":["gpu","vram","attention","out-of-memory","optimization"],"backgroundTag":null,"analyzedSha":"82a973c04367123ae98bd9abdf80d9eda9b910e2","analyzedAt":"2026-08-14T16:46:43.225Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}