使用sentencepiece模型替换词表

本文介绍了在使用DeBERTa模型进行下游任务时,如何利用SentencePiece进行文本Tokenization。SentencePiece提供了四种切分方法,作者针对中文文本发现BPE在某些情况下效果尚可,但需要手动调整。通过训练,得到.model和.vocab文件。实验发现,增大vocab_size并不总是带来更好的效果,可能因为训练中学习到过多噪声特征。知乎上的相关实验显示,词表过大可能导致验证集表现下降。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在用DeBERTa模型跑一些下游任务,了解到了sentencepiece模型,用于替代预训练模型中的词表。

sentencepiece 是google开源的文本Tokenzier工具,本身提供四种切分方法。包括:char, word, byte-pair-encoding(bpe), unigram language model(unigram 默认类别)

经过实验对比,我发现针对中文文本,采用bpe的效果还算可以,但也存在一些问题,最好手动再进行对其进行调整。

通过对自己的文本进行训练,最后得到.model 和.vocab文件可供使用。

整个过程流程如下:

  • 安装 sentencepiece        

         整个过程比较简单,Github上有详细的介绍,这里我使用vcpkg进行安装。​​

Installation

Python module

SentencePiece provides Python wrapper that supports both SentencePiece training and segmentation. You can install Python binary package of SentencePiece with.

% pip install sentencepiece

For more detail, see Python module

Build and install SentencePiece command line tools from C++ source

The following tools and libraries are required to build SentencePiece:

  • cmake
  • C++11 compiler
  • gperftools library (optional, 10-40% performance improvement can be obtained.)

On Ubuntu, the build tools can be installed with apt-get:

% sudo apt-get install cmake build-essential pkg-config libgoogle-perftools-dev

Then, you can build and install command line tools as follows.

% git clone https://github.com/google/sentencepiece.git 
% cd sentencepiece
% mkdir build
% cd build
% cmake ..
% make -j $(nproc)
% sudo make install
% sudo ldconfig -v

On OSX/macOS, replace the last command with sudo update_dyld_shared_cache

Build and install using vcpkg

You can download and install sentencepiece using the vcpkg dependency manager:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install sentencepiece

The sentencepiece port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

  • 训练sentencepiece模型

        很简单,也是一句话的事,不过如果采用bpe进行训练的话,随着vocab_size的上升,时间会变得很长。我针对一个20GB+的中文文本进行训练,将vocab_size设置为320000,后台运行了一整天。

Train SentencePiece Model

% spm_train --input=<input> --model_prefix=<model_name> --vocab_size=8000 --character_coverage=1.0 --model_type=<type>
  • --input: one-sentence-per-line raw corpus file. No need to run tokenizer, normalizer or preprocessor. By default, SentencePiece normalizes the input with Unicode NFKC. You can pass a comma-separated list of files.
  • --model_prefix: output model name prefix. <model_name>.model and <model_name>.vocab are generated.
  • --vocab_size: vocabulary size, e.g., 8000, 16000, or 32000
  • --character_coverage: amount of characters covered by the model, good defaults are: 0.9995 for languages with rich character set like Japanese or Chinese and 1.0 for other languages with small character set.
  • --model_type: model type. Choose from unigram (default), bpechar, or word. The input sentence must be pretokenized when using word type.

        代码如图所示: 

import sentencepiece as spm

spm.SentencePieceTrainer.Train(input='/data/data.txt', model_prefix='/data/sentencepiece/mypiece', vocab_size=320000, character_coverage=1, model_type='bpe', num_threads=96)

 再之后就可以导入训练好的模型进行使用啦。

关于效果:

  • 首先有个疑问,是不是词表越大越好?是不是vocab_size越大越好?

        针对这个问题,我在网上简单检索了一下发现知乎上有位作者烛之文做了相关实验,对比了中文新闻文本数据集下的spm+cnn模型,词表8000,20000,320000(sentencepiece能训练的最大词表)的效果。https://zhuanlan.zhihu.com/p/307485012

        从他的实验结果可以看出,随着词表增大,在训练集上更早的达到“潜在的最好效果”,而在验证集上的表现越来越差。理论上不是词表越大越好吗,它毕竟降低了未登录词出现的概率。他认为是该新闻数据集的每个label的特征都是很明显的,而且这些影响特征都是可用高频词汇组合出来的。如果加大词表,就相当于training过程中,让model学到很多label的噪声特征,导致在验证集上效果降低。

<think>我们已知用户意图是了解如何使用Python实现SentencePiece的Unigram语言模型。根据引用[1]和引用[2],我们知道SentencePiece是一个开源工具包,支持Unigram和BPE等子词算法。这里我们将重点放在Unigram语言模型的实现上。 步骤: 1. 安装SentencePiece(如果尚未安装)。 2. 准备训练数据(文本文件)。 3. 配置Unigram模型训练参数。 4. 训练模型。 5. 使用模型进行编码和解码。 注意:SentencePiece已经实现了Unigram算法,我们不需要从零开始实现,而是使用其提供的Python接口。 具体实现如下:</think>### 使用Python实现SentencePiece的Unigram语言模型 #### 1. 安装SentencePiece ```bash pip install sentencepiece ``` #### 2. 训练Unigram模型 ```python import sentencepiece as spm # 配置训练参数 spm.SentencePieceTrainer.train( input='text.txt', # 输入文本文件路径 model_prefix='unigram', # 输出模型前缀 vocab_size=8000, # 词表大小 model_type='unigram', # 指定Unigram算法 character_coverage=0.9995, pad_id=0, # 特殊符号配置 unk_id=1, bos_id=2, eos_id=3 ) ``` *关键参数说明*: - `model_type='unigram'`:使用Unigram语言模型算法[^2] - `character_coverage`:覆盖字符比例(推荐0.9995) - 特殊符号需显式声明ID(如pad/unk/bos/eos) #### 3. 加载与使用模型 ```python sp = spm.SentencePieceProcessor() sp.load('unigram.model') # 加载训练好的模型 # 文本编码 text = "自然语言处理" encoded_ids = sp.encode_as_ids(text) # [259, 487, 1024, 765] encoded_pieces = sp.encode_as_pieces(text) # ['▁自', '然', '语言', '处理'] # 文本解码 decoded_text = sp.decode_ids(encoded_ids) # "自然语言处理" ``` #### 4. 自定义词表操作 ```python # 获取完整词表 vocab = {sp.id_to_piece(i): i for i in range(sp.get_piece_size())} # 添加自定义词汇(需重新训练) with open('user_dict.txt', 'w') as f: f.write("ChatGPT\n大语言模型\n") spm.SentencePieceTrainer.train( ..., user_defined_symbols='user_dict.txt' # 加载自定义词汇 ) ``` #### 5. 关键特性说明 1. **Unigram算法特点**: - 基于概率最大化删除最不重要的子词 - 通过$P(w)=\prod_{i=1}^{k}P(p_i)$计算子词序列概率[^2] - 支持采样分词(`enable_sampling=True`) 2. **多语言支持**: ```python spm.SentencePieceTrainer.train( ..., accept_language='zh,en,ja' # 指定语言 ) ``` 3. **子词正则化**: ```python sp.encode(text, out_type=str, enable_sampling=True, alpha=0.1, nbest_size=-1) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值