Files
product/visual-chat-task-list.md
T
2026-03-27 10:49:34 +08:00

26 KiB
Raw Blame History

智能可视化语音聊天系统 — 详细任务清单(本机实时版)

目标:在本机(RTX 5090 / WSL2)实现"浏览器访问 → WebRTC 传输 → 单工语音对话 → 数字人口型同步"的实时可用系统。
基础environments.mdresearch-notes.md 中已验证的环境、模型和踩坑修复全部复用。
最后更新2026-03-25 — 经过逐组件可行性硬核验证后修订(第三版)。


0. 逐组件可行性验证报告(执行前必读)

0.1 组件全景审计表

组件 选型 许可证 纯本地 RTX 5090 验证 实时性证据 风险等级
VAD Silero VAD 6.x MIT 是(CPU) N/A(纯CPU) 流式 VADIterator32ms 帧级延迟
ASR SenseVoice-Small (FunASR) Apache 2.0 是(GPU) 已有用户确认 cu128 可跑 中文 CER 4.2%CPU 14x实时,GPU 更快
LLM 在线 API (OpenAI 兼容) N/A 否(设计如此) N/A 流式,首 token ~0.5-1.5s 中(网络)
TTS Kokoro-82M-v1.1-zh Apache 2.0 是(GPU) 确认支持 CUDA 12.8 RTX 50 系 210x实时(4090)<2GB VRAM
TTS 升级 Qwen3-TTS 0.6B Apache 2.0 是(GPU) 确认可跑,需 torch.compile 优化 97ms 首音频,RTF<0.25(优化后)
口型 MuseTalk v1.5 MIT 是(GPU) 已在你机器验证通过 30fps+(V100)RTX 5090 更快 中(需改流式)
头动底片 LivePortrait MIT 是(离线预处理) 已在你机器验证通过 离线,无实时要求
WebRTC aiortc BSD-3-Clause N/A(纯Python) asyncio 原生,H.264 已优化

结论:全部组件均为开源许可(MIT / Apache 2.0 / BSD-3),全部可本地运行,全部有 RTX 5090 兼容路径。

0.2 两个致命问题及修正

问题一:faster-whisper 中文识别率灾难

faster-whisper large-v3-turbo SenseVoice-Small
中文 WER/CER WER 77%(几乎不可用) CER 4.2%(优秀)
中文方言 不支持 7 大方言 + 26 种口音
推理速度(GPU) ~50x 实时 RTF 0.0076130x 实时)
模型大小 ~1.5GB ~234MB
许可证 MIT Apache 2.0

决定:ASR 从 faster-whisper 改为 SenseVoice-Small。 faster-whisper 的 turbo 模型砍掉了 28/32 层 decoder,导致中文(需要更复杂解码的语言)准确率暴跌,完全不可接受。

问题二:CosyVoice2 实际延迟远超宣传

宣传值 开源版实测值(社区)
流式首块延迟 150ms 1 - 4.5 秒
原因 阿里云预训练音色,无特征提取 开源 zero-shot 需提取 token/embedding
流式实现 优化的 chunk 流 累积式 chunk1A, 2A, 3A...),无 KV cache

决定:TTS 从 CosyVoice2 改为 Kokoro-82M(快速启动) + Qwen3-TTS 0.6B(质量升级路径)。

0.3 修正后的端到端延迟预算

阶段 选型 预估延迟 数据来源
VAD 尾部检测 Silero VAD ~300ms 默认 silence_duration_ms=300
ASR 转写(3s) SenseVoice-Small GPU ~50-150ms RTF 0.00763s × 0.0076 ≈ 23ms + 开销
LLM 首 token 在线流式 ~500-1500ms 取决于模型/网络
TTS 首音频块 Kokoro-82M ~20-50ms 210x 实时 on 4090
MuseTalk 首帧批 MuseTalk batch=4 ~100-200ms 30fps+ → 4帧 ≈ 130ms
WebRTC 编码传输 aiortc H.264 ~50-100ms 软编码
合计 ~1.0 - 2.3s

比上版预算更优,因为 SenseVoice 比 faster-whisper 更快,Kokoro 比 CosyVoice2 快一个数量级。

0.4 GPU 显存预算(RTX 5090 = 32GB

模型 精度 VRAM 常驻
MuseTalk (UNet + VAE + Whisper) fp16 ~3-4GB
SenseVoice-Small fp16 ~0.8GB
Kokoro-82M fp16 ~1.5GB
PyTorch CUDA 上下文 ~1GB 固定
合计 ~6-7GB

32GB VRAM 用不到 1/4,若后续升级 Qwen3-TTS 0.6B+3GB)仍有充裕余量。

