如何将openai-whisper分词器集成到spaCy并保留前导空格实体?
问题解决:OpenAI Whisper Tokenizer集成spaCy及保留实体前导空格
一、Whisper Tokenizer作为spaCy自定义分词器的正确集成方式
直接将Tokenizer赋值给nlp.tokenizer会报错,因为spaCy的分词器需要遵循内部Tokenizer接口规范,而Whisper的Tokenizer是为语音转文本设计的,接口与spaCy不兼容。正确做法是自定义适配类,将Whisper的分词逻辑包装成spaCy可识别的格式:
import spacy from spacy.tokens import Doc from whisper.tokenizer import get_tokenizer # 加载spaCy模型 nlp = spacy.load("en_core_web_sm") # 自定义适配spaCy的Whisper分词器类 class WhisperSpaCyTokenizer: def __init__(self, vocab): self.vocab = vocab # 初始化Whisper分词器(以英文为例,可按需调整参数) self.whisper_tokenizer = get_tokenizer(multilingual=False, language="en") def __call__(self, text): # 使用Whisper分词器编码文本 token_ids = self.whisper_tokenizer.encode(text) # 将token ID转换为对应文本 token_texts = [self.whisper_tokenizer.decode([tid]) for tid in token_ids] # 标记哪些token是空格(用于spaDoc的空格属性) space_token_id = self.whisper_tokenizer.encode(" ")[0] spaces = [tid == space_token_id for tid in token_ids] # 构造符合spaCy规范的Doc对象 return Doc(self.vocab, words=token_texts, spaces=spaces) # 替换spaCy默认分词器 nlp.tokenizer = WhisperSpaCyTokenizer(nlp.vocab) # 测试分词效果 doc = nlp(" Toby makes fun") print([token.text for token in doc])
二、保留实体前导空格的解决方案
spaCy的ent.text默认返回实体token的纯文本,会剥离前导空格。要保留原始文本中的空格,需根据实体在原始文本中的字符位置直接截取:
nlp = spacy.load("en_core_web_sm") raw_text = " Toby makes fun" ref_doc = nlp(raw_text) # 从原始文本中截取带空格的实体内容 entities_with_space = [] for ent in ref_doc.ents: # 利用实体的字符起止索引,从原始文本中提取完整内容 ent_full_text = raw_text[ent.start_char:ent.end_char] entities_with_space.append((ent_full_text, ent.label_)) print(entities_with_space) # 输出:[(' Toby', 'PERSON')]
说明
ent.start_char和ent.end_char是实体在原始文本中的准确字符位置,基于此截取的内容会完整保留原始格式(包括前导空格)。- 即使替换了Whisper分词器,只要
Doc对象正确维护了字符位置映射,该方法依然有效。
内容的提问来源于stack exchange,提问作者afsara_ben
相关产品推荐
相关产品推荐

