Hub documentation
Ваш первый Docker Space: генерация текста с T5
Ваш первый Docker Space: генерация текста с T5
В следующих разделах вы узнаете основы создания Docker Space, его настройки и развёртывания на нём вашего кода. Мы создадим Space Text Generation с Docker, который будет использоваться для демонстрации модели google/flan-t5-small, способной генерировать текст по заданному входному тексту, с использованием FastAPI в качестве сервера.
Готовую версию этого хостинга можно найти здесь.
Создать новое пространство Docker
Мы начнём с создания нового Space и выбора Docker в качестве SDK.

Hugging Face Spaces — это Git-репозитории, что позволяет работать над Space поэтапно (и совместно) путём отправки коммитов. Ознакомьтесь с руководством Getting Started with Repositories, чтобы узнать, как создавать и редактировать файлы, прежде чем продолжать. Если вы предпочитаете работать через интерфейс, вы также можете выполнять работу непосредственно в браузере.
Выбор Docker в качестве SDK при создании нового Space инициализирует ваш Docker Space, устанавливая свойство sdk в значение docker в YAML-блоке файла README.md.
sdk: dockerВы можете изменить порт приложения по умолчанию для вашего Space, задав свойство app_port в YAML-блоке файла README.md. Порт по умолчанию — 7860.
app_port: 7860Добавьте зависимости
Для Space Text Generation мы создадим приложение на FastAPI, демонстрирующее модель генерации текста Flan T5. Для инференса модели мы будем использовать 🤗 Transformers pipeline. Для начала необходимо установить несколько зависимостей. Это можно сделать, создав файл requirements.txt в нашем репозитории и добавив в него следующие зависимости:
fastapi==0.74.*
requests==2.27.*
sentencepiece==0.1.*
torch==1.11.*
transformers==4.*
uvicorn[standard]==0.17.*Эти зависимости будут установлены в Dockerfile, который мы создадим позже.
Создание приложения
Начнём с создания тестового приложения FastAPI, чтобы убедиться, что мы можем запустить эндпоинт. Первый шаг — создать файл приложения, в данном случае назовём его main.py.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World!"}Создание Dockerfile
Основной шаг при создании Docker Space — это создание Dockerfile. Подробнее о Dockerfile можно прочитать здесь. Хотя в этом учебном материале мы используем FastAPI, Dockerfile предоставляют пользователям большую гибкость, позволяя создавать ML-демо нового поколения. Давайте напишем Dockerfile для нашего приложения
# read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
# you will also find guides on how best to write your Dockerfile
FROM python:3.9
# The two following lines are requirements for the Dev Mode to be functional
# Learn more about the Dev Mode at https://huggingface.co/dev-mode-explorers
RUN useradd -m -u 1000 user
WORKDIR /app
COPY --chown=user ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY --chown=user . /app
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
Когда изменения сохранены, Space будет пересобран, и ваша демонстрация должна стать доступной через несколько секунд! Здесь приведён пример результата на этом этапе.

