Hub 文档

您的第一个 Docker 空间:使用 T5 进行文本生成

Hugging Face's logo
加入 Hugging Face 社区

并获取增强型文档体验

开始使用

您的第一个 Docker Space:使用 T5 进行文本生成

在接下来的部分中,您将学习创建 Docker Space 的基础知识,包括配置它并将您的代码部署到它。我们将使用 Docker 创建一个 **文本生成** Space,它将用于演示 google/flan-t5-small 模型,该模型可以使用 FastAPI 作为服务器,在给定一些输入文本的情况下生成文本。

您可以在此处找到此托管的完整版本 这里.

创建一个新的 Docker Space

我们将从 创建一个全新的 Space 开始,并选择 **Docker** 作为我们的 SDK。

Hugging Face Spaces 是 Git 存储库,这意味着您可以通过推送提交来逐步(以及协作地)处理您的 Space。请查看 存储库入门 指南,了解如何在继续之前创建和编辑文件。如果您喜欢使用 UI,您也可以直接在浏览器中进行操作。

创建新的 Space 时选择 **Docker** 作为 SDK 将通过在您的 README.md 文件的 YAML 块中将 sdk 属性设置为 docker 来初始化您的 Docker Space。

sdk: docker

您可以选择通过在您的 README.md 文件的 YAML 块中设置 app_port 属性来更改 Space 的默认应用程序端口。默认端口为 7860

app_port: 7860

添加依赖项

对于 **文本生成** Space,我们将构建一个 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

如果您有 密钥,可以使用 `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 的一些细节。您可以在 DockerTemplates/fastapi_t5 空间的“文件和版本”选项卡中找到完整代码。

  1. 编写 FastAPI 端点以进行推理

我们将使用 `transformers` 中的 `pipeline` 来加载 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"]}
  1. 编写 `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>
  1. 在 `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")
  1. 在 `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);
});
  1. 授予对正确目录的权限

正如在 权限部分 中所讨论的,容器使用用户 ID 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 端点Shiny 应用,一切皆有可能!请查看 一些官方示例。如果需要,您还可以将 Space 升级到 GPU 😃

调试

您可以通过查看 **构建** 和 **容器** 日志来调试 Space。点击 **打开日志** 按钮打开模态。

如果一切顺利,您将在 **构建** 选项卡中看到 `正在推送镜像` 和 `正在调度 Space`

在 **容器** 选项卡中,您将看到应用程序状态,在本例中为 `Uvicorn 正在运行于 http://0.0.0.0:7860`

此外,您可以在 Space 上启用开发模式。开发模式允许您通过 VSCode 或 SSH 连接到正在运行的 Space。在此处了解更多信息:https://huggingface.co/dev-mode-explorers

了解更多

< > 在 GitHub 上更新