BPE训练



from tokenizers import Tokenizer
from tokenizers.models import BPE
from tokenizers.trainers import BpeTrainer
from tokenizers.pre_tokenizers import Whitespace
import os
 
# 初始化BPE分词器
tokenizer = Tokenizer(BPE())
tokenizer.pre_tokenizer = Whitespace()
 
# 配置训练器
trainer = BpeTrainer(
    vocab_size=1000,
    special_tokens=["<|endoftext|>", "<unk>", "<pad>"]
)
 
# 指定目录并收集所有txt文件路径
root_dir = r"F:python codesHeroes"
file_paths = []
 
for root, dirs, files in os.walk(root_dir):
    for file in files:
        if file.endswith('.txt'):
            file_path = os.path.join(root, file)
            file_paths.append(file_path)
            print(f"找到文件: {file_path}")
 
if not file_paths:
    print("未找到任何txt文件,请检查目录是否正确")
else:
    # 训练分词器
    tokenizer.train(file_paths, trainer)
    print("分词器训练完成")
    tokenizer.save("bpe_tokenizer.json")
    print("分词器已保存为 bpe_tokenizer.json")
 
    # 获取词表
    vocab = tokenizer.get_vocab()
    # 按照词频从高到低排序
    sorted_vocab = sorted(vocab.items(), key=lambda x: x[1], reverse=True)
    word_list = [word for word, _ in sorted_vocab]
 
    # 将词表保存到文件中
    with open("bpe_vocabulary.txt", "w", encoding="utf-8") as f:
        for word in word_list:
            f.write(word + "
")
 
    print("BPE词表已保存到 bpe_vocabulary.txt")

要理解这段代码,我们需要逐行拆解其功能,从 “导入依赖” 到 “训练 & 保存分词器”,每个步骤都对应 BPE(字节对编码)分词器构建的核心流程。以下是一行行的详细解读:

1. 导入必要的库和模块

python

运行


from tokenizers import Tokenizer

作用:从 Hugging Face 开源的
tokenizers
库中导入核心类
Tokenizer
。说明:
Tokenizer
是所有分词器(包括 BPE、WordPiece 等)的基础容器,负责管理分词逻辑、词表、编码 / 解码等核心功能。

python

运行


from tokenizers.models import BPE

作用:从
tokenizers.models
模块导入
BPE
类(Byte Pair Encoding,字节对编码)。说明:
BPE
是一种常用的分词算法,核心思想是 “从基础字符开始,不断合并出现频率最高的字符对”,能平衡词汇量和语义完整性(适合处理多语言、未登录词)。

python

运行


from tokenizers.trainers import BpeTrainer

作用:从
tokenizers.trainers
模块导入
BpeTrainer
类。说明:
BpeTrainer
是专门用于训练 BPE 分词器的工具,负责定义训练规则(如词表大小、特殊符号)、处理训练数据、生成词表等。

python

运行


from tokenizers.pre_tokenizers import Whitespace

作用:从
tokenizers.pre_tokenizers
模块导入
Whitespace
类。说明:
pre_tokenizers
(预分词器)是训练前的 “数据预处理步骤”,
Whitespace
的功能是 “按空格分割文本”(例如将
"hello world"
拆为
["hello", "world"]
),为后续 BPE 合并做准备。

python

运行


import os

作用:导入 Python 内置的
os
模块。说明:
os
模块用于与操作系统交互,这里主要用来遍历文件夹、获取文件路径(收集训练用的 txt 文件)。

2. 初始化 BPE 分词器

python

运行



# 初始化BPE分词器
tokenizer = Tokenizer(BPE())

作用:创建一个基于 BPE 算法的分词器实例。说明:
Tokenizer(BPE())
表示 “用 BPE 模型初始化分词器”,此时分词器还没有词表,需要后续通过训练生成。

python

运行


tokenizer.pre_tokenizer = Whitespace()

作用:为初始化的分词器绑定 “预分词规则”。说明:指定分词器在处理文本时,先按空格分割文本(预分词),再对分割后的片段进行 BPE 合并。如果不指定预分词器,BPE 会直接从原始字符开始处理,可能导致效率低下。

3. 配置 BPE 训练器

python

运行



# 配置训练器
trainer = BpeTrainer(
    vocab_size=1000,
    special_tokens=["<|endoftext|>", "<unk>", "<pad>"]
)

作用:创建 BPE 训练器实例,并定义训练的核心参数。参数解读:

vocab_size=1000
:指定训练完成后词表的总大小为 1000(包括普通词汇和特殊符号)。词表大小需根据数据量调整,数据量小时词表不宜过大(避免过拟合)。
special_tokens=[...]
:定义分词器需要识别的特殊符号,这些符号不参与 BPE 合并,需手动指定:

<|endoftext|>
:文本结束符(表示一段文本的结尾,常见于 GPT 类模型);
<unk>
:未知词符(遇到词表中没有的词时,用该符号替换);
<pad>
:填充符(用于将不同长度的文本补成相同长度,方便批量训练)。

4. 收集训练数据(遍历文件夹找 txt 文件)

python

运行



# 指定目录并收集所有txt文件路径
root_dir = r"F:python codesHeroes"

作用:定义训练数据所在的根文件夹路径。说明:
r
前缀表示 “原始字符串”,避免路径中的
被解析为转义字符(例如
r"F: est"
不会把
解析为制表符)。需根据实际 txt 文件存放路径修改。

python

运行


file_paths = []

作用:创建一个空列表
file_paths
,用于存储所有找到的 txt 文件路径

python

运行


for root, dirs, files in os.walk(root_dir):

作用:调用
os.walk()
遍历
root_dir
文件夹及其所有子文件夹。返回值解读:

root
:当前正在遍历的文件夹路径;
dirs
:当前文件夹下的所有子文件夹列表;
files
:当前文件夹下的所有文件列表。

python

运行



    for file in files:

作用:遍历当前文件夹(
root
)下的所有文件。

python

运行


        if file.endswith('.txt'):

作用:筛选出后缀为
.txt
的文件
(只用 txt 文件作为训练数据,避免其他格式文件干扰)。

python

运行


            file_path = os.path.join(root, file)

作用:将 “当前文件夹路径(root)” 和 “文件名(file)” 拼接成完整的文件路径。例子:若
root

F:python codesHeroes

file

hero1.txt
,则
file_path

F:python codesHeroeshero1.txt

python

运行


            file_paths.append(file_path)

作用:将拼接好的 txt 文件路径添加到
file_paths
列表中,完成 “收集训练数据路径” 的操作。

python

运行


            print(f"找到文件: {file_path}")

作用:打印找到的 txt 文件路径,方便用户确认 “是否正确找到目标文件”(排查路径错误)。

5. 训练分词器(核心逻辑)

python

运行


if not file_paths:

作用:判断
file_paths
列表是否为空(即是否找到任何 txt 文件)。

python

运行


    print("未找到任何txt文件,请检查目录是否正确")

作用:若未找到 txt 文件,打印错误提示,避免后续代码报错(无数据时无法训练)。

python

运行


else:

作用:若找到 txt 文件,执行后续的 “训练 – 保存” 逻辑。

python

运行



    # 训练分词器
    tokenizer.train(file_paths, trainer)

作用:用收集到的 txt 文件训练 BPE 分词器,是整个代码的核心步骤。过程解读:
分词器读取
file_paths
中的所有 txt 文件内容;按
Whitespace
预分词规则分割文本;
BpeTrainer
按规则合并高频字符对,直到词表大小达到
vocab_size=1000
;将生成的词表绑定到
tokenizer
中,此时分词器具备 “编码文本” 的能力。

python

运行


    print("分词器训练完成")

作用:提示训练完成,方便用户感知流程进度。

python

运行


    tokenizer.save("bpe_tokenizer.json")

作用:将训练好的分词器(包含词表、预分词规则、BPE 模型参数)保存为
bpe_tokenizer.json
文件。说明:后续使用时,只需通过
Tokenizer.from_file("bpe_tokenizer.json")
即可加载分词器,无需重新训练。

python

运行


    print("分词器已保存为 bpe_tokenizer.json")

作用:提示分词器保存完成,告知用户文件名称和位置(默认保存在代码运行目录下)。

6. 提取并保存词表

python

运行



    # 获取词表
    vocab = tokenizer.get_vocab()

作用:从训练好的分词器中提取词表字典。说明:
vocab
是一个
{词: 词ID}
的字典(例如
{"the": 5, "a": 12}
),词 ID 是分词器编码时用的数字标识。

python

运行



    # 按照词频从高到低排序
    sorted_vocab = sorted(vocab.items(), key=lambda x: x[1], reverse=True)

作用:对词表按 “词 ID” 倒序排序(间接体现词频高低)。逻辑解读:

vocab.items()
:将字典转为
(词, 词ID)
的元组列表;
key=lambda x: x[1]
:按元组的第 2 个元素(词 ID)排序;
reverse=True
:倒序排列(BPE 训练中,词频越高的词,词 ID 越小,倒序后高频词排在前面)。

python

运行



    word_list = [word for word, _ in sorted_vocab]

作用:从排序后的词表中提取 “纯词列表”,去掉词 ID。说明:
_
表示 “忽略该变量”(这里不需要词 ID,只需要词本身),
word_list
最终是
["<|endoftext|>", "the", "a", ...]
的格式。

python

运行



    # 将词表保存到文件中
    with open("bpe_vocabulary.txt", "w", encoding="utf-8") as f:

作用:创建
bpe_vocabulary.txt
文件,以 “写入模式(w)” 和 “UTF-8 编码” 打开(避免中文乱码)。说明:
with
语句会自动管理文件关闭,避免手动关闭文件的遗漏。

python

运行



        for word in word_list:
            f.write(word + "
")

作用:将
word_list
中的每个词按 “一行一个词” 的格式写入
bpe_vocabulary.txt
。例子:文件内容会是:

plaintext



<|endoftext|>
<unk>
<pad>
the
a
...

python

运行


    print("BPE词表已保存到 bpe_vocabulary.txt")

作用:提示词表保存完成,方便用户后续查看词表内容(验证词表是否符合预期)。

整体流程总结

这段代码的核心目标是基于自定义 txt 数据训练一个 BPE 分词器,完整流程可概括为:

导入依赖 → 2. 初始化 BPE 分词器(绑定预分词规则) → 3. 配置训练器(指定词表大小、特殊符号) → 4. 遍历文件夹收集 txt 训练数据 → 5. 训练分词器 → 6. 保存分词器和词表。

训练后的分词器可用于 NLP 任务(如文本编码、模型预训练),词表文件则方便人工检查分词效果。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容