#
Понимание класса Interface

В этом разделе мы подробно рассмотрим класс `Interface` и разберем основные параметры, используемые для его создания.

##
Как создать Interface

Вы заметите, что класс `Interface` имеет 3 обязательных параметра:

`Interface(fn, inputs, outputs, ...)`

Это параметры:

- `fn`: функция прогнозирования, обернутая интерфейсом Gradio. Эта функция может принимать один или несколько параметров и возвращать одно или несколько значений
- `inputs`: тип(ы) компонента(ов) ввода. Gradio предоставляет множество готовых компонентов, таких как `"image"` или `"mic"`.
- `outputs`: тип(ы) компонента(ов) вывода. Опять же, Gradio предоставляет множество предварительно созданных компонентов, например, `" image"` или `"label"`.

Полный список компонентов смотрите в документации Gradio. Каждый предварительно созданный компонент можно настроить, инстанцировав соответствующий ему класс.

Например, как мы видели в предыдущем разделе, вместо передачи `"textbox"` в параметр `inputs`, вы можете передать компонент `Textbox(lines=7, label="Prompt")` для создания текстового поля с 7 строками и меткой.

Давайте рассмотрим еще один пример, на этот раз с компонентом `Audio`.

##
Простой пример со звуком

Как уже говорилось, Gradio предоставляет множество различных входов и выходов. Поэтому давайте создадим `Interface`, работающий с аудио.

В этом примере мы создадим функцию audio-to-audio, которая принимает аудиофайл и просто переворачивает его.

Для ввода мы будем использовать компонент `Audio`. При использовании компонента `Audio`, вы можете указать, будет ли источником звука файл, который загружает пользователь или микрофон, с помощью которого пользователь записывает свой голос. В данном случае давайте зададим `"microphone"`. Просто ради интереса добавим к `Audio` метку, которая будет гласить “Speak here…“.

Кроме того, мы хотели бы получать аудио в виде массива numpy, чтобы можно было легко “перевернуть” его. Поэтому мы зададим `"type"` в значение `"numpy"`, которое передаст входные данные в виде кортежа (`sample_rate`, `data`) в нашу функцию.

Мы также будем использовать компонент вывода `Audio`, который может автоматически рендерить кортеж с частотой дискретизации и массивом данных numpy в воспроизводимый аудиофайл. В этом случае нам не нужно делать никаких настроек, поэтому мы будем использовать строку ярлык `"audio"`.

    import numpy as np
    import gradio as gr

    def reverse_audio(audio):
        sr, data = audio
        reversed_audio = (sr, np.flipud(data))
        return reversed_audio

    mic = gr.Audio(source="microphone", type="numpy", label="Speak here...")
    gr.Interface(reverse_audio, mic, "audio").launch()

Код, приведенный выше, создаст интерфейс, подобный приведенному ниже (если ваш браузер не не запрашивает разрешения на использование микрофона, откройте демо в отдельной вкладке.)

Теперь вы сможете записать свой голос и услышать, как вы говорите в обратную сторону - жутковато 👻!

##
Обработка нескольких входов и выходов

Допустим, у нас есть более сложная функция, с несколькими входами и выходами. В примере ниже у нас есть функция, которая принимает индекс выпадающего списка, значение слайдера и число, и возвращает пример музыкального тона.

Посмотрите, как мы передаем список входных и выходных компонентов, и посмотрите, сможете ли вы проследить за тем, что происходит.

Ключевым моментом здесь является то, что когда вы передаете:

- список входных компонентов, каждый компонент соответствует параметру по порядку.
- список выходных компонентов, каждый компонент соответствует возвращаемому значению.

В приведенном ниже фрагменте кода показано, как три компонента ввода соответствуют трем аргументам функции `generate_tone()`:

    import numpy as np
    import gradio as gr

    notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]

    def generate_tone(note, octave, duration):
        sr = 48000
        a4_freq, tones_from_a4 = 440, 12 * (octave - 4) + (note - 9)
        frequency = a4_freq * 2 ** (tones_from_a4 / 12)
        duration = int(duration)
        audio = np.linspace(0, duration, duration * sr)
        audio = (20000 * np.sin(audio * (2 * np.pi * frequency))).astype(np.int16)
        return (sr, audio)

    gr.Interface(
        generate_tone,
        [
            gr.Dropdown(notes, type="index"),
            gr.Slider(minimum=4, maximum=6, step=1),
            gr.Textbox(type="number", value=1, label="Duration in seconds"),
        ],
        "audio",
    ).launch()

###
Метод launch()

До сих пор мы использовали метод `launch()` для запуска интерфейса, но мы не обсуждали, что он делает.

По умолчанию метод `launch()` запускает демо на веб-сервере, который работает локально. Если вы выполняете свой код в блокноте Jupyter или Colab, то Gradio встроит демо GUI в блокнот, чтобы вы могли легко им пользоваться.

Вы можете настроить поведение `launch()` с помощью различных параметров:

- `inline` - отображать ли интерфейс в виде строки в блокнотах Python.
- `inbrowser` - автоматически ли запускать интерфейс в новой вкладке браузера по умолчанию.
- `share` - создавать ли для интерфейса общедоступную ссылку с вашего компьютера. Что-то вроде ссылки на Google Drive!

Мы рассмотрим параметр `share` более подробно в следующем разделе!

##
✏️ Давайте применим это!

Давайте создадим интерфейс, который позволит вам продемонстрировать демо модели распознавания речи. Чтобы было интереснее, мы будем принимать либо микрофонный вход, либо загруженный файл.

Как обычно, мы загрузим нашу модель распознавания речи с помощью функции `pipeline()` из 🤗 Transformers. Если вам нужно быстро вспомнить, вы можете вернуться к этому разделу в Главе 1. Далее мы реализуем функцию `transcribe_audio()`, которая обрабатывает аудио и возвращает транскрипцию. Наконец, мы обернем эту функцию в `Interface` с компонентами `Audio` на входе и просто текстом на выходе. В целом, код этого приложения выглядит следующим образом:

    from transformers import pipeline
    import gradio as gr

    model = pipeline("automatic-speech-recognition")

    def transcribe_audio(mic=None, file=None):
        if mic is not None:
            audio = mic
        elif file is not None:
            audio = file
        else:
            return "You must either provide a mic recording or a file"
        transcription = model(audio)["text"]
        return transcription

    gr.Interface(
        fn=transcribe_audio,
        inputs=[
            gr.Audio(source="microphone", type="filepath", optional=True),
            gr.Audio(source="upload", type="filepath", optional=True),
        ],
        outputs="text",
    ).launch()

Если ваш браузер не запрашивает разрешения на использование микрофона, откройте демо в отдельной вкладке.

Вот и все! Теперь вы можете использовать этот интерфейс для транскрибирования аудио. Обратите внимание, что передавая параметр `optional` как `True`, мы позволяем пользователю предоставить либо микрофон, либо аудиофайл (либо ни то, ни другое, но в этом случае будет выдано сообщение об ошибке).

Продолжайте, чтобы узнать, как поделиться своим интерфейсом с другими!

Update on GitHub