
Лаборатория исследований безопасности, воспроизводящая CVE-2023-6572 (GHSA-gqvf-3hgp-5hxv): внедрение команд в обработке workflow_run в gradio-app/gradio для generate-changeset.yml
Автоматизированный исследовательский артефакт — не вышестоящий проект.
Этот репозиторий — одноразовая лаборатория, созданная автоматизированной системой для магистерской диссертации в Université Laval по воспроизведению опубликованных уязвимостей в рабочих процессах GitHub Actions. Это точный снимок
gradio-app/gradioна коммите1d986217f6f4fc1829e528d2afe365635788204f(2023-11-03), распространённый под собственной лицензией этого проекта, файл которой включён в этот снимок без изменений.Вышестоящий проект не участвует, никогда не является целью, а изучаемая здесь уязвимость уже публична. Каждый секрет и переменная в этом репозитории — случайно сгенерированное фиктивное значение — никаких реальных учётных данных здесь нет. Ссылки на действия и образы раннеров закреплены на те значения, которым они соответствовали на 2023-11-03; см.
pinning.mdв выводе системы для каждого изменения, внесённого в снимок.Вопросы или возражения: [email protected]
Website | Documentation | Guides | Getting Started | Examples | 中文
Gradio — это библиотека Python с открытым исходным кодом, которая используется для создания демо-версий и веб-приложений для машинного обучения и науки о данных.
С помощью Gradio вы можете быстро создать красивый пользовательский интерфейс вокруг ваших моделей машинного обучения или рабочих процессов науки о данных и позволить людям «попробовать его» — перетаскивая собственные изображения, вставляя текст, записывая свой голос и взаимодействуя с вашим демо — всё через браузер.

Gradio полезен для:
Демонстрации ваших моделей машинного обучения клиентам/коллегам/пользователям/студентам.
Развёртывания ваших моделей быстро с автоматическими ссылками для публикации и получения обратной связи о производительности модели.
Отладки вашей модели интерактивно во время разработки с помощью встроенных инструментов манипуляции входными данными.
Предварительное требование: Gradio требует Python 3.8 или выше, и это всё!
Один из лучших способов поделиться вашей моделью машинного обучения, API или рабочим процессом науки о данных с другими — это создать интерактивное приложение, которое позволит вашим пользователям или коллегам попробовать демо в своих браузерах.
Gradio позволяет вам создавать демо и делиться ими, всё на Python. И обычно всего в нескольких строках кода! Итак, давайте начнём.
Чтобы запустить Gradio с простым примером «Hello, World», выполните следующие три шага:
1. Установите Gradio с помощью pip:
pip install gradio
2. Запустите код ниже как Python-скрипт или в Jupyter Notebook (или Google Colab):
import gradio as gr
def greet(name):
return "Hello " + name + "!"
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
demo.launch()
Мы сокращаем импортированное имя до gr для лучшей читаемости кода, использующего Gradio. Это широко принятая конвенция, которой вы должны следовать, чтобы любой, кто работает с вашим кодом, мог легко его понять.
3. Демо ниже появится автоматически внутри Jupyter Notebook или откроется в браузере на http://localhost:7860, если запущено из скрипта:

При локальной разработке, если вы хотите запустить код как Python-скрипт, вы можете использовать CLI Gradio для запуска приложения в режиме перезагрузки, который обеспечит бесшовную и быструю разработку. Узнайте больше о перезагрузке в Руководстве по автоперезагрузке.
gradio app.py
Примечание: вы также можете выполнить python app.py, но это не обеспечит механизм автоматической перезагрузки.
InterfaceВы заметите, что для создания демо мы создали gr.Interface. Этот класс Interface может обернуть любую Python-функцию в пользовательский интерфейс. В примере выше мы видели простую текстовую функцию, но функция может быть чем угодно — от генератора музыки до калькулятора налогов или функции предсказания предобученной модели машинного обучения.
Основной класс Interface инициализируется с тремя обязательными параметрами:
fn: функция, вокруг которой создаётся интерфейсinputs: какие компоненты использовать для ввода (например, "text", "image" или "audio")outputs: какие компоненты использовать для вывода (например, "text", "image" или "label")Давайте подробнее рассмотрим эти компоненты, используемые для ввода и вывода.
В предыдущих примерах мы видели простые компоненты Textbox, но что если вы хотите изменить внешний вид или поведение компонентов интерфейса?
Допустим, вы хотите настроить поле ввода текста — например, сделать его больше и добавить текст-подсказку. Если использовать фактический класс Textbox вместо строкового сокращения, у вас будет доступ к гораздо большей настраиваемости через атрибуты компонентов.
import gradio as gr
def greet(name):
return "Hello " + name + "!"
demo = gr.Interface(
fn=greet,
inputs=gr.Textbox(lines=2, placeholder="Name Here..."),
outputs="text",
)
demo.launch()

Предположим, у вас есть более сложная функция с несколькими входами и выходами. В примере ниже мы определяем функцию, которая принимает строку, логическое значение и число, а возвращает строку и число. Посмотрите, как передать список компонентов ввода и вывода.
import gradio as gr
def greet(name, is_morning, temperature):
salutation = "Good morning" if is_morning else "Good evening"
greeting = f"{salutation} {name}. It is {temperature} degrees today"
celsius = (temperature - 32) * 5 / 9
return greeting, round(celsius, 2)
demo = gr.Interface(
fn=greet,
inputs=["text", "checkbox", gr.Slider(0, 100)],
outputs=["text", "number"],
)
demo.launch()

