Понимание удержания с помощью Gradio

Осознание эффективности использования Gradio для удержания внимания

Как использовать веб-приложения для аналитики

Изображение от DALL-E 3

Я помню момент, когда я создал свое первое веб-приложение. Это было около восьми лет назад, и я был довольно новичком аналитиком и был уверен, что БИ-инструменты могут решить все проблемы.

Инженерная команда создала прототип новой SDK и хотела узнать, собирает ли она данные лучше. Они тестировали его на наборе устройств, анализировали данные и сравнивали их со старой версией. Однако набор устройств постоянно менялся, поэтому обновление его в БИ-инструментах потребовало бы немалых усилий. Поэтому я решил создать веб-приложение.

Я нашел набор статей (если я правильно помню, десять или одиннадцать), прочитал их все и попытался использовать этот опыт для своей задачи. Мне понадобилась примерно неделя, чтобы закончить первый прототип. Мне пришлось написать и серверную, и клиентскую часть, так что теперь я мог считать себя хотя бы младшим разработчиком полного стека. Для серверной части я использовал Flask (мне повезло не столкнуться с Django, иначе я бы потратил целый месяц), а для клиентской части – Bootstrap и Leaflet.

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

Однако я рад, что в наше время существует множество инструментов, позволяющих аналитикам и ученым-данным создавать прототипы за меньше часа. Во многих случаях такие прототипы могут повысить уровень вашей аналитики. Вот несколько примеров:

  • Прогноз дохода и аудитории в зависимости от входных параметров (например, бюджета маркетинга или рынков, на которых мы запустим новую функцию),
  • Инструменты, которые ускорят работу вашей команды или сократят ее (например, калькулятор A/B-тестирования или автоматический анализ корневой причины),
  • MVP-решения, например, если вы хотите использовать машинное обучение для автоматизации некоторых внутренних процессов, стоит протестировать прототип перед тем, как тратить время на производственную версию. В одной из моих предыдущих статей я поделился таким прототипом машинного обучения, «Создайте свое первое приложение глубокого обучения за час».

В этой статье я хотел бы рассказать вам об одной из таких рамок, которая может помочь вам быстро и практически без особых усилий создавать красивые веб-приложения без потребности в JavaScript и CSS. Мы узнаем основы Gradio, разработаем несколько веб-приложений и опубликуем их на HuggingFace Spaces, чтобы любой мог получить к ним доступ.

Gradio – не единственная рамка такого рода. Существует несколько других альтернативных библиотек на Python с открытым исходным кодом:

  • Streamlit – еще одна популярная и мощная библиотека для создания приложений для работы с данными с минимальным количеством кода. Она также поддерживается HuggingFace Spaces, поэтому вы можете размещать такие приложения.
  • Dash может быть удобен, если вы уже привыкли к Plotly, и предоставляет больше возможностей для настройки.
  • Однако, если вы хотите построить что-то особое и сложное, вашим последним спасением будут Flask или даже Django.

Подробнее о основных функциях различных фреймворков можно узнать в этой статье.

Основы Gradio

Gradio – это библиотека на Python с открытым исходным кодом, которая используется для создания интерактивных приложений.

Основные преимущества Gradio:

  • вы можете создавать приложения, используя только Python, что также означает, что вы можете использовать все библиотеки Python в вашем приложении,
  • вы можете запускать его в Jupyter Notebook или отдельной веб-странице,
  • вы можете постоянно размещать Gradio-приложения на пространствах HuggingFace.

Нет универсального решения, поэтому у Gradio есть свои ограничения:

  • Он явно разработан для применения в задачах машинного обучения. Поэтому, если вы используете его для других случаев, вам может потребоваться изменить значения по умолчанию (например, отключить флагирование с помощью allow_flagging = "never").
  • Ограничены возможности настройки, особенно при речи о дизайне.
  • Я бы имел в виду, что Gradio в первую очередь является фреймворком для быстрого прототипирования. В основном он работает хорошо, но иногда я сталкиваюсь с некоторым странным поведением. Например, редактирование таблицы в Safari работает нелогично или иногда вам нужно перезапустить Jupyter Notebook, чтобы интерфейс загрузился.

