Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

(English|简体中文|日本語|한국어)

FunASR OpenAI-Compatible API Server

An OpenAI-style /v1/audio/transcriptions endpoint for private speech transcription. This example implements a speech API subset, not the entire OpenAI API or a compatibility guarantee for every SDK/framework feature.

This page starts the repository's example server. The packaged funasr-server is a different implementation; see API boundaries before reusing its settings. For in-process AutoModel.generate() rather than HTTP requests, use the Python SDK guide (中文).

For the maintained packaged-service route, start with Agent integration. The example has no built-in authentication or upload limit; api_key="not-needed" does not authenticate it. Keep local testing on loopback. Before sharing, configure TLS, gateway authentication, upload/time/rate limits, audio/transcript retention, and private health/model/schema access using the security guide.

API Contract

  • Example python server.py in this directory: startup and omitted multipart model both default to sensevoice. There is no spk form field; the example only preserves speaker labels already returned by the model.
  • Packaged funasr-server: startup --model auto selects fun-asr-nano for a device string starting with cuda, otherwise sensevoice. Omitted multipart model independently defaults to fun-asr-nano. spk=true requests the separate speaker pipeline for non-native diarization models; default is False.

Specify model explicitly in requests: startup preloading and the request default are different settings. Query the deployed /v1/models; for example, paraformer-en is registered by this example but is not a built-in alias of the packaged server. Verify fields with the running /openapi.json, not just the checked-in example schema.

response_format=verbose_json selects a response shape; it does not enable diarization or force timestamp generation. This example copies sentence_info into segments if present, otherwise returns segments=[]. Speaker labels can be absent or null. MOSS supplies native anonymous labels; it does not need spk=true or external VAD/CAM++.

SDK output such as timestamp, or Nano's timestamps / ctc_timestamps, is not automatically converted into HTTP segments. This example accepts multipart file, model, language, and response_format; SDK options such as use_itn, hotwords, raw arrays, and spk are not its form fields. Its language is the submitted hint or auto, not detected language; the packaged service can use backend language detection.

In this example, duration is elapsed time around generate() in seconds, excluding initial model loading; it is not audio duration. The packaged server's verbose response uses audio duration in seconds (its fallback can use 0 when audio metadata is unavailable). Segment start/end use seconds in both services. The packaged fallback can synthesize coarse segments from text and audio duration; those are not word-level forced alignment. Its verbose schema includes task and per-segment id/words, while this example includes model; do not assume identical JSON fields. See response examples and speaker requests.

Quick Start

Use a fresh checkout and a POSIX shell with Python 3.11 installed:

git clone https://github.com/modelscope/FunASR.git FunASR-api
cd FunASR-api
git checkout --detach d91d961e37a005837b1523bcc6b09f087877be54
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
python -m pip install fastapi uvicorn python-multipart
python -m pip check
cd examples/openai_api
python server.py --host 127.0.0.1 --model sensevoice --device cpu --port 8000

This pins source only, not dependencies, model weights, audio decoders, or CUDA. A PyPI install alone does not provide repository examples. These are setup instructions, not evidence of a fresh installation or successful acoustic inference on your hardware.

Wait for model loading before checking GET /health; download and startup time depend on the checkpoint, cache, network, and hardware. Health alone does not verify transcription. The commands below use this directory unless stated otherwise. After preparing CUDA-capable dependencies, replace the CPU command with python server.py --host 127.0.0.1 --model sensevoice --device cuda --port 8000; do not start both on the same port.

Need copy-paste integration snippets for Python SDK, JavaScript/TypeScript, HTTP clients, agent tools, a browser demo, Postman, OpenAPI imports, Kubernetes deployment, or Dify/n8n-style workflows? See Client recipes, JavaScript/TypeScript recipes, Gradio browser demo, workflow recipes, the Chinese workflow recipes, the Postman collection, the OpenAPI spec, the security and gateway guide, and the Kubernetes deployment template.

End-to-end smoke test

In another terminal, enter the same checkout, activate .venv, and enter examples/openai_api. The optional scripts check health and transcription:

bash smoke_test.sh
# Cross-platform alternative without curl/bash:
python smoke_test.py

