All apps · 0 apps
SenseVoice-API
Docker app from hsiang's Repository
Overview
Readme
View on GitHubSenseVoice-API
OpenAI-compatible Speech-to-Text API powered by SenseVoice-Small (Alibaba FunAudioLLM).
Ultra-low latency (~70ms for 10s audio). Emotion detection. Audio event detection. Language identification. Word-level timestamps. One container.
Features
- OpenAI-compatible
/v1/audio/transcriptionsendpoint - WebSocket streaming
/v1/audio/transcriptions/stream - Emotion detection (happy, sad, angry, neutral)
- Audio event detection (Speech, Music, Applause, Laughter, BGM, etc.)
- Auto language identification (zh, en, ja, ko, yue)
- Speaker diarization — identify who is speaking (via
cam++model, opt-in) - Word-level timestamps (via
verbose_json) - Non-autoregressive: ~70ms for 10s audio on GPU
- CUDA 12.8 for RTX 5060 Ti / Blackwell GPUs
- First start downloads model (~900MB), subsequent starts are instant
Quick Start
docker run -d --gpus all \
-p 10095:10095 \
-v /mnt/user/appdata/sensevoice-api/models:/root/.cache/huggingface \
--name sensevoice-api \
ghcr.io/hsiang-han/sensevoice-api:latest
Usage Examples
# Basic transcription (OpenAI-compatible)
curl -X POST http://localhost:10095/v1/audio/transcriptions \
-F "file=@audio.wav"
# Response: {"text": "识别结果"}
# Verbose response (emotion + event + timestamps)
curl -X POST http://localhost:10095/v1/audio/transcriptions \
-F "file=@audio.wav" \
-F "response_format=verbose_json"
Response Examples
Standard (json):
{"text": "今天天气真好,我们出去玩吧。"}
Verbose (verbose_json):
{
"task": "transcribe",
"language": "zh",
"duration": 4.8,
"text": "今天天气真好,我们出去玩吧。",
"emotion": "happy",
"event": "Speech",
"processing_time": 0.072,
"words": [
{"word": "今天", "start": 0.21, "end": 0.63},
{"word": "天气", "start": 0.63, "end": 1.05},
{"word": "真好", "start": 1.05, "end": 1.47}
]
}
Verbose with speaker diarization (ENABLE_SPK=true):
{
"task": "transcribe",
"language": "zh",
"duration": 12.4,
"text": "今天开会讨论一下项目进展。好的没问题。",
"emotion": "neutral",
"event": "Speech",
"processing_time": 0.183,
"segments": [
{"start": 0.24, "end": 4.10, "text": "今天开会讨论一下项目进展。", "speaker": "spk1", "emotion": "neutral"},
{"start": 4.85, "end": 7.30, "text": "好的没问题。", "speaker": "spk2", "emotion": "happy"}
]
}
WebSocket Streaming
import websockets, asyncio
async def stream():
async with websockets.connect("ws://localhost:10095/v1/audio/transcriptions/stream") as ws:
with open("audio.wav", "rb") as f:
await ws.send(f.read())
result = await ws.recv()
print(result)
# {"text": "...", "language": "zh", "emotion": "neutral", "event": "Speech", "is_final": true}
asyncio.run(stream())
OpenAI SDK
from openai import OpenAI
client = OpenAI(base_url="http://localhost:10095/v1", api_key="none")
result = client.audio.transcriptions.create(
model="sensevoice-small",
file=open("audio.wav", "rb"),
)
print(result.text)
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/v1/audio/transcriptions |
POST | Speech-to-text (OpenAI-compatible) |
/v1/audio/transcriptions/stream |
WebSocket | Streaming transcription |
/v1/models |
GET | List models |
/health |
GET | Health check (shows enabled features) |
/docs |
GET | Swagger documentation |
SenseVoice Unique Capabilities
| Capability | Description | How to access |
|---|---|---|
| Emotion detection | happy, sad, angry, neutral | verbose_json → emotion field |
| Audio event detection | Speech, Music, Applause, Laughter, BGM, Cry, Cough, Sneeze, Breath | verbose_json → event field |
| Language identification | zh, en, ja, ko, yue (auto-detected) | verbose_json → language field |
| Word-level timestamps | Forced-alignment timestamps per word | verbose_json → words array |
| Speaker diarization | Identify who is speaking (requires ENABLE_SPK=true) |
verbose_json → segments[].speaker field |
| Mixed-language | Code-switching between supported languages | Automatic |
Environment Variables
| Variable | Default | Description |
|---|---|---|
DEVICE |
cuda:0 |
Compute device (cuda:0, cuda:1, cpu) |
MODEL_ID |
FunAudioLLM/SenseVoiceSmall |
HuggingFace model ID |
ENABLE_SPK |
false |
Enable speaker diarization via cam++ model (~7MB extra download) |
BATCH_SIZE |
1 |
Inference batch size |
PORT |
10095 |
Server port |
HF_ENDPOINT |
https://huggingface.co |
HuggingFace mirror (China: https://hf-mirror.com) |
Unraid
Add template repo: https://github.com/hsiang-han/unraid_templates
Or manually install with:
- Repository:
ghcr.io/hsiang-han/sensevoice-api:latest - Extra Parameters:
--gpus all - Model Cache path:
/mnt/user/appdata/sensevoice-api/models→/root/.cache/huggingface
Hardware Requirements
- NVIDIA GPU with 2GB+ VRAM
- NVIDIA driver 550+ (Ampere/Ada) or 570+ (Blackwell)
- Docker with NVIDIA Container Toolkit
Build
docker compose -f docker/gpu/docker-compose.yml up --build
Credits
- SenseVoice by Alibaba FunAudioLLM / Tongyi Lab
- FunASR toolkit
License
MIT
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/hsiang-han/sensevoice-api:latestRuntime arguments
- Web UI
http://[IP]:[PORT:10095]/docs- Network
bridge- Shell
bash- Privileged
- false
- Extra Params
--gpus all
Template configuration
REST API and WebSocket port. Swagger docs at /docs
- Target
- 10095
- Default
- 10095
- Value
- 10095
Model download cache (~900MB). First start downloads model here; subsequent starts are instant. Persists across container recreates.
- Target
- /root/.cache/huggingface
- Default
- /mnt/user/appdata/sensevoice-api/models
- Value
- /mnt/user/appdata/sensevoice-api/models
Inference device. GPU: cuda:0 (recommended, ~70ms/10s audio), cuda:1 for second GPU. CPU: set to cpu (slower, but no GPU required — remove --gpus all from Extra Parameters).
- Target
- DEVICE
- Default
- cuda:0
- Value
- cuda:0
HuggingFace model identifier. Default model is pre-downloaded in image.
- Target
- MODEL_ID
- Default
- FunAudioLLM/SenseVoiceSmall
- Value
- FunAudioLLM/SenseVoiceSmall
HuggingFace download endpoint. China users: change to https://hf-mirror.com for faster model downloads.
- Target
- HF_ENDPOINT
- Default
- https://huggingface.co
- Value
- https://huggingface.co
Identify who is speaking using cam++ model. Adds ~7MB speaker model download on first start. Results appear in verbose_json format as 'segments' with 'speaker' field. Requires response_format=verbose_json in client.
- Target
- ENABLE_SPK
- Default
- false
- Value
- false
Inference batch size
- Target
- BATCH_SIZE
- Default
- 1
- Value
- 1
Internal API server port
- Target
- PORT
- Default
- 10095
- Value
- 10095
GPU devices to expose (all, 0, 1, etc.)
- Target
- NVIDIA_VISIBLE_DEVICES
- Default
- all
- Value
- all
NVIDIA driver capabilities
- Target
- NVIDIA_DRIVER_CAPABILITIES
- Default
- compute,utility
- Value
- compute,utility