Чтобы начать использовать Gradio, нам нужно установить пакет Python.

pip install gradio

Следуя старой традиции программистов, давайте начнем с “Привет, мир!”

Мы можем использовать класс gr.Interface для определения интерфейса (документация). Это один из основных классов Gradio, который помогает создать веб-приложение на основе любой функции Python.

Нам нужно указать следующие параметры:

  • inputs: компоненты ввода интерфейса (в нашем случае просто текстовое поле),
  • outputs: компоненты вывода интерфейса (в нашем случае также просто текстовое поле),
  • fn: основной функционал (функция, которая получает входы и возвращает выходы, в нашем случае получает имя из ввода и возвращает “Привет, <имя>!”),
  • title & description: немного разметки, чтобы сделать наше приложение более удобным для пользователя.
import gradio as grdemo = gr.Interface(    inputs=[gr.Textbox(label="Имя", lines=1)],    outputs=[gr.Textbox(label="Результат", lines=1)],    fn=lambda x: 'Привет, %s!' % x,    title="Привет, мир!",    description="Ваше первое приложение с помощью Gradio",    allow_flagging='never')demo.launch()

Вы можете запустить этот код в своем Jupyter Notebook и увидеть результаты. Это довольно удобно для отладки. Позже мы обсудим, как сделать ваше веб-приложение доступным для других.

Изображение от автора

Вот и все: всего несколько строк кода, и ваше первое приложение Gradio работает. Также стоит отметить, что оно выглядит довольно красиво, и нам не пришлось использовать волшебство фронт-энда для этого.

Gradio запускает много процессов в фоновом режиме, когда вы работаете с Jupyter Notebook, поэтому время от времени стоит закрывать соединения с помощью gr.close_all().

Мы рассмотрели самый простой пример и увидели строительные блоки Gradio: входы, выходы и функции. Теперь мы готовы перейти к реальным аналитическим задачам.

Симуляция роста

В качестве первого примера рассмотрим влияние удержания на рост пользователей продукта.

Удержание как основа роста

Два параметра определяют рост продукта:

  • привлечение (количество новых пользователей за каждый период),
  • удержание (способность удерживать клиентов в продукте).

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

Мы можем описать любую кривую удержания с помощью следующей функции с набором параметров (a, b, c и d):

Давайте поговорим о наиболее распространенном случае удержания: когорта определяется первым действием в продукте, и все действия учитываются при удержании. В этом случае удержание для периоды = 0 должно быть равно 1 (потому что вход в когорту и события удержания совпадают). Таким образом, мы можем автоматически определить один из параметров:

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

Мы можем использовать эту формулу, чтобы определить кривую удержания. Итак, у нас есть все, что нам нужно, чтобы продолжить разработку.

Визуализация кривой удержания

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

Аналогично нашему примеру «Hello, World», нам нужно использовать класс gr.Interface и передать inputs, outputs и fn, чтобы их сопоставить.

  • Теперь нам нужно больше входных параметров. Поэтому inputs будет списком контролов. Мы будем использовать контролы gr.Slider и gr.Dropdown. Для gr.Slider нам нужно передать минимальное и максимальное значения, значения по умолчанию и метку, которую мы будем использовать в функции. Для gr.Dropdown нам нужно определить список возможных значений, значение по умолчанию и метку.
  • У нас по-прежнему будет только один выход — график, поэтому outputs будет gr.Plot без каких-либо параметров.
  • Функция fn будет сопоставлять входные параметры с выходами, поэтому она получит входные аргументы и вернет объект plotly.Figure, который будет визуализирован.
