Hub documentation

Seu primeiro Docker Space: Geração de texto com T5

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Seu primeiro Docker Space: Geração de texto com T5

Nas seções a seguir, você aprenderá os fundamentos para criar um Space com Docker, configurá-lo e implantar seu código nele. Criaremos um Space de Text Generation com Docker que será usado para demonstrar o modelo google/flan-t5-small, capaz de gerar texto a partir de um texto de entrada, utilizando o FastAPI como servidor.

Você pode encontrar uma versão concluída deste hospedado aqui.

Crie um novo Espaço Docker

Vamos começar criando um novo Space e escolhendo Docker como nosso SDK.

Os Hugging Face Spaces são repositórios Git, o que significa que você pode trabalhar no seu Space de forma incremental (e colaborativa) enviando commits. Dê uma olhada no guia Getting Started with Repositories para aprender como criar e editar arquivos antes de continuar. Se você preferir trabalhar com uma interface gráfica, também pode realizar o trabalho diretamente no navegador.

Selecionar Docker como SDK ao criar um novo Space inicializa seu Space Docker definindo a propriedade sdk como docker no bloco YAML do seu arquivo README.md.

sdk: docker

Você tem a opção de alterar a porta padrão de aplicativo do seu Space definindo a propriedade app_port no bloco YAML do seu arquivo README.md. A porta padrão é 7860.

app_port: 7860

Adicione as dependências

Para o Space de Geração de Texto, vamos construir um aplicativo FastAPI que apresenta um modelo de geração de texto chamado Flan T5. Para a inferência do modelo, usaremos um pipeline do 🤗 Transformers para utilizar o modelo. Precisamos começar instalando algumas dependências. Isso pode ser feito criando um arquivo requirements.txt em nosso repositório e adicionando as seguintes dependências a ele:

fastapi==0.74.*
requests==2.27.*
sentencepiece==0.1.*
torch==1.11.*
transformers==4.*
uvicorn[standard]==0.17.*

Essas dependências serão instaladas no Dockerfile que criaremos mais tarde.

Crie o aplicativo

Vamos iniciar o processo com um aplicativo FastAPI fictício para verificar se conseguimos fazer um endpoint funcionar. O primeiro passo é criar um arquivo de aplicativo, neste caso, vamos chamá-lo de main.py.

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World!"}

Crie o Dockerfile

A etapa principal para um Espaço Docker é a criação de um Dockerfile. Você pode ler mais sobre Dockerfiles aqui. Embora estejamos usando FastAPI neste tutorial, os Dockerfiles oferecem grande flexibilidade aos usuários, permitindo que você construa uma nova geração de demonstrações de ML. Vamos escrever o Dockerfile para a nossa aplicação

# 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"]

Quando as alterações forem salvas, o Space será reconstruído e sua demonstração deve estar no ar após alguns segundos! Aqui está um exemplo de resultado nesse ponto.

Testando localmente

Dica para usuários avançados (pode pular): Se você está desenvolvendo localmente, este é um bom momento para executar docker build e docker run para depurar localmente, mas é ainda mais fácil enviar as alterações para o Hub e ver como fica!

docker build -t fastapi .
docker run  -it -p 7860:7860 fastapi

Se você tiver Secrets, pode usar docker buildx e passar os segredos como argumentos de build

export SECRET_EXAMPLE="my_secret_value"
docker buildx build --secret id=SECRET_EXAMPLE,env=SECRET_EXAMPLE -t fastapi .

e execute com docker run passando os segredos como variáveis de ambiente

export SECRET_EXAMPLE="my_secret_value"
docker run -it -p 7860:7860 -e SECRET_EXAMPLE=$SECRET_EXAMPLE fastapi

Adicionando alguns ML ao nosso app

Como mencionado anteriormente, a ideia é usar um modelo Flan T5 para geração de texto. Vamos adicionar alguns HTML e CSS para um campo de entrada, então vamos criar um diretório chamado static com os arquivos index.html, style.css e script.js. Neste momento, sua estrutura de arquivos deve ser assim:

/static
/static/index.html
/static/script.js
/static/style.css
Dockerfile
main.py
README.md
requirements.txt

Vamos passar por todas as etapas para fazer isso funcionar. Vamos pular alguns detalhes do CSS e do HTML. Você pode encontrar o código completo na aba Files and versions do Space DockerTemplates/fastapi_t5.

  1. Escreva o endpoint do FastAPI para fazer inferência

Usaremos o pipeline do transformers para carregar o modelo google/flan-t5-small. Definiremos um endpoint chamado infer_t5 que recebe uma entrada e retorna o resultado da chamada de inferência

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"]}
  1. Escreva o index.html para ter um formulário simples contendo o código da página.
<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>
  1. No arquivo main.py, monte os arquivos estáticos e exiba o arquivo html na rota raiz
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")
  1. No arquivo script.js, faça-o tratar a solicitação
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);
});
  1. Conceda permissões aos diretórios corretos

Conforme discutido na Seção de Permissões, o contêiner é executado com o ID de usuário 1000. Isso significa que o Space pode enfrentar problemas de permissão. Por exemplo, o transformers baixa e faz o cache dos modelos no caminho sob o caminho HF_HOME. A maneira mais fácil de resolver isso é criar um usuário com as permissões adequadas e usá-lo para executar o aplicativo do contêiner. Podemos fazer isso adicionando as seguintes linhas ao 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

O Dockerfile final deve ser parecido com este:


# 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"]

Sucesso! Seu aplicativo deve estar funcionando agora! Confira DockerTemplates/fastapi_t5 para ver o resultado final.

Que jornada! Lembre-se de que os Docker Spaces oferecem muita liberdade, então você não está limitado a usar FastAPI. De um Go Endpoint a um Shiny App, o limite é a lua! Confira alguns exemplos oficiais. Você também pode fazer o upgrade do seu Space para uma GPU, se necessário 😃

Depuração

Você pode depurar seu Space verificando os logs de Build e Container. Clique no botão Open Logs para abrir o modal.

Se tudo deu certo, você verá Pushing Image e Scheduling Space na aba Build

Na aba Container, você verá o status da aplicação, neste caso, Uvicorn running on http://0.0.0.0:7860

Além disso, você pode ativar o Dev Mode no seu Space. O Dev Mode permite que você se conecte ao seu Space em execução via VSCode ou SSH. Saiba mais aqui: https://huggingface.co/dev-mode-explorers

Saiba Mais

Update on GitHub