0.5 "开源可控"确认清单

组件 许可证 可商用 代码仓库 离线可用
Silero VAD MIT github.com/snakers4/silero-vad
SenseVoice-Small Apache 2.0 github.com/FunAudioLLM/SenseVoice
Kokoro-82M Apache 2.0 github.com/hexgrad/kokoro
Qwen3-TTS Apache 2.0 github.com/QwenLM/Qwen3-TTS
MuseTalk v1.5 MIT github.com/TMElyralab/MuseTalk
LivePortrait MIT github.com/KlingTeam/LivePortrait
aiortc BSD-3 github.com/aiortc/aiortc

零云端依赖(LLM 除外,且 LLM 有本地兜底),零非开源组件。

0.6 "稳健落地"保障策略

风险 发生时 保底方案 切换成本
SenseVoice 在 nightly PyTorch 编译失败 M0 用 MuseTalk 自带 whisper-tiny 做 ASR(精度低但能跑) 改一行 import
Kokoro 中文质量不达标 M1 切 Qwen3-TTS 0.6B(已验证 RTX 5090 可跑) 换一个 TTS 服务封装
Qwen3-TTS RTX 5090 推理慢 M4 torch.compile + CUDA graphs 优化(社区已有方案,RTF<0.25 加 2 行代码
MuseTalk 流式改造困难 M1 先用"分段文件处理"TTS 输出完整 WAV → MuseTalk 批量合成 → 整段播放 延迟增加 2-3s 但可用
在线 LLM 不可用 运行时 本地预设话术兜底,8s 超时自动触发 已内建
aiortc 软编码瓶颈 M2 改用 ffmpeg + NVENC 硬编码管道 约 1 天工作量

1. 总体架构

1.1 系统拓扑

浏览器 (Chrome)
   │
   │ WebRTC (ICE/DTLS/SRTP)
   │
   ▼
┌─────────────────────────────────────────────────────┐
│              webrtc-gateway (aiortc + FastAPI)       │
│  ┌──────────┐              ┌──────────────────────┐ │
│  │ 上行音频 │              │ 下行视频 + 音频轨    │ │
│  └────┬─────┘              └──────────▲───────────┘ │
└───────┼───────────────────────────────┼─────────────┘
        │                               │
        ▼                               │
┌──────────────┐                 ┌──────┴──────┐
│  Silero VAD  │                 │   mixer     │
│  (CPU,MIT)   │                 │ (音视频合流) │
└──────┬───────┘                 └──▲───────▲──┘
       │ speech.end                 │       │
       ▼                           │       │
┌──────────────┐            ┌──────┴──┐ ┌──┴──────────┐
│ SenseVoice   │            │MuseTalk │ │ TTS 音频    │
│ ASR (GPU)    │            │ 口型渲染│ │ (Kokoro)    │
│ Apache 2.0   │            │ (GPU)   │ │ Apache 2.0  │
└──────┬───────┘            │ MIT     │ └──────▲──────┘
       │ text               └────▲────┘        │
       ▼                        │ wav          │ text
┌──────────────┐          ┌─────┴──────┐       │
│ LLM Client   │──text──▶│ Kokoro TTS ├───────┘
│ (在线 API)   │          │ (GPU)      │
└──────────────┘          └────────────┘

1.2 单工状态机

         speech.start              speech.end
  ┌────┐ ──────────▶ ┌──────────────┐ ────────▶ ┌──────────┐
  │IDLE│             │USER_SPEAKING │            │THINKING  │
  └──▲─┘ ◀────────── └──────────────┘            └────┬─────┘
     │   barge-in                                     │ tts.ready
     │   (用户抢话)                                    ▼
     │               ┌─────────────────┐         ┌────────────────┐
     └───────────────│                 │◀────────│AVATAR_SPEAKING │
       playback.done │  (回到 IDLE)    │         └────────────────┘
                     └─────────────────┘

状态规则

  • IDLE:数字人播放闭嘴循环视频,下行静音
  • USER_SPEAKING:数字人立即切闭嘴循环(如正在说话则中断),录音开始
  • THINKING:录音结束,ASR → LLM → TTS 管线启动,数字人继续闭嘴循环
  • AVATAR_SPEAKINGMuseTalk 输出帧 + TTS 音频同步下发
  • 任何状态下检测到 speech.start → 立即跳转 USER_SPEAKINGbarge-in

1.3 进程内通信(不用消息中间件)

单机单进程,所有模块通过 asyncio.Queueasyncio.Event 通信,延迟最低:

audio_chunk_queue: asyncio.Queue[bytes]      # VAD → ASR
text_queue: asyncio.Queue[str]               # ASR → LLM
tts_chunk_queue: asyncio.Queue[bytes]        # LLM→TTS → mixer
avatar_frame_queue: asyncio.Queue[np.ndarray] # TTS→MuseTalk → mixer
state_event: asyncio.Event                    # 状态变更通知

2. 环境与依赖

2.1 创建统一 conda 环境

conda create -n digital-human python=3.10 -y
conda activate digital-human
conda install -y -c conda-forge ffmpeg

# PyTorch nightlyRTX 5090 必须,已验证版本)
pip install --pre torch torchvision torchaudio \
  --index-url https://download.pytorch.org/whl/nightly/cu128

2.2 安装各模块依赖

# MuseTalk 依赖链(按 research-notes.md 已验证)
cd /home/xsl/work/MuseTalk
pip install -r requirements.txt
pip install --no-build-isolation chumpy
pip install mmengine
MMCV_WITH_OPS=1 pip install mmcv==2.1.0 --no-build-isolation
pip install "mmdet>=3.3.0" "mmpose>=1.3.0"
pip install xtcocotools json-tricks munkres
pip install "transformers>=4.45.0"

# ASR - SenseVoice
pip install funasr

# TTS - Kokoro
pip install kokoro soundfile

# TTS 升级备选 - Qwen3-TTSM4 阶段再装)
# pip install qwen3-tts

# VAD
pip install silero-vad

# WebRTC + Web 服务
pip install aiortc aiohttp uvicorn fastapi

# 工具库
pip install pydantic python-dotenv tenacity numpy opencv-python-headless

2.3 模型权重

模型 路径 状态 大小
MuseTalk v1.5 全套 /home/xsl/work/MuseTalk/models/ 已有 5.5GB
LivePortrait 权重 /home/xsl/work/LivePortrait/pretrained_weights/ 已有 1.2GB
SenseVoice-Small 首次调用自动下载 新增 ~234MB
Kokoro-82M-v1.1-zh 首次调用自动下载 新增 ~180MB
Silero VAD 首次调用自动下载 自动 ~2MB
# SenseVoice 模型会在首次 AutoModel() 调用时自动下载
# Kokoro 模型会在首次 import kokoro 时自动下载
# 也可以手动预下载:
python -c "from funasr import AutoModel; AutoModel(model='FunAudioLLM/SenseVoiceSmall', device='cuda:0')"
python -c "import kokoro; kokoro.KPipeline(lang_code='z')"

2.4 MuseTalk 补丁(必须,已验证)

torch.load(weights_only=False) monkey patch — 保持 research-notes.md 中已验证的方案。

2.5 验收清单

  • python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name())" → True, NVIDIA GeForce RTX 5090
  • SenseVoice 加载模型 + 转写一段中文音频成功
  • Kokoro 合成一句中文语音成功
  • MuseTalk 单样例推理输出视频成功

