GitPedia

FunSpeech

开箱即用的本地私有化部署语音服务,快速搭建Qwen3ASR/FunASR与CosyVoice2/3后端

From zaigie·Updated June 15, 2026·View on GitHub·

ASR + TTS API 网关,兼容阿里云语音 API 与 OpenAI TTS API,支持 WebSocket 流式协议。 模型推理由独立子服务承载(每个引擎独立 venv + 容器),通过 docker-compose 编排。 The project is written primarily in Python, distributed under the MIT License license, first published in 2025. Key topics include: asr, cosyvoice, cosyvoice2, cosyvoice3, docker.

<div align="center">

FunSpeech

<h3>开箱即用的本地私有化部署语音服务 — 微服务架构</h3>

ASR + TTS API 网关,兼容阿里云语音 API 与 OpenAI TTS API,支持 WebSocket 流式协议。
模型推理由独立子服务承载(每个引擎独立 venv + 容器),通过 docker-compose 编排。


Static Badge
Static Badge
Static Badge

</div>

[!IMPORTANT]
从单体版升级? 先读 docs/migration_to_latest.md

本分支已重构为微服务架构 (gateway + 4 个 GPU 子服务)。对外 HTTP/WS 协议字节级兼容, 客户端代码不用动; 但部署侧 docker-compose、模型缓存挂载路径、.env 变量都有变化。迁移文档覆盖:数据原地复用、必改的 mount 路径、.env 增删项、零停机切换、回滚步骤。

架构

                       ┌─────────────────────────┐
   外部客户端 ────────► │  gateway (CPU)          │
   (HTTP/WS)           │  - Aliyun/OpenAI 协议   │
                       │  - 句子状态机 + ITN     │
                       │  - 采样率/格式转换      │
                       └────────┬────────────────┘
                                │ HTTP / WS (X-Internal-Token)
                ┌───────────────┼───────────────┬───────────────┐
                ▼               ▼               ▼               ▼
         funasr (GPU)   dolphin (GPU)   qwen3-asr (GPU)   cosyvoice (GPU)
         Paraformer/    DataoceanAI     Qwen3-ASR-1.7B    CosyVoice2/3
         SenseVoice     Dolphin Small   (vLLM 加速)        (in-process)

子服务各自一个 pyproject.toml + uv.lock + Dockerfile,依赖完全隔离。
例如 funasr 用 transformers 4.51.3,qwen3-asr 用 transformers 4.57.1 + vLLM 0.11+,
互不冲突。

快速开始

1. 准备环境

bash
git clone https://cnb.cool/nexa/FunSpeech.git cd FunSpeech # 必须: 拉 cosyvoice 上游源码 (git submodule) # 不做这一步, cosyvoice 镜像启动会 ModuleNotFoundError git submodule update --init --recursive cp .env.example .env # 按需修改

如果机器在国内,把代理放进 .env:

bash
HTTP_PROXY=http://host.docker.internal:7890 # macOS/Windows Docker Desktop HTTPS_PROXY=http://host.docker.internal:7890 # Linux 服务器: 改成宿主机 LAN IP, 例如 http://192.168.1.10:7890

2. 构建 + 启动

Dockerfile 用了 RUN --mount=type=cache 给 apt / uv 双缓存,需要 BuildKit。Docker 23+ 默认开启;低版本手动启用:

bash
export DOCKER_BUILDKIT=1 export COMPOSE_DOCKER_CLI_BUILD=1
bash
docker compose build # 重 build 时 apt/uv 走本机缓存,极快 docker compose up -d # 默认: gateway + qwen3-asr + cosyvoice docker compose --profile funasr up -d # 加上 funasr (paraformer/sensevoice) docker compose --profile dolphin up -d # 加上 dolphin docker compose --profile funasr --profile dolphin up -d # 全部 ASR 引擎

服务暴露在 http://localhost:${GATEWAY_PORT:-8000}

3. 验证

bash
# 健康 curl http://localhost:8000/stream/v1/asr/health curl http://localhost:8000/stream/v1/tts/health # ASR curl -X POST "http://localhost:8000/stream/v1/asr?format=wav&sample_rate=16000" \ -H "Content-Type: application/octet-stream" \ --data-binary @audio.wav # TTS curl -X POST "http://localhost:8000/stream/v1/tts" \ -H "Content-Type: application/json" \ -d '{"text":"你好","voice":"中文女"}' \ --output speech.wav

WebSocket 测试页:

  • ASR: http://localhost:8000/ws/v1/asr/test
  • TTS: http://localhost:8000/ws/v1/tts/test

服务列表

