Instructions to use czyhust/finetune_moss-sortformer with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- NeMo
How to use czyhust/finetune_moss-sortformer with NeMo:
# tag did not correspond to a valid NeMo domain.
- Notebooks
- Google Colab
- Kaggle
File size: 13,638 Bytes
74e4281 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | # 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 数据集:
```bash
# 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 数据集:
```bash
# 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 |
|