ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

双人抢话时说话人分离为何失效?FunASR SOND 模型数据预处理三层拆解

双人抢话时说话人分离为何失效?FunASR SOND 模型数据预处理三层拆解 双人抢话时说话人分离为何失效FunASR SOND 模型数据预处理三层拆解【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASRFunASR 里的 SOND 模型DiarSondModel专门处理多说话人重叠场景下的说话人分离它怎么对待原始波形是 SOND 数据预处理里最大的变量。所以下面不按流水线平铺而是从三个你大概率会碰到的真实问题切入逐层拆代码最后落在一组能直接带走的参数坑上。问题一原始波形真的直接进网络吗不是。模型看到的从来不是波形而是帧。看训练数据加载入口 funasr/datasets/audio_datasets/datasets.py每个样本都要过这么一段固定动作data_src load_audio_text_image_video(source, fsself.fs) # 统一重采样到 16kHz if self.preprocessor_speech: data_src self.preprocessor_speech(data_src, fsself.fs) speech, speech_lengths extract_fbank( data_src, data_typeself.data_type, frontendself.frontend, is_finalTrue ) # speech: [b, T, d]这里有两件事值得记住。第一load_audio_text_image_video会把任何来路的音频——麦克风 44.1kHz、电话 8kHz——统一重采样到 16kHz这是后面所有特征能对得上的前提。第二extract_fbank调的是前端里的 WavFrontend它把波形切成 25ms 一帧、步进 10ms再转成 80 维梅尔谱——说白了就是把频谱按人耳的感知方式重新分桶低频分得细、高频分得粗。fbank 之后通常还会跟两步LFR把多帧相邻特征拼成一个宽帧时间轴变短每步能看到更长上下文和 CMVN拿训练集的均值方差对每个频带做标准化把不同录音设备的电平差异抹平。上图这类会议数据就是重叠问题的典型来源好几个人声叠在同一条混合波形里数据预处理要做的就是让这种混合信号既可比不同录音之间分布一致又可学细节没被抹掉。问题二干净录音上训练的模型为什么一进会议室就垮因为模型只会学你喂给它的东西。FunASR 的答案是两味增强而且都只在self.training为真时生效SpecAug随机把某些频段或时间步打黑等于逼模型学会信息不全也能判断还带时间扭曲模拟语速变化实现在 funasr/models/specaug/specaug.pyProfileAugSOND 专属的一味药作用在说话人画像这一路输入上扰动说话人向量和它的长度逼模型靠语音内容判断这是谁而不是背下某个固定嵌入。这两步挂在哪看 funasr/models/sond/e2e_diar_sond.py 的encode()顺序是死的提特征 → 增强 → 归一化 → 编码器feats, feats_lengths self._extract_feats(speech, speech_lengths) # 1. fbank 特征 if self.specaug is not None and self.training: feats, feats_lengths self.specaug(feats, feats_lengths) # 2. 增强仅训练 if self.normalize is not None: feats, feats_lengths self.normalize(feats, feats_lengths) # 3. CMVN 归一化 encoder_outputs self.encoder(feats, feats_lengths) # 4. 编码器注意归一化排在增强后面这个顺序不是随手写的让 CMVN 把增强后的分布也重新拉回基准编码器才能永远吃到同一套分布的特征训练才稳。问题三两个人声叠在一起模型怎么知道是谁在说传统做法是每帧每个说话人各出一个 0/1重叠帧就变成了多标签分类损失函数都得换。SOND 用了个巧招——Power-Set EncodingPSE幂集编码给说话人编号取 1、2、4、8……2 的幂这一帧谁在说话直接合成一个数字两人重叠就是 123。默认max_spk_num16模型退化成在 2 的 16 次方种组合里做单选重叠不再是需要特判的情况。生成标签只有三行pad_bin_labels F.pad(binary_labels, (0, self.max_spk_num - binary_labels.shape[2]), constant, 0.0) raw_pse_labels torch.sum(pad_bin_labels * self.power_weight, dim2, keepdimTrue) pse_labels torch.argmax((raw_pse_labels.int() self.int_token_arr).float(), dim2)前向推理则反过来走编码器出语音表示说话人编码器出画像表示两个相似度打分器ci/cd scorer算出这一帧像谁解码器吐出 PSE 编号再拆回此刻谁在说话的时间轴标签。️ 上手看一遍全链路顺手带走参数表这条链你不用手工搭。用AutoModel.from_pretrained加载 SOND 系模型时frontend、specaug、normalize、encoder 全靠模型配置文件实例化并注册进 FunASR 的注册表模型 ID 可以查model_zoo/modelscope_models.md。你要做的是读懂下面这张表参数位置控制什么n_mels80WavFrontend梅尔特征维数frame_length25/frame_shift10msWavFrontend窗长与帧移决定时间分辨率lfr_m/lfr_nWavFrontendLFR 宽帧拼接缩短序列cmvn_fileWavFrontend训练集均值方差归一化统计量specaug/profileaug模型配置数据增强仅训练期生效全链路一图收束⚠️ 踩坑提醒开工前记住三件事增强在推理期是静默的。SpecAug 和 ProfileAug 都查self.training你想在小批数据上验证增强效果时记得先把模型切到train()模式否则不会报错只是悄悄不生效。CMVN 统计量跟着域走。cmvn_file用训练集统计算出来换域推理时沿用旧统计等于把错位的归一化喂给编码器错误率会跳但你很难第一时间定位到这里。max_spk_num 是上限不是估计值。PSE 的 token 空间是 2 的 max_spk_num 次方种组合场景里说话人数可能超配置时得在训练期改配置重训推理时改数字权重是不认的。延伸阅读特征前端全部实现funasr/frontends/SOND 模型与编码器源码funasr/models/sond/训练与推理教程docs/tutorial/README_zh.md【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表