Qwen3-ASR-0.6B保姆级教程:支持WebSocket实时语音流接入方案
本文介绍了如何在星图GPU平台上自动化部署Qwen3-ASR-0.6B镜像,并构建支持WebSocket实时语音流的语音识别应用。该方案能实现低延迟的语音转文字功能,典型应用场景包括为在线会议或直播提供实时字幕服务,提升交互体验。
Qwen3-ASR-0.6B保姆级教程:支持WebSocket实时语音流接入方案
想不想让你的应用能“听懂”人说话?无论是中文普通话、粤语,还是英语、日语,甚至带点口音,都能准确识别成文字?今天,我们就来手把手教你部署一个功能强大的语音识别模型——Qwen3-ASR-0.6B,并且给它加上一个酷炫的实时语音流识别功能。
这个模型最大的特点就是“小而精悍”。它只有0.6B(6亿)参数,但支持52种语言和方言,识别又快又准。更重要的是,我们今天要实现的方案,能让你通过WebSocket实时传输语音流,就像打电话一样,这边说话,那边文字就出来了,延迟极低,体验丝滑。
无论你是想做一个智能语音助手、会议实时转录工具,还是给直播加字幕,这个教程都能帮你快速搞定。下面,我们就从零开始,一步步搭建起来。
1. 环境准备与快速部署
在开始动手之前,我们先看看需要准备些什么。整个过程非常简单,跟着做就行。
1.1 系统要求与依赖安装
首先,确保你的电脑或服务器环境满足以下基本要求:
- Python版本:建议使用 Python 3.8 到 3.11 之间的版本。
- 操作系统:Linux(如Ubuntu 20.04/22.04)或 macOS 是首选,Windows 系统也可以,但可能需要处理一些额外的依赖问题。
- 内存:至少 4GB 可用内存。模型本身不大,但运行推理和前端需要一些开销。
- 网络:能顺畅访问模型下载源(如 Hugging Face)。
接下来,我们创建一个干净的Python环境并安装核心依赖。打开你的终端或命令行工具,执行以下命令:
# 1. 创建并激活一个新的虚拟环境(可选但推荐)
python -m venv qwen_asr_env
source qwen_asr_env/bin/activate # Linux/macOS
# 对于Windows,使用:qwen_asr_env\Scripts\activate
# 2. 升级pip到最新版本
pip install --upgrade pip
# 3. 安装核心依赖库
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu # 如果是CPU环境
# 如果你有NVIDIA GPU并想使用CUDA,请安装对应的torch CUDA版本,例如:
# pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
pip install transformers qwen3-asr gradio
这里简单解释一下这几个包是干什么的:
torch:PyTorch深度学习框架,是模型运行的基础。transformers:Hugging Face出品的库,提供了加载和使用各种预训练模型的统一接口。qwen3-asr:通义千问官方提供的ASR模型推理工具包,封装了模型加载和推理的复杂逻辑。gradio:一个快速构建机器学习Web界面的库,我们用它来做前端演示。
1.2 一键启动基础版WebUI
依赖装好后,我们先来验证一下模型是否能正常工作。最简单的方法就是运行官方提供的Gradio演示界面。
创建一个新的Python脚本文件,比如叫做 run_basic_demo.py,然后把下面的代码复制进去:
# run_basic_demo.py
import gradio as gr
from qwen3_asr import Qwen3ASRPipeline
# 1. 加载模型管道
# 首次运行会自动从Hugging Face下载模型,请保持网络通畅
print("正在加载Qwen3-ASR-0.6B模型,首次下载可能需要几分钟...")
pipe = Qwen3ASRPipeline.from_pretrained("Qwen/Qwen3-ASR-0.6B")
# 2. 定义处理函数
def transcribe_audio(audio_path):
"""
处理上传的音频文件,将其转换为文字。
audio_path: Gradio上传音频后返回的临时文件路径
"""
if audio_path is None:
return "请先上传或录制一段音频。"
try:
# 调用模型进行识别
result = pipe(audio_path)
# result 是一个字典,其中 'text' 字段就是识别出的文本
transcribed_text = result.get('text', '识别失败')
return transcribed_text
except Exception as e:
return f"识别过程中出现错误:{str(e)}"
# 3. 创建Gradio界面
with gr.Blocks(title="Qwen3-ASR-0.6B 语音识别演示") as demo:
gr.Markdown("# 🎤 Qwen3-ASR-0.6B 语音识别演示")
gr.Markdown("上传一个音频文件(支持wav, mp3等格式)或直接使用麦克风录制,点击识别按钮。")
# 输入组件:音频上传和麦克风录制
audio_input = gr.Audio(sources=["upload", "microphone"], type="filepath", label="输入音频")
# 输出组件:文本框显示识别结果
text_output = gr.Textbox(label="识别结果", lines=5, placeholder="识别出的文字将显示在这里...")
# 按钮:触发识别
submit_btn = gr.Button("开始识别", variant="primary")
# 绑定事件:点击按钮时,调用 transcribe_audio 函数
submit_btn.click(fn=transcribe_audio, inputs=audio_input, outputs=text_output)
# 添加一个清除按钮(可选)
clear_btn = gr.Button("清除")
clear_btn.click(lambda: (None, ""), inputs=None, outputs=[audio_input, text_output])
# 4. 启动Web服务
if __name__ == "__main__":
# share=True 会生成一个可公开访问的临时链接,方便测试
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
# 在浏览器中打开 http://localhost:7860 即可访问
保存文件后,在终端运行它:
python run_basic_demo.py
等待模型加载完成(第一次运行需要下载约1.2GB的模型文件),然后在浏览器中打开 http://localhost:7860,你就能看到一个简单的语音识别界面了。你可以上传一个MP3或WAV文件,或者直接点击麦克风按钮录音,然后点击“开始识别”,文字就会出现在下方的文本框里。
这个基础版本已经能用了,但它是一次性处理整个音频文件。接下来,我们要给它升级,实现“边说话边出字”的实时流式识别。
2. 实现WebSocket实时语音流识别
实时流式识别的核心思想是:建立一个持久的双向通信通道(WebSocket),客户端(比如网页)不断发送一小段一小段的音频数据,服务端收到后立刻识别并返回文字结果。
2.1 搭建WebSocket服务端
我们需要一个能处理WebSocket连接的服务。这里我们使用 websockets 库和 asyncio 异步框架。首先安装额外依赖:
pip install websockets soundfile numpy
然后,创建一个新的服务端脚本 realtime_asr_server.py:
# realtime_asr_server.py
import asyncio
import websockets
import json
import numpy as np
import soundfile as sf
import io
import logging
from typing import Optional
from qwen3_asr import Qwen3ASRPipeline
# 设置日志,方便查看运行状态
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# 全局模型管道(避免重复加载)
_pipeline: Optional[Qwen3ASRPipeline] = None
def get_pipeline():
"""懒加载模型管道"""
global _pipeline
if _pipeline is None:
logger.info("正在加载 Qwen3-ASR-0.6B 模型...")
_pipeline = Qwen3ASRPipeline.from_pretrained("Qwen/Qwen3-ASR-0.6B")
logger.info("模型加载完毕。")
return _pipeline
async def handle_audio_stream(websocket, path):
"""
处理一个WebSocket连接,接收音频流并返回识别结果。
"""
client_ip = websocket.remote_address[0]
logger.info(f"新的客户端连接: {client_ip}")
pipeline = get_pipeline()
# 可以在这里初始化一个流式识别器(如果pipeline支持)
# 目前我们先以非流式模式处理每个音频片段
# 注意:真正的低延迟流式需要模型支持流式推理,这里用片段模拟
try:
async for message in websocket:
# 预期接收到的消息是二进制音频数据(如PCM格式)
if isinstance(message, bytes):
# 1. 将二进制数据转换为numpy数组(假设是16位单声道PCM,采样率16kHz)
# 这是WebRTC等前端库常用的格式
audio_array = np.frombuffer(message, dtype=np.int16).astype(np.float32) / 32768.0
if len(audio_array) == 0:
await websocket.send(json.dumps({"text": "", "error": "收到空音频数据"}))
continue
# 2. 将音频数据保存为临时WAV文件(因为当前pipeline可能接受文件路径)
# 或者,如果pipeline支持直接输入numpy数组就更好了
# 这里我们假设需要保存为文件
import tempfile
import os
sample_rate = 16000 # 假设采样率是16kHz
with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as tmp_file:
temp_wav_path = tmp_file.name
sf.write(temp_wav_path, audio_array, sample_rate, subtype='PCM_16')
# 3. 调用模型识别
try:
result = pipeline(temp_wav_path)
transcribed_text = result.get('text', '')
# 可以返回更多信息,如置信度、时间戳等
response = {
"text": transcribed_text,
"status": "success"
}
except Exception as e:
logger.error(f"识别失败: {e}")
response = {
"text": "",
"status": "error",
"message": str(e)
}
finally:
# 清理临时文件
os.unlink(temp_wav_path)
# 4. 将识别结果发送回客户端
await websocket.send(json.dumps(response))
elif isinstance(message, str):
# 处理文本消息,例如控制命令
data = json.loads(message)
cmd = data.get("command")
if cmd == "reset":
# 可以在这里重置识别状态(如清空上下文)
await websocket.send(json.dumps({"status": "reset_ok"}))
elif cmd == "ping":
await websocket.send(json.dumps({"status": "pong"}))
except websockets.exceptions.ConnectionClosedOK:
logger.info(f"客户端连接正常关闭: {client_ip}")
except Exception as e:
logger.error(f"处理客户端 {client_ip} 时发生错误: {e}")
finally:
logger.info(f"客户端断开连接: {client_ip}")
async def main():
"""
启动WebSocket服务器
"""
# 预加载模型,避免第一个连接等待太久
_ = get_pipeline()
server = await websockets.serve(
handle_audio_stream,
"0.0.0.0", # 监听所有网络接口
8765, # 端口号
ping_interval=20,
ping_timeout=40
)
logger.info("WebSocket实时语音识别服务器已启动,监听 ws://0.0.0.0:8765")
# 保持服务器运行
await server.wait_closed()
if __name__ == "__main__":
asyncio.run(main())
这个服务端做了几件事:
- 启动一个WebSocket服务器,监听8765端口。
- 当客户端连接后,它会持续接收二进制音频数据。
- 将收到的音频数据临时保存为WAV文件。
- 调用Qwen3-ASR模型进行识别。
- 将识别出的文字以JSON格式返回给客户端。
注意:上面的代码是一个简化示例,将每个音频片段单独保存为文件再识别,这在实时性上会有一些延迟。Qwen3-ASR模型本身支持流式推理,最佳实践是使用其流式API,直接处理音频流。为了教程清晰,我们先以此为基础。你可以查阅Qwen3-ASR官方文档,将 pipeline 调用替换为真正的流式处理接口。
2.2 创建带实时识别功能的前端
有了服务端,我们还需要一个网页前端来录音并发送音频流。我们用Gradio来快速构建这个界面,因为它内置了音频录制和WebSocket客户端功能。
创建一个新的脚本 realtime_asr_webui.py:
# realtime_asr_webui.py
import gradio as gr
import asyncio
import websockets
import json
import numpy as np
from threading import Thread
import queue
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# WebSocket服务器地址(根据实际情况修改)
WS_SERVER = "ws://localhost:8765"
class RealtimeASRClient:
"""一个简单的WebSocket客户端,用于管理连接和发送音频"""
def __init__(self, server_url):
self.server_url = server_url
self.websocket = None
self.connected = False
self.message_queue = queue.Queue()
self.receive_thread = None
async def connect(self):
"""连接到WebSocket服务器"""
try:
self.websocket = await websockets.connect(self.server_url, ping_interval=None)
self.connected = True
logger.info("已连接到WebSocket服务器")
# 启动接收线程
self.receive_thread = Thread(target=self._receive_loop, daemon=True)
self.receive_thread.start()
return True
except Exception as e:
logger.error(f"连接失败: {e}")
self.connected = False
return False
def _receive_loop(self):
"""在新线程中运行接收循环"""
async def _async_receive():
try:
async for message in self.websocket:
try:
data = json.loads(message)
# 将收到的消息放入队列,供前端读取
self.message_queue.put(data)
except json.JSONDecodeError:
logger.warning(f"收到非JSON消息: {message}")
except websockets.exceptions.ConnectionClosed:
logger.info("WebSocket连接已关闭")
self.connected = False
except Exception as e:
logger.error(f"接收消息出错: {e}")
self.connected = False
# 在新线程中运行异步函数
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
new_loop.run_until_complete(_async_receive())
async def send_audio_chunk(self, audio_chunk_bytes):
"""发送一段音频数据(bytes)"""
if not self.connected or self.websocket is None:
logger.warning("未连接,无法发送音频")
return False
try:
await self.websocket.send(audio_chunk_bytes)
return True
except Exception as e:
logger.error(f"发送音频失败: {e}")
self.connected = False
return False
async def disconnect(self):
"""断开连接"""
if self.websocket:
await self.websocket.close()
self.connected = False
logger.info("已断开WebSocket连接")
def get_latest_result(self):
"""从队列中获取最新的识别结果(非阻塞)"""
try:
return self.message_queue.get_nowait()
except queue.Empty:
return None
# 创建全局客户端实例
client = RealtimeASRClient(WS_SERVER)
def start_realtime_transcription(audio_input, state):
"""
开始实时转录。
audio_input: Gradio的Audio组件状态(包含采样率、音频数据等)
state: 用于保存识别状态的字典
"""
if audio_input is None:
return "请先点击‘开始录音’按钮。", state
samplerate, audio_data = audio_input
# audio_data 是 (samples, channels) 形状的numpy数组,可能是立体声
# 转换为单声道并确保是float32格式
if len(audio_data.shape) > 1:
audio_data = audio_data.mean(axis=1) # 立体声转单声道
# 这里我们需要将音频数据分块并发送。
# 为了简化演示,我们一次性发送整个录音(模拟流式)。
# 在实际应用中,你应该从Gradio的流式输出中获取实时音频块。
# 将float32的numpy数组转换为16位PCM的bytes
audio_int16 = (audio_data * 32767).astype(np.int16)
audio_bytes = audio_int16.tobytes()
# 在一个新线程中异步发送
async def send_audio():
if not client.connected:
success = await client.connect()
if not success:
return "连接服务器失败,请检查后端服务是否启动。"
sent = await client.send_audio_chunk(audio_bytes)
if sent:
return "音频已发送,等待识别结果..."
else:
return "发送音频失败。"
# 运行异步函数
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
result_msg = loop.run_until_complete(send_audio())
loop.close()
# 等待一小段时间,然后尝试获取结果
import time
time.sleep(1) # 模拟处理时间,实际应等待WebSocket返回
latest = client.get_latest_result()
if latest and latest.get("status") == "success":
transcribed = latest.get("text", "(无识别结果)")
return transcribed, state
else:
return result_msg + " (未收到结果)", state
def stop_transcription(state):
"""停止转录"""
async def disconnect():
await client.disconnect()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(disconnect())
loop.close()
return "已停止实时识别。", state
# 构建Gradio界面
with gr.Blocks(title="Qwen3-ASR 实时语音识别", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# 🎤 Qwen3-ASR-0.6B 实时语音识别演示
**支持WebSocket流式传输,体验低延迟语音转文字**
1. 确保后端WebSocket服务器 (`realtime_asr_server.py`) 正在运行。
2. 点击下方“开始录音”按钮,对着麦克风说话。
3. 点击“发送并识别”按钮,将录音发送到服务器进行实时识别。
4. 识别结果将显示在下方文本框中。
""")
# 状态存储
state = gr.State(value={"recording": False})
with gr.Row():
with gr.Column(scale=1):
# 音频输入组件
audio_source = gr.Audio(
sources=["microphone"],
type="numpy",
label="录制语音",
interactive=True
)
# 控制按钮
with gr.Row():
send_btn = gr.Button("发送并识别", variant="primary")
stop_btn = gr.Button("停止", variant="secondary")
# 服务器状态显示
status_box = gr.Textbox(label="连接状态", value="未连接", interactive=False)
# 一个用于测试连接的按钮
test_btn = gr.Button("测试连接")
with gr.Column(scale=2):
# 实时结果显示
result_box = gr.Textbox(
label="实时识别结果",
placeholder="识别出的文字将实时显示在这里...",
lines=10,
interactive=False
)
# 历史记录(可选)
# history_box = gr.Textbox(label="历史记录", lines=5, interactive=False)
# 按钮事件绑定
send_btn.click(
fn=start_realtime_transcription,
inputs=[audio_source, state],
outputs=[result_box, state]
)
stop_btn.click(
fn=stop_transcription,
inputs=[state],
outputs=[result_box, state]
)
# 测试连接函数
async def test_connection():
try:
# 尝试连接
test_client = RealtimeASRClient(WS_SERVER)
connected = await test_client.connect()
if connected:
await test_client.disconnect()
return "✅ 连接服务器成功!"
else:
return "❌ 连接服务器失败。"
except Exception as e:
return f"❌ 连接出错: {str(e)}"
def test_connection_wrapper():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
result = loop.run_until_complete(test_connection())
loop.close()
return result
test_btn.click(
fn=test_connection_wrapper,
inputs=None,
outputs=status_box
)
# 页面加载时尝试连接
def on_load():
# 这里可以尝试预连接,但Gradio的load事件处理较复杂,我们先不实现
return "请点击‘测试连接’按钮检查服务器状态。"
demo.load(on_load, inputs=None, outputs=status_box)
if __name__ == "__main__":
# 启动Gradio前端,注意不要和WebSocket服务器端口冲突
demo.launch(server_name="0.0.0.0", server_port=7861, share=False)
这个前端界面提供了:
- 一个麦克风录音组件。
- “发送并识别”按钮,用于将录制的音频发送到我们的WebSocket服务器。
- 一个文本框,用于显示服务器返回的识别结果。
- 一个测试连接按钮,用于检查后端服务是否正常。
2.3 运行完整的实时识别系统
现在,让我们把整个系统跑起来。你需要打开两个终端窗口。
终端1:启动WebSocket后端服务
python realtime_asr_server.py
看到“WebSocket实时语音识别服务器已启动,监听 ws://0.0.0.0:8765”的日志,说明后端启动成功。
终端2:启动Gradio前端界面
python realtime_asr_webui.py
在浏览器中打开 http://localhost:7861。
操作步骤:
- 在前端页面,点击“测试连接”按钮,应该显示“✅ 连接服务器成功!”。
- 点击录音组件,允许浏览器使用麦克风,并说几句话(比如“你好,今天天气不错”)。
- 点击“发送并识别”按钮。
- 稍等片刻,识别结果就会显示在“实时识别结果”文本框中。
恭喜!你已经成功搭建了一个支持WebSocket实时语音流识别的系统。虽然当前示例为了清晰,采用的是“录制-发送-识别”的伪实时模式,但你已经掌握了最核心的架构:WebSocket通信、音频数据传输、模型调用。接下来,你可以在此基础上进行优化。
3. 进阶优化与实用技巧
基础功能跑通了,但想让它更实用、更强大?下面分享几个进阶技巧。
3.1 实现真正的低延迟流式识别
上面的例子是发送整段录音。要实现真正的“边说边出字”,需要将音频切成小块(比如每200毫秒)并连续发送。这需要:
- 修改前端:使用Gradio的
stream模式,或者使用专门的音频流库(如pyaudio)在Python中捕获实时音频流,并分块发送。 - 修改后端:使用Qwen3-ASR模型真正的流式推理接口。根据官方文档,
Qwen3ASRPipeline可能支持传入一个音频流迭代器。你需要将接收到的音频块缓存起来,组成一个连续的流喂给模型。
这里提供一个概念性的后端修改思路:
# 伪代码,展示流式处理思路
from qwen3_asr import Qwen3ASRStreamingPipeline
async def handle_real_stream(websocket, path):
pipeline = Qwen3ASRStreamingPipeline.from_pretrained("Qwen/Qwen3-ASR-0.6B")
streamer = pipeline.stream() # 获取一个流式识别器
async for audio_chunk_bytes in websocket:
# 将音频字节转换为模型需要的格式
audio_array = bytes_to_array(audio_chunk_bytes)
# 将音频数据送入流式识别器
streamer.feed(audio_array)
# 尝试获取当前已识别的部分结果
partial_result = streamer.get_partial_text()
if partial_result:
await websocket.send(json.dumps({"partial": partial_result}))
# 音频流结束,获取最终结果
final_result = streamer.finalize()
await websocket.send(json.dumps({"final": final_result}))
具体实现请务必查阅Qwen3-ASR项目的最新文档和示例。
3.2 支持更多音频格式和参数
我们的示例假设音频是16kHz、单声道、16位PCM。但实际应用可能遇到各种格式。
- 格式转换:可以在后端使用
librosa或pydub库进行实时转码。 - 自动检测:从前端发送的音频数据中提取采样率、声道数等信息,并在后端进行相应处理。
# 示例:使用librosa处理不同格式
import librosa
def process_audio_bytes(audio_bytes, original_sr=None):
# 先将bytes加载为numpy数组,假设是原始PCM数据
# 实际情况更复杂,可能需要解析WAV头等信息
# 这里使用librosa的load函数(如果数据是完整文件)
# 对于流式数据,需要更底层的处理
with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as f:
f.write(audio_bytes)
temp_path = f.name
audio, sr = librosa.load(temp_path, sr=16000) # 重采样到16kHz
os.unlink(temp_path)
return audio, sr
3.3 提升系统稳定性
- 错误处理:在网络不稳定、音频数据异常、模型推理失败时,要有完善的错误处理和重试机制。
- 连接管理:管理多个并发的WebSocket连接,避免资源泄漏。
- 日志与监控:记录详细的日志,便于排查问题。可以监控识别延迟、成功率等指标。
3.4 部署到生产环境
对于正式项目,你可能需要考虑:
- 使用ASGI服务器:用
uvicorn或hypercorn来运行WebSocket服务,性能更好。 - 容器化:使用Docker将模型和服务打包,便于部署和扩展。
- API网关:如果需要对外提供API,可以考虑使用FastAPI等框架包装WebSocket端点,并添加认证、限流等功能。
一个简单的FastAPI集成示例:
from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse
app = FastAPI()
# 原有的 handle_audio_stream 函数...
# 将其适配为FastAPI的WebSocket端点
@app.websocket("/ws/asr")
async def websocket_asr_endpoint(websocket: WebSocket):
await websocket.accept()
await handle_audio_stream(websocket, "") # 复用之前的处理函数
然后用Uvicorn运行:uvicorn your_script:app --host 0.0.0.0 --port 8000
4. 总结
通过这个教程,我们完成了一件很酷的事情:将强大的Qwen3-ASR-0.6B语音识别模型,与WebSocket实时通信技术结合起来,搭建了一个低延迟的语音转文字系统。
我们主要做了三件事:
- 环境搭建与基础识别:学会了如何安装依赖、加载模型,并运行一个简单的Gradio界面进行文件识别。
- 实时流式架构:构建了WebSocket服务端和客户端,实现了音频流的实时传输与识别。
- 功能演示与优化方向:实现了一个可运行的演示系统,并探讨了如何向更低延迟、更稳定、更易用的生产级系统演进。
这个方案的价值在哪里?
- 低延迟交互:适用于智能语音助手、实时字幕、会议转录等需要即时反馈的场景。
- 多语言支持:得益于Qwen3-ASR对52种语言和方言的支持,你的应用可以轻松国际化。
- 本地部署:数据无需上传到第三方服务器,隐私和安全更有保障。
- 轻量高效:0.6B的模型在精度和速度间取得了很好的平衡,对硬件要求相对友好。
下一步你可以尝试:
- 查阅Qwen3-ASR官方文档,将后端替换为真正的流式推理接口,实现毫秒级延迟。
- 美化前端界面,增加实时显示识别波形的功能。
- 将服务部署到云服务器,并通过HTTPS/WSS协议提供安全的公网访问。
- 结合大语言模型(LLM),打造一个能听、能说、能思考的完整语音交互应用。
希望这个教程能成为你探索语音AI世界的一块敲门砖。动手试试看,创造出属于你自己的语音应用吧!
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐


所有评论(0)