Files
ViGent2/Docs/DevLogs/Day28.md
Kevin Wong 0e3502c6f0 更新
2026-02-27 16:11:34 +08:00

9.3 KiB
Raw Permalink Blame History

CosyVoice FP16 加速 + 文档更新 + AI改写界面重构 + 标题字幕面板重排与视频帧预览 (Day 28)

概述

CosyVoice 3.0 声音克隆服务开启 FP16 半精度推理,预估提速 30-40%。同步更新 4 个项目文档。重构 AI 改写文案界面RewriteModal 两步流程 + ScriptExtractionModal 逻辑抽取)。前端将"标题与字幕"面板从第二步移至第四步(素材编辑之后),样式预览窗口背景从紫粉渐变改为视频片头帧截图,实现所见即所得。


改动内容

1. CosyVoice FP16 半精度加速

  • 问题: CosyVoice 3.0 以 FP32 全精度运行RTF (Real-Time Factor) 约 0.9-1.35x,生成 2 分钟音频需要约 2 分钟
  • 根因: AutoModel() 初始化时未传入 fp16=TrueLLM 推理和 Flow Matching (DiT) 均在 FP32 下运行
  • 修复: 一行改动开启 FP16 自动混合精度
# 旧: _model = AutoModel(model_dir=str(MODEL_DIR))
# 新:
_model = AutoModel(model_dir=str(MODEL_DIR), fp16=True)
  • 生效机制: CosyVoice3Modelllm_job()token2wav() 中通过 torch.cuda.amp.autocast(self.fp16) 自动将计算转为 FP16
  • 预期效果:
    • 推理速度提升 30-40%
    • 显存占用降低 ~30%
    • 语音质量基本无损0.5B 模型 FP16 精度充足)
  • 验证: 服务重启后自检通过,健康检查 ready: true

2. 文档全面更新 (4 个文件)

补充 Day 27 新增的 MuseTalk 混合唇形同步方案、性能优化、Remotion 并发渲染等内容到所有相关文档。

