stable-diffusion-webui icon indicating copy to clipboard operation
stable-diffusion-webui copied to clipboard

[Bug]: Images left in a temp folder C:\Users\username\AppData\Local\Temp

Open 4lt3r3go opened this issue 3 years ago • 41 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues and checked the recent builds/commits

What happened?

founded 1,6 GB of spare images created by the UI in the folder C:\Users\username\AppData\Local\Temp

Steps to reproduce the problem

i hope to be helpfull.

What should have happened?

.

Commit where the problem happens

No response

What platforms do you use to access UI ?

Windows

What browsers do you use to access the UI ?

Brave

Command Line Arguments

No response

Additional information, context and logs

No response

4lt3r3go avatar Oct 21 '22 01:10 4lt3r3go

To expand on this: It appears every time this is opened, a new temp folder is created, which isn't cleared. After reading this thread, I used a space manager on my temp folder and found all the offending folders within.

MegaScience avatar Oct 21 '22 01:10 MegaScience

I experience this too, just deleted thousands of images

rasamaya avatar Oct 21 '22 03:10 rasamaya

Also experienced this. I just freed up 30 gigs by deleting left over SD images... Genuine question: Why do we need the temp folder? Can we not just use the images in the folder they were generated in instead for the preview images?

samuel-reyes avatar Oct 21 '22 05:10 samuel-reyes

Gradio creates these files, even when using the "bytes" type. Not sure if intended or not on Gradio's part, and I couldn't find a way to disable this behaviour.

C43H66N12O12S2 avatar Oct 21 '22 06:10 C43H66N12O12S2

I have the same issue. I made a issue here. It seems to be something with loading images from the history tab? But I haven't confirmed anything myself. https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/3202

SesuMoe avatar Oct 22 '22 01:10 SesuMoe

Tempfile issue came from gradio-app/gradio#2265 commit. This repo only managed to patch what gradio had done to our temporary storage by not clearing it, and also exposing security issues to it.

I tested randomly to access the SD Webui content of my friend's server by asking specific dir, and I managed to be able to steal his files by using this recent patch. The file= support been there since months but the recent base64 change is from gradio itself as what I've been looking again. Kinda dangerous security issue they had exposed from 3.5 update.

Need a restricted access to the file= parameter, and it's outside of this repository scope sadly. All of this are handled by gradio instantly.

ReiFan49 avatar Oct 22 '22 03:10 ReiFan49

Would it make sense to open an issue in the upstream Gradio repository about this? After all, that's a genuine issue, especially on Windows systems where the temp directory doesn't automatically get cleared. It's also an issue on long running servers, as the temp directory on Linux gets cleared when one restarts the machine or after quite a few days.

As far as I can tell, they're using the https://docs.python.org/3/library/tempfile.html library, (e.g. here ), but not properly cleaning up those files.

stefnotch avatar Oct 24 '22 09:10 stefnotch

Worst case I think we could try having a parallel process launched that starts cleaning this area when the UI starts.

papuSpartan avatar Oct 24 '22 17:10 papuSpartan

Don't know if this is still necessary, but putting something like

os.environ["TEMP"] = os.environ["TMP"] = "[drive]:/path/to/dir"

in launch.py seems to completely override the system-level user variables.

I redirected to a ramdisk, but if nothing else it should make it easier to keep things clean.

baloneysammich avatar Oct 26 '22 21:10 baloneysammich

os.environ["TEMP"] = os.environ["TMP"] = "[drive]:/path/to/dir"

Great find! Just realized I had 10gb of files in my temp folder and they multiply. I now chain commands in the following way (Windows Terminal):

rm "[my-temp-path]*" -r; $env:COMMANDLINE_ARGS="[webui-args]"; $env:TEMP="[my-temp-path]"; $env:TMP="[my-temp-path]"; .\webui.bat;

So it cleans up temp folder every time the webui starts.

anastasiuspernat avatar Oct 26 '22 23:10 anastasiuspernat

where is the temp folder on macs?

kelvinz avatar Oct 27 '22 02:10 kelvinz

image

Here is how I ended up editing mine. I'd greatly appreciate it, if someone who know what they're doing

  1. opens an upstream issue
  2. opens a pull request with a fix like this, until the upstream issue gets resolved
def prepare_enviroment():
    os.environ["TEMP"] = os.environ["TMP"] = os.path.abspath(os.path.join("outputs", "temp"))
    os.makedirs(os.environ["TEMP"], exist_ok=True)

stefnotch avatar Oct 27 '22 08:10 stefnotch

Saving images in the %TEMP% directory, even temporarily, is in my opinion a major problem as doing so prematurely degrades the associated hard drive's lifespan and performance for no good reason. Even when the images are kept, it needlessly duplicates the write operations.

