【中文编码】利用bert-base-chinese中的Tokenizer实现中文编码嵌入

  最近接触文本处理,查询了一些资料,记录一下中文文本编码的处理方法吧。

  先下载模型和词表:bert-base-chinese镜像下载

  如下图示,下载好的以下文件均存放在 bert-base-chinese 文件夹下

  


  

1. 词编码嵌入简介

  按我通俗的理解,就是文本要进入模型,得编码成数字的形式,那么,怎么给定数字的形式呢,不能随便给一个数字吧,此时就需要一个词表,该表中有很多很多的字,每个字都有在该表中唯一的位置,每个字编码时,采用其在词表中的位置。

  下载文件中的 vocab.txt 就是已经设定好的词表,打开看看:

  

2. 词编码嵌入实现

  利用transformers库中的BertTokenizer实现分词编码,实例化一个tokenizer,载入预先下载好的词表,调用encode函数进行编码,encode函数有5个常用参数:

  ①text: 需要编码的文本;

  ②add_special_tokens: 是否添加特殊token,即CLS分类token和SEP分隔token;

  ③max_length: 文本的最大长度,根据需要处理的最长文本长度设置;

  ④pad_to_max_length: 是否填充到最大长度,以0补位;

  ⑤return_tensors: 返回的tensor类型,有4种为 'pt', 'tf', 'np', 'jax' 分别代表 pytorch tensor、tensorflow tensor、int32数组形式和 jax tensor;

python 复制代码
from transformers import BertTokenizer

bert_name = './bert-base-chinese'
tokenizer = BertTokenizer.from_pretrained(bert_name)
text = '一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。'
input_ids = tokenizer.encode(
    text,
    add_special_tokens=True,
    max_length=128,
    pad_to_max_length=True,
    return_tensors='pt'
    )
print('text:\n', text)
print('text字符数:', len(text))
print('input_ids:\n', input_ids)  
print('input_ids大小:', input_ids.size())

  输出为:

python 复制代码
text:
 一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。
text字符数: 31
input_ids:
 tensor([[ 101,  671, 2573, 3299, 5862, 8024,  671, 2573, 6716, 7231, 8024,  671,
         2573, 1068, 2255, 7410, 3868, 6814,  511, 3470, 6864, 6814, 2145, 8024,
         2809, 2094, 5442,  679, 7309, 1728, 3362,  511,  102,    0,    0,    0,
            0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
            0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
            0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
            0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
            0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
            0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
            0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
            0,    0,    0,    0,    0,    0,    0,    0]])
input_ids大小: torch.Size([1, 128])

  查看一下tokenizer的信息:

  可以看到整个词表的大小为21128个字,共有5种特殊token标记:

  PAD: 填充标记,编码为0;

  UNK: 未知字符标记,即该字不在所定义的词表中,编码为100;

  CLS: 分类标记,蕴含整个文本的含义,编码为101;

  SEP: 分隔字符标记,用于断开两句话,编码为102;

  MASK: 掩码标记,该字被遮挡,编码为103;

  测试一下这些特殊token:

python 复制代码
from transformers import BertTokenizer

bert_name = './bert-base-chinese'
tokenizer = BertTokenizer.from_pretrained(bert_name)
text = '[CLS]一念月落,一念身错,[SEP]一念关山难涉过。[MASK]逢过客,执子者不问因果。[PAD][PAD][PAD],檒檒'
input_ids = tokenizer.encode(
    text,
    add_special_tokens=False,
    max_length=128,
    pad_to_max_length=False,
    return_tensors='pt'
    )
print('text:\n', text)
print('text字符数:', len(text))
print('input_ids:\n', input_ids)  
print('input_ids大小:', input_ids.size())

  输出为:

python 复制代码
text:
 [CLS]一念月落,一念身错,[SEP]一念关山难涉过。[MASK]逢过客,执子者不问因果。[PAD][PAD][PAD],檒檒
