Sync model card with GitHub README

#16
by gaoyang07 - opened
Files changed (1) hide show
  1. README.md +147 -105
README.md CHANGED
@@ -20,62 +20,84 @@ pipeline_tag: audio-text-to-text
20
 
21
  # MOSS-Transcribe-Diarize
22
 
 
 
 
 
 
 
 
 
23
  <div align="center">
24
  <a href="https://github.com/OpenMOSS/MOSS-Transcribe-Diarize"><img src="https://img.shields.io/badge/GitHub-OpenMOSS%2FMOSS--Transcribe--Diarize-black?logo=github"></a>
25
- <a href="https://huggingface.co/OpenMOSS-Team/MOSS-Transcribe-Diarize"><img src="https://img.shields.io/badge/HuggingFace-Model-orange?logo=huggingface"></a>
26
  <a href="https://arxiv.org/abs/2601.01554"><img src="https://img.shields.io/badge/arXiv-2601.01554-b31b1b?logo=arxiv"></a>
 
27
  </div>
28
 
29
- MOSS-Transcribe-Diarize 0.9B is an end-to-end audio understanding model for long-form multi-speaker transcription, diarization, timestamps, and acoustic event awareness.
30
-
31
- It supports transcription and diarization across 50+ languages, single-pass inference on audio recordings up to 90 minutes long, and custom hotword prompting for domain-specific terms.
32
-
33
- Given an audio or video file, the model generates a compact speaker-aware transcript in one pass, including timestamps and anonymous speaker labels such as `[S01]`, `[S02]`, and beyond.
34
 
35
  ## News
36
 
