OddASR:支持离线转录和流式转录的、兼容 OpenAI API 的自动语音识别服务

License: MIT
Python 3.12.0+

OddASR 是一个兼容 OpenAI API 的自动语音识别(ASR)服务器,支持离线转录和流式转录,采用 2-pass ASR 策略以提高准确性。

注意:

  • 首次运行时,会自动下载模型文件。模型文件会保存在 models/ 目录下。
  • 模型文件大小较大,建议在有足够磁盘空间的环境运行。
  • 国内用户建议使用镜像加速下载模型文件。
  • 本项目基于 Paraformer、Moonshine、SenseVoice 模型实现,若需要使用其他模型,请自行在配置文件中指定模型路径。

功能特性

  • ✅ OpenAI API 兼容:可作为 OpenAI Whisper API 的替代方案(中文准确率比 Whisper 高,英文准确率也比 Whisper 高,但英文延迟会高一些
  • ✅ 多种响应格式:支持 text、srt、vtt、json、verbose_json、spk
  • ✅ 实时流式识别:支持 WebSocket 实时音频处理,集成 VAD 语音活动检测
  • ✅ 文件流式识别:网页端可选择本地音频文件,通过 WebSocket 以流式方式逐块发送并实时显示转写结果
  • ✅ 离线处理:支持批量音频文件转录,支持自定义模型和后端
  • ✅ 语音活动检测:采用 Silero VAD 实现智能语音检测
  • ✅ 2-pass ASR:结合流式和离线模型,兼顾低延迟和高准确率
  • ✅ 多后端支持:支持 FunASR (Paraformer)、SenseVoice、Moonshine ASR 模型,支持自定义模型和后端
  • ✅ 说话人识别:支持说话人分离(Speaker Diarization),仅 FunASR 后端可用
  • ✅ Web 界面:提供企业蓝主题网页 Demo,支持麦克风录音、文件流式、离线上传三种识别方式,支持音频播放预览
  • ✅ 模型动态切换:通过 API 动态切换后端模型(需重启服务生效)

快速开始

安装

直接安装:

pip install oddasr

或者从源码编译:

# 克隆仓库
git clone https://github.com/oddmeta/oddasr.git
cd oddasr

# 安装依赖
pip install -r requirements.txt
pip install -e .

配置(可选)

服务启动时无需配置文件,使用内置 DEFAULT_CONFIG。如需自定义,在项目根目录创建 config.json,只需覆盖需要修改的项即可:

{
  "active_model_index": 0,
  "model_options": [...]
}

详见 配置 部分。

基本用法

启动服务器:

oddasr-server

或使用自定义配置:

oddasr-server --config config.json

服务器启动后的访问地址:

Web 界面提供三种识别方式:

  • 🌊 流式识别:使用麦克风实时录音,通过 WebSocket 流式传输
  • 📂 文件流式识别:选择本地音频文件,通过 WebSocket 以流式方式逐块发送
  • 📁 离线识别:上传音频文件,通过 HTTP API 获取完整转写结果

架构

2-Pass ASR

OddASR 采用 2-pass ASR 策略:

  1. 流式识别:使用流式 ASR 模型进行实时转录
  2. 离线优化:使用离线 ASR 模型和标点模型进行最终优化

这种组合同时实现了低延迟和高准确率。

支持的模型

后端流式识别离线识别标点说话人识别
FunASRparaformer-zh-streamingparaformer-zh
Moonshinemoonshine/basemoonshine/base
SenseVoicesherpa-onnx (内置 VAD)sherpa-onnx (内置 VAD)内置

API 使用方法

Python 客户端

import openai

client = openai.OpenAI(
    base_url="http://localhost:9002/v1",
    api_key="dummy"  # 兼容需要,实际无需填写
)

# 离线转录
with open("audio.wav", "rb") as audio_file:
    transcript = client.audio.transcriptions.create(
        model="oddasr-2",
        model_type="funasr",
        file=audio_file,
        response_format="text"  # text, srt, vtt, json, verbose_json, spk
    )
    print(transcript.text)

cURL

curl -X POST http://localhost:9002/v1/audio/transcriptions \
  -H "Content-Type: multipart/form-data" \
  -F "file=@audio.wav" \
  -F "model=oddasr-2" \
  -F "model_type=funasr" \
  -F "response_format=text"

WebSocket 流式识别

import asyncio
import websockets
import json
import base64

async def realtime_transcription():
    uri = "ws://localhost:9003/v1/realtime"

    async with websockets.connect(uri) as websocket:
        async for message in websocket:
            data = json.loads(message)

            if data['type'] == 'conversation.item.input_audio_transcription.completed':
                print(f"转录结果: {data['transcript']}")
            elif data['type'] == 'response.audio_transcript.delta':
                print(f"中间结果: {data['delta']}", end='\r')
            elif data['type'] == 'error':
                print(f"错误: {data['error']['message']}")

asyncio.run(realtime_transcription())

流式测试客户端

项目内置了流式转写测试程序,支持命令行参数:

# 基本用法
python tests/test_api_streaming.py tests/test.wav

# 指定 chunk 大小和服务器地址
python tests/test_api_streaming.py tests/test.wav --chunk-ms 300 --host 192.168.1.10 --port 9003

# 以最快速度发送(不模拟实时延迟)
python tests/test_api_streaming.py tests/test.wav --no-simulate-realtime

功能特点:

  • 自动将音频重采样到 16kHz
  • 支持自定义 chunk 时长(默认 600ms)
  • 支持模拟实时发送或全速发送
  • 显示发送进度、partial 中间结果和 final 最终结果

响应格式

格式说明使用场景
text纯文本简单转录
srtSubRip 字幕视频字幕
vttWebVTT 字幕网页视频
json简单 JSON程序处理
verbose_json带时间戳的详细 JSON分析调试
spk说话人识别模型输出说话人识别

项目结构

oddasr/
├── app.py                     # 主程序入口
├── logic/                     # 业务逻辑
│   ├── odd_asr_server.py           # WebSocket 服务器
│   ├── odd_asr_stream_handler.py   # 流式处理器(OpenAI Realtime API 兼容)
│   ├── odd_asr_instance_pool.py    # ASR 模型实例池管理
│   └── odd_asr_global.py           # 全局状态
├── models/                    # ASR 模型
│   ├── base_asr.py                 # ASR 基类接口
│   ├── funasr_asr.py               # FunASR 实现(含 Cython 加速)
│   ├── moonshine_asr.py            # Moonshine 实现
│   ├── sensevoice_asr.py           # SenseVoice (sherpa-onnx) 实现
│   ├── two_pass_asr.py             # 2-pass ASR 控制器
│   └── punctuation.py              # 标点模型
├── router/                    # Flask 路由
│   ├── api.py                      # REST API 路由
│   └── front.py                    # 前端页面路由
├── utils/                     # 工具函数
│   ├── audio.py                    # 音频处理(含重采样)
│   ├── vad.py                      # Silero VAD 语音活动检测
│   ├── formatters.py               # 响应格式化(text/srt/vtt/json)
│   ├── messages.py                 # WebSocket 消息格式(OpenAI 兼容)
│   └── model_manager.py            # 模型下载管理
├── templates/                 # Web 模板
│   └── index.html                  # 网页 Demo(Tab 布局、企业蓝主题)
├── static/                    # 静态文件
├── tests/                     # 测试文件
│   ├── test_api_offline.py         # 离线 API 集成测试
│   ├── test_api_streaming.py       # 流式 WebSocket 测试客户端
│   ├── test_vad.py                 # VAD 单元测试
│   └── test_two_pass_asr.py        # 2-pass ASR 测试
├── docs/                      # 文档
├── models/oddasr_model/       # 本地 ONNX 模型(SenseVoice)
├── config.json                # 用户自定义配置(可选)
├── requirements.txt           # 依赖列表
└── setup.py                   # 打包配置

开发

运行测试

# 运行所有测试
pytest tests/

# 运行指定测试
pytest tests/test_vad.py

代码结构

代码遵循清晰的架构设计:

  • logic/:服务器和请求处理
  • models/:ASR 模型实现(FunASR、Moonshine、SenseVoice)
  • utils/:音频处理、VAD、格式化工具

配置

服务使用内置 DEFAULT_CONFIG 启动,无需配置文件即可运行。如需自定义,在项目根目录创建 config.json,只需覆盖需要修改的项。

配置示例

{
  "active_model_index": 0,
  "model_options": [
    {
      "model_type": "funasr",
      "output_type": ["text", "srt", "vtt", "json", "verbose_json", "spk"],
      "options": {
        "streaming": {
          "model": "paraformer-zh-streaming",
          "device": "cpu",
          "max_instance": 1
        },
        "offline": {
          "model": "paraformer-zh",
          "device": "cpu",
          "max_instance": 1
        },
        "punc": {
          "model": "iic/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727",
          "revision": "v2.0.4"
        },
        "spk": {
          "model": "iic/speech_eres2netv2_sv_zh-cn_16k-common",
          "revision": "v2.0.4",
          "enable": false
        }
      }
    },
    {
      "model_type": "sensevoice",
      "output_type": ["text"],
      "options": {
        "streaming": {
          "model": "models/oddasr_model/model/model.int8.onnx",
          "device": "cpu",
          "max_instance": 1
        },
        "offline": {
          "model": "models/oddasr_model/model/model.int8.onnx",
          "device": "cpu",
          "max_instance": 1
        }
      }
    }
  ],
  "vad": {
    "vad_use_model": true,
    "vad_model_name": "silero-vad",
    "vad_model_threshold": 0.5,
    "vad_device": "cpu",
    "vad_silence_duration": 1.0
  },
  "2pass": {
    "max_audio_samples": 480000
  }
}

配置参数说明

模型配置

参数说明默认值
active_model_index默认激活的模型选项索引0
model_options可用模型配置列表见 DEFAULT_CONFIG
model_options[].model_typeASR 后端(funasr/moonshine/sensevoice)funasr
model_options[].output_type该后端支持的响应格式["text"]
model_options[].options.streaming.model流式识别模型名称paraformer-zh-streaming
model_options[].options.streaming.device流式模型运行设备(cpu/cuda)cpu
model_options[].options.offline.model离线识别模型名称paraformer-zh
model_options[].options.offline.device离线模型运行设备(cpu/cuda)cpu
model_options[].options.spk.enable启用说话人识别(仅 FunASR)false

VAD 配置

参数说明默认值
vad.vad_use_model使用 Silero VAD 模型true
vad.vad_model_threshold语音检测阈值0.5
vad.vad_silence_duration触发结束说话的静音时长(秒)1.0
vad.vad_speech_padding语音前后填充时长(秒)0.3
vad.vad_energy_threshold能量模式阈值0.01

2-Pass 配置

参数说明默认值
2pass.max_audio_samples最大音频采样数(约 30s@16kHz480000

服务器配置

参数说明默认值
server.max_connections最大 WebSocket 连接数10
server.ping_intervalWebSocket ping 间隔(秒)30
server.ping_timeoutWebSocket ping 超时(秒)300

许可证

MIT 许可证 – 详见 LICENSE 文件

技术支持

致谢

  • FunASR – 优秀的 ASR 模型
  • Moonshine – 快速流式 ASR
  • SenseVoice – ONNX优化SenseVoice模型
  • Silero VAD – 语音活动检测
  • OpenAI – API 设计灵感来源