text字符数: 64
input_ids:
 tensor([[ 101,  671, 2573, 3299, 5862, 8024,  671, 2573, 6716, 7231, 8024,  102,
          671, 2573, 1068, 2255, 7410, 3868, 6814,  511,  103, 6864, 6814, 2145,
         8024, 2809, 2094, 5442,  679, 7309, 1728, 3362,  511,    0,    0,    0,
          117,  100,  100]])
input_ids大小: torch.Size([1, 39])

  也可以利用tokenize函数直接实现分词,并采用convert_tokens_to_ids函数和convert_ids_to_tokens函数实现词与编码的相互转换:

python 复制代码
from transformers import BertTokenizer

bert_name = './bert-base-chinese'
tokenizer = BertTokenizer.from_pretrained(bert_name)
text = '一念月落,一念身错,一念关山难涉过。棋逢过客,执子者不问因果。'
tokens = tokenizer.tokenize(text)
input_ids = tokenizer.convert_tokens_to_ids(tokens)
tokenxx = tokenizer.convert_ids_to_tokens(input_ids)

print('中文分词:\n', tokens)
print('分词-->编码:\n', input_ids)
print('编码-->分词:\n', tokenxx)

  输出为:

python 复制代码
中文分词:
 ['一', '念', '月', '落', ',', '一', '念', '身', '错', ',', '一', '念', '关', '山', '难', '涉', '过', '。', '棋', '逢', '过', '客', ',', '执', '子', '者', '不', '问', '因', '果', '。']
分词-->编码:
 [671, 2573, 3299, 5862, 8024, 671, 2573, 6716, 7231, 8024, 671, 2573, 1068, 2255, 7410, 3868, 6814, 511, 3470, 6864, 6814, 2145, 8024, 2809, 2094, 5442, 679, 7309, 1728, 3362, 511]
编码-->分词:
 ['一', '念', '月', '落', ',', '一', '念', '身', '错', ',', '一', '念', '关', '山', '难', '涉', '过', '。', '棋', '逢', '过', '客', ',', '执', '子', '者', '不', '问', '因', '果', '。']

  

  除了BertTokenizer,还有AutoTokenizer也是常用的分词类,使用方法与BertTokenizer类似,可以参考这篇文章了解不同的Tokenizer。

相关推荐
HyperAI超神经2 分钟前
在线教程丨最高4倍生成速度提升,DiffusionGemma可同时生成整块文本,基于多轮并行去噪持续优化结果
人工智能·google·长上下文
名不经传的养虾人3 分钟前
从0到1:企业级AI项目迭代日记 Vol.46|三个检索源、缓存限流、深度整合——联网检索一日冲刺
数据库·人工智能·agent·ai编程·ai工作流·企业ai
w3296362714 分钟前
一、什么是 OpenCode?
人工智能·ai编程·开发工具·opencode
寰宇视讯4 分钟前
镓未来GaN助力荣耀WIN 360W氮化镓适配器,高效充电触手可及!
人工智能·神经网络·生成对抗网络
MartinYeung54 分钟前
[论文学习]LoRA-Leak:针对 LoRA 微调语言模型的成员推断攻击深度分析与隐私风险评估
人工智能·学习·语言模型
deepdata_cn6 分钟前
AI大模型通用上下文标准(MCP)
人工智能·mcp
邵宇然8 分钟前
用 Rust 重写 Python AI 服务:从 GIL 瓶颈到零成本抽象的性能跃迁
人工智能
KIO no way11 分钟前
AI内容分发策略正在重写规则_CSDN_AI数字营销的大模型辅助发布体验
人工智能
oort12312 分钟前
AI+基层治理·智慧政务解决方案——AI 民意速办智能助手深度方案
人工智能·政务
福建佰胜张工13 分钟前
3HNA006722-001 O-RING:ABB 喷涂机器人流体系统核心密封件技术解析
网络·人工智能·机器人