Как размещать модели и датасеты на Hugging Face Spaces с помощью Streamlit: пошаговое руководство

Как размещать модели и датасеты на 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 - о том, как это сделать, у нас есть отдельное пошаговое руководство.

Отправить тому, кому пригодится

Ссылка сохранит весь материал без сокращений.

По почте

Заметили неточность? Сообщить редакции