As such, I would much prefer having the option to not have a temp directory at all. For cases where saving to disk is required, then at the very least I would like the files to be directly saved in the normal output directory.

SmashManiac avatar Oct 27 '22 23:10 SmashManiac

If you set the TEMP/TMP paths in a batch file instead of launch.py then you won't run into conflicts when pulling new updates. I assume this would also work in a Mac/Linux shell script.

I wrote a quick Powershell script to create a ramdisk on launch and remove it afterwards, using the free ImDisk since I already had it installed. It opens two Windows Terminal windows, but you just need to close the Stable Diffusion terminal and everything else will clean up.

Here's the script for anyone who wants to copy it. The "1G" in the first imdisk command sets the ramdisk size. In my case it's 1GB, but you can use an "M" instead if you want megabytes.

# Elevate if not admin
if ([Security.Principal.WindowsIdentity]::GetCurrent().Groups -notcontains 'S-1-5-32-544') {
    Start-Process -FilePath 'wt' -Verb RunAs -ArgumentList "pwsh -File $($MyInvocation.MyCommand.Path)"
    exit
}

imdisk -a -m R: -s 1G -p "/fs:ntfs /q /y"

$env:PYTHON, $env:GIT, $env:VENV_DIR = ''
$env:COMMANDLINE_ARGS = ''
$env:TEMP, $env:TMP = 'R:'

cd $PSScriptRoot
Start-Process -FilePath 'wt' -Wait -Verb RunAs -ArgumentList webui.bat
imdisk -D -m R:

GatesDA avatar Oct 27 '22 23:10 GatesDA

@GatesDA

I use the Imdisk GUI tool to create a ramdisk at startup, but I ran your command out of curiosity. According to

imdisk -l -m R:

your command creates a "Virtual Memory" type ramdisk. According to this post at superuser, that's slower than a "Physical Memory" ramdisk and can involve writes to disk. AFAICT, in order to create a PM ramdisk you need to use the awe option:

imdisk -a -m R: -s 1G -p "/fs:ntfs /q /y" -t file -o awe

The downside is that the memory isn't dynamically allocated, so the full 1G will be considered in use until the ramdisk is detached.

baloneysammich avatar Oct 28 '22 14:10 baloneysammich

If you set the TEMP/TMP paths in a batch file instead of launch.py then you won't run into conflicts when pulling new updates. I assume this would also work in a Mac/Linux shell script.

@GatesDA Until this is fixed, could you describe exactly what you add to the batch file in order to accomplish this?

EVA-x-3 avatar Oct 28 '22 15:10 EVA-x-3

@EVA-x-3 Copy or edit webui-user.bat and add these to the other set commands. Swap in your own path if you're using a different drive letter or not using a ramdisk.

set TEMP=R:
set TMP=R:

@baloneysammich

I ran some quick benchmarks. I expected them to be basically identical, but on my system the virtual memory ramdisk is actually significantly faster (25% on reads, 21% on writes). Might be something to do with how ImDisk handles things?

In any case, virtual memory performs just fine as long as you have enough physical RAM. The post you linked to cites a user who was trying to speed up a system with only 512MB of physical RAM by increasing virtual memory to 2GB. The issue there is a lack of physical memory, not the use of virtual memory.

You'll actually start forcing virtual memory disk writes quicker with a fixed-size ramdisk in physical RAM, since that kicks in when you run out of physical RAM. Making the ramdisk in physical RAM just prioritizes it over everything that uses the standard virtual memory system.

GatesDA avatar Oct 28 '22 16:10 GatesDA

@GatesDA

Yeah, I realized after I posted it that most people probably wouldn't be interested. And I shouldn't have mentioned speed, that was misleading.

The main reason I pointed it out is that data on a VM-backed ramdisk can be moved to page file after periods of inactivity, even if there is plenty of free RAM. It's probably a silly thing to be concerned about though.

baloneysammich avatar Oct 28 '22 17:10 baloneysammich

Instead of writing to a ramdisk, could you write to nul.

Gerschel avatar Oct 30 '22 22:10 Gerschel

@Gerschel Tried it, but rendering causes a FileNotFoundError and the UI doesn't show the final image. It still showed the in-progress images and saved the final to my output directory.

If anyone wants to try to get it working, set the temp directories to nul (with one "L"). This tells Windows to discard the temp files without saving them anywhere.

set TEMP=nul
set TMP=nul

GatesDA avatar Oct 31 '22 16:10 GatesDA

Don't know if this is still necessary, but putting something like

os.environ["TEMP"] = os.environ["TMP"] = "[drive]:/path/to/dir"

in launch.py seems to completely override the system-level user variables.

I redirected to a ramdisk, but if nothing else it should make it easier to keep things clean.

Thats the fix. It could be implemented into the WebUI Settings.

Username69992872 avatar Nov 02 '22 19:11 Username69992872

I don't think this deserves a settings entry at all. I think the fix should be implemented, and simply applied. And ideally, the temp directory would get cleaned up upon exit.

stefnotch avatar Nov 02 '22 19:11 stefnotch

@Username69992872

GatesDA suggestion to set the variables in a batch file is better actually. I removed my changes to launch.py and set the variables in webui-user.bat instead.

baloneysammich avatar Nov 02 '22 21:11 baloneysammich

https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/4202 I added a simple fix that will work if user use ctrl+c

aliencaocao avatar Nov 03 '22 05:11 aliencaocao

@aliencaocao In case it helps, my Powershell script cleans up automatically even "if the user force closes the app by closing the console window directly or task kill". (That's why I'm using Powershell instead of a batch file.)

Since I'm dismounting the ramdisk, it also removes the images currently in use by the browser. I don't think a ramdisk should be the default, though.

On a related note, I've since tweaked it so it runs in the background after elevation. No more second terminal. It still has an extra UAC prompt for the ramdisk stuff, but a regular temp folder wouldn't need one.

# Elevate and hide if not admin
if ([Security.Principal.WindowsIdentity]::GetCurrent().Groups -notcontains 'S-1-5-32-544') {
    Start-Process -FilePath 'pwsh' -Verb RunAs -ArgumentList "-WindowStyle hidden -File $($MyInvocation.MyCommand.Path)"
    exit
}

imdisk -a -m R: -s 1G -p "/fs:ntfs /q /y"

$env:PYTHON, $env:GIT, $env:VENV_DIR = ''
$env:COMMANDLINE_ARGS = ''
$env:TEMP, $env:TMP = 'R:'

cd $PSScriptRoot
Start-Process -FilePath 'wt' -Wait -Verb RunAs -ArgumentList webui.bat
imdisk -D -m R:

GatesDA avatar Nov 03 '22 07:11 GatesDA

@aliencaocao In case it helps, my Powershell script cleans up automatically even "if the user force closes the app by closing the console window directly or task kill". (That's why I'm using Powershell instead of a batch file.)

Since I'm dismounting the ramdisk, it also removes the images currently in use by the browser. I don't think a ramdisk should be the default, though.

On a related note, I've since tweaked it so it runs in the background after elevation. No more second terminal. It still has an extra UAC prompt for the ramdisk stuff, but a regular temp folder wouldn't need one.

# Elevate and hide if not admin
if ([Security.Principal.WindowsIdentity]::GetCurrent().Groups -notcontains 'S-1-5-32-544') {
    Start-Process -FilePath 'pwsh' -Verb RunAs -ArgumentList "-WindowStyle hidden -File $($MyInvocation.MyCommand.Path)"
    exit
}

imdisk -a -m R: -s 1G -p "/fs:ntfs /q /y"

$env:PYTHON, $env:GIT, $env:VENV_DIR = ''
$env:COMMANDLINE_ARGS = ''
$env:TEMP, $env:TMP = 'R:'

cd $PSScriptRoot
Start-Process -FilePath 'wt' -Wait -Verb RunAs -ArgumentList webui.bat
imdisk -D -m R:

Do you use a ramdisk for performance reasons or just because everything is deleted afterwards, so no temp size creep?

Manimap avatar Nov 03 '22 12:11 Manimap

@Manimap Just to clean up. It also has the benefit of reducing drive wear. I haven't been watching how it affects performance since my SSD ought to have been plenty fast enough for files like these.

GatesDA avatar Nov 03 '22 13:11 GatesDA

@Manimap Just to clean up. It also has the benefit of reducing drive wear. I haven't been watching how it affects performance since my SSD ought to have been plenty fast enough for files like these.

Thanks !

Manimap avatar Nov 03 '22 14:11 Manimap

@baloneysammich

I use the Imdisk GUI tool to create a ramdisk at startup, but I ran your command out of curiosity. According to The downside is that the memory isn't dynamically allocated, so the full 1G will be considered in use until the ramdisk is detached.

For Linux, there is tmpfs or ramfs, which actually dynamically deallocates memory once the files are deleted. For Windows, the best option is to use WinFsp as a user-level file system driver with either the preinstalled memfs or my fork, which addresses some of the performance issues with memfs: https://github.com/Ceiridge/WinFsp-MemFs-Extended It's perfect for such temp files, because the memory is only allocated and deallocated as needed

Ceiridge avatar Nov 11 '22 17:11 Ceiridge

Why unsaved data gets turned into files in the first place instead of just being kept inside the program's memory while it is running?

TiagoTiago avatar Nov 11 '22 17:11 TiagoTiago

Why unsaved data gets turned into files in the first place instead of just being kept inside the program's memory while it is running?

Because to display in a browser, you cannot keep it in memory. The browser needs a proper file handle

aliencaocao avatar Nov 12 '22 01:11 aliencaocao