Вы просто оборачиваете компоненты в список. Каждый компонент в списке inputs соответствует одному из параметров функции, по порядку. Каждый компонент в списке outputs соответствует одному из значений, возвращаемых функцией, также по порядку.
Gradio поддерживает множество типов компонентов, таких как Image, DataFrame, Video или Label. Давайте попробуем функцию преобразования изображения в изображение, чтобы почувствовать их!
import numpy as np
import gradio as gr
def sepia(input_img):
sepia_filter = np.array([
[0.393, 0.769, 0.189],
[0.349, 0.686, 0.168],
[0.272, 0.534, 0.131]
])
sepia_img = input_img.dot(sepia_filter.T)
sepia_img /= sepia_img.max()
return sepia_img
demo = gr.Interface(sepia, gr.Image(width=200, height=200), "image")
demo.launch()

При использовании компонента Image в качестве ввода ваша функция получит массив NumPy с формой (height, width, 3), где последнее измерение представляет значения RGB. Мы также вернём изображение в виде массива NumPy.
Вы также можете задать тип данных, используемый компонентом, с помощью аргумента type=. Например, если вы хотите, чтобы ваша функция принимала путь к файлу изображения вместо массива NumPy, компонент ввода Image можно записать так:
gr.Image(type="filepath", shape=...)
Также обратите внимание, что наш компонент ввода Image имеет кнопку редактирования 🖉, которая позволяет обрезать и масштабировать изображения. Такая манипуляция изображениями может помочь выявить предвзятости или скрытые недостатки модели машинного обучения!
Вы можете узнать больше о множестве компонентов и о том, как их использовать, в документации Gradio.
Gradio включает высокоуровневый класс gr.ChatInterface, который похож на gr.Interface, но специально разработан для интерфейсов чат-ботов. Класс gr.ChatInterface также оборачивает функцию, но эта функция должна иметь определённую сигнатуру. Функция должна принимать два аргумента: message и затем history (аргументы можно называть как угодно, но порядок должен быть таким):
message: str, представляющий ввод пользователяhistory: list из list, представляющий разговоры до этого момента. Каждый внутренний список состоит из двух str, представляющих пару: [ввод пользователя, ответ бота].Ваша функция должна возвращать одну строку — ответ бота на конкретный ввод пользователя message.
В остальном gr.ChatInterface не имеет обязательных параметров (хотя доступно несколько для настройки интерфейса).
Вот игрушечный пример:
import random
import gradio as gr
def random_response(message, history):
return random.choice(["Yes", "No"])
demo = gr.ChatInterface(random_response)
demo.launch()

Вы можете узнать больше о gr.ChatInterface здесь.
Gradio предлагает два подхода к созданию приложений:
1. Interface и ChatInterface, которые предоставляют высокоуровневую абстракцию для создания демо, о которой мы говорили до сих пор.
2. Blocks, низкоуровневый API для проектирования веб-приложений с более гибкими макетами и потоками данных. Blocks позволяет делать такие вещи, как поддержка нескольких потоков данных и демо, контроль расположения компонентов на странице, обработка сложных потоков данных (например, выходы могут служить входами для других функций) и обновление свойств/видимости компонентов на основе взаимодействия с пользователем — и всё это на Python. Если вам нужна такая настраиваемость, попробуйте Blocks!
Давайте посмотрим на простой пример. Обратите внимание, как API здесь отличается от Interface.
import gradio as gr
def greet(name):
return "Hello " + name + "!"
with gr.Blocks() as demo:
name = gr.Textbox(label="Name")
output = gr.Textbox(label="Output Box")
greet_btn = gr.Button("Greet")
greet_btn.click(fn=greet, inputs=name, outputs=output, api_name="greet")
demo.launch()

На что обратить внимание:
Blocks создаются с помощью конструкции with, и любой компонент, созданный внутри этой конструкции, автоматически добавляется в приложение.Button, а затем к этой кнопке добавлен обработчик события click. API для этого должен выглядеть знакомо! Как и Interface, метод click принимает Python-функцию, компоненты ввода и компоненты вывода.Вот приложение, которое даст вам представление о том, что возможно с Blocks:
import numpy as np
import gradio as gr
def flip_text(x):
return x[::-1]
def flip_image(x):
return np.fliplr(x)
with gr.Blocks() as demo:
gr.Markdown("Flip text or image files using this demo.")
with gr.Tab("Flip Text"):
text_input = gr.Textbox()
text_output = gr.Textbox()
text_button = gr.Button("Flip")
with gr.Tab("Flip Image"):
with gr.Row():
image_input = gr.Image()
image_output = gr.Image()
image_button = gr.Button("Flip")
with gr.Accordion("Open for More!"):
gr.Markdown("Look at me...")
text_button.click(flip_text, inputs=text_input, outputs=text_output)
image_button.click(flip_image, inputs=image_input, outputs=image_output)
demo.launch()

Здесь происходит гораздо больше! Мы расскажем, как создавать такие сложные приложения на Blocks, в разделе building with blocks.
Поздравляем, теперь вы знакомы с основами Gradio! 🥳 Переходите к нашему следующему руководству, чтобы узнать больше о ключевых функциях Gradio.
Gradio построен на множестве замечательных библиотек с открытым исходным кодом, пожалуйста, поддержите их тоже!
Gradio распространяется под лицензией Apache License 2.0, которая находится в файле LICENSE в корневом каталоге этого репозитория.
Также ознакомьтесь со статьёй Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild, ICML HILL 2019, и, пожалуйста, цитируйте её, если используете Gradio в своей работе.
@article{abid2019gradio,
title = {Gradio: Hassle-Free Sharing and Testing of ML Models in the Wild},
author = {Abid, Abubakar and Abdalla, Ali and Abid, Ali and Khan, Dawood and Alfozan, Abdulrahman and Zou, James},
journal = {arXiv preprint arXiv:1906.02569},
year = {2019},
}