VibeVoice:5.69 万星的语音仓库,删掉了自己的 TTS

VibeVoice:5.69 万星的语音仓库,删掉了自己的 TTS

star 数和仓库里还能跑起来的代码,是两件互不相干的事。

2026-11-10 打开 microsoft/VibeVoice,页面顶部写着 56,901 star、6,401 fork、132 个未关闭 issue。这个仓库是 2025-08-25 建的,到今天 14 个半月,MIT 协议,Python 实现,最后一次代码推送停在 2026-10-08。

这些数字最容易读错的地方在 star:这 5.69 万颗星基本不是投给语音识别(ASR)的。它们绝大部分落在 2025 年 8 月底那两周,投给的是 VibeVoice-1.5B——一个能生成 90 分钟、最多 4 个说话人多轮对话的 TTS 模型。2025-09-05,仓库换了一个只有 9 个文件的提交,把 TTS 的推理路径从 main 上拿掉,README 里留下的理由是一句话:代码被移除,因为我们无法为滥用风险构建足够的防护。今天再 clone 这个仓库,vibevoice/modular/ 下没有 modeling_vibevoice_inference.py,也没有 TTS 的 processor,demo/ 里没有 inference_from_file.py。

我把 README、docs 下四份模型文档、vibevoice/modular/ 的完整模块清单、那个删除提交的 parent 关系、HF 上权重仓库的可用状态都核对了一遍,并把 7.5 Hz 这个帧率自己算了一遍。下面写的是官方文档里不显眼、但直接决定你能不能用它、能用它干什么的东西。

本文提纲

  1. 先看数字:5.69 万星,161 个 commit
  2. 被删掉的那条推理路径,还在 6,401 个 fork 里
  3. 7.5 Hz 是三代模型共用的时间基准
  4. 上下文预算:64K 是怎么算出来的
  5. 模块边界:模型代码在,数据管线不在
  6. ASR 的精度结构:说话人切分强,文本中等
  7. 语言覆盖:非流式 50+,流式 10
  8. CPU 版:I2_S 混合量化,不是 BitNet b1.58
  9. 该怀疑的地方

先看数字:5.69 万星,161 个 commit

把仓库的几个计数放在一起看,会得到一个和"明星开源项目"完全不同的画像。

指标 数值 意味什么
Star 56,901 注意力最高峰在 2025 年 8 月底
Fork 6,401 fork/star = 11.2%,异常地高
Commit 161 14 个半月,平均每月 11 个提交
Issue 249 个(132 个未关) 语义功能讨论远多于真实工单
PR 118 个(45 个已合并) 合并率 38%,剩下 73 个还开着
Watcher 273 与 star 的比例是 1:208

先看 fork 比例。同类项目 fork/star 通常落在 3%–8%,11.2% 属于偏高。偏高有两种解释:一是开发者在改代码,二是开发者在备份。这个仓库的情况明显是后者——TTS 代码被移除后,大量用户 fork 是为了保住自己那一份还能跑的副本。fork 数在这里不是采用度指标,是抢救行为指标。

再看 watcher 和 star 的 208:1。正常项目的 watcher 大概是 star 的 1%–3%,这里是 0.48%。说明绝大多数 star 是一次性的情绪表达,没有转化成"我要跟进这个仓库"。配合 73 个未合并 PR 和最后一次推送停在 2026-10-08(一个月没动代码),可以给这个仓库一个定位:它是发布式仓库,不是活跃开发区。每个模型发一轮,文档和 demo 跟着更新,然后停。你要当推理运行时用,没问题;你要提交 PR 参与开发,大概率排队。

被删掉的那条推理路径,还在 6,401 个 fork 里

那次移除不是 git rm,是换根。

提交 8107244 的 parent 数是 0——它是一个孤儿根提交(orphan root commit),没有父节点。它的文件变更统计是:新增 9 个文件、删除 0 行。这 9 个文件是 LICENSE、96 行的 README.md、177 行的 .gitignore、SECURITY.md,以及 5 张 Figures/ 下的示意图。换句话说,这个提交把一整棵新树挂成了 main 的新起点,历史被切断,而不是在原有历史上做删除记录。

这在工程上是有意为之。如果只是 rm 掉几个目录,git 历史里仍然能 git checkout 回到 8 月底的任何一次提交,克隆后 git log --follow 就能把模型代码捞回来。换成孤儿根提交,新 clone 的人拿到的是一个"从第一天起就没有 TTS"的仓库,历史里翻不到任何可恢复的痕迹。方案文档、模型卡、技术报告都还留着,唯独可执行的代码路径没了。

但 git 的分布式特性决定了这件事只能做到一半。2025-08-25 当天下午 16:22 建的 fork(paperwave/VibeVoice)到现在仍然是 57 个文件,demo/inference_from_file.py 和 vibevoice/modular/modeling_vibevoice_inference.py 都还在,modeling_vibevoice_inference.py 正是那个负责把文本和音色 prompt 拼成输入、跑 diffusion 去噪、再解码成波形的推理封装。微软可以从 main 上拿走代码,拿不走已经落在 6,401 个账号磁盘上的对象。

这条路径对想复现 TTS 的人意味着什么:官方渠道已经断了。HF 上 microsoft/VibeVoice-1.5B 的权重还在(LICENSE 是 MIT),README 的模型表里 Playground 一栏写的是 Disabled,docs/vibevoice-tts.md 还在讲怎么用——但 main 分支上没有能把权重喂进去的 processor,也没有推理脚本。想跑,只能去 fork 里捡,或者自己按论文补一条管线。

7.5 Hz 是三代模型共用的时间基准

这个家族真正的技术资产不是参数量,是那条 7.5 Hz 的时间线。

README 的原话是:连续的声学 tokenizer 和语义 tokenizer,工作在 7.5 Hz 的超低帧率。这个数字不是调出来的,是算出来的:24,000 Hz 采样率经过 8×5×5×4×2×2 = 3,200 倍下采样,24000/3200 = 7.5。也就是每秒钟音频只产生 7.5 个 token,每个 token 覆盖 133 毫秒。

为什么这件事重要,把时长换算一下就很清楚:1 分钟 = 450 帧,10 分钟 = 4,500 帧,60 分钟 = 27,000 帧。如果换成 Whisper 那种 50 Hz 的梅尔帧率做 token,一小时就是 18 万帧,长音频场景在上下文预算上会直接撞墙。7.5 Hz 让"一小时的会议"变成一个语言模型勉强吃得下的序列长度。

生成侧用的是 next-token diffusion:LLM 负责文本上下文和对话流向,diffusion head 负责把声学细节去噪出来。TTS 的 config 里 ddpm_num_inference_steps = 20,也就是每个 133 毫秒的帧要跑 20 步去噪。90 分钟对话 = 40,500 帧 = 810,000 次去噪步骤。这不是"生成慢"的感性描述,是计算量的线性账——时长翻倍,扩散步数就翻倍,这是它必须配 H100 级别的卡、也必须在演示里做流式播放的结构性原因。

这套 tokenizer 加 diffusion head 在仓库里被三代模型复用:TTS-1.5B 用它出声,Realtime-0.5B 用它低延迟出声,ASR-7B 用它做输入的离散化表示(modular_vibevoice_diffusion_head.py 三个模型共用)。所以"删掉 TTS"删的是应用层,底座没动——这也是为什么 ASR 还能在 2026 年继续出新品。家族里五个模型的共用关系是这样:

MERMAID_BLOCK_0

图中虚线框那个节点仍然挂在文档和 HF 权重上,但已经不在可执行路径里。

上下文预算:64K 是怎么算出来的

ASR 文档给的能力是:单次处理最长 60 分钟音频,上下文窗口 64K token。这两个数字是一套账。

60 分钟 = 3,600 秒 × 7.5 Hz = 27,000 个音频 token。一小时的中文或英文演讲,按 150–200 词/分钟算大约 9,000–12,000 词,对应 12,000–18,000 个文本 token。音频加文本总共 39,000–45,000,落在 65,536 以内,还剩大约三分之一余量给 prompt、时间戳标记和说话人标签。所以 64K 不是"随便选了个大数",是"刚好装下一小时会议、留一点余量"。

代价在 KV cache。我按常见的 7B 结构(28 层、4 个 KV 头、head dim 128、FP16)粗算:每 token 的 KV 约为 2 × 28 × 4 × 128 × 2 bytes ≈ 57 KB,64K token 就是 约 3.7 GB 显存,还不含 14 GB 左右的权重和激活。这个数字是我按结构估的,不是官方实测——仓库里没有一行显存占用数据,这是文档的一个空白。

90 分钟那条更极端:40,500 帧,加文本逼近 60K,再加上 20 步扩散的中间激活,这就是为什么 TTS 演示要按段生成而不是一口气吐完。同一套 7.5 Hz 基准,做识别是"一小时的序列不炸",做生成是"一小时的序列 × 20 步",前者是内存压力,后者是算力压力。

Realtime-0.5B 走的是另一条账:8K 上下文,文档给的定位大约是 10 分钟量级。600 秒 × 7.5 = 4,500 个音频 token,加文本约 2,000–3,500,再加对话历史,8K 就满了。这也解释了为什么实时版是 0.5B 而不是 7B——延迟预算不允许更大的模型,上下文也不允许更长的记忆。

这套预算换算还有一层部署成本的含义。7B 权重的 FP16 本体约 14 GB,加上 64K 上下文的 KV,一张 24 GB 卡(4090、L40S、A10 这一级)刚好卡在能跑与不能跑的边界上;如果 batch 大于 1,或者你想并发处理两路会议,就得往 40 GB / 80 GB 走。仓库没有写最低显存要求,只给了"在 NVIDIA PyTorch 容器里装 flash-attn"这条路径——这说明官方的默认假设是"你在有 GPU 的服务器上跑,安装环境你自己搞"。对没有显卡的用户,唯一的门是 BitNet 那条 CPU 路线,代价是掉精度。

模块边界:模型代码在,数据管线不在

把 vibevoice/modular/ 目录列出来,能清楚看到切了哪一刀:

configuration_vibevoice.py            配置(TTS)
configuration_vibevoice_streaming.py  配置(流式)
modeling_vibevoice.py                 TTS 模型结构,22 KB
modeling_vibevoice_asr.py             ASR 模型结构
modeling_vibevoice_streaming.py       流式模型结构
modeling_vibevoice_streaming_inference.py  流式推理封装
modular_vibevoice_diffusion_head.py   diffusion head
modular_vibevoice_text_tokenizer.py   文本 tokenizer
modular_vibevoice_tokenizer.py        声学 / 语义 tokenizer
streamer.py                           流式输出

modeling_vibevoice.py 还在,我读了它的内容:VibeVoiceForConditionalGeneration、SpeechConnector、prediction_head 的 diffusion loss 计算都在,22,454 字节,架构描述完整。也就是说模型的定义没被删。被删的是 processor/ 下的 TTS processor——那一层负责把音频解码成梅尔、切成帧、和文本一起 pad 成模型输入,以及把模型输出的 latent 反解成波形。没有它,权重和结构之间缺一段胶水,理论可以自己补,工程上等于重写一条推理管线。

再看 demo/ 目录现在的样子:vibevoice_realtime_demo.py、vibevoice_realtime_colab.ipynb、vibevoice_asr_inference_from_file.py、vibevoice_asr_streaming_inference_from_file.py、vibevoice_asr_streaming_fastapi_demo.py、asr_demo/、voices/、web/。没有 TTS 的任何入口。而 web/app.py 第一屏的 import 就能看出仓库现在把"可执行的默认路径"给了谁:

from vibevoice.modular.modeling_vibevoice_streaming_inference import (...)
from vibevoice.processor.vibevoice_streaming_processor import (...)

vibevoice_streaming_processor 存在,vibevoice_processor(TTS 那个)不存在。所以这个仓库现在的真实定位是:流式 ASR 的推理运行时 + 三份模型文档。训练和微调只剩 finetuning-asr/(LoRA),TTS 那边一个字都没有。

这个切法对使用者的实际影响是可验证的:官方文档教你 pip install -e . 然后跑 demo,你会发现装完之后能跑的全是 ASR;TTS 的部分文档还留着,链接还指向 HF,但你在本地找不到第二条命令。

ASR 的精度结构:说话人切分强,文本中等

ASR-7B 的定位是"Who / When / What"一体化:一次前向同时给转写文本、说话人归属和时间戳,不做"先 VAD 切段、再 ASR、再聚类说话人"的三段式流水线。这套端到端设计的收益和代价,在官方那张 MLC-Challenge 表里看得很清楚:

数据集 语言 DER cpWER tcpWER WER
MLC-Challenge 平均 11 种 3.42 14.81 15.66 12.07
MLC-Challenge 英语 4.28 11.48 13.02 7.99
MLC-Challenge 葡萄牙语 7.98 29.91 31.65 21.54
AISHELL-4 中文 6.77 24.99 25.35 21.40
AliMeeting 中文 10.92 29.33 29.51 27.40
AMI-IHM 英语 11.92 20.41 20.82 18.81
AMI-SDM 英语 13.43 28.82 29.80 24.65

DER 3.42 是说话人切分错误率,翻成准确率就是 96.6%。WER 12.07 是文本错误率,准确率约 88%。这两个数字放在一起说明一件事:它判断"谁在什么时候说话"的能力,明显强于它听清"说了什么"的能力。

cpWER 14.81 比 WER 高 2.7 个点,这个差值就是"说话人归属错误"贡献的:文本可能听对了,但挂到了错的人身上,在会议记录里这比错字更致命。葡萄牙语的 cpWER 29.91 对 WER 21.54,差了 8.4 个点,说明多说话人葡萄牙语的归属问题特别严重。

远场和重叠语音是另一道坎:AMI-IHM(头戴麦)DER 11.92,AMI-SDM(远场阵列)DER 13.43,1.5 个点的差距是混响和串音。中文会议两项(AISHELL-4 WER 21.40、AliMeeting WER 27.40)都比英语难,这两份都是真实会议录音,有交叠说话、有口音、有口语化重复。

把它和传统三段式流水线并排看,取舍会更清楚。三段式的做法是:VAD 先切出语音段,普通 ASR 逐段转写,再用说话人嵌入聚类做 diarization,最后按时间戳合并。好处是每一段都能单独换模型、单独调阈值,坏处是三处误差会相乘——VAD 漏掉一句,转写就少一句;ASR 的句子边界和聚类的时间边界错开,某个词就会挂到错的人头上;而 cpWER 这类指标恰好惩罚的就是这种错配。VibeVoice-ASR 把三件事放进一次前向,误差不再相乘,但同时失去三个可以单独拧的旋钮:切分灵敏度、热词强度、说话人数量上限。它的 DER 3.42 / WER 12.07 应该被理解为"一次前向的联合结果",而不是"三段式三个模块各自最优"的替代品。

这里有个必须说清楚的事:仓库文档里没有 Whisper 的 DER/WER 对照表。ASR 文档只列自家和 Parakeet/SenseVoice/FunASR 的部分指标(而且只在 CPU 版那张表里),所以"VibeVoice-ASR 比 Whisper 强"这个说法在仓库层面无法验证。能验证的只有反向结论:在 CPU 版那张表里,Whisper 在 Fleurs-en(3.99 vs 5.21)和 Libri-clean(1.98 vs 2.41)上更准。它的卖点不是绝对 WER,是"一次前向拿到带时间戳、带说话人的结构化结果,不用自己拼三段式流水线"。ASR 文档只列自家和 Parakeet/SenseVoice/FunASR 的部分指标(而且只在 CPU 版那张表里),所以"VibeVoice-ASR 比 Whisper 强"这个说法在仓库层面无法验证。能验证的只有反向结论:在 CPU 版那张表里,Whisper 在 Fleurs-en(3.99 vs 5.21)和 Libri-clean(1.98 vs 2.41)上更准。它的卖点不是绝对 WER,是"一次前向拿到带时间戳、带说话人的结构化结果,