README.md

  • 项目描述更新为 "LatentSync 1.6 + MuseTalk 1.5 混合唇形同步"
  • 唇形同步功能描述改为混合方案(短视频 LatentSync长视频 MuseTalk
  • 技术栈表新增 MuseTalk 1.5
  • 项目结构新增 models/MuseTalk/
  • 服务架构表新增 MuseTalk (端口 8011)
  • 文档中心新增 MuseTalk 部署指南链接
  • 性能优化描述新增降频检测 + Remotion 16 并发

DEPLOY_MANUAL.md

  • GPU 分配说明更新 (GPU0=MuseTalk+CosyVoice, GPU1=LatentSync)
  • 步骤 3 拆分为 3a (LatentSync) + 3b (MuseTalk)
  • 环境变量表新增 7 个 MuseTalk 变量,移除过时的 DOUYIN_COOKIE
  • LatentSync 推理步数默认值 20→16
  • 测试运行新增 MuseTalk 启动终端
  • PM2 管理新增 MuseTalk 服务(第 5 项)
  • 端口检查、日志查看命令新增 8011/vigent2-musetalk

SUBTITLE_DEPLOY.md

  • 技术架构图更新为 LatentSync/MuseTalk 混合路由
  • 新增唇形同步路由说明
  • Remotion 配置表新增 concurrency 参数 (默认 16)
  • GPU 分配说明更新
  • 更新日志新增 v1.3.0 条目

BACKEND_README.md

  • 健康检查接口描述更新为含 LatentSync + MuseTalk + 混合路由阈值
  • 环境变量配置新增 MuseTalk 相关变量
  • 服务集成指南新增"唇形同步混合路由"章节

3. AI 改写文案界面重构

RewriteModal 重构

将 AI 改写弹窗改为两步式流程,提升交互体验:

第一步 — 配置与触发

  • 自定义提示词输入(可选),自动持久化到 localStorage
  • "开始改写"按钮触发 /api/ai/rewrite 请求

第二步 — 结果对比与选择

  • 上方AI 改写结果 + "使用此结果"按钮(紫粉渐变色,醒目)
  • 下方:原文对比 + "保留原文"按钮(灰色低调)
  • 底部:可"重新改写"(重回第一步,保留自定义提示词)
  • ESC 快捷键关闭

ScriptExtractionModal 逻辑抽取

将文案提取模态框的全部业务逻辑抽取到独立 hook useScriptExtraction

  • useScriptExtraction.ts (新建): 管理 URL/文件双模式输入、拖拽上传、提取请求、步骤状态机 (config → processing → result)、剪贴板复制
  • ScriptExtractionModal.tsx: 纯展示组件,消费 hook 返回值,新增 ESC/Enter 快捷键

ScriptEditor 工具栏调整

  • 按钮组右对齐 (justify-end),统一高度 h-7 和圆角
  • "历史文案"按钮用灰色 (bg-gray-600) 区分辅助功能
  • "文案提取助手"用紫色 (bg-purple-600) 表示主功能
  • "AI多语言"用绿渐变 (emerald-teal)"AI生成标题标签"用蓝渐变 (blue-cyan)
  • "AI智能改写"和"保存文案"移至文本框下方状态栏

4. 标题字幕面板重排 + 视频帧背景预览

面板顺序重排

<TitleSubtitlePanel> 从第二步移至第四步(素材编辑之后),使用户在设置标题字幕样式时已经完成了素材选择和时间轴编排。

新顺序:

一、文案提取与编辑(不变)
二、配音(原三)
三、素材编辑(原四)
四、标题与字幕(原二)→ 移到素材编辑之后

新建 useVideoFrameCapture hook

从视频 URL 截取 0.1s 处帧画面,返回 JPEG data URL

  • 创建 <video> 元素,设置 crossOrigin="anonymous"(素材存储在 Supabase Storage 跨域地址)
  • 先绑定 loadedmetadata / canplay / seeked / error 事件监听,再设 src避免事件丢失
  • loadedmetadatacanplay 触发后 seek 到 0.1sseeked 回调中用 canvas drawImage 截帧
  • canvas 缩放到 480px 宽再编码(预览窗口最大 280px节省内存
  • canvas.toDataURL("image/jpeg", 0.7) 导出
  • 防御 videoWidth/videoHeight 为 0 的边界情况
  • try-catch 防 canvas taint失败返回 null降级渐变
  • isActive 标志 + seeked 去重标志防止 stale 和重复更新
  • 截图完成后清理 video 元素释放内存

按需截取(性能优化)

只在样式预览窗口打开时才触发截取:

const materialPosterUrl = useVideoFrameCapture(
  showStylePreview ? firstTimelineMaterialUrl : null
);

截取源优先使用时间轴第一段素材(用户拖拽排序后的真实片头),回退到 selectedMaterials[0](未生成配音、时间轴为空时)。

预览背景替换

FloatingStylePreview 有视频帧时直接显示原始画面(不加半透明,保证颜色真实),文字靠描边保证可读性;无视频帧时降级为原紫粉渐变背景。

踩坑记录

  1. CORS tainted canvas: 素材文件存储在 Supabase Storage (api.hbyrkj.top),是跨域签名链接。必须设 video.crossOrigin = "anonymous" 才能让 canvas toDataURL 不被 SecurityError 拦截
  2. 时间轴为空: useTimelineEditoraudioDuration <= 0(未选配音)时返回空数组,需回退到 selectedMaterials[0]
  3. 事件监听顺序: 必须先绑定事件监听再设 video.src,否则快速加载时事件可能丢失

📁 修改文件清单

文件 改动
models/CosyVoice/cosyvoice_server.py AutoModel() 新增 fp16=True 参数
README.md 混合唇形同步描述、技术栈、服务架构、项目结构更新
Docs/DEPLOY_MANUAL.md MuseTalk 部署步骤、环境变量、PM2 管理、端口检查
Docs/SUBTITLE_DEPLOY.md 架构图、Remotion concurrency、GPU 分配、更新日志
Docs/BACKEND_README.md 健康检查、环境变量、混合路由章节
frontend/.../RewriteModal.tsx 两步式改写流程(自定义提示词 → 结果对比)
frontend/.../script-extraction/useScriptExtraction.ts 新建 — 文案提取逻辑 hook
frontend/.../ScriptExtractionModal.tsx 纯展示组件,消费 hook新增快捷键
frontend/.../ScriptEditor.tsx 工具栏右对齐 + 按钮分色 + 改写/保存移至底部
frontend/.../useVideoFrameCapture.ts 新建 — 视频帧截取 hookcrossOrigin + canvas 缩放
frontend/.../useHomeController.ts 新增 useMemo 计算素材 URL调用帧截取 hookshowStylePreview 门控
frontend/.../HomePage.tsx 面板重排(二↔四互换),编号更新,透传 materialPosterUrl
frontend/.../TitleSubtitlePanel.tsx 编号"二"→"四",新增 previewBackgroundUrl prop
frontend/.../FloatingStylePreview.tsx 新增 previewBackgroundUrl prop条件渲染视频帧/渐变背景

🔍 验证

  • CosyVoice 重启成功,健康检查 {"ready": true}
  • 自检推理通过7.2s for "你好"
  • FP16 通过 torch.cuda.amp.autocast(self.fp16) 在 LLM 和 Flow Matching 阶段生效
  • npx tsc --noEmit — 零错误
  • AI 改写:自定义提示词持久化 → 改写结果 + 原文对比 → "使用此结果"/"保留原文"
  • 文案提取URL / 文件双模式 → 处理中动画 → 结果填入
  • 面板顺序:一→文案、二→配音、三→素材编辑、四→标题与字幕
  • 样式预览背景:有素材时显示真实视频片头帧,无素材降级紫粉渐变
  • 预览关闭时不触发截取,不浪费资源

💡 CosyVoice 性能分析备注

当前性能基线 (FP32, 优化前)

文本长度 音频时长 推理耗时 RTF
42 字 9.8s 13.2s 1.35x
89 字 18.2s 20.3s 1.12x
~530 字 115.8s 107.7s 0.93x
~670 字 143.5s 131.6s 0.92x

未来可选优化(收益递减,暂不实施)

优化项 预期提升 复杂度
TensorRT (DiT 模块) +20-30% 需编译 .plan 引擎
torch.compile() +10-20% 一行代码,但首次编译慢
vLLM (LLM 模块) +10-15% 额外依赖