1. 在线语音转文字(ASR)
1. 在线语音转文字(ASR)1. 概念介绍1.1 “ASR”是什么?1.2 实现原理1. 声学模型2. 语言模型3. 发音词典4. 解码器5. 端到端ASR2. 项目架构关键代码1. 语音处理与识别核心 (largemodel/largemodel/asr.py)2. VAD智能录音 (largemodel/largemodel/asr.py)代码解析3. 实践操作3.1 配置在线ASR3.2 启动并测试功能
1. 概念介绍
1.1 “ASR”是什么?
ASR(Automatic Speech Recognition,自动语音识别)是一种将人类的语音信号转化为文本的技术。它广泛应用于智能助手、语音命令控制、电话客服自动化、实时字幕生成等领域。ASR 的目标是让机器能够“听懂”人类的语言,并将其转换为计算机可以处理和理解的形式。
1.2 实现原理
ASR 系统的实现主要依赖于以下几个关键技术组件:
1. 声学模型
- 声学模型负责将输入的声音信号转换为音素或子词单元。这通常涉及到特征提取步骤,如使用梅尔频率倒谱系数(MFCCs)或滤波器组(Filter Banks)来表示音频信号。
- 这些特征随后被送入深度神经网络(DNN)、卷积神经网络(CNN)、循环神经网络(RNN)或者更先进的Transformer架构中进行训练,以学习如何从音频特征映射到对应的音素或文字。
2. 语言模型
- 语言模型用于预测在给定前文条件下下一个最可能出现的词语,从而帮助提高识别准确性。它基于大量的文本数据训练而成,了解哪些词汇序列更有可能出现。
- 常见的语言模型包括n-gram模型、RNN-based LM以及最近流行的Transformer-based LM等。
3. 发音词典
- 发音词典提供了单词与它们对应的发音之间的映射关系。这对于连接声学模型和语言模型至关重要,因为它允许系统根据已知的发音规则去理解和匹配听到的声音。
4. 解码器
- 解码器的任务是在给定声学模型、语言模型和发音词典的情况下,找到最可能的单词序列作为输出。这个过程通常涉及复杂的搜索算法,比如Viterbi算法或者是基于图的搜索方法,用来寻找最优路径。
5. 端到端ASR
- 随着深度学习的发展,出现了端到端的ASR系统,这些系统试图直接从原始音频信号中学习到文本输出,而不需要显式的声学模型、发音词典和语言模型分离设计。这类系统常常基于序列到序列(Seq2Seq)框架,例如使用注意力机制(Attention Mechanism)或Transformer架构,大大简化了传统ASR系统的复杂度。
总的来说,现代ASR系统通过结合上述各个组件,并利用大规模的数据集和强大的计算资源进行训练,实现了高效准确的人类语音转文字的能力。随着技术的进步,ASR系统的性能也在持续提升,应用场景也日益广泛。
2. 项目架构
关键代码
1. 语音处理与识别核心 (largemodel/largemodel/asr.py)
x # From largemodel/largemodel/asr.py def kws_handler ( self ) -> None : if self . stop_event . is_set (): return if self . listen_for_speech ( self . mic_index ): asr_text = self . ASR_conversion ( self . user_speechdir ) # 进行 ASR 转换 / Perform ASR conversion if asr_text == 'error' : # 检查 ASR 结果长度是否小于4个字符 / Check if ASR result length is less than 4 characters self . get_logger (). warn ( "I still don't understand what you mean. Please try again" ) playsound ( self . audio_dict [ self . error_response ]) # 错误响应 / Error response else : self . get_logger (). info ( asr_text ) self . get_logger (). info ( "okay😀, let me think for a moment..." ) self . asr_pub_result ( asr_text ) # 发布 ASR结果 / Publish ASR result else : return def ASR_conversion ( self , input_file : str ) -> str : if self . use_oline_asr : result = self . modelinterface . oline_asr ( input_file ) if result [ 0 ] == 'ok' and len ( result [ 1 ]) > 4 : return result [ 1 ] else : self . get_logger (). error ( f'ASR Error:{result[1]}' ) # ASR error. return 'error' else : result = self . modelinterface . SenseVoiceSmall_ASR ( input_file ) if result [ 0 ] == 'ok' and len ( result [ 1 ]) > 4 : return result [ 1 ] else : self . get_logger (). error ( f'ASR Error:{result[1]}' ) # ASR error. return 'error'
2. VAD智能录音 (largemodel/largemodel/asr.py)
xxxxxxxxxx # From largemodel/largemodel/asr.py def listen_for_speech ( self , mic_index = 0 ): p = pyaudio . PyAudio () # Create PyAudio instance. / 创建PyAudio实例。 audio_buffer = [] # Store audio data. / 存储音频数据。 silence_counter = 0 # Silence counter. / 静音计数器。 MAX_SILENCE_FRAMES = 90 # 30帧*30ms=900ms静音后停止 / Stop after 900ms of silence (30 frames * 30ms) speaking = False # Flag indicating speech activity. / 语音活动标志。 frame_counter = 0 # Frame counter. / 计数器。 stream_kwargs = { 'format' : pyaudio . paInt16 , 'channels' : 1 , 'rate' : self . sample_rate , 'input' : True , 'frames_per_buffer' : self . frame_bytes , } if mic_index ! = 0 : stream_kwargs [ 'input_device_index' ] = mic_index # Prompt the user to speak via the buzzer. / 通过蜂鸣器提示用户讲话。 self . pub_beep . publish ( UInt16 ( data = 1 )) time . sleep ( 0.5 ) self . pub_beep . publish ( UInt16 ( data = 0 )) try : # Open audio stream. / 打开音频流。 stream = p . open ( ** stream_kwargs ) while True : if self . stop_event . is_set (): return False frame = stream . read ( self . frame_bytes , exception_on_overflow = False ) # Read audio data. / 读取音频数据。 is_speech = self . vad . is_speech ( frame , self . sample_rate ) # VAD detection. / VAD检测。 if is_speech : # Detected speech activity. / 检测到语音活动。 speaking = True audio_buffer . append ( frame ) silence_counter = 0 else : if speaking : # Detect silence after speech activity. / 在语音活动后检测静音。 silence_counter += 1 audio_buffer . append ( frame ) # Continue recording buffer. / 持续记录缓冲。 # End recording when silence duration meets the threshold. / 静音持续时间达标时结束录音。 if silence_counter > = MAX_SILENCE_FRAMES : break frame_counter += 1 if frame_counter % 2 == 0 : self . get_logger (). info ( '1' if is_speech else '-' ) # Real-time status display. finally : stream . stop_stream () stream . close () p . terminate () # Save valid recording (remove trailing silence). / 保存有效录音(去除尾部静音)。 if speaking and len ( audio_buffer ) > 0 : # Trim the last silent part. / 裁剪最后静音部分。 clean_buffer = audio_buffer [: \- MAX_SILENCE_FRAMES ] if len ( audio_buffer ) > MAX_SILENCE_FRAMES else audio_buffer with wave . open ( self . user_speechdir , 'wb' ) as wf : wf . setnchannels ( 1 ) wf . setsampwidth ( p . get_sample_size ( pyaudio . paInt16 )) wf . setframerate ( self . sample_rate ) wf . writeframes ( b'' . join ( clean_buffer )) return True
代码解析
ASR(语音转文字)功能由ASRNode节点 (asr.py) 提供。该节点负责音频的录制、转换和发布。
-
音频录制 (
listen_for_speech):- 此函数使用
pyaudio库从麦克风捕获音频流。 - 它集成了
webrtcvad库进行语音活动检测(VAD)。函数循环读取音频帧,并使用vad.is_speech()判断每一帧是否包含人声。 - 当检测到语音时,数据被写入一个缓冲区。当检测到持续的静默(由
MAX_SILENCE_FRAMES定义)时,录音停止。 - 最终,缓冲区中的音频数据被写入一个
.wav文件,路径为self.user_speechdir。
- 此函数使用
-
后端选择与执行 (
ASR_conversion):kws_handler函数在录音成功后调用ASR_conversion函数。- 此函数通过读取ROS参数
use_oline_asr(一个布尔值)来决定调用哪个后端实现。 - 若为
false,则调用self.modelinterface.SenseVoiceSmall_ASR方法,对应本地识别。 - 若为
true,则调用self.modelinterface.oline_asr方法,对应在线识别。 - 该函数将音频文件路径作为参数传递给所选的方法,并处理返回的结果。
-
结果发布 (
asr_pub_result):ASR_conversion返回有效的文本后,kws_handler会调用asr_pub_result函数。- 此函数将文本字符串封装在一个
std_msgs.msg.String消息中,并通过ROS发布者将其发布到/asr话题。
3. 实践操作
3.1 配置在线ASR
-
先从前面通义千问的注册教程中获取API Key
-
打开模型接口配置文件
large_model_interface.yaml:
xxxxxxxxxx vim ~/yahboom_ws/src/largemodel/config/large_model_interface.yaml
3. 填入你的API凭证 : 找到在线ASR的部分,填入你的Key,然后选择语音识别到模型
xxxxxxxxxx # large_model_interface.yaml # ----------------------------------------------------------------------------- # 大模型设置 (Large Language Models Settings) # ----------------------------------------------------------------------------- ## 在线大模型 (Online Large Language Models) # 通义千问平台配置 (Tongyi Platform Configuration) online_asr_api_key : "Your_AccessKey_ID" # ----------------------------------------------------------------------------- # 语音识别设置 (Speech Recognition Settings) # ----------------------------------------------------------------------------- ## 在线语音识别 (Online ASR) oline_asr_model : 'paraformer-realtime-8k-v2' # 可选:'paraformer-realtime-v2'、'paraformer-realtime-v1'等,使用的是通义千问平台的API oline_asr_sample_rate : 16000 # ASR音频采样率
4. 打开主配置文件yahboom.yaml:
xxxxxxxxxx gedit ~/yahboom_ws/src/largemodel/config/yahboom.yaml
5. 启用在线ASR模式 : 将use_oline_asr参数设置为True。
xxxxxxxxxx # yahboom.yaml asr : ros__parameters : use_oline_asr : True # 关键: 从False修改为True regional_setting : "China"
3.2 启动并测试功能
- 启动命令 :
xxxxxxxxxx ros2 launch largemodel asr_only.launch.py
2. 测试 : 对着麦克风说:你好小亚,它就会回应:I‘m here,然后就可以开始说话了,最后会展示出它收录到的声音被转成了文字打印在了终端。