去年在开发一个智能客服质检系统时,客户突然提出要支持本地部署的语音转写功能。当时市面上主流的方案要么需要联网调用API,要么价格昂贵得离谱。经过多方调研,最终选择了阿里巴巴开源的FunASR作为基础引擎,成功实现了离线环境下的高精度语音转写。今天就把这套经过实战检验的离线文件转写方案分享给大家。
FunASR作为工业级语音识别工具包,最大的优势在于:
在实际项目中,我们发现硬件配置直接影响转写速度。以下是经过测试的推荐配置:
| 音频时长 | CPU核心 | 内存 | 显存 | 转写速度 |
|---|---|---|---|---|
| 1小时 | 4核 | 8G | 无 | 2x实时 |
| 8小时 | 8核 | 16G | 4G | 5x实时 |
| 24小时 | 16核 | 32G | 8G | 10x实时 |
注意:若使用GPU加速,需要安装对应版本的CUDA驱动。我们实测Tesla T4显卡可使长音频转写速度提升3倍以上。
推荐使用Docker部署,省去依赖安装的麻烦:
bash复制# 拉取官方镜像
docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.1.5
# 启动容器(注意挂载模型目录)
docker run -it --rm -p 10095:10095 \
-v /path/to/local/models:/workspace/models \
registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.1.5
模型文件需要单独下载,建议选择1.8G的paraformer-zh-large模型:
bash复制wget https://www.modelscope.cn/api/v1/models/damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch/repo?Revision=master
在实际业务中,我们经常遇到各种格式的音频文件。以下是经过优化的预处理代码:
python复制import librosa
import soundfile as sf
def convert_audio(input_path, output_path='./temp.wav'):
"""统一转换为16k采样率的wav格式"""
try:
y, sr = librosa.load(input_path, sr=16000)
sf.write(output_path, y, sr, subtype='PCM_16')
return output_path
except Exception as e:
print(f"音频转换失败: {str(e)}")
return None
常见问题处理:
基于FastAPI实现RESTful接口:
python复制from fastapi import FastAPI, UploadFile
from funasr import AutoModel
app = FastAPI()
model = AutoModel(model="/workspace/models/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch")
@app.post("/transcribe")
async def transcribe_audio(file: UploadFile):
temp_path = f"/tmp/{file.filename}"
with open(temp_path, "wb") as buffer:
buffer.write(await file.read())
# 执行转写
result = model.generate(input=temp_path)
return {
"text": result[0]['text'],
"segments": result[0]['segments']
}
通过测试发现,当处理大批量小音频时,频繁加载模型会严重拖慢速度。我们采用以下优化策略:
优化前后性能对比:
| 方案 | 100个10秒音频 | 资源占用 |
|---|---|---|
| 原始方案 | 8分12秒 | CPU 80% |
| 优化方案 | 1分45秒 | CPU 65% |
在连续运行72小时后,我们发现内存会缓慢增长。通过memory_profiler定位到问题:
python复制# 有问题的代码
def transcribe():
vad_model = AutoModel(model="fsmn-vad") # 每次调用都新建实例
# 修正后
vad_model = None
def transcribe():
global vad_model
if vad_model is None:
vad_model = AutoModel(model="fsmn-vad")
我们最终采用的部署方案:
code复制 +-----------------+
| Nginx LB |
+--------+--------+
|
+---------------+---------------+
| | |
+-------+-------+ +-----+-------+ +-----+-------+
| Worker Pod1 | | Worker Pod2 | | Worker Pod3 |
| (2CPU 4GB) | | (2CPU 4GB) | | (2CPU 4GB) |
+---------------+ +-------------+ +-------------+
关键配置参数:
yaml复制# Kubernetes deployment示例
resources:
limits:
cpu: "2"
memory: "4Gi"
requests:
cpu: "1"
memory: "2Gi"
livenessProbe:
httpGet:
path: /health
port: 8000
建议监控以下核心指标:
实现方案:
python复制from prometheus_client import start_http_server, Summary
TRANSCODE_TIME = Summary('transcode_seconds', 'Time spent transcribing audio')
@TRANSCODE_TIME.time()
def transcode_audio():
# 转写逻辑
标点符号问题:初期转写结果没有标点,通过在后处理中添加基于规则的标点预测模型解决
方言识别:当遇到带口音的普通话时,准确率下降约15%。解决方案是:
长音频分段:超过30分钟的音频直接转写容易OOM,最佳实践是:
python复制from funasr import AutoModel
model = AutoModel(vad_model="fsmn-vad", punc_model="ct-punc")
result = model.generate(
input=audio_path,
batch_size_s=300, # 每5分钟切分一次
hotword='客户服务' # 业务关键词提升识别率
)
特殊符号处理:遇到产品型号、专业术语时,建议通过hotword参数注入领域词汇表:
python复制hotwords = ["iPhone14 ProMax", "RTX4090", "MySQL8.0"]
result = model.generate(input=audio_path, hotword=" ".join(hotwords))
这套方案已经在金融、医疗等多个行业落地,最高支持过单日10万小时的转写任务。建议初次部署时先从CPU版本开始,待业务量增长后再考虑GPU加速方案。对于需要定制化训练的场景,FunASR也提供了完整的微调工具链,这个我们后续可以再深入探讨