finetune_moss-sortformer / docs /simulation_pipelines.md
czyhust's picture
Full upload
74e4281 verified
|
Raw
History Blame Contribute Delete
13.6 kB

Simulation Data Pipelines

本文档描述 G-STAR finetuning pipeline 中两条独立的多说话人数据仿真流水线:FastMSS 流水线(主)NeMo 流水线(旧)


一、全局概览

两条流水线共享 LibriSpeech 源数据,但在仿真引擎、中间格式和最终产物上完全不同。

                    ┌─── LibriSpeech 源数据 ──────────────┐
                    │   WHAM/MUSAN 噪声                    │
                    │                                      │
              ┌─────▼──────────────────────────────────┐  │
              │  PIPE A: NeMo 仿真流水线(旧)          │  │
              │    data_simulation_nemo.sh              │  │
              │    run_all_speakers_simulation_nemo.sh  │  │
              │    → sentence_level_multispeaker_       │  │
              │      simulator.py                       │  │
              │    → utterance-level JSON               │  │
              │    → standardize_manifest_format.py     │  │
              │    → segment-level JSONL                │  │
              └────────────────────────────────────────┘  │
                                                          │
              ┌─────▼──────────────────────────────────┐  │
              │  PIPE B: FastMSS 仿真流水线(主)       │  │
              │    data_simulation_fastmss.sh           │  │
              │    run_fastmss-*.sh                     │  │
              │    → recipes/sim.py (5-stage Hydra)     │  │
              │    → Lhotse CutSet → WAV + RTTM         │  │
              │    → nemo_manifest.jsonl                │  │
              └────────────────────────────────────────┘  │
                                                          │
              ┌─────▼──────────────────────────────────┐  │
              │  Training / Inference                  │  │
              │    train.sh → streaming_sortformer_     │  │
              │      diar_train.py                      │  │
              │    infer.sh → e2e_diarize_speech.py     │  │
              │    (消耗 segment-level JSONL)           │  │
              └────────────────────────────────────────┘  │

二、根目录 Shell 脚本总览

脚本 用途 所属流水线
data/nemo/simulate.sh NeMo 单次仿真:并行跑 train/dev/test Pipe A
data/nemo/run_all_speakers.sh NeMo 全量仿真:遍历 2-10 spk,合并输出,标准化为 JSONL Pipe A
data/fastmss/simulate.sh FastMSS 单次仿真入口:调用 recipes/sim.py + 分析脚本 Pipe B
data/fastmss/run_6spk_v1.sh v1 config: 90s, WHAM noise, 1-6 spk, 30k train / 3k dev / 3k test Pipe B
data/fastmss/run_6spk_v1.1.sh v1.1 config: 50% reverb/noise 概率, 2-6 spk, speed perturbation Pipe B
data/fastmss/run_6spk_v2.sh v2 config: WHAM + MUSAN 双噪声源, 基于 v1.1 Pipe B
data/fastmss/run_mini_testset.sh 小测试集: 600 meetings, seed=45, 8 workers, 用于调试验证 Pipe B
train.sh Sortformer 微调入口 (Hydra) 训练
run_finetune_8spk.sh 8-spk 微调预设 训练
run_train_10spk.sh 10-spk 微调预设(从 4-spk checkpoint 扩展) 训练
infer.sh 流式 diarization 推理 + DER 评估 推理
run_infer_8spk.sh / run_infer_8spk_base.sh 8-spk 推理(微调模型 / 预训练 baseline) 推理
path.sh 环境配置:PYTHONPATH + conda env 激活 全局
data/nemo/prepare_data.sh 6 阶段数据预处理(详见第三节) Pipe A 前置

三、Pipe A:NeMo 仿真流水线(旧)

3.1 数据预处理:data/nemo/prepare_data.sh

为 NeMo 模拟器准备 LibriSpeech + WHAM 源数据,共 6 个阶段(stage 参数控制):

阶段 脚本 说明
Stage 1 data/nemo/scripts/get_librispeech_data.py FLAC → WAV 转换(sox),生成 JSON manifest
Stage 2 data/nemo/scripts/create_alignment_manifest.py 集成 CorentinJ 格式的词级对齐,产出 CTM + 对齐 manifest
Stage 3 data/shared/scripts/pathfiles_to_diarize_manifest.py WHAM 噪声 wav → diarization manifest
Stage 4 cat 合并 train clean_100+360+other_500 → train_960(test/dev 同理)
Stage 5 data/fastmss/scripts/get_max_audio_duration.py 分析仿真数据集音频时长分布(直方图 + CDF)
Stage 6 data/shared/scripts/split_manifest_by_spk.py 按说话人数拆分标准化 manifest(≤4 / >4)