37
- * 2026-07-14: 🏆 MOSS-Transcribe-Diarize won first place in the [2nd MLC-SLM Challenge](https://www.nexdata.ai/competition/mlc-slm) at INTERSPEECH 2026, spanning 14 languages.
38
- * 2026-07-09: Released MOSS-Transcribe-Diarize 0.9B.
39
 
40
  ## Contents
41
 
42
  - [Introduction](#introduction)
43
  - [Model Architecture](#model-architecture)
44
  - [Evaluation](#evaluation)
 
45
  - [Quickstart](#quickstart)
46
  - [Environment Setup](#environment-setup)
47
  - [Python Usage](#python-usage)
48
- - [Serve with vLLM and SGLang](#serve-with-vllm-and-sglang)
 
 
49
  - [Subtitle Web App](#subtitle-web-app)
50
- - [Output Format](#output-format)
51
- - [More Information](#more-information)
52
- - [License](#license)
53
  - [Citation](#citation)
54
 
55
  ## Introduction
56
 
57
- MOSS-Transcribe-Diarize 0.9B turns real-world long-form audio into structured, speaker-aware transcripts in one pass. Instead of stitching together separate ASR and diarization systems, it jointly performs speech transcription and speaker diarization, producing time-aligned text with consistent speaker labels.
 
 
 
 
58
 
59
- The model is built for meetings, calls, podcasts, interviews, lectures, videos, and other long or messy multi-speaker recordings. It can also emit acoustic event annotations, giving downstream systems a richer view of what happened, who spoke, and when.
60
 
61
- Core capabilities:
 
 
 
 
62
 
63
- * **Long-form transcription**: Converts long audio or video recordings into timestamped text.
64
- * **Speaker-aware diarization**: Assigns anonymous speaker labels such as `[S01]` and `[S02]` without a separate diarization pipeline.
65
- * **Promptable generation**: Supports custom transcription instructions, hotwords, and acoustic event annotations.
66
 
67
  ## Model Architecture
68
 
69
  <p align="center">
70
- <img src="Model_Architecture.png" alt="MOSS-Transcribe-Diarize 0.9B model architecture" width="900">
71
  </p>
72
 
 
 
 
 
 
 
 
 
73
 
74
  This Hugging Face repository includes the custom Transformers remote code required to load the model with `trust_remote_code=True`.
75
 
76
  ## Evaluation
77
 
78
- We evaluate MOSS-Transcribe-Diarize using three objective metrics: Character Error Rate (CER), concatenated minimum-permutation Character Error Rate (cpCER), and Delta-cp. Lower is better for all metrics. A dash (`-`) indicates that the result is unavailable.
 
 
79
 
80
  <div style="overflow-x: auto;">
81
  <table style="white-space: nowrap;">
@@ -159,17 +181,14 @@ We evaluate MOSS-Transcribe-Diarize using three objective metrics: Character Err
159
 
160
  ### Environment Setup
161
 
162
- Use a clean Python environment. The model uses custom Transformers code, so load the model and processor with `trust_remote_code=True`.
163
 
164
  ```bash
165
- conda create -n moss-transcribe-diarize python=3.12 -y
166
- conda activate moss-transcribe-diarize
167
-
168
  git clone https://github.com/OpenMOSS/MOSS-Transcribe-Diarize.git
169
  cd MOSS-Transcribe-Diarize
170
-
171
- pip install --index-url https://download.pytorch.org/whl/cu128 torch torchaudio
172
- pip install -e .
173
  ```
174
 
175
  The GitHub package provides helper utilities such as audio/video loading, transcription message construction, transcript parsing, CLI inference, and the subtitle web app. The model weights and remote-code model files are loaded from this Hugging Face repository.
@@ -198,11 +217,7 @@ model = AutoModelForCausalLM.from_pretrained(
198
  trust_remote_code=True,
199
  dtype="auto",
200
  ).to(dtype=dtype).to(device).eval()
201
-
202
- processor = AutoProcessor.from_pretrained(
203
- model_id,
204
- trust_remote_code=True,
205
- )
206
 
207
  messages = build_transcription_messages(audio_path)
208
  result = generate_transcription(
@@ -221,30 +236,109 @@ for segment in parse_transcript(result["text"]):
221
  print(segment.start, segment.end, segment.speaker, segment.text)
222
  ```
223
 
224
- The message flow follows the common Qwen multimodal pattern:
225
 
226
  1. `processor.apply_chat_template(messages, tokenize=False)` renders text with audio placeholders.
227
- 2. The helper utilities load audio waveforms from the same messages.
228
  3. `processor(text=text, audio=audios)` computes Whisper input features and expands audio placeholders.
229
  4. `model.generate(...)` produces timestamped transcription and diarization text.
230
 
231
- ### Custom Prompt and Hotwords
232
 
233
- The default prompt is optimized for timestamped transcription and speaker diarization:
234
 
235
- ```text
236
- 请将音频转写为文本,每一段需以起始时间戳和说话人编号([S01]、[S02]、[S03]…)开头,正文为对应的语音内容,并在段末标注结束时间戳,以清晰标明该段语音范围。
 
 
 
 
237
  ```
238
 
239
- To add hotwords, append a short hint to the default prompt:
240
 
241
- ```text
242
- 请将��频转写为文本,每一段需以起始时间戳和说话人编号([S01]、[S02]、[S03]…)开头,正文为对应的语音内容,并在段末标注结束时间戳,以清晰标明该段语音范围。热词提示:热词1, 热词2, 热词3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  ```
244
 
245
- More prompt recipes are available in the GitHub repository: <https://github.com/OpenMOSS/MOSS-Transcribe-Diarize/blob/main/examples/prompts.md>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
 
247
- ### Serve with vLLM and SGLang
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
 
249
  MOSS-Transcribe-Diarize supports vLLM serving through the OpenAI-compatible transcription API. Use a pinned vLLM nightly build that includes the MOSS-Transcribe-Diarize model registration. Choose one of the following commands: for CUDA 12 environments, use `cu129`; for CUDA 13 environments, use `cu130`.
250
 
@@ -274,47 +368,25 @@ curl http://localhost:8000/v1/audio/transcriptions \
274
  -F temperature="0"
275
  ```
276
 
277
- The recommended way to serve MOSS-Transcribe-Diarize is [SGLang Omni](https://github.com/sgl-project/sglang-omni) through the OpenAI-compatible `/v1/audio/transcriptions` endpoint. Install `sglang-omni` by following the [installation guide](https://github.com/sgl-project/sglang-omni/blob/main/docs/get_started/installation.md), then download the model:
278
-
279
- ```bash
280
- hf download OpenMOSS-Team/MOSS-Transcribe-Diarize
281
- ```
282
-
283
- Serve the model:
284
-
285
- ```bash
286
- sgl-omni serve \
287
- --model-path OpenMOSS-Team/MOSS-Transcribe-Diarize \
288
- --port 8000 \
289
- --max-running-requests 16 \
290
- --cuda-graph-max-bs 16 \
291
- --mem-fraction-static 0.80
292
- ```
293
 
294
- Use `response_format=verbose_json` when you need parsed speaker segments. `json` returns the raw transcript text only.
295
 
296
- ```bash
297
- curl -X POST http://localhost:8000/v1/audio/transcriptions \
298
- -F model=OpenMOSS-Team/MOSS-Transcribe-Diarize \
299
- -F file=@audio.wav \
300
- -F response_format=verbose_json
301
  ```
302
 
303
- For longer multi-speaker audio, raise `max_new_tokens` so the decoder can finish the full diarized transcript:
304
 
305
- ```bash
306
- curl -X POST http://localhost:8000/v1/audio/transcriptions \
307
- -F model=OpenMOSS-Team/MOSS-Transcribe-Diarize \
308
- -F file=@audio.wav \
309
- -F response_format=verbose_json \
310
- -F max_new_tokens=65536
311
  ```
312
 
313
-
314
 
315
  ### Subtitle Web App
316
 
317
- The source package includes a local subtitle workflow for upload, review, subtitle export, and optional FFmpeg burn-in:
318
 
319
  ```bash
320
  mtd-subtitle-web \
@@ -334,39 +406,9 @@ mtd-subtitle /path/to/input.mp4 \
334
  --render
335
  ```
336
 
337
- ## Output Format
338
-
339
- The canonical output format is:
340
-
341
- ```text
342
- [start_time][Sxx]transcribed speech[end_time]
343
- ```
344
-
345
- Example:
346
-
347
- ```text
348
- [0.48][S01]Welcome everyone[1.66][12.26][S02]The new transcription pipeline is ready for evaluation[13.81][14.36][S01]Great, include the diarization results in the report[18.76]
349
- ```
350
-
351
- In this format:
352
-
353
- * `start_time` and `end_time` are timestamps in seconds.
354
- * `[S01]`, `[S02]`, and similar labels are anonymous model-generated speaker labels.
355
- * Speaker labels are relative labels within the input audio and should not be interpreted as real speaker identities.
356
-
357
- ## More Information
358
-
359
- * **GitHub**: <https://github.com/OpenMOSS/MOSS-Transcribe-Diarize>
360
- * **MOSI.AI**: <https://mosi.cn>
361
- * **OpenMOSS**: <https://www.open-moss.com>
362
-
363
- ## License
364
-
365
- MOSS-Transcribe-Diarize 0.9B is licensed under the Apache License 2.0.
366
-
367
  ## Citation
368
 
369
- If you use MOSS-Transcribe-Diarize 0.9B, please cite the technical report:
370
 
371
  ```bibtex
372
  @misc{moss_transcribe_diarize_2026,
 
20
 
21
  # MOSS-Transcribe-Diarize
22
 
23
+ <br>
24
+
25
+ <p align="center">
26
+ <img src="https://raw.githubusercontent.com/OpenMOSS/MOSS-Transcribe-Diarize/main/assets/OpenMOSS_Logo.png" height="70" align="middle" />
27
+ &nbsp;&nbsp;&nbsp;&nbsp;
28
+ <img src="https://raw.githubusercontent.com/OpenMOSS/MOSS-Transcribe-Diarize/main/assets/mosi-logo.png" height="50" align="middle" />
29
+ </p>
30
+
31
  <div align="center">
32
  <a href="https://github.com/OpenMOSS/MOSS-Transcribe-Diarize"><img src="https://img.shields.io/badge/GitHub-OpenMOSS%2FMOSS--Transcribe--Diarize-black?logo=github"></a>
 
33
  <a href="https://arxiv.org/abs/2601.01554"><img src="https://img.shields.io/badge/arXiv-2601.01554-b31b1b?logo=arxiv"></a>
34
+ <a href="https://x.com/MosiAI_Official"><img src="https://img.shields.io/badge/Twitter-Follow-black?logo=x&amp"></a>
35
  </div>
36
 
37
+ MOSS-Transcribe-Diarize 0.9B is an open-source SOTA end-to-end audio understanding model for long-form multi-speaker transcription, diarization, timestamps, and acoustic event awareness. MOSS-Transcribe-Diarize Pro is a stronger model with higher overall performance and will be available through API access soon.
 
 
 
 
38
 
39
  ## News
40
 
41
+ * 2026-07-14: 🏆 MOSS-Transcribe-Diarize won first place in the [2nd MLC-SLM Challenge](https://www.nexdata.ai/competition/mlc-slm) at INTERSPEECH 2026, covering 14 languages.
42
+ * 2026-07-09: Open-sourced MOSS-Transcribe-Diarize 0.9B.
43
 
44
  ## Contents
45
 
46
  - [Introduction](#introduction)
47
  - [Model Architecture](#model-architecture)
48
  - [Evaluation](#evaluation)
49
+ - [Objective Evaluation](#objective-evaluation)
50
  - [Quickstart](#quickstart)
51
  - [Environment Setup](#environment-setup)
52
  - [Python Usage](#python-usage)
53
+ - [Serve with SGLang Omni](#serve-with-sglang-omni)
54
+ - [Serve with vLLM](#serve-with-vllm)
55
+ - [Custom Prompt and Hotwords](#custom-prompt-and-hotwords)
56
  - [Subtitle Web App](#subtitle-web-app)
 
 
 
57
  - [Citation](#citation)
58
 
59
  ## Introduction
60
 
61
+ MOSS-Transcribe-Diarize is our flagship SOTA model family for turning real-world long-form audio into structured, speaker-aware transcripts in one pass. Instead of stitching together separate ASR and diarization systems, these models jointly perform speech transcription and speaker diarization, producing time-aligned text with precise timestamps and consistent speaker labels such as `[S01]`, `[S02]`, and beyond.
62
+
63
+ Built for meetings, calls, podcasts, interviews, lectures, and video content, MOSS-Transcribe-Diarize is designed to handle long, messy, multi-speaker recordings where reliability matters. It can also emit optional acoustic event annotations, giving downstream systems a richer understanding of what happened, who spoke, and when.
64
+
65
+ MOSS-Transcribe-Diarize supports 50+ languages.
66
 
67
+ The model accepts raw audio and emits a compact timestamped transcript. The canonical output format is:
68
 
69
+ ```text
70
+ [start_time][Sxx]transcribed speech[end_time]
71
+ ```
72
+
73
+ Timestamps are expressed in seconds, and adjacent segments are concatenated into a single stream, for example:
74
 
75
+ ```text
76
+ [0.48][S01]Welcome everyone[1.66][12.26][S02]The new transcription pipeline is ready for evaluation[13.81][14.36][S01]Great, include the diarization results in the report[18.76]
77
+ ```
78
 
79
  ## Model Architecture
80
 
81
  <p align="center">
82
+ <img src="Model_Architecture.png" alt="MOSS-Transcribe-Diarize model architecture" width="90%" />
83
  </p>
84
 
85
+ | Component | Specification |
86
+ |---|---|
87
+ | Text backbone | Qwen3-0.6B style causal decoder |
88
+ | Audio encoder | Whisper-Medium encoder configuration |
89
+ | Audio frontend | `WhisperFeatureExtractor`, 16 kHz, 80 mel bins, 30 s chunks |
90
+ | Audio-text bridge | 4x temporal merge + MLP adaptor |
91
+ | Fusion | Audio features replace <code>&lt;&#124;audio_pad&#124;&gt;</code> embeddings via `masked_scatter` |
92
+ | Output format | Compact `[start][Sxx]text[end]` transcript with speaker tags such as `[S01]` |
93
 
94
  This Hugging Face repository includes the custom Transformers remote code required to load the model with `trust_remote_code=True`.
95
 
96
  ## Evaluation
97
 
98
+ ### Objective Evaluation
99
+
100
+ We evaluate MOSS-Transcribe-Diarize using three objective metrics: Character Error Rate (CER), concatenated minimum-permutation Character Error Rate (cpCER), and Δcp. Lower is better for all metrics. Best results are bolded, second-best results are underlined. A dash (`-`) indicates that the result is unavailable.
101
 
102
  <div style="overflow-x: auto;">
103
  <table style="white-space: nowrap;">
 
181
 
182
  ### Environment Setup
183
 
184
+ Use a clean Python environment. The project is tested with Python 3.12 and Transformers 5.x.
185
 
186
  ```bash
 
 
 
187
  git clone https://github.com/OpenMOSS/MOSS-Transcribe-Diarize.git
188
  cd MOSS-Transcribe-Diarize
189
+ uv venv --python 3.12 .venv
190
+ source .venv/bin/activate
191
+ uv pip install -e ".[torch-runtime]" --torch-backend=auto
192
  ```
193
 
194
  The GitHub package provides helper utilities such as audio/video loading, transcription message construction, transcript parsing, CLI inference, and the subtitle web app. The model weights and remote-code model files are loaded from this Hugging Face repository.
 
217
  trust_remote_code=True,
218
  dtype="auto",
219
  ).to(dtype=dtype).to(device).eval()
220
+ processor = AutoProcessor.from_pretrained(model_id, trust_remote_code=True)
 
 
 
 
221
 
222
  messages = build_transcription_messages(audio_path)
223
  result = generate_transcription(
 
236
  print(segment.start, segment.end, segment.speaker, segment.text)
237
  ```
238
 
239
+ The message flow follows the common Qwen multimodal pattern. The chat template is loaded from the model by `AutoProcessor`:
240
 
241
  1. `processor.apply_chat_template(messages, tokenize=False)` renders text with audio placeholders.
242
+ 2. `process_audio_info(messages, sampling_rate)` loads audio waveforms from the same messages.
243
  3. `processor(text=text, audio=audios)` computes Whisper input features and expands audio placeholders.
244
  4. `model.generate(...)` produces timestamped transcription and diarization text.
245
 
246
+ ### Serve with SGLang Omni
247
 
248
+ [SGLang Omni](https://github.com/sgl-project/sglang-omni) is the recommended serving backend for MOSS-Transcribe-Diarize, providing optimized long-form audio inference through the OpenAI-compatible `/v1/audio/transcriptions` endpoint.
249
 
250
+ SGLang Omni currently targets CUDA 13 environments. Please follow the official [installation guide](https://github.com/sgl-project/sglang-omni/blob/main/docs/get_started/installation.md) for the supported setup. For CUDA 12 environments, the vLLM workflow is also available below.
251
+
252
+ Download the model:
253
+
254
+ ```bash
255
+ hf download OpenMOSS-Team/MOSS-Transcribe-Diarize
256
  ```
257
 
258
+ Serve the model:
259
 
260
+ ```bash
261
+ sgl-omni serve \
262
+ --model-path OpenMOSS-Team/MOSS-Transcribe-Diarize \
263
+ --port 8000 \
264
+ --max-running-requests 16 \
265
+ --cuda-graph-max-bs 16 \
266
+ --mem-fraction-static 0.80
267
+ ```
268
+
269
+ Use `response_format=verbose_json` when you need parsed speaker segments. `json` returns the raw transcript text only.
270
+
271
+ ```bash
272
+ curl -X POST http://localhost:8000/v1/audio/transcriptions \
273
+ -F model=OpenMOSS-Team/MOSS-Transcribe-Diarize \
274
+ -F file=@audio.wav \
275
+ -F response_format=verbose_json
276
  ```
277
 
278
+ ```python
279
+ import requests
280
+
281
+ with open("audio.wav", "rb") as f:
282
+ resp = requests.post(
283
+ "http://localhost:8000/v1/audio/transcriptions",
284
+ data={
285
+ "model": "OpenMOSS-Team/MOSS-Transcribe-Diarize",
286
+ "response_format": "verbose_json",
287
+ },
288
+ files={"file": ("audio.wav", f, "audio/wav")},
289
+ timeout=300,
290
+ )
291
+
292
+ resp.raise_for_status()
293
+ payload = resp.json()
294
+ print(payload["text"])
295
+ for segment in payload.get("segments", []):
296
+ print(f"[{segment['start']:.2f}-{segment['end']:.2f}] {segment['text']}")
297
+ ```
298
+
299
+ For longer multi-speaker audio, raise `max_new_tokens` so the decoder can finish the full diarized transcript:
300
 
301
+ ```bash
302
+ curl -X POST http://localhost:8000/v1/audio/transcriptions \
303
+ -F model=OpenMOSS-Team/MOSS-Transcribe-Diarize \
304
+ -F file=@audio.wav \
305
+ -F response_format=verbose_json \
306
+ -F max_new_tokens=65536
307
+ ```
308
+
309
+ | Parameter | Type | Default | Description |
310
+ |---|---|---|---|
311
+ | `file` | file | required | Audio file uploaded as multipart form data |
312
+ | `model` | string | server default | Model identifier |
313
+ | `language` | string | unset | Optional language hint |
314
+ | `response_format` | string | `json` | `json`, `verbose_json`, or `text` |
315
+ | `temperature` | float | model default (`0.0`) | Sampling temperature |
316
+ | `max_new_tokens` | int | `5120` | Max generated tokens; raise for long audio, for example `65536` |
317
+ | `prompt` | string | unset | Optional instruction override; omit to use the built-in transcribe+diarize prompt |
318
+
319
+ For benchmarking, performance numbers, and implementation details, see the [SGLang Omni cookbook](https://github.com/sgl-project/sglang-omni/blob/main/docs/cookbook/moss_transcribe_diarize.md). The following single-H100 results are reported for short- and long-sequence multi-speaker ASR tasks.
320
+
321
+ `movies` short-sequence ASR:
322
+
323
+ | Concurrency | Throughput (req/s) | Mean latency (s) | RTF mean | audio_s/s |
324
+ |---:|---:|---:|---:|---:|
325
+ | 1 | 2.57 | 0.388 | 0.0612 | 29.76 |
326
+ | 2 | 4.89 | 0.409 | 0.0659 | 56.55 |
327
+ | 4 | 6.62 | 0.513 | 0.0790 | 76.64 |
328
+ | 8 | 6.80 | 0.533 | 0.0810 | 78.70 |
329
+ | 16 | 7.08 | 0.659 | 0.0922 | 81.98 |
330
+
331
+ `aishell4_long` long-sequence ASR:
332
+
333
+ | Concurrency | Throughput (req/s) | Mean latency (s) | RTF mean | audio_s/s |
334
+ |---:|---:|---:|---:|---:|
335
+ | 1 | 0.022 | 45.2 | 0.0197 | 50.64 |
336
+ | 2 | 0.032 | 60.7 | 0.0265 | 74.25 |
337
+ | 4 | 0.036 | 105.6 | 0.0461 | 81.64 |
338
+ | 8 | 0.040 | 172.6 | 0.0754 | 90.62 |
339
+ | 16 | 0.043 | 282.8 | 0.1237 | 98.83 |
340
+
341
+ ### Serve with vLLM
342
 
343
  MOSS-Transcribe-Diarize supports vLLM serving through the OpenAI-compatible transcription API. Use a pinned vLLM nightly build that includes the MOSS-Transcribe-Diarize model registration. Choose one of the following commands: for CUDA 12 environments, use `cu129`; for CUDA 13 environments, use `cu130`.
344
 
 
368
  -F temperature="0"
369
  ```
370
 
371
+ ### Custom Prompt and Hotwords
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
 
373
+ The default prompt is optimized for timestamped transcription and speaker diarization:
374
 
375
+ ```text
376
+ 请将音频转写为文本,每一段需以起始时间戳和说话人编号([S01]、[S02]、[S03]…)开头,正文为对应的语音内容,并在段末标注结束时间戳,以清晰标明该段语音范围。
 
 
 
377
  ```
378
 
379
+ To add hotwords, append a short hint to the default prompt:
380
 
381
+ ```text
382
+ 请将音频转写为文本,每一段需以起始时间戳和说话人编号([S01]、[S02]、[S03]…)开头,正文为对应的语音内容,并在段末标注结束时间戳,以清晰标明该段语音范围。热词提示:热词1, 热词2, 热词3
 
 
 
 
383
  ```
384
 
385
+ More prompt recipes are available in [examples/prompts.md](https://github.com/OpenMOSS/MOSS-Transcribe-Diarize/blob/main/examples/prompts.md). The same prompt can be passed to `build_transcription_messages`, `mtd-subtitle`, and `mtd-subtitle-web`.
386
 
387
  ### Subtitle Web App
388
 
389
+ The package also includes a local subtitle workflow for upload, review, subtitle export, and optional FFmpeg burn-in:
390
 
391
  ```bash
392
  mtd-subtitle-web \
 
406
  --render
407
  ```
408
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
  ## Citation
410
 
411
+ If you use MOSS-Transcribe-Diarize, please cite the technical report:
412
 
413
  ```bibtex
414
  @misc{moss_transcribe_diarize_2026,