跳到正文

配置参考 ​

配置文件与路径解析 ​

config.toml 按域分组:server / upstream / concurrency / socket / logging / recording / vad。各组字段如下(键名不带组前缀),未出现的键使用下表默认值, 出现未知键会直接报错(deny_unknown_fields),避免拼错字段名却静默失效。

配置文件按以下顺序解析,命中即止:

  1. 第一个位置参数:stream-vad-proxy ./my-config.toml
  2. 环境变量 STREAM_VAD_PROXY_CONFIG_PATH
  3. 进程当前工作目录下的 ./config.toml

logging.dir 与 recording.dir 的相对路径按配置文件所在目录解析,所以从安装目录 (dist/<platform>/)运行时日志与录音都落在安装目录里。根 bun run dev:vad 正是以交付目录 为 CWD 启动的。

启动时会做一次配置自检 + 模型预检,任一项不通过就直接退出:

  • 端口非 0;
  • wsPath / healthPath 以 / 开头且互不相同;
  • maxSessions > 0;
  • vad.windowSize == 512、vad.threshold ∈ [0, 1];
  • upstream.defaultProfile 在 upstream.profiles 中必须存在;
  • 激活的 Profile 参数防御性校验(如 iflytek-iat 校验 url 为 http://、appid 非空、svc 非空、采样率组合受支持、攒批与超时参数合法等);
  • 模型可加载且能跑通一窗推理。

凭据与部署地址走环境变量,优先于配置文件:IFLYTEK_IAT_URL 覆盖激活 Profile 的 url、 IFLYTEK_IAT_APPID 覆盖激活 Profile 的 appid。仓库内的 config.toml 这两项一律留空。

server — 监听 ​

字段类型默认值说明
hoststring"0.0.0.0"实际监听地址
portuint1610093实际监听端口
healthPathstring"/health"HTTP 健康检查路径
wsPathstring"/audio"WebSocket 升级路径
wsSubprotocolstring"audio.drachtio.org"要求客户端声明的子协议;为空则不强制

upstream — 上游 ASR Profile 配置 ​

采用 Profile 模式组织上游,由 defaultProfile 指定当前激活的 Profile 名称:

toml
[upstream]
defaultProfile = "iflytek"

[upstream.profiles.iflytek]
provider = "iflytek-iat"
url = ""
appid = ""
svc = "iat"
type = "1"
busid = "stream-vad-proxy"
authNeed = false
sampleRate = 8000
chunkBytes = 800
maxChunkBytes = 8000
requestTimeoutMs = 10000
connectTimeoutMs = 3000
grsPollIntervalMs = 20
grsMaxPolls = 100
drainIdleMs = 1500
drainTimeoutMs = 8000
字段类型默认值说明
defaultProfilestring"iflytek"默认激活的 Profile 名称
profilesmap{ "iflytek": ... }Profile 映射表,键为 Profile 名称,值为具体厂商配置

Profile: iflytek-iat(科大讯飞私有云实时识别) ​

当 Profile 的 provider 为 "iflytek-iat"(或别名 "iflytek")时生效。协议细节与命令时序见上游适配器。

字段类型默认值说明
providerenum"iflytek-iat"上游提供方类型
urlstring""形如 http://host:port/iat/。只支持 http://,适配器不实现 TLS
appidstring""厂商分配的应用 ID
svcstring"iat"厂商服务名,实时识别取 iat
typestring"1"语种:1 普通话 / 2 维语 / 3 英语 / 4 粤语。厂商要求字符串形态
busidstring"stream-vad-proxy"业务 ID,仅用于厂商侧日志追踪
authNeedboolfalse透传给厂商的 auth_need
sampleRatei328000厂商侧采样率。与 vad.sampleRate(16000)不一致时由适配器做抗混叠降采样
chunkBytesusize800单次 auw 的目标字节数(8kHz 下 800 字节 ≈ 50ms)。按降采样后计
maxChunkBytesusize8000攒批上限。命令是串行 HTTP 往返,逐 20ms 帧一发追不上实时流
requestTimeoutMsuint6410000单次 HTTP 往返超时
connectTimeoutMsuint643000建链探测超时
grsPollIntervalMsuint6420段末取结果的轮询间隔
grsMaxPollsuint32100轮询次数上限;超限按当前累计文本收尾并记 warn,不算致命错误
drainIdleMsuint641500客户端 flush 后等待收尾帧的帧间空闲上限
drainTimeoutMsuint648000同一次排空的硬上限

url 与 appid 是凭据性质的部署参数,仓库内的 config.toml 一律留空,运行时用环境变量注入:

powershell
$env:IFLYTEK_IAT_URL = "http://<host>:<port>/iat/"
$env:IFLYTEK_IAT_APPID = "<appid>"

concurrency — 并发 ​

字段类型默认值说明
maxSessionsusize256并发会话上限;超过后新连接返回 503
workerThreadsusize0tokio 工作线程数;0 表示按 CPU 核心数自动

socket — 套接字 ​

字段类型默认值说明
tcpNoDelaybooltrue对下游连接与上游连接同时启用 TCP_NODELAY
maxFrameBytesusize4194304单个 WebSocket 帧最大字节数;超过即 1002 协议错误

logging — 日志 ​

字段类型默认值说明
dirstring"logs"日志目录,按天滚动;相对路径按配置文件所在目录解析
levelstring"info"本 crate 的日志级别(实际过滤器是 stream_vad_proxy=<level>,warn);设了 RUST_LOG 则以环境变量为准
debugTextFramesboolfalse打印转发的客户端文本帧与上游回传文本帧;客户端首帧 metadata 始终记录,不受此开关影响
debugAudioFramesboolfalse每个二进制帧落一条日志(字节数)
debugVadStateboolfalseVAD 边沿落日志:开嗓、段完成、pre-roll 回补,调阈值时打开

recording — 录音 ​

字段类型默认值说明
enabledboolfalse启用上行音频录制
dirstring"recordings"录制目录;相对路径按配置文件所在目录解析

录的是客户端推来的原始流,也就是本地 VAD 实际看到的那份音频,可以直接拿它回放复现某次误判。

vad — 语音活动检测 ​

字段类型默认值说明
modelstring"silero-vad/silero_vad.onnx"Silero VAD 模型文件名或路径
bufferSizeSecondsfloat30.0VAD 内部环形缓冲秒数
thresholdfloat0.35语音判定阈值,取值 [0, 1];调高更抗噪、更容易漏掉轻声
minSilenceDurationfloat0.35判定语音段结束所需的尾部静音秒数
minSpeechDurationfloat0.15有效语音段的最短秒数,低于此值不算一段
windowSizeint32512单窗采样点数,必须是 512
maxSpeechDurationfloat20.0单段语音最长秒数,超过强制切段
sampleRateint3216000采样率,全链路固定 16kHz 单声道 PCM16
numThreadsint321ONNX 推理线程数
providerstring"cpu"ONNX 执行后端
debugboolfalsesherpa-onnx 自身的调试输出
preRollMsuint32500开嗓前预缓冲毫秒数,上升沿时一次性冲给上游,避免吃掉首字

vad.pool — Silero VAD 实例池 ​

字段类型默认值说明
enabledbooltrue是否启用 VAD 实例池化复用(基于无锁环形队列 crossbeam_queue::ArrayQueue)
prewarmSessionsusize16服务启动在监听网络端口前并发预热加载并热身的实例数
maxIdleSessionsusize64实例池允许缓存的最大空闲实例数上限,超额归还实例自然析构

校验规则:prewarmSessions <= maxIdleSessions <= concurrency.maxSessions。

两点必须知道:

  • 默认值对齐的是 onnx-platform/sherpa-asr-server/config.toml 的实际运行值 (0.35 / 0.35 / 0.15),不是编译期默认(0.5 / 0.5 / 0.25)。
  • windowSize 不是可调旋钮。仓库内的 silero_vad.onnx 是 silero v4,输入签名 x:[1,512],窗口大小写死在计算图里,填别的值启动时就会被拦下。音频按 512 采样点整窗喂入, 余数跨帧保留。

模型路径解析 ​

vad.model 按以下顺序解析,命中即止:

  1. 绝对路径直接使用
  2. <配置文件所在目录>/<model>
  3. <配置文件所在目录>/../models/<model>
  4. 从配置目录向上最多 4 级,查找 onnx-platform/models/<model> 与 models/<model>

构建脚本已把 onnx-platform/models/silero-vad/silero_vad.onnx 拷进交付目录,所以从交付目录运行时走第 2 条 即命中;在仓库内直接 cargo run 则走第 4 条回落到 onnx-platform/models/。

与其它配置的关系 ​

  • 接入侧只改 apps/callflow-esl/config.toml 的 audioFork.wsUrl 指向本代理, bugName / mixType / sampleRate 全部不动。
  • 要吃到开嗓提速,业务侧需把 bargeInTrigger 设为 "speech-start";默认的 partial 策略 只认有文本的帧,空文本 VAD 帧不会触发打断,抗环境底噪误触最稳妥。
  • 部署到 WSL docker 计算集群时使用 deploy/wsl-docker/configs/stream-vad-proxy.toml, 端口与上游地址按集群约定另有一套值,见 deploy/wsl-docker/README.md。

文档与代码在同一仓库维护,现有 Markdown 是唯一内容源。