SenseVoice-small-onnx REST API调用指南:curl+Python双路径接入语音转写服务

发布时间:2026/5/19 3:50:21

SenseVoice-small-onnx REST API调用指南:curl+Python双路径接入语音转写服务 SenseVoice-small-onnx REST API调用指南curlPython双路径接入语音转写服务1. 引言你有没有遇到过这样的场景手头有一段会议录音需要整理成文字或者有一段外语视频需要生成字幕但手动听写不仅耗时耗力还容易出错。传统的语音转写工具要么识别不准要么不支持多语言要么就是价格昂贵。今天我要介绍的SenseVoice-small-onnx语音识别服务正好能解决这些痛点。这是一个基于ONNX量化技术的高效语音识别模型不仅支持中文、粤语、英语、日语、韩语等多种语言还能自动检测语言类型识别速度也相当快——10秒的音频推理只需要70毫秒。更重要的是它提供了简单易用的REST API接口无论你是习惯用命令行工具curl还是喜欢用Python编程都能轻松接入。这篇文章我就来手把手教你怎么用这两种方式快速上手这个语音转写服务。2. 服务快速启动2.1 环境准备在开始调用API之前我们需要先把服务跑起来。别担心整个过程非常简单基本上就是安装依赖→启动服务两步走。首先确保你的系统已经安装了Python 3.7或更高版本。然后打开终端执行下面的命令安装必要的依赖包pip install funasr-onnx gradio fastapi uvicorn soundfile jieba这几个包的作用我简单解释一下funasr-onnx这是核心的语音识别推理库gradio和fastapi用来构建Web界面和API服务uvicornASGI服务器用来运行FastAPI应用soundfile处理音频文件jieba中文分词工具安装过程通常很快如果遇到网络问题可以尝试使用国内的镜像源比如清华源或者阿里云源。2.2 启动服务依赖安装完成后启动服务就一行命令的事python3 app.py --host 0.0.0.0 --port 7860这里有两个参数需要注意--host 0.0.0.0表示服务监听所有网络接口这样你不仅能在本机访问其他设备也能访问--port 7860指定服务运行的端口号7860是Gradio的默认端口启动成功后你会看到类似下面的输出INFO: Started server process [12345] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:7860 (Press CTRLC to quit)看到这个提示说明服务已经正常启动了。2.3 服务访问地址服务启动后你可以通过几个不同的地址来访问Web界面打开浏览器访问http://localhost:7860这里提供了一个图形化的操作界面你可以直接上传音频文件点击按钮就能看到转写结果适合快速测试和演示。API文档访问http://localhost:7860/docs这是自动生成的API文档页面基于Swagger UI你可以在这里看到所有可用的接口还能直接在线测试API调用。健康检查访问http://localhost:7860/health这个接口用来检查服务是否正常运行如果返回{status: healthy}说明一切正常。3. 使用curl调用REST API3.1 基础调用方法如果你习惯用命令行工具或者需要在脚本中集成语音识别功能curl是个不错的选择。它的调用方式非常简单基本上就是向指定的URL发送一个POST请求。最基础的调用命令长这样curl -X POST http://localhost:7860/api/transcribe \ -F fileaudio.wav \ -F languageauto \ -F use_itntrue让我拆解一下这个命令的各个部分-X POST指定使用POST方法http://localhost:7860/api/transcribe这是转写接口的地址-F fileaudio.wav上传音频文件符号后面跟的是本地文件路径-F languageauto设置语言为自动检测-F use_itntrue启用逆文本正则化3.2 参数详解在实际使用中你可能需要调整一些参数来获得更好的识别效果。下面我详细说说每个参数的作用file参数这是必填参数指定要转写的音频文件。支持多种常见格式WAV格式audio.wavMP3格式audio.mp3M4A格式audio.m4aFLAC格式audio.flac文件大小建议控制在100MB以内过大的文件可能需要分段处理。language参数这个参数控制识别语言有几个选项auto自动检测语言推荐zh中文en英语yue粤语ja日语ko韩语如果你知道音频的具体语言直接指定语言代码可以获得更准确的识别结果。如果不确定就用auto让模型自己判断。use_itn参数ITN是Inverse Text Normalization的缩写中文叫逆文本正则化。这个功能很实用它能把口语化的数字、单位等转换成标准的书面形式。举个例子口语说三点五ITN会转成3.5口语说百分之二十ITN会转成20%口语说二零二三年ITN会转成2023年对于会议记录、访谈整理这类场景建议开启ITN功能这样生成的文字更规范。3.3 实际调用示例下面我举几个实际场景的例子你可以根据自己的需要参考使用。示例1转写中文会议录音curl -X POST http://localhost:7860/api/transcribe \ -F filemeeting.wav \ -F languagezh \ -F use_itntrue示例2转写英文播客curl -X POST http://localhost:7860/api/transcribe \ -F filepodcast.mp3 \ -F languageen \ -F use_itnfalse示例3自动检测多语言视频音频curl -X POST http://localhost:7860/api/transcribe \ -F filevideo.m4a \ -F languageauto \ -F use_itntrue3.4 处理返回结果调用成功后你会得到一个JSON格式的响应。响应内容通常包含这些信息{ text: 转写后的文字内容, language: 检测到的语言代码, duration: 10.5, segments: [ { start: 0.0, end: 2.5, text: 第一段文字 }, { start: 2.5, end: 5.0, text: 第二段文字 } ] }各个字段的含义text完整的转写文本language检测到的语言比如zh、en等duration音频时长单位是秒segments分段信息包含每段的开始时间、结束时间和文本内容如果你只需要完整的文字直接取text字段就行。如果需要时间戳信息比如做字幕文件就用segments里的数据。4. 使用Python调用API4.1 直接使用SDK除了通过HTTP接口SenseVoice还提供了Python SDK用起来更直观。首先确保你已经安装了funasr-onnx包然后可以这样使用from funasr_onnx import SenseVoiceSmall # 初始化模型 model SenseVoiceSmall( model_dir/root/ai-models/danieldong/sensevoice-small-onnx-quant, batch_size10, quantizeTrue ) # 单文件转写 result model([audio.wav], languageauto, use_itnTrue) print(result[0][text]) # 批量转写多个文件 results model([audio1.wav, audio2.mp3, audio3.m4a], languagezh) for res in results: print(res[text])这种方式的优点是直接在Python环境里运行不需要启动HTTP服务适合集成到现有的Python项目中。4.2 通过requests库调用HTTP接口如果你已经在运行HTTP服务或者需要在不同的服务之间调用用requests库会更方便import requests import json def transcribe_audio(file_path, languageauto, use_itnTrue): 调用语音转写API Args: file_path: 音频文件路径 language: 语言代码默认auto use_itn: 是否启用逆文本正则化默认True Returns: 转写结果字典 url http://localhost:7860/api/transcribe with open(file_path, rb) as f: files {file: f} data { language: language, use_itn: str(use_itn).lower() } response requests.post(url, filesfiles, datadata) if response.status_code 200: return response.json() else: print(f请求失败: {response.status_code}) print(response.text) return None # 使用示例 result transcribe_audio(meeting.wav, languagezh) if result: print(f识别结果: {result[text]}) print(f检测语言: {result[language]}) print(f音频时长: {result[duration]}秒)4.3 处理长音频文件实际使用中你可能会遇到比较长的音频文件比如一两个小时的会议录音。直接上传大文件可能会超时这时候可以分段处理import wave import math def split_audio(file_path, segment_duration300): 将长音频分割成小段 Args: file_path: 音频文件路径 segment_duration: 每段时长单位秒默认5分钟 Returns: 分段文件路径列表 # 这里需要根据实际音频格式处理 # 可以使用pydub、librosa等库 # 简化示例实际使用时需要完整实现 pass def transcribe_long_audio(file_path, languageauto): 转写长音频文件 Args: file_path: 音频文件路径 language: 语言代码 Returns: 完整的转写文本 # 分割音频 segments split_audio(file_path) all_text [] for segment_file in segments: result transcribe_audio(segment_file, languagelanguage) if result and result[text]: all_text.append(result[text]) # 合并结果 full_text .join(all_text) return full_text4.4 错误处理与重试在实际应用中网络波动、服务暂时不可用等情况都可能发生加上适当的错误处理和重试机制能让程序更健壮import time from requests.exceptions import RequestException def transcribe_with_retry(file_path, max_retries3, retry_delay2): 带重试机制的语音转写 Args: file_path: 音频文件路径 max_retries: 最大重试次数 retry_delay: 重试延迟单位秒 Returns: 转写结果或None for attempt in range(max_retries): try: result transcribe_audio(file_path) if result: return result except RequestException as e: print(f第{attempt 1}次尝试失败: {e}) if attempt max_retries - 1: print(f{retry_delay}秒后重试...) time.sleep(retry_delay) else: print(达到最大重试次数放弃) return None # 使用示例 result transcribe_with_retry(important_meeting.wav, max_retries5) if result: print(转写成功) else: print(转写失败请检查网络或服务状态)5. 实际应用场景5.1 会议记录自动化对于经常需要开会的团队来说手动整理会议纪要是个苦差事。用SenseVoice可以轻松实现会议记录自动化import os from datetime import datetime class MeetingTranscriber: def __init__(self, api_urlhttp://localhost:7860/api/transcribe): self.api_url api_url def transcribe_meeting(self, audio_file, output_dirmeeting_notes): 转写会议录音并保存为文本 Args: audio_file: 会议录音文件 output_dir: 输出目录 # 创建输出目录 os.makedirs(output_dir, exist_okTrue) # 转写音频 result transcribe_audio(audio_file, languagezh) if not result: print(转写失败) return # 生成文件名 timestamp datetime.now().strftime(%Y%m%d_%H%M%S) output_file os.path.join(output_dir, fmeeting_{timestamp}.txt) # 保存结果 with open(output_file, w, encodingutf-8) as f: f.write(f会议记录 - {timestamp}\n) f.write( * 50 \n\n) f.write(result[text]) print(f会议记录已保存到: {output_file}) return output_file # 使用示例 transcriber MeetingTranscriber() transcriber.transcribe_meeting(weekly_meeting.wav)5.2 视频字幕生成做视频内容的朋友都知道加字幕是个体力活。用这个服务可以快速生成字幕文件def generate_subtitles(audio_file, output_srt, languageauto): 生成SRT格式字幕文件 Args: audio_file: 音频文件 output_srt: 输出SRT文件路径 language: 语言代码 result transcribe_audio(audio_file, languagelanguage) if not result or segments not in result: print(转写失败或没有分段信息) return with open(output_srt, w, encodingutf-8) as f: for i, segment in enumerate(result[segments], 1): start_time format_time(segment[start]) end_time format_time(segment[end]) text segment[text] f.write(f{i}\n) f.write(f{start_time} -- {end_time}\n) f.write(f{text}\n\n) def format_time(seconds): 将秒数格式化为SRT时间格式 Args: seconds: 秒数 Returns: HH:MM:SS,mmm格式的时间字符串 hours int(seconds // 3600) minutes int((seconds % 3600) // 60) secs int(seconds % 60) millis int((seconds - int(seconds)) * 1000) return f{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d} # 使用示例 generate_subtitles(video_audio.wav, subtitles.srt, languagezh)5.3 多语言内容处理如果你的内容涉及多种语言SenseVoice的自动语言检测功能就派上用场了def process_multilingual_content(audio_files): 处理多语言音频内容 Args: audio_files: 音频文件路径列表 Returns: 按语言分类的转写结果 results_by_language {} for audio_file in audio_files: print(f处理文件: {audio_file}) # 使用自动语言检测 result transcribe_audio(audio_file, languageauto) if result: language result[language] text result[text] if language not in results_by_language: results_by_language[language] [] results_by_language[language].append({ file: audio_file, text: text }) print(f 检测到语言: {language}) print(f 转写长度: {len(text)}字符) return results_by_language # 使用示例 audio_files [chinese.wav, english.mp3, japanese.m4a] results process_multilingual_content(audio_files) for lang, items in results.items(): print(f\n{lang}语言内容:) for item in items: print(f 文件: {item[file]}) print(f 内容: {item[text][:100]}...) # 只显示前100字符6. 性能优化与最佳实践6.1 批量处理技巧如果你需要处理大量音频文件逐个调用API效率不高。可以试试批量处理import concurrent.futures from typing import List, Dict def batch_transcribe(file_paths: List[str], max_workers: int 4) - Dict[str, str]: 批量转写音频文件 Args: file_paths: 音频文件路径列表 max_workers: 最大并发数 Returns: 文件名到转写结果的映射 results {} def transcribe_single(file_path): try: result transcribe_audio(file_path) return file_path, result[text] if result else None except Exception as e: print(f转写 {file_path} 失败: {e}) return file_path, None # 使用线程池并发处理 with concurrent.futures.ThreadPoolExecutor(max_workersmax_workers) as executor: future_to_file { executor.submit(transcribe_single, file_path): file_path for file_path in file_paths } for future in concurrent.futures.as_completed(future_to_file): file_path, text future.result() if text: results[file_path] text print(f完成: {file_path}) return results # 使用示例 audio_files [faudio_{i}.wav for i in range(1, 11)] results batch_transcribe(audio_files, max_workers5) print(f成功转写 {len(results)}/{len(audio_files)} 个文件)6.2 缓存机制对于重复处理的音频文件可以添加缓存机制减少不必要的API调用import hashlib import pickle import os class CachedTranscriber: def __init__(self, cache_dirtranscription_cache): self.cache_dir cache_dir os.makedirs(cache_dir, exist_okTrue) def get_file_hash(self, file_path): 计算文件哈希值作为缓存键 hasher hashlib.md5() with open(file_path, rb) as f: buf f.read() hasher.update(buf) return hasher.hexdigest() def transcribe_with_cache(self, file_path, languageauto, use_itnTrue): 带缓存的语音转写 Args: file_path: 音频文件路径 language: 语言代码 use_itn: 是否启用ITN Returns: 转写结果 # 生成缓存键 file_hash self.get_file_hash(file_path) cache_key f{file_hash}_{language}_{use_itn} cache_file os.path.join(self.cache_dir, f{cache_key}.pkl) # 检查缓存 if os.path.exists(cache_file): print(f从缓存加载: {file_path}) with open(cache_file, rb) as f: return pickle.load(f) # 调用API转写 print(f调用API转写: {file_path}) result transcribe_audio(file_path, languagelanguage, use_itnuse_itn) # 保存到缓存 if result: with open(cache_file, wb) as f: pickle.dump(result, f) return result # 使用示例 transcriber CachedTranscriber() result transcriber.transcribe_with_cache(frequently_used.wav)6.3 服务质量监控在生产环境中使用最好加上一些监控指标import time from collections import deque from datetime import datetime class TranscriptionMonitor: def __init__(self, window_size100): self.response_times deque(maxlenwindow_size) self.success_count 0 self.failure_count 0 self.start_time time.time() def record_request(self, successTrue, durationNone): 记录请求结果 if success: self.success_count 1 if duration is not None: self.response_times.append(duration) else: self.failure_count 1 def get_stats(self): 获取统计信息 total_requests self.success_count self.failure_count uptime time.time() - self.start_time stats { total_requests: total_requests, success_rate: self.success_count / total_requests if total_requests 0 else 0, avg_response_time: sum(self.response_times) / len(self.response_times) if self.response_times else 0, uptime_hours: uptime / 3600, requests_per_hour: total_requests / (uptime / 3600) if uptime 0 else 0 } return stats def print_report(self): 打印监控报告 stats self.get_stats() print(\n *50) print(语音转写服务监控报告) print(*50) print(f运行时间: {stats[uptime_hours]:.1f} 小时) print(f总请求数: {stats[total_requests]}) print(f成功率: {stats[success_rate]*100:.1f}%) print(f平均响应时间: {stats[avg_response_time]*1000:.1f} ms) print(f请求频率: {stats[requests_per_hour]:.1f} 次/小时) print(*50) # 使用示例 monitor TranscriptionMonitor() # 在每次API调用后记录 start_time time.time() result transcribe_audio(test.wav) duration time.time() - start_time if result: monitor.record_request(successTrue, durationduration) else: monitor.record_request(successFalse) # 定期打印报告 monitor.print_report()7. 总结通过这篇文章你应该已经掌握了SenseVoice-small-onnx语音识别服务的两种调用方式。无论是简单的curl命令还是灵活的Python编程都能轻松接入这个强大的语音转写服务。让我简单总结一下重点curl方式适合快速测试和简单的脚本集成一行命令就能完成语音转写。记住关键参数file指定音频文件language设置语言推荐用auto自动检测use_itn控制是否启用文本规范化。Python方式更适合复杂的应用场景。你可以用SDK直接调用也可以通过requests库访问HTTP接口。Python的优势在于能方便地处理错误、实现批量操作、添加缓存机制还能集成到更大的应用系统中。在实际使用中我有几个小建议对于会议记录、访谈整理这类场景记得开启ITN功能这样数字、百分比等会转换成更规范的格式处理长音频时考虑分段处理避免超时或内存不足如果是生产环境使用加上适当的错误处理和重试机制大量处理时用批量并发的方式能显著提高效率这个服务的识别准确率相当不错特别是对中文的支持很好。多语言自动检测也是个很实用的功能不用手动指定语言就能处理混合内容。最重要的是它完全开源免费部署也简单个人开发者和小团队用起来没什么负担。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

相关新闻