使用node调用FireRedASR2 模型

6 阅读5分钟

FireRedASR2 Node.js 服务

本文档面向希望理解、运行或二次开发本仓库的读者,说明项目目标、架构、数据流与关键配置。


1. 项目是什么

这是一个在 Node.js 上运行的 FireRedASR2-AED 语音识别服务:

  • 离线/整段:通过 HTTP 上传 WAV,返回整段转写文本。
  • 流式:通过 WebSocket 持续接收 PCM(16 kHz、单声道、16 bit 小端),按滑动窗口做中间结果(partial)与句末结果(final)。

数据管线(概念上)

音频 (WAV/PCM)FBank 特征(Kaldi 风格 povey 窗 + am.mvn 做 CMVN)→ Encoder ONNXDecoder ONNX(AED、16 层、带 cross-attention 与 KV-cache 自回归)→ 词表 tokens.txt 拼成可读文本。


2. 技术栈与依赖

依赖作用
onnxruntime-nodeCPU 上加载并运行 encoder.int8.onnx / decoder.int8.onnx
expressHTTP 路由、静态资源(public/index.html 演示页)
multerPOST /transcribe 上传音频文件到临时目录
wsWebSocket 服务器,路径 /ws

环境:Node.js ≥ 16(见 package.jsonengines)。


3. 仓库中主要文件

路径职责
index.js服务入口:模型加载、WAV 解析、ASR 管线、HTTP/WS 协议、StreamSession 流式逻辑
fbank.js纯 JS 的 FBank + am.mvn CMVN,对齐训练侧配置(见文件头注释)
public/index.html浏览器端流式 Demo:麦克风 → PCM → WebSocket
uploads/multer 临时目录(可自动创建)
模型目录(默认名见 index.jsMODEL_DIR需包含 encoder.int8.onnxdecoder.int8.onnxtokens.txtam.mvn

4. 核心模块说明

4.1 WAV 读取(readWav

  • HTTP 整段识别使用。
  • 要求 RIFF/WAVEPCM format=116-bit;多声道会混成单声道。
  • 若采样率不是 16 kHz,会做简单线性插值重采样到 16 kHz。

4.2 特征:fbank.js

  • 输出为 对数 FBank(行主序 [numFrames * numMels]),与训练侧 conf.yaml 等对齐(Povey 窗、80 mel、25 ms 帧长 / 10 ms 步长、FFT 上取 2 的幂等)。
  • loadAmMvn / applyCmvn:从 am.mvn 读入 shift/scale,原地
    feat = (feat - shift) * scale(详见 fbank.js 内注释)。

4.3 ASRPipeline

  1. load()
    加载 tokens.txtam.mvnencoder.int8.onnxdecoder.int8.onnx(图优化在 encoder 上开启)。

  2. transcribePcm(samples)
    输入为 Float32Array,表示 -1~1 归一化 的 16 kHz 单声道 PCM。
    流程:computeFbankapplyCmvnencoder.run_decodeAEDtokensToText

  3. _decodeAED

    • 从 encoder 输出取各层的 cross_k_* / cross_v_*mask
    • Decoder 逐步自回归:每步 feed 上一步 token、step、各层 空的 self KV 后由 decoder 更新为 new_self_k_cache_* / new_self_v_cache_*(自注意力侧 KV-cache)。
    • 每步对 logits 取 argmax;若得到 EOS 则结束。
    • 常数如 N_LAYERS=16D_MODEL=1280SOS_ID/EOS_IDindex.js 顶部定义。
  4. 特殊词元与 BPE
    SPECIAL_TOKEN_MAX 以下词元在 tokensToText 中忽略;WORD_BOUNDARY(SentencePiece 的 )用于在字/子词间插空格

4.4 全局推理调度:Semaphore + ASR_CONCURRENCY

  • ONNX Runtime 在 CPU 上多任务并发容易争抢线程。
  • 通过 信号量 把对 asr.* 的调用限制为 最多 ASR_CONCURRENCY 个并发(默认 1,即串行),兼顾多 WebSocket 连接的公平与 CPU 稳定性。

5. HTTP 接口

方法/路径说明
GET /health服务状态(加载中/就绪/错误)、token 数、WebSocket 连接数等
GET /info模型与流式相关公开参数(采样率、窗口、解码间隔、并发等)
POST /transcribemultipart 上传文件,字段名 audio(见启动日志说明);成功返回 textduration_secelapsed_mstiming_ms
静态文件public/ 与项目根均可能被静态挂载;前端 Demo 一般访问 http://localhost:PORT/

上传限制示例:multerfileSize 在代码中配置(如 100 MB)。

端口:默认 3000index.jsPORT)。


6. WebSocket 流式协议(/ws

6.1 客户端 → 服务端

  • 二进制帧原始 PCM,16 bit little-endian,单声道,16000 HzInt16 序列的字节流)。
  • JSON 文本帧(节选):
type含义
start清空缓冲,开始新一句(utterance),并回复 started
end对当前缓冲做 finalreason: client_end
resetend 相同流程,对当前缓冲做 finalreason: client_reset);runFinal 结束后会内部 reset 清空缓冲。源码注释中的「等价 end+start」指收尾并准备接下一段输入,并非再发一条 start 消息
config可带 sample_rate,仅校验为 16000

