Closed aliabid94 closed 1 year ago
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
All the demos for this PR have been deployed at https://huggingface.co/spaces/gradio-pr-deploys/pr-2750-all-demos
That was fast @aliabid94! Backend code looks good (left some nits), but will let @pngwn or @gary149 advise on the frontend and design.
Can we release a beta version with this so that @apolinario can use it for dreambooth?
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
Discussed further with @aliabid94 and we're rethinking this approach. Rather than ProgressBar
being a separate component, it would make more sense to utilize the ETA status tracker that we have already implemented. The alternative approach would allow functions to yield
a special type of "progress update" (syntax TBD) that would serve as a manual update of the ETA in the status bar. This would also be reflected in the progress bar that is built-in to each component.
That being said, we've released gradio==3.12.0b1
in case you want to use this stopgap progress bar @apolinario. (Also @apolinario would be interested in hearing your thoughts on these two options)
First of all: thanks for turning this around in record time! Some thoughts:
I quite like the idea of an independent progress bar. From a user perspective I think if both approaches existed could be cool. This is something the AUTOMATIC1111 would use as well as they already have a hacked version for e.g. - however I think it would be nice if it could also fit more info such as ETA, it/s
Regardless if it is a progress bar or the output component (or both), I think it would be great to have tqdm
automatic integration. So alternatively to the user doing their own yields. This is just a default way to do progress bar that is so simple and it contains so much information (it/s, progress %, ETA) that recreating it with yields would be a bit laborious
Oh I really like the idea of tqdm integration, will look into that!
+1 on the tqdm integration
Not sure about having two different ways of showing progress bars though. I prefer having a single way unless there is a strong advantage to have a separate progress bar component. I know AUTOMATIC1111 GUI has a progress bar, but wouldn't it be better if the progress bar is incorporated into the output component itself, as is our current status tracker?
I'm a bit confused here. The StatusTracker
is a progress bar just the styling is different. If we want to change the styling then that is a separate issue.
I thought the requests we have had a few times is for a separate ProgressBar
, like in the SD WebGUI, but I do think that it should be bound to an event and receive the same data as the built in status tracker, currenttime / eta
with queue position / queue size
all included, otherwise I don't really see the usefulness of this. Since everything happens on the server what would be timed if not the duration of an event? And if it is a bar rather than an infinite spinner, how would a user be able to provide an accurate estimated 100% value for the bar to 'complete'?
I know AUTOMATIC1111 GUI has a progress bar, but wouldn't it be better if the progress bar is incorporated into the output component itself, as is our current status tracker?
This has really been my position all along but as above, the StatusTracker
is a progress bar. The only value of the request is if it is standalone, otherwise is just a reskin which we can support in userland in the future via custom components but I certainly don't think we should have multiple styles of the built in loading indicator in core.
Yes so to summarize my takeaways:
ProgressBar
componentProgressBar
component, but we do not include this in coreHow does that sound @aliabid94?
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
Thing is with tqdm is that this isn't really true:
This is just a default way to do progress bar that is so simple and it contains so much information (it/s, progress %, ETA) that recreating it with yields would be a bit laborious
We would have to pass that information down to the component and render it in some way, so we'd need to support a vast array of inputs in the UI. We aren't just taking the default tqdm output and rendering it directly into the webpage somehow, we need to take the data is spits out and do something with it.
I'm strongly against dumping the stdout text into the page, i think it looks really bad and goes against the whole point of gradio. These UIs are for anyone, not just people familiar with typical CLI outputs. This needs designing properly before being included. cc @gary149
If we are going to add this can we get some API + design proposals as well as breakdown of the various possible bits of UI that we would render based on the tqdm options the user passes?
I'm strongly against dumping the stdout text into the page, i think it looks really bad and goes against the whole point of gradio. These UIs are for anyone, not just people familiar with typical CLI outputs. This needs designing properly before being included. cc @gary149
Not sure I follow @pngwn. We wouldn't display the raw progress bar that tqdm prints. We would extract the information and plug that into our existing status tracker. So the output would look pretty much the same.
But even dumping the text isn't great either, what works in a CLI tool isn't a great experience for end users. And that means we need to match the tqdm
API if we want to support it fully.
@pngwn there's a TQDM Notebook class that afaik exposes some of the outputs for the programs to use, I don't really know how it works under the hood but could potentially be used for this: https://tqdm.github.io/docs/notebook/
Regarding the progress bar. I still see how it could be interesting for users to choose whether their output is in a progress bar or on the output field. I think there's room for both, but I agree this may make sense as a custom/user component. But just FYI if I had to choose between a custom progress bar or a native one on the output field for this particular demo I would choose a custom progress bar
The big issue with a custom component ProgressBar is that we currently don't have a mechanism to pass anything but the output components the current progress of a request/ queue request. We'll need to build in more flexibility to be able to do that.
To summarize:
Here's a possible implementation:
import gradio as gr
import img_model
with gr.Blocks() as demo:
prompt = gr.Textbox(label="Enter text")
img = gr.Image()
def load_image(data):
total_steps = 50
for step in img_model.load():
# ...
yield gr.Status(step / total_steps, text="Loading model")
return img_model(data[prompt])
prompt.submit(load_image, {prompt}, img)
demo.queue().launch()
which would look something like:
For a tqdm-like wrapper, we could have:
import gradio as gr
import img_model
with gr.Blocks() as demo:
prompt = gr.Textbox(label="Enter text")
img = gr.Image()
def load_image(data):
total_steps = 50
for _ in gr.Track(img_model.load()):
# ...
yield gr.Status(text="Loading model")
return img_model(data[prompt])
prompt.submit(load_image, {prompt}, img)
demo.queue().launch()
where the gr.Track
can automatically keep track of length and progress, and yielding a gr.Status() will automatically get that information.
For the tqdm integration, it would be better if users can somehow return or yield the tqdm object itself so that people don’t have to learn a new syntax. Users are already using tqdm in their code so it would be better if we integrated with tqdm instead of offering a replacement
Yeah I thought about that but in the syntax
for obj in tqdm(objects):
yield ...
there isn't really access to the tqdm object within the loop, so not sure how to yield it
the other reason not to use tqdm is that we would then have the users printing to the console as a result of using tqdm. If multiple users are being processed at once, the output will get ugly
there isn't really access to the tqdm object within the loop, so not sure how to yield it
So tqdm(iterable)
returns a new iterable, and this contains all of the info you'd need. Here's a complete example:
from tqdm import tqdm
# Create a list of numbers to iterate over
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Create a tqdm object to track the progress of the iteration
pbar = tqdm(numbers)
# Iterate over the list of numbers
for number in pbar:
time.sleep(0.5)
# Print the current status of the tqdm object
print("current_iteration", pbar.n)
print("out of", pbar.total)
the other reason not to use tqdm is that we would then have the users printing to the console as a result of using tqdm. If multiple users are being processed at once, the output will get ugly
That's not really a problem -- I don't think people care too much about the console
The main thing is that people are already using tqdm
and so forcing them to switch to something else so that their function works with Gradio is not ideal (cc @apolinario for your thoughts too)
Question about the gr.Status
implementation, would this replace gr.ProgressBar
?
The main thing is that people are already using tqdm and so forcing them to switch to something else so that their function works with Gradio is not ideal (cc @apolinario for your thoughts too)
I agree. Also there's quite a bit of people that re-use the same code for Colab and Gradio demos, so if tqdm worked for both that would be great.
Also, in quite a bit of occasions, the user does not have control over the loop/code that uses tqdm, they build a Gradio demo on an external function/library that contains the loop already (with tqdm), so it would be very laborious for the user to interject and change that
the other reason not to use tqdm is that we would then have the users printing to the console as a result of using tqdm. If multiple users are being processed at once, the output will get ugly
FYI this already happens on most Spaces that have generative media that I come across/build - leaving tqdm there by default. However most of them have queues (otherwise they OOM if multiple parallel requests happen) so the logs don't get that messy/overlappy and it is usually good to be able to track usage
Another real life example that just happened to me, that makes me thing how integrating with tqdm would be great:
I would like to integrate the snapshot_download
function from huggingface_hub
with a Gradio progress bar. Without native integration, I would need to fork huggingface_hub just to inject Gradio integration (or capture the terminal output and throw some yields), but if Gradio can bind to already existing tqdm from other functions that automatically spit in progress bars, that would be incredibly awesome
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
The demo notebooks don't match the run.py files. Please run this command from the root of the repo and then commit the changes:
pip install nbformat && cd demo && python generate_notebooks.py
Very cool @aliabid94. Going through this PR bit by bit and leaving my comments here:
progress.tqdm()
over progress.track()
. People are already familiar with tqdm.tqdm()
syntax and will expect it to return the iterable just like tqdm.tqdm()
When run without queuing enabled, I get the following:
AttributeError: 'Interface' object has no attribute '_queue'
May want to catch this and tell users to enable queueing
When I run this:
import gradio as gr
import time
progress = gr.Progress()
def test(x, progress=progress):
for i in range(10):
time.sleep(0.3)
progress(i/10)
return x
gr.Interface(test, "number", "number").queue().launch()
it works great, but what is the "0 steps" that it shows on the top right?
Add support for progressbar component. Feel free to leave feedback on API or visual design.
See example in demo/progress/run.py
Snippet for tqdm-like wrapper
Snippet for explicit status:
Closes: #340