-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
if user exits browser or tab, gradio not cleaning up process/threads #4016
Comments
Hi @pseudotensor ! Thanks for filing the issue. This is a bit tricky. There isn't an official API for killing a running thread in python AFAIK so i don't think there's anything gradio can do (plus we don't really know when a dev starts a thread from their event handler). The best would be to somehow tell Tagging @gante here who implemented |
is it not related to https://github.com/gradio-app/gradio/pull/2783/files ? |
Hi @pseudotensor. Yea its related. The main difference is that in #2783, the function is not spawning a new thread and is instead yielding each iteration of a python iterator. In that case, gradio can check whether the client is still alive at each iteration. if not, we can terminate the function and clean up. In the case of |
Didn't mean to close, was closed by other repo. |
I basically need to know in gradio when user closes tab. How can I do that? |
As far as I know, there is no way to detect if a user closes a browser tab. @aliabid94 is that correct? |
+1, I really need that too I have a gradio interface that allow users to upload their files to the storage but the files still there even when the users exit the interface and the storage get full, we need like a change event for gradio.State() trigger when the leave the page it should help a lot of users not only me im i right? |
This would help a lot. My gradio space can only run at 1 user at a time and if a process takes up too much time without a client, i would like to terminate the thread. |
I have the same problem. I have a small testing script:
When a user closes the tab the create_thread() function stops running, but thread_function() continues. I tried to see if create_thread() raises an exception, but it doesn't. |
Hi @abidlabs , If I store something like a cuda model in gr.state() how am I supposed to clear it after user exits? Any ideas how to work-around this gradio issue? i.e. it's a simple thing:
Why does gradio/fastapi/etc. preserve gr.state forever? Do other app builders like streamlit have some mechanism? Or is there a way to look at all memory across all users and manage it in gradio/fastapi? The reason why this is important is because the opposite of a global or local state also doesn't work. That is, if one makes a model or database globally, then due to how python works, no matter what I do I cannot free that memory. There's always some reference somewhere in gradio that points to it in some thread. So this leaves me in a wedged state w.r.t. gradio. |
GPT-4 suggests something like using a ping on the hash. Ping is used to detect lifetime of the connection. If UI doesn't return ping in some developer set time interval, then the session hash based objects should all be cleaned up. With code like this: javascript on blocks head:
and something like this in the App.create_app():
and
but it and I don't know how to pass the session has through in the java script even though I can see in other logging that a session hash is used. Then one would use that clean-up to clean-up any gr.State objects for that given session hash. I presume already gr.State objects are indexed by the session hash. |
The problem right now is no matter what, even a small use of gr.State() leads to a memory leak, and over long enough time or with heavy use, eventually one gets OOM. I'm encountering this all the time with gradio. |
Another GPT-4 idea is to use a websocket that client initiates. When the client goes down (UI or API), then the fastapi/gradio app can cleanup. I tried to hack something, but it's not working:
and:
I can't even get this part to work, let alone cleanup. But seems ws is good way to go. And everything here is all hardcoded localhost, which doesn't work: |
Seems streamlit does this properly: streamlit/streamlit#6166 with websockets. |
At least this javascript triggers from UI to the app:
with:
and required imports. |
The above works perfectly to detect when the user closes the browser. @abidlabs Please, can you guys incorporate this in order to clear the gr.State for that session? Just need to:
|
What's really needed is a callback like streamlit for each state once disconnect reached. This way one can properly handle things like cuda models, to put the model off GPU and clear torch cache, but only for that specific state. I confirmed at least manually that this would work with above approach. During disconnect, I found my model state and did:
before popping out the item because cuda would remain in cache unless moved to cpu first and then cleared cache. i.e.
|
For actual gradio changes, best to edit client.ts directly and always establish that websocket. |
…anage freeing up of state objects
Fixes gradio-app#4016 in gradio
Describe the bug
https://huggingface.co/docs/transformers/internal/generation_utils#transformers.TextIteratorStreamer
When using this, if user exits tab or closes browser, generation continues in background indefinitely.
Is there an existing issue for this?
Reproduction
Enter "The sky is" and soon after close the tab. The generation will continue. For larger models, this is problem since gradio thinks the user is gone, queue is open, but now threads will overlap.
Also, note that adding a
raise StopIteration()
has no effect on the model.generate(), it only terminates the respond generation. So GPU usage continues in background. i.e.This will lead to a termination of output to gradio chatbot, but continue to use GPU in other thread. It doesn't help to join the thread, that just holds there until generation finishes. Some methods for excepting a thread exist, but that doesn't solve first issue and is not standard to do.
Screenshot
Logs
System Info
Severity
blocking all usage of gradio
The text was updated successfully, but these errors were encountered: