VoiceTyper Server
voice-typer-server 是 VoiceTyper 的语音识别服务端。它负责接收客户端上传的音频,完成识别、标点恢复,并可选调用 LLM 做二次纠错。
亮点
- 本地运行,默认不依赖云端 ASR
- 流式识别(默认):WebSocket 双通道——录音时 HUD 实时预览(跟嘴),松手后离线整段复识别产出准确最终结果
- 非流式识别(兼容):HTTP POST,供 Linux 客户端及非流式场景使用
- 默认最终识别模型为 SenseVoice-Small:自带标点与 ITN(「六十四兆」→「64兆」),单模型覆盖中英粤日韩
- 可选启用 API Key
- 可选接入 OpenAI 兼容 LLM 做纠错
- 支持
python -m、命令行和脚本三种启动方式
适合谁
如果你只是想把 VoiceTyper 跑起来,这个 README 已经够用。
如果你要改代码、打包发布或二次开发,文末有开发者入口。
Python 版本
- 最低支持:Python 3.10
- 推荐版本:Python 3.12+
快速开始
最常见的用法是:
- 安装服务端
- 启动服务端
- 让客户端连接
127.0.0.1:6008
安装与启动
推荐方式:使用脚本
适合 Linux 和 macOS 用户。
cd server
./scripts/voice_typer_server.sh setup
./scripts/voice_typer_server.sh run
脚本会:
- 创建虚拟环境
~/.venvs/voice-typer - 安装
voice-typer-server - 用一组默认参数启动服务
默认启动参数:
--host 127.0.0.1--port 6008--device cpu
命令行覆盖示例:
./scripts/voice_typer_server.sh run --host 0.0.0.0 --onnx-threads 2
直接使用 Python 包
如果你已经安装了 voice-typer-server,可以直接运行:
python -m voice_typer_server --host 127.0.0.1 --port 6008
或:
voice-typer-server --host 127.0.0.1 --port 6008
查看帮助:
voice-typer-server --help
Docker
如果你更喜欢容器方式:
docker build -t voice-typer-server:latest .
docker run -d -p 6008:6008 --name voice-typer voice-typer-server:latest
Windows 服务
在 Windows 上可将 VoiceTyper Server 注册为系统服务,实现开机自启和后台运行。
安装与注册
REM 1. 安装环境(自动安装 pywin32 依赖)
scripts\voice_typer_server.bat setup --local
REM 2. 注册为 Windows 服务(需管理员权限,默认开机自启、默认流式模式)
REM Windows 原生客户端支持流式,无需额外参数;若连接的是 Linux 等非流式客户端,请追加 --no-streaming
scripts\voice_typer_server.bat install -- --host 127.0.0.1 --port 6008 --device cpu
REM 启用 LLM 校对(推荐,可显著提升识别准确率)
scripts\voice_typer_server.bat install -- --host 127.0.0.1 --port 6008 --device cpu ^
--llm-base-url https://api.openai.com/v1 ^
--llm-api-key sk-xxx ^
--llm-model gpt-4o-mini
REM 手动启动模式(不随系统启动)
scripts\voice_typer_server.bat install --startup manual -- --host 127.0.0.1 --port 6008
管理服务
REM 启动服务
scripts\voice_typer_server.bat start
REM 停止服务
scripts\voice_typer_server.bat stop
REM 卸载服务
scripts\voice_typer_server.bat uninstall
也可以通过 services.msc(服务管理器)图形化操作,服务名为 VoiceTyper 语音识别服务。
服务日志
服务模式下日志写入文件:%USERPROFILE%\.voice-typer\server.log,最大 10MB,保留 3 个备份。
注意事项
- 安装、卸载、启停服务均需要管理员权限
- 服务默认以
LocalSystem账户运行。如果模型已缓存在当前用户目录下,首次启动可能需要重新下载 - 修改运行参数需先卸载再重新安装服务
常用启动参数
--host:监听地址,默认127.0.0.1--port:监听端口,默认6008--streaming/--no-streaming:识别模式,默认流式(WebSocket);--no-streaming切换为非流式(HTTP)--device:cpu/cuda/cuda:N--model:流式预览模型(默认paraformer-zh-streaming)或非流式识别模型(默认paraformer-zh)--offline-model:仅流式模式,松手后用于整段复识别的离线模型,默认paraformer-zh--chunk-size:流式 chunk 大小,格式left,current,right(单位 60ms 帧),默认0,10,5--punc-model:标点模型,默认ct-punc,设为none可禁用--onnx-threads:ONNX Runtime 线程数,默认4--api-keys:API Key 列表,逗号分隔--llm-base-url、--llm-api-key、--llm-model:启用 LLM 纠错
示例:
# 流式模式(默认)
voice-typer-server --host 0.0.0.0 --device cpu --api-keys akey
# 非流式兼容模式
voice-typer-server --no-streaming --host 0.0.0.0 --device cpu --api-keys akey
常见使用场景
仅本机使用
这是默认场景:
voice-typer-server --host 127.0.0.1 --port 6008
此时本机客户端可直接访问,一般不需要额外配置鉴权。
局域网远程使用
如果客户端和服务端不在同一台机器上,建议启用 API Key:
voice-typer-server --host 0.0.0.0 --api-keys your_key
然后在客户端配置中填入:
- 服务端 IP
- 对应端口
api_key
启用 LLM 纠错
voice-typer-server \
--llm-base-url https://api.openai.com/v1 \
--llm-api-key sk-xxx \
--llm-model gpt-4o-mini
客户端再启用 llm_recorrect 即可。
接口
/health(GET)
通用健康检查,返回 {"status":"ok","ready":bool,"streaming":bool,"llm_enabled":bool}。
流式模式(默认):/recognize/stream(WebSocket)
WebSocket 端点,客户端与服务端保持长连接,边发音频边获取识别片段。
协议概要:
- 连接后发送
{"type":"start","sample_rate":16000} - 录音期间持续发送 binary 帧(float32 PCM,每帧约 600ms = 9600 samples)
- 松开热键后发送
{"type":"finalize"} - 服务端返回若干
{"type":"partial","text":"...","seq":N}(逐字预览,来自流式模型)和最终{"type":"final","text":"...","asrElapsed":0.82}(准确结果,来自对完整音频的离线整段复识别)
两通道说明
| 消息类型 | 识别模型 | 用途 | 是否插入目标程序 |
|---|---|---|---|
partial |
sensevoice-small(对已累积音频整段重跑) |
HUD 实时预览,跟嘴显示 | 否 |
final |
sensevoice-small(同一个模型) |
准确最终结果,含标点和 LLM 纠错 | 是 |
默认只加载一个模型。SenseVoice 的 RTF 约 0.01,重跑 15s 音频约 165ms,远在 600ms 送帧周期内,因此预览直接复用它,不再需要独立的流式模型。
好处是预览会自我修正(
识别功能和并→识别功能合并)并自带标点,松手时也不会整段跳变。代价是partial必须是全量文本而非增量——见PROTOCOL.md§4.3。用
--offline-model paraformer-zh可回到双模型流式,此时--model与--chunk-size恢复生效。
非流式模式(--no-streaming):/recognize(HTTP POST)
提交整段音频,返回完整识别结果。
推荐方式:
Content-Type: application/octet-stream- 请求体直接放 16kHz
float32原始音频字节
可选参数:
- 查询参数
llm_recorrect=true|false
同时也兼容旧版 multipart/form-data 上传。
示例:
curl -X POST "http://127.0.0.1:6008/recognize?llm_recorrect=false" \
-H "Content-Type: application/octet-stream" \
--data-binary @test.float32
带 API Key:
curl -X POST http://127.0.0.1:6008/recognize \
-H "Authorization: Bearer your-api-key" \
-F "audio=@test.wav"
模型与运行说明
- 服务端使用
onnxruntime - 流式模式默认只加载一个模型:
sensevoice-small(--offline-model):预览期整段重跑产出partial,松手后产出final,自带标点与 ITN- 若
--offline-model指定为 paraformer,则回到双模型:--model(默认paraformer-zh-streaming)负责预览
- 非流式模式仅加载一个模型:
sensevoice-small(--model):整段识别,自带标点与 ITN
--punc-model(默认ct-punc)只对 paraformer 生效;用 SenseVoice 时会被忽略并记一条日志
短名会自动映射到 ONNX 模型仓库,首次使用会从 ModelScope 自动下载。
如果模型目录中只有 model_quant.onnx,服务端会自动使用量化模型。
可选的最终识别模型
| 短名 | 仓库 | 体积 | 说明 |
|---|---|---|---|
sensevoice-small(默认) |
iic/SenseVoiceSmall-onnx |
241MB | 官方 int8 导出。自带标点/ITN,无需 ct-punc |
sensevoice-small-fp32 |
manyeyes/sensevoice-small-onnx |
893MB | 社区 fp32 导出。实测质量与 int8 持平,速度慢约 1.6 倍 |
paraformer-zh |
damo/speech_paraformer-large...onnx |
227MB + ct-punc 1.0GB | 旧默认值。需要外挂 ct-punc 才有标点,且数字保持「六十四兆」这样的口语形式 |
切换模型:
voice-typer-server --offline-model paraformer-zh # 流式模式
voice-typer-server --no-streaming --model paraformer-zh # 非流式模式
模型对比基准
想自己验证选型(强烈建议用你自己的录音,TTS 语料太干净,测不出真实口音与噪声下的差距):
# 内置 TTS 语料(macOS)
python scripts/bench_asr.py
# 自己的录音:16k 单声道 wav,同名 .txt 存参考文本才会算 CER
python scripts/bench_asr.py --audio-dir ~/my_recordings
性能优化
NVIDIA GPU 加速
使用 CUDA 加速识别:
voice-typer-server --device cuda
# 多卡指定:
voice-typer-server --device cuda:1
内存优化
流式模式同时加载流式预览模型和离线识别模型,内存占用约比非流式多 220MB。如果内存紧张,可以:
- 切换到非流式模式(
--no-streaming),仅加载一个模型 - 关闭标点模型,可降低部分资源占用:
voice-typer-server --punc-model none
常见问题
服务启动了,但客户端连不上
- 检查服务端实际监听地址
- 检查客户端配置中的
host和port - 本机部署时,应优先使用
127.0.0.1:6008
远程调用返回 401
- 检查是否配置了
--api-keys - 检查客户端是否正确带上
Authorization: Bearer ...
首次启动较慢
首次运行可能会下载模型,这是正常现象。
Apple Silicon 为什么没有 MPS
当前服务端只支持:
cpucudacuda:N
在 Apple Silicon 上建议直接使用 cpu。
开发者说明
如果你要修改代码或发布包,请查看:
主要代码位置:
Release files for voice-typer-server 1.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| voice_typer_server-1.5.0.tar.gz | 35.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| voice_typer_server-1.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 70.7 kB
Release files / voice_typer_server-1.5.0.tar.gz
| Download URL | voice_typer_server-1.5.0.tar.gz |
|---|---|
| Size | 35.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1a07d33b7a16a268941e4a48ac934c53e1f3214b9460aecdc6c58d80c24f6a33
|
|
BLAKE2b-256 checksum How to use checksums |
b048dddbd813e86026b2adef0bd046dbe3d95ab118f68de21433239b461b101c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / voice_typer_server-1.5.0-py3-none-any.whl
| Download URL | voice_typer_server-1.5.0-py3-none-any.whl |
|---|---|
| Size | 35.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
193dea89bbfed0bc4ffa30669be4ea9d7a7d463bd292b3f83f56bbbc54942e5a
|
|
BLAKE2b-256 checksum How to use checksums |
7ef98d42f73a0315e2445997af962d54c246ad1496ed7282c7a0a01ac04e03c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|