在CTranslate2的Whisper模型中,批量生成并不比逐个循环快。我在Translator模型上尝试了同样的事情,结果显示批量处理远远优越(快得多)。我使用ct2工具将Whisper小转换为int8。此外,批量处理时GPU内存更高,所以我认为CTranslate2正在进行“适当的”批量处理(而不是循环 Package 器)。以下是我的简单Whisper代码。
import time
import numpy as np
from ctranslate2 import StorageView
from ctranslate2.models import Whisper
from transformers import WhisperProcessor
def make_prompts(tokenizer, n: int) -> list[list[int]]:
prompt = tokenizer.convert_tokens_to_ids(
[
"<|startoftranscript|>",
"<|en|>",
"<|transcribe|>",
]
)
return [prompt] * n
def loop(
whisper: Whisper,
features: list[StorageView],
prompts: list[list[int]],
):
for feat, prompt in zip(features, prompts):
_ = whisper.generate(
feat,
[prompt],
return_scores=True,
return_no_speech_prob=True,
)
def batch(
whisper: Whisper,
features: StorageView,
prompts: list[list[int]],
):
_ = whisper.generate(
features,
prompts,
return_scores=True,
return_no_speech_prob=True,
)
def main():
N_SAMPLES = 8
N_SEC = 5
SR = 16000
# load model and processor
whisper = Whisper("models/whisper-small", device="cuda")
processor = WhisperProcessor.from_pretrained("openai/whisper-small")
tokenizer = processor.tokenizer
# generate required data
chunks = np.random.random((N_SAMPLES, N_SEC * SR)).astype(np.float32)
inputs = processor(chunks, return_tensors="np", sampling_rate=SR)
mels = inputs["input_features"]
features_loop = [StorageView.from_array(m[None, :]) for m in mels]
features_batch = StorageView.from_array(mels)
prompts = make_prompts(tokenizer, N_SAMPLES)
# warm up
print("warming up... ", end="", flush=True)
for _ in range(7):
loop(whisper, features_loop, prompts)
batch(whisper, features_batch, prompts)
print("done")
N = 20
print(f"benchmarking each method for {N} iterations")
# loop time
t0 = time.perf_counter()
for _ in range(N):
loop(whisper, features_loop, prompts)
elapsed = time.perf_counter() - t0
print(f"loop time: {elapsed:0.3f} secs")
# batch time
t0 = time.perf_counter()
for _ in range(N):
batch(whisper, features_batch, prompts)
elapsed = time.perf_counter() - t0
print(f"batch time: {elapsed:0.3f} secs")
main()
当我在colab(T4 GPU)上运行代码时,它输出:
benchmarking each method for 20 iterations
loop time: 25.311 secs
batch time: 30.086 secs
有什么办法可以提高Whisper批量生成的速度吗?
5条答案
按热度按时间wkyowqbh1#
当然!很高兴你问了!哈哈。Ctranslate2实际上确实支持真正的批处理,但在C++层面上。我会给你我的仓库,它使用
WhisperS2T
通过惊人的WhisperS2T
以及直接链接到该仓库。据我所知,关于“批处理”处理的讨论已经相当多,但由于仓库的状态,目前还不可行。另一方面,faster-whisper
具有WhisperS2T
没有的其他功能。请记住,我的仓库有点过时,因为我还没有将其更新为最新的WhisperS2T
,所以如果API有任何更改,请咨询上游。然而,如果你使用我的仓库作为样本脚本并保持版本相同,你应该没问题。我现在对
WhisperS2T
有很多经验,所以请随时联系我。https://github.com/BBC-Esq/WhisperS2T-transcriber
...以及令人惊叹的...
https://github.com/shashikg/WhisperS2T
在约150颗星的时候,它默默无闻地飞行着...但它击败了Huggingface的“疯狂”(讨厌这个名字)的Whisper实现,后者有数千颗星。这只是说明了多少颗星星的典型Huggingface仓库与他们的产品质量完全无关,而是更多地受到市场营销和网络伙伴推荐的影响。...归功于应得的荣誉。试试
whisperS2T
并期待你的反馈!9wbgstp72#
顺便说一下,我还没有时间更新我的whispers2t批处理仓库中的这个坏小子,所以请稍等。;-)
它允许您指定任务,选择任何ctranslate2量化,递归处理所有子目录,排除某些文件扩展名不被处理,更改束宽,批处理大小(感谢WhisperS2T),等等。
ssm49v7z3#
上一条帖子我承诺...但是这里是我对
WhisperS2T
的分析。我相信我的仓库使用传统的 "循环" 来处理使用 WhisperS2T...但是你也可以一次性发送一批信息直接到ctranslate2
进行处理,这本质上是WhisperS2T
运行的方式。然而,我选择了 "循环" 方法,因为如果你一次发送所有音频文件...如果有一个失败了,它们都会失败,你会得到零个转录。我发现如果我处理,比如说,500个音频文件,其中一个可能有损坏的数据,因此整个过程触发了一个错误...这个问题应该已经修复了,不过根据这个讨论:
shashikg/WhisperS2T#50
无论如何,展开下面的内容以查看我对库的分析(不是最新的版本,但仍然):
我的个人总结
esbemjvw4#
谢谢你告诉我关于WhisperS2T的信息。我会稍后查看。目前我并没有使用
faster-whisper
,而是直接使用CTranslate2。希望批量处理可以用于加速生成,但现在它与仅使用标准循环相比并没有速度提升。kqhtkvqz5#
Whisper S2T基本上直接使用ctranslate 2。