Equivalent manual commands using public Chinese sample audio, not a Japanese/Korean validation set:

curl -L https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/BAC009S0764W0121.wav -o sample.wav
curl http://localhost:8000/health
curl http://localhost:8000/v1/models
curl http://localhost:8000/openapi.json
curl http://localhost:8000/v1/audio/transcriptions \
  -F file=@sample.wav \
  -F model=sensevoice \
  -F response_format=verbose_json

Browser demo with Gradio

For local file upload or recorded microphone audio, follow the maintained Gradio browser demo. It uses a separate Python 3.12 environment, .venv-gradio, rather than this API server's environment. The guide covers the funasr, vllm, and sglang-omni profiles, explicit model selection, Docker/Kubernetes connectivity, microphone permissions, and privacy limits. The UI is a separate HTTP client, not an authentication gateway or a realtime transcription service.

Usage with OpenAI SDK (Python)

In the same activated environment, install the separate HTTP client with python -m pip install openai. This is not the FunASR Python SDK. Replace meeting.wav with a real local audio file supported by your prepared decoders.

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")

# Basic transcription
with open("meeting.wav", "rb") as audio:
    result = client.audio.transcriptions.create(model="sensevoice", file=audio)
print(result.text)

# Inspect the verbose response; segments may be empty
with open("meeting.wav", "rb") as audio:
    result = client.audio.transcriptions.create(
        model="sensevoice", file=audio, response_format="verbose_json",
    )
# verbose_json does not enable diarization; see API Contract above
print(getattr(result, "segments", []))

Usage with curl

curl http://localhost:8000/v1/audio/transcriptions \
  -F file=@audio.wav \
  -F model=sensevoice

# With verbose output
curl http://localhost:8000/v1/audio/transcriptions \
  -F file=@audio.wav \
  -F model=sensevoice \
  -F response_format=verbose_json

Available Models

These are aliases in this example's MODEL_CONFIGS, not a universal SDK or server model list. The endpoint removes rich <|...|> tags from returned text; it does not expose dedicated emotion/event fields.

  • sensevoice: SenseVoiceSmall + FSMN-VAD. Does not enable sentence timestamps or external speaker clustering by default.
  • paraformer: paraformer-zh + FSMN-VAD + CT punctuation. Punctuation is configured; verbose_json alone does not request sentence records.
  • paraformer-en: paraformer-en + FSMN-VAD. Example-only alias relative to the packaged server; no punctuation component configured here.
  • fun-asr-nano: Fun-ASR-Nano via AutoModel, HF hub + FSMN-VAD. Not a vLLM route in this example. CTC timestamp availability depends on complete checkpoint weights.
  • moss-transcribe-diarize: Third-party OpenMOSS native transcription/diarization adapter. Requires its separate dependency environment; preserves model-provided timestamps and anonymous labels.

For checkpoint-specific language and license information, use model selection and the model's own license. FunASR software's MIT license is not a license for every model weight. Benchmark the selected route on your own workload; these aliases do not define universal speed or capacity.

Fun-ASR-MLT-Nano is a separate multilingual checkpoint, not a built-in alias in either service; base Nano does not establish Korean support. For a custom checkpoint, the packaged route uses --model-path and --hub with request model="custom"; these are not example-server options. Follow the model-selection and Agent guides for checkpoint-specific setup.

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 for funasr-server, Docker Compose, Kubernetes, vLLM, SGLang Omni, LocalAI, and FunClip paths. Its speaker labels are anonymous within one recording, not real-world identities or cross-recording speaker recognition. An alias appearing in /v1/models does not prove its dependencies or weights are ready.

API Endpoints

Endpoint Method Description
/v1/audio/transcriptions POST Transcribe audio (OpenAI-compatible)
/v1/models GET List available models
/health GET Health check + loaded models
/docs GET Interactive API documentation (Swagger)

Prefer no-code API checks? Use the Gradio browser demo for local upload or microphone testing, or import the Postman collection and run health, model-list, and transcription requests from Postman. For API gateways, developer portals, or client generation, use the OpenAPI spec.