import plotly.express as px# функции для расчета удержанияdef get_retention(a, b, c, d, periods):    return  a + 1./(b + c * (periods ** d))def get_retention_same_event(a, c, d, periods):    b = 1./(1 - a)    return get_retention(a, b, c, d, periods)# определение функции - возврат графика в зависимости от входных параметровdef get_retention_plot(a, c, d, num_periods):    df = pd.DataFrame({'x': range(num_periods + 1)})    df['retention'] = df.x.map(lambda x: get_retention_same_event(a, c, d, x))    return px.line(df, x = 'x', y = 'retention',                   color_discrete_sequence = px.colors.qualitative.Prism,                   title = 'Кривая удержания', labels = {'x': 'период'})# определение входных параметровinputs = [    gr.Slider(0, 1, 0.03, label="a"),    gr.Slider(0, 5, 0.55, label="c"),    gr.Slider(0, 5, 1.5, label="d"),    gr.Dropdown([10, 30, 60, 90], value = 30, label="Количество периодов"),    gr.Dropdown([10, 100, 1000, 10000], value = 10000, label="Количество новых пользователей каждый период")]# определение выходовoutputs = gr.Plot()# определение интерфейсаdemo = gr.Interface(    fn=get_retention_plot,    inputs=inputs,    outputs=outputs,    cache_examples=True,    allow_flagging = 'never' # скрытие функциональности флагов по умолчанию на интерфейсе)# запускdemo.launch(debug = True)

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

Добавление больше графиков

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

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

Нам нужно внести всего несколько изменений в нашу реализацию:

  • Измените функцию get_retention_plot, чтобы она получала еще один параметр для размера когорты, рассчитывала количество пользователей с течением времени и возвращала три диаграммы.
  • Параметр outputs теперь равен списку из трех объектов gr.Plot().
def get_retention_plot(a, c, d, num_periods, cohort_size):    ret_df = pd.DataFrame({'x': range(num_periods + 1)})    ret_df['retention'] = ret_df.x.map(lambda x: get_retention_same_event(a, c, d, x))        ret_fig = px.line(ret_df.iloc[1:], x = 'x', y = 'retention',                       color_discrete_sequence = px.colors.qualitative.Prism,                       title = 'Кривая удержания')    # simulation    tmp_data = []    for cohort in range(num_periods + 1):        for cohort_period in range(num_periods + 1):            period = cohort_period + cohort            if period > num_periods:                continue            retention = get_retention_same_event(a, c, d, cohort_period)            tmp_data.append(                {                    'cohort': 'когорта %s' % str(cohort).rjust(3, '0'),                    'cohort_period': cohort_period,                    'period': period,                    'retention': retention,                    'users': int(round(retention * cohort_size))                }            )    users_df = pd.DataFrame(tmp_data)    users_fig = px.area(users_df.groupby('period').users.sum(),                    color_discrete_sequence = px.colors.qualitative.Prism,                       title = 'Активные пользователи')    cohorts_fig = px.area(users_df.pivot_table(index = 'period', columns = 'cohort', values = 'users',                    aggfunc = 'sum'),                    color_discrete_sequence = px.colors.qualitative.Prism,                     title = 'Активные пользователи по когортам')    return ret_fig, users_fig, cohorts_figinputs = [    gr.Slider(0, 1, 0.03, label="a"),    gr.Slider(0, 5, 0.55, label="c"),    gr.Slider(0, 5, 1.5, label="d"),    gr.Dropdown([10, 30, 60, 90], value = 30, label="Количество периодов"),    gr.Dropdown([10, 100, 1000, 10000], value = 10000, label="Количество новых пользователей каждый период")]outputs = [gr.Plot(), gr.Plot(),  gr.Plot()]demo = gr.Interface(    fn=get_retention_plot,    inputs=inputs,    outputs=outputs,    allow_flagging = 'never',    cache_examples=True,)demo.launch(debug = True)

Фантастика, теперь мы можем увидеть полную картину и проанализировать взаимосвязи. Однако есть место для улучшений – мы можем добавить форматирование, чтобы наше приложение было более удобным для пользователей.

Изображение автора

Добавление немного стиля

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

Для этого мы будем использовать gr.Blocks() в качестве контекста. Эта функциональность позволяет создавать более настраиваемые веб-приложения и определять макеты и потоки данных (события, которые запускают функции и последующее выполнение).

