Qwen3-ASR-1.7B基础教程:qwen-asr SDK本地加载与自定义封装
本文介绍了如何在星图GPU平台上自动化部署Qwen3-ASR-1.7B语音识别模型v2,并利用其SDK进行本地加载与自定义封装。该模型支持多语言识别,可广泛应用于会议记录自动转写、音频内容审核等场景,帮助开发者快速构建离线语音识别服务。
Qwen3-ASR-1.7B基础教程:qwen-asr SDK本地加载与自定义封装
想自己动手搭建一个离线的语音识别服务吗?今天咱们就来聊聊怎么把Qwen3-ASR-1.7B这个强大的语音识别模型,从镜像里的“黑盒”变成你手里可以随意调用的工具。
你可能已经在镜像里体验过它的转写效果了——上传音频,点击识别,文字就出来了。但如果你想让这个能力集成到自己的应用里,或者想对识别流程做些定制,那就需要了解它背后的技术栈了。
这篇文章就是为你准备的。我会带你一步步了解qwen-asr SDK怎么用,怎么在本地加载模型,以及怎么根据自己的需求进行封装。看完之后,你就能把这个17亿参数的语音识别引擎,变成你项目里的一行代码调用。
1. 环境准备与快速部署
1.1 系统要求
在开始之前,先确认你的环境能满足基本要求:
- GPU:至少12GB显存(推荐16GB以上)
- 内存:16GB RAM或更高
- 存储:至少20GB可用空间(用于存放模型权重)
- Python版本:3.9-3.11
- CUDA版本:11.8或12.x(与PyTorch版本匹配)
如果你不确定自己的环境,可以运行下面的命令检查:
# 检查GPU和CUDA
nvidia-smi
# 检查Python版本
python --version
# 检查PyTorch和CUDA
python -c "import torch; print(f'PyTorch版本: {torch.__version__}'); print(f'CUDA可用: {torch.cuda.is_available()}')"
1.2 安装依赖包
qwen-asr SDK的依赖相对简单,主要是PyTorch和音频处理库:
# 创建虚拟环境(可选但推荐)
python -m venv asr_env
source asr_env/bin/activate # Linux/Mac
# 或 asr_env\Scripts\activate # Windows
# 安装PyTorch(根据你的CUDA版本选择)
# CUDA 12.1
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu121
# 或者CUDA 11.8
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu118
# 安装qwen-asr核心包
pip install qwen-asr
# 安装其他辅助库
pip install fastapi uvicorn gradio # 如果你需要Web服务
pip install soundfile librosa # 音频文件处理
1.3 下载模型权重
qwen-asr SDK支持从魔搭社区直接下载模型,但如果你需要在完全离线环境下使用,可以提前下载好权重文件:
from qwen_asr import Qwen3ASRPipeline
import os
# 方式1:在线下载(需要网络)
# 这会自动从魔搭社区下载权重到缓存目录
pipeline = Qwen3ASRPipeline.from_pretrained("Qwen/Qwen3-ASR-1.7B")
# 方式2:使用本地权重文件
# 先手动下载权重文件(约5.5GB)
# 下载地址:https://modelscope.cn/models/Qwen/Qwen3-ASR-1.7B
# 下载后解压到本地目录,比如 ./qwen3-asr-1.7b
# 然后指定本地路径加载
model_path = "./qwen3-asr-1.7b"
pipeline = Qwen3ASRPipeline.from_pretrained(model_path)
如果你在完全离线的环境,我建议提前下载好权重文件。模型包含两个主要的权重文件(shard):
model-00001-of-00002.safetensorsmodel-00002-of-00002.safetensors
总共大约5.5GB,确保下载完整。
2. 基础概念快速入门
2.1 qwen-asr SDK是什么?
简单来说,qwen-asr SDK是阿里为Qwen3-ASR系列模型提供的一个Python工具包。它把复杂的语音识别流程封装成了几个简单的函数调用。
你可以把它想象成一个“语音转文字”的转换器:
- 输入:音频文件或音频数据
- 处理:自动进行格式转换、特征提取、模型推理
- 输出:识别出的文字内容
2.2 核心组件了解
qwen-asr SDK主要包含以下几个部分:
- Qwen3ASRPipeline:主入口类,负责整个识别流程
- 音频处理器:自动处理不同格式的音频文件
- Tokenizer:处理文本的编码和解码
- 模型本身:1.7B参数的神经网络,负责从声音到文字的转换
2.3 工作流程概览
当你调用识别功能时,背后发生了这些事情:
音频文件 → 格式检查 → 重采样到16kHz → 提取声学特征 →
模型推理 → 生成文字序列 → 解码为可读文本 → 返回结果
整个过程都是自动的,你只需要关心输入和输出。
3. 分步实践操作
3.1 第一步:最简单的识别示例
让我们从一个最简单的例子开始,感受一下qwen-asr有多容易使用:
from qwen_asr import Qwen3ASRPipeline
# 1. 加载模型(第一次运行会自动下载权重)
print("正在加载模型,这可能需要一些时间...")
pipeline = Qwen3ASRPipeline.from_pretrained("Qwen/Qwen3-ASR-1.7B")
print("模型加载完成!")
# 2. 准备音频文件
# 确保是WAV格式,16kHz采样率,单声道
audio_path = "test_audio.wav" # 替换为你的音频文件路径
# 3. 执行识别
print("开始识别音频...")
result = pipeline(audio_path)
print("识别完成!")
# 4. 查看结果
print(f"识别内容:{result}")
就这么简单!四行核心代码(不算打印语句)就完成了一次语音识别。
3.2 第二步:指定识别语言
Qwen3-ASR-1.7B支持多种语言,你可以明确告诉它要识别哪种语言:
from qwen_asr import Qwen3ASRPipeline
pipeline = Qwen3ASRPipeline.from_pretrained("Qwen/Qwen3-ASR-1.7B")
# 测试中文音频
chinese_result = pipeline("chinese_audio.wav", language="zh")
print(f"中文识别:{chinese_result}")
# 测试英文音频
english_result = pipeline("english_audio.wav", language="en")
print(f"英文识别:{english_result}")
# 让模型自动检测语言(推荐大多数情况)
auto_result = pipeline("mixed_audio.wav", language="auto")
print(f"自动检测识别:{auto_result}")
支持的语言代码:
zh:中文(普通话)en:英文ja:日语ko:韩语yue:粤语auto:自动检测(默认)
3.3 第三步:处理非WAV格式音频
如果你手头不是WAV格式的音频怎么办?别担心,我们可以用Python的音频库先转换一下:
import librosa
import soundfile as sf
from qwen_asr import Qwen3ASRPipeline
def convert_to_wav(input_path, output_path="converted.wav"):
"""将任意格式音频转换为WAV格式"""
# 加载音频文件
audio, sr = librosa.load(input_path, sr=16000, mono=True)
# 保存为WAV格式
sf.write(output_path, audio, sr)
print(f"已转换:{input_path} -> {output_path}")
return output_path
# 使用示例
pipeline = Qwen3ASRPipeline.from_pretrained("Qwen/Qwen3-ASR-1.7B")
# 转换MP3文件
wav_path = convert_to_wav("input.mp3")
# 识别转换后的文件
result = pipeline(wav_path)
print(f"识别结果:{result}")
这个转换函数可以处理MP3、M4A、FLAC等常见格式,自动重采样到16kHz并转为单声道。
4. 快速上手示例
4.1 完整的工作示例
让我们看一个更实际的例子:批量处理一个文件夹里的所有音频文件:
import os
from pathlib import Path
from qwen_asr import Qwen3ASRPipeline
class BatchASRProcessor:
"""批量语音识别处理器"""
def __init__(self, model_path="Qwen/Qwen3-ASR-1.7B"):
print("初始化语音识别模型...")
self.pipeline = Qwen3ASRPipeline.from_pretrained(model_path)
print("模型就绪!")
def process_file(self, audio_path, language="auto"):
"""处理单个音频文件"""
try:
result = self.pipeline(str(audio_path), language=language)
return {
"file": audio_path.name,
"status": "success",
"text": result
}
except Exception as e:
return {
"file": audio_path.name,
"status": "error",
"error": str(e)
}
def process_folder(self, folder_path, output_file="results.txt"):
"""处理整个文件夹的音频文件"""
folder = Path(folder_path)
audio_files = list(folder.glob("*.wav")) + list(folder.glob("*.mp3"))
if not audio_files:
print(f"在 {folder_path} 中没有找到音频文件")
return
print(f"找到 {len(audio_files)} 个音频文件,开始处理...")
results = []
for i, audio_file in enumerate(audio_files, 1):
print(f"处理中 ({i}/{len(audio_files)}): {audio_file.name}")
result = self.process_file(audio_file)
results.append(result)
# 保存结果
with open(output_file, "w", encoding="utf-8") as f:
for r in results:
if r["status"] == "success":
f.write(f"文件:{r['file']}\n")
f.write(f"内容:{r['text']}\n")
f.write("-" * 50 + "\n")
else:
f.write(f"文件:{r['file']} - 处理失败:{r['error']}\n")
print(f"处理完成!结果已保存到 {output_file}")
# 使用示例
if __name__ == "__main__":
# 创建处理器
processor = BatchASRProcessor()
# 处理整个文件夹
processor.process_folder("./audio_files", "transcriptions.txt")
# 或者处理单个文件
result = processor.process_file("./audio_files/meeting.wav")
print(f"会议记录:{result['text']}")
这个类提供了完整的批量处理能力,你可以直接拿来用在自己的项目里。
4.2 实时录音识别示例
如果你想实现“边说边转写”的效果,可以结合Python的录音功能:
import pyaudio
import wave
import threading
import time
from queue import Queue
from qwen_asr import Qwen3ASRPipeline
class RealtimeASR:
"""简易实时语音识别"""
def __init__(self, chunk_duration=5):
"""
chunk_duration: 每次处理的音频时长(秒)
"""
self.chunk_duration = chunk_duration
self.is_recording = False
self.audio_queue = Queue()
# 加载模型
print("加载语音识别模型...")
self.pipeline = Qwen3ASRPipeline.from_pretrained("Qwen/Qwen3-ASR-1.7B")
# 音频参数
self.FORMAT = pyaudio.paInt16
self.CHANNELS = 1
self.RATE = 16000
self.CHUNK = 1024
def record_audio(self):
"""录音线程"""
p = pyaudio.PyAudio()
stream = p.open(
format=self.FORMAT,
channels=self.CHANNELS,
rate=self.RATE,
input=True,
frames_per_buffer=self.CHUNK
)
print("开始录音...")
frames = []
while self.is_recording:
data = stream.read(self.CHUNK)
frames.append(data)
# 每积累够chunk_duration时长的数据就处理一次
if len(frames) >= (self.RATE * self.chunk_duration) / self.CHUNK:
# 保存临时文件
temp_file = "temp_chunk.wav"
wf = wave.open(temp_file, 'wb')
wf.setnchannels(self.CHANNELS)
wf.setsampwidth(p.get_sample_size(self.FORMAT))
wf.setframerate(self.RATE)
wf.writeframes(b''.join(frames))
wf.close()
# 放入队列处理
self.audio_queue.put(temp_file)
frames = [] # 清空,开始积累下一段
stream.stop_stream()
stream.close()
p.terminate()
def process_audio(self):
"""处理音频线程"""
while self.is_recording or not self.audio_queue.empty():
if not self.audio_queue.empty():
audio_file = self.audio_queue.get()
try:
result = self.pipeline(audio_file, language="zh")
print(f"\n识别结果:{result}")
except Exception as e:
print(f"识别出错:{e}")
def start(self):
"""开始实时识别"""
self.is_recording = True
# 启动录音线程
record_thread = threading.Thread(target=self.record_audio)
record_thread.start()
# 启动处理线程
process_thread = threading.Thread(target=self.process_audio)
process_thread.start()
print("按Enter键停止...")
input()
self.stop()
record_thread.join()
process_thread.join()
def stop(self):
"""停止识别"""
self.is_recording = False
print("已停止录音")
# 使用示例
if __name__ == "__main__":
# 注意:需要先安装pyaudio: pip install pyaudio
asr = RealtimeASR(chunk_duration=3) # 每3秒识别一次
asr.start()
这个实时识别示例展示了如何将qwen-asr集成到流式处理场景中。虽然它还不是真正的“流式识别”(模型本身是端到端的),但对于很多实时性要求不高的场景已经够用了。
5. 自定义封装实践
5.1 为什么要自定义封装?
直接使用qwen-asr SDK虽然简单,但在实际项目中你可能需要:
- 添加预处理逻辑:比如自动降噪、音量归一化
- 集成后处理:比如标点恢复、数字格式统一
- 错误处理增强:更完善的异常捕获和重试机制
- 性能优化:缓存机制、批量处理优化
- 业务逻辑整合:与你的业务系统深度集成
5.2 基础封装示例
下面是一个基础的封装类,添加了常用的增强功能:
import os
import time
from typing import Optional, List, Dict, Union
from pathlib import Path
import numpy as np
from qwen_asr import Qwen3ASRPipeline
class EnhancedASRService:
"""增强版语音识别服务"""
def __init__(self,
model_path: str = "Qwen/Qwen3-ASR-1.7B",
cache_dir: Optional[str] = None,
device: str = "cuda"):
"""
初始化增强版ASR服务
Args:
model_path: 模型路径,可以是本地路径或魔搭模型ID
cache_dir: 缓存目录,用于存储临时文件
device: 运行设备,cuda或cpu
"""
self.model_path = model_path
self.device = device
self.cache_dir = cache_dir or "./asr_cache"
# 创建缓存目录
os.makedirs(self.cache_dir, exist_ok=True)
# 性能统计
self.stats = {
"total_calls": 0,
"total_audio_duration": 0.0,
"total_processing_time": 0.0
}
# 加载模型
self._load_model()
def _load_model(self):
"""加载模型,带进度提示"""
print(f"正在加载语音识别模型: {self.model_path}")
start_time = time.time()
try:
self.pipeline = Qwen3ASRPipeline.from_pretrained(
self.model_path,
torch_dtype="auto",
device_map=self.device
)
load_time = time.time() - start_time
print(f"模型加载完成,耗时 {load_time:.2f} 秒")
except Exception as e:
print(f"模型加载失败: {e}")
raise
def transcribe(self,
audio_input: Union[str, Path, np.ndarray],
language: str = "auto",
task: str = "transcribe",
**kwargs) -> Dict:
"""
核心转写方法
Args:
audio_input: 音频输入,可以是文件路径或numpy数组
language: 语言代码
task: 任务类型,transcribe或translate
**kwargs: 其他参数
Returns:
包含识别结果和元数据的字典
"""
start_time = time.time()
self.stats["total_calls"] += 1
try:
# 执行识别
if isinstance(audio_input, (str, Path)):
# 文件路径
text = self.pipeline(str(audio_input), language=language)
audio_duration = self._get_audio_duration(str(audio_input))
else:
# numpy数组
# 需要先保存为临时文件
temp_file = self._save_temp_audio(audio_input)
text = self.pipeline(temp_file, language=language)
audio_duration = len(audio_input) / 16000 # 假设16kHz采样率
# 更新统计
processing_time = time.time() - start_time
self.stats["total_audio_duration"] += audio_duration
self.stats["total_processing_time"] += processing_time
# 计算实时因子
rtf = processing_time / audio_duration if audio_duration > 0 else 0
# 返回结构化结果
return {
"status": "success",
"text": text,
"language": language,
"audio_duration": audio_duration,
"processing_time": processing_time,
"real_time_factor": rtf,
"timestamp": time.time()
}
except Exception as e:
return {
"status": "error",
"error": str(e),
"audio_input": str(audio_input) if isinstance(audio_input, (str, Path)) else "numpy_array",
"timestamp": time.time()
}
def batch_transcribe(self,
audio_files: List[Union[str, Path]],
language: str = "auto",
max_workers: int = 1) -> List[Dict]:
"""
批量转写
Args:
audio_files: 音频文件列表
language: 语言代码
max_workers: 最大并行数(当前版本暂不支持真正并行)
Returns:
识别结果列表
"""
results = []
print(f"开始批量处理 {len(audio_files)} 个文件...")
for i, audio_file in enumerate(audio_files, 1):
print(f"进度: {i}/{len(audio_files)} - {audio_file}")
result = self.transcribe(audio_file, language=language)
results.append({
"file": str(audio_file),
**result
})
# 简单进度显示
if i % 5 == 0 or i == len(audio_files):
success_count = sum(1 for r in results if r["status"] == "success")
print(f" 已完成 {i} 个,成功 {success_count} 个")
return results
def _get_audio_duration(self, audio_path: str) -> float:
"""获取音频时长(秒)"""
try:
import librosa
audio, sr = librosa.load(audio_path, sr=None, mono=True)
return len(audio) / sr
except:
# 如果无法获取,返回估计值
return 0.0
def _save_temp_audio(self, audio_array: np.ndarray, sr: int = 16000) -> str:
"""保存numpy数组为临时音频文件"""
import soundfile as sf
temp_path = os.path.join(self.cache_dir, f"temp_{int(time.time())}.wav")
sf.write(temp_path, audio_array, sr)
return temp_path
def get_statistics(self) -> Dict:
"""获取服务统计信息"""
avg_rtf = (self.stats["total_processing_time"] /
self.stats["total_audio_duration"] if self.stats["total_audio_duration"] > 0 else 0)
return {
**self.stats,
"average_real_time_factor": avg_rtf,
"average_processing_time_per_call": (
self.stats["total_processing_time"] / self.stats["total_calls"]
if self.stats["total_calls"] > 0 else 0
)
}
def cleanup(self):
"""清理临时文件"""
import shutil
if os.path.exists(self.cache_dir):
shutil.rmtree(self.cache_dir)
print(f"已清理缓存目录: {self.cache_dir}")
# 使用示例
if __name__ == "__main__":
# 创建增强版服务
asr_service = EnhancedASRService()
# 单个文件识别
result = asr_service.transcribe("meeting.wav", language="zh")
print(f"识别结果: {result['text']}")
print(f"处理耗时: {result['processing_time']:.2f}秒")
print(f"实时因子: {result['real_time_factor']:.2f}")
# 批量处理
audio_files = ["audio1.wav", "audio2.wav", "audio3.wav"]
batch_results = asr_service.batch_transcribe(audio_files)
# 查看统计
stats = asr_service.get_statistics()
print(f"\n服务统计:")
print(f"总调用次数: {stats['total_calls']}")
print(f"总音频时长: {stats['total_audio_duration']:.1f}秒")
print(f"平均实时因子: {stats['average_real_time_factor']:.2f}")
# 清理
asr_service.cleanup()
这个封装类提供了比原生SDK更丰富的功能,包括:
- 详细的性能统计
- 结构化的返回结果
- 错误处理
- 批量处理支持
- 临时文件管理
5.3 添加后处理功能
在实际应用中,识别出的原始文本可能需要进行一些后处理。下面我们添加一些常见的后处理功能:
import re
from typing import Dict
class PostProcessor:
"""识别结果后处理器"""
@staticmethod
def add_punctuation(text: str) -> str:
"""添加标点符号(简易版)"""
# 简单的规则:在特定关键词后添加标点
patterns = [
(r'(好的|是的|对的)([^。!?])', r'\1,\2'),
(r'(然后|接着|接下来)([^,。!?])', r'\1,\2'),
(r'(但是|不过|然而)([^,。!?])', r'\1,\2'),
(r'(\d+)(分钟|小时|天|周|月|年)([^。!?])$', r'\1\2。\3'),
]
processed = text
for pattern, replacement in patterns:
processed = re.sub(pattern, replacement, processed)
# 确保以标点结尾
if processed and processed[-1] not in '。!?.!?':
processed += '。'
return processed
@staticmethod
def format_numbers(text: str) -> str:
"""统一数字格式"""
# 中文数字转阿拉伯数字
chinese_numbers = {
'零': '0', '一': '1', '二': '2', '三': '3', '四': '4',
'五': '5', '六': '6', '七': '7', '八': '8', '九': '9',
'十': '10', '百': '100', '千': '1000', '万': '10000', '亿': '100000000'
}
# 简单的数字转换(实际应用可能需要更复杂的逻辑)
for cn, num in chinese_numbers.items():
text = text.replace(cn, num)
return text
@staticmethod
def remove_fillers(text: str) -> str:
"""去除口头禅和填充词"""
fillers = ['嗯', '啊', '那个', '这个', '然后呢', '就是说', '对吧']
for filler in fillers:
# 去除单独出现的填充词
pattern = r'\s*' + re.escape(filler) + r'\s*'
text = re.sub(pattern, ' ', text)
# 合并多余空格
text = re.sub(r'\s+', ' ', text).strip()
return text
@staticmethod
def process_result(result: Dict) -> Dict:
"""完整后处理流程"""
if result["status"] != "success":
return result
original_text = result["text"]
# 应用各个后处理步骤
text = original_text
text = PostProcessor.remove_fillers(text)
text = PostProcessor.format_numbers(text)
text = PostProcessor.add_punctuation(text)
# 返回增强后的结果
return {
**result,
"text": text,
"original_text": original_text,
"post_processed": True
}
# 在EnhancedASRService中使用后处理
class EnhancedASRServiceWithPostProcess(EnhancedASRService):
"""带后处理的增强版ASR服务"""
def transcribe(self,
audio_input: Union[str, Path, np.ndarray],
language: str = "auto",
task: str = "transcribe",
enable_post_process: bool = True,
**kwargs) -> Dict:
"""
转写方法,支持后处理
Args:
enable_post_process: 是否启用后处理
"""
# 调用父类的识别方法
result = super().transcribe(audio_input, language, task, **kwargs)
# 如果需要后处理
if enable_post_process and result["status"] == "success":
result = PostProcessor.process_result(result)
return result
# 使用示例
if __name__ == "__main__":
# 创建带后处理的服务
asr_service = EnhancedASRServiceWithPostProcess()
# 识别并自动后处理
result = asr_service.transcribe(
"conversation.wav",
language="zh",
enable_post_process=True
)
print("原始识别结果:")
print(result.get("original_text", result["text"]))
print("\n后处理结果:")
print(result["text"])
后处理可以显著提升识别结果的可读性,特别是在处理对话、会议记录等场景时。
6. 实用技巧与进阶
6.1 性能优化技巧
如果你发现识别速度不够快,可以尝试这些优化方法:
# 技巧1:使用半精度推理
pipeline = Qwen3ASRPipeline.from_pretrained(
"Qwen/Qwen3-ASR-1.7B",
torch_dtype=torch.float16, # 使用半精度
device_map="cuda"
)
# 技巧2:启用缓存(如果多次识别相同音频)
from functools import lru_cache
import hashlib
@lru_cache(maxsize=100)
def cached_transcribe(audio_path: str, language: str = "auto"):
"""带缓存的识别函数"""
# 生成缓存键
with open(audio_path, 'rb') as f:
audio_hash = hashlib.md5(f.read()).hexdigest()
cache_key = f"{audio_hash}_{language}"
# 这里简化为直接调用,实际应该检查缓存
return pipeline(audio_path, language=language)
# 技巧3:批量处理时预加载模型到GPU
# 在长时间运行的服务器中,保持模型常驻内存
class ASRServer:
def __init__(self):
self.pipeline = None
def ensure_loaded(self):
if self.pipeline is None:
self.pipeline = Qwen3ASRPipeline.from_pretrained(
"Qwen/Qwen3-ASR-1.7B",
device_map="cuda"
)
def transcribe(self, audio_path, language="auto"):
self.ensure_loaded()
return self.pipeline(audio_path, language=language)
6.2 常见问题解决
问题1:显存不足
# 解决方案:使用CPU或混合精度
pipeline = Qwen3ASRPipeline.from_pretrained(
"Qwen/Qwen3-ASR-1.7B",
device_map="cpu", # 使用CPU(速度会慢)
# 或者
torch_dtype=torch.float16, # 半精度减少显存
low_cpu_mem_usage=True # 减少CPU内存使用
)
问题2:音频太长
# 解决方案:分段处理
def transcribe_long_audio(audio_path, chunk_duration=60):
"""处理长音频,分段识别"""
import librosa
import soundfile as sf
# 加载音频
audio, sr = librosa.load(audio_path, sr=16000, mono=True)
total_duration = len(audio) / sr
results = []
chunk_samples = chunk_duration * sr
for i in range(0, len(audio), chunk_samples):
chunk = audio[i:i + chunk_samples]
# 保存为临时文件
temp_file = f"chunk_{i//chunk_samples}.wav"
sf.write(temp_file, chunk, sr)
# 识别
result = pipeline(temp_file, language="auto")
results.append(result)
# 清理临时文件
os.remove(temp_file)
# 合并结果
full_text = " ".join(results)
return full_text
问题3:识别准确率不高
# 解决方案:音频预处理
def preprocess_audio(audio_path, output_path):
"""音频预处理:降噪、归一化等"""
import noisereduce as nr
import librosa
# 加载音频
audio, sr = librosa.load(audio_path, sr=16000, mono=True)
# 降噪
audio_denoised = nr.reduce_noise(y=audio, sr=sr)
# 音量归一化
audio_normalized = librosa.util.normalize(audio_denoised)
# 保存
import soundfile as sf
sf.write(output_path, audio_normalized, sr)
return output_path
# 使用预处理后的音频
cleaned_audio = preprocess_audio("noisy_audio.wav", "cleaned.wav")
result = pipeline(cleaned_audio, language="auto")
6.3 集成到Web服务
如果你想提供一个语音识别API服务,可以这样集成:
from fastapi import FastAPI, File, UploadFile, HTTPException
from pydantic import BaseModel
import tempfile
import os
app = FastAPI(title="Qwen3-ASR API服务")
# 全局ASR服务实例
asr_service = None
class TranscriptionRequest(BaseModel):
language: str = "auto"
enable_post_process: bool = True
class TranscriptionResponse(BaseModel):
text: str
language: str
processing_time: float
real_time_factor: float
status: str
@app.on_event("startup")
async def startup_event():
"""启动时加载模型"""
global asr_service
print("正在启动语音识别服务...")
asr_service = EnhancedASRServiceWithPostProcess()
print("服务启动完成")
@app.post("/transcribe", response_model=TranscriptionResponse)
async def transcribe_audio(
file: UploadFile = File(...),
language: str = "auto",
enable_post_process: bool = True
):
"""音频转写接口"""
if not file.filename.lower().endswith('.wav'):
raise HTTPException(status_code=400, detail="仅支持WAV格式音频")
# 保存上传的文件
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
content = await file.read()
tmp.write(content)
tmp_path = tmp.name
try:
# 执行识别
result = asr_service.transcribe(
tmp_path,
language=language,
enable_post_process=enable_post_process
)
if result["status"] != "success":
raise HTTPException(status_code=500, detail=result.get("error", "识别失败"))
# 返回结果
return TranscriptionResponse(
text=result["text"],
language=result["language"],
processing_time=result["processing_time"],
real_time_factor=result["real_time_factor"],
status="success"
)
finally:
# 清理临时文件
if os.path.exists(tmp_path):
os.unlink(tmp_path)
@app.get("/health")
async def health_check():
"""健康检查"""
return {"status": "healthy", "service": "qwen3-asr-api"}
@app.get("/stats")
async def get_statistics():
"""获取服务统计"""
if asr_service:
return asr_service.get_statistics()
return {"error": "服务未初始化"}
# 运行命令:uvicorn asr_api:app --host 0.0.0.0 --port 7861
这个FastAPI服务提供了完整的RESTful API,你可以通过HTTP请求来使用语音识别功能。
7. 总结
通过这篇教程,你应该已经掌握了Qwen3-ASR-1.7B模型的核心使用方法。我们从最简单的SDK调用开始,一步步深入到自定义封装和Web服务集成。
关键要点回顾:
- 基础使用很简单:qwen-asr SDK设计得很友好,几行代码就能完成语音识别
- 多语言支持完善:中、英、日、韩、粤语都支持,还能自动检测语言
- 完全离线可用:下载好权重文件后,不需要网络连接也能使用
- 性能表现不错:实时因子RTF<0.3,意味着10秒音频3秒内就能转写完
- 易于集成:无论是Python脚本、Web服务还是桌面应用,都能方便地集成
实际应用建议:
- 会议记录:搭配录音设备,自动生成会议纪要
- 内容审核:识别音频中的敏感内容,支持多语言
- 语音助手:作为智能设备的前端识别模块
- 教育应用:语言学习中的发音评估和转写
下一步学习方向:
如果你对这个模型感兴趣,可以继续探索:
- 结合时间戳对齐模型,生成带时间轴的字幕
- 尝试Fine-tuning,让模型适应你的专业领域
- 探索流式识别,实现真正的实时转写
- 集成到更大的系统中,比如智能客服、视频会议平台
语音识别技术正在变得越来越普及,掌握这样一个强大的本地化识别工具,能为你的项目增添不少价值。希望这篇教程能帮助你快速上手,把Qwen3-ASR-1.7B变成你得力的助手。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐


所有评论(0)