聚焦全球科技前沿动态,深度解读AI、芯片、互联网行业趋势

K100_AI单卡全离线部署同声传译系统_42.228.13.241:5000

K100_AI单卡全离线部署同声传译系统_42.228.13.241:5000 - 图片1

K100_AI单卡全离线部署同声传译系统_42.228.13.241:5000 - 图片2

K100_AI单卡全离线部署同声传译系统_42.228.13.241:5000 - 图片3

一、引言 在全球化交流日益频繁的当下,同声传译已成为国际会议、跨国商务洽谈、学术交流等场景中不可或缺的沟通桥梁。然而,传统同声传译高度依赖专业译员的人力投入,成本高昂且难以规模化覆盖;而现有的云端AI同传方案则受制于网络带宽、数据隐私与延迟波动等问题,在涉密会议、偏远地区或网络受限环境中往往难以落地。如何在保证翻译质量的前提下,实现低延迟、高隐私、全离线的同声传译系统,成为当前AI语音技术领域亟待攻克的关键命题。 本文用K100_AI单卡在全离线环境里完成同声传译系统的部署,用到的ASR模型是Qwen3-ASR-1.7B,该模型作为语音识别旗舰模型,支持52种语言与方言的语种识别与语音识别,并原生支持流式与离线两种推理模式。用到的TTS模型是Qwen3-TTS-12Hz-1.7B-VoiceDesign,该模型创新性地支持通过自然语言描述直接设计音色——无需参考音频、无需预设说话人,即可生成符合场景需求的目标语种语音。用到的文本翻译模式是Qwen3.5-9B。 二、方案设计 系统采用ASR-翻译-TTS三阶段流水线架构,全部运行于单张海光K100_AI算力卡,实现全离线同声传译。语音识别选用Qwen3-ASR-1.7B,支持流式推理与多语种识别,保证低延迟;语音合成选用Qwen3-TTS-12Hz-1.7B-VoiceDesign,支持自然语言描述直接设计音色,无需参考音频。翻译模块采用Qwen3.5-9B模型,三者通过流水线并行调度。 运行时,音频经VAD切分后送入ASR流式识别,文本增量送入翻译模块,译文再实时驱动TTS合成目标语种语音。支持中英日韩法德等多语种切换,VoiceDesign允许用户动态调整语音风格参数。全部推理离线完成,数据不出本地,满足高安全等级部署需求,单卡即可支撑完整同传服务。 三、实施方法及代码 3.1硬件环境 本方案的硬件平台为一台H3C服务器,配置如下: 组件 规格 GPU 8×海光DCU 64GB K100_AI 只需占用一张K100_AI显卡 3.2软件栈 本方案的软件栈基于Docker容器化技术构建,使用经过海光DCU适配的vLLM推理镜像: 镜像一(Qwen3-ASR-1.7B): harbor.sourcefind.cn:5443/dcu/admin/base/custom:vllm0.15.1-ubuntu22.04-dtk26.04-0130-py3.10-20260220 该镜像基于vLLM 0.15.1推理框架、DTK 26.04,Python 3.10环境,单卡部署Qwen3-ASR-1.7B,200ms即可完成语音识别。 镜像二(Qwen3.5-9B): 42.228.13.241:5000/jenkins/model_test_env/vllm:0.21.0-ubuntu22.04-dtk2604-py3.10-20260702-0235 该镜像包含vLLM 0.21推理框架、DTK 26.04、Python 3.10环境,单卡部署Qwen3.5-9B(和ASR、TTS同张单卡部署),平均每秒生成31token。 镜像三(Qwen3-TTS-12Hz-1.7B-VoiceDesign): harbor.sourcefind.cn:5443/dcu/admin/base/custom:vllm018-ubuntu22.04-dtk26.04-nemotron-20260422 该镜像基于vLLM0.18.1和vLLM-omni 0.18.0推理框架、DTK 26.04,Python 3.10环境,单卡部署Qwen3-TTS-12Hz-1.7B-VoiceDesign,平均语音合成延迟低于500ms。 软件项目: 1、Qwen3-ASR-1.7B环境部署参照https://developer.sourcefind.cn/codes/modelzoo/qwen3-asr_pytorch里面操作步骤,项目下载链接为:https://developer.sourcefind.cn/codes/modelzoo/qwen3-asr_pytorch/-/archive/main/qwen3-asr_pytorch-main.zip。 2、Qwen3-TTS-12Hz-1.7B-VoiceDesign环境部署参照https://developer.sourcefind.cn/codes/modelzoo/qwen3-tts_pytorch里面操作步骤,项目下载链接为:https://developer.sourcefind.cn/codes/modelzoo/qwen3-tts_pytorch/-/archive/master/qwen3-tts_pytorch-master.zip。 3、同声传译自编程序代码如下: #!/usr/bin/env python3 """ 以太天枢 · 同声传译独立模块(TTS 流式/非流式无缝播放版) 后端:HTTP 获取 TTS PCM 块(流式或一次性)→ 封装为 WAV 片段 → WebSocket 推送 前端:Web Audio API 解码并精确调度,实现无缝连续播放 修改:流式 TTS 不再封装为 WAV,直接传输原始 PCM;前端同步创建 AudioBuffer。 新增:VAD 静音持续时间前端可调;TTS 播放时是否静音麦克风可选项。 """ import eventlet import sys if 'gunicorn' not in sys.modules: eventlet.monkey_patch() import json import os import io import wave import time import base64 import struct import threading from collections import defaultdict from concurrent.futures import ThreadPoolExecutor import numpy as np import requests from flask import Flask, render_template_string, request from flask_socketio import SocketIO, emit from scipy import signal HISTORY_FILE = "history.json" history_lock = threading.Lock() def load_server_history(): if not os.path.exists(HISTORY_FILE): return [] try: with open(HISTORY_FILE, 'r', encoding='utf-8') as f: return json.load(f) except Exception: return [] def append_server_history(record): with history_lock: history = load_server_history() history.append(record) # 保留最近 500 条 if len(history) > 500: history = history[-500:] with open(HISTORY_FILE, 'w', encoding='utf-8') as f: json.dump(history, f, ensure_ascii=False, indent=2) # ========== 配置处理 ========== CONFIG_FILE = "config.json" DEFAULT_CONFIG = { "asr_api_url": "http://192.168.222.65:8084/v1/audio/transcriptions", "asr_model": "Qwen3-ASR-1.7B", "asr_api_key": "PassWord@123456", "asr_sample_rate": 16000, "asr_frame_duration": 30, "asr_vad_mode": 1, "asr_silence_thresh": 15, "ai_api_url": "http://192.168.222.65:8085/v1/chat/completions", "ai_model": "Qwen3.5-9B", "ai_api_key": "PassWord@123456", "tts_api_url": "http://192.168.222.65:8086/v1/audio/speech", "tts_model": "Qwen3-TTS-12Hz-1.7B-VoiceDesign", "tts_api_key": "PassWord@123456", "tts_sample_rate": 24000, "tts_stream_mode": False, "vad_energy_threshold": 0.04, "vad_silence_duration": 0.5, # 默认静音持续0.5秒切分 "vad_max_speech_sec": 15, "noise_words": [ "ok.", "Yeah.", "hmm", "uh", "um", "ah", "oh", "mhm", "嗯。", "啊", "哦" ] } def load_config(): if os.path.exists(CONFIG_FILE): try: with open(CONFIG_FILE, 'r', encoding='utf-8') as f: cfg = json.load(f) for k, v in DEFAULT_CONFIG.items(): cfg.setdefault(k, v) return cfg except Exception: return DEFAULT_CONFIG.copy() else: return DEFAULT_CONFIG.copy() config = load_config() ASR_API_URL = config["asr_api_url"] ASR_MODEL = config["asr_model"] ASR_API_KEY = config["asr_api_key"] ASR_SAMPLE_RATE = config["asr_sample_rate"] ASR_FRAME_DURATION = config["asr_frame_duration"] ASR_VAD_MODE = config["asr_vad_mode"] ASR_SILENCE_THRESH = config["asr_silence_thresh"] AI_API_URL = config["ai_api_url"] AI_MODEL = config["ai_model"] AI_API_KEY = config["ai_api_key"] TTS_API_URL = config["tts_api_url"] TTS_MODEL = config["tts_model"] TTS_API_KEY = config["tts_api_key"] TTS_SAMPLE_RATE = config.get("tts_sample_rate", 24000) ENERGY_THRESHOLD = config.get("vad_energy_threshold", 0.04) SILENCE_DURATION_SEC = config.get("vad_silence_duration", 0.5) # 默认全局值,但会被每个会话覆盖 MAX_SPEECH_SEC = config.get("vad_max_speech_sec", 15) NOISE_WORDS = set(config.get("noise_words", [])) executor = ThreadPoolExecutor(max_workers=10) asr_session = requests.Session() if ASR_API_KEY: asr_session.headers['Authorization'] = f'Bearer {ASR_API_KEY}' app = Flask(__name__) app.secret_key = os.urandom(24).hex() socketio = SocketIO(app, async_mode='eventlet', cors_allowed_origins="*", ping_timeout=60, ping_interval=25, max_http_buffer_size=10 * 1024 * 1024) # 会话结构新增 vad_silence_duration,用于动态调整 VAD 静音阈值 sessions = defaultdict(lambda: { 'vad': { 'voiced_frames': b'', 'silence_duration': 0.0, 'speaking': False, 'speech_duration': 0.0, 'energy_threshold': ENERGY_THRESHOLD }, 'language_pair': { 'source': 'auto', 'target': 'zh' }, 'enable_tts': False, 'tts_stream_mode': config.get("tts_stream_mode", False), 'voice_instructions': '请用年轻女性的嗓音,自然、亲切地朗读以下内容。', 'stop_event': threading.Event(), 'lock': threading.Lock(), 'vad_silence_duration': SILENCE_DURATION_SEC # 可动态修改 }) def is_noise_text(text): t = text.strip().lower().rstrip('.') return t in NOISE_WORDS def transcribe_audio(wav_bytes): try: resp = asr_session.post( ASR_API_URL, files={'file': ('audio.wav', io.BytesIO(wav_bytes), 'audio/wav')}, data={'model': ASR_MODEL, 'prompt': '解析为简体中文'}, timeout=10 ) resp.raise_for_status() result = resp.json() return result.get('text', '').strip() except Exception as e: print(f"ASR 请求失败: {e}") return "" def translate_text(text, source_lang, target_lang): if not text: return "" system_prompt = ( f"你是一个专业翻译引擎。只将用户输入的文本从{source_lang}翻译成{target_lang}," "只输出译文,不要添加任何解释或额外内容。" ) if source_lang == 'auto': system_prompt = ( "你是一个专业翻译引擎。自动检测用户输入的语言,并将其翻译成" f"{target_lang}。只输出译文,不要添加任何解释或额外内容。" ) messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": text} ] headers = { "Authorization": f"Bearer {AI_API_KEY}", "Content-Type": "application/json" } payload = { "model": AI_MODEL, "messages": messages, "max_tokens": 1024, "temperature": 0.3, "stream": False, "chat_template_kwargs": {"enable_thinking": False} } try: resp = requests.post(AI_API_URL, headers=headers, json=payload, timeout=200) resp.raise_for_status() data = resp.json() return data['choices'][0]['message']['content'].strip() except Exception as e: print(f"翻译请求失败: {e}") return f"[翻译错误: {e}]" def synthesize_speech(sid, text, instructions, stream_mode=False): """ 合成语音并发送给客户端。 - 非流式:一次性获取完整 PCM,封装为 WAV 后发送(兼容性更好)。 - 流式:直接发送原始 PCM 块(16-bit 单声道小端序),避免 WAV 头导致的边界问题。 """ headers = { "Authorization": f"Bearer {TTS_API_KEY}", "Content-Type": "application/json" } payload = { "model": TTS_MODEL, "input": text, "instructions": instructions, "task_type": "VoiceDesign", "response_format": "pcm", "stream": stream_mode, "sample_rate": TTS_SAMPLE_RATE } try: resp = requests.post( TTS_API_URL, headers=headers, json=payload, stream=True, timeout=30 ) if resp.status_code != 200: print(f"TTS 请求失败 [{resp.status_code}]: {resp.text[:100]}") return socketio.emit('tts_stream_start', {'sample_rate': TTS_SAMPLE_RATE}, room=sid) if stream_mode: # 流式:直接发送 raw PCM (16-bit little-endian) for chunk in resp.iter_content(chunk_size=4096): if not chunk: break # 确保 chunk 长度为偶数(2字节一个样本) if len(chunk) % 2 != 0: chunk = chunk[:-1] # 丢弃最后一个不完整字节 if not chunk: continue audio_b64 = base64.b64encode(chunk).decode('utf-8') socketio.emit('tts_audio_chunk', {'audio': audio_b64}, room=sid) else: # 非流式:仍然使用 WAV 封装(一次性发送,保证兼容) full_pcm = resp.content if full_pcm: wav_io = io.BytesIO() with wave.open(wav_io, 'wb') as wf: wf.setnchannels(1) wf.setsampwidth(2) wf.setframerate(TTS_SAMPLE_RATE) wf.writeframes(full_pcm) wav_bytes = wav_io.getvalue() audio_b64 = base64.b64encode(wav_bytes).decode('utf-8') socketio.emit('tts_audio_chunk', {'audio': audio_b64}, room=sid) socketio.emit('tts_stream_end', {}, room=sid) except Exception as e: print(f"TTS 调用异常: {e}") socketio.emit('tts_stream_end', {}, room=sid) def process_audio_segment(sid, pcm_bytes): if not pcm_bytes: return wav_io = io.BytesIO() with wave.open(wav_io, 'wb') as wf: wf.setnchannels(1) wf.setsampwidth(2) wf.setframerate(ASR_SAMPLE_RATE) wf.writeframes(pcm_bytes) wav_bytes = wav_io.getvalue() text = transcribe_audio(wav_bytes) if not text or is_noise_text(text): return socketio.emit('asr_text', {'text': text}, room=sid) session = sessions[sid] lang = session['language_pair'] translated = translate_text(text, lang['source'], lang['target']) if translated: socketio.emit('translated_text', {'text': translated}, room=sid) if session['enable_tts'] and translated: synthesize_speech(sid, translated, session['voice_instructions'], stream_mode=session['tts_stream_mode']) # 新增:保存到服务端文件 executor.submit(append_server_history, { "time": time.strftime("%Y-%m-%d %H:%M:%S"), "original": text, "translated": translated }) # ========== WebSocket 事件 ========== @socketio.on('connect') def on_connect(): emit('connected', {'sid': request.sid}) @socketio.on('disconnect') def on_disconnect(): sessions.pop(request.sid, None) @socketio.on('clear_audio_state') def on_clear_audio_state(): sid = request.sid sessions[sid]['vad'] = { 'voiced_frames': b'', 'silence_duration': 0.0, 'speaking': False, 'speech_duration': 0.0, 'energy_threshold': ENERGY_THRESHOLD } # 注意:不清除 vad_silence_duration @socketio.on('set_language') def on_set_language(data): sid = request.sid sessions[sid]['language_pair'] = { 'source': data.get('source', 'auto'), 'target': data.get('target', 'zh') } @socketio.on('set_tts') def on_set_tts(data): sid = request.sid sessions[sid]['enable_tts'] = data.get('enable', False) sessions[sid]['tts_stream_mode'] = data.get('stream_mode', False) instructions = data.get('voice_instructions') if instructions: sessions[sid]['voice_instructions'] = instructions # 新增:动态调整 VAD 静音持续时间(秒) @socketio.on('set_vad_silence_duration') def on_set_vad_silence_duration(data): sid = request.sid duration = data.get('duration', 0.5) # 限制范围 0.2 ~ 2.5 duration = max(0.2, min(2.5, duration)) sessions[sid]['vad_silence_duration'] = duration emit('log_message', {'message': f'✅ VAD 静音阈值已设为 {duration:.1f} 秒'}, room=sid) @socketio.on('calibrate_noise_result') def on_calibrate_noise_result(data): sid = request.sid rms = data.get('rms', 0.01) new_threshold = max(rms * 1.5, 0.01) sessions[sid]['vad']['energy_threshold'] = new_threshold emit('log_message', {'message': f'✅ 校准完成:底噪RMS {rms:.4f},语音阈值设为 {new_threshold:.4f}'}, room=sid) @socketio.on('audio_chunk') def on_audio_chunk(data): sid = request.sid session = sessions[sid] vad_state = session['vad'] threshold = vad_state['energy_threshold'] raw_bytes = bytes(data) if isinstance(data, bytearray) else data if len(raw_bytes) < 4: return original_rate = struct.unpack_from('= threshold: vad_state['voiced_frames'] += pcm_frame vad_state['silence_duration'] = 0.0 vad_state['speech_duration'] += frame_duration if not vad_state['speaking']: vad_state['speaking'] = True else: if vad_state['speaking']: vad_state['voiced_frames'] += pcm_frame vad_state['silence_duration'] += frame_duration if (vad_state['silence_duration'] >= silence_dur_thresh or vad_state['speech_duration'] >= MAX_SPEECH_SEC): segment_bytes = vad_state['voiced_frames'] vad_state['voiced_frames'] = b'' vad_state['silence_duration'] = 0.0 vad_state['speaking'] = False vad_state['speech_duration'] = 0.0 if segment_bytes: executor.submit(process_audio_segment, sid, segment_bytes) @app.route('/') def index(): return render_template_string(INTERPRETER_HTML) # ========== HTML 模板(增加 VAD 滑块 和 TTS 麦克风静音选项) ========== INTERPRETER_HTML = ''' 以太天枢 · 同声传译 ⚡ 以太天枢 · 同声传译 🟡 未连接 🌐 语言设置 🔊 语音合成 (TTS) 启用 TTS 流式播放 🔇 TTS 播放时静音麦克风 🎤 VAD 静音持续时间 0.5 秒 🎤 控制 📜 历史记录 🚀 准备就绪,请点击“开始实时传译” ''' print("=" * 50) print("🌐 以太天枢 · 同声传译 服务启动中...") print(" 访问地址: http://localhost:5001 gunicorn -k eventlet -w 1 同声传译:app --bind 0.0.0.0:5001") print(" ASR 模型:", ASR_MODEL) print(" 翻译模型:", AI_MODEL) print(" TTS 模型:", TTS_MODEL, "(默认流式关闭,播放完毕自动恢复麦克风)") print(" 新增: VAD 静音持续时间可调 (0.2~2.5秒)") print(" 新增: TTS 播放时麦克风静音选项") print("=" * 50) if __name__ == '__main__': socketio.run(app, host='0.0.0.0', port=5001, debug=False) 3.3模型下载与准备 1、Qwen3-ASR-1.7B(语音识别模型): 下载链接:https://modelscope.cn/models/Qwen/Qwen3-ASR-1.7B/files 2、Qwen3.5-9B(语言翻译模型): 下载链接:https://modelscope.cn/models/Qwen/Qwen3.5-9B/files 3、Qwen3-TTS-12Hz-1.7B-VoiceDesign(语音合成模型) 下载链接: https://modelscope.cn/models/Qwen/Qwen3-TTS-12Hz-1.7B-VoiceDesign/files 3.4 模型启动参数 1、Qwen3-ASR-1.7B启动参数: cat Qwen3-ASR-1.7B.sh HIP_VISIBLE_DEVICES=6 vllm serve '/home/models/Qwen3-ASR-1.7B' \ --trust-remote-code \ --gpu-memory-utilization 0.3 \ --limit-mm-per-prompt '{"audio": 1}' \ --port 8084 \ --served-model-name Qwen3-ASR-1.7B \ --api-key PassWord@123456 2、Qwen3.5-9B启动参数: cat Qwen3.5-9B.sh #!/bin/bash export VLLM_SPEC_DECODE_EAGER=1 export VLLM_MLA_DISABLE=0 export VLLM_USE_FLASH_MLA=1 export VLLM_RPC_TIMEOUT=1800000 export HIP_VISIBLE_DEVICES=6 export ALLREDUCE_STREAM_WITH_COMPUTE=1 # 海光CPU绑定核,通过hy-smi --showtopo参考numa节点 export VLLM_NUMA_BIND=1 export VLLM_RANK0_NUMA=0 export VLLM_RANK1_NUMA=0 export VLLM_RANK2_NUMA=0 export VLLM_RANK3_NUMA=0 export VLLM_RANK4_NUMA=0 export VLLM_RANK5_NUMA=0 export VLLM_RANK6_NUMA=0 export VLLM_RANK7_NUMA=0 export NCCL_MAX_NCHANNELS=16 export NCCL_MIN_NCHANNELS=16 vllm serve "/home/models/Qwen3.5-9B" \ --gpu-memory-utilization 0.4 \ --port 8085 \ --max-model-len 32768 \ --max-num-seqs 32 \ --served-model-name Qwen3.5-9B \ --tensor-parallel-size 1 \ --enable-auto-tool-choice \ --tool-call-parser qwen3_xml \ --trust-remote-code \ --enable-prefix-caching \ --enable-chunked-prefill \ --api-key PassWord@123456 3、Qwen3-TTS-12Hz-1.7B-VoiceDesign启动参数: cat Qwen3-TTS-12Hz-1.7B-VoiceDesign.sh HIP_VISIBLE_DEVICES=6 vllm-omni serve /home/models/Qwen3-TTS-12Hz-1.7B-VoiceDesign \ --stage-configs-path qwen3-tts_pytorch-master/qwen3_tts.yaml \ --gpu-memory-utilization 0.1 \ --omni \ --port 8086 \ --trust-remote-code \ --enforce-eager \ --served-model-name Qwen3-TTS-12Hz-1.7B-VoiceDesign cat qwen3-tts_pytorch-master/qwen3_tts.yaml async_chunk: true stage_args: - stage_id: 0 stage_type: llm is_comprehension: true runtime: devices: "0" engine_args: model_stage: qwen3_tts max_num_seqs: 10 model_arch: Qwen3TTSTalkerForConditionalGeneration worker_type: ar scheduler_cls: vllm_omni.core.sched.omni_ar_scheduler.OmniARScheduler enforce_eager: false trust_remote_code: true async_scheduling: true enable_prefix_caching: false engine_output_type: latent gpu_memory_utilization: 0.1 distributed_executor_backend: "mp" max_num_batched_tokens: 512 max_model_len: 4096 custom_process_next_stage_input_func: vllm_omni.model_executor.stage_input_processors.qwen3_tts.talker2code2wav_async_chunk # Use named connector to apply runtime.connectors.extra. output_connectors: to_stage_1: connector_of_shared_memory default_sampling_params: temperature: 0.9 top_k: 50 max_tokens: 4096 seed: 42 detokenize: false repetition_penalty: 1.05 stop_token_ids: [2150] - stage_id: 1 stage_type: llm runtime: devices: "0" engine_args: model_stage: code2wav max_num_seqs: 1 model_arch: Qwen3TTSCode2Wav worker_type: generation scheduler_cls: vllm_omni.core.sched.omni_generation_scheduler.OmniGenerationScheduler enforce_eager: true trust_remote_code: true async_scheduling: true enable_prefix_caching: false engine_output_type: audio gpu_memory_utilization: 0.3 distributed_executor_backend: "mp" # Must be divisible by num_code_groups and cover (left_context + chunk). max_num_batched_tokens: 8192 # async_chunk appends windows per step; max_model_len must cover accumulated stream. max_model_len: 32768 engine_input_source: [0] final_output: true final_output_type: audio # Distributed connector configuration input_connectors: from_stage_0: connector_of_shared_memory tts_args: max_instructions_length: 500 default_sampling_params: temperature: 0.0 top_p: 1.0 top_k: -1 max_tokens: 65536 seed: 42 detokenize: true repetition_penalty: 1.0 runtime: enabled: true defaults: window_size: -1 max_inflight: 1 connectors: connector_of_shared_memory: name: SharedMemoryConnector extra: shm_threshold_bytes: 65536 # Frame-aligned codec streaming transport. codec_streaming: true # Connector polling / timeout (unit: loop count, sleep interval in seconds). connector_get_sleep_s: 0.01 connector_get_max_wait_first_chunk: 3000 connector_get_max_wait: 300 # Align with Omni: small chunks with sufficient context overlap. codec_chunk_frames: 25 codec_left_context_frames: 25 edges: - from: 0 to: 1 window_size: -1 qwen3_tts.yaml参数一定要注意设置:engine_args:gpu_memory_utilization: 0.1 四、运行测试 1、启动Qwen3-ASR-1.7B docker exec -it qwen3-asr bash cd /home/models/ nohup ./Qwen3-ASR-1.7B.sh & 2、启动Qwen3.5-9B docker exec -it vllm0.21-new bash cd /home/models/ nohup ./Qwen3.5-9B.sh & 3、启动Qwen3-TTS-12Hz-1.7B-VoiceDesign docker exec -it qwen3-tts bash cd /home/models/ nohup ./Qwen3-TTS-12Hz-1.7B-VoiceDesign.sh & 4、启动同声传译自编程序 root@:/opt# source audio-MCP/bin/activate (audio-MCP) root@:/opt# gunicorn -k eventlet -w 1 同声传译-TTS流式切换-手机版:app --bind 0.0.0.0:5001 /opt/audio-MCP/lib/python3.13/site-packages/gunicorn/workers/geventlet.py:10: EventletDeprecationWarning: Eventlet is deprecated. It is currently being maintained in bugfix mode, and we strongly recommend against using it for new projects. If you are already using Eventlet, we recommend migrating to a different framework. For more detail see https://eventlet.readthedocs.io/en/latest/asyncio/migration.html import eventlet [2026-07-05 13:57:01 +0800] [3858228] [INFO] Starting gunicorn 22.0.0 [2026-07-05 13:57:01 +0800] [3858228] [INFO] Listening at: http://0.0.0.0:5001 (3858228) [2026-07-05 13:57:01 +0800] [3858228] [INFO] Using worker: eventlet [2026-07-05 13:57:01 +0800] [3858229] [INFO] Booting worker with pid: 3858229 1 RLock(s) were not greened, to fix this error make sure you run eventlet.monkey_patch() before importing any other modules. ================================================== 🌐 以太天枢 · 同声传译 服务启动中... 访问地址: http://localhost:5001 gunicorn -k eventlet -w 1 同声传译:app --bind 0.0.0.0:5001 ASR 模型: Qwen3-ASR-1.7B 翻译模型: Qwen3.5-9B TTS 模型: Qwen3-TTS-12Hz-1.7B-VoiceDesign (默认流式关闭,播放完毕自动恢复麦克风) 新增: VAD 静音持续时间可调 (0.2~2.5秒) 新增: TTS 播放时麦克风静音选项 ================================================== 5、访问同声传译自编程序 用谷歌浏览器访问,访问之前需要做安全授权设置: 地址栏执行:chrome://flags/ 搜索:Insecure origins treated as secure 填入:http://192.168.222.65:5001  #根据实际的URL填写 然后访问:http://192.168.222.65:5001 先执行噪音校准,获取背景噪声。根据说话人的语速调整VAD静音持续时间,语速越快,该时间就越小。