Блоки откроют нам новые возможности:

  • С помощью gr.Blocks() мы можем использовать gr.Row() и gr.Column() для организации макета.
  • gr.Markdown позволяет добавлять элементы разметки, например, заголовок или даже LaTeX с формулами (по умолчанию их нужно помещать внутри $).
  • gr.Accordion может помочь скрыть некоторые параметры, которые вы не хотите показывать пользователю по умолчанию.
  • Также такой подход позволяет определить более сложную логику обновлений. Например, обновлять диаграммы не только при нажатии кнопки отправки, но и при изменении любого входного параметра. Мы будем использовать эту функциональность в следующем примере.

При работе с блоками нам нужно определить каждый вход и выход как переменные, например, a = gr.Slider(0, 1, 0.03, label=”a”).

Также нет стандартных элементов управления, поэтому мы должны определить кнопки сами — btn_caption = gr.Button(“Submit”).

Действие при нажатии кнопки также должно быть указано, устанавливая уже знакомые параметры — inputs, outputs и fn.

btn_caption.click(fn=get_retention_plot,         inputs=[a, c, d, num_periods, cohort_size],         outputs=[plot1, plot2, plot3])

Вот полная версия кода.

with gr.Blocks() as demo:    gr.Markdown("# Понимание роста 🚀")    with gr.Row():        with gr.Column():            gr.Markdown("## Параметры кривой удержания 📈")            gr.Markdown(r"$\textbf{удержание}(\textsf{x}) = \textsf{a} + \frac{\textsf{1}}{\textsf{b} + \textsf{c} * \textsf{x}^{\textsf{d}}}\ где\ \textsf{b} = \frac{\textsf{1}}{\textsf{1}-\textsf{a}}$")            with gr.Row():                a = gr.Slider(0, 1, 0.03, label="a")                c = gr.Slider(0, 5, 0.55, label="c")                d = gr.Slider(0, 5, 1.5, label="d")            with gr.Accordion("Дополнительные параметры", open=False):                with gr.Row():                    num_periods = gr.Dropdown([10, 30, 60, 90], value = 30, label="Количество периодов")                    cohort_size = gr.Dropdown([10, 100, 1000, 10000], value = 10000, label="Количество новых пользователей в каждом периоде")            btn_caption = gr.Button("Submit")        with gr.Column():            plot1 = gr.Plot()    with gr.Row():        plot2 = gr.Plot()        plot3 = gr.Plot()        btn_caption.click(fn=get_retention_plot,         inputs=[a, c, d, num_periods, cohort_size],         outputs=[plot1, plot2, plot3])demo.launch()

Хостинг вашего приложения

Также мы можем использовать HuggingFace Spaces для хостинга наших веб-приложений и легкого обмена ими с другими.

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

Следующим шагом является создание нового Space. Инструкции с более подробной информацией можно найти в документации.

Изображение от автора

Для нового Space вам нужно заполнить следующие параметры: имя, лицензия и Gradio как ваш SDK.

Изображение от автора

Затем вам нужно зафиксировать свой код в репозитории Git из Hugging Spaces. Прежде всего, нам нужно склонировать репозиторий.

-- клонирование репогит clone https://huggingface.co/spaces/<your_login>/<your_app_name>cd <your_app_name>

Недавно HuggingFace изменил процесс аутентификации в Git, поэтому сначала нам нужно создать токен, а затем установить его для Git-репо.

git remote set-url origin https://<your_login>:<token>@huggingface.co/spaces/<your_login>/<your_app_name>git pull origin

Теперь пришло время зафиксировать файлы, связанные с нашим приложением. Нам нужно иметь по крайней мере следующие файлы:

  • app.py с кодом Python, который запускает приложение Gradio
  • requirements.txt со списком пакетов Python, необходимых для вашего приложения. В нашем случае – только pandas и plotly.

Затем базовые шаги с git: добавить, зафиксировать и отправить в HuggingFaces.

git add app.pygit add requirements.txtgit commit -m 'Первая версия приложения симулятора удержания'git push

На создание приложения ушло пару минут, и оно готово. Теперь наше веб-приложение работает на платформе HuggingFaces Spaces. Вы можете попробовать его здесь.

