Как размещать модели и датасеты на Hugging Face Spaces с помощью Streamlit: пошаговое руководство
Пошаговое руководство по созданию интерактивных демо ML-моделей и визуализации датасетов на Hugging Face Spaces с помощью Streamlit. Готовые примеры кода, настройка зависимостей и публикация за несколько минут.
Вы обучили модель машинного обучения или подготовили интересный датасет и хотите показать результат коллегам, заказчику или всему сообществу. Самый быстрый способ сделать это без аренды серверов и настройки веб-инфраструктуры - использовать связку Hugging Face Spaces и Streamlit. Вы загружаете файлы, пишете короткий скрипт на Python и через несколько минут получаете публичную ссылку на работающее веб-приложение. Никакой магии: платформа берёт на себя хостинг, установку зависимостей и перезапуск приложения при каждом обновлении кода. В этом руководстве мы последовательно разберём весь путь - от создания пустого Space до публикации интерактивного демо с моделью генерации текста и визуализацией датасета.
Почему Hugging Face Spaces и Streamlit - идеальная пара для демонстрации AI-проектов
Специалисты по машинному обучению регулярно сталкиваются с проблемой: модель готова, метрики на тестовой выборке выглядят убедительно, но показать её работу вживую негде. Традиционные варианты - поднимать собственный сервер, настраивать Docker-контейнеры, арендовать облачные инстансы - требуют времени и дополнительных компетенций в DevOps. Для небольших команд и независимых разработчиков этот порог часто оказывается слишком высоким.
Hugging Face Spaces решает эту задачу радикально. Платформа предоставляет бесплатный хостинг для веб-приложений с поддержкой двух фреймворков из коробки: Streamlit и Gradio. Вы просто создаёте репозиторий, добавляете файлы с кодом и получаете готовый URL. Никаких счетов за хостинг на старте, никакой возни с сертификатами и балансировщиками нагрузки. Streamlit, в свою очередь, превращает Python-скрипт в интерактивное веб-приложение без единой строки HTML, CSS или JavaScript. Вы описываете интерфейс привычными вызовами функций - st.slider, st.button, st.dataframe - и фреймворк сам рендерит страницу в браузере.
Вместе эти два инструмента дают результат, который раньше требовал связки из трёх-четырёх разных сервисов. Вы фокусируетесь на сути - модели и данных - а платформа закрывает всё остальное. Такой подход перекликается с общей философией Hugging Face: сделать технологии машинного обучения доступными. Мы уже рассказывали, как превратить тысячи моделей в работающие веб-демо одной строкой кода с Gradio и как развернуть любую модель на Amazon SageMaker за пять минут. Сегодня мы детально разберём связку Spaces + Streamlit - самый простой маршрут для быстрого прототипирования.
Первые шаги: создание Spaces и загрузка файлов
Для начала работы нужна учётная запись на Hugging Face. Регистрация бесплатна и занимает пару минут. После входа в аккаунт нажмите на аватар в правом верхнем углу и выберите «New Space». Платформа предложит заполнить несколько полей: название Space, лицензию и - самое важное - выбрать SDK. Укажите Streamlit. Через несколько секунд система создаст пустой репозиторий, готовый к приёму файлов.
Загрузить код можно двумя способами. Первый - через веб-интерфейс: перетащите файлы прямо в окно браузера, и они окажутся в репозитории. Второй - через Git: клонируйте репозиторий командой git clone, добавьте файлы локально и выполните git push. Оба варианта работают одинаково надёжно. Как только в репозитории появляется файл app.py, Space автоматически запускает сборку: устанавливает зависимости, перечисленные в requirements.txt, и стартует приложение. Логи сборки отображаются в реальном времени - если что-то пойдёт не так, вы сразу увидите ошибку.
Для проверки работоспособности создайте минимальный app.py с таким содержимым:
import streamlit as st
st.title("Моё первое демо")
st.write("Привет, Hugging Face Spaces!")
Сохраните файл, дождитесь окончания сборки и откройте сгенерированный URL. Вы увидите работающее веб-приложение. Это база, от которой мы будем отталкиваться дальше.
Структура проекта: что должно быть в репозитории
Минимальный набор для запуска Streamlit-приложения на Spaces состоит из двух файлов: app.py и requirements.txt. Первый - точка входа, именно его платформа ищет при старте. Второй - список Python-зависимостей, которые нужно установить перед запуском. Без requirements.txt сборка, скорее всего, упадёт, потому что в стандартном окружении нет ни transformers, ни pandas, ни даже самого streamlit (на практике Streamlit предустановлен, но явное указание зависимости - хороший тон).
Для более сложных проектов структура может включать:
packages.txt- системные пакеты, устанавливаемые через apt-get (например,libmagic-devдля работы с файлами);- папку с файлами модели - если модель не загружается на лету из Hugging Face Hub, а лежит локально;
- папку с данными - CSV-файлы, изображения, любые статические ресурсы;
- дополнительные Python-модули - если логика приложения разнесена по нескольким файлам.
Всё это просто размещается рядом с app.py. Платформа не накладывает ограничений на структуру директорий - работают стандартные правила импорта Python.
Оживляем модель: воссоздаём «Write with Transformer» с настройкой гиперпараметров
Оригинальное приложение «Write with Transformer» от Hugging Face в своё время наглядно продемонстрировало, как нейросеть дописывает текст за пользователем. Мы воссоздадим его упрощённую, но полностью функциональную версию с помощью Streamlit. За основу возьмём модель GPT-2 - она достаточно компактна, чтобы быстро стартовать на бесплатном CPU-окружении Spaces, и при этом выдаёт осмысленные продолжения текста.
Код приложения состоит из трёх логических блоков: загрузка модели и токенизатора, создание элементов интерфейса и вызов генерации по нажатию кнопки. Вот как это выглядит:
import streamlit as st
from transformers import pipeline
@st.cache_resource
def load_model():
return pipeline("text-generation", model="gpt2")
generator = load_model()
st.title("Write with Transformer (Streamlit-версия)")
prompt = st.text_area("Введите начало текста:", value="Искусственный интеллект - это")
temperature = st.slider("Температура", min_value=0.1, max_value=2.0, value=0.8, step=0.1)
top_p = st.slider("Top-p (nucleus sampling)", min_value=0.1, max_value=1.0, value=0.9, step=0.05)
max_length = st.slider("Максимальная длина", min_value=20, max_value=200, value=80, step=10)
if st.button("Сгенерировать"):
with st.spinner("Модель думает..."):
result = generator(
prompt,
max_length=max_length,
temperature=temperature,
top_p=top_p,
do_sample=True
)
st.write(result[0]["generated_text"])
Разберём ключевые моменты. Декоратор @st.cache_resource гарантирует, что модель загрузится только один раз - при первом обращении. При последующих взаимодействиях с интерфейсом (передвинули слайдер, нажали кнопку) Streamlit не будет заново скачивать и инициализировать GPT-2, а возьмёт уже готовый объект из кэша. Это критически важно для скорости работы: загрузка модели может занимать десятки секунд, а с кэшированием ответ на действия пользователя приходит мгновенно.
Функция pipeline("text-generation", model="gpt2") - это высокоуровневая обёртка из библиотеки Transformers, которая скрывает под капотом токенизацию, прямой проход через модель и декодирование ответа. Вы можете заменить gpt2 на любую другую модель генерации текста из Hugging Face Hub - например, "sberbank-ai/rugpt3small_based_on_gpt2" для русского языка.
Добавляем интерактивность: слайдеры, выпадающие списки и чекбоксы
Streamlit предоставляет набор виджетов, которые покрывают практически все сценарии настройки моделей. В примере выше мы использовали st.slider для непрерывных параметров - температуры и top-p. Этот виджет удобен, когда параметр принимает значения из диапазона и пользователю полезно визуально оценить выбранный уровень. Для дискретных опций лучше подходит st.selectbox - например, чтобы дать пользователю выбор между несколькими предобученными моделями:
model_name = st.selectbox(
"Выберите модель:",
("gpt2", "distilgpt2", "gpt2-medium")
)
Чекбоксы через st.checkbox хороши для бинарных флагов - включать ли жадное декодирование вместо сэмплирования, применять ли штраф за повторения. Радиокнопки (st.radio) подходят для взаимоисключающих вариантов. Все значения, возвращаемые виджетами, - это обычные переменные Python, которые можно сразу передавать в функцию генерации. Никаких колбэков, никакого управления состоянием вручную - Streamlit сам отслеживает изменения и перезапускает скрипт при каждом взаимодействии пользователя с интерфейсом.
Связка виджетов с гиперпараметрами модели выглядит естественно: каждый слайдер или выпадающий список соответствует одному аргументу функции generator(). Это позволяет даже неспециалисту осмысленно экспериментировать с поведением нейросети, не заглядывая в код.
Визуализация датасетов: от загрузки CSV до красивых графиков
Показывать работу модели - только половина дела. Часто нужно представить данные, на которых модель обучалась или которые получились в результате её работы. Hugging Face Spaces отлично справляется с ролью хостинга для интерактивных дашбордов. Разберём пример: загружаем классический датасет Ирисов Фишера, выводим таблицу и строим графики с возможностью выбора осей.
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
st.title("Визуализация датасета Ирисов Фишера")
df = pd.read_csv("iris.csv")
st.subheader("Таблица данных")
st.dataframe(df)
st.subheader("График рассеяния")
col1, col2 = st.columns(2)
with col1:
x_axis = st.selectbox("Ось X", df.columns[:-1])
with col2:
y_axis = st.selectbox("Ось Y", df.columns[:-1], index=1)
fig, ax = plt.subplots()
sns.scatterplot(data=df, x=x_axis, y=y_axis, hue="species", ax=ax)
st.pyplot(fig)
st.subheader("Распределение признаков")
feature = st.selectbox("Выберите признак:", df.columns[:-1])
fig2, ax2 = plt.subplots()
sns.histplot(data=df, x=feature, hue="species", kde=True, ax=ax2)
st.pyplot(fig2)
Этот скрипт создаёт страницу с тремя секциями: таблица, график рассеяния и гистограмма распределения. Пользователь выбирает, какие колонки отложить по осям, и графики перестраиваются мгновенно. st.dataframe выводит интерактивную таблицу с сортировкой и поиском - удобнее, чем статичная картинка. Функция st.pyplot встраивает matplotlib-график прямо в страницу, автоматически подгоняя размер под ширину контента.
Датасет iris.csv должен лежать в корне репозитория рядом с app.py. Вы можете заменить его на любой другой CSV-файл - данные опроса, результаты A/B-теста, логи модели. Streamlit не ограничивает объём данных, но стоит помнить, что на бесплатном тарифе Spaces доступно 16 ГБ оперативной памяти - для большинства исследовательских датасетов этого хватает с запасом.
Работа с requirements.txt: какие библиотеки указать
Файл requirements.txt - это список зависимостей, который платформа использует при сборке окружения. Для NLP-демо с моделью генерации текста он выглядит так:
streamlit==1.28.1
transformers==4.35.0
torch==2.1.0
Для приложения с визуализацией данных набор другой:
streamlit==1.28.1
pandas==2.1.3
matplotlib==3.8.2
seaborn==0.13.0
Версии зафиксированы для воспроизводимости: если через полгода выйдет новая мажорная версия библиотеки с ломающими изменениями, ваше демо продолжит работать. Если версии не указывать, платформа установит последние доступные - это быстрее на старте, но рискованнее в долгосрочной перспективе. Если вы используете GPU-версию Space (доступна за дополнительную плату), замените torch на torch==2.1.0+cu118 с соответствующим индексом.
Системные зависимости, которые нельзя установить через pip, перечисляются в packages.txt - по одному названию пакета на строку. Например, для работы с аудиофайлами может понадобиться ffmpeg, для обработки изображений - libgl1.
Публикация и совместное использование: как показать проект миру
Как только сборка завершилась успешно, Space автоматически получает публичный URL вида https://huggingface.co/spaces/ваш-логин/название-space. Эту ссылку можно отправлять коллегам, вставлять в презентации, прикреплять к резюме. Никаких дополнительных действий не требуется - приложение доступно всем, у кого есть ссылка.
Чтобы встроить демо в блог или на страницу портфолио, используйте iframe. Hugging Face Spaces поддерживает embedding: добавьте к URL параметр ?embed=true, и интерфейс приложения отобразится без навигационной панели платформы. Код для вставки выглядит так:
<iframe src="https://huggingface.co/spaces/username/space-name?embed=true" width="100%" height="600"></iframe>
Если вы пока не готовы показывать проект широкой аудитории, Spaces поддерживают приватный режим. В настройках репозитория переключите видимость на «Private» - доступ останется только у вас и тех, кому вы явно его предоставите. Это удобно для клиентских демо или внутренних инструментов команды.
Обновление приложения происходит автоматически при любом изменении файлов в репозитории. Загрузили новую версию app.py через веб-интерфейс - через минуту изменения уже в продакшене. Сделали git push - триггер тот же. Платформа отслеживает состояние репозитория и перезапускает сборку при каждом коммите. Логи сборки доступны во вкладке «Settings» Space - там же можно вручную перезапустить приложение или сменить SDK.
Что дальше: расширяем возможности и улучшаем демо
Бесплатный тариф Spaces работает на CPU, чего достаточно для небольших моделей и визуализации данных. Если демо требует GPU - например, вы используете большую генеративную модель или хотите ускорить инференс - платформа предлагает апгрейд до GPU-окружения. Стоимость зависит от типа ускорителя (T4, A10G, A100) и тарифицируется по часам использования.
Загрузку пользовательских файлов в демо реализует виджет st.file_uploader. Он принимает изображения, CSV, аудио - любые форматы - и возвращает объект, с которым можно работать дальше: передать в модель для классификации, отобразить на странице, добавить в датасет. Это превращает демо из статичной витрины в полноценный инструмент, которым могут пользоваться люди без технической подготовки.
Кэширование через @st.cache_resource и @st.cache_data - тема, достойная отдельной статьи. В двух словах: первое кэширует «тяжёлые» объекты вроде моделей и токенизаторов, второе - результаты вычислений и загруженные данные. Правильное кэширование сокращает время отклика с десятков секунд до долей секунды и снижает нагрузку на память.
Streamlit - не единственный вариант для Spaces. Платформа также поддерживает Gradio, который лучше подходит для демо с нестандартными интерфейсами (аудио, видео, 3D-модели). Мы рассказывали, как комбинировать нейросети в цепочки с Gradio 2.0 - этот материал будет полезен, если вы перерастёте возможности Streamlit. Выбор между фреймворками - вопрос задачи, а не ограничений платформы.
Hugging Face Spaces снимает инфраструктурный барьер между работающей моделью и её аудиторией. Вы пишете Python-код, платформа делает его доступным по ссылке. Для быстрого прототипирования, демонстрации результатов и сбора обратной связи этого достаточно. А когда проект вырастет во что-то большее, всегда можно перейти к продакшен-решениям вроде Amazon SageMaker - о том, как это сделать, у нас есть отдельное пошаговое руководство.