如果你使用 DeepSeek、元宝 AI、Copilot、ChatGPT 等 AI 工具,协助配置轩辕镜像、编写 docker pull 命令、修改 Docker Compose 镜像地址、配置镜像加速、排查镜像拉取失败、分析报错日志等问题,请先让 AI 阅读并遵守轩辕镜像的规则文档。
只需在 AI 对话中先发送下面这句话即可:
请先完整阅读并严格遵守以下文档中的全部规则与要求:
https://xuanyuan.cloud/agents.md
在未充分阅读并理解该文档前,不要生成任何命令、配置、修改建议、故障排查方案或技术回答。后续所有输出都必须严格以该文档中的规范为最高优先级执行。查看 agents.md 用法指南与完整示范。国内用户首推 元宝 AI、DeepSeek 的深度思考模式,不推荐豆包 AI;Cursor 等编辑器可在对话 @ 该链接,或加入 User Rules。 若 AI 无法访问外链,可 打开说明文档 复制全文粘贴。文档会随站点更新,复制内容可能过期,建议定期检查。
FastKokoKokoro-82M文本转语音模型的Docker化FastAPI封装器
最快开始(docker run)
预构建的多架构镜像,内置模型。
:latest 标签可用,但为确保稳定使用,请固定到发布标签。
| 您的硬件 | 镜像 |
|---|---|
| 无GPU(任何笔记本电脑、VPS、纯CPU服务器) | kokoro-fastapi-cpu:latest |
| Apple Silicon(M1/M2/M3) | Docker中使用 kokoro-fastapi-cpu:latest,或通过 ./start-gpu_mac.sh 原生运行以使用MPS |
| NVIDIA GTX 9xx、10xx、20xx、30xx、40xx(x86_64) | kokoro-fastapi-gpu:latest-cu126 或 kokoro-fastapi-gpu:latest |
| NVIDIA RTX 50系列 / Blackwell(x86_64) | kokoro-fastapi-gpu:latest-cu128 |
| arm64上的NVIDIA(Jetson、GH200) | kokoro-fastapi-gpu:latest(内置cu129,上游无cu126 arm64轮询包) |
| AMD GPU | kokoro-fastapi-rocm:latest(实验性,仅x86_64) |
docker run -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu:latest # CPU
docker run --gpus all -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-gpu:latest # NVIDIA(x86_64或arm64)
docker run --gpus all -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-gpu:latest-cu128 # NVIDIA Blackwell / RTX 50系列
docker run --device=/dev/kfd --device=/dev/dri -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-rocm:latest # AMD
通过环境变量进行配置,参见 core/config.py。:latest 和 :latest-cu126 标签解析为同一个多架构镜像。
快速开始(docker compose)
git clone https://github.com/remsky/Kokoro-FastAPI.git
cd Kokoro-FastAPI
cd docker/gpu # 用于NVIDIA GPU支持
# 或 cd docker/cpu # 用于CPU支持
# 或 cd docker/rocm # 用于AMD GPU(ROCm,实验性,仅amd64)
docker compose up --build
# *Apple Silicon(M1/M2/M3)用户注意:
# Docker GPU镜像是仅CUDA的,无法在Apple Silicon上运行。使用Docker时,请使用 `docker/cpu`。
# 如需原生MPS(Apple GPU)加速,请通过UV直接运行 `./start-gpu_mac.sh`。
cd ../.. # 返回仓库根目录,以便使用以下路径
# 模型将自动下载,如有需要也可手动下载:
python docker/scripts/download_model.py --output api/src/models/v1_0
# 或通过UV直接运行:
./start-gpu.sh # 用于GPU支持
./start-cpu.sh # 用于CPU支持
直接运行(通过uv)
git clone https://github.com/remsky/Kokoro-FastAPI.git
cd Kokoro-FastAPI
如果尚未运行,请运行 https://github.com/remsky/Kokoro-FastAPI/blob/master/docker/scripts/download_model.py
通过UV直接启动(带热重载)
Linux和macOS
./start-cpu.sh OR
./start-gpu.sh
Windows
.\start-cpu.ps1 OR
.\start-gpu.ps1
启动并运行?
作为OpenAI兼容的语音端点在本地运行
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8880/v1", api_key="not-needed"
)
with client.audio.speech.with_streaming_response.create(
model="kokoro",
voice="af_sky+af_bella", #单个或多个语音包组合
input="Hello world!"
) as response:
response.stream_to_file("output.mp3")
API将在 http://localhost:8880 可用
OpenAI兼容的语音端点
# 使用OpenAI的Python库
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8880/v1", api_key="not-needed")
response = client.audio.speech.create(
model="kokoro",
voice="af_bella+af_sky", # 参见 /api/src/core/openai_mappings.json 进行自定义
input="Hello world!",
response_format="mp3"
)
response.stream_to_file("output.mp3")
或通过Requests:
import requests
response = requests.get("http://localhost:8880/v1/audio/voices")
voices = [v["id"] for v in response.json()["voices"]]
# 生成音频
response = requests.post(
"http://localhost:8880/v1/audio/speech",
json={
"model": "kokoro",
"input": "Hello world!",
"voice": "af_bella",
"response_format": "mp3", # 支持:mp3、wav、opus、flac
"speed": 1.0
}
)
# 保存音频
with open("output.mp3", "wb") as f:
f.write(response.content)
快速测试(从另一个终端运行):
python examples/assorted_checks/test_openai/test_openai_tts.py # 测试OpenAI兼容性
python examples/assorted_checks/test_voices/test_all_voices.py # 测试所有可用语音
语音组合
组合语音并生成音频:
import requests
response = requests.get("http://localhost:8880/v1/audio/voices")
voices = [v["id"] for v in response.json()["voices"]]
# 示例1:简单语音组合(50%/50%混合)
response = requests.post(
"http://localhost:8880/v1/audio/speech",
json={
"input": "Hello world!",
"voice": "af_bella+af_sky", # 等权重
"response_format": "mp3"
}
)
# 示例2:加权语音组合(67%/33%混合)
response = requests.post(
"http://localhost:8880/v1/audio/speech",
json={
"input": "Hello world!",
"voice": "af_bella(2)+af_sky(1)", # 2:1比例 = 67%/33%
"response_format": "mp3"
}
)
# 示例3:将组合语音下载为.pt文件
response = requests.post(
"http://localhost:8880/v1/audio/voices/combine",
json="af_bella(2)+af_sky(1)" # 2:1比例 = 67%/33%
)
# 保存.pt文件
with open("combined_voice.pt", "wb") as f:
f.write(response.content)
# 使用下载的语音文件
response = requests.post(
"http://localhost:8880/v1/audio/speech",
json={
"input": "Hello world!",
"voice": "combined_voice", # 使用保存的语音文件
"response_format": "mp3"
}
)
多种输出音频格式
流式支持
硬件变体
# GPU:需要支持 CUDA 12.6+ 的 NVIDIA 驱动(~35x-100x 实时速度)
cd docker/gpu
docker compose up --build
# CPU:PyTorch CPU 推理
cd docker/cpu
docker compose up --build
# AMD GPU:ROCm 6.4(实验性,仅支持 amd64)
cd docker/rocm
docker compose up --build
吞吐量
基准测试通过本地 API 进行生成,文本长度最高达长篇书籍(~1.5 小时输出),测量处理时间和实时因子。测试环境如下:
关键性能指标:
模型卸载/显存回收
POST /dev/unload 会将模型从显存中释放,并在下一次请求时延迟加载。回收量随负载(激活池,而非仅权重)扩展但会达到稳定值:分块上限为 450 令牌。长文本约为 30 个段落。测试环境同上。
| 工作负载 | 加载时 | 基准值 | 回收量 | 重新加载时间 |
|---|---|---|---|---|
| 短文本(6s 音频) | 3.11 GB | 2.37 GB | 758 MiB | +4.9s |
| 长文本(7.5m) | 3.98 GB | 2.37 GB | 1,656 MiB | +5.1s |
基准值为宿主系统+CUDA 上下文。可通过 examples/ 目录下的 uv run --extra benchmarks assorted_checks/benchmarks/benchmark_model_unload.py 复现。
转录往返测试(WER/CER)
端到端往返测试:使用 Kokoro 合成音频,通过 https://github.com/SYSTRAN/faster-whisper 将结果转录回文本,与源文本比较。脚本和数据位于 examples/assorted_checks/test_transcription/。
长篇英文(整本书《地心游记》,古登堡计划,语音 af_heart,CUDA float16 上的 base.en Whisper 模型,基准测试基于 cu126 GPU 构建):
| 测试 | 输入字符数 | 音频长度 | 合成加速比 | 转录加速比 | WER |
|---|---|---|---|---|---|
| 短文本(~第7章) | 64,996 | 66分06秒 | 36.4x 实时 | 62.4x 实时 | 0.047 |
| 整本书 | 502,766 | 507分52秒 | 45.7x 实时 | 65.1x 实时 | 0.033 |
完整回归区间参见 examples/assorted_checks/test_transcription/BASELINE.md。
按语言检查(每种语音单句,多语言 Whisper small 模型。拉丁语系使用 WER,日语/中文/印地语使用 CER):
| 语言 | 语音 | 指标 | 得分 |
|---|---|---|---|
| 英语 | af_heart | WER | 0.000 |
| 英语(英国) | bf_emma | WER | 0.111 |
| 西班牙语 | ef_dora | WER | 0.000 |
| 法语 | ff_siwis | WER | 0.000 |
| 意大利语 | if_sara | WER | 0.000 |
| 葡萄牙语 | pf_dora | WER | 0.000 |
| 印地语 | hf_alpha | CER | 0.059 |
| 日语 | jf_alpha | CER | 0.000 |
| 中文 | zf_xiaobei | CER | 0.143 |
注意:这些是单句短文本测试,非全面的按语言质量基准。它们仅确认每种语音能生成目标语言的可转录音频;更深入的按语言质量评估仍在进行中。
复现方法参见 examples/assorted_checks/test_transcription/README.md。
模型一次可处理最多 510 个音素化令牌的分块,但这通常会导致“急促”语音或其他 artifacts。服务器中额外增加了一层分块逻辑,通过环境变量配置 TARGET_MIN_TOKENS、TARGET_MAX_TOKENS 和 ABSOLUTE_MAX_TOKENS 创建灵活分块,默认值分别为 175、250、450。
生成带词级时间戳的音频(非流式):
import requests
import base64
import json
response = requests.post(
"http://localhost:8880/dev/captioned_speech",
json={
"model": "kokoro",
"input": "Hello world!",
"voice": "af_bella",
"speed": 1.0,
"response_format": "mp3",
"stream": False,
},
stream=False
)
with open("output.mp3","wb") as f:
audio_json=json.loads(response.content)
# 解码 base64 流为字节
chunk_audio=base64.b64decode(audio_json["audio"].encode("utf-8"))
# 处理流式分块
f.write(chunk_audio)
# 打印词级时间戳
print(audio_json["timestamps"])
生成带词级时间戳的音频(流式):
import requests
import base64
import json
response = requests.post(
"http://localhost:8880/dev/captioned_speech",
json={
"model": "kokoro",
"input": "Hello world!",
"voice": "af_bella",
"speed": 1.0,
"response_format": "mp3",
"stream": True,
},
stream=True
)
f=open("output.mp3","wb")
for chunk in response.iter_lines(decode_unicode=True):
if chunk:
chunk_json=json.loads(chunk)
# 解码 base64 流为字节
chunk_audio=base64.b64decode(chunk_json["audio"].encode("utf-8"))
# 处理流式分块
f.write(chunk_audio)
# 打印词级时间戳
print(chunk_json["timestamps"])
将文本转换为音素和/或直接从音素生成音频:
import requests
def get_phonemes(text: str, language: str = "a"):
"""获取输入文本的音素和令牌"""
response = requests.post(
"http://localhost:8880/dev/phonemize",
json={"text": text, "language": language} # "a" 表示美式英语
)
response.raise_for_status()
result = response.json()
return result["phonemes"], result["tokens"]
input文本中可嵌入两种令牌,由服务器端(API、WebUI或任何客户端)解析:
[pause:1.5s] 插入指定时长的静音。格式必须严格匹配(冒号、结尾s、不区分大小写)。[pause=1.5]、[PAUSE 1.0] 以及 SSML <break> 均不被识别,会被直接朗读。[Worcester](/wˈʊstər/) 会朗读斜杠间的IPA音标而非原词。仅支持英语;使用 /dev/phonemize 端点获取IPA音标。The city of [Worcester](/wˈʊstər/) is easy. [pause:1s] See?
通过以下端点监控系统状态和资源使用情况:
/debug/threads - 获取线程信息和堆栈跟踪/debug/storage - 监控临时文件和输出目录使用情况/debug/system - 获取系统信息(CPU、内存、GPU)POST /dev/unload - 从VRAM释放模型;下次请求时会惰性重新加载适用于调试资源耗尽或性能问题。
全局API的loguru日志级别可通过 API_LOG_LEVEL 环境变量设置。默认值为 DEBUG。
Docker
修改相应的compose配置文件或追加到命令行:
docker run --env 'API_LOG_LEVEL=WARNING' ...
通过UV直接运行
Linux 和 macOS
export API_LOG_LEVEL=WARNING
./start-cpu.sh 或
./start-gpu.sh
Windows
$env:API_LOG_LEVEL = 'WARNING'
.\start-cpu.ps1 或
.\start-gpu.ps1
API会自动对输入文本进行规范化处理,可能导致部分短语被错误移除或修改。可通过在请求JSON中添加 "normalization_options":{"normalize": false} 禁用规范化:
import requests
response = requests.post(
"http://localhost:8880/v1/audio/speech",
json={
"input": "Hello world!",
"voice": "af_heart",
"response_format": "pcm",
"normalization_options":
{
"normalize": False
}
},
stream=True
)
for chunk in response.iter_content(chunk_size=1024):
if chunk:
# 处理流式数据块
pass
部分Linux用户以非root用户运行时可能遇到GPU权限问题。 无法保证以下解决方案适用于所有情况,请根据您的安全需求谨慎选择:
选项1:容器组(推荐方案)
services:
kokoro-tts:
# ... 现有配置 ...
group_add:
- "video"
- "render"
选项2:主机系统组
services:
kokoro-tts:
# ... 现有配置 ...
user: "${UID}:${GID}"
group_add:
- "video"
[!NOTE] 可能需要将主机用户添加到相关组:
sudo usermod -aG docker,video $USER并重启系统。
选项3:设备权限(谨慎使用)
services:
kokoro-tts:
# ... 现有配置 ...
devices:
- /dev/nvidia0:/dev/nvidia0
- /dev/nvidiactl:/dev/nvidiactl
- /dev/nvidia-uvm:/dev/nvidia-uvm
[!WARNING] 降低系统安全性。仅在开发环境中使用。
前提条件:必须正确配置NVIDIA GPU、驱动程序和容器工具包。
有关详细信息,请访问 NVIDIA Container Toolkit 安装指南。
WAV响应的头部包含流式标记(0xFFFFFFFF)大小字段。大多数播放器(soundfile、pydub/ffmpeg、浏览器、系统播放器)可正常处理,但Python标准库 wave 模块无法识别,会显示错误时长。建议使用 soundfile.info(path).duration 或 ffprobe 获取准确时长。
分支策略:
release 分支:包含最新稳定版本,推荐用于生产环境。特定版本的Docker镜像由此分支构建。master 分支:用于活跃开发。可能包含实验性功能、进行中的更改或尚未纳入稳定版本的修复。如需获取最新代码可使用此分支,但稳定性可能较低。latest Docker标签通常指向此分支的构建。[!NOTE] 本项目本质上是一个以开发为重点的项目。
如遇问题,可能需要回退到发布标签中的某个版本,或从源代码构建、排查问题并提交PR。
自由开源是社区共同努力的结果,而每个人的时间精力有限。如果您想支持本项目,欢迎提交PR、请我喝杯咖啡,或报告使用过程中发现的任何bug/功能需求。
本API使用HuggingFace的 Kokoro-82M 模型。
访问模型页面了解训练细节、架构和功能。我与该模型的开发团队无任何关联,开发此包装器仅为方便使用和个人项目。
本项目采用Apache License 2.0许可 - 详情如下:
完整的Apache 2.0许可文本可在以下地址获取:[***]
使用 contrib.rocks 生成。
来自真实用户的反馈,见证轩辕镜像的优质服务