Изображение автора

Выглядит намного лучше, чем наша первоначальная версия, поскольку макет не требует прокрутки, и пользователям не нужно догадываться, что означают параметры a, c и d.

Прогнозирование удержания

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

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

Давайте не будем тратить время зря и перейдем к реализации.

Получение данных из файлов

Вот код, который генерирует всего интерфейс и бизнес-логику. Он может выглядеть немного сложным. Не беспокойтесь. Мы обсудим основные моменты позже.

# анализирует файл или строку и возвращает фрейм данныхdef parse_file(input_text_or_file, num_periods):    if isinstance(input_text_or_file, str):        df = pd.read_csv(StringIO(input_text_or_file), sep = '\t')    else:        df = pd.read_csv(input_text_or_file.name, sep = '\t')    return df# принимает фрейм данных и возвращает графикdef show_graph_for_df(df, num_periods):    df['period'] = df.period.map(int)    df['retention_fact'] = df.retention_fact.map(float)    result = scipy.optimize.minimize(lambda x: get_mse_for_retention(x, df), [random.random(), random.random(), random.random()])    a, c, d = result.x    pred_df = pd.DataFrame({'period': range(num_periods + 1)})    pred_df['retention_pred'] = pred_df.period.map(lambda x: get_retention_same_event(a, c, d, x))    pred_df = pred_df.merge(df, how = 'left')        fig = go.Figure()    fig.add_trace(go.Scatter(x=pred_df.period, y=pred_df.retention_fact, name='факт',                             line=dict(color=plotly.colors.qualitative.Prism[0], width=3)))        fig.add_trace(go.Scatter(x=pred_df.period, y=pred_df.retention_pred, name='прогноз',                             line=dict(color=plotly.colors.qualitative.Prism[0], width=3, dash='dot')))        fig.update_layout(title='Модель дневного удержания (a = %.2f, c = %.2f, d = %.2f)' % (a, c, d),                       yaxis_title='удержание',                       xaxis_title='период')    return fig# принимает файл и возвращает графикdef show_graph_for_file(temp_file, num_periods):    df = parse_file(temp_file, num_periods)    return show_graph_for_df(df, num_periods)# жестко закодированный пример данныхdefault_csv = 'period\tretention_fact\n0\t1\n1\t0.55\n2\t0.4\n3\t0.35\n4\t0.3\n'# интерфейс с помощью gr.Blocks() as demo:    gr.Markdown('# Прогнозирование кривой удержания 📊')    periods = gr.Dropdown([10, 30, 90, 180], label="Количество периодов", value = 30)    gr.Markdown('Загрузите файл .csv с данными, используйте данные по умолчанию в качестве примера или введите числа вручную в разделе Загруженные данные.')    gr.Markdown('''__Формат файла:__ 2 столбца (`period` и `retention_fact`)''')        with gr.Row():        upload_button = gr.UploadButton(label="Загрузить файл", file_types = ['.csv'], live=True, file_count = "single")        default_button = gr.Button('Показать пример')        with gr.Row():        with gr.Accordion("Загруженные данные", open=False):            gr.Markdown('Вы можете изменять значения в таблице')            table = gr.Dataframe(type="pandas", col_count=2, interactive = True, headers = ['period', 'retention_fact'])                with gr.Row():            image = gr.Plot()        # бизнес-логика триггеров и событий    upload_button.upload(fn=show_graph_for_file, inputs=[upload_button, periods], outputs=image, api_name="upload_graph")    upload_button.upload(fn=parse_file, inputs=[upload_button, periods], outputs=table, api_name="upload_csv")    default_button.click(fn=lambda x: show_graph_for_file(default_csv, x), inputs=[periods], outputs=image, api_name="upload_example_graph")    default_button.click(fn=lambda x: parse_file(default_csv, x), inputs=[periods], outputs=table, api_name="upload_example_csv")    table.change(fn=show_graph_for_df, inputs=[table, periods], outputs=image, api_name="upload_table_graph")    periods.change(fn=show_graph_for_df, inputs=[table, periods], outputs=image, api_name="upload_periods_graph")demo.launch(debug=True)

