目录
PreTrainedTokenizerFast
python
from transformers import PreTrainedTokenizerFast
tokenizer = PreTrainedTokenizerFast.from_pretrained("openai/whisper-base")
tokenizer 的词表(vocabulary)
self.vocab = self.processor.tokenizer.get_vocab() whisper 这个是什么
Whisper 模型是 OpenAI 推出的一个语音识别(ASR)模型,其输入是音频,但它的输出是文本。文本输出是通过一个 tokenizer 将文字转换成 token ID(数字)再经过模型预测输出的。
python
self.processor.tokenizer.get_vocab()
-
self.processor
:通常是一个WhisperProcessor
实例,封装了 Whisper 模型使用的 tokenizer 和 feature extractor。 -
self.processor.tokenizer
:是 Whisper 使用的 tokenizer(比如基于SentencePiece
的 tokenizer)。 -
get_vocab()
:返回一个字典{token_string: token_id}
,即词表。
🔍 举例:
返回值可能是这样的一个字典(只是示意):
python
{ "<s>": 0, "</s>": 1,
"hello": 432,
"world": 987,
"▁the": 52,
"▁": 3,
"": 50256, ... }
其中:
-
token 是字符串,有些前面带
▁
(表示空格,来源于 SentencePiece/BPE) -
值是整数,是对应 token 的 ID
📌 使用场景:
-
分析模型词表分布,比如哪些 token 被频繁使用;
-
实现 token 到字符的反向映射(
vocab.items()
反转可得到{id: token}
); -
做语言分析、可视化、调试等。
whisper 获取 tokenizer
python
# coding=utf-8
import sys
import os
current_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(current_dir)
print('current_dir', current_dir)
paths = [current_dir, current_dir+'/../']
paths.append(os.path.join(current_dir, 'src'))
for path in paths:
sys.path.insert(0, path)
os.environ['PYTHONPATH'] = (os.environ.get('PYTHONPATH', '') + ':' + path).strip(':')
from addict import Dict
from transformers import Seq2SeqTrainer, Seq2SeqTrainingArguments, WhisperForConditionalGeneration, WhisperProcessor
from typing import List
def _load_timestamps_transcript(self, transcript: List[dict]):
assert isinstance(transcript, list), f"transcript应该为list,当前为:{type(transcript)}"
data = dict()
labels = self.processor.tokenizer.prefix_tokens[:3]
for t in transcript:
# 将目标文本编码为标签ID
start = t['start'] if round(t['start'] * 100) % 2 == 0 else t['start'] + 0.01
if self.timestamp_begin is None:
start = self.vocab[f'<|{start:.2f}|>']
else:
start = self.timestamp_begin + round(start * 100) // 2
end = t['end'] if round(t['end'] * 100) % 2 == 0 else t['end'] - 0.01
if self.timestamp_begin is None:
end = self.vocab[f'<|{end:.2f}|>']
else:
end = self.timestamp_begin + round(end * 100) // 2
label = self.processor(text=t['text']).input_ids[4:-1]
labels.extend([start])
labels.extend(label)
labels.extend([end])
data['labels'] = labels + [self.endoftext]
return data
if __name__ == '__main__':
args = Dict()
args.base_model="models/whisper-large-v3-finetune"
args.language='zh'
args.task="transcribe"#['transcribe', 'translate']
args.timestamps=False
args.local_files_only=True
args.processor = WhisperProcessor.from_pretrained(args.base_model,
language=args.language,
task=args.task,
no_timestamps=not args.timestamps,
local_files_only=args.local_files_only)
labels = args.processor.tokenizer.prefix_tokens[:3]
print(labels)
transcript=["asdf"]
_load_timestamps_transcript(args, transcript)
labels值:[50258, 50260, 50360]
labels值都一样吗
不,值不一样 。prefix_tokens[:3]
的值会根据以下参数变化:
-
语言参数 (
args.language
): 不同语言对应不同的token ID- 英语可能是50358
- 中文可能是50359
- 西班牙语可能是50360
- 以此类推(具体值取决于Whisper的tokenizer实现)
-
任务参数 (
args.task
):- "transcribe"(转录)对应一个token ID
- "translate"(翻译)对应另一个token ID
例如:
- 英语转录任务:
[50258, 50358, 50359]
(对应<|startoftranscript|>
,<|en|>
,<|transcribe|>
) - 中文翻译任务:
[50258, 50359, 50363]
(对应<|startoftranscript|>
,<|zh|>
,<|translate|>
)
为什么需要这些labels?
这些前缀标记是Whisper模型能够支持多语言、多任务的关键机制。模型通过这些特殊标记来"知道":
- 输入语音是什么语言
- 应该执行转录还是翻译任务
- 输出应该是什么语言(翻译任务时)
当您设置language=args.language
和task=args.task
参数时,WhisperProcessor会自动为您生成相应的prefix tokens,这就是为什么labels
的值会随着这些参数变化而变化。
这是Whisper区别于其他语音识别模型的一个重要特点,使它能够用一个统一的模型处理多种语言和任务。