首页 / 资讯中心 / 文章详情

三代同堂怎么选:轻量版、1.5 与 2B 的速度音质显存对照

三代同堂怎么选:轻量版、1.5 与 2B 的速度音质显存对照 ★ FEATURED ARTICLE
三代同堂怎么选轻量版、1.5 与 2B 的速度音质显存对照【免费下载链接】VoxCPMVoxCPM: Tokenizer-Free TTS for Context-Aware Speech Generation and True-to-Life Voice Cloning项目地址: https://gitcode.com/OpenBMB/VoxCPMVoxCPM 现在有三代可以同时选择640M 的 VoxCPM-0.5B、800M 的 VoxCPM1.5以及把参数量拉到 2B 的 VoxCPM2。它们共用同一套 API、同一份微调脚本甚至同一套 CLI 参数看起来“换个模型 ID 就行”。但真正落到生产环境三者在采样率、token 率、显存占用、首包延迟上的差别会直接决定你应当按单卡部署还是按集群部署、单条生成还是批处理以及是否需要更换整条音频管线。本文不按“参数越大越强”的顺序来写而是从当前仓库快照配置目录里只有conf/voxcpm_v1/与conf/voxcpm_v1.5/README 中 VoxCPM2 标注为coming soon出发把源码里的 hop_length、patch_size、静态 KV cache 都算一遍再结合社区部署的实测口径给出可以改进为决策表的结论。一、先把三代摆到同一张表上三代的能力边界官方在 README.md 的 Model Versions 里已经写清了两代第三代则通过社区发布补齐维度VoxCPM-0.5B轻量版VoxCPM1.5VoxCPM22B参数量640M800M2BAudioVAE 采样率16 kHz44.1 kHz48 kHzLM token 率12.5 Hzpatch26.25 Hzpatch4未在仓库快照中体现语言中英中英30 种语言 中文方言社区报道在 8~9 种间有出入RTF单卡 RTX 40900.17~0.150.13推理引擎~0.30裸 PyTorch社区实测显存口径~5 GB~6 GB~8 GB特色能力零样本克隆、上下文感知韵律 44.1kHz 高保真克隆、SFT/LoRA 音色设计文字造声、多语种需要先说明表中 0.5B 与 1.5 的 RTF、参数、采样率、token 率来自 README.md 与 docs/release_note.md2B 一行来自社区发布与部署教程当前仓库代码并未包含 VoxCPM2 的实现src/voxcpm/model/下只有一套VoxCPMConfig默认patch_size: int 2、dtype: str bfloat16。这意味着本文讨论的“迁移成本”对 1.5 是有源码兜底的对 2B 则要留出接口变更的余量。二、音质采样率只是表面patch 与 hop 的整数关系才是内核很多人比较音质时只看“16k / 44.1k / 48k”但在 VoxCPM 里采样率从来不是孤立参数它必须和 hop_length、patch_size 一起满足一个整数约束。看 src/voxcpm/modules/audiovae/audio_vae.py 的定义class AudioVAEConfig(BaseModel): encoder_dim: int 128 encoder_rates: List[int] [2, 5, 8, 8] latent_dim: int 64 ... sample_rate: int 16000而 hop_length 是各级下采样率的连乘self.hop_length np.prod(encoder_rates) # 2*5*8*8 640 self.sample_rate sample_rate self.chunk_size math.prod(encoder_rates) # 640这组默认值16000 Hz / 640恰好等于 0.5B 的几何640 个采样点一帧 latent16000/640 25 帧/秒再乘 patch2正好得到 12.5 token/秒。反推 1.5 的配置44100 Hz 要维持同样的 25 帧/秒 latent 速率hop_length 必须是 176444100/25再乘 patch4才能落在 6.25 token/秒。两个直接推论1.5 的“6.25Hz”属于把 latent 帧率保持不变、只把 patch 拉长一倍的做法并非把模型“做快”的工程技巧。这解释了 docs/release_note.md 里那句容易被误读的话LocEnc/LocDiT 的 patch size 从 2 改成 4LM 处理速率减半但由于局部模块要处理更长上下文网络深度被扩了所以参数从 640M 涨到 800M。参数量上涨而速度反而更快原因在这里。AudioVAE 的默认配置是给 0.5B 用的。VoxCPMModel.from_local的加载逻辑是audio_vae_config getattr(config, audio_vae_config, None) audio_vae AudioVAE(configaudio_vae_config) if audio_vae_config else AudioVAE()如果权重目录里的config.json没有携带audio_vae_config代码会静默回落到 16 kHz 的默认 VAE。这是从 0.5B 迁移到 1.5 时最隐蔽的一个问题模型照样能推理不报错但声音会“糊”掉一层44.1kHz 的高频细节全被丢掉。排查时应该先打印model.tts_model.sample_rate和model.tts_model.audio_vae.hop_length确认而不要只凭听感判断。至于客观指标仓库里 docs/performance.md 的表格标注的是VoxCPM0.5B本身1.5 的官方说法是“在评测集上表现相近”2B 的评测数据不在本次快照中。0.5B 的成绩是Seed-TTS-eval 英文 WER 1.85 / SIM 72.9中文 CER 0.93 / SIM 77.2CV3-eval 中文 CER 3.40、英文 WER 4.04。但它并非全面领先在test-Hard上 CER 8.87明显落后于 CosyVoice2 的 6.83。困难集才是大参数真正能拉开差距的地方这一点在后面选型会用到。音质还有一个容易被忽视的回退denoiseTrue会先走 ZipEnhancer而 docs/usage_guide.md 明确写了“启用提示语音增强会把采样率限制到 16kHz”。也就是说如果你在 1.5 上开着降噪做克隆44.1kHz 的优势会被这个开关本身抵消。想拿到高保真克隆正确做法是关掉降噪并在素材侧解决噪声问题。三、速度RTF 只差 0.02但每秒音频的计算结构完全不同官方给出的 RTF 是 0.17 与 ~0.15看起来几乎一样。但 RTF 是“每个音频秒”的口径它把两件方向相反的事混在一起了。先看生成循环。在 src/voxcpm/model/voxcpm.py 的_inference里每个 token 都要跑一次扩散采样pred_feat self.feat_decoder( mudit_hidden, patch_sizeself.patch_size, condprefix_feat_cond.transpose(1, 2).contiguous(), n_timestepsinference_timesteps, cfg_valuecfg_value, )inference_timesteps默认 10也就是每个 token 要跑 10 步去噪。于是每秒音频的成本可以拆成1.56.25 个 token × 10 步去噪 62.5 次扩散前向解码端每 token 出4 × 1764 7056个采样点160 ms。0.5B12.5 个 token × 10 步去噪 125 次扩散前向解码端每 token 出2 × 640 1280个采样点80 ms。LM 与 DiT 的调用次数少一半是 1.5 更快的主因代价是 AudioVAE 解码端每秒要输出 44100 个采样点、而 0.5B 只有 16000 个解码负载约为前者的 2.76 倍。两相抵消后RTF 落在 0.15 对 0.17——这就是数字接近却结构不同的原因。同一套计算规则也能解释 2B 的口径分歧。社区一边有“4090 上 RTF 0.13、比实时快 7.7 倍”的说法另一边有教程给出裸 PyTorch 下 ~0.30 的表格。两者并不矛盾0.13 是接入高吞吐推理引擎Nano-vLLM 一类之后的结果0.30 是不做服务化、直接跑仓库原生的torch循环。同代模型在不同后端上的差距比三代模型之间的差距还大。所以比较 RTF 时必须先对齐后端否则表格是没有意义的。还有一个工程细节决定了“能不能真的跑到标称 RTF”src/voxcpm/model/voxcpm.py 的optimize()只在 CUDA triton 下生效if self.device ! cuda: raise ValueError(VoxCPMModel can only be optimized on CUDA device) self.base_lm.forward_step torch.compile(..., modereduce-overhead, fullgraphTrue) self.residual_lm.forward_step torch.compile(..., modereduce-overhead, fullgraphTrue)而在__init__里optimizeTrue会顺带做一次预热生成Warm up VoxCPMModel...。也就是说如果你在 MPS 或 CPU 上跑__init__会自动回落到mps/cpu既拿不到torch.compile的收益还要付出一次预热时间。CPU/端侧的实时性请按社区 ONNX、ANE 那条路线的实测值来估不要直接套 4090 的 RTF。流式场景还要算首包。src/voxcpm/core.py 把streaming_prefix_len固定在 3即每次解码都带上最近 3 个 patch 的上下文来保证拼接平滑。换算成音频1.5 的首包大约对应3 × 160 ms 480 ms的内容0.5B 是3 × 80 ms 240 ms。轻量版在“第一句话什么时候出声”这项上天然占优这也是它在语音助手、IVR 里仍有位置的原因。四、显存权重只是入场券静态 KV cache 才是固定成本按 bf16 计算三代的权重下限大概是640M → 1.28 GB800M → 1.6 GB2B → 4 GB。但社区给出的实测是 5 / 6 / 8 GB多出来的部分主要来自三块。第一块是两张静态 KV cache。__init__里对 base_lm 和 residual_lm 各做了一次self.base_lm.setup_cache(1, config.max_length, self.device, get_dtype(self.config.dtype)) self.residual_lm.setup_cache(1, config.max_length, self.device, get_dtype(self.config.dtype))而 src/voxcpm/modules/minicpm4/cache.py 是按max_length一次性分配的self.kv_cache torch.zeros( 2, num_layers, batch_size, num_kv_heads, max_length, dim_kv_head, devicedevice, dtypedtype, )config.max_length默认 4096batch_size写死为 1。所以显存里长期躺着一块“按最长序列预留”的缓存而且这个 batch 维度是 1——原生路径下想提高并发只能多进程/多实例这也是社区要另做 Nano-vLLM、vLLM-Omni 集成的根本原因而不是单纯为了“更快的 kernel”。第二块是AudioVAE 解码器。1.5 的解码端每秒要重建 44100 个采样点2B 是 48000解码器本身的显存与中间激活都随采样率上抬。第三块是降噪器。from_pretrained(load_denoiserTrue)是默认行为会额外拉起 ZipEnhancer 的 pipeline。显存吃紧时这是第一个该关的开关load_denoiserFalse或 CLI 的--no-denoiser代价只是失去提示音频降噪能力。顺带一个被忽略的容量上限max_length4096个 token按各自 token 率换算0.5B 单次理论上限约4096/12.5 ≈ 327 秒1.5 约4096/6.25 ≈ 655 秒。当然提示音频的 token 也要占额度实际可用会更短。做有声书这类长文本时1.5 的“同等显存下能装更长的音频”是实打实的收益不只是音质升级。五、什么场景其实不需要 2B把上面三节合起来可以给出一个不依赖“谁更强”的判断顺序。第一类下游链路本身就是窄带的用 2B 纯属浪费。电话客服、IVR、语音回环TTS 出来再喂 ASR、车载提示音终端采样率往往就是 16k。这种场景 0.5B 的 16k 输出正好对齐还能省下 2.76 倍的存储与带宽16k 单声道 16bit 约 32 KB/s44.1k 约 88 KB/s48k 约 96 KB/s。一小时的音频前者约 115 MB后者 317 MB 起。批量生产时这是直接的账单差异。第二类任务本身是“短句 高并发”瓶颈在调度而不是模型能力。由于原生 KV cache 的 batch 维度是 12B 想要靠单卡扛并发必须上推理引擎而 0.5B/1.5 更容易用多实例把卡填满。社区教程里那句“先拿 1.5 跑一条 20 秒样音满意了再切 2B”是对的并发还没解决之前更大的模型只会让排队更长。第三类只做中英且音色固定。2B 的核心增量是多语种、音色设计、48kHz。如果业务是中英双语、音色来自固定的几条参考音频那 2B 的能力用不上。此时正确做法是 1.5 LoRA用 5~10 分钟音频把音色固化下来比每次靠参考音频做零样本克隆更稳也省掉长 prompt 占用的 token 额度。仓库已经支持全参与 LoRA 两条路见 docs/finetune.mdLoRA 配置里enable_dit: true是必须的——文档明确写了它“required for voice cloning”。反过来哪些场景确实该上 2B两类一是多语种/方言覆盖30 语言 方言这是 0.x/1.5 完全没有的能力硬做只能靠外部拼接二是前面test-Hard暴露的短板——困难文本、强表现力长句、需要文字描述造声的角色配音。在这些地方参数量的边际收益才真正兑现。六、旧版本迁移配置只改两行成本在别处如果只看训练配置“迁移成本”几乎为零。把两个版本的 YAML 逐行 diff差异只有两行# conf/voxcpm_v1/voxcpm_finetune_lora.yaml → conf/voxcpm_v1.5/voxcpm_finetune_lora.yaml -pretrained_path: /path/to/VoxCPM-0.5B/ -sample_rate: 16000 pretrained_path: /path/to/VoxCPM1.5/ sample_rate: 44100推理侧同理VoxCPM.from_pretrained()的签名没变generate()的参数没变CLI 的--cfg-value、--inference-timesteps也没变只有默认模型 ID 指向了openbmb/VoxCPM1.5见 src/voxcpm/core.py 与 src/voxcpm/cli.py。换模型真的就是换一个字符串。真正的成本有四处且都不在配置文件里其一采样率变了下游全链路要复核。44.1kHz 输出意味着存储格式是否还按 16k 归档、播放器重采样策略、与字幕/口型对齐的时间戳、以及任何假设“采样率16000”的硬编码。build_prompt_cache内部会把参考音频torchaudio.functional.resample到模型采样率所以参考素材不必手动转码但输出侧的假设没人帮你兜底。同样训练数据也必须按 44.1kHz 准备docs/finetune.md写得很清楚0.5B 用 16kHz1.5 用 44.1kHz。其二LoRA 权重不能跨代复用。LoRA 的r/alpha虽可沿用但注入位置依赖隐藏维度和 patch 结构target_modules_lm: [q_proj,v_proj,k_proj,o_proj]而 1.5 的局部模块深度与 0.5B 不同权重形状对不上。仓库的加载逻辑是“能加载的加载、其余跳过并打印数量”Loaded N LoRA parameters, skipped M所以它不会崩只会静默地少加载一部分——这种“不报错的降级”比直接失败更难查。跨代迁移必须重训 LoRA并核对 skipped 是否为 0。其三默认值会悄悄漂移。from_pretrained的默认hf_model_id已经是openbmb/VoxCPM1.5。如果你的代码习惯性省略这个参数某次升级依赖之后模型就换了代而app.py里还留了HF_REPO_ID这个环境变量出口默认openbmb/VoxCPM1.5。生产环境应该显式固定模型 ID 与本地路径而不是依赖默认值。其四流式路径的隐含限制。_generate_with_prompt_cache里有一句if retry_badcase and streaming: warnings.warn(Retry on bad cases is not supported in streaming mode, setting retry_badcaseFalse.)retry_badcaseTrue是 README 推荐开启的兜底默认 3 次、阈值 6.0但在流式模式下它会被静默关闭。也就是说你从“非流式 重试”切到“流式”时稳定性兜底同时消失了。做实时业务时这一条要单独设计超时与重生成策略不能指望框架层。七、给一个可以直接执行的选型顺序先定采样率而不是先定参数量。下游是 16k 窄带链路 → 0.5B需要高保真、且能接受 2.76 倍的存储与带宽 → 1.5需要 48kHz 与多语种 → 2B。采样率定错后面所有优化都是白做。再定并发模型。单请求、离线批处理裸torch就够高并发服务必须上推理引擎此时才谈 2B 的 RTF 0.13 是否可信否则它的真实成本是 0.30 量级。最后定音色策略。靠参考音频做零样本克隆就用原生prompt_wav_path prompt_text音色要长期固定就走 LoRA并接受“换代会重训”的成本。调参只调两个旋钮inference_timesteps默认 10决定质量与速度的斜率cfg_value默认 2.0决定对提示的贴合度。长文本降 cfg、短句升 cfg这是 docs/usage_guide.md 给出的经验规则比盲目加大模型更有效。一个最小可用的加载与流式片段三代通用只需换模型 IDimport numpy as np, soundfile as sf from voxcpm import VoxCPM model VoxCPM.from_pretrained( openbmb/VoxCPM1.5, # 或 openbmb/VoxCPM-0.5B load_denoiserFalse, # 显存吃紧时先关这个但开启降噪会把提示限制到 16kHz ) print(model.tts_model.sample_rate, model.tts_model.audio_vae.hop_length) chunks [] for chunk in model.generate_streaming( textVoxCPM 的三代模型共用同一套推理接口差别在采样率与 token 率。, cfg_value2.0, inference_timesteps10, ): chunks.append(chunk) sf.write(out.wav, np.concatenate(chunks), model.tts_model.sample_rate)选型的本质不是选出“最强的一代”而是找到一个采样率、并发模型、音色策略三者同时成立的组合。VoxCPM 把这三代做成同一套接口好处是迁移几乎零代码改动坏处也正是这一点——那些不会报错、只会让音质或延迟悄悄退化的参数才是真正需要盯住的地方。【免费下载链接】VoxCPMVoxCPM: Tokenizer-Free TTS for Context-Aware Speech Generation and True-to-Life Voice Cloning项目地址: https://gitcode.com/OpenBMB/VoxCPM创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站