Давайте рассмотрим это поближе. В интерфейсе у нас есть следующие элементы:

  • periods — входной параметр,
  • upload_button — входной параметр, который позволяет загружать данные из файла .csv,
  • default_button — позволяет обновить таблицу и график с предопределенными значениями как пример,
  • table показывает фрейм данных из загруженных данных (из файла .csv или примера); также, вы можете изменить числа в таблице на месте, и график будет обновлен — так что это тоже входной параметр,
  • image — выходной параметр, который показывает график.
Изображение автора

Функция parse_file получает либо файл из upload_button, либо строку из примера по умолчанию и возвращает pandas дата фрейм, который мы можем использовать дальше. Так что использование данных из файлов довольно просто.

Решающая бизнес-логика определена в следующем фрагменте кода. Он определяет действия для всех элементов интерфейса:

  • для загрузки файла формата .csv — таблица и график обновляются,
  • для нажатия на кнопку “Показать пример” — таблица и график обновляются,
  • для изменения данных в таблице — обновляется только график,
  • для изменения количества периодов — обновляется только график.
upload_button.upload(fn=show_graph_for_file, inputs=[upload_button, periods], outputs=image, api_name="upload_graph")upload_button.upload(fn=parse_file, inputs=[upload_button, periods], outputs=table, api_name="upload_csv")default_button.click(fn=lambda x: show_graph_for_file(default_csv, x), inputs=[periods], outputs=image, api_name="upload_example_graph")default_button.click(fn=lambda x: parse_file(default_csv, x), inputs=[periods], outputs=table, api_name="upload_example_csv")table.change(fn=show_graph_for_df, inputs=[table, periods], outputs=image, api_name="upload_table_graph")periods.change(fn=show_graph_for_df, inputs=[table, periods], outputs=image, api_name="upload_periods_graph")

Определение функции наилучшей подгонки

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

  • Сначала мы определяем функцию get_mse_for_retention, которая возвращает ошибку для заданного набора параметров (a, c и d). В качестве ошибки мы используем стандартное среднее квадратичное отклонение (MSE).
  • Затем мы используем функцию scipy.optimize.minimize для оптимизации. Нам нужно передать только два параметра: функцию для оптимизации (мы передали лямбда-функцию с жестко заданным дата фреймом, так как мы оптимизируем только параметры) и начальные значения для параметров (просто список случайных значений).
  • После оптимизации мы можем получить оптимальные параметры, используя result.x.
def get_mse_for_retention(params, df):    tmp_df = df.copy()    tmp_df['retention_pred'] = tmp_df.index.map(        lambda x: get_retention_same_event(params[0], params[1], params[2], x)    )        tmp_df['se'] = (tmp_df.retention_fact - tmp_df.retention_pred)    tmp_df['se'] = tmp_df['se']**2        return tmp_df.se.mean() ** 0.5result = scipy.optimize.minimize(lambda x: get_mse_for_retention(x, df), [random.random(), random.random(), random.random()])a, c, d = result.xprint(a, c, d)

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

Последний шаг

Я следовал тем же инструкциям и также разместил это приложение в пространстве HuggingFace Spaces. Так что вы можете попробовать поиграть с ним здесь.

Вы можете найти весь код для обоих приложений в GitHub.

Резюме

В этой статье мы прошли основы библиотеки Gradio и научились создавать приятные веб-приложения только с помощью Python.

Мы изучили несколько подходов:

  • Высокоуровневый класс gr.Interface, который позволяет создавать рабочий прототип быстро,
  • Более настраиваемый способ использования gr.Blocks, где вы можете указать точное расположение, которое вам нужно, и определить сложные взаимосвязи между входами и выходами.

Большое спасибо за чтение этой статьи. Надеюсь, она была полезной для вас. Если у вас есть какие-либо вопросы или комментарии, пожалуйста, оставьте их в разделе комментариев.

Ссылка

Эта статья вдохновлена курсом “Building Generative AI Applications with Gradio” course.