在 GitHub 上执行或查看/下载此笔记本
文本分词
为什么我们需要分词?
几乎所有语言都拥有数量庞大的可能词汇。因此,处理文本的机器学习任务必须支持包含数千个单词的大词汇表。然而,处理如此庞大的词汇表至关重要。输入和输出嵌入(例如 one-hot 向量)通常是巨大的向量,这会导致内存消耗和内存使用增加。更重要的是,使用这种极其稀疏和高维的嵌入进行学习可能不是最优的。
一个简单的方法是直接使用字符代替单词。后一种方法减轻了上述一些问题,但它需要处理更长的序列(从机器学习角度来看,这也是一个关键问题)。
我们能否在单词和字符之间找到一个折衷方案?是的,这就是分词器试图做的事情。
一种流行的技术称为基于规则的分词(例如spaCy),它允许根据语法规则、空格和标点符号将文本分割成更小的块。不幸的是,这种方法是语言相关的,必须针对每种考虑的语言进行设置……
另一种结合词级和字符级分词优点的方法是一种混合解决方案,称为子词分词,其原理是常用词不应被分割成更小的子词,而罕见词应被分解成有意义的(即更频繁的)子词。
SpeechBrain 目前依赖于对SentencePiece 分词器的自定义集成,它将输入视为原始输入流。支持以下分词器算法:
SentencePiece 分词器在 speechbrain.tokenizer.SentencePiece
中可用。接下来,我们将介绍上述所有技术,但首先,让我们安装 SpeechBrain。
%%capture
# Installing SpeechBrain via pip
BRANCH = 'develop'
!python -m pip install git+https://github.com/speechbrain/speechbrain.git@$BRANCH
# Clone SpeechBrain repository
!git clone https://github.com/speechbrain/speechbrain/
%cd /content/speechbrain/
我们还需要下载一个 csv 文件来训练我们的分词器。
%%capture
!wget https://www.dropbox.com/s/atg0zycfbacmwqi/dev-clean.csv
在 SpeechBrain 中训练 sentencepiece 分词器
SentencePiece 是一个可以通过少量参数实例化的类
model_dir:这是训练好的分词器模型保存的目录。模型将保存为
model_dir/model_type_vocab_size.model
vocab_sizes:这是所选分词器类型(BPE,Unigram)的词汇表大小。对于字符分词,vocab_size 是可选的;对于 BPE 和 unigram 分词,它是强制的。
csv_train:这是用于学习分词器的 csv 文件路径。
csv_read:这是包含 csv 文件中词序列的数据条目 (csv 头)。
model_type:可以是:word, char, bpe 或 unigram 分词。
现在,我们将其应用于我们的 dev-clean.csv。
import torch
from speechbrain.tokenizers.SentencePiece import SentencePiece
spm = SentencePiece(model_dir="tokenizer_data",
vocab_size=2000,
annotation_train="dev-clean.csv",
annotation_read="wrd",
model_type="bpe",
annotation_list_to_check=["dev-clean.csv"])
%less tokenizer_data/2000_bpe.vocab
如您所见,SetencePiece 库是一个无监督的文本分词器和解分词器。一些 token 带有代表空格的 _
符号。sentence piece 解分词将简单地合并 token 序列并将 _
替换为空格。
高级参数
character_coverage
:模型覆盖的字符数(取值范围 [0.98 - 1])。默认值:对于字符集较小的语言为 1.0。对于字符集丰富的语言,如日语或中文,可以设置为 0.995。bos_id/eos_id/pad_id/unk_id
:允许用户为bos/eos/pad and unk
token 定义特定索引。split_by_whitespace
:此参数允许 sentencepiece 提取交叉词片段并将空格视为一个唯一的 token。num_sequences
:最多使用num_sequences
来训练分词器(限制大型数据集的训练文本)。csv_list_to_check
:用于检查分词器恢复单词准确性的 csv 文件列表。user_defined_symbols
:这是一个字符串列表(用逗号“,”分隔),强制插入特定词汇。
例如,如果我们将 character_coverage
设置为 0.98
并减小 vocab_size
spm = SentencePiece(model_dir="tokenizer_data",
vocab_size=500,
annotation_train="dev-clean.csv",
annotation_read="wrd",
model_type="unigram",
character_coverage=0.98,
annotation_list_to_check=["dev-clean.csv"])
如我们所见,由于缺少一些字符,我们无法从文本中恢复所有单词。
在 SpeechBrain 中加载预训练的 sentence piece 分词器
加载 sentencepiece 分词器非常简单。我们只需要指定模型的路径、vocab_size
和 model_type
。
spm = SentencePiece(model_dir="tokenizer_data",
vocab_size=2000,
model_type="bpe")
现在,我们可以直接使用从 tokenizer_data/2000_bpe.model
加载的分词器。此功能对于复现结果非常有用。例如,您可以将您的分词器上传到互联网,其他人可以下载它以获得与您相同的分词结果。
如何使用 sentencepiece
SentencePiece 对象可在 speechbrain.tokenizer.SentencePiece.sp
访问。通过访问此对象,您可以轻松地执行分词和解分词。如果您对 SentencePiece 的所有功能感兴趣,请随时阅读官方教程。
让我们尝试对一些文本进行分词和解分词!
# Encode as pieces
print(spm.sp.encode_as_pieces('THIS IS A TEST'))
# Encode as ids
print(spm.sp.encode_as_ids('THIS IS A TEST'))
# Decode from ids
print(spm.sp.decode_ids([244, 177, 3, 1, 97]))
# Decode from pieces
print(spm.sp.decode_pieces(['▁THIS', '▁IS', '▁A', '▁T', 'EST']))
将 SpeechBrain SentencePiece 与 PyTorch 一起使用
我们设计了 SentencePiece 包装器,以便与我们的数据转换管道(请参阅教程)一起使用,从而处理张量。为此,有两种选项可用:
选项 1:直接从单词张量 + 名为
int2lab
的外部字典(将您的张量映射到单词)生成 token 张量。选项 2:如果您使用我们的 DynamicDataset,DynamicItem 将自动生成 token 张量。
选项 1 示例
# INPUTS
# word vocab
dict_int2lab = {1: "HELLO", 2: "WORLD", 3: "GOOD", 4:"MORNING"}
# wrd tensors
wrd_tensor = torch.Tensor([[1, 2, 0], [3,4,2]])
# relative lens tensor (will help for dealing with padding)
lens_tensor = torch.Tensor([0.75, 1.0])
我们的 SentencePiece 可以像任何其他 pytorch 函数一样调用,并将张量传递给 call 方法。参数如下: batch:这是一个 word_ids 张量(即您的单词)。形状:[batch_size, max_seq_lenght] batch_lens:这是一个相对长度张量。形状:[batch_size] int2lab:将 word_ids 映射到单词的字典。 task:“encode”:将单词 batch 张量转换为 token 张量。“decode”:将 token 张量转换为单词序列列表。“decode_from_list”:将 token 序列列表转换为单词序列列表。
encoded_seq_ids, encoded_seq_lens = spm(
wrd_tensor,
lens_tensor,
dict_int2lab,
"encode",
)
# tokens tensor
print(encoded_seq_ids)
# relative lens token tensor
print(encoded_seq_lens)
然后,我们可以简单地通过为函数指定 "decode"
来对其进行解码!
# decode from torch tensors (batch, batch_lens)
words_seq = spm(encoded_seq_ids, encoded_seq_lens, task="decode")
print(words_seq)
选项 2 示例
注意:请先阅读我们的 dataio 教程,以便完全理解接下来的内容。
在这里,我们使用分词器对从 .csv 文件获得的文本进行动态分词。在以下示例中,我们将其与 SpeechBrain 的 data_io 管道结合使用。
首先,我们从 csv 文件定义一个 DynamicItemDataset
import speechbrain as sb
train_set = sb.dataio.dataset.DynamicItemDataset.from_csv(
csv_path="dev-clean.csv",
)
%less dev-clean.csv
然后,我们定义 text_pipeline(即为迷你批次中收集的每个样本调用的内容)。在 text_pipeline 中,我们只需调用分词器即可获得分词后的文本!
@sb.utils.data_pipeline.takes("wrd")
@sb.utils.data_pipeline.provides(
"wrd", "tokens_list", "tokens"
)
def text_pipeline(wrd):
yield wrd
tokens_list = spm.sp.encode_as_ids(wrd)
yield tokens_list
tokens = torch.LongTensor(tokens_list)
yield tokens
一些额外的 SpeechBrain 内容以完成数据管道
train_set.add_dynamic_item(text_pipeline)
train_set.set_output_keys(["wrd", "tokens", "tokens_list"])
最后,我们创建一个包含已定义转换(即分词器)的数据加载器。
train_dataloader = sb.dataio.dataloader.make_dataloader(train_set, batch_size=1)
现在,我们可以轻松地获取我们的分词样本!!
b = next(iter(train_dataloader))
print(b.wrd)
print(b.tokens)
print(b.tokens_list)
引用 SpeechBrain
如果您在研究或商业中使用 SpeechBrain,请使用以下 BibTeX 条目引用它:
@misc{speechbrainV1,
title={Open-Source Conversational AI with {SpeechBrain} 1.0},
author={Mirco Ravanelli and Titouan Parcollet and Adel Moumen and Sylvain de Langen and Cem Subakan and Peter Plantinga and Yingzhi Wang and Pooneh Mousavi and Luca Della Libera and Artem Ploujnikov and Francesco Paissan and Davide Borra and Salah Zaiem and Zeyu Zhao and Shucong Zhang and Georgios Karakasidis and Sung-Lin Yeh and Pierre Champion and Aku Rouhe and Rudolf Braun and Florian Mai and Juan Zuluaga-Gomez and Seyed Mahed Mousavi and Andreas Nautsch and Xuechen Liu and Sangeet Sagar and Jarod Duret and Salima Mdhaffar and Gaelle Laperriere and Mickael Rouvier and Renato De Mori and Yannick Esteve},
year={2024},
eprint={2407.00463},
archivePrefix={arXiv},
primaryClass={cs.LG},
url={https://arxiv.org/abs/2407.00463},
}
@misc{speechbrain,
title={{SpeechBrain}: A General-Purpose Speech Toolkit},
author={Mirco Ravanelli and Titouan Parcollet and Peter Plantinga and Aku Rouhe and Samuele Cornell and Loren Lugosch and Cem Subakan and Nauman Dawalatabad and Abdelwahab Heba and Jianyuan Zhong and Ju-Chieh Chou and Sung-Lin Yeh and Szu-Wei Fu and Chien-Feng Liao and Elena Rastorgueva and François Grondin and William Aris and Hwidong Na and Yan Gao and Renato De Mori and Yoshua Bengio},
year={2021},
eprint={2106.04624},
archivePrefix={arXiv},
primaryClass={eess.AS},
note={arXiv:2106.04624}
}