6.2 服务端 → 客户端

type含义
ready握手成功,可带 sample_ratewindow_sec
partial滑动窗口上的中间识别结果
final一句定稿(可带 reason
error错误信息
busy模型未就绪,连接会被关闭
started响应 start

6.3 StreamSession 流式策略(调参前必读)

  • 缓冲:用 Float32Array 累加整段;超过 STREAM_WINDOW_SEC(如 12 s) 只保留尾部窗口,避免无限增长。
  • 首次解码:缓冲时长 ≥ STREAM_MIN_AUDIO_SEC 才可能触发第一次 partial。
  • 节流:两次解码间隔 ≥ STREAM_MIN_DECODE_INTERVAL_MS,减轻 CPU 压力。
  • 静音/能量:用末尾约 120 ms 的 RMS 估计连续静音;整段 bufferRms 低于 STREAM_MIN_BUFFER_RMS跳过推理,减少无意义输出。
  • 收尾 final 触发条件(在代码中 shouldFinalize):
    • 末尾静音持续 ≥ STREAM_SILENCE_TAIL_SEC;或
    • utteranceStartedAt 起算时长 ≥ STREAM_MAX_UTTERANCE_SEC

以上常量均在 index.js 顶部,修改后需自行回归测试流式体验与延迟。


7. 运行步骤(概要)

  1. 安装依赖:npm install
  2. FireRedASR2 ONNX 模型目录 放到本仓库默认路径,或改 index.jsMODEL_DIR / 使用上级目录的 fallback 路径(见 resolveModelDir
  3. 启动:npm startnpm run dev--watch 下文件变更会重启 Node)
  4. 浏览器打开首页测试流式;或用 POST /transcribe 测整段

若模型缺失,进程会在 main() 中打印检查项并 process.exit(1)


8. 学习路径建议

  1. 先读 index.js 顶部注释与配置常量,建立「整段 vs 流式」的边界。
  2. 跟踪 transcribePcmencoder_decodeAEDtokensToText 这一条完整链路。
  3. 对照 fbank.js 文件头理解特征是否与论文/工程侧「Kaldi 风格」一致。
  4. 阅读 StreamSessionws.on('message'),理解 partial/final 的触发条件。
  5. 打开 public/index.html 看前端如何 getUserMedia → AudioContext → 重采样/整形 → WebSocket`

9. 扩展与注意点

  • GPU:当前 InferenceSession 使用 cpu;若需 CUDA 等,需改 executionProviders 并保证本机 ORT 与驱动支持。
  • 并发与延迟ASR_CONCURRENCY、流式窗口与间隔会直接影响延迟、吞吐与公平性;生产环境应结合压测与业务 SLA 调参。
  • 长音频整段:HTTP 路径用完整 WAV 解码,不受「滑动窗口」截断,与 WS 流式行为不同。

想要拿源码的联系作者 wx:18404966472 或者私信