Merge pull request #3599 from LauraGPT/codex/moss-service-docs-20260901

feat: serve MOSS diarization across deployment stack
This commit is contained in:
zhifu gao
2026-09-01 14:50:49 +08:00
committed by GitHub
35 changed files with 547 additions and 39 deletions
+19 -2
View File
@@ -5,7 +5,13 @@ on:
paths:
- "funasr/models/moss_transcribe_diarize/**"
- "funasr/auto/auto_model.py"
- "funasr/bin/_server_app.py"
- "funasr/bin/server.py"
- "examples/openai_api/**"
- "README*.md"
- "docs/index.rst"
- "docs/moss_transcribe_diarize*.md"
- "web-pages/product-site/data/deployments.json"
- "tests/test_moss_transcribe_diarize_*.py"
- ".github/workflows/test-moss-adapter.yml"
push:
@@ -14,7 +20,13 @@ on:
paths:
- "funasr/models/moss_transcribe_diarize/**"
- "funasr/auto/auto_model.py"
- "funasr/bin/_server_app.py"
- "funasr/bin/server.py"
- "examples/openai_api/**"
- "README*.md"
- "docs/index.rst"
- "docs/moss_transcribe_diarize*.md"
- "web-pages/product-site/data/deployments.json"
- "tests/test_moss_transcribe_diarize_*.py"
- ".github/workflows/test-moss-adapter.yml"
@@ -45,9 +57,14 @@ jobs:
funasr/models/moss_transcribe_diarize/model.py \
tests/test_moss_transcribe_diarize_model.py \
tests/test_moss_transcribe_diarize_docs.py
python -m py_compile funasr/models/moss_transcribe_diarize/model.py
python -m py_compile \
funasr/models/moss_transcribe_diarize/model.py \
funasr/bin/_server_app.py \
funasr/bin/server.py \
examples/openai_api/server.py
- name: Run adapter and documentation contracts
run: |
python -m pytest -q \
tests/test_moss_transcribe_diarize_model.py \
tests/test_moss_transcribe_diarize_docs.py
tests/test_moss_transcribe_diarize_docs.py \
tests/test_server_app_openai_segments.py
+7 -4
View File
@@ -251,8 +251,12 @@ pip install torch torchaudio
pip install funasr vllm fastapi uvicorn python-multipart
funasr-server --device cuda
# → POST /v1/audio/transcriptions at localhost:8000
# Joint long-form ASR + anonymous speaker labels (offline HTTP):
funasr-server --model moss-transcribe-diarize --device cuda:0
```
[MOSS service, Docker, Kubernetes, vLLM, SGLang, LocalAI, and FunClip guide →](./docs/moss_transcribe_diarize.md)
Verify it with a public sample:
```bash
@@ -333,10 +337,9 @@ inference on physical Blackwell hardware.
## What's new
- **FunASR 1.4.11** is the current PyPI release. It improves readable multilingual subtitles while preserving real model timestamps. Install with `python -m pip install -U "funasr==1.4.11"`. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.11)
- **MOSS-Transcribe-Diarize integration** adds long-form ASR, timestamps, and anonymous speaker labels in one generation, without an external VAD or speaker pipeline. FunASR supports local Transformers and existing vLLM/SGLang services; FunClip can export speaker-aware SRT and clips. [Deployment guide ->](./docs/moss_transcribe_diarize.md)
- **llama.cpp runtime v0.2.6** provides verified prebuilt archives for ten Linux, macOS, and Windows targets, including dedicated Windows CUDA packages for RTX 30/40 and RTX 50 GPUs. [Download matrix ->](https://www.funasr.com/en/deploy/llama-cpp.html)
- **Realtime serving is faster and more resilient**: compatible WebSocket sessions are batched instead of serialized, and queued decoding no longer closes healthy sessions by default. On the H100 regression workload, 12-client STOP p95 fell from 19.8 s to 0.4 s. [Production guide ->](./docs/vllm_guide.md)
- **MOSS-Transcribe-Diarize** brings long-form ASR, timestamps, and anonymous speaker labels to FunASR services, Docker, Kubernetes, vLLM/SGLang workflows, and FunClip. [Deploy MOSS ->](./docs/moss_transcribe_diarize.md)
- **FunASR 1.4.11** is the current PyPI release, with more readable multilingual subtitles and preserved model timestamps. [Install or upgrade ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.11)
- **Production deployment** now includes faster, more resilient realtime serving and verified llama.cpp archives for ten Linux, macOS, and Windows targets. [GPU services ->](./docs/vllm_guide.md) · [CPU/edge packages ->](https://www.funasr.com/en/deploy/llama-cpp.html)
> See [GitHub Releases](https://github.com/modelscope/FunASR/releases) for the complete changelog and downloadable assets.
+7 -4
View File
@@ -99,10 +99,9 @@ Whisper は単一モデルですが、**FunASR はツールキット**です—
## 最新情報
- **FunASR 1.4.11** は現在の PyPI 安定版です。実際のモデル timestamp を保持しながら、多言語字幕の可読性を改善しました。更新:`python -m pip install -U "funasr==1.4.11"`。[Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.11)
- **MOSS-Transcribe-Diarize 連携**では、長時間音声の ASR、timestamp、匿名 speaker label を 1 回の生成で処理でき、外部 VAD や speaker pipeline は不要です。FunASR は local Transformers と既存の vLLM/SGLang service に対応し、FunClip は speaker 付き SRT と clip を出力できます。[Deployment guide ->](./docs/moss_transcribe_diarize.md)
- **llama.cpp runtime v0.2.6** は Linux、macOS、Windows の 10 target 向け検証済み archive を提供し、RTX 30/40 と RTX 50 向け Windows CUDA package を分けて用意しています。[Download matrix ->](https://www.funasr.com/en/deploy/llama-cpp.html) · [Release ->](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.2.6)
- **Realtime serving の高速化と安定化**:互換 WebSocket session を直列処理せず batch 化し、decode queue によって正常な session を default で切断しないようにしました。H100 regression workload では 12-client STOP p95 が 19.8 秒から 0.4 秒に短縮しました。[Production guide ->](./docs/vllm_guide.md)
- **MOSS-Transcribe-Diarize** を FunASR service、Docker、Kubernetes、vLLM/SGLang workflow、FunClip に統合し、長時間 ASR、timestamp、匿名 speaker label を一度に処理できます。[MOSS をデプロイ ->](./docs/moss_transcribe_diarize.md)
- **FunASR 1.4.11** は現在の PyPI 安定版で、多言語字幕の可読性を改善しながらモデル本来の timestamp を保持します。[Install / upgrade ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.11)
- **Production deployment** に、より高速で安定した realtime serving と、Linux、macOS、Windows の 10 target 向け llama.cpp package を追加しました。[GPU service ->](./docs/vllm_guide.md) · [CPU / edge package ->](https://www.funasr.com/en/deploy/llama-cpp.html)
> 完全な変更履歴と download asset は [GitHub Releases](https://github.com/modelscope/FunASR/releases) を参照してください。
@@ -140,11 +139,15 @@ pip install funasr
# OpenAI互換API(推奨)
pip install funasr fastapi uvicorn python-multipart
funasr-server --device cuda
# オフライン長時間音声 ASR + 匿名 speaker label:
funasr-server --model moss-transcribe-diarize --device cuda:0
# Dockerストリーミングサービス
docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.12
```
[MOSS service / Docker / Kubernetes / vLLM / SGLang / LocalAI / FunClip guide →](./docs/moss_transcribe_diarize.md)
CPU/エッジで Python なしのオフライン ASR が必要な場合は、llama.cpp / GGUF ランタイムを使えます:[funasr.com/deploy/llama-cpp](https://www.funasr.com/en/deploy/llama-cpp.html) · [Fun-ASR-Nano-GGUF](https://huggingface.co/FunAudioLLM/Fun-ASR-Nano-GGUF) · [SenseVoiceSmall-GGUF](https://huggingface.co/FunAudioLLM/SenseVoiceSmall-GGUF)。
[Colab quickstart →](./examples/colab/README_ja.md) · [OpenAI API example →](./examples/openai_api/README_ja.md) · [Client recipes →](./examples/openai_api/CLIENTS.md) · [Workflow recipes →](./examples/openai_api/WORKFLOWS.md) · [Postman collection →](./examples/openai_api/POSTMAN.md) · [OpenAPI spec →](./examples/openai_api/OPENAPI.md) · [Security guide →](./examples/openai_api/SECURITY.md) · [Deployment matrix →](./docs/deployment_matrix_ja.md) · [デプロイドキュメント →](./runtime/readme.md) · [Agent連携 →](https://modelscope.github.io/FunASR/agent.html)
+7 -4
View File
@@ -99,10 +99,9 @@ Whisper는 단일 모델이지만, **FunASR는 툴킷**입니다. 용도에 맞
## 최신 소식
- **FunASR 1.4.11**은 현재 PyPI 안정 버전입니다. 실제 모델 timestamp를 유지하면서 다국어 자막의 가독성을 개선했습니다. 업데이트: `python -m pip install -U "funasr==1.4.11"`. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.11)
- **MOSS-Transcribe-Diarize 연동**은 긴 오디오의 ASR, timestamp, 익명 speaker label을 한 번의 생성으로 처리하므로 외부 VAD 또는 speaker pipeline이 필요하지 않습니다. FunASR은 local Transformers와 기존 vLLM/SGLang service를 지원하고, FunClip은 speaker별 SRT와 clip을 내보낼 수 있습니다. [Deployment guide ->](./docs/moss_transcribe_diarize.md)
- **llama.cpp runtime v0.2.6**은 Linux, macOS, Windows 10개 target용 검증된 archive를 제공하며 RTX 30/40 및 RTX 50용 Windows CUDA package를 별도로 제공합니다. [Download matrix ->](https://www.funasr.com/en/deploy/llama-cpp.html) · [Release ->](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.2.6)
- **Realtime serving 성능과 안정성 개선**: 호환 WebSocket session을 직렬 처리하지 않고 batch 처리하며, decode queue 때문에 정상 session을 기본적으로 종료하지 않습니다. H100 regression workload에서 12-client STOP p95가 19.8초에서 0.4초로 줄었습니다. [Production guide ->](./docs/vllm_guide.md)
- **MOSS-Transcribe-Diarize**를 FunASR service, Docker, Kubernetes, vLLM/SGLang workflow, FunClip에 통합해 긴 오디오 ASR, timestamp, 익명 speaker label을 한 번에 처리합니다. [MOSS 배포 ->](./docs/moss_transcribe_diarize.md)
- **FunASR 1.4.11**은 현재 PyPI 안정 버전으로, 모델의 실제 timestamp를 유지하면서 다국어 자막 가독성을 개선합니다. [Install / upgrade ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.11)
- **Production deployment**에 더 빠르고 안정적인 realtime serving과 Linux, macOS, Windows 10개 target용 llama.cpp package를 추가했습니다. [GPU service ->](./docs/vllm_guide.md) · [CPU / edge package ->](https://www.funasr.com/en/deploy/llama-cpp.html)
> 전체 변경 기록과 download asset은 [GitHub Releases](https://github.com/modelscope/FunASR/releases)에서 확인할 수 있습니다.
@@ -140,11 +139,15 @@ pip install funasr
# OpenAI 호환 API (권장)
pip install funasr fastapi uvicorn python-multipart
funasr-server --device cuda
# 오프라인 장시간 ASR + 익명 speaker label:
funasr-server --model moss-transcribe-diarize --device cuda:0
# Docker 스트리밍 서비스
docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.12
```
[MOSS service / Docker / Kubernetes / vLLM / SGLang / LocalAI / FunClip guide →](./docs/moss_transcribe_diarize.md)
CPU/엣지에서 Python 없이 오프라인 ASR만 필요하다면 llama.cpp / GGUF 런타임을 사용할 수 있습니다: [funasr.com/deploy/llama-cpp](https://www.funasr.com/en/deploy/llama-cpp.html) · [Fun-ASR-Nano-GGUF](https://huggingface.co/FunAudioLLM/Fun-ASR-Nano-GGUF) · [SenseVoiceSmall-GGUF](https://huggingface.co/FunAudioLLM/SenseVoiceSmall-GGUF).
[Colab quickstart →](./examples/colab/README_ko.md) · [OpenAI API example →](./examples/openai_api/README_ko.md) · [Client recipes →](./examples/openai_api/CLIENTS.md) · [Workflow recipes →](./examples/openai_api/WORKFLOWS.md) · [Postman collection →](./examples/openai_api/POSTMAN.md) · [OpenAPI spec →](./examples/openai_api/OPENAPI.md) · [Security guide →](./examples/openai_api/SECURITY.md) · [Deployment matrix →](./docs/deployment_matrix_ko.md) · [배포 문서 →](./runtime/readme.md) · [Agent 연동 →](https://modelscope.github.io/FunASR/agent.html)
+7 -4
View File
@@ -149,10 +149,9 @@ Whisper 是单个模型,**FunASR 是一个工具箱**——按场景挑模型
## 最新动态
- **FunASR 1.4.11** 是当前 PyPI 稳定版,重点改善多语言可读字幕,并保留模型真实时间戳。升级命令:`python -m pip install -U "funasr==1.4.11"`。[发布页 ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.11)
- **MOSS-Transcribe-Diarize 已接入生态**:一次生成同时完成长音频转写、时间戳和匿名说话人标签,无需外挂 VAD 或说话人流水线。FunASR 支持本地 Transformers 及已有 vLLM/SGLang 服务,FunClip 可导出带说话人的 SRT 和片段。[部署指南 ->](./docs/moss_transcribe_diarize_zh.md)
- **llama.cpp runtime v0.2.6** 提供覆盖 Linux、macOS、Windows 十种目标的已验证预编译包,并为 RTX 30/40 与 RTX 50 显卡分别提供 Windows CUDA 包。[下载矩阵 ->](https://www.funasr.com/deploy/llama-cpp.html)
- **实时服务更快、更稳定**:兼容的 WebSocket 会话改为批处理,排队解码也不再默认误关健康连接。在 H100 回归负载下,12 路客户端 STOP p95 从 19.8 秒降至 0.4 秒。[生产部署指南 ->](./docs/vllm_guide_zh.md)
- **MOSS-Transcribe-Diarize** 已接入 FunASR 服务、Docker、Kubernetes、vLLM/SGLang 工作流和 FunClip,一次完成长音频转写、时间戳与匿名说话人标注。[部署 MOSS ->](./docs/moss_transcribe_diarize_zh.md)
- **FunASR 1.4.11** 是当前 PyPI 稳定版,重点改善多语言可读字幕并保留模型真实时间戳。[安装或升级 ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.11)
- **工业部署** 新增更快、更稳定的实时服务,以及覆盖 Linux、macOS、Windows 十种目标的 llama.cpp 预编译包。[GPU 服务 ->](./docs/vllm_guide_zh.md) · [CPU/端侧包 ->](https://www.funasr.com/deploy/llama-cpp.html)
> 完整改动记录和可下载资产请查看 [GitHub Releases](https://github.com/modelscope/FunASR/releases)。
@@ -275,8 +274,12 @@ funasr *.wav --output-format srt --output-dir ./output
pip install funasr fastapi uvicorn python-multipart
funasr-server --model sensevoice --device cuda
# → POST /v1/audio/transcriptions,地址 localhost:8000
# 离线长音频联合转写 + 匿名说话人标签:
funasr-server --model moss-transcribe-diarize --device cuda:0
```
[MOSS 服务、Docker、Kubernetes、vLLM、SGLang、LocalAI 与 FunClip 部署指南 →](./docs/moss_transcribe_diarize_zh.md)
使用公开样例音频验证服务:
```bash
+2
View File
@@ -73,6 +73,8 @@ Overview
./deployment_matrix.md
./deployment_matrix_zh.md
./moss_transcribe_diarize.md
./moss_transcribe_diarize_zh.md
./runtime/readme.md
./runtime/docs/SDK_tutorial_online.md
./runtime/docs/SDK_tutorial.md
+38
View File
@@ -95,6 +95,44 @@ clients keep the exact tagged generation in `raw_text`; in structured mode,
`raw_text` is the cleaned `text` returned by vLLM and the authoritative speaker
metadata is in `sentence_info`.
## FunASR OpenAI-compatible service
The built-in offline HTTP service exposes the same normalized result through
`/v1/audio/transcriptions`. It loads the pinned Transformers revision and does
not attach an external VAD or speaker model:
```bash
python -m pip install "transformers>=5.6,<6" fastapi uvicorn python-multipart
funasr-server --model moss-transcribe-diarize --device cuda:0 --port 8000
curl -fsS http://127.0.0.1:8000/v1/audio/transcriptions \
-F file=@meeting.wav \
-F model=moss-transcribe-diarize \
-F response_format=verbose_json
```
The response contains `text`, audio `duration`, and `segments` with `start`,
`end`, `text`, and anonymous `speaker` labels. The request does not need
`spk=true`; if a generic client sends it, the service still uses MOSS's native
labels and does not start a second diarization pipeline.
For a reproducible GPU container, build from the repository root with
`examples/openai_api/docker-compose.moss.yml`. Kubernetes operators can build
the same `funasr-moss-api:local` image and apply
`examples/openai_api/kubernetes/funasr-moss-api.yaml`; replace the local image
reference with the immutable digest from their registry before rollout.
MOSS is an offline long-form model, so it is not exposed by FunASR's realtime
WebSocket service. Use the HTTP endpoint for complete files. FunClip consumes
the same `sentence_info` contract for speaker-aware subtitles and clips.
The built-in service path was reproduced on one H100 80GB with Transformers
`5.16.0.dev0` and Torch `2.11.0+cu130`. The pinned model processed the bundled
6.000-second sample (`ea03e1f473ad1618a03da3327a545369cb8f6f06cb0f4115535e5a866167d47e`)
through the real HTTP endpoint and returned one non-empty monotonic segment
labelled `S01`, with `duration=6.0`. This is a functional service-contract
smoke, not an accuracy, throughput, concurrency, or production-capacity claim.
## Choose a serving path
| Path | Environment | Response contract | Use when |
+35
View File
@@ -85,6 +85,41 @@ speaker `segments` 直接映射到 `sentence_info`。认证可通过 `vllm_api_k
此时 `raw_text` 保留原始标签生成;结构化模式下,`raw_text` 是 vLLM 返回的清理后
`text`,权威说话人信息位于 `sentence_info`。
## FunASR OpenAI 兼容服务
内置离线 HTTP 服务通过 `/v1/audio/transcriptions` 返回同一套标准化结果。
服务加载固定的 Transformers revision,不会外挂 VAD 或第二套说话人模型:
```bash
python -m pip install "transformers>=5.6,<6" fastapi uvicorn python-multipart
funasr-server --model moss-transcribe-diarize --device cuda:0 --port 8000
curl -fsS http://127.0.0.1:8000/v1/audio/transcriptions \
-F file=@meeting.wav \
-F model=moss-transcribe-diarize \
-F response_format=verbose_json
```
响应包含 `text`、音频 `duration`,以及带 `start`、`end`、`text` 和匿名
`speaker` 标签的 `segments`。请求不需要设置 `spk=true`;即使通用客户端传入
该字段,服务也只使用 MOSS 原生标签,不会启动第二套说话人流水线。
GPU 容器可在仓库根目录使用
`examples/openai_api/docker-compose.moss.yml` 构建。Kubernetes 运维可构建同一
`funasr-moss-api:local` 镜像,再应用
`examples/openai_api/kubernetes/funasr-moss-api.yaml`;上线前应将本地镜像名
替换为内部镜像仓库的不可变 digest。
MOSS 是离线长音频模型,不接入 FunASR 的实时 WebSocket 服务;完整文件请使用
HTTP 接口。FunClip 通过同一套 `sentence_info` 契约生成带说话人信息的字幕与
片段。
内置服务路径已在一张 H100 80GB、Transformers `5.16.0.dev0`、Torch
`2.11.0+cu130` 环境复现。固定 revision 的模型通过真实 HTTP 接口处理仓库自带
6.000 秒样例(`ea03e1f473ad1618a03da3327a545369cb8f6f06cb0f4115535e5a866167d47e`),
返回一个非空、时间单调且标记为 `S01` 的 segment,`duration=6.0`。这只是服务
契约 smoke test,不代表准确率、吞吐、并发或生产容量。
## 选择服务后端
| 路径 | 环境 | 响应契约 | 适用场景 |
+4
View File
@@ -20,6 +20,10 @@ If the server is on another machine, replace `localhost` with the reachable host
| `paraformer` | Mandarin production transcription | Includes VAD and punctuation. |
| `paraformer-en` | English transcription | Smaller English-only route. |
| `fun-asr-nano` | LLM-based ASR experiments | Pair with vLLM for higher throughput deployments. |
| `moss-transcribe-diarize` | Offline multi-speaker long-form audio | Returns timestamps and anonymous speaker labels in `verbose_json`; do not add external VAD or diarization. |
For MOSS server, Docker, Kubernetes, vLLM, SGLang Omni, LocalAI, and FunClip
paths, use the [dedicated deployment guide](../../docs/moss_transcribe_diarize.md).
## Python OpenAI SDK
+27
View File
@@ -0,0 +1,27 @@
FROM pytorch/pytorch:2.9.1-cuda12.8-cudnn9-runtime
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
FUNASR_MODEL=moss-transcribe-diarize \
FUNASR_DEVICE=cuda:0 \
FUNASR_PORT=8000
WORKDIR /opt/funasr
RUN apt-get update \
&& apt-get install -y --no-install-recommends ffmpeg git libsndfile1 \
&& rm -rf /var/lib/apt/lists/*
COPY . /opt/funasr
RUN python -m pip install --upgrade pip \
&& python -m pip install . fastapi "uvicorn[standard]" python-multipart \
&& python -m pip install "transformers>=5.6,<6"
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=5s --start-period=10m --retries=3 \
CMD python -c "import os, urllib.request; urllib.request.urlopen('http://127.0.0.1:%s/health' % os.getenv('FUNASR_PORT', '8000'), timeout=3).read()" || exit 1
CMD ["sh", "-c", "funasr-server --host 0.0.0.0 --port ${FUNASR_PORT:-8000} --device ${FUNASR_DEVICE:-cuda:0} --model ${FUNASR_MODEL:-moss-transcribe-diarize}"]
+4
View File
@@ -51,6 +51,10 @@ For OpenAI SDK clients, remember that SDK base URLs include `/v1`; this Gradio d
| `paraformer` | Mandarin-oriented production transcription. |
| `paraformer-en` | English-only compatibility checks. |
| `fun-asr-nano` | LLM-based ASR and vLLM experiments. |
| `moss-transcribe-diarize` | Offline long-form transcription with timestamps and anonymous speaker labels; select `verbose_json`. |
MOSS requires the dedicated GPU service environment and is not a realtime
microphone model. See the [MOSS deployment guide](../../docs/moss_transcribe_diarize.md).
See the [model selection guide](../../docs/model_selection.md) for a deeper comparison.
+4
View File
@@ -51,6 +51,10 @@ OpenAI SDK 的 base URL 需要包含 `/v1`;这个 Gradio demo 使用的是不
| `paraformer` | 中文生产转写。 |
| `paraformer-en` | 英文兼容性检查。 |
| `fun-asr-nano` | LLM-based ASR 和 vLLM 实验。 |
| `moss-transcribe-diarize` | 离线长音频转写、时间戳和匿名说话人标签;请选择 `verbose_json`。 |
MOSS 需要专用 GPU 服务环境,不适合作为实时麦克风模型。详见
[MOSS 部署指南](../../docs/moss_transcribe_diarize_zh.md)。
更完整的对比见 [模型选择指南](../../docs/model_selection_zh.md)。
+5
View File
@@ -11,6 +11,11 @@ cd examples/openai_api
python server.py --model sensevoice --device cuda --port 8000
```
For offline multi-speaker files, start the isolated MOSS service with
`funasr-server --model moss-transcribe-diarize --device cuda:0`, set
`FUNASR_MODEL=moss-transcribe-diarize`, and request `verbose_json`. See the
[MOSS deployment guide](../../docs/moss_transcribe_diarize.md).
Then verify the service from another terminal:
```bash
+5
View File
@@ -11,6 +11,11 @@ cd examples/openai_api
python server.py --model sensevoice --device cuda --port 8000
```
处理离线多人音频时,使用
`funasr-server --model moss-transcribe-diarize --device cuda:0` 启动独立服务,设置
`FUNASR_MODEL=moss-transcribe-diarize` 并请求 `verbose_json`。详见
[MOSS 部署指南](../../docs/moss_transcribe_diarize_zh.md)。
在另一个终端验证服务:
```bash
+5 -1
View File
@@ -38,7 +38,7 @@ Replace them with the URL reachable from your app, container, or workflow runtim
| Field | Type | Required | Notes |
|---|---|---|---|
| `file` | binary | yes | Audio file such as wav, mp3, flac, m4a, ogg, or webm. |
| `model` | string | no | Defaults to `sensevoice`; available aliases are listed by `/v1/models`. |
| `model` | string | no | Defaults to `sensevoice`; `/v1/models` also lists `moss-transcribe-diarize` for offline long-form transcription with native anonymous speaker labels. |
| `language` | string | no | Optional language hint. |
| `response_format` | string | no | Use `json` or `verbose_json`. |
@@ -51,3 +51,7 @@ curl -fsS http://localhost:8000/openapi.json > /tmp/funasr-openapi-live.json
```
The live FastAPI schema may include framework-specific validation details; this checked-in spec keeps the public integration surface small and stable.
MOSS requires its isolated Transformers environment. Start it with
`funasr-server --model moss-transcribe-diarize --device cuda:0` and request
`response_format=verbose_json`; see the [deployment guide](../../docs/moss_transcribe_diarize.md).
+5 -1
View File
@@ -38,7 +38,7 @@
| Field | Type | Required | 说明 |
|---|---|---|---|
| `file` | binary | yes | 音频文件,例如 wav、mp3、flac、m4a、ogg 或 webm。 |
| `model` | string | no | 默认 `sensevoice`;可用别名由 `/v1/models` 返回。 |
| `model` | string | no | 默认 `sensevoice`;`/v1/models` 也会列出用于离线长音频与原生匿名说话人标签的 `moss-transcribe-diarize`。 |
| `language` | string | no | 可选语言提示。 |
| `response_format` | string | no | 使用 `json` 或 `verbose_json`。 |
@@ -51,3 +51,7 @@ curl -fsS http://localhost:8000/openapi.json > /tmp/funasr-openapi-live.json
```
实时 FastAPI schema 可能包含框架级校验细节;仓库中的静态规范保留更小、更稳定的公开集成面。
MOSS 需要独立 Transformers 环境。使用
`funasr-server --model moss-transcribe-diarize --device cuda:0` 启动,并请求
`response_format=verbose_json`;详见 [部署指南](../../docs/moss_transcribe_diarize_zh.md)。
+6
View File
@@ -92,6 +92,12 @@ curl http://localhost:8000/v1/audio/transcriptions \
| `paraformer` | 120x realtime | 15x realtime | zh/en | Punctuation |
| `paraformer-en` | 120x realtime | 15x realtime | en | English only |
| `fun-asr-nano` | 17x realtime | 3.6x realtime | zh/en/ja + Chinese dialects/accents | LLM-based, timestamps |
| `moss-transcribe-diarize` | Validate on target GPU | Offline only | Multilingual | Long-form timestamps + anonymous speaker labels |
MOSS uses a pinned third-party HF revision and must not be combined with an
external VAD or speaker model. See the [complete MOSS deployment guide](../../docs/moss_transcribe_diarize.md)
for `funasr-server`, Docker Compose, Kubernetes, vLLM, SGLang Omni, LocalAI,
and FunClip paths.
## API Endpoints
+5
View File
@@ -89,6 +89,11 @@ curl http://localhost:8000/v1/audio/transcriptions \
| `paraformer` | 120x realtime | 15x realtime | zh/en | 句読点復元 |
| `paraformer-en` | 120x realtime | 15x realtime | en | 英語認識 |
| `fun-asr-nano` | 17x realtime | 3.6x realtime | 中英日 + 中国語方言・地域アクセント | LLM-based、タイムスタンプ |
| `moss-transcribe-diarize` | 対象 GPU で要検証 | オフラインのみ | 多言語 | 長時間 timestamp + 匿名 speaker label |
MOSS は固定 revision の third-party HF model を使用し、外部 VAD / speaker model
とは併用しません。[MOSS deployment guide](../../docs/moss_transcribe_diarize.md) に
`funasr-server`、Docker、Kubernetes、vLLM、SGLang、LocalAI、FunClip をまとめています。
## API エンドポイント
+5
View File
@@ -89,6 +89,11 @@ curl http://localhost:8000/v1/audio/transcriptions \
| `paraformer` | 120x realtime | 15x realtime | zh/en | 문장부호 복원 |
| `paraformer-en` | 120x realtime | 15x realtime | en | 영어 인식 |
| `fun-asr-nano` | 17x realtime | 3.6x realtime | 중영일 + 중국어 방언/지역 억양 | LLM-based, 타임스탬프 |
| `moss-transcribe-diarize` | 대상 GPU 검증 필요 | 오프라인 전용 | 다국어 | 장시간 timestamp + 익명 speaker label |
MOSS는 고정 revision의 third-party HF model을 사용하며 외부 VAD / speaker model과
결합하지 않습니다. `funasr-server`, Docker, Kubernetes, vLLM, SGLang, LocalAI,
FunClip 경로는 [MOSS deployment guide](../../docs/moss_transcribe_diarize.md)를 참고하세요.
## API 엔드포인트
+5
View File
@@ -89,6 +89,11 @@ curl http://localhost:8000/v1/audio/transcriptions \
| `paraformer` | 120x realtime | 15x realtime | zh/en | 标点恢复 |
| `paraformer-en` | 120x realtime | 15x realtime | en | 英文识别 |
| `fun-asr-nano` | 17x realtime | 3.6x realtime | 中/英/日 + 中文方言/口音 | LLM-based,时间戳 |
| `moss-transcribe-diarize` | 需在目标 GPU 验证 | 仅离线 | 多语言 | 长音频时间戳 + 匿名说话人标签 |
MOSS 使用固定 revision 的第三方 HF 模型,不能外挂 VAD 或说话人模型。完整的
`funasr-server`、Docker Compose、Kubernetes、vLLM、SGLang Omni、LocalAI 与
FunClip 路径见 [MOSS 部署指南](../../docs/moss_transcribe_diarize_zh.md)。
## API 端点
+5
View File
@@ -25,6 +25,11 @@ If the workflow engine runs in Docker, `localhost` usually means the workflow co
Before configuring a low-code tool, you can import the [Postman collection](POSTMAN.md) and run health, model-list, and transcription requests from a GUI. For schema-driven imports, use the [OpenAPI spec](OPENAPI.md). Set `FUNASR_BASE_URL`, choose a local audio file for the multipart `file` field, and keep `MODEL_ALIAS=sensevoice` for the first test.
For offline multi-speaker meetings, set `MODEL_ALIAS=moss-transcribe-diarize`
and keep `response_format=verbose_json` so downstream nodes receive native
anonymous speaker segments. Use the [MOSS deployment guide](../../docs/moss_transcribe_diarize.md)
for the isolated GPU service and file-duration limits.
## Multipart HTTP request
Every workflow engine eventually needs to send this request shape:
+4
View File
@@ -25,6 +25,10 @@ curl -fsS "$FUNASR_BASE_URL/v1/models"
在配置低代码工具前,可以先导入 [Postman collection](POSTMAN_zh.md),从图形界面跑通 health、模型列表和转写请求;需要按 schema 导入时可使用 [OpenAPI spec](OPENAPI_zh.md)。设置 `FUNASR_BASE_URL`,在 multipart `file` 字段选择本地音频文件,第一次测试建议保持 `MODEL_ALIAS=sensevoice`。
处理离线多人会议时,将 `MODEL_ALIAS` 改为 `moss-transcribe-diarize`,并保留
`response_format=verbose_json`,下游节点即可收到模型原生匿名说话人 segments。
独立 GPU 服务与文件时长边界见 [MOSS 部署指南](../../docs/moss_transcribe_diarize_zh.md)。
## Multipart HTTP 请求
所有工作流引擎最终都需要发出下面这种请求:
@@ -0,0 +1,26 @@
services:
funasr-moss-api:
build:
context: ../..
dockerfile: examples/openai_api/Dockerfile.moss
image: funasr-moss-api:local
ports:
- "${FUNASR_HOST_PORT:-8000}:8000"
environment:
FUNASR_PORT: "8000"
FUNASR_DEVICE: "${FUNASR_DEVICE:-cuda:0}"
FUNASR_MODEL: moss-transcribe-diarize
HF_HOME: /root/.cache/huggingface
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
volumes:
- funasr-moss-cache:/root/.cache
shm_size: "8gb"
volumes:
funasr-moss-cache:
+5
View File
@@ -57,6 +57,11 @@ For in-cluster clients, use `http://funasr-api.speech.svc.cluster.local:8000` as
| Memory request | `8Gi` | Tune after observing startup and real audio workloads. |
| Startup probe | 10 minutes | Increase if your registry, model hub, or storage backend is slow. |
The `moss-transcribe-diarize` alias uses a separate GPU image and resource profile. Build
`examples/openai_api/Dockerfile.moss`, then apply `funasr-moss-api.yaml` after
replacing `funasr-moss-api:local` with your registry's immutable image digest.
The complete runtime matrix is in the [MOSS deployment guide](../../../docs/moss_transcribe_diarize.md).
## GPU notes
The example Dockerfile is CPU-first. For GPU clusters you need to adapt the image to CUDA-capable PyTorch/FunASR dependencies, then add your cluster's GPU scheduling fields, for example:
@@ -57,6 +57,11 @@ python smoke_test.py --base-url http://localhost:8000
| 内存 request | `8Gi` | 根据启动过程和真实音频负载观测结果调整。 |
| Startup probe | 10 分钟 | registry、模型下载或存储后端较慢时增大。 |
`moss-transcribe-diarize` 使用独立的 GPU 镜像与资源配置。先构建
`examples/openai_api/Dockerfile.moss`,将 `funasr-moss-api.yaml` 中的
`funasr-moss-api:local` 替换为内部镜像仓库的不可变 digest 后再应用。完整运行矩阵
见 [MOSS 部署指南](../../../docs/moss_transcribe_diarize_zh.md)。
## GPU 说明
示例 Dockerfile 默认面向 CPU。GPU 集群需要先把镜像改成 CUDA-capable PyTorch/FunASR 依赖,再根据集群增加 GPU 调度字段,例如:
@@ -0,0 +1,86 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: funasr-moss-cache
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 40Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: funasr-moss-api
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: funasr-moss-api
template:
metadata:
labels:
app.kubernetes.io/name: funasr-moss-api
spec:
containers:
- name: api
image: funasr-moss-api:local
imagePullPolicy: IfNotPresent
env:
- name: FUNASR_MODEL
value: moss-transcribe-diarize
- name: FUNASR_DEVICE
value: cuda:0
- name: FUNASR_PORT
value: "8000"
ports:
- name: http
containerPort: 8000
startupProbe:
httpGet:
path: /health
port: http
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 60
readinessProbe:
httpGet:
path: /health
port: http
periodSeconds: 10
resources:
requests:
cpu: "4"
memory: 24Gi
nvidia.com/gpu: "1"
limits:
memory: 48Gi
nvidia.com/gpu: "1"
volumeMounts:
- name: cache
mountPath: /root/.cache
- name: dshm
mountPath: /dev/shm
volumes:
- name: cache
persistentVolumeClaim:
claimName: funasr-moss-cache
- name: dshm
emptyDir:
medium: Memory
sizeLimit: 8Gi
---
apiVersion: v1
kind: Service
metadata:
name: funasr-moss-api
spec:
selector:
app.kubernetes.io/name: funasr-moss-api
ports:
- name: http
port: 8000
targetPort: http
+2 -1
View File
@@ -181,7 +181,8 @@
"sensevoice",
"paraformer",
"paraformer-en",
"fun-asr-nano"
"fun-asr-nano",
"moss-transcribe-diarize"
],
"default": "sensevoice",
"description": "FunASR model alias."
+9 -1
View File
@@ -6,6 +6,7 @@ Works with any agent framework that supports OpenAI audio API.
Usage:
python server.py --model sensevoice --device cuda --port 8000
python server.py --model moss-transcribe-diarize --device cuda:0 --port 8000
Then use with any OpenAI-compatible client:
curl http://localhost:8000/v1/audio/transcriptions \
@@ -54,6 +55,13 @@ MODEL_CONFIGS = {
"vad_model": "fsmn-vad",
"vad_kwargs": {"max_single_segment_time": 30000},
},
"moss-transcribe-diarize": {
"model": "OpenMOSS-Team/MOSS-Transcribe-Diarize",
"model_revision": "e8681d68e7042738ffca8ac8212bc8fcb1131ab8",
"hub": "hf",
"backend": "hf",
"trust_remote_code": True,
},
}
@@ -99,7 +107,7 @@ async def transcribe(
Accepts the same parameters as OpenAI's /v1/audio/transcriptions:
- file: Audio file (wav, mp3, flac, m4a, ogg, webm)
- model: Model to use (sensevoice, paraformer, fun-asr-nano)
- model: Model to use (sensevoice, paraformer, fun-asr-nano, moss-transcribe-diarize)
- language: Optional language hint
- response_format: json or verbose_json
"""
+13 -3
View File
@@ -1,7 +1,8 @@
"""FunASR Server — unified vLLM-based inference service.
Provides OpenAI-compatible API (/v1/audio/transcriptions) and REST API (/asr).
Uses vLLM for Fun-ASR-Nano (GPU) or falls back to AutoModel for non-LLM models (SenseVoice/Paraformer).
Uses vLLM for Fun-ASR-Nano (GPU) or AutoModel for supported models, including
MOSS-Transcribe-Diarize's joint transcription and anonymous speaker labels.
"""
import io
@@ -32,6 +33,8 @@ PACKAGE_VERSION = (Path(__file__).resolve().parents[1] / "version.txt").read_tex
_LANGUAGE_TAG_RE = re.compile(r"<\|(zh|en|yue|ja|ko)\|>")
MOSS_MODEL_REVISION = "e8681d68e7042738ffca8ac8212bc8fcb1131ab8"
NATIVE_DIARIZATION_MODELS = {"moss-transcribe-diarize"}
def extract_language_from_asr_text(text):
@@ -257,6 +260,13 @@ def create_app(
"vad_model": "fsmn-vad",
"punc_model": "ct-punc",
},
"moss-transcribe-diarize": {
"model": "OpenMOSS-Team/MOSS-Transcribe-Diarize",
"model_revision": MOSS_MODEL_REVISION,
"hub": "hf",
"backend": "hf",
"trust_remote_code": True,
},
}
def _load_spk_model():
@@ -335,7 +345,7 @@ def create_app(
if app.state.model_path:
cfg["model"] = app.state.model_path
cfg["hub"] = app.state.hub
elif app.state.hub:
elif app.state.hub and "hub" not in cfg:
cfg["hub"] = app.state.hub
cfg["device"] = device
cfg["disable_update"] = True
@@ -434,7 +444,7 @@ def create_app(
segments.append(segment)
if not segments and text:
segments = build_openai_fallback_segments(text, duration)
if use_spk and segments:
if use_spk and model_name not in NATIVE_DIARIZATION_MODELS and segments:
audio_data, sr = sf.read(audio_path)
attach_speaker_labels(
audio_data,
+10 -1
View File
@@ -5,6 +5,7 @@ Usage:
funasr-server # default: sensevoice on cuda:0, port 8000
funasr-server --device cpu --port 9000
funasr-server --model paraformer
funasr-server --model moss-transcribe-diarize --device cuda:0
funasr-server --model-path /path/to/local/model
funasr-server --model-path username/paraformer --hub hf
funasr-server --cors-origin http://localhost:3000
@@ -31,6 +32,7 @@ Examples:
funasr-server # Start with SenseVoice on GPU
funasr-server --device cpu # Start on CPU
funasr-server --model paraformer # Use Paraformer model
funasr-server --model moss-transcribe-diarize --device cuda:0
funasr-server --port 9000 # Custom port
funasr-server --model-path /path/to/local/model # Use local model
funasr-server --model-path username/model --hub hf # Use HuggingFace model
@@ -45,7 +47,14 @@ Then use with OpenAI SDK:
parser.add_argument("--host", default="0.0.0.0", help="Bind address (default: 0.0.0.0)")
parser.add_argument("--port", type=int, default=8000, help="Port (default: 8000)")
parser.add_argument("--device", default="cuda", help="Device: cuda, cpu, mps (default: cuda)")
parser.add_argument("--model", default="auto", help="Pre-load model: auto (GPU=fun-asr-nano, CPU=sensevoice), sensevoice, paraformer, fun-asr-nano")
parser.add_argument(
"--model",
default="auto",
help=(
"Pre-load model: auto (GPU=fun-asr-nano, CPU=sensevoice), "
"sensevoice, paraformer, fun-asr-nano, moss-transcribe-diarize"
),
)
parser.add_argument("--model-path", default=None, help="Local model path or model ID (overrides --model)")
parser.add_argument("--hub", default="ms", help="Model hub: ms (ModelScope), hf (HuggingFace) (default: ms)")
parser.add_argument(
@@ -1,3 +1,4 @@
import json
from pathlib import Path
import pytest
@@ -78,3 +79,82 @@ def test_all_deployment_matrices_link_moss_guide(matrix: Path) -> None:
"FunASR 소유 model 또는 `AutoModel` backend가 아닙니다",
):
assert stale_claim not in moss_row
def test_moss_guides_cover_funasr_service_and_offline_boundaries() -> None:
for guide in GUIDES:
text = guide.read_text(encoding="utf-8")
assert "funasr-server --model moss-transcribe-diarize" in text
assert "response_format=verbose_json" in text
assert "examples/openai_api/docker-compose.moss.yml" in text
assert "examples/openai_api/kubernetes/funasr-moss-api.yaml" in text
assert "WebSocket" in text
assert "FunClip" in text
def test_moss_service_recipes_are_pinned_and_gpu_scoped() -> None:
dockerfile = ROOT / "examples" / "openai_api" / "Dockerfile.moss"
compose = ROOT / "examples" / "openai_api" / "docker-compose.moss.yml"
kubernetes = (
ROOT / "examples" / "openai_api" / "kubernetes" / "funasr-moss-api.yaml"
)
assert dockerfile.is_file()
assert compose.is_file()
assert kubernetes.is_file()
docker_text = dockerfile.read_text(encoding="utf-8")
compose_text = compose.read_text(encoding="utf-8")
kubernetes_text = kubernetes.read_text(encoding="utf-8")
for text in (docker_text, compose_text, kubernetes_text):
assert "moss-transcribe-diarize" in text
assert "transformers>=5.6,<6" in docker_text
assert "capabilities: [gpu]" in compose_text
assert "nvidia.com/gpu" in kubernetes_text
def test_github_pages_indexes_moss_deployment_guide() -> None:
index = (ROOT / "docs" / "index.rst").read_text(encoding="utf-8")
assert "./moss_transcribe_diarize.md" in index
assert "./moss_transcribe_diarize_zh.md" in index
def test_readmes_link_the_runnable_moss_service() -> None:
readmes = [
ROOT / "README.md",
ROOT / "README_zh.md",
ROOT / "README_ja.md",
ROOT / "README_ko.md",
ROOT / "examples" / "openai_api" / "README.md",
ROOT / "examples" / "openai_api" / "README_zh.md",
ROOT / "examples" / "openai_api" / "README_ja.md",
ROOT / "examples" / "openai_api" / "README_ko.md",
]
for readme in readmes:
text = readme.read_text(encoding="utf-8")
assert "moss-transcribe-diarize" in text
assert "moss_transcribe_diarize" in text
def test_openai_consumer_docs_expose_moss_alias_and_boundaries() -> None:
paths = [
"CLIENTS.md",
"GRADIO.md",
"GRADIO_zh.md",
"OPENAPI.md",
"OPENAPI_zh.md",
"WORKFLOWS.md",
"WORKFLOWS_zh.md",
"JAVASCRIPT.md",
"JAVASCRIPT_zh.md",
"kubernetes/README.md",
"kubernetes/README_zh.md",
]
root = ROOT / "examples" / "openai_api"
for relative in paths:
text = (root / relative).read_text(encoding="utf-8")
assert "moss-transcribe-diarize" in text
assert "moss_transcribe_diarize" in text
spec = json.loads((root / "openapi.json").read_text(encoding="utf-8"))
model = spec["components"]["schemas"]["TranscriptionRequest"]["properties"]["model"]
assert "moss-transcribe-diarize" in model["enum"]
+47
View File
@@ -442,6 +442,53 @@ def test_spk_request_lazily_loads_and_reuses_speaker_model(monkeypatch):
]
def test_moss_service_uses_pinned_joint_transcription_config(monkeypatch):
module = load_server_app(monkeypatch)
DummyAutoModel = install_dummy_funasr(monkeypatch)
module.create_app(device="cuda:0", preload_model="moss-transcribe-diarize")
config = DummyAutoModel.instances[-1]
assert config["model"] == "OpenMOSS-Team/MOSS-Transcribe-Diarize"
assert config["model_revision"] == "e8681d68e7042738ffca8ac8212bc8fcb1131ab8"
assert config["hub"] == "hf"
assert config["backend"] == "hf"
assert config["trust_remote_code"] is True
assert "vad_model" not in config
assert "spk_model" not in config
def test_moss_verbose_json_preserves_native_speaker_segments(monkeypatch):
module = load_server_app(monkeypatch)
DummyAutoModel = install_dummy_funasr(
monkeypatch,
generated_result={
"text": "hello again",
"sentence_info": [
{"start": 100, "end": 900, "spk": "S01", "text": "hello"},
{"start": 950, "end": 1700, "spk": "S02", "sentence": "again"},
],
},
)
monkeypatch.setattr(module.sf, "info", lambda path: types.SimpleNamespace(duration=1.7))
app = module.create_app(device="cuda:0", preload_model="moss-transcribe-diarize")
transcribe = app.routes[("POST", "/v1/audio/transcriptions")]
response = asyncio.run(
transcribe(
file=DummyUpload(),
model="moss-transcribe-diarize",
language=None,
response_format="verbose_json",
spk=True,
)
)
assert [segment["speaker"] for segment in response["segments"]] == ["S01", "S02"]
assert [segment["text"] for segment in response["segments"]] == ["hello", "again"]
assert not any(config.get("model") == "cam++" for config in DummyAutoModel.instances)
def test_server_versions_follow_package_version(monkeypatch):
expected = (REPO_ROOT / "funasr" / "version.txt").read_text().strip()
module = load_server_app(monkeypatch)
+27 -2
View File
@@ -1,6 +1,6 @@
{
"schema_version": 1,
"verified": "2026-08-30",
"verified": "2026-09-01",
"deployments": [
{
"id": "moss-transcribe-diarize",
@@ -13,7 +13,7 @@
"models": ["OpenMOSS-Team/MOSS-Transcribe-Diarize (third-party Apache-2.0 model)"],
"operating_systems": ["Linux"],
"interfaces": ["OpenAI-compatible HTTP", "vLLM", "SGLang Omni", "Transformers", "LocalAI / moss-transcribe.cpp"],
"tested": {"funasr": "AutoModel vLLM + SGLang adapters; third-party model@e8681d68", "runtime": "vLLM 0.27.1 / Torch 2.13.0+cu129 / H100 80GB", "verified": "2026-08-30"},
"tested": {"funasr": "AutoModel HF + vLLM + SGLang adapters and OpenAI HTTP service; third-party model@e8681d68", "runtime": "Transformers 5.16.0.dev0 + Torch 2.11.0+cu130 and vLLM 0.27.1 + Torch 2.13.0+cu129 / H100 80GB", "verified": "2026-09-01"},
"commands": {
"install": [
"uv venv --python 3.12 .venv-moss && curl -fL https://github.com/vllm-project/vllm/releases/download/v0.27.1/vllm-0.27.1%2Bcu129-cp38-abi3-manylinux_2_28_x86_64.whl -o vllm-0.27.1+cu129-cp38-abi3-manylinux_2_28_x86_64.whl && echo 'bf0d52faa2a51e7a01c6856a7a8a2d1307fd0ff711415d34168a67ffac0fa47b vllm-0.27.1+cu129-cp38-abi3-manylinux_2_28_x86_64.whl' | sha256sum -c - && uv pip install --python .venv-moss/bin/python --torch-backend=auto \"vllm[audio] @ file://$PWD/vllm-0.27.1+cu129-cp38-abi3-manylinux_2_28_x86_64.whl\"",
@@ -33,6 +33,31 @@
]
},
"runtime_paths": [
{
"id": "funasr-server",
"tested": "Transformers 5.16.0.dev0 / Torch 2.11.0+cu130 / H100 80GB; real HTTP response verified 2026-09-01",
"translations": {
"zh": {"name": "FunASR OpenAI 兼容服务", "summary": "直接使用内置 funasr-server 加载固定 revision 的 HF 后端,返回带匿名说话人标签的 verbose_json;可使用专用 Docker Compose 与 Kubernetes GPU 配方。"},
"en": {"name": "FunASR OpenAI-compatible service", "summary": "Load the pinned HF backend directly with funasr-server and return verbose_json with anonymous speaker labels; dedicated Docker Compose and Kubernetes GPU recipes are included."}
},
"commands": {
"install": [
"python -m pip install 'transformers>=5.6,<6' fastapi uvicorn python-multipart"
],
"launch": [
"funasr-server --model moss-transcribe-diarize --device cuda:0 --port 8000",
"docker compose -f examples/openai_api/docker-compose.moss.yml up --build"
],
"health": [
"curl -fsS http://127.0.0.1:8000/health",
"curl -fsS http://127.0.0.1:8000/v1/models"
],
"smoke": [
"curl -fsS http://127.0.0.1:8000/v1/audio/transcriptions -F file=@runtime/llama.cpp/tests/sample.wav -F model=moss-transcribe-diarize -F response_format=verbose_json | tee /tmp/funasr-moss-transcription.json",
"python - <<'PY'\nimport json\n\nwith open('/tmp/funasr-moss-transcription.json', encoding='utf-8') as stream:\n payload = json.load(stream)\nsegments = payload.get('segments', [])\nassert payload.get('text', '').strip() and segments, payload\nassert all(item.get('speaker') and item.get('start') <= item.get('end') for item in segments), payload\nprint(payload['text'], sorted({item['speaker'] for item in segments}))\nPY"
]
}
},
{
"id": "vllm",
"tested": "vLLM 0.27.1 / Torch 2.13.0+cu129 / H100 80GB; FunASR adapter verified",
+8 -2
View File
@@ -128,7 +128,7 @@ def test_detail_commands_come_from_registry(built_site):
assert command in rendered
def test_moss_detail_renders_separate_vllm_and_sglang_runtime_paths(built_site):
def test_moss_detail_renders_all_service_runtime_paths(built_site):
for relative in (
'deploy/moss-transcribe-diarize.html',
'en/deploy/moss-transcribe-diarize.html',
@@ -136,8 +136,14 @@ def test_moss_detail_renders_separate_vllm_and_sglang_runtime_paths(built_site):
soup = read_soup(built_site / relative)
paths = soup.select('[data-runtime-path]')
assert [path['data-runtime-path'] for path in paths] == ['vllm', 'sglang-omni']
assert [path['data-runtime-path'] for path in paths] == [
'funasr-server',
'vllm',
'sglang-omni',
]
rendered = '\n'.join(path.get_text('\n') for path in paths)
assert 'funasr-server --model moss-transcribe-diarize' in rendered
assert 'docker-compose.moss.yml' in rendered
assert 'vllm serve OpenMOSS-Team/MOSS-Transcribe-Diarize' in rendered
assert 'sgl-omni serve' in rendered
assert 'response_format=diarized_json' in rendered
+18 -9
View File
@@ -107,15 +107,24 @@ def test_moss_transcribe_diarize_contract_tracks_third_party_upstream(valid_regi
'OpenMOSS-Team/MOSS-Transcribe-Diarize (third-party Apache-2.0 model)'
]
assert entry['tested'] == {
'funasr': 'AutoModel vLLM + SGLang adapters; third-party model@e8681d68',
'runtime': 'vLLM 0.27.1 / Torch 2.13.0+cu129 / H100 80GB',
'verified': '2026-08-30',
'funasr': 'AutoModel HF + vLLM + SGLang adapters and OpenAI HTTP service; third-party model@e8681d68',
'runtime': 'Transformers 5.16.0.dev0 + Torch 2.11.0+cu130 and vLLM 0.27.1 + Torch 2.13.0+cu129 / H100 80GB',
'verified': '2026-09-01',
}
assert 'LocalAI / moss-transcribe.cpp' in entry['interfaces']
assert {'cpu', 'desktop-edge-gpu'} <= set(entry['hardware'])
runtime_paths = {path['id']: path for path in entry['runtime_paths']}
assert set(runtime_paths) == {'vllm', 'sglang-omni'}
assert set(runtime_paths) == {'funasr-server', 'vllm', 'sglang-omni'}
service_commands = '\n'.join(
command
for group in ('install', 'launch', 'health', 'smoke')
for command in runtime_paths['funasr-server']['commands'][group]
)
assert 'funasr-server --model moss-transcribe-diarize' in service_commands
assert 'docker-compose.moss.yml' in service_commands
assert 'response_format=verbose_json' in service_commands
assert 'real HTTP response verified 2026-09-01' in runtime_paths['funasr-server']['tested']
assert runtime_paths['vllm']['tested'] == (
'vLLM 0.27.1 / Torch 2.13.0+cu129 / H100 80GB; FunASR adapter verified'
)
@@ -222,7 +231,7 @@ def test_audio_cpp_contract_tracks_mainline_nano_and_sensevoice(valid_registry):
entry = next(item for item in valid_registry['deployments'] if item['id'] == 'audio-cpp')
llama_cpp = next(item for item in valid_registry['deployments'] if item['id'] == 'llama-cpp')
assert valid_registry['verified'] == '2026-08-30'
assert valid_registry['verified'] == '2026-09-01'
assert entry['maturity'] == 'community-verified'
assert entry['selector_rank'] > llama_cpp['selector_rank']
assert entry['tested'] == {
@@ -391,7 +400,7 @@ def test_sensevoice_native_server_contract_tracks_merged_runtime(valid_registry)
llama_cpp = next(item for item in valid_registry['deployments'] if item['id'] == 'llama-cpp')
audio_cpp = next(item for item in valid_registry['deployments'] if item['id'] == 'audio-cpp')
assert valid_registry['verified'] == '2026-08-30'
assert valid_registry['verified'] == '2026-09-01'
assert entry['maturity'] == 'production-verified'
assert llama_cpp['selector_rank'] < entry['selector_rank'] < audio_cpp['selector_rank']
assert entry['tested'] == {
@@ -485,9 +494,9 @@ def test_runtime_paths_require_unique_ids_translations_and_commands(valid_regist
item for item in data['deployments']
if item['id'] == 'moss-transcribe-diarize'
)
entry['runtime_paths'][1]['id'] = 'vllm'
del entry['runtime_paths'][0]['translations']['en']['summary']
del entry['runtime_paths'][1]['commands']['health']
entry['runtime_paths'][2]['id'] = 'vllm'
del entry['runtime_paths'][1]['translations']['en']['summary']
del entry['runtime_paths'][2]['commands']['health']
errors = validate_registry(data)