3.2 仿真过程

data_simulation_nemo.sh
    → sentence_level_multispeaker_simulator.py
        → 输出:utterance-level JSON(每行一个 utterance)
            → standardize_manifest_format.py
                → 输出:segment-level JSONL(每行一个音频段)
                    → split_manifest_by_spk.py
                        → 输出:按 spk 数拆分的 JSONL

核心脚本:data/nemo/scripts/sentence_level_multispeaker_simulator.py

  • NeMo MultiSpeakerSimulator 的子类
  • 以整句为单位拼接(非词级 chunk)
  • 可配置 silence/overlap/session_length/spk_count
  • 输出 utterance-level JSON + RTTM 文件

桥接脚本:data/nemo/scripts/standardize_manifest_format.py

  • NeMo utterance-level JSON → 标准 segment-level JSONL
  • 添加 uniq_id 字段防止 key 冲突
  • 这是训练/推理实际消费的格式

3.3 相关文件清单

data/
├── prepare_data.sh                              # 6 阶段数据预处理
├── conf/default_data_simulator.yaml             # NeMo 仿真器配置
└── scripts/
    ├── get_librispeech_data.py                  # FLAC→WAV + manifest
    ├── create_alignment_manifest.py             # 对齐 manifest
    ├── pathfiles_to_diarize_manifest.py         # 噪声 manifest
    ├── sentence_level_multispeaker_simulator.py # 句子级模拟器(入口)
    ├── multispeaker_simulator.py                # 词级模拟器(旧,已弃用)
    ├── standardize_manifest_format.py           # 格式标准化(桥接)
    └── get_max_audio_duration.py                # 时长分布分析

四、Pipe B:FastMSS 仿真流水线(主)

4.1 前置准备

FastMSS 的输入是 Lhotse CutSet(含词级对齐),由以下脚本生成:

data/fastmss/scripts/create_cutsets.py

  • /F00120240032/librispeech/.../lhotse_format_manifests/ 读取 recordings + supervisions manifests
  • 生成 librispeech_cutset_{split}.jsonl.gz

**src/third_party/FastMSS/scripts/split_musan.py**(v2 新增)

  • 将 MUSAN 噪声按 8:1:1 拆分到 {tr,cv,tt}.wavlist

4.2 仿真过程

run_fastmss-*.sh
    → data_simulation_fastmss.sh
        → src/third_party/FastMSS/recipes/sim.py (Hydra 5 阶段流水线)
            → Stage 1: 加载 CutSet → 停顿处切分 → 保存 merged CutSet
            → Stage 2: 扫描噪声目录/wavlist → 过滤短噪声 → noise_files.txt
            → Stage 3: RIRSimulator → pyroomacoustics → all_rooms.json
            → Stage 4: ConversationalMeetingSimulator → 并行生成 WAV + Lhotse manifests
            → Stage 5: 生成 RTTM + nemo_manifest.jsonl
        → analyze_speaker_distribution.py
        → analyze_duration_distribution.py

4.3 recipes/sim.py 5 阶段详解

阶段 输入 输出 说明
Stage 1 librispeech_cutset_{split}.jsonl.gz {data_dir}/manifests/all_cuts.jsonl.gz 加载 CutSet,merge 指定 split,在词对齐停顿处切分 utterance
Stage 2 噪声目录 + wavlist 文件 {output_dir}/manifests/noise_files.txt 递归扫描音频文件(支持目录 glob 和 wavlist 逐行读取),过滤 <2s 的短噪声
Stage 3 房间/麦克风/RIR 配置 {rir_dir}/all_rooms.json pyroomacoustics 生成房间脉冲响应,可配 RT60/房间尺寸/麦克风类型
Stage 4 CutSet + 噪声 + RIR WAV 文件 + Lhotse manifests 并行生成 n_meetings 场会议:HMM 轮次切换、spk 权重采样、增益随机化、RIR 卷积、噪声混合
Stage 5 Stage 4 manifests RTTM 文件 + nemo_manifest.jsonl 生成逐 meeting 的 RTTM(0.2s 间隙合并),生成 NeMo 格式 diarization manifest

4.4 配置文件层级

