> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-zh/yin-pin-yu-yu-yin/whisperx.md).

# 带说话人分离的 WhisperX

在 Clore.ai GPU 上运行 WhisperX，实现带词级时间戳和说话人分离的快速语音转录。

WhisperX 为 OpenAI 的 Whisper 增加了三项关键升级： **词级时间戳** 通过强制音素对齐， **说话人分离** 使用 pyannote.audio，以及 **最高可达 70× 实时速度** 通过使用 faster-whisper 进行批量推理实现。它是生产级转录流水线中需要精确时间和说话人识别的首选工具。

**GitHub：** [m-bain/whisperX](https://github.com/m-bain/whisperX) **PyPI：** [whisperx](https://pypi.org/project/whisperx/) **许可证：** BSD-4-Clause **论文：** [arxiv.org/abs/2303.00747](https://arxiv.org/abs/2303.00747)

## 主要特性

* **词级时间戳** — 通过 wav2vec2 强制对齐实现 ±50 毫秒精度（而原版 Whisper 为 ±500 毫秒）
* **说话人分离** — 通过 pyannote.audio 3.1 识别谁说了什么
* **批量推理** — 在 RTX 4090 上最高可达 70× 实时速度
* **VAD 预过滤** — Silero VAD 在转录前去除静音
* **所有 Whisper 模型** — 从 tiny 到 large-v3-turbo
* **多种输出格式** — JSON、SRT、VTT、TXT、TSV
* **自动语言检测** — 或强制指定特定语言以加快处理

## 需求

| 组件     | 最低             | 推荐                     |
| ------ | -------------- | ---------------------- |
| GPU    | RTX 3060 12 GB | RTX 4090 24 GB         |
| 显存     | 4 GB（小型模型）     | 10 GB+（large-v3-turbo） |
| 内存     | 8 GB           | 16 GB+                 |
| 磁盘     | 5 GB           | 20 GB（模型缓存）            |
| Python | 3.9+           | 3.11                   |
| CUDA   | 12.8+          | 12.8+                  |

**需要 HuggingFace 令牌** 用于说话人分离 — 请在以下位置接受许可协议 [pyannote/speaker-diarization-3.1](https://huggingface.co/pyannote/speaker-diarization-3.1).

**Clore.ai 推荐：** RTX 3090（0.07–0.21 美元/小时）适用于 batch size 为 16 的 large-v3-turbo 模型。RTX 4090（0.14–0.42 美元/小时）适用于 batch size 为 32 时的最大吞吐量。

## 安装

```bash
# 安装 WhisperX
pip install whisperx

# 验证 GPU
python -c "import torch; print(torch.cuda.get_device_name(0))"
```

如果遇到 CUDA 版本冲突：

```bash
pip install torch==2.5.1+cu124 torchaudio==2.5.1+cu124 --index-url https://download.pytorch.org/whl/cu128
pip install whisperx
```

## 快速开始

```python
import whisperx
import json

device = "cuda"
compute_type = "float16"  # "int8" 可降低 VRAM 占用
batch_size = 16            # 如果 VRAM 紧张，可降到 4-8

# 1. 加载模型
model = whisperx.load_model("large-v3-turbo", device, compute_type=compute_type)

# 2. 加载并转录音频
audio = whisperx.load_audio("interview.mp3")
result = model.transcribe(audio, batch_size=batch_size)
print(f"语言：{result['language']}")

# 3. 对齐以获得词级时间戳
model_a, metadata = whisperx.load_align_model(
    language_code=result["language"], device=device
)
result = whisperx.align(
    result["segments"], model_a, metadata, audio, device,
    return_char_alignments=False,
)

# 4. 打印结果
for seg in result["segments"]:
    print(f"[{seg['start']:.2f}s → {seg['end']:.2f}s] {seg['text']}")
    for w in seg.get("words", []):
        print(f"  '{w['word']}' @ {w.get('start', 0):.2f}s")

# 5. 保存
with open("transcript.json", "w") as f:
    json.dump(result, f, indent=2, ensure_ascii=False)
```

## 使用示例

### 带说话人分离的转录

```python
import whisperx
import gc
import torch

device = "cuda"
HF_TOKEN = "hf_your_token_here"  # 来自 huggingface.co/settings/tokens

# 第 1 步：转录
model = whisperx.load_model("large-v3-turbo", device, compute_type="float16")
audio = whisperx.load_audio("meeting.mp3")
result = model.transcribe(audio, batch_size=16)

# 在加载对齐模型前释放 GPU 内存
del model; gc.collect(); torch.cuda.empty_cache()

# 第 2 步：对齐
model_a, metadata = whisperx.load_align_model(
    language_code=result["language"], device=device
)
result = whisperx.align(result["segments"], model_a, metadata, audio, device)
del model_a; gc.collect(); torch.cuda.empty_cache()

# 第 3 步：说话人分离
diarize_model = whisperx.DiarizationPipeline(
    use_auth_token=HF_TOKEN, device=device
)
diarize_segments = diarize_model(audio, min_speakers=2, max_speakers=6)

# 第 4 步：为词分配说话人
result = whisperx.assign_word_speakers(diarize_segments, result)

for seg in result["segments"]:
    speaker = seg.get("speaker", "UNKNOWN")
    print(f"[{speaker}] [{seg['start']:.1f}s → {seg['end']:.1f}s] {seg['text']}")
```

### 命令行用法

```bash
# 基础转录
whisperx audio.mp3 --model large-v3-turbo --device cuda

# 强制指定语言（更快，跳过检测）
whisperx audio.mp3 --model large-v3-turbo --language en --device cuda

# 带说话人分离
whisperx audio.mp3 --model large-v3-turbo --diarize --hf_token hf_your_token

# SRT 字幕输出
whisperx audio.mp3 --model large-v3-turbo --output_format srt --output_dir ./subs/

# 低 VRAM 模式
whisperx audio.mp3 --model medium --compute_type int8 --batch_size 4 --device cuda

# 批量处理目录
for f in /data/audio/*.mp3; do
  whisperx "$f" --model large-v3-turbo --output_dir /data/transcripts/
done
```

### SRT 生成脚本

```python
import whisperx

def transcribe_to_srt(audio_path, output_path, model_name="large-v3-turbo"):
    device = "cuda"
    model = whisperx.load_model(model_name, device, compute_type="float16")
    audio = whisperx.load_audio(audio_path)
    result = model.transcribe(audio, batch_size=16)

    model_a, metadata = whisperx.load_align_model(
        language_code=result["language"], device=device
    )
    result = whisperx.align(result["segments"], model_a, metadata, audio, device)

    with open(output_path, "w") as f:
        for i, seg in enumerate(result["segments"], 1):
            start = format_ts(seg["start"])
            end = format_ts(seg["end"])
            f.write(f"{i}\n{start} --> {end}\n{seg['text'].strip()}\n\n")

    print(f"SRT 已保存到 {output_path}")

def format_ts(seconds):
    h = int(seconds // 3600)
    m = int((seconds % 3600) // 60)
    s = int(seconds % 60)
    ms = int((seconds % 1) * 1000)
    return f"{h:02d}:{m:02d}:{s:02d},{ms:03d}"

transcribe_to_srt("podcast.mp3", "podcast.srt")
```

## 性能基准

| 方法             | 模型                 | 1 小时音频     | GPU          | 大致速度      |
| -------------- | ------------------ | ---------- | ------------ | --------- |
| 原版 Whisper     | large-v3           | \~60 分钟    | RTX 3090     | 1×        |
| faster-whisper | large-v3           | \~5 分钟     | RTX 3090     | \~12×     |
| **WhisperX**   | **large-v3-turbo** | **\~1 分钟** | **RTX 3090** | **\~60×** |
| **WhisperX**   | **large-v3-turbo** | **\~50 秒** | **RTX 4090** | **\~70×** |

| 批量大小 | 速度（RTX 4090） | 显存    |
| ---- | ------------ | ----- |
| 4    | \~30× 实时     | 6 GB  |
| 8    | \~45× 实时     | 8 GB  |
| 16   | \~60× 实时     | 10 GB |
| 32   | \~70× 实时     | 14 GB |

## 给 Clore.ai 用户的建议

* **在步骤之间释放 VRAM** — 删除模型并调用 `torch.cuda.empty_cache()` 在转录、对齐和说话人分离之间
* **HuggingFace 令牌** — 在说话人分离可用前，必须先接受 pyannote 模型许可协议；设置 `HF_TOKEN` 为环境变量
* **batch size 调优** — 从 `batch_size=16`开始，在 12 GB 显卡上降到 4–8，在 24 GB 显卡上提高到 32
* **`int8` 计算** — 使用 `compute_type="int8"` 在几乎不损失质量的情况下将 VRAM 占用减半
* **Docker 镜像** — `pytorch/pytorch:2.11.0-cuda12.8-cudnn9-runtime`
* **持久化模型缓存** — 挂载 `/root/.cache/huggingface` 以避免每次容器重启时重新下载模型

## 故障排查

| 问题                    | 解决方案                                                                  |
| --------------------- | --------------------------------------------------------------------- |
| `CUDA 内存不足`           | 减少 `batch_size`，使用 `compute_type="int8"`，或使用更小的模型（medium、small）       |
| 说话人分离返回 `UNKNOWN`     | 请确保 HuggingFace 令牌有效，并且你已接受 pyannote 许可协议                             |
| `没有名为 'whisperx' 的模块` | `pip install whisperx` — 请确保没有拼写错误（它是 `whisperx`，不是 `whisper-x`)      |
| 词级时间戳较差               | 请检查 `whisperx.align()` 是否在 `transcribe()` 之后调用 — 原始 Whisper 输出不具备词级精度 |
| 语言检测错误                | 使用以下方式强制指定语言 `--language en` 或 `language="en"` 在 Python API 中         |
| 处理缓慢                  | 增大 `batch_size`，使用 `large-v3-turbo` 替代 `large-v3`，请确保 GPU 没有被共享       |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-zh/yin-pin-yu-yu-yin/whisperx.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
