🌿 轻松构建基于AI的实时音频应用 🌿
⚡ 快速介绍
Diart是一个用于构建基于AI的实时音频应用的Python框架。其主要特点是能够以最先进的性能实时识别不同的说话人,这项任务通常被称为"说话人分类"。
diart.SpeakerDiarization
流水线结合了说话人分割和说话人嵌入模型,为增量聚类算法提供支持,随着对话的进行,其准确性不断提高:
使用diart,您还可以创建自定义AI流水线、对其进行基准测试、调整超参数,甚至使用WebSocket在网络上提供服务。
我们提供以下预训练流水线:
- 说话人分类
- 语音活动检测
- 转录(即将推出)
- 说话人感知转录(即将推出)
💾 安装
1) 确保您的系统具备以下依赖项:
ffmpeg < 4.4
portaudio == 19.6.X
libsndfile >= 1.2.2
或者,我们提供了一个environment.yml
文件用于预配置的conda环境:
conda env create -f diart/environment.yml
conda activate diart
2) 安装软件包:
pip install diart
获取 🎹 pyannote模型的访问权限
默认情况下,diart基于huggingface hub上的pyannote.audio模型。要使用这些模型,请按以下步骤操作:
- 接受
pyannote/segmentation
模型的用户条款 - 接受最新的
pyannote/segmentation-3.0
模型的用户条款 - 接受
pyannote/embedding
模型的用户条款 - 安装huggingface-cli并使用您的用户访问令牌登录(或在diart CLI或API中手动提供)
🎙️ 音频流
从命令行
录制的对话:
diart.stream /path/to/audio.wav
实时对话:
# 使用"microphone:ID"选择非默认设备
# 查看`python -m sounddevice`获取可用设备
diart.stream microphone
默认情况下,diart运行说话人分类流水线,相当于设置--pipeline SpeakerDiarization
,但您也可以将其设置为--pipeline VoiceActivityDetection
。更多选项请参见diart.stream -h
。
从Python
使用StreamingInference
在音频源上运行流水线并将结果写入磁盘:
from diart import SpeakerDiarization
from diart.sources import MicrophoneAudioSource
from diart.inference import StreamingInference
from diart.sinks import RTTMWriter
pipeline = SpeakerDiarization()
mic = MicrophoneAudioSource()
inference = StreamingInference(pipeline, mic, do_plot=True)
inference.attach_observers(RTTMWriter(mic.uri, "/output/file.rttm"))
prediction = inference()
对于数据集的推理和评估,我们建议使用Benchmark
(参见关于可重复性的说明)。
🧠 模型
您可以使用--segmentation
和--embedding
参数来使用其他模型。
或在Python中:
import diart.models as m
segmentation = m.SegmentationModel.from_pretrained("model_name")
embedding = m.EmbeddingModel.from_pretrained("model_name")
预训练模型
以下是diart当前支持的所有模型列表:
模型名称 | 模型类型 | CPU时间* | GPU时间* |
---|---|---|---|
🤗 pyannote/segmentation (默认) | 分割 | 12ms | 8ms |
🤗 pyannote/segmentation-3.0 | 分割 | 11ms | 8ms |
🤗 pyannote/embedding (默认) | 嵌入 | 26ms | 12ms |
🤗 hbredin/wespeaker-voxceleb-resnet34-LM (ONNX) | 嵌入 | 48ms | 15ms |
🤗 pyannote/wespeaker-voxceleb-resnet34-LM (PyTorch) | 嵌入 | 150ms | 29ms |
🤗 speechbrain/spkrec-xvect-voxceleb | 嵌入 | 41ms | 15ms |
🤗 speechbrain/spkrec-ecapa-voxceleb | 嵌入 | 41ms | 14ms |
🤗 speechbrain/spkrec-ecapa-voxceleb-mel-spec | 嵌入 | 42ms | 14ms |
🤗 speechbrain/spkrec-resnet-voxceleb | 嵌入 | 41ms | 16ms |
🤗 nvidia/speakerverification_en_titanet_large | 嵌入 | 91ms | 16ms |
分割模型的延迟是在VAD流水线中测量的(5秒块)。
嵌入模型的延迟是在使用pyannote/segmentation
的说话人分离流水线中测量的(同样是5秒块)。
* CPU: AMD Ryzen 9 - GPU: RTX 4060 Max-Q
自定义模型
可以通过提供加载器函数来集成第三方模型:
from diart import SpeakerDiarization, SpeakerDiarizationConfig
from diart.models import EmbeddingModel, SegmentationModel
def segmentation_loader():
# 它应该接收一个波形并返回一个分割张量
return load_pretrained_model("my_model.ckpt")
def embedding_loader():
# 它应该接收(波形,权重)并返回每个说话人的嵌入
return load_pretrained_model("my_other_model.ckpt")
segmentation = SegmentationModel(segmentation_loader)
embedding = EmbeddingModel(embedding_loader)
config = SpeakerDiarizationConfig(
segmentation=segmentation,
embedding=embedding,
)
pipeline = SpeakerDiarization(config)
如果你有一个ONNX模型,你可以使用from_onnx()
:
from diart.models import EmbeddingModel
embedding = EmbeddingModel.from_onnx(
model_path="my_model.ckpt",
input_names=["x", "w"], # 默认为 ["waveform", "weights"]
output_name="output", # 默认为 "embedding"
)
📈 调整超参数
Diart实现了一个基于optuna的优化器,允许你根据需要调整流水线的超参数。
从命令行
diart.tune /wav/dir --reference /rttm/dir --output /output/dir
使用diart.tune -h
查看更多选项。
从Python
from diart.optim import Optimizer
optimizer = Optimizer("/wav/dir", "/rttm/dir", "/output/dir")
optimizer(num_iter=100)
这将把结果写入/output/dir
中的sqlite数据库。
分布式调优
对于更大的数据集,有时并行运行多个优化进程更方便。 要做到这一点,请在推荐的DBMS(例如MySQL或PostgreSQL)上创建一个研究,确保研究和数据库名称匹配:
mysql -u root -e "CREATE DATABASE IF NOT EXISTS example"
optuna create-study --study-name "example" --storage "mysql://root@localhost/example"
现在你可以运行多个指向这个数据库的相同优化器:
diart.tune /wav/dir --reference /rttm/dir --storage mysql://root@localhost/example
或在Python中:
from diart.optim import Optimizer
from optuna.samplers import TPESampler
import optuna
db = "mysql://root@localhost/example"
study = optuna.load_study("example", db, TPESampler())
optimizer = Optimizer("/wav/dir", "/rttm/dir", study)
optimizer(num_iter=100)
🧠🔗 构建流水线
对于更高级的用法,diart还提供了可以组合以创建自己的流水线的构建块。
流式处理由RxPY提供支持,但blocks
模块完全独立,可以单独使用。
示例
从麦克风流中获取考虑重叠的说话人嵌入:
import rx.operators as ops
import diart.operators as dops
from diart.sources import MicrophoneAudioSource
from diart.blocks import SpeakerSegmentation, OverlapAwareSpeakerEmbedding
segmentation = SpeakerSegmentation.from_pretrained("pyannote/segmentation")
embedding = OverlapAwareSpeakerEmbedding.from_pretrained("pyannote/embedding")
mic = MicrophoneAudioSource()
stream = mic.stream.pipe(
# 重新格式化流为5秒持续时间和500毫秒移动
dops.rearrange_audio_stream(sample_rate=segmentation.model.sample_rate),
ops.map(lambda wav: (wav, segmentation(wav))),
ops.starmap(embedding)
).subscribe(on_next=lambda emb: print(emb.shape))
mic.read()
输出:
# 形状为(批次大小,说话人数量,嵌入维度)
torch.Size([1, 3, 512])
torch.Size([1, 3, 512])
torch.Size([1, 3, 512])
...
🌐 WebSockets
Diart还兼容WebSocket协议,可以在网络上提供流水线服务。
从命令行
diart.serve --host 0.0.0.0 --port 7007
diart.client microphone --host <server-address> --port 7007
注意: 确保客户端使用与服务器相同的step
和sample_rate
,可以通过--step
和-sr
设置。
使用-h
查看更多选项。
从Python
对于自定义解决方案,也可以在Python中使用WebSocketAudioSource
创建服务器:
from diart import SpeakerDiarization
from diart.sources import WebSocketAudioSource
from diart.inference import StreamingInference
pipeline = SpeakerDiarization()
source = WebSocketAudioSource(pipeline.config.sample_rate, "localhost", 7007)
inference = StreamingInference(pipeline, source)
inference.attach_hooks(lambda ann_wav: source.send(ann_wav[0].to_rttm()))
prediction = inference()
🔬 由研究驱动
Diart是论文基于端到端局部分割的考虑重叠的低延迟在线说话人分离的官方实现, 作者为Juan Manuel Coria、 Hervé Bredin、 Sahar Ghannay 和Sophie Rosset。
我们提出将在线说话人分类问题视为增量聚类和局部分类的结合,应用于每500毫秒更新一次的滚动缓冲区。提出的流程中的每一步都旨在充分利用最近提出的端到端重叠感知分割模型在检测和分离重叠说话人方面的强大能力。特别是,我们提出了统计池化层(最初在x-vector架构中引入)的修改版本,以降低分割模型预测同时说话人的帧的权重。此外,我们从初始分割步骤中导出不可链接约束,以防止两个局部说话人在增量聚类步骤中被错误合并。最后,我们展示了如何将所提出方法的延迟在500毫秒到5秒之间调整,以满足特定用例的要求,并系统分析了延迟对整体性能的影响(在AMI、DIHARD和VoxConverse数据集上)。
引用
如果您发现diart有用,请务必引用我们的论文:
@inproceedings{diart,
author={Coria, Juan M. and Bredin, Hervé and Ghannay, Sahar and Rosset, Sophie},
booktitle={2021 IEEE Automatic Speech Recognition and Understanding Workshop (ASRU)},
title={Overlap-Aware Low-Latency Online Speaker Diarization Based on End-to-End Local Segmentation},
year={2021},
pages={1139-1146},
doi={10.1109/ASRU51503.2021.9688044},
}
可重复性
重要: 我们强烈建议安装 pyannote.audio<3.1
以复现这些结果。
更多信息,请参阅此问题。
Diart 旨在轻量化并能够在实际场景中实现实时流式处理。 其性能与论文中报告的非常接近(有时甚至略好)。
为获得最佳结果,请确保使用以下超参数:
数据集 | 延迟 | tau | rho | delta |
---|---|---|---|---|
DIHARD III | 任意 | 0.555 | 0.422 | 1.517 |
AMI | 任意 | 0.507 | 0.006 | 1.057 |
VoxConverse | 任意 | 0.576 | 0.915 | 0.648 |
DIHARD II | 1秒 | 0.619 | 0.326 | 0.997 |
DIHARD II | 5秒 | 0.555 | 0.422 | 1.517 |
diart.benchmark
和 diart.inference.Benchmark
可以运行、评估并测量流程的实时延迟。例如,对于 DIHARD III 配置:
diart.benchmark /wav/dir --reference /rttm/dir --tau-active=0.555 --rho-update=0.422 --delta-new=1.517 --segmentation pyannote/segmentation@Interspeech2021
或使用推理 API:
from diart.inference import Benchmark, Parallelize
from diart import SpeakerDiarization, SpeakerDiarizationConfig
from diart.models import SegmentationModel
benchmark = Benchmark("/wav/dir", "/rttm/dir")
model_name = "pyannote/segmentation@Interspeech2021"
model = SegmentationModel.from_pretrained(model_name)
config = SpeakerDiarizationConfig(
# 设置论文中使用的分割模型
segmentation=model,
step=0.5,
latency=0.5,
tau_active=0.555,
rho_update=0.422,
delta_new=1.517
)
benchmark(SpeakerDiarization, config)
# 并行运行相同的基准测试
p_benchmark = Parallelize(benchmark, num_workers=4)
if __name__ == "__main__": # 多进程需要
p_benchmark(SpeakerDiarization, config)
这会预先计算模型输出的批次,因此运行速度会快很多。
有关更多选项,请参阅 diart.benchmark -h
。
为方便起见并促进未来的比较,我们还提供了 论文实现的预期输出 ,以 RTTM 格式提供表 1 和图 5 中每个条目的结果。 这包括 VBx 离线基线以及我们提出的在线方法,延迟分别为 500 毫秒、1 秒、2 秒、3 秒、4 秒和 5 秒。
📑 许可证
MIT 许可证
版权所有 (c) 2021 巴黎-萨克雷大学
版权所有 (c) 2021 法国国家科学研究中心
特此免费授予任何获得本软件及相关文档文件("软件")副本的人不受限制地处理本软件的权利,
包括但不限于使用、复制、修改、合并、出版、发布、再许可和/或销售软件副本的权利,
以及允许向其提供软件的人这样做,但须符合以下条件:
上述版权声明和本许可声明应包含在本软件的所有副本或实质性部分中。
本软件按"原样"提供,不附带任何明示或暗示的担保,包括但不限于对适销性、特定用途适用性和
非侵权性的担保。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,
无论是在合同诉讼、侵权行为还是其他方面,由软件或软件的使用或其他交易引起、引起或与之相关。
Logo 由 DesignEvo 免费 logo 设计器 生成