LLM 文本处理进阶:从 BPE 分词到滑动窗口取样详解
本文系统介绍了大型语言模型(LLM)处理文本的两大核心技术:BPE分词和滑动窗口采样。首先分析了传统词汇级分词器的局限性,重点阐述了BPE(BytePairEncoding)如何通过子词拆分解决OOV问题,并演示了tiktoken库的实际应用。然后针对上下文长度限制问题,详细讲解了滑动窗口采样方法,包括其重叠机制的设计原理和具体实现代码。这两种技术的结合构成了LLM文本处理的基础架构,使模型能够高
大型语言模型(LLM)的输入并非原始文本,而是一串数字 ID。将人类语言转化为机器可理解的数字序列,这一过程由分词器(Tokenizer)和数据取样技术共同完成。本文基于你的代码结构,详细讲解从基础分词到现代 LLM 的 BPE 与滑动窗口采样机制,并配上可运行的代码示例。
一、从基础到 BPE:分词器的演进
1. 传统基础分词器的实现与局限性
你实现的 SimpleTokenizeV2 本质是:
-
使用正则表达式将文本按词与标点切开;
-
构建词汇表;
-
再把词映射成 ID。
示例(假设的词表):
# 假设词汇表
# vocab = {
# "Hello": 10, "do": 11, "like": 12, "tea": 13, "...": 14,
# "<|endoftext|>": 1000, "<|unk|>": 1001
# }
text_oov = "Hello, do you like tea? SomeunknownPlace"
ids_oov = tokenizer.encode(text_oov)
print(ids_oov)
# 输出示例: [10, 11, 12, 13, 14, 1001]
# 'SomeunknownPlace' 变成 <|unk|>
问题在于:
-
新词(OOV)直接变成
<unk>,语义丢失。 -
随文章增长,词表会爆炸增长,训练与存储成本失控。
这些都说明:传统词汇级 Tokenizer 生态位有限,难以支撑 LLM。
2. BPE 的崛起:LLM 默认武器
BPE(Byte Pair Encoding)以“子词”为策略,给 LLM 带来真实的增长曲线优势:
-
任意新词可被拆成已有子词 → 无
<unk>。 -
词表更可控,从几十万个词收缩到五万级别。
-
UTF-8 字节级兼容 → 能处理任何语言符号。
使用 tiktoken(OpenAI 官方 BPE)示例:
import tiktoken
bpe = tiktoken.get_encoding("gpt2")
text = "Hello, do you like tea? SomeunknownPlace"
ids = bpe.encode(text)
print("BPE IDs:", ids)
print("解码结果:", bpe.decode(ids))
真实输出类似:
BPE IDs: [15496, 11, 481, 345, 781, 1481, 13, 30, 874, 2619, 8722, 14250]
解码结果: Hello, do you like tea? SomeunknownPlace
可见:
-
SomeunknownPlace被拆成多个已知的子词。 -
信息零损失保留。
-
模型能理解子词结构(Some / unknown / Place)。
这就是 GPT 系列稳定且鲁棒的底层关键。
二、超长文本与滑动窗口采样
即使分词之后,你仍会遇到一个老大难:
模型的最大上下文限制(如 1024 / 2048 / 4096)。
而原始文本常常有几万、几十万 Token。
解决方案就是:滑动窗口采样(Sliding Window Sampling)。
1. 概念说明
假设:
-
Token 序列长度为
len(S) -
模型能接受的最大长度为
W -
窗口步长为
K(一般K < W)
则第 i 个样本为:
[
sample_i = S[iK : iK + W]
]
采用重叠窗口(overlap),能让模型在学习时保持上下文连续性。
2. 可执行代码示例
import torch
# 生成一个长度 50 的 token 序列
S = torch.arange(50)
W = 10 # 窗口大小
K = 6 # 步长
print(f"原始序列 S: {S}")
print(f"窗口 W={W}, 步长 K={K},重叠长度={W-K}")
samples = []
for i in range(0, len(S) - W + 1, K):
sample = S[i : i + W]
samples.append(sample)
for idx, sample in enumerate(samples):
print(f"样本 {idx}: {sample.tolist()}")
输出:
窗口 W=10, 步长 K=6,重叠长度=4
样本 0: [0,1,2,3,4,5,6,7,8,9]
样本 1: [6,7,8,9,10,11,12,13,14,15]
样本 2: [12,13,14,15,16,17,18,19,20,21]
...
业务价值非常明确:
-
重叠(overlap)让模型学习到跨窗口的“语义桥”;
-
长文本得以拆分成可训练块,但又不丢失语义连贯性;
-
在训练 Transformer 时尤其关键。
三、总结
LLM 文本处理本质由两个核心机制驱动:
| 阶段 | 工具 | 作用 | 解决问题 |
|---|---|---|---|
| 编码层 | BPE / tiktoken | 文本 → Token IDs | 解决 OOV、词表爆炸、跨语言兼容 |
| 结构化样本层 | 滑动窗口采样 | 生成训练样本 | 解决上下文限制、保持长文本连贯性 |
这两件事打通后,你就具备了构建任意 LLM 数据处理流水线的底层能力。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)