语言覆盖:非流式 50+,流式 10

2026-09-03 发布的 VibeVoice-ASR-Streaming-7B 是家族里最新的一个,参数规模和 ASR 一样是 7B,能力描述是"边收边转、支持自定义热词、10 种语言"。文档里的用法有两个:

python demo/vibevoice_asr_streaming_fastapi_demo.py --model_path [checkpoint]
python demo/vibevoice_asr_streaming_inference_from_file.py --model_path [checkpoint] --audio_files [audio]

FastAPI 那个起在 7870 端口,WebSocket 在整段录音期间保持连接,文本边说边出;文件版则按 chunk 打印,加 --context_info "Microsoft,VibeVoice" 可以像非流式模型的热词那样把识别偏置到特定术语上。

有一个细节值得单独拎出来:chunk 大小和 lookahead 不是命令行参数,是从 checkpoint 的 preprocessor_config.json 里读的。官方说法是"一个 checkpoint 永远跑在它训练时用的那个 chunk 上"。这等于承认了流式 ASR 的一个硬约束——分块边界是训练时定死的,你不能自己调 chunk 大小来换延迟,想更快只能换 checkpoint。这也是为什么非流式 50+ 语言、流式只有 10 种:分块训练要为每种语言单独对齐 chunk 边界和 lookahead,语言越多,数据摊得越薄,训出来的收益越差。

对使用者的判断很直接:如果你的场景是多语种会议转写(比如一次会议里中英日混着说),流式版不够用,只能走非流式 60 分钟一次过,代价是没有实时字幕。如果场景是单一语言的实时字幕,流式版可用,但你要接受它只覆盖 10 种语言。还有一点:流式版没有公开的精度表,文档只讲怎么跑,没给 WER/DER——这是比语言覆盖更值得警惕的文档缺口。

CPU 版:I2_S 混合量化,不是 BitNet b1.58

2026-07-23 发布的 VibeVoice-ASR-BitNet 是另一个仓库(microsoft/VibeASR.cpp)里的东西,README 一句"异构量化(I8_S + I2_S)"就带过了。拆开看:

组件 FP16 BitNet 版 压缩比
VAE Tokenizer 1.31 GB 0.65 GB 2.0×
LM Decoder 3.32 GB 0.92 GB 3.6×
合计 4.62 GB 1.58 GB 2.9×

名字叫 BitNet,但这里没有 BitNet b1.58 那套"训练时就约束权重到 {-1,0,1}"的机制。它是训练后量化:tokenizer 走 8-bit(I8_S),语言模型走 2-bit(I2_S),两块不同精度混在一起,所以叫异构。这两件事的区别很重要——BitNet b1.58 的卖点是"从训练开始就省",可以做无损或近无损;I2_S 的卖点是"把已经训好的权重压到 2 bit",一定有精度损失。名字借了势,机制不一样。

精度损失有多大,官方那张 WER 表写得算诚实:

Benchmark 7B FP16 BitNet 差
MLC-EN 7.82 8.25 +0.43
Libri-clean 2.17 2.41 +0.24
Fleurs-en 4.73 5.21 +0.48
AMI-ihm 17.42 21.36 +3.94
AliMeeting 36.21 40.58 +4.37
AISHELL4 19.83 27.45 +7.62

README 的说法是"适度的精度下降(1–4% 绝对 WER 增加)"。这个说法在 AMI、AliMeeting 勉强算成立(+3.94、+4.37 已经压线),在中文 AISHELL-4 上不成立——从 19.83 掉到 27.45,是 +7.62 个绝对点,相对恶化 38%。而且 27.45 这个数字比同表的 SenseVoice(22.52)和 FunASR(20.41)都差:中文场景下,一个专门的中文模型在 CPU 上不仅更快,还更准。

