Skip to content

TTS MultiModel v2.2.2

Choose a tag to compare

@ReSerendipity ReSerendipity released this 22 Sep 01:20
· 135 commits to main since this release
e64d0e6

v2.2.2

三引擎本地 TTS(VoxCPM2 / IndexTTS 2.5 / IndexTTS 2.0)+ FastAPI/htmx 界面 + OpenAI 兼容口。
本版主要是 v2.2.1 之后累积的桌面/便携分发链路 + 一轮发布前置回归的修复。

一定要知道的四条

  1. 干净环境装出来的镜像/便携包此前起不来默认引擎。 vendored VoxCPM 在模块顶层
    from einops import rearrange,而 einops 只在 training extra 里声明过,funasr/modelscope
    又只在 extras 里要它 —— 于是任何按 requirements.txt / [project].dependencies
    装出来的环境(Docker 镜像、便携包)导入 tts-1 引擎就 ModuleNotFoundError。
    开发机永远看不见这件事(einops 从训练链路传递进来了)。现已提为核心依赖,并补上同样缺席的
    addict,另加守卫:核心声明的每个包必须在两份钉版集里都有钉版。
  2. 镜像构建的间歇性失败已根治。 真因不是日志里那条 update-alternatives ... bash-builtins.7.gz
    (它是良性噪声),而是 apt-get update 对「某个索引没抓下来」只报 W: 并返回 0,
    两行之后才炸成 E: Unable to locate package python3.12。现在两段 RUN 都以
    「PPA 索引里真查得到 python3.12」为前置条件,重试 5 轮仍取不到就硬停并给出可操作原因。
  3. IndexTTS 的 device-side assert 已修,且真因不是"第二次引擎切换"。 是预热绕过了串行队列、
    与用户请求并发
    (预热从后台加载线程直接调 engine.infer,用户侧那把 per-engine 信号量管不到它),
    而 IndexTTS 推理不可重入 → 整个 CUDA context 被毒化,同进程后续合成全废。
    修法在引擎层按注册名加锁;真机并发下字节数与串行完全一致(2.5 = 336,642 B / 2.0 = 239,674 B)。
  4. CSRF 防护不再会静默关闭。 以前 data/.csrf_secret 写不出来时只 warning,然后以空密钥
    继续挂中间件(等于把 HMAC 绑定摘掉照常接请求);现在直接拒绝启动并说明怎么修
    (容器/桌面部署要给 data/ 可写卷)。密钥改 0o600 落盘,老文件自动收紧。

安全与依赖台账

  • Dependabot:20 条告警已逐条 triage + 绑定理由 dismiss(open 归零),台账在
    docs/SECURITY_DEPENDABOT_TRIAGE.md。注意:其中 8 条只有 PYSEC 号、没有 GHSA 记录,
    Dependabot 从没为它们开过单 —— 别把"告警清零"当"风险登记完成"。
  • transformers 停在 4.52.1 是实测决定的:indextts 2.0.0 钉 transformers==4.52.1 +
    tokenizers==0.21.0;抬到 4.57.6 时 IndexTTS 2.0/2.5 直接 ImportError(三引擎只剩一个能用)。
    代价按 OSV 实测是 16 个公告,其中 8 条上游根本没有修复版本;已逐条写可达性判据与理由后
    在 pip-audit / Trivy 里绑由头豁免(Trivy 侧带 2026-12-31 到期,pip-audit 没有到期机制,靠文档复审约定)。
  • CodeQL 存量:open 110 → 76,critical 1 → 0,差额逐条对上账;
    分诊表见 docs/SECURITY_CODEQL_TRIAGE.md。
  • 发布物已剔除曾随包分发的本机 HTTPS 私钥(app/cert.pem/key.pem),并加进门禁负向断言。

其它

  • OpenAI 口 tts-1-hd(IndexTTS 2.5)此前必然 500(该口没有参考音频通道),现返回 400 并指明应走哪个端点。
  • 桌面/便携链路:Tauri 壳自绘标题栏与窗口控制、NSIS 安装器(中文安装须知 + 许可页)、
    便携三组件分卷(core/torch/model)+ SHA256SUMS 全覆盖 + 回读校验、增量更新契约、
    完整性自检 Ed25519 签名 + enforce 阻断、篡改模拟门禁。
  • CI 两处"永远绿的假信号"已修:gpu-smoke 的 job 因缺 secret + 零注册 runner 一直 skipped
    而 run 顶层 success(现会 warning + 写进 step summary);镜像内的引擎模块此前从没被导入过(新增探针)。

本次 Release 附带的资产

  • tts_multimodel-2.2.2-py3-none-any.whl(28,375,881 B)
  • tts_multimodel-2.2.2.tar.gz(28,318,388 B)
  • SHA256SUMS.txt(对上述两件;已做回读校验)

两件产物由 python -m build 产出并通过 twine check。
wheel 的 METADATA 现在带 Requires-Dist: einops>=0.7.0 与 Requires-Dist: addict>=2.4.0
(已安装包内核对),所以这条修复对 pip 安装方同样生效,不只是镜像与便携包。

不含 ~26 GB 的便携分卷(core/torch/model)与桌面增量包 —— 那需要
scripts/release_gate.ps1 -ModelDir ... -RuntimeDir ... -TorchWheelDir ... 真实构建并单独确认;
本批改动不含权重变化,重传 13 个 model 分卷是逐字节浪费。
也没有 GPG 分离签名:仓库只配了 1 个 Actions secret(MANIFEST_SIGNING_KEY_B64),
GPG_PRIVATE_KEY 不存在,所以 gpg-signed-release.yml 只会 notice 跳过。
tag 为注解读但不过 GPG 签名 —— 与本仓历史一致(v2.1.0/v2.2.0/v2.2.1 是轻量 tag,
v2.0.1 是无签名的注解 tag),不做无法验证的签名承诺。

版本口径(如实说明)

本批含 43 个 feat: 提交,按 SemVer 应为 2.3.0;仍标 2.2.2 是仓库所有者的显式决定 ——
内容与 2026-09-16 那次建了又撤销的 v2.2.2 tag 属同一批,CHANGELOG 沿用该号。
另:release-please.yml 此前是结构性空转(skip-github-pull-request: true 而仓库从无 release PR,
且 5 个入参被 action 静默忽略、配置文件根本不存在、job 没声明 outputs),
所以本次 Release 是手工打的 tag + 手工建的 Release,不是 CI 自动发的。

已知未覆盖(发版时点的事实,不粉饰)

  • 桌面安装包链路(staging → 7z 分卷 → NSIS)没有任何 workflow 覆盖,本机也无从安装验证;
    上面的"干净环境缺依赖"结论在镜像侧是实测(探针 run 35618578940),在便携侧只到
    "清单缺项"的证据强度。
  • GPU 冒烟(真加载 + 真合成)需要一台带 gpu 标签的 self-hosted runner,本仓库没有注册 runner,
    因此它在 CI 上永远 skipped。真机验收由维护者本人完成。
  • 锁集的"全新 venv 真装"复验(GB 级下载)仍待执行。
  • 新查出、本次未动的一处打包缺口:wheel 里 integrated_app/security/ 只有 .py,
    integrity_manifest.json 与其 .sig.ed25519、签名公钥都没被打进包(已按产物核对)。
    而 integrity_selfcheck.py:166 在清单不存在时只 logger.info("跳过自检") 并返回
    skipped=16 / manifest_signed=False,enforce=True 也不会拦 —— 也就是说
    纯 pip install 那条部署路径上,Ed25519 完整性保护实际从不运行。
    桌面便携包与 Docker 镜像不受影响(两者都另外拷了源码树,所以容器启动探测是绿的)。
    修法两步:补 package-data;并把"enforce 模式下没有清单"从 info 跳过改成硬失败。
    发版当天不改它 —— 它会改变随包内容,且 enforce 行为得在装出来的环境里实测,不是照读代码。