src/third_party/FastMSS/recipes/
├── default.yaml                           # 基础配置
└── extend_sortformer/6spk/
    ├── v1.yaml                            # 6-spk base: 90s, WHAM, RIR, Markov HMM
    ├── v1.1.yaml                          # 增强版: 50% reverb/noise, speed perturbation
    ├── v2.yaml                            # 新增 MUSAN 双噪声
    └── dataset_splits/
        ├── train.yaml                     # cutset_train-clean-{100,360,500}
        ├── dev.yaml                       # cutset_dev-{clean,other}
        └── test.yaml                      # cutset_test-{clean,other}

4.5 相关文件清单

src/third_party/FastMSS/
├── fastmss/
│   ├── simulator.py                       # ConversationalMeetingSimulator 核心引擎
│   ├── hmm_turn_taking.py                 # 4 状态 HMM 轮次模型
│   ├── rirsimulator.py                    # RIR 生成器 (pyroomacoustics)
│   └── utils.py                           # 音频工具
├── recipes/
│   ├── sim.py                             # 5 阶段 Hydra 仿真入口
│   ├── default.yaml
│   └── extend_sortformer/6spk/            # 6-spk 配置
├── scripts/
│   ├── split_musan.py                     # MUSAN 噪声拆分
│   ├── analyze_speaker_distribution.py    # 说话人分布统计
│   └── analyze_duration_distribution.py   # 时长分布统计
└── preprocessing/
    ├── download_wham.sh                   # 下载 WHAM 噪声
    └── download_otospeech.sh              # 下载 otoSpeech

五、两条流水线对比

维度 Pipe A (NeMo) Pipe B (FastMSS)
模仿真引擎 sentence_level_multispeaker_simulator.py recipes/sim.py (Hydra)
输入格式 LibriSpeech WAV + 对齐 JSON Lhotse CutSet (.jsonl.gz)
轮次模型 简单 silence/overlap 控制 4 状态 Markov HMM(hold/switch/interruption/backchannel)
房间仿真 NeMo RIRMultiSpeakerSimulator pyroomacoustics RIRSimulator
噪声输入 WHAM dir 目录 + wavlist(支持 WHAM/MUSAN 等)
仿真粒度 句子级 chunk 拼接 词级对齐切分,更细粒度
并行策略 Shell 级 & 后台并行 Python 多进程 parallel_map
中间输出 utterance-level JSON Lhotse Recording + Supervision manifests
最终产物 segment-level JSONL(需 standardize_manifest_format.py 转换) nemo_manifest.jsonl(直接可用)
当前状态 旧流水线,用于 10-spk 主线流水线,用于 Sortformer 微调

六、关键桥接脚本

脚本 方向 说明
data/fastmss/scripts/create_cutsets.py Lhotse manifests → CutSet 为 FastMSS 生成输入
data/nemo/scripts/standardize_manifest_format.py NeMo utterance JSON → segment JSONL 为训练/推理转换格式

注意:FastMSS Stage 5 直接产出 nemo_manifest.jsonl,格式与训练/推理消费的 segment-level JSONL 兼容,无需额外转换步骤。


七、典型使用流程

使用 FastMSS (Pipe B) 生成 v2 数据集:

# 1. 拆分 MUSAN(仅 v2 需要)
python src/third_party/FastMSS/scripts/split_musan.py /path/to/musan data/dump_fastmss/musan_noise_wavlists

# 2. 运行仿真(生成 train/dev/test)
bash run_fastmss-extend_sortformer-6spk-dataset_v2.sh

# 3. 产物位于 data/dump_fastmss/simulated_sessions/extend_sortformer-6spk-dataset_v2/{train,dev,test}/
#    每个目录包含: audio/*.wav, rttm/*.rttm, nemo_manifest.jsonl

使用 NeMo (Pipe A) 生成 10-spk 数据集:

# 1. 预处理
bash data/prepare_data.sh

# 2. 全量仿真
bash run_all_speakers_simulation_nemo.sh

八、路径约定

用途 默认路径 说明
LibriSpeech /F00120240032/librispeech/corpus_librispeech/corpus 源数据
lhotse manifests /F00120240032/librispeech/.../lhotse_format_manifests FastMSS 输入
WHAM noise /F00120240032/wham_noise/wham_noise/wham_noise/{tr,cv,tt} 噪声目录
LibriSpeech Alignments /F00120240032/LibriSpeech-Alignments 词级对齐
FastMSS 输出 data/dump_fastmss/simulated_sessions/{version}/{split}/ 仿真产物
NeMo 输出 data/dump/simulated_10spk_dataset/ 旧流水线产物
训练输出 exp/ gitignored
模型 checkpoints checkpoints/ gitignored