速度是真的。AMD EPYC 7V13(AVX2+FMA,24 核)上,RTF 从单线程 1.58 降到 2 线程 0.84、4 线程 0.46、8 线程 0.27;对比 whisper.cpp 是 2.1–2.7 倍(同一个约 20 秒的音频、稳态测量)。Apple M4 上单线程 0.63,4 线程 0.21;Intel i7-13700 上单线程 0.93,8 线程 0.33。

这组数字里最有用的不是"比 whisper.cpp 快 2 倍多",是2 线程就进实时。0.84 意味着双核就能跟上一路音频的输入速率,一台 4 核 NUC 级别的机器可以当常驻转写服务跑,不需要 GPU。这是这个项目真正的落点:不是"压缩比好看",是"把 7B 的 ASR 塞进没有显卡的机器"。

该怀疑的地方

1. 三张官方表格对不上同一个模型。 ASR 文档里 AliMeeting(中文)WER 是 27.40,VibeASR.cpp 那张表里同一个 7B FP16 是 36.21,差 8.8 个点;AISHELL-4 一份写 21.40,另一份写 19.83,差 1.6 个点。两份都是微软官方文档,没有说明口径差异(是否只算单人段、是否归一化数字、是否用了不同测试子集)。结论是:这些数字不能跨表横比,看到"某模型比某模型低 3 个点"这种结论时先确认它们出自同一份表。

2. star 是遗产,不是采用度。 5.69 万星里绝大部分投给的是 2025 年 8 月那个 TTS,而那个 TTS 的代码在这个仓库里已经不存在了。拿 star 数推断"这个 ASR 很成熟"是错的依据。真正的采用度信号是 fork 里的备份行为、HF 下载量、以及 205 个未关闭议题里有多少是 ASR 相关的使用问题——这三样都比 star 有意义。

3. "1–4% 的精度损失"是选择性表述。 六项基准里有一项是 +7.6,两项超过 4。如果只看 MLC-EN(+0.43),会得到"几乎无损"的印象;如果只看 AISHELL-4,会得到"中文不可用"的印象。两个印象都不完整,但 README 只给了前一个方向的数字。

4. RTF 测的是 20 秒片段的稳态。 官方口径写得很清楚:约 20 秒音频、跳过第一次预热、不含模型加载。这意味着两条关键数字缺失:冷启动到第一段输出的延迟,和"一小时音频一次过"的端到端耗时。会议转写场景真正要的是后一个,仓库没给。

5. 64K 和 90 分钟的能力依赖显存,但没有一个显存实测。 我上面那个 3.7 GB KV 估算是我按 28 层/4 KV 头/128 维算的,不是官方数字。跑一小时会议到底要多少显存、会不会 OOM、要不要开 flash attention,文档一个字没写,只给了 docker 里装 flash-attn 的命令。这属于"能跑"和"能稳定跑"之间的信息差。

6. 防护只挡了便利性,没挡模型。 移除 TTS 代码的理由是滥用风险,但 HF 上的权重仍然公开、LICENSE 仍然 MIT、docs 里的用法文档仍然完整,fork 里还有 57 个文件的完整推理代码。谁真想跑,成本是"翻一个 fork"而不是"写一套管线"。这个不对称值得注意:它降低了随手滥用的门槛,但没有改变有能力的人的成本。

参考文档与链接

你如果为了保住 TTS 去 fork 过这个仓库,或者在 4 核小机器上真跑过 ASR-BitNet,欢迎在评论区说一下实测的 RTF 和一小时音频的显存占用——这两个数字官方文档都没有,比我这里的估算有用得多。


作者: itech001
来源: 公众号:AI人工智能时代(the-ai-era)
网站: https://www.theaiera.top/
关注每日最新AI新闻和技术博客,主页有更多的文章的AI 技术参考:https://www.theaiera.top

本文首发于 AI 人工智能时代,转载请注明出处。

posted @ 2026-11-10 09:29  iTech  阅读(9)  评论(0)    收藏  举报