1. 引言
英伟达在5月1日发布了一款开源语音识别模型:Parakeet TDT 0.6B V2,其以 600M 参数登顶 Hugging Face Open ASR 榜单。官方链接:nvidia/parakeet-tdt-0.6b-v2
- 极致转录效率:60 分钟音频仅需 1 秒内完成转录(A100 推理)
- OpenASR 榜首表现:超越 Whisper、Conformer、Wav2Vec 等主流闭源模型
- 极小参数量:仅 0.6B(轻量级,适合边缘设备)
- 高精度:平均 WER 6.05%(Hugging Face Open ASR 榜单),优于 Whisper-large-v3
- 高鲁棒性:多语速、多口音、多录音环境下表现稳定(英文)
2. 环境准备
部署环境基于NVIDIA nemo框架,现在开始,
首先,确保电脑环境安装好了Anaconda
conda create --name nemo_py310 python=3.10
conda activate nemo_py310
conda install -c conda-forge cmake
pip install sentencepiece
pip install -U nemo_toolkit["asr"]
为了充分发挥 TDT 模型在某些解码环节的性能(如 CUDA graphs with while loops),NeMo 会提示安装 cuda-python
。如果需要,可以运行(此步骤可选,不安装也能运行,但可能会有性能提示),若想要部署cuda环境,详细见:
pip install cuda-python>=12.3 # 请根据您环境的CUDA主版本选择合适的cuda-python版本
3. 编写推理脚本
我们将编写一个 Python 脚本来加载模型、处理音频、执行转录,并计算一些性能指标。
新建Python 代码保存为文件,例如 run_parakeet_transcribe.py。
脚本概览
脚本主要包含以下部分:
- 配置模型名称和音频路径。
- 加载 Parakeet-TDT-0.6B-V2 模型。
- 读取音频文件并获取时长。
- 执行语音转文字的推理。
- 提取转录文本,计算每分钟字数 (WPM) 和近似实时因子 (RTFx)。
- 将转录结果保存到
.txt
文件。 - (可选)集成 NVTX 标记,便于使用 NVIDIA Nsight Systems 进行性能剖析。
代码详解
run_parakeet_transcribe.py:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import nemo.collections.asr as nemo_asr
import torch
import time
import wave # 用于获取 .wav 文件时长
import os
# --- 配置参数 ---
# 重要:如果您已手动下载模型,请修改此处为您的 .nemo 文件绝对路径
# MODEL_NAME = "nvidia/parakeet-tdt-0.6b-v2" # 在线下载模式
MODEL_NAME = "/home/garyhuang/ASR/parakeet-tdt-0.6b-v2.nemo" # 离线加载模式,替换为您的实际路径
AUDIO_FILE_PATH = "/home/garyhuang/ASR/2086-149220-0033.wav" # 替换为您的音频文件路径
TARGET_WPM = 400 # 目标每分钟字数
# --- NVTX 辅助类 (可选,用于性能分析) ---
class NvtxTracer:
def __init__(self, name: str):
self.name = name
def __enter__(self):
if torch.cuda.is_available():
torch.cuda.nvtx.range_push(self.name)
def __exit__(self, type, value, traceback):
if torch.cuda.is_available():
torch.cuda.nvtx.range_pop()
# --- 音频处理函数 ---
def get_audio_duration_wav(filepath: str) -> float:
try:
with wave.open(filepath, 'r') as wf:
frames = wf.getnframes()
rate = wf.getframerate()
duration = frames / float(rate)
return duration
except wave.Error as e:
print(f"错误:无法读取WAV文件 {filepath}: {e}")
return 0.0
except FileNotFoundError:
print(f"错误:音频文件未找到于 {filepath}")
return 0.0
# --- 主程序 ---
def main():
print("--- ASR 性能测试脚本 (Parakeet TDT 0.6B V2) ---")
if not os.path.exists(AUDIO_FILE_PATH):
print(f"错误:音频文件未找到于 {AUDIO_FILE_PATH}")
return
# 检查模型文件路径是否有效(尤其对于离线加载)
# 如果MODEL_NAME是HuggingFace ID,则此检查不适用,由NeMo内部处理下载
if "/" in MODEL_NAME and not os.path.exists(MODEL_NAME): # 简单判断是否为路径
print(f"错误:本地模型文件未找到于 {MODEL_NAME}")
return
print(f"\n正在加载模型: {MODEL_NAME}...")
asr_model = None
load_time_start = time.perf_counter()
with NvtxTracer("ModelLoading"):
try:
# 如果 MODEL_NAME 是 HuggingFace ID (如 "nvidia/parakeet-tdt-0.6b-v2")
# 且希望强制在线下载,或者首次使用,可以用 from_pretrained:
# asr_model = nemo_asr.models.ASRModel.from_pretrained(model_name=MODEL_NAME)
# 如果 MODEL_NAME 是本地 .nemo 文件路径,推荐使用 restore_from:
if "/" in MODEL_NAME: # 再次判断是否为路径
asr_model = nemo_asr.models.ASRModel.restore_from(restore_path=MODEL_NAME)
else: # 否则认为是HuggingFace ID
asr_model = nemo_asr.models.ASRModel.from_pretrained(model_name=MODEL_NAME)
except Exception as e:
print(f"加载模型时发生错误: {e}")
print("请检查模型名称/路径,网络连接(如果在线下载),或文件是否损坏。")
return
load_time_end = time.perf_counter()
model_load_duration = load_time_end - load_time_start
print(f"模型加载完成,耗时: {model_load_duration:.2f} 秒")
if torch.cuda.is_available():
print("CUDA 可用,将模型移至 GPU。")
asr_model = asr_model.cuda()
else:
print("警告:CUDA 不可用。模型将在 CPU 上运行,性能会显著降低。")
print(f"\n准备转录音频文件: {AUDIO_FILE_PATH}")
audio_duration_seconds = get_audio_duration_wav(AUDIO_FILE_PATH)
if audio_duration_seconds == 0: return
audio_duration_minutes = audio_duration_seconds / 60.0
print(f"音频时长: {audio_duration_seconds:.2f} 秒 ({audio_duration_minutes:.2f} 分钟)")
transcribed_text = ""
word_count = 0
inference_duration = 0
try:
with NvtxTracer("PreProcessing"):
paths2audio_files = [AUDIO_FILE_PATH]
print("预处理阶段完成 (主要由模型内部处理)。")
print("\n开始推理...")
inference_time_start = time.perf_counter()
with NvtxTracer("Inference"):
# 将路径列表作为第一个位置参数传入
hypotheses = asr_model.transcribe(paths2audio_files, batch_size=1)
inference_time_end = time.perf_counter()
inference_duration = inference_time_end - inference_time_start
print(f"推理完成,耗时: {inference_duration:.2f} 秒")
with NvtxTracer("PostProcessing"):
print("\n开始后处理...")
if hypotheses and len(hypotheses) > 0:
# Parakeet TDT 模型卡片示例的输出结构
if hasattr(hypotheses[0], 'text'):
transcribed_text = hypotheses[0].text
# 其他可能的输出格式处理
elif isinstance(hypotheses[0], str):
transcribed_text = hypotheses[0]
elif isinstance(hypotheses[0], list) and len(hypotheses[0]) > 0 and isinstance(hypotheses[0][0], str) :
transcribed_text = hypotheses[0][0]
else:
print(f"警告:未知的转录输出格式: {type(hypotheses[0])}。")
transcribed_text = str(hypotheses[0])
word_count = len(transcribed_text.split())
print("后处理完成。")
else:
transcribed_text = "错误:转录未返回任何结果。"
word_count = 0
except Exception as e:
print(f"\n处理过程中发生未知错误: {e}")
return
if transcribed_text and word_count > 0 :
output_txt_filename = os.path.splitext(AUDIO_FILE_PATH)[0] + ".txt"
try:
with open(output_txt_filename, 'w', encoding='utf-8') as f:
f.write(transcribed_text)
print(f"\n转录结果已保存到: {output_txt_filename}")
except IOError as e:
print(f"\n错误:无法写入转录结果到文件 {output_txt_filename}: {e}")
print(f"\n--- 结果分析 ---")
print(f"转录文本: \"{transcribed_text}\"")
print(f"总字数: {word_count}")
print("\n--- 测试结束 ---")
if __name__ == "__main__":
main()
4. 准备工作与运行脚本
下载模型(离线部署)
如果您的服务器网络访问 Hugging Face 不稳定,或者您希望进行离线部署:
- 手动下载
.nemo
文件:- 下载链接:
https://huggingface.co/nvidia/parakeet-tdt-0.6b-v2/resolve/main/parakeet-tdt-0.6b-v2.nemo
- 将下载的文件(例如
parakeet-tdt-0.6b-v2.nemo
)放置到您服务器的某个目录下,比如我们示例中的/home/garyhuang/ASR/
。
- 下载链接:
- 修改脚本中的
MODEL_NAME
:
确保脚本中的MODEL_NAME
变量指向这个本地文件的绝对路径,并确保加载模型时使用的是ASRModel.restore_from(restore_path=MODEL_NAME)
。
如果网络良好,您可以直接将 MODEL_NAME
设置为 "nvidia/parakeet-tdt-0.6b-v2"
,脚本首次运行时会自动下载。
准备音频文件
- 准备一个
.wav
或.flac
格式的音频文件。模型期望输入是 16kHz 的单声道音频。 - 将音频文件路径更新到脚本中的
AUDIO_FILE_PATH
变量。
执行脚本
- 将上述 Python 代码保存为文件,例如
run_parakeet_transcribe.py
。 - 在终端中,进入脚本所在目录,然后运行:
如果想同时使用 NVIDIA Nsight Systems 进行性能剖析:python run_parakeet_transcribe.py
之后可以用nsys profile -o parakeet_profile --stats=true python run_parakeet_transcribe.py
nsys-ui parakeet_profile.nsys-rep
(或.qdrep
) 文件打开分析报告。
5. 解读输出结果
脚本运行成功后,会看到类似以下的命令行输出:
--- ASR 性能测试脚本 (Parakeet TDT 0.6B V2) ---
... (模型加载日志) ...
模型加载完成,耗时: 8.90 秒
CUDA 可用,将模型移至 GPU。
准备转录音频文件: /home/garyhuang/ASR/2086-149220-0033.wav
音频时长: 7.43 秒 (0.12 分钟)
预处理阶段完成 (主要由模型内部处理)。
开始推理...
Transcribing: 100%|██████████| 1/1 [00:01<00:00, 1.45s/it]
推理完成,耗时: 1.46 秒
开始后处理...
后处理完成。
转录结果已保存到: /home/garyhuang/ASR/2086-149220-0033.txt
--- 结果分析 ---
转录文本: "Well, I don't wish to see it any more, observed Phebe, turning away her eyes. It is certainly very like the old portrait."
总字数: 23
每分钟字数 (WPM): 185.61
--- 测试结束 ---
- 转录文本: 模型识别出的语音内容。
- TXT 文件: 转录文本会保存到与输入音频文件同名(扩展名为.txt)的文件中。
- WPM 和 RTFx: 性能指标,详见下文。
也会看到在文件目录下出现以下结构:
2086-149220-0033的转录结果如下:
6. 常见问题与排错锦囊
在我们探索过程中,遇到了一些典型问题,这里总结一下:
网络错误导致模型下载失败
- 症状:
MaxRetryError
,NewConnectionError: [Errno 101] Network is unreachable
。 - 原因: 无法连接到 Hugging Face 下载模型。
- 解决:
- 检查服务器网络。
- 如无法解决,采用手动下载
.nemo
文件的方式(见上文),并在脚本中通过ASRModel.restore_from(restore_path="本地路径")
加载。 - 具体操作可参考模型权重下载方法中 light-hf-proxy方法
加载本地模型文件路径问题
- 症状:
Repo id must be in the form 'repo_name' or 'namespace/repo_name': '/path/to/your.nemo'. Use repo_type argument if needed.
- 原因: 使用
ASRModel.from_pretrained(model_name="本地路径")
时,NeMo 可能将本地路径误认为 Hugging Face 仓库 ID。 - 解决: 明确使用
ASRModel.restore_from(restore_path="本地路径")
来加载本地.nemo
文件。
transcribe()
参数错误
- 症状:
TypeError: EncDecRNNTModel.transcribe() got an unexpected keyword argument 'paths2audio_files'
。 - 原因:
transcribe()
函数期望音频文件列表作为第一个位置参数,而非关键字参数。 - 解决: 将
asr_model.transcribe(paths2audio_files=my_audio_list, ...)
修改为asr_model.transcribe(my_audio_list, ...)
。
性能警告:cuda-python
缺失
- 症状:
No conditional node support for Cuda. ... Reason: No cuda-python module. Please do pip install cuda-python>=12.3
- 原因: 缺少
cuda-python
包,导致 TDT 解码器中某个 CUDA 优化无法启用。 - 解决: (可选)安装
pip install cuda-python>=12.3
(版本需与您的CUDA主版本匹配)以获取潜在的性能提升。不安装不影响基本功能。
7. 性能指标浅析
- WPM (Words Per Minute - 每分钟字数):
- 计算公式:
总字数 / (音频时长_秒 / 60)
- 反映了在给定音频上的有效转录速率。是衡量ASR系统吞吐量的一个用户友好指标。
- 计算公式:
- RTFx (Real-Time Factor - 实时因子):
- 计算公式:
音频时长_秒 / 推理耗时_秒
- 表示模型处理音频的速度是其实际播放速度的多少倍。例如,RTFx 为 5.0 意味着处理10秒的音频仅需2秒。RTFx > 1 表示快于实时。
- 计算公式:
这些指标受硬件、音频质量、模型大小等多种因素影响。
8. 总结与展望
如果想要转录自己的音频文件,只需替换“2086-149220-0033.wav”和脚本中的“2086-149220-0033.wav”即可.
最后,所有的项目文件我打包放在这里了:
通过网盘分享的文件:NVIDIA-parakeet-tdt-0.6b-v2
链接: https://pan.baidu.com/s/1VNOoPqTJzUwo3mD37NhQwA?pwd=jrh7 提取码: jrh7