如果你使用 DeepSeek、元宝 AI、Copilot、ChatGPT 等 AI 工具,协助配置轩辕镜像、编写 docker pull 命令、修改 Docker Compose 镜像地址、配置镜像加速、排查镜像拉取失败、分析报错日志等问题,请先让 AI 阅读并遵守轩辕镜像的规则文档。
只需在 AI 对话中先发送下面这段话即可:
请先阅读并遵守:https://xuanyuan.cloud/agents.md
未读文档前不要生成 pull 命令或排错方案。查看 agents.md 用法指南与完整示范。国内用户首推 元宝 AI、DeepSeek 的深度思考模式,不推荐豆包 AI;Cursor 等编辑器可在对话 @ 该链接,或加入 User Rules。 若 AI 无法访问外链,可 打开说明文档 复制全文粘贴。文档会随站点更新,复制内容可能过期,建议定期检查。
Kokoro-82M文本转语音模型的Docker化FastAPI封装。几分钟内生成数小时的高质量语音。
使用、推荐或支持Kokoro-FastAPI作为后端的社区项目:
预构建的多架构镜像,内置模型。
:latest标签可用,但为确保稳定使用,请固定到发布标签。
无GPU(笔记本电脑、仅CPU服务器)
docker run -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu:latest
NVIDIA(GTX 900系列至RTX 40系列;内置cu126)
docker run --gpus all -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-gpu:latest
NVIDIA RTX 50系列/Blackwell(内置cu128)
docker run --gpus all -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-gpu:latest-cu128
NVIDIA arm64(Jetson、GH200;相同标签,内置cu129)
docker run --gpus all -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-gpu:latest
AMD GPU(ROCm,实验性,仅x86_64)
docker run --device=/dev/kfd --device=/dev/dri -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-rocm:latest
Apple Silicon(原生MPS克隆;CPU镜像也可运行)
./start-gpu_mac.sh
gpu:latest 与 gpu:latest-cu126 为同一镜像。通过环境变量进行配置,详见配置指南。
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
配置指南涵盖了镜像与构建、卷挂载以及环境变量的相关内容。
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 或
./start-gpu.sh
Windows
.\start-cpu.ps1 或
.\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")
兼容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, aac, pcm
"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 # 测试所有可用语音
流式支持
# 兼容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_bella",
input="Hello world!"
) as response:
response.stream_to_file("output.mp3")
# 流式输出到扬声器(需要PyAudio)
import pyaudio
player = pyaudio.PyAudio().open(
format=pyaudio.paInt16,
channels=1,
rate=24000,
output=True
)
with client.audio.speech.with_streaming_response.create(
model="kokoro",
voice="af_bella",
response_format="pcm",
input="Hello world!"
) as response:
for chunk in response.iter_bytes(chunk_size=1024):
player.write(chunk)
或通过requests:
import requests
response = requests.post(
"http://localhost:8880/v1/audio/speech",
json={
"input": "Hello world!",
"voice": "af_bella",
"response_format": "pcm"
},
stream=True
)
for chunk in response.iter_content(chunk_size=1024):
if chunk:
# 处理流式块
pass
关键流式指标:
多种输出音频格式
语音组合
import requests
response = requests.get("http://localhost:8880/v1/audio/voices")
voices = [v["id"] for v in response.json()["voices"]]
# 加权语音组合(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"
}
)
# 下载组合语音为 .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"
}
)
加权混合表达式可能会很快变得冗长。voice_aliases 为每个请求映射一个短名称,适用于 voice 字段和 [voice:...] 标签:
{"voice_aliases": {...}});可与 API 调用互换使用。from openai import OpenAI
client = OpenAI(base_url="http://localhost:8880/v1", api_key="not-needed")
client.audio.speech.create(
model="kokoro",
voice="narrator",
input="[voice:narrator] Once upon a time. [voice:villain] Never!",
extra_body={
"allow_voice_tags": True,
"voice_aliases": {"narrator": "af_bella(2)+af_sky", "villain": "am_michael"},
},
)
或者
curl -X POST http://localhost:8880/v1/audio/speech \
-H "Content-Type: application/json" \
-d '{
"model": "kokoro",
"voice": "narrator",
"input": "[voice:narrator] Once upon a time. [voice:villain] Never!",
"allow_voice_tags": true,
"voice_aliases": {"narrator": "af_bella(2)+af_sky", "villain": "am_michael"},
"response_format": "mp3"
}' --output aliased.mp3
POST /dev/tune 通过 https://github.com/remsky/inno-kokoro 接收 3 至 30 秒的单个英语说话者音频片段,并生成向该片段调优的语音。这是调优工具,而非克隆工具:预期效果是相似的语音范围,而非完全匹配。仅调优您有权使用的语音。
curl -s http://localhost:8880/dev/tune -F audio=@ref.wav -F 'request={"input":"Hello there."}' -o out.mp3
curl -s http://localhost:8880/dev/tune -F audio=@ref.wav -F return_voice_pack=true -o ref.pt
curl -s http://localhost:8880/dev/tune -F audio=@ref.wav -F save_voice=am_ref # 保存为 am_ref_tuned,需设置 ALLOW_LOCAL_VOICE_SAVING=true
request 是 /v1/audio/speech 的请求体(不含 voice);语音包仅在响应期间存在,除非 save_voice 将其保存在 VOICES_DIR 中am_、bf_、ax_ 等),保存的语音会添加 _tuned 后缀。捆绑的调优语音以 _inno 结尾prosody_head(默认启用)、fmax 音高上限(单位:Hz,默认自动)ENABLE_INNO_TUNER=true 启用并显示 Web 播放器标签页ALLOW_LOCAL_VOICE_SAVING=true 允许将语音保存到运行中的服务器。[voice:...] 标签可在任何接受 input 的位置内联切换说话者\v1\audio\speech 每个请求需设置 allow_voice_tags: true;\dev\dialogue 默认允许标签ENABLE_VOICE_TAGS=false 可在服务器范围内禁用:该参数将被拒绝,且 \dev\dialogue 返回 403 错误curl -X POST http://localhost:8880/v1/audio/speech \
-H "Content-Type: application/json" \
-d '{
"model": "kokoro",
"voice": "af_heart",
"input": "The narrator opens. [voice:af_bella] Did it land? [pause:0.3s] [voice:am_michael] It did.",
"allow_voice_tags": true,
"response_format": "mp3"
}' --output dialogue.mp3
使用官方 OpenAI 客户端时,在 extra_body 中传递参数:
client.audio.speech.create(
model="kokoro",
voice="af_jadzia",
input="The narrator opens. [voice:af_bella] Did it land?",
extra_body={"allow_voice_tags": True},
)
POST /dev/dialogue 使用结构化的对话轮次,并允许通过参数控制 pause_between_turns(轮次间停顿)。
curl -X POST http://localhost:8880/dev/dialogue \
-H "Content-Type: application/json" \
-d '{
"turns": [
{"voice": "af_bella", "text": "Did the multi speaker support land?"},
{"voice": "am_michael", "text": "It did. Turns switch voices inline."}
],
"pause_between_turns": 0.4,
"response_format": "mp3"
}' --output dialogue.mp3
注意:
voice(或默认语音)。lang_code 将覆盖所有说话者的语言。语音数量对生成速度的影响极小。但对于频繁切换的场景,如果每个说话者的文本少于约 2 句话,分块处理需求会减慢生成速度。生成成本仍为固定值,不会随文本长度增加而累积。可使用 examples/assorted_checks/test_dialogue/ 重新生成。
[pause:1.5s] 插入指定时长的静音。格式必须严格如此(冒号、末尾 s、不区分大小写)。[pause=1.5] 和 [PAUSE 1.0] 无法识别,会被直接朗读。[Worcester](/wˈʊstər/) 会朗读斜杠间的国际音标(IPA)而非单词本身。仅支持英语;使用 /dev/phonemize 获取 IPA。[voice:am_michael] 切换后续内容的发言者。allow_voice_tags: true,且服务器端需启用 ENABLE_VOICE_TAGS(默认开启)。否则标签会按原样朗读。voice 参数相同的组合语法([voice:af_bella(2)+af_sky]),voice_aliases 中定义短名称/别名,[rate:1.5] 调整发言语速,直至下一个语速标签或语音切换;[rate:1.0] 恢复默认语速。在请求 speed 的基础上叠加生效,限制范围为 0.25-4.0。与语音标签的启用条件相同。{"grandpa": {"voice": "am_michael", "rate": 0.8}} 会在别名被使用时(作为 voice 参数或标签)应用该语速。适用于语速过快或过慢的语音,以及同一语音的命名预设(如 narrator_fast、narrator_slow)。[rate:] 标签会缩放发言者的校准语速而非替换它,因此被限制为 0.8 的别名在 [rate:1.1] 下仍保持相应的慢速比例。每个 [voice:...] 标签会重置为新语音自身的语速,因此校准后的发言者不会将其语速影响到下一个发言者;使用 speed 可设置整个请求的语速。The city of [Worcester](/wˈʊstər/) is easy. [pause:1s] See?
在 /v1/audio/speech 或 /dev/captioned_speech 接口中,同时发送 ssml: true 和 allow_voice_tags: true 可实现一次调用完成翻译和语音合成。这两个标志均为必需,因为翻译会生成 [voice:] 和 [rate:] 片段,若缺少标志这些片段会被直接朗读;仅设置 ssml 会返回 400 错误。
{
"model": "kokoro",
"input": " Hi there ",
"voice": "af_bella",
"allow_voice_tags": true,
"ssml": true
}
POST /dev/ssml 用于单独进行翻译(当需要文本形式的令牌而非音频,或在合成前检查令牌时)。发送 text(若语音请求使用了语音则同时发送 voice),然后将结果与 allow_voice_tags: true 一起传递。若未指定语音,</> 会被剥离,仅保留其内容。
<break time="0.75s"/> 转换为 [pause:0.75s]。若使用 strength= 而非 time=,则 none/x-weak 对应 0s,weak 对应 0.25s,medium 对应 0.5s,strong 对应 1s,x-strong 对应 1.5s<voice name="am_michael"> 转换为 [voice:am_michael],在结束标签处恢复原语音<prosody rate="0.75"> 转换为 [rate:0.75],也支持 80% 或 1.2。在请求 speed 的基础上缩放发言语速,限制范围为 0.25-4.0,在结束标签处恢复;忽略 pitch/volume<phoneme alphabet="ipa" ph="wˈʊstər">Worcester</phoneme> 转换为 [Worcester](/wˈʊstər/),仅支持 IPA 和英语<say-as alias="WWW"> 朗读别名<desc> 及其文本会被丢弃,音频描述不属于语音内容<p>、<s>、<emphasis>、<sub>、<sup> 等:标记会被丢弃,仅朗读文本内容SSML_MAX_DEPTH(10)会返回 400 错误;没有方言使用 DTD,实际文档的嵌套深度通常为 2-5google:style、mstts:express-as、amazon:effect)需要在 <speak> 标签上声明对应的 xmlns:,供应商文档常省略此声明GET /dev/ssml 以数据形式提供这些转换规则表,直接从转换器读取curl -s http://localhost:8880/dev/ssml -H "Content-Type: application/json" \
-d '{"text": " The city of Worcester is easy. See? "}'
# {"text": "The city of [Worcester](/wˈʊstər/) is easy. [pause:1.0s] See?"}
模型每个 chunk 最多处理 510 个音素化令牌,但过长的 chunk 容易导致“急促”语音及其他失真。服务器在顶层添加了自己的分块层,大小由 TARGET_MIN_TOKENS、TARGET_MAX_TOKENS 和 ABSOLUTE_MAX_TOKENS 控制(默认值分别为 175、250、450,可通过环境变量设置)。
将文本转换为音素和/或直接从音素生成音频:
import requests
def get_phonemes(text: str, language: str = "a"):
"""Get phonemes and tokens for input text"""
response = requests.post(
"http://localhost:8880/dev/phonemize",
json={"text": text, "language": language} # "a" for American English
)
response.raise_for_status()
result = response.json()
return result["phonemes"], result["tokens"]
def generate_audio_from_phonemes(phonemes: str, voice: str = "af_bella"):
"""Generate audio from phonemes"""
response = requests.post(
"http://localhost:8880/dev/generate_from_phonemes",
json={"phonemes": phonemes, "voice": voice},
headers={"Accept": "audio/wav"}
)
if response.status_code != 200:
print(f"Error: {response.text}")
return None
return response.content
# Example usage
text = "Hello world!"
try:
# Convert text to phonemes
phonemes, tokens = get_phonemes(text)
print(f"Phonemes: {phonemes}") # e.g. ðɪs ɪz ˈoʊnli ɐ tˈɛst
print(f"Tokens: {tokens}") # Token IDs including start/end tokens
# Generate and save audio
if audio_bytes := generate_audio_from_phonemes(phonemes):
with open("speech.wav", "wb") as f:
f.write(audio_bytes)
print(f"Generated {len(audio_bytes)} bytes of audio")
except Exception as e:
print(f"Error: {e}")
示例脚本见 examples/phoneme_examples/generate_phonemes.py。
时间戳(单词级别)
生成带单词级别时间戳的音频(非流式):
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)
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)
chunk_audio=base64.b64decode(chunk_json["audio"].encode("utf-8"))
f.write(chunk_audio)
print(chunk_json["timestamps"])
若设置 "allow_voice_tags": true,每个时间戳还会包含发言单词的 voice,因此多发言者字幕可直接标注,无需客户端重新推导分割;若未设置,则该字段不存在。
时间戳(流式 chunk)
当设置了stream、return_download_link和return_timing时,响应会携带X-Timing-Path头部,指向包含每个块时序信息的JSON辅助文件。音频主体保持不变,不会进行额外计算;这正是Web UI跟读功能的实现基础。
response = requests.post(
"http://localhost:8880/v1/audio/speech",
json={
"input": "Hello world! [pause:1s] Again.",
"voice": "af_bella",
"stream": True,
"return_download_link": True,
"return_timing": True,
},
stream=True,
)
audio = b"".join(response.iter_content(1024))
timings = requests.get(f"http://localhost:8880/v1{response.headers['x-timing-path']}").json()
# {"chunks": [{"text": "Hello world!", "start": 0.0, "end": 0.64}, ...]}
/dev/captioned_speech。start/end为最终音频中的秒数,已考虑停顿和语速。[pause:Ns]间隔会显示为{"text": ""}条目。text经过规范化处理(如数字展开等),因此需按单词对齐而非精确匹配。allow_voice_tags时,每个语音块会携带其voice信息,与带字幕的时间戳相同;否则不包含。吞吐量
本地API生成性能测试,文本长度涵盖长篇书籍(约1.5小时输出),测量处理时间和实时因子。测试环境:
关键性能指标:
模型卸载/显存回收
POST /dev/unload会将模型从显存中释放,并在下次请求时延迟重新加载。回收量随负载(激活池,而非仅权重)增长但会达到平稳:块大小上限为450 tokens。长文本约等于30个段落。测试环境同上。
| 工作负载 | 已加载 | 基准值 | 回收量 | 重新加载时间 |
|---|---|---|---|---|
| 短文本(6秒音频) | 3.11 GB | 2.37 GB | 758 MiB | +4.9s |
| 长文本(7.5分钟) | 3.98 GB | 2.37 GB | 1,656 MiB | +5.1s |
基准值包含主机+CUDA上下文。可通过项目examples/目录下的uv run --extra benchmarks assorted_checks/benchmarks/benchmark_model_unload.py复现。
要在空闲超时后自动卸载模型,可将MODEL_AUTO_UNLOAD_TIMEOUT_SECONDS设置为正整数秒数。默认值0表示禁用自动卸载。
转录往返测试(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。
所有设置均通过环境变量或项目根目录下的.env文件中的行进行配置。完整参考见配置指南。
用于调试资源耗尽或性能问题的系统状态和资源使用情况端点。/debug/*路由会暴露主机和进程内部信息,因此默认关闭;需设置ENABLE_DEBUG_ENDPOINTS=true启用。
/debug/threads - 获取线程信息和堆栈跟踪/debug/storage - 各挂载分区的磁盘使用情况/debug/system - 获取系统信息(CPU、内存、GPU)/dev/model - 获取模型加载状态和自动卸载计时。默认关闭;需设置ALLOW_DEV_UNLOAD=true启用POST /dev/unload - 从显存释放模型;下次请求时延迟重新加载。默认关闭;需设置ALLOW_DEV_UNLOAD=true启用POST /dev/reload - 将模型加载到显存。默认关闭;需设置ALLOW_DEV_UNLOAD=true启用稳定性:/v1/* OpenAI兼容路由为稳定API。/dev/*和/debug/*为运维辅助工具,在次要版本间可能会更改或需要通过标志启用。
全局API的https://loguru.readthedocs.io/en/stable/api/logger.html#levels可通过`API_LOG_LEVEL`环境变量设置。默认值为`DEBUG`。具体运行方法参见配置指南。
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
有关容器组、主机组和设备权限选项,参见docs/troubleshooting.md#linux-gpu-permissions。
有关HSA覆盖、MIOpen预热、hipBLAS回退和原生Linux主机要求,参见docs/troubleshooting.md#amd-gpu-rocm。
WAV 响应在头部的大小字段中使用流标记(0xFFFFFFFF)。大多数读取器均可正常处理:soundfile、pydub/ffmpeg、浏览器、操作系统播放器。Python 标准库 wave 无法处理,会报告错误的时长。若需获取准确长度,请使用 soundfile.info(path).duration 或 ffprobe。
分支策略:
release 分支: 包含最新稳定构建,推荐用于生产环境。使用特定版本标签的 Docker 镜像由此分支构建。master 分支: 活跃开发中。包含实验性功能、进行中的变更以及尚未发布的修复。用于获取最新代码,但稳定性较低。此分支不发布镜像;:latest 标签与其他所有标签一样,均从 release 分支构建。[!NOTE] 这本质上是一个以开发为中心的项目。
如果遇到问题,若出现意外情况,你可能需要回滚 release 标签的版本,或从源码构建和/或排查问题并提交 PR。
自由开源是社区共同的努力,而一天的时间毕竟有限。如果你想支持本项目,欢迎提交 PR、请我喝杯咖啡,或报告使用过程中发现的任何 bug/功能需求等。
正在处理代码,或让 AI 代理分析代码?AGENTS.md 涵盖了仓库布局、命令和约定。
本 API 使用 HuggingFace 上的 https://huggingface.co/hexgrad/Kokoro-82M 模型。
访问模型页面了解更多关于训练、架构和功能的详细信息。我与该模型的开发工作无任何关联,开发此包装器仅为方便使用和个人项目。
本项目采用 Apache License 2.0 许可证 - 详情如下:
完整的 Apache 2.0 许可证文本可在以下地址获取:https://www.apache.org/licenses/LICENSE-2.0
使用 contrib.rocks 生成。
来自真实用户的反馈,见证轩辕镜像的优质服务