mirror of
https://github.com/gradio-app/gradio.git
synced 2025-01-18 10:44:33 +08:00
Add a guide on how to use apps like functions (#1799)
* Add examples for series and parallel * Create demo + guide * More formatting * Change name of guide * Fix typo * Use english to german as example instead * Expand phrase a bit
This commit is contained in:
parent
106934fe70
commit
3f9ec2c345
25
demo/english_translator/run.py
Normal file
25
demo/english_translator/run.py
Normal file
@ -0,0 +1,25 @@
|
||||
import gradio as gr
|
||||
|
||||
from transformers import pipeline
|
||||
|
||||
pipe = pipeline("translation", model="t5-base")
|
||||
|
||||
|
||||
def translate(text):
|
||||
return pipe(text)[0]["translation_text"]
|
||||
|
||||
|
||||
with gr.Blocks() as demo:
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
english = gr.Textbox(label="English text")
|
||||
translate_btn = gr.Button(value="Translate")
|
||||
with gr.Column():
|
||||
german = gr.Textbox(label="German Text")
|
||||
|
||||
translate_btn.click(translate, inputs=english, outputs=german)
|
||||
examples = gr.Examples(examples=["I went to the supermarket yesterday.", "Helen is a good swimmer."],
|
||||
inputs=[english])
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
27
demo/generate_english_german/run.py
Normal file
27
demo/generate_english_german/run.py
Normal file
@ -0,0 +1,27 @@
|
||||
import gradio as gr
|
||||
|
||||
from transformers import pipeline
|
||||
|
||||
english_translator = gr.Blocks.load(name="spaces/freddyaboulton/english-translator")
|
||||
english_generator = pipeline("text-generation", model="distilgpt2")
|
||||
|
||||
|
||||
def generate_text(text):
|
||||
english_text = english_generator(text)[0]["generated_text"]
|
||||
german_text = english_translator(english_text)
|
||||
return english_text, german_text
|
||||
|
||||
|
||||
with gr.Blocks() as demo:
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
seed = gr.Text(label="Input Phrase")
|
||||
with gr.Column():
|
||||
english = gr.Text(label="Generated English Text")
|
||||
german = gr.Text(label="Generated German Text")
|
||||
btn = gr.Button("Generate")
|
||||
btn.click(generate_text, inputs=[seed], outputs=[english, german])
|
||||
gr.Examples(["My name is Clara and I am"], inputs=[seed])
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
@ -230,7 +230,7 @@ def skip() -> dict:
|
||||
return update()
|
||||
|
||||
|
||||
@document()
|
||||
@document("load")
|
||||
class Blocks(BlockContext):
|
||||
"""
|
||||
Blocks is Gradio's low-level API that allows you to create more custom web
|
||||
@ -262,7 +262,7 @@ class Blocks(BlockContext):
|
||||
btn.click(fn=update, inputs=inp, outputs=out)
|
||||
|
||||
demo.launch()
|
||||
Demos: blocks_hello, blocks_flipper, blocks_speech_text_length
|
||||
Demos: blocks_hello, blocks_flipper, blocks_speech_text_length, generate_english_german
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
@ -686,21 +686,19 @@ class Blocks(BlockContext):
|
||||
For reverse compatibility reasons, this is both a class method and an instance
|
||||
method, the two of which, confusingly, do two completely different things.
|
||||
|
||||
Class method: loads a demo from a Hugging Face Spaces repo and creates it locally
|
||||
Parameters:
|
||||
name (str): the name of the model (e.g. "gpt2"), can include the `src` as prefix (e.g. "models/gpt2")
|
||||
src (str | None): the source of the model: `models` or `spaces` (or empty if source is provided as a prefix in `name`)
|
||||
api_key (str | None): optional api key for use with Hugging Face Hub
|
||||
alias (str | None): optional string used as the name of the loaded model instead of the default name
|
||||
type (str): the type of the Blocks, either a standard `blocks` or `column`
|
||||
Returns: Blocks instance
|
||||
|
||||
Instance method: adds an event for when the demo loads in the browser.
|
||||
Class method: loads a demo from a Hugging Face Spaces repo and creates it locally and returns a block instance.
|
||||
|
||||
|
||||
Instance method: adds an event for when the demo loads in the browser and returns None.
|
||||
Parameters:
|
||||
fn: Callable function
|
||||
inputs: input list
|
||||
outputs: output list
|
||||
Returns: None
|
||||
name: Class Method - the name of the model (e.g. "gpt2"), can include the `src` as prefix (e.g. "models/gpt2")
|
||||
src: Class Method - the source of the model: `models` or `spaces` (or empty if source is provided as a prefix in `name`)
|
||||
api_key: Class Method - optional api key for use with Hugging Face Hub
|
||||
alias: Class Method - optional string used as the name of the loaded model instead of the default name
|
||||
fn: Instance Method - Callable function
|
||||
inputs: Instance Method - input list
|
||||
outputs: Instance Method - output list
|
||||
"""
|
||||
if isinstance(self_or_cls, type):
|
||||
if name is None:
|
||||
|
77
guides/using_blocks_like_functions.md
Normal file
77
guides/using_blocks_like_functions.md
Normal file
@ -0,0 +1,77 @@
|
||||
<script type="module" src="https://gradio.s3-us-west-2.amazonaws.com/3.0.24/gradio.js"></script>
|
||||
|
||||
# Using Gradio Blocks Like Functions
|
||||
Tags: TRANSLATION, HUB, SPACES
|
||||
|
||||
|
||||
Docs: Blocks
|
||||
|
||||
**Prerequisite**: This Guide builds on the Blocks Introduction. Make sure to [read that guide first](/introduction_to_blocks).
|
||||
|
||||
## Introduction
|
||||
|
||||
Did you know that apart from being a full-stack machine learning demo, a Gradio Blocks app is also a regular-old python function!?
|
||||
|
||||
This means that if you have a gradio Blocks (or Interface) app called `demo`, you can use `demo` like you would any python function.
|
||||
|
||||
So doing something like `output = demo("Hello", "friend")` will run the first event defined in `demo` on the inputs "Hello" and "friend" and store it
|
||||
in the variable `output`.
|
||||
|
||||
If I put you to sleep 🥱, please bear with me! By using apps like functions, you can seamlessly compose Gradio apps.
|
||||
The following section will show how.
|
||||
|
||||
## Treating spaces like functions
|
||||
|
||||
Let's say we have the following demo that translates english text to german text.
|
||||
|
||||
$code_english_translator
|
||||
|
||||
I already went ahead and hosted it in Hugging Face spaces at [freddyaboulton/english-to-german](https://huggingface.co/spaces/freddyaboulton/english-to-german).
|
||||
You can see the demo below as well:
|
||||
|
||||
<gradio-app space="freddyaboulton/english-to-german"> </gradio-app>
|
||||
|
||||
Now, let's say you have an app that generates english text, but you wanted to additionally generate german text.
|
||||
|
||||
You could either:
|
||||
|
||||
1. Copy the source code of my english-to-german translation and paste it in your app.
|
||||
|
||||
2. Load my english-to-german translation in your app and treat it like a normal python function.
|
||||
|
||||
Option 1 technically always works, but it often introduces unwanted complexity.
|
||||
|
||||
Option 2 lets you borrow the functionality you want without tightly coupling our apps.
|
||||
|
||||
All you have to do is call the `Blocks.load` class method in your source file.
|
||||
After that, you can use my translation app like a regular python function!
|
||||
|
||||
The following code snippet and demo shows how to use `Blocks.load`.
|
||||
|
||||
Note that the variable `english_translator` is my english to german app, but its used in `generate_text` like a regular function.
|
||||
|
||||
$code_generate_english_german
|
||||
|
||||
<gradio-app space="freddyaboulton/generate-english-german"> </gradio-app>
|
||||
|
||||
## How to control which function in the app to use
|
||||
|
||||
If the app you are loading defines more than one function, you can specify which function to use with the `fn_index` parameter.
|
||||
Imagine my app also defined an english to spanish translation function. In order to use it in our text generation app,
|
||||
we would use the following code:
|
||||
|
||||
```python
|
||||
english_generator(text, fn_index=1)[0]["generated_text"]
|
||||
```
|
||||
|
||||
Functions in gradio spaces are zero-indexed, so since the spanish translator would be the second function in my space,
|
||||
you would use index 1.
|
||||
|
||||
## Parting Remarks
|
||||
|
||||
We showed how treating a Blocks app like a regular python helps you compose functionality across different apps.
|
||||
Any Blocks app can be treated like a function, but a powerful pattern is to `load` an app hosted on
|
||||
[Hugging Face Spaces](https://huggingface.co/spaces) prior to treating it like a function in your own app.
|
||||
You can also load models hosted on the [Hugging Face Model Hub](https://huggingface.co/models) - see the [Using Hugging Face Integrations](/using_hugging_face_integrations) guide for an example.
|
||||
|
||||
### Happy building! ⚒️
|
@ -112,6 +112,8 @@ The code above generates the following demo.
|
||||
|
||||
As you can see, the demo looks the same, but it uses a webcam input instead of user-uploaded images.
|
||||
|
||||
You can learn more about this feature, and how to use it with the new Blocks API in the [Using Gradio Blocks Like Functions guide](/using_blocks_like_functions)
|
||||
|
||||
## Using multiple Spaces
|
||||
|
||||
Sometimes a single model inference will not be enough: you might want to call multiple models by piping them (using the output of model A as the input of model B). `Series` can achieve this. Other times, you might want to run two models in parallel to compare them. `Parallel` can do this!
|
||||
|
Loading…
Reference in New Issue
Block a user