Тестирование локально
Совет для опытных пользователей (можно пропустить): Если вы разрабатываете локально, сейчас подходящий момент, чтобы выполнить docker build и docker run для отладки на своей машине, но ещё проще — отправить изменения на Hub и посмотреть, как всё выглядит!
docker build -t fastapi . docker run -it -p 7860:7860 fastapi
Если у вас есть Secrets, вы можете использовать docker buildx и передавать секреты в качестве аргументов сборки
export SECRET_EXAMPLE="my_secret_value"
docker buildx build --secret id=SECRET_EXAMPLE,env=SECRET_EXAMPLE -t fastapi .и запустите с помощью docker run, передав секреты в виде переменных окружения
export SECRET_EXAMPLE="my_secret_value"
docker run -it -p 7860:7860 -e SECRET_EXAMPLE=$SECRET_EXAMPLE fastapiДобавление ML в наше приложение
Как уже упоминалось, идея состоит в том, чтобы использовать модель Flan T5 для генерации текста. Нам нужно добавить немного HTML и CSS для поля ввода, поэтому создадим каталог static с файлами index.html, style.css и script.js. На данный момент структура ваших файлов должна выглядеть так:
/static /static/index.html /static/script.js /static/style.css Dockerfile main.py README.md requirements.txt
Разберём все шаги, необходимые для запуска. Мы пропустим некоторые детали CSS и HTML. Весь код можно найти на вкладке Files and versions в Space DockerTemplates/fastapi_t5.
- Напишите эндпоинт FastAPI для выполнения инференса
Мы будем использовать pipeline из transformers для загрузки модели google/flan-t5-small. Мы создадим эндпоинт с именем infer_t5, который принимает входные данные и возвращает результат вызова инференса
from transformers import pipeline
pipe_flan = pipeline("text2text-generation", model="google/flan-t5-small")
@app.get("/infer_t5")
def t5(input):
output = pipe_flan(input)
return {"output": output[0]["generated_text"]}- Создайте
index.htmlс простой формой, содержащей код страницы.
<main>
<section id="text-gen">
<h2>Text generation using Flan T5</h2>
<p>
Model:
<a
href="https://huggingface.co/google/flan-t5-small"
rel="noreferrer"
target="_blank"
>google/flan-t5-small
</a>
</p>
<form class="text-gen-form">
<label for="text-gen-input">Text prompt</label>
<input
id="text-gen-input"
type="text"
value="German: There are many ducks"
/>
<button id="text-gen-submit">Submit</button>
<p class="text-gen-output"></p>
</form>
</section>
</main>- В файле
main.pyподключите статические файлы и отобразите html-файл в корневом маршруте
app.mount("/", StaticFiles(directory="static", html=True), name="static")
@app.get("/")
def index() -> FileResponse:
return FileResponse(path="/app/static/index.html", media_type="text/html")- В файле
script.jsреализуйте обработку запроса
const textGenForm = document.querySelector(".text-gen-form");
const translateText = async (text) => {
const inferResponse = await fetch(`infer_t5?input=${text}`);
const inferJson = await inferResponse.json();
return inferJson.output;
};
textGenForm.addEventListener("submit", async (event) => {
event.preventDefault();
const textGenInput = document.getElementById("text-gen-input");
const textGenParagraph = document.querySelector(".text-gen-output");
textGenParagraph.textContent = await translateText(textGenInput.value);
});- Предоставление разрешений для нужных каталогов
Как обсуждалось в разделе «Права доступа», контейнер запускается с идентификатором пользователя 1000. Это означает, что Space может столкнуться с проблемами прав доступа. Например, transformers скачивает и кэширует модели в каталоге, расположенном по пути HF_HOME. Самый простой способ решить эту проблему — создать пользователя с необходимыми правами и использовать его для запуска приложения в контейнере. Для этого добавьте следующие строки в Dockerfile.
# Switch to the "user" user
USER user
# Set home to the user's home directory
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATHИтоговый Dockerfile должен выглядеть так:
# read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
# you will also find guides on how best to write your Dockerfile
FROM python:3.9
# The two following lines are requirements for the Dev Mode to be functional
# Learn more about the Dev Mode at https://huggingface.co/dev-mode-explorers
RUN useradd -m -u 1000 user
WORKDIR /app
COPY --chown=user ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY --chown=user . /app
USER user
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]Успех! Ваше приложение должно работать! Ознакомьтесь с DockerTemplates/fastapi_t5, чтобы увидеть итоговый результат.

Какой путь! Помните, что Docker Spaces предоставляют вам большую свободу, поэтому вы не ограничены использованием FastAPI. От Go Endpoint до Shiny App — пределом служит только луна! Загляните в некоторые официальные примеры. При необходимости вы также можете обновить свой Space до GPU 😃
Отладка
Вы можете отлаживать свой Space, просматривая логи Build и Container. Нажмите кнопку Open Logs, чтобы открыть модальное окно.

Если всё прошло успешно, на вкладке Build вы увидите Pushing Image и Scheduling Space

На вкладке Container отображается статус приложения, в данном случае Uvicorn running on http://0.0.0.0:7860

Кроме того, вы можете включить режим разработчика (Dev Mode) в вашем Space. Режим разработчика позволяет подключиться к работающему Space через VSCode или SSH. Подробнее здесь: https://huggingface.co/dev-mode-explorers