服务端口镜像GPU默认启动profile
gateway8000funspeech/gateway(默认)
funasr-08001funspeech/funasrfunasr
dolphin-08002funspeech/dolphindolphin
qwen3-asr-08003funspeech/qwen3-asr(默认, 默认 ASR 引擎)
cosyvoice-08004funspeech/cosyvoice(默认)

每个子服务暴露 GET /health + 自有业务端点(详见各 services/*/README.md)。

对外 API(网关)

ASR

端点方法说明
/stream/v1/asrPOST一句话语音识别
/stream/v1/asr/modelsGET模型列表
/stream/v1/asr/healthGET健康检查
/ws/v1/asrWS流式识别(Aliyun 协议)

可识别模型(models.json):qwen3-asr-flash(默认)、paraformer-largesensevoice-small(后两者需 --profile funasr)、dolphin-small(需 --profile dolphin)。

TTS

端点方法说明
/stream/v1/ttsPOST语音合成
/openai/v1/audio/speechPOSTOpenAI 兼容
/rest/v1/tts/asyncPOST/GET异步长文本合成
/stream/v1/tts/voicesGET音色列表
/stream/v1/tts/voices/infoGET音色详细信息
/stream/v1/tts/voices/refreshPOST刷新音色
/stream/v1/tts/healthGET健康检查
/ws/v1/ttsWS双向流式合成(Aliyun 协议)

外部协议与之前的进程内版本完全兼容。

配置(网关侧 env)

变量默认说明
GATEWAY_PORT8000对外暴露端口
APPTOKEN / APPKEY-外部鉴权(可选)
INTERNAL_SERVICE_TOKENfunspeech-internal网关→子服务鉴权头(X-Internal-Token)
ASR_MODEL_MODEallall / offline / realtime
TTS_MODEL_MODEallall / sft / clone
ASR_ENABLE_REALTIME_PUNCfalse流式中间结果是否带标点
AUTO_LOAD_CUSTOM_ASR_MODELS-启动时预热的额外 ASR 模型 id
FUNASR_SERVICE_URLShttp://funasr-0:8001子服务 URL,逗号分隔多副本
DOLPHIN_SERVICE_URLShttp://dolphin-0:8002
QWEN3_ASR_SERVICE_URLShttp://qwen3-asr-0:8003
COSYVOICE_SERVICE_URLShttp://cosyvoice-0:8004
SERVICE_REQUEST_TIMEOUT60子服务调用超时(秒)
INFERENCE_THREAD_POOL_SIZEmax(4, CPU 核数)网关同步调用线程池大小;高 QPS 调大
HTTPX_MAX_CONNECTIONS200网关→子服务 HTTP 连接池上限;>100 req/s 时调到 500+
HTTPX_MAX_KEEPALIVE50保活连接数上限

子服务专属 env(模型版本、TRT/FP16/vLLM 等)请见 .env.exampledocs/deployment.md §6 和各 services/*/README.md

关于"GPU 并发数":子服务内部的 GPU 并发已在代码里硬编码 (funasr/dolphin=1, cosyvoice=2, qwen3-asr=Lock+vLLM 内部 batching), 不通过环境变量暴露。横向扩展请用多副本, 见下文。

开发

单独跑某个子服务

bash
cd services/funasr uv sync PORT=8001 INTERNAL_SERVICE_TOKEN=test uv run python server.py

网关本地跑(连容器里的子服务)

bash
uv sync FUNASR_SERVICE_URLS=http://localhost:8001 \ COSYVOICE_SERVICE_URLS=http://localhost:8004 \ INTERNAL_SERVICE_TOKEN=funspeech-internal \ uv run python start.py

性能与副本规划

在 NVIDIA RTX 4090 24G 上的实测单副本容量 (完整数据见 benchmarks/):

子服务单副本容量单条延迟显存
funasr (all)~12 req/s~80 ms~3 GiB
dolphin~12 req/s~80 ms~1 GiB
qwen3-asr~5 req/s (vLLM 内部 batch 可吃 64 并发)~190 ms0.85 × 卡显存 (vLLM KV pool)
cosyvoice (clone)2 路实时 TTS (RTF ≈ 1.05)~3.5 s / 句~4 GiB

ASR 看 req/s, TTS 看"几路实时" (RTF ≤ 1) — 单副本 sem=2 时同时 2 路 RTF=1.05 刚好实时, 4 路就开始 RTF=1.75 卡顿。想 N 路实时 TTS 需 ceil(N/2) 张卡。

横向扩展 = 多卡多副本, 不是单卡多副本 (同一服务两副本绑同一张卡, 实测总容量不升反降)。

用规划脚本一键算出应该开几副本 / 怎么绑卡, 并在当前目录生成完整 docker-compose.generated.yml:

bash
python3 scripts/plan_deployment.py # 交互式 python3 scripts/plan_deployment.py --preset 4090-quad # 看预设 python3 scripts/plan_deployment.py --list-presets

详细说明见 docs/deployment.md §4.3

模型权重缓存

所有 GPU 子服务通过 bind mount 共享 MODELSCOPE_CACHE(默认 ~/.cache/modelscope/hub/models,
mount 到容器 /root/.cache/modelscope/hub),
因此即便 funasr / cosyvoice 各自的 transformers 版本不同,权重文件可以复用。

提前下载:

bash
pip install modelscope modelscope download --model iic/CosyVoice-300M-SFT modelscope download --model FunAudioLLM/Fun-CosyVoice3-0.5B-2512 modelscope download --model iic/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch modelscope download --model iic/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online modelscope download --model iic/punc_ct-transformer_zh-cn-common-vocab272727-pytorch modelscope download --model iic/speech_fsmn_vad_zh-cn-16k-common-pytorch # 按需: modelscope download --model DataoceanAI/dolphin-small modelscope download --model Qwen/Qwen3-ASR-1.7B

音色管理(克隆)

零样本克隆音色由 cosyvoice 子服务托管。把 张三.wav + 张三.txt 放到 ./voices/ 卷,然后:

bash
curl -X POST http://localhost:8000/stream/v1/tts/voices/refresh

或通过 API 上传(需要外部 multipart 接入,见 docs/)。所有音色状态(spk2info.pt + voice_registry.json)
持久化到 ./voices/ 卷。

已知设计取舍

  • vLLM 加速 CosyVoice 默认关闭:vLLM 0.11+ 要求 transformers ≥4.55,
    与 CosyVoice 主代码所需的 4.51.3 冲突。如果性能瓶颈明显,可拆出 services/cosyvoice_vllm/
    独立 venv 启用,见 services/cosyvoice/README.md 的多副本注释。
  • Qwen3-ASR 流式不走 vLLM 通用 /v1/realtime:vLLM 通用 realtime 端点对
    Qwen3-ASR 质量明显劣化(无跨段上下文、无 token 修订,见 vllm Issue #35767)。
    我们用官方 qwen_asr.Qwen3ASRModel.streaming_transcribe + init_streaming_state,
    在子服务进程内跑,具备 unfixed_chunk / unfixed_token 修订能力。
  • Qwen3-ASR 子服务进程内 GPU 串行: vLLM 的 Python LLM(...) 入口
    非线程安全, 子服务用 asyncio.Lock 保证只有一个调用进 vLLM。这不影响 vLLM
    自身的 continuous batching (batching 在 engine 内部), 但要靠多副本扩吞吐。
  • 音色 CRUD 多副本同步 (commit 299075b): URL 列表第一个 = 写副本 (primary)。
    所有 POST/DELETE /voices 自动路由到 primary, 写后网关广播 POST /voices/reload
    让其它副本从磁盘热重载 spk2info.pt。详见 docs/deployment.md §5.2

目录结构

.
├── app/                       # 网关代码
│   ├── api/v1/                # FastAPI 路由 (Aliyun + OpenAI)
│   ├── services/asr/          # ASR 引擎抽象 + HTTP 客户端
│   ├── services/tts/          # TTS 引擎抽象 + HTTP 客户端 (含 voice_manager)
│   ├── services/websocket_*.py
│   ├── core/config.py         # 网关 env
│   └── utils/audio.py         # 重采样、PCM/WAV 转码、ITN
├── services/                  # 各子服务(独立 venv + Dockerfile)
│   ├── funasr/
│   ├── dolphin/
│   ├── qwen3_asr_vllm/
│   └── cosyvoice/             # third_party/CosyVoice 是官方 submodule
├── scripts/
│   ├── plan_deployment.py     # 副本规划 (零依赖)
│   └── analyze_audio_rms.py   # 远场过滤阈值分析
├── benchmarks/                # 4090 实测数据 + 测试脚本 (git-lfs)
│   ├── README.md
│   ├── scripts/               # bench_tts.py / bench_asr.py / ...
│   ├── audio/                 # TTS 生成的测试样本
│   └── results/               # 结果 (json + log)
├── docker-compose.yml
├── .env.example
└── pyproject.toml             # 网关 deps (CPU only, ~57 包)

相关链接

许可证

MIT — 见 LICENSE

Contributors

Showing top 1 contributor by commit count.

View all contributors on GitHub →

This article is auto-generated from zaigie/FunSpeech via the GitHub API.Last fetched: 6/23/2026