Downloads · 30 days
31
9% of all-time downloads
qzxyz/qwen3asr_rk
qwen3asr_rk is a machine learning model from qzxyz. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
v1.3.0 — Merged Encoder, Token Rollback, 代码重构 (engine.py -56%)
Downloads · 30 days
31
9% of all-time downloads
All-time downloads
335
Public
Repo size
11.7 GB
Likes
10
Trending 1
Click a slice to open those files.
.rknn3.8 GB · 32%
From the Hugging Face model README
v1.3.0 — Merged Encoder, Token Rollback, 代码重构 (engine.py -56%)
基于 RKNN 编码器 (NPU) + RKLLM 解码器 (NPU) 的 Qwen3-ASR 语音识别运行库。
qwen3asr_rknn/
├── python/ # Python 运行库
│ ├── qwen3asr/ # 核心库 (v1.3.0)
│ │ ├── __init__.py # 包入口
│ │ ├── engine.py # 主引擎 (文件转录, 组件加载)
│ │ ├── stream.py # 流式识别会话 (StreamSession)
│ │ ├── encoder.py # RKNN 编码器 (merged/split 自动检测)
│ │ ├── decoder.py # RKLLM 解码器 (ctypes EMBED 模式)
│ │ ├── mel.py # Mel 频谱提取 (Whisper 兼容)
│ │ ├── vad.py # Silero VAD 封装
│ │ ├── config.py # 配置常量和默认参数
│ │ └── utils.py # 音频加载、ITN、文本处理
│ ├── transcribe.py # 文件转录 CLI
│ └── mic_stream.py # 麦克风实时识别 CLI
├── scripts/ # 辅助脚本
│ ├── test_vad_stream.py # VAD 流式识别测试
│ ├── bench_encoder.py # 编码器性能测试
│ └── onnx2rknn_*.py # 模型转换脚本
├── models/ # 模型文件 (部署时需要)
│ ├── encoder/rk3576/ # Split 编码器 (FE+BE, 旧方案)
│ ├── qwen3_asr_encoder_merged.fp16.{N}s.rk3576.rknn
│ │ # ▲ Merged 编码器 (推荐, 快 1.4-1.8x)
│ ├── rkllm/ # RKLLM 解码器
│ ├── embd/ # Embedding 表
│ ├── vad/ # Silero VAD 模型
│ ├── mel_filters.npy # Mel 滤波器
│ └── tokenizer/ # Tokenizer
├── lib/ # RKLLM 运行库 (librkllmrt.so)
├── audio/ # 测试音频
├── _transfer/ # 模型转换/测试工具
└── docs/ # 本文档
# 复制整个 qwen3asr_rknn/ 目录到目标机器
scp -r qwen3asr_rknn/ user@target:/path/to/
# 确保依赖已安装
pip install numpy librosa soundfile tokenizers
# 可选: pip install pydub (支持更多音频格式)
cd /path/to/qwen3asr_rknn/python
# 基本用法
python transcribe.py --audio /path/to/audio.wav
# 指定语言和上下文
python transcribe.py --audio audio.wav --language Chinese --context "新闻节目"
# 英文识别
python transcribe.py --audio english.wav --language English
# 自动检测语言
python transcribe.py --audio audio.wav --language auto
# 更多参数
python transcribe.py --audio audio.wav \
--chunk-size 20 \
--memory-num 3 \
--cpus 4 \
--max-new-tokens 300 \
--start 10 --duration 60
# 查看可用设备
python mic_stream.py --list-devices
# 开始实时识别 (默认 USB 麦克风)
python mic_stream.py
# 自定义参数
python mic_stream.py --device plughw:2,0 --chunk-size 10 --language Chinese
# 限制时长
python mic_stream.py --max-seconds 60
from qwen3asr import Qwen3ASREngine
# 初始化引擎
engine = Qwen3ASREngine(
model_dir="/path/to/models",
platform="rk3576",
encoder_sizes=[2, 3, 4], # 只加载需要的尺寸 (加快启动)
enabled_cpus=2, # 2 = A72 大核
repeat_penalty=1.15, # W4A16 推荐 >1.0
compact_suffix=True, # 精简提示词, 省 ~120ms/chunk
)
# --- 文件转录 ---
result = engine.transcribe(
audio="audio.wav",
language="Chinese",
chunk_size=4.0, # 4s chunk, 配合 merged encoder 最佳
memory_num=2,
rollback_tokens=2, # Token 回退防止边界错误
)
print(result["text"])
print(f"RTF: {result['stats']['rtf']:.3f}")
# --- 流式识别 ---
stream = engine.create_stream(
language="Chinese",
chunk_size=4.0,
memory_num=2,
rollback_tokens=2,
)
# 喂入音频数据 (16kHz mono float32)
import numpy as np
pcm = np.zeros(16000 * 4, dtype=np.float32) # 4秒
result = stream.feed_audio(pcm)
print(result["text"]) # 中间结果
final = stream.finish()
print(final["text"])
# --- 带 VAD 的流式识别 ---
from qwen3asr import SileroVAD
vad = SileroVAD("/path/to/models/vad/silero_vad.onnx")
stream = engine.create_stream(language="Chinese", vad=vad)
# VAD 自动过滤静音, 仅在检测到语音时触发 ASR
engine.close()
Qwen3ASREngine.__init__)| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
model_dir | str | 必填 | 模型根目录 |
platform | str | "rk3576" | 平台:rk3576 或 rk3588 |
encoder_sizes | list | None | 加载的编码器尺寸列表,如 [2,3,4];None=全部加载 |
encoder_quant | str | "fp16" | 编码器量化:fp16 或 int8 (int8 质量差,不推荐) |
decoder_quant | str | "w4a16_g128" | 解码器量化类型 |
enabled_cpus | int | 2 | RKLLM CPU 核心数 (2=A72 大核) |
max_context_len | int | 4096 | KV 缓存最大上下文长度 |
max_new_tokens | int | 500 | 每次生成最大 token 数 |
top_k | int | 1 | Top-K 采样 (1=贪心, 推荐用于 ASR) |
top_p | float | 1.0 | 核采样阈值 |
temperature | float | 1.0 | 采样温度 |
repeat_penalty | float | 1.15 | 重复惩罚 (W4A16 推荐 >1.0) |
frequency_penalty | float | 0.0 | 频率惩罚 |
presence_penalty | float | 0.0 | 存在惩罚 |
embed_flash | int | 1 | Flash Embedding 模式 |
compact_suffix | bool | True | 精简后缀提示词,节省 ~120ms/chunk |
decoder_callback | Callable | None | 流式回调 callback(text, is_finish) |
transcribe() — 文件/数组一次性转录| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
audio | str/ndarray | 必填 | 音频文件路径或 16kHz float32 数组 |
language | str | "Chinese" | 语言:Chinese/English/auto 等 |
context | str | "" | 上下文描述 (提升准确率) |
chunk_size | float | 30.0 | 音频块大小 (秒, 自动裁剪到编码器容量) |
memory_num | int | 2 | 滑动窗口块数 (保留最近 N 块 embedding) |
rollback_tokens | int | 5 | 前缀回退 token 数 (减少边界抖动) |
max_new_tokens | int | 500 | 每块最大生成 token 数 |
start_second | float | 0.0 | 起始偏移 (秒) |
duration | float | None | 持续时间 (秒, None=全部) |
max_chunks | int | None | 最大处理块数 |
apply_itn_flag | bool | True | 是否应用逆文本归一化 |
create_stream() — 创建流式会话| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
language | str | "Chinese" | 语言提示 |
context | str | "" | 上下文描述 |
chunk_size | float | 4.0 | 每块秒数 (流式推荐 2-5s) |
memory_num | int | 2 | 滑动窗口大小 (≥2) |
unfixed_chunks | int | 0 | 前 N 块不使用前缀文本 |
rollback_tokens | int | 2 | 前缀回退 token 数 |
max_new_tokens | int | 128 | 每块最大 token 数 |
on_text | Callable | None | 文本回调 on_text(full_text) |
vad | SileroVAD | None | VAD 实例,自动过滤静音 |
注意:
transcribe()和create_stream()的默认参数不同。transcribe()使用大 chunk (30s) 和较多回退 (rb=5) 适合离线;create_stream()使用小 chunk (4s) 和少量回退 (rb=2) 适合实时。
Chinese, English, Cantonese, Arabic, German, French, Spanish, Portuguese, Indonesian, Italian, Korean, Russian, Thai, Vietnamese, Japanese, Turkish, Hindi, Malay, Dutch, Swedish, Danish, Finnish, Polish, Czech, Filipino, Persian, Greek, Romanian, Hungarian, Macedonian
支持两种部署模式,自动检测:
将 Frontend + Backend 合并为单个 RKNN 模型,减少一次 NPU 调用开销。
qwen3_asr_encoder_merged.fp16.{N}s.rk3576.rknn (369-371MB)input_features(1, 128, T_mel) + attention_mask(1, 1, T_down, T_down)audio_embeds(1, T_down, 1024) 浮点 embeddingFrontend 和 Backend 分开推理:
encoder_fe.fp16.{N}s.rk3576.rknn (~22MB)encoder_be.fp16.{N}s.rk3576.rknn (~350MB)ceil(T_mel / 8) + 1 (3层CNN子采样), 每秒 ~13 tokensrkllm_set_chat_template(handle, "", "", "") - 禁用内置模板role = "" - 空角色embed_flash = 1 - Flash Embeddingcompact_suffix = True - 精简后缀,省约 10 tokens / 120ms标准模式:
<|im_start|>system
You are a helpful assistant. {context}<|im_end|>
<|im_start|>user
<|audio_start|>{AUDIO_EMBEDDING}<|audio_end|>
数字用0123456789,语音转录:<|im_end|>
<|im_start|>assistant
language {Language}<asr_text>{prefix_text}
精简模式 (compact_suffix=True):
<|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
<|audio_start|>{AUDIO_EMBEDDING}<|audio_end|><|im_end|>
<|im_start|>assistant
<asr_text>{prefix_text}
chunk_size 秒分块memory_num 块的 embedding (滑动窗口)_decode_with_window() 统一核心)rollback_tokens 个 token (减少边界错误)_feed_with_vad()), 仅在检测到语音时触发 ASR解决分块边界处的文本错误 (如 "九百六。十七期" → "九百六十七期"):
rollback_tokens=0: 无回退rollback_tokens=2-3: 推荐, 平衡准确率与重复推理开销rollback_tokens=5: transcribe() 默认, 适合离线批量工作原理: 提交前缀文本时截掉最后 N 个 token, 让 LLM 在下一块重新生成这部分, 从而消除边界伪影。
锁定 CPU/NPU/DDR 频率可显著提升性能稳定性 (~27% 提升):
# 锁定 CPU 大核 (需 root)
echo userspace > /sys/devices/system/cpu/cpufreq/policy4/scaling_governor
echo 2208000 > /sys/devices/system/cpu/cpufreq/policy4/scaling_setspeed
echo 2208000 > /sys/devices/system/cpu/cpufreq/policy6/scaling_setspeed
# 锁定 NPU
echo userspace > /sys/class/devfreq/fdab0000.npu/governor
echo 1000000000 > /sys/class/devfreq/fdab0000.npu/userspace/set_freq
# 锁定 DDR
echo userspace > /sys/class/devfreq/dmc/governor
echo 2736000000 > /sys/class/devfreq/dmc/userspace/set_freq
# 查看 NPU 负载
cat /sys/kernel/debug/rknpu/load
| Chunk | 编码 (ms) | vs Split 加速 | RTF (60s 音频) | 适用场景 |
|---|---|---|---|---|
| 2s | ~302 | 1.79x | ~0.55 | 低延迟实时 |
| 3s | ~364 | 1.55x | ~0.56 | 折中 |
| 4s | ~499 | 1.38x | ~0.57 | 流式推荐 |
| 5s | ~643 | 1.20x | ~0.58 | 质量优先 |
| Chunk | FE (ms) | BE (ms) | 总编码 (ms) | RTF |
|---|---|---|---|---|
| 2s | ~60 | ~480 | ~540 | ~0.70 |
| 3s | ~60 | ~505 | ~565 | ~0.68 |
| 4s | ~60 | ~630 | ~690 | ~0.66 |
| 5s | ~60 | ~710 | ~770 | ~0.65 |
| 指标 | 锁频前 | 锁频后 | 提升 |
|---|---|---|---|
| 首 chunk 延迟 | ~2.4s | ~1.8s | ~25% |
| 后续 chunk 延迟 | ~1.8s | ~1.4s | ~22% |
| RTF (60s 音频) | 0.78 | 0.57 | 27% |
encoder_merged.fp16.*.rknn) 或 split (encoder_fe/be)decoder_qwen3.w4a16_g128.{platform}.rkllmmel_filters.npz, embed_tokens.npy, tokenizer.jsonlibrkllmrt.so 在 lib/ 目录numpy, librosa, soundfile, tokenizersrknnlite)arecord -l (实时场景)decoder_qwen3.*.rkllm (model_type=qwen3, 非 qwen3_vl)rkllm_set_chat_template(h, "", "", "")role = "" (空字符串)merged 关键字encoder_sizes=[4] 只加载单个尺寸可节省内存max_context_len 可降低 KV 缓存内存rollback_tokens ≥ 1unfixed_chunks > 0 会延迟前缀使用repeat_penalty (推荐 1.15-1.3)memory_num ≥ 2rollback_tokens (2-3)