3. VAD 语音活动检测(Silero VAD, MIT

3.1 实现

from silero_vad import load_silero_vad, VADIterator

model = load_silero_vad()
vad_iterator = VADIterator(
    model,
    threshold=0.5,
    sampling_rate=16000,
    min_silence_duration_ms=300,  # 尾部静音判定
    speech_pad_ms=30,
)

# 流式处理 WebRTC 上行音频帧
for audio_chunk in webrtc_audio_stream:
    speech_dict = vad_iterator(audio_chunk)
    if speech_dict:
        if 'start' in speech_dict:
            arbitrator.on_speech_start()
        if 'end' in speech_dict:
            arbitrator.on_speech_end(recorded_audio)

3.2 验收

  • 静音环境不误触发
  • 正常说话稳定触发
  • 说话结束后 ~300ms 内检测到 speech.end

4. ASR 语音识别(SenseVoice-Small, Apache 2.0, 本地 GPU

4.1 模型加载

from funasr import AutoModel
from funasr.utils.postprocess_utils import rich_transcription_postprocess

asr_model = AutoModel(
    model="FunAudioLLM/SenseVoiceSmall",
    device="cuda:0",
    hub="hf",
)

4.2 推理接口

async def transcribe(audio_array: np.ndarray) -> str:
    """16kHz mono float32 numpy array → 文本"""
    res = asr_model.generate(
        input=audio_array,
        cache={},
        language="zh",
        use_itn=True,
    )
    return rich_transcription_postprocess(res[0]["text"])

4.3 性能预期

  • AISHELL-1 中文 CER: 4.2%(比 whisper-turbo 的 77% WER 好一个量级)
  • 3 秒语音推理延迟: ~50-150ms (GPU)
  • VRAM: ~0.8GB

4.4 验收

  • 10 条中文测试语音,转写准确率主观 > 90%
  • 单段 3 秒语音延迟 < 300ms

5. LLM 对话(在线 API,流式输出)

5.1 客户端实现

import openai

client = openai.AsyncOpenAI(
    api_key=os.getenv("LLM_API_KEY"),
    base_url=os.getenv("LLM_BASE_URL"),
)

async def chat_stream(messages: list[dict]) -> AsyncIterator[str]:
    response = await client.chat.completions.create(
        model=os.getenv("LLM_MODEL", "gpt-4o-mini"),
        messages=messages,
        stream=True,
        max_tokens=150,
        temperature=0.7,
    )
    async for chunk in response:
        if chunk.choices[0].delta.content:
            yield chunk.choices[0].delta.content

5.2 流式分句送 TTS

  • LLM 流式输出 token → 累积到句子边界(。!?,\n)→ 立即送 TTS
  • 系统提示词要求"用简短口语回复,每句不超过 30 字"

5.3 降级策略

  • 超时 8s 或网络错误 → 返回预设兜底话术
  • tenacity 做 1 次快速重试(2s 超时)

5.4 验收

  • 正常首 token < 2 秒
  • 断网 3 秒内返回兜底话术
  • 20 轮对话上下文连贯

6. TTS 语音合成(Kokoro-82M, Apache 2.0, 本地 GPU

6.1 模型加载

import kokoro

pipeline = kokoro.KPipeline(lang_code='z')  # z = 中文

6.2 合成接口

async def synthesize(text: str) -> tuple[np.ndarray, int]:
    """文本 → (audio_array, sample_rate)"""
    generator = pipeline(text, voice='zf_xiaoxiao')  # 中文女声
    audio_chunks = []
    for _, _, chunk in generator:
        audio_chunks.append(chunk)
    audio = np.concatenate(audio_chunks)
    return audio, 24000  # Kokoro 输出 24kHz

6.3 音频格式对齐

  • Kokoro 输出 24kHz → 需重采样到 16kHz 供 MuseTalk whisper
  • 下行音频可保持 24kHz(WebRTC 支持)

6.4 升级路径(Qwen3-TTS

M4 阶段如果 Kokoro 中文质量不满意,切换到 Qwen3-TTS 0.6B

  • 97ms 首音频延迟
  • 更好的中文自然度
  • 需额外 ~3GB VRAM(总计仍 <10GB
  • RTX 5090 需 torch.compile + CUDA graphs 优化(社区已验证方案)

6.5 验收

  • 40 字中文文本合成延迟 < 500ms
  • 音质清晰,无明显机器感
  • 连续合成 20 句无崩溃

7. 数字人渲染(MuseTalk v1.5, MIT, 本地 GPU

7.1 离线预处理:底片库(一次性)

Step 1: 用 LivePortrait 生成闭嘴自然动作循环视频

conda activate digital-human
cd /home/xsl/work/LivePortrait

for drv in d3.mp4 d6.mp4 d10.mp4; do
  python inference.py \
    -s /path/to/avatar_photo.jpg \
    -d assets/examples/driving/$drv \
    --flag_crop_driving_video \
    -o /home/xsl/product/assets/avatar_loops/
done

Step 2: 用 MuseTalk 预处理(提取 latents/coords/masks → 缓存)

cd /home/xsl/work/MuseTalk
python -m scripts.realtime_inference \
  --inference_config configs/inference/realtime.yaml \
  --version v15 \
  --unet_model_path models/musetalkV15/unet.pth \
  --unet_config models/musetalkV15/musetalk.json

预处理产物缓存后,运行时直接加载,不再需要人脸检测和解析。

7.2 实时口型合成:改造 MuseTalk

核心:将 Avatar.inference() 从完整音频文件改为流式音频 chunk。

class RealtimeAvatar:
    def __init__(self, prepared_data_path):
        # 加载预处理缓存
        self.latents = torch.load(f"{prepared_data_path}/latents.pt")
        self.coords = pickle.load(open(f"{prepared_data_path}/coords.pkl", 'rb'))
        self.frames = [...]   # 预加载原始帧
        self.masks = [...]    # 预加载 mask
        self.frame_idx = 0

    async def process_audio_chunk(self, pcm_16k: np.ndarray) -> list[np.ndarray]:
        """接收 TTS PCM 块 → 返回口型帧列表"""
        whisper_features = audio_processor.get_audio_feature(pcm_16k)
        whisper_chunks = audio_processor.get_whisper_chunk(whisper_features, ...)

        output_frames = []
        for batch in datagen(whisper_chunks, self.latents, batch_size=4):
            pred = unet.model(batch_latent, timesteps, encoder_hidden_states=audio_feat)
            recon = vae.decode_latents(pred)
            for frame in recon:
                blended = blend_frame(frame, self.frame_idx)
                output_frames.append(blended)
                self.frame_idx = (self.frame_idx + 1) % len(self.frames)
        return output_frames

    def get_idle_frame(self) -> np.ndarray:
        """闭嘴循环帧(不过 UNet"""
        frame = self.frames[self.frame_idx % len(self.frames)]
        self.frame_idx = (self.frame_idx + 1) % len(self.frames)
        return frame

7.3 帧率与同步

  • 25fps(与底片一致),每帧 40ms
  • TTS 音频时长 → 计算帧数 → MuseTalk 生成对应数量帧
  • asyncio 定时器控制帧发送节奏

7.4 验收

  • 闭嘴循环 60 秒无卡顿
  • 5 秒 TTS 音频口型帧 200ms 内开始输出
  • 口型同步主观无 >200ms 错位

8. WebRTC 网关与前端

8.1 后端(aiortc + FastAPI, BSD-3

@app.post("/webrtc/offer")
async def webrtc_offer(request: Request):
    params = await request.json()
    offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"])
    pc = RTCPeerConnection()

    video_track = AvatarVideoTrack()   # 从 MuseTalk 帧队列读取
    audio_track = AvatarAudioTrack()   # 从 TTS 音频队列读取
    pc.addTrack(video_track)
    pc.addTrack(audio_track)

    @pc.on("track")
    def on_track(track):
        if track.kind == "audio":
            asyncio.ensure_future(process_incoming_audio(track))

    await pc.setRemoteDescription(offer)
    answer = await pc.createAnswer()
    await pc.setLocalDescription(answer)
    return {"sdp": pc.localDescription.sdp, "type": pc.localDescription.type}

8.2 前端页面(纯 HTML/JS,无框架依赖)

┌──────────────────────────────┐
│         数字人视频            │
│      (WebRTC video 标签)     │
│                              │
├──────────────────────────────┤
│  🎤 正在倾听...              │  ← 状态指示
├──────────────────────────────┤
│  你: "今天天气怎么样?"       │  ← ASR 字幕
│  AI: "今天天气不错呢..."     │  ← LLM 回复字幕
└──────────────────────────────┘
  • 页面加载 → 自动建 WebRTC 连接 → 请求麦克风权限
  • 下行视频+音频 → <video> 标签
  • WebSocket 接收字幕和状态更新
  • 断连 3 秒自动重连

8.3 验收

  • Chrome 打开 3 秒内看到数字人视频
  • 说话后字幕区显示 ASR 文本
  • 刷新页面自动重连

9. 单工仲裁器

class SessionState(Enum):
    IDLE = "idle"
    USER_SPEAKING = "user_speaking"
    THINKING = "thinking"
    AVATAR_SPEAKING = "avatar_speaking"

class Arbitrator:
    def __init__(self):
        self.state = SessionState.IDLE
        self._lock = asyncio.Lock()
        self._cancel = asyncio.Event()

    async def on_speech_start(self):
        async with self._lock:
            if self.state == SessionState.AVATAR_SPEAKING:
                self._cancel.set()
            self.state = SessionState.USER_SPEAKING

    async def on_speech_end(self, audio: bytes):
        async with self._lock:
            self.state = SessionState.THINKING
        asyncio.create_task(self._run_pipeline(audio))

    async def on_playback_done(self):
        async with self._lock:
            if not self._cancel.is_set():
                self.state = SessionState.IDLE

验收

  • 数字人说话中用户插嘴 → 200ms 内停止
  • 连续抢话 20 次无死锁

10. 配置

.env

# LLM
LLM_API_KEY=sk-xxx
LLM_BASE_URL=https://api.openai.com/v1
LLM_MODEL=gpt-4o-mini
LLM_MAX_TOKENS=150
LLM_TIMEOUT=8

# 模型路径(复用现有)
MUSETALK_DIR=/home/xsl/work/MuseTalk
MUSETALK_UNET=/home/xsl/work/MuseTalk/models/musetalkV15/unet.pth
MUSETALK_CONFIG=/home/xsl/work/MuseTalk/models/musetalkV15/musetalk.json

# 服务
WEBRTC_PORT=8080
AVATAR_FPS=25

11. 目录结构

/home/xsl/product/
├── main.py                      # 入口
├── config.py                    # 配置
├── .env
├── requirements.txt
│
├── core/
│   ├── state_machine.py         # 单工仲裁器
│   ├── session.py               # 会话管理
│   └── pipeline.py              # ASR→LLM→TTS→Avatar 编排
│
├── services/
│   ├── vad.py                   # Silero VAD
│   ├── asr.py                   # SenseVoice-Small
│   ├── llm.py                   # LLM 客户端
│   ├── tts.py                   # Kokoro TTS
│   └── avatar.py                # MuseTalk 实时推理
│
├── webrtc/
│   ├── gateway.py               # aiortc 信令
│   ├── video_track.py           # 数字人视频轨
│   └── audio_track.py           # 数字人音频轨
│
├── web/
│   ├── index.html
│   ├── app.js
│   └── style.css
│
├── assets/
│   ├── avatar_loops/            # 预生成闭嘴循环视频
│   └── avatar_prepared/         # MuseTalk 预处理缓存
│
├── scripts/
│   ├── prepare_avatar.sh        # 预处理底片
│   ├── start.sh                 # 一键启动
│   └── smoke_test.py            # 冒烟测试
│
└── docs/
    ├── visual-chat-task-list.md
    ├── environments.md
    └── research-notes.md

12. 里程碑

M0:环境就绪(0.5 天)

  • 创建 digital-human conda 环境
  • 安装全部依赖(PyTorch nightly + MuseTalk + SenseVoice + Kokoro + aiortc
  • 验证四个 GPU 模型可分别加载并推理
  • 验证四个模型可同时常驻 GPU(显存 < 10GB

M1:离线管线串通(2 天)

  • services/asr.pySenseVoice 输入 WAV → 输出文本
  • services/llm.py:输入文本 → 流式输出文本
  • services/tts.py:Kokoro 输入文本 → 输出 WAV
  • services/avatar.pyMuseTalk 输入 WAV → 输出帧序列(失败自动回退简易口型)
  • scripts/smoke_test.py:一段录音走完全链路输出视频文件(当前为文本输入链路,产出 wav + mp4

M2WebRTC + 数字人常驻(2 天)

  • webrtc/gateway.pyaiortc 信令接口
  • webrtc/video_track.py:发闭嘴循环帧
  • webrtc/audio_track.py:发静音
  • web/:前端页面
  • 浏览器可看到数字人循环视频

M3:全链路联调 + 单工(2 天)

  • services/vad.pySilero VAD 处理上行音频
  • core/state_machine.py:仲裁器
  • core/pipeline.py:完整 VAD→ASR→LLM→TTS→MuseTalk→下行
  • barge-in 实现
  • WebSocket 字幕下发

M4:优化与稳定(2 天)

  • 端到端延迟调优(目标 < 3s
  • 1 小时长时间运行测试
  • 显存监控(nvidia-smi 周期采样)
  • LLM 降级测试
  • 评估是否升级 Qwen3-TTS(中文质量对比)
  • 20 轮连续对话压测

补充自动化脚本:

  • scripts/qa_check.py:文本链路压测(支持 20 轮)
  • scripts/llm_fallback_check.pyLLM 断网/超时兜底验证
  • scripts/gpu_monitor.shGPU 利用率与显存采样(CSV
  • scripts/model_probe.pyASR/TTS/VAD 快速加载与推理探测

13. 被排除的方案及原因(决策日志)

方案 排除原因
faster-whisper (大模型中文) 中文 WER 77%,完全不可接受
CosyVoice2 (TTS) 开源版流式首包 1-4.5s,与宣传 150ms 严重不符
edge-tts 依赖微软云服务器,非本地,离线不可用
Fish-Speech S2 许可证限制商用,需单独授权
LatentSync 仅 4fps,无法实时
Redis/ZeroMQ 消息总线 单机单进程无需中间件,asyncio Queue 延迟更低
ChatTTS 流式推理未完全实现,首包延迟不稳定