在 Hugging Face 上部署语音到语音模型
引言
语音到语音 (S2S) 是 Hugging Face 的一个令人兴奋的新项目,它结合了多种先进模型,创造出一种无缝、近乎神奇的体验:您说话,系统便以合成语音回应。
该项目实现了一个级联管道,利用 Hugging Face Hub 上 Transformers 库中可用的模型。该管道包含以下组件:
- 语音活动检测 (VAD)
- 语音到文本 (STT)
- 语言模型 (LM)
- 文本到语音 (TTS)
更重要的是,S2S 支持多语言!它目前支持英语、法语、西班牙语、中文、日语和韩语。您可以在单语言模式下运行管道,或使用 `auto` 标志进行自动语言检测。更多详情请查看此处的仓库。
> 👩🏽💻: That's all amazing, but how do I run S2S?
> 🤗: Great question!
运行语音到语音模型需要大量的计算资源。即使在高端笔记本电脑上,您也可能会遇到延迟问题,尤其是在使用最先进的模型时。虽然强大的 GPU 可以缓解这些问题,但并非所有人都有能力(或愿意!)设置自己的硬件。
Hugging Face 的推理端点 (IE) 在这里发挥了作用。推理端点允许您租用配备 GPU(或您可能需要的其他硬件)的虚拟机,并且只需支付系统运行时间费用,为部署像语音到语音这样高性能的应用程序提供了理想的解决方案。
在这篇博文中,我们将引导您一步一步地将语音到语音模型部署到 Hugging Face 推理端点。我们将涵盖以下内容:
- 了解推理端点以及设置 IE 的不同方式的快速概览,包括自定义容器镜像(S2S 所需的)
- 为 S2S 构建自定义 Docker 镜像
- 将自定义镜像部署到 IE 并享受 S2S 的乐趣!
推理端点
推理端点提供了一种可扩展且高效的部署机器学习模型的方式。这些端点允许您以最少的设置来提供模型,并利用各种强大的硬件。推理端点非常适合部署需要高性能和可靠性的应用程序,而无需管理底层基础设施。
以下是几个主要功能,请务必查阅文档以获取更多信息:
- 简单性 - 得益于 IE 对 Hugging Face Hub 中模型的直接支持,您可以在几分钟内启动并运行。
- 可伸缩性 - 您无需担心伸缩问题,因为 IE 会自动伸缩(包括缩减到零),以处理不同的负载并节省成本。
- 定制化:您可以定制 IE 的设置以处理新任务。更多内容请见下文。
推理端点支持所有 Transformers 和 Sentence-Transformers 任务,但也可以支持自定义任务。以下是 IE 设置选项:
- 预构建模型:直接从 Hugging Face Hub 快速部署模型。
- 自定义处理程序:为更复杂的管道定义自定义推理逻辑。
- 自定义 Docker 镜像:使用您自己的 Docker 镜像来封装所有依赖项和自定义代码。
对于较简单的模型,选项 1 和 2 是理想之选,使推理端点部署变得非常简单。然而,对于像 S2S 这样复杂的管道,您需要选项 3 的灵活性:使用自定义 Docker 镜像部署我们的 IE。
这种方法不仅提供了更大的灵活性,还通过优化构建过程和收集必要数据来提高性能。如果您正在处理复杂的模型管道或希望优化应用程序部署,本指南将提供宝贵的见解。
在推理端点上部署语音到语音模型
我们开始吧!
构建自定义 Docker 镜像
为了开始创建自定义 Docker 镜像,我们首先克隆了 Hugging Face 的默认 Docker 镜像仓库。这为在推理任务中部署机器学习模型提供了一个很好的起点。
git clone https://github.com/huggingface/huggingface-inference-toolkit
为什么要克隆默认仓库?
- 坚实的基础:该仓库提供了一个预优化的基础镜像,专为推理工作负载设计,提供了一个可靠的起点。
- 兼容性:由于镜像构建时与 Hugging Face 的部署环境对齐,这确保了您部署自己的自定义镜像时能够顺利集成。
- 易于定制:该仓库提供了一个清晰且结构化的环境,方便根据您应用程序的特定需求定制镜像。
您可以在此处查看我们所有的更改。
为语音到语音应用程序定制 Docker 镜像
克隆仓库后,下一步是调整镜像以支持我们的语音到语音管道。
- 添加语音到语音项目
为了顺利集成项目,我们将语音到语音代码库和任何所需的数据集作为子模块添加。这种方法提供了更好的版本控制,确保在构建 Docker 镜像时始终提供确切版本的代码和数据。
通过将数据直接包含在 Docker 容器中,我们避免了每次实例化端点时都必须下载数据,这显著缩短了启动时间并确保了系统的可重现性。数据存储在 Hugging Face 仓库中,这提供了方便的跟踪和版本控制。
git submodule add https://github.com/huggingface/speech-to-speech.git
git submodule add https://huggingface.co/andito/fast-unidic
- 优化 Docker 镜像
接下来,我们修改了 Dockerfile 以满足我们的需求:
- 精简镜像:我们删除了与我们用例无关的包和依赖项。这减少了镜像大小,并减少了推理过程中不必要的开销。
- 安装依赖项:我们将 `requirements.txt` 的安装从入口点移到了 Dockerfile 本身。这样,依赖项在构建 Docker 镜像时安装,从而加快了部署速度,因为这些包无需在运行时安装。
- 部署自定义镜像
修改完成后,我们构建并将自定义镜像推送到 Docker Hub
DOCKER_DEFAULT_PLATFORM="linux/amd64" docker build -t speech-to-speech -f dockerfiles/pytorch/Dockerfile .
docker tag speech-to-speech andito/speech-to-speech:latest
docker push andito/speech-to-speech:latest
Docker 镜像构建并推送后,即可在 Hugging Face 推理端点中使用。通过使用此预构建镜像,端点可以更快地启动和更高效地运行,因为所有依赖项和数据都已预打包在镜像中。
设置推理端点
使用自定义 Docker 镜像只需要稍微不同的配置,您可以查看文档。我们将通过 GUI 和 API 两种方法来完成此操作。
预备步骤
- 登录:https://huggingface.co/login
- 请求访问 meta-llama/Meta-Llama-3.1-8B-Instruct
- 创建细粒度令牌:https://huggingface.co/settings/tokens/new?tokenType=fineGrained
- 选择访问门控仓库
- 如果您正在使用 API,请确保选择管理推理端点的权限
推理端点 GUI
- 导航至 https://ui.endpoints.huggingface.co/new
- 填写相关信息
- 模型仓库 -
andito/s2s
- 模型名称 - 如果您不喜欢生成的名称,可以随意重命名
- 例如
speech-to-speech-demo
- 保持小写和简短
- 例如
- 选择您偏好的云和硬件 - 我们使用了
AWS
GPU
L4
- 每小时只需
$0.80
,足以处理这些模型
- 每小时只需
- 高级配置(点击展开箭头 ➤)
- 容器类型 -
Custom
- 容器端口 -
80
- 容器 URL -
andito/speech-to-speech:latest
- Secrets -
HF_TOKEN
|<您的令牌在此>
- 容器类型 -
- 模型仓库 -
点击显示图像
模型仓库实际上并不重要,因为模型是在容器创建阶段指定和下载的,但推理端点需要一个模型,所以您可以随意选择一个轻量级的模型。
您需要指定
HF_TOKEN
,因为我们需要在容器创建阶段下载受限模型。如果您使用不受限或非私有模型,则无需此操作。
当前的 huggingface-inference-toolkit entrypoint 默认使用端口 5000,但推理端点期望端口 80。您应该在 Container Port 中匹配此设置。我们已经在 Dockerfile 中设置了它,但如果您从头开始创建自己的,请注意!
推理端点 API
在这里,我们将逐步介绍使用 API 创建端点的步骤。只需在您选择的 Python 环境中运行此代码即可。
确保使用 0.25.1
或更高版本
pip install huggingface_hub>=0.25.1
使用可以写入端点的令牌(写入或细粒度)
from huggingface_hub import login
login()
from huggingface_hub import create_inference_endpoint, get_token
endpoint = create_inference_endpoint(
# Model Configuration
"speech-to-speech-demo",
repository="andito/s2s",
framework="custom",
task="custom",
# Security
type="protected",
# Hardware
vendor="aws",
accelerator="gpu",
region="us-east-1",
instance_size="x1",
instance_type="nvidia-l4",
# Image Configuration
custom_image={
"health_route": "/health",
"url": "andito/speech-to-speech:latest", # Pulls from DockerHub
"port": 80
},
secrets={'HF_TOKEN': get_token()}
)
# Optional
endpoint.wait()
概述
主要组件
- 语音到语音
- 这是一个 Hugging Face 库,我们将一些特定于推理端点的文件放在
inference-endpoint
分支中,该分支将很快合并到主分支。
- 这是一个 Hugging Face 库,我们将一些特定于推理端点的文件放在
- andito/s2s 或任何其他仓库。我们不需要这个,因为我们已经在容器创建阶段有了模型,但推理端点需要一个模型,所以我们传递了一个轻量级的仓库。
- andimarafioti/speech-to-speech-toolkit.
- 这从 huggingface/huggingface-inference-toolkit 分叉而来,以帮助我们构建所需的自定义容器。
构建 Web 服务器
为了使用该端点,我们需要构建一个小型 Web 服务。它的代码在 speech_to_speech 库中的 s2s_handler.py
中完成,我们将其用于客户端,并在 speech_to_speech_inference_toolkit 中的 webservice_starlette.py
中完成,我们使用它来构建 docker 镜像。通常,您只为端点设置一个自定义处理程序,但由于我们想要实现极低的延迟,我们还构建了 Web 服务来支持 WebSocket 连接而不是普通的请求。这听起来一开始令人望而生畏,但 Web 服务只有 32 行代码!
此代码将在启动时运行 prepare_handler
,它将初始化所有模型并预热它们。然后,每条消息将由 inference_handler.process_streaming_data
处理。
此方法简单地从客户端接收音频数据,将其分块为 VAD 的小部分,并将其提交到队列进行处理。然后,它检查输出处理队列(来自模型的语音响应!)并在有内容时返回。所有内部处理都由 Hugging Face 的 speech_to_speech 库处理。
自定义处理程序自定义客户端
Web 服务接收并返回音频。但仍有一个重要缺失部分,我们如何录制和播放音频?为此,我们创建了一个客户端来连接到服务。最简单的方法是将分析分为 Web 服务连接和音频录制/播放。
初始化 Web 服务客户端需要为所有消息设置一个包含我们的 Hugging Face 令牌的头。在初始化客户端时,我们设置了在常见消息(打开、关闭、错误、消息)上执行的操作。这将决定当服务器向客户端发送消息时,客户端会做什么。
我们可以看到,对消息的反应是直截了当的,其中 on_message
是唯一一个更复杂的方法。此方法了解服务器何时完成响应并开始“回听”用户。否则,它会将服务器的数据放入播放队列。
客户端的音频部分有 4 个任务
- 录制音频
- 提交音频录音
- 接收来自服务器的音频响应
- 播放音频响应
音频在 audio_input_callback
方法中录制,它只是将所有块提交到一个队列。然后,通过 send_audio
方法将其发送到服务器。在这里,如果没有音频要发送,我们仍然提交一个空数组,以便从服务器接收响应。来自服务器的响应由我们在博客前面看到的 on_message
方法处理。然后,音频响应的播放由 audio_output_callback
方法处理。在这里,我们只需要确保音频在预期的范围内(我们不希望因为一个有缺陷的包而损害某人的耳膜!),并确保输出数组的大小是播放库所期望的。
结论
在这篇文章中,我们逐步介绍了如何在 Hugging Face 推理端点上使用自定义 Docker 镜像部署语音到语音 (S2S) 管道。我们构建了一个自定义容器来处理 S2S 管道的复杂性,并演示了如何将其配置为可扩展、高效的部署。Hugging Face 推理端点让部署像语音到语音这样高性能的应用程序变得更容易,而无需管理硬件或基础设施的麻烦。
如果您有兴趣尝试或有任何问题,请随意探索以下资源:
有问题或疑问?请在相关 GitHub 仓库中发起讨论,我们乐意提供帮助!