Agent Framework Integration

The multipart HTTP/tool-function pattern can be used to integrate LangChain, LlamaIndex, AutoGen, CrewAI, Semantic Kernel, Dify, and n8n; validate the chosen integration against this service's supported fields. These recipes do not establish compatibility with every framework version or realtime API. See Client recipes and JavaScript/TypeScript recipes for SDK and agent-tool patterns, plus workflow recipes for low-code HTTP nodes and webhook workers (中文).

Both services map the workflow request alias whisper-1 to the startup-selected model; this does not run OpenAI Whisper. A workflow container's localhost refers to that container. Use an intentionally authorized reachable gateway/service address, not unrestricted public exposure.

LangChain Example

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="x")

def transcribe_for_agent(audio_path: str) -> str:
    """Tool function for LangChain agent."""
    with open(audio_path, "rb") as audio:
        result = client.audio.transcriptions.create(model="sensevoice", file=audio)
    return result.text

Docker Deployment

From the repository root, build the example image with the following commands. The default image starts the example server.py in CPU mode, not the packaged funasr-server.

This is a local-development publication setting, not authentication. The container still listens on 0.0.0.0; only the host-published port binds to 127.0.0.1. Do not change the container listener to loopback. The current Dockerfile installs unpinned PyPI FunASR/dependencies while copying this example, so it is not the source-pinned Python environment above or a reproducible acoustic environment.

cd examples/openai_api
cp .env.example .env

FUNASR_HOST_PORT=127.0.0.1:8000 docker compose up --build

Equivalent one-off docker run command:

docker build -t funasr-api .

docker run --rm -p 127.0.0.1:8000:8000 \
  -e FUNASR_DEVICE=cpu \
  -e FUNASR_MODEL=sensevoice \
  funasr-api

For GPU hosts, use NVIDIA Container Toolkit and a CUDA-capable PyTorch/FunASR image. After adapting the image dependencies for CUDA, run the same server with FUNASR_DEVICE=cuda:

docker run --rm --gpus all -p 127.0.0.1:8000:8000 \
  -e FUNASR_DEVICE=cuda \
  -e FUNASR_MODEL=sensevoice \
  funasr-api

Verify the container from another terminal:

BASE_URL=http://localhost:8000 bash smoke_test.sh
python smoke_test.py --base-url http://localhost:8000

The optional validate_docker.sh combines build/run/smoke steps, but its default port publication uses all host interfaces and does not inherit the loopback settings above. Review its networking before running it; use the explicit loopback build/run/smoke recipe above for local testing on shared networks. Its GPU mode additionally requires NVIDIA Container Toolkit and a CUDA-capable image. These instructions are not evidence of a Docker or acoustic inference test.

Kubernetes Deployment

Before sharing the service across a team or exposing it through a gateway, review the security and gateway guide for TLS, authentication, upload limits, rate limits, and logging.

For an internal cluster service with persistent model cache, health probes, and a private ClusterIP, start from the Kubernetes deployment template. Build and push the example image, apply the manifests, then verify through kubectl port-forward with python smoke_test.py --base-url http://localhost:8000.

Keep the default CPU mode until you have built a CUDA-capable image and configured GPU scheduling for your cluster.

Configuration

The following defaults belong to this example's server.py, not funasr-server; compare API boundaries.

Arg Default Description
--host 0.0.0.0 Bind address
--port 8000 Port
--device cuda Device (cuda/cpu/mps)
--model sensevoice Pre-load model at startup

Docker environment variables:

Env Default Description
FUNASR_PORT 8000 Container port passed to server.py
FUNASR_DEVICE cpu Container device mode; set to cuda only when the image has CUDA-capable dependencies
FUNASR_MODEL sensevoice Model alias loaded at container startup

Troubleshooting

  • If CUDA is unavailable, use --device cpu for a slower but simple smoke test.
  • If port 8000 is occupied, start with --port 9000 and run BASE_URL=http://localhost:9000 bash smoke_test.sh or python smoke_test.py --base-url http://localhost:9000.
  • If model download is slow, retry with a stable network or pre-download the model from ModelScope/Hugging Face.