Transformers Tokenizer 使用详解

Transformers Tokenizer 使用详解

一、基础用法

1.1 初始化 Tokenizer

python 复制代码
from transformers import AutoTokenizer, BertTokenizer, GPT2Tokenizer

# 推荐方式:自动检测模型对应的 tokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
# 或指定具体 tokenizer 类
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")

1.2 基本编码解码

python 复制代码
text = "Hello, how are you? I'm doing fine."

# 1. 编码为 token IDs
input_ids = tokenizer.encode(text)
print(input_ids)  # [101, 7592, 1010, 2129, 2024, 2017, 1029, 102, 1045, 1005, 1049, 2515, 3836, 1012, 102]

# 2. 解码回文本
decoded = tokenizer.decode(input_ids)
print(decoded)  # "[CLS] hello, how are you? [SEP] i'm doing fine. [SEP]"

# 3. 跳过特殊 token 解码
clean_decoded = tokenizer.decode(input_ids, skip_special_tokens=True)
print(clean_decoded)  # "hello, how are you? i'm doing fine."

# 4. 分词(tokenize)
tokens = tokenizer.tokenize(text)
print(tokens)  # ['hello', ',', 'how', 'are', 'you', '?', 'i', "'", 'm', 'doing', 'fine', '.']

二、核心参数详解

2.1 填充和截断参数

python 复制代码
# 单文本处理
inputs = tokenizer(
    text,
    padding="max_length",    # 填充到最大长度
    max_length=20,           # 最大长度
    truncation=True,         # 截断
    return_tensors="pt"      # 返回 PyTorch 张量
)
print(inputs["input_ids"].shape)  # torch.Size([1, 20])

# 批量处理 - 不同策略
texts = ["Hello world", "This is a longer sentence", "Short"]

# 动态填充到批次内最长
batch1 = tokenizer(texts, padding=True, return_tensors="pt")
print(batch1["input_ids"].shape)  # torch.Size([3, 最长序列长度])

# 填充到指定长度
batch2 = tokenizer(texts, padding="max_length", max_length=10, return_tensors="pt")

# 仅填充到模型最大长度
batch3 = tokenizer(texts, padding="longest", return_tensors="pt")

2.2 高级参数

python 复制代码
# 完整参数示例
inputs = tokenizer(
    text,
    # 长度控制
    max_length=512,
    truncation=True,
    padding="max_length",
    
    # 返回格式
    return_tensors="pt",  # "tf" (TensorFlow), "np" (NumPy), None (列表)
    return_token_type_ids=True,  # 是否返回 token_type_ids
    return_attention_mask=True,  # 是否返回 attention_mask
    return_overflowing_tokens=False,  # 是否返回溢出的 token
    return_special_tokens_mask=True,  # 特殊 token 掩码
    return_offsets_mapping=False,  # token 到原始文本的偏移
    return_length=False,  # 返回序列长度
    
    # 添加特殊 token
    add_special_tokens=True,  # 自动添加 [CLS], [SEP] 等
    
    # 截断策略
    stride=0,  # 滑动窗口步长,配合 return_overflowing_tokens 使用
)

三、句子对处理

python 复制代码
# 句子对任务(如文本分类、相似度计算)
question = "What is Transformers?"
context = "Transformers is a library by Hugging Face."

# 方法1:直接传入两个参数
inputs = tokenizer(question, context, padding=True, truncation=True)

# 方法2:使用 text_pair 参数
inputs = tokenizer(question, text_pair=context)

# 查看 token_type_ids(区分两个句子)
print(inputs["token_type_ids"])
# 输出:[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
# 0 表示第一个句子,1 表示第二个句子

# 方法3:批量处理句子对
questions = ["Q1", "Q2"]
contexts = ["C1", "C2"]
batch_inputs = tokenizer(questions, contexts, padding=True)

四、处理长文本

4.1 滑动窗口截断

python 复制代码
long_text = "..."  # 很长的文本

# 使用滑动窗口处理长文本
inputs = tokenizer(
    long_text,
    truncation=True,
    max_length=512,
    stride=256,  # 重叠长度
    return_overflowing_tokens=True,
    return_tensors="pt"
)

print(len(inputs["input_ids"]))  # 多个片段

4.2 分块处理

python 复制代码
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("gpt2")

def chunk_text(text, chunk_size=1000):
    """将长文本分块处理"""
    tokens = tokenizer.encode(text)
    chunks = []
    
    for i in range(0, len(tokens), chunk_size):
        chunk = tokens[i:i + chunk_size]
        # 添加必要的特殊 token
        chunks.append(chunk)
    
    return chunks

# 处理长文本
long_text = "..."  # 超长文本
chunks = chunk_text(long_text, chunk_size=512)

五、批量处理优化

python 复制代码
# 批量处理时使用更高效的方式
texts = ["text1", "text2", "text3", ...]  # 大量文本

# 方法1:直接批量处理(适合内存充足的情况)
batch_inputs = tokenizer(texts, padding=True, truncation=True)

# 方法2:分批处理(适合超大文本集)
batch_size = 32
all_inputs = {"input_ids": [], "attention_mask": []}

for i in range(0, len(texts), batch_size):
    batch_texts = texts[i:i+batch_size]
    batch_inputs = tokenizer(batch_texts, padding=True, truncation=True)
    
    all_inputs["input_ids"].extend(batch_inputs["input_ids"])
    all_inputs["attention_mask"].extend(batch_inputs["attention_mask"])

# 方法3:使用 Dataset 和 DataLoader
from torch.utils.data import DataLoader

class TextDataset:
    def __init__(self, texts, tokenizer, max_length=512):
        self.texts = texts
        self.tokenizer = tokenizer
        self.max_length = max_length
    
    def __len__(self):
        return len(self.texts)
    
    def __getitem__(self, idx):
        return self.tokenizer(
            self.texts[idx],
            max_length=self.max_length,
            truncation=True,
            padding="max_length",
            return_tensors="pt"
        )

dataset = TextDataset(texts, tokenizer)
dataloader = DataLoader(dataset, batch_size=32, collate_fn=lambda x: x)

六、特殊 token 处理

python 复制代码
# 查看特殊 token
print(tokenizer.special_tokens_map)
# {'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}

# 获取特殊 token 的 ID
cls_token_id = tokenizer.cls_token_id
sep_token_id = tokenizer.sep_token_id
pad_token_id = tokenizer.pad_token_id

# 添加自定义特殊 token
special_tokens_dict = {
    'additional_special_tokens': ['[SPECIAL1]', '[SPECIAL2]']
}
num_added_toks = tokenizer.add_special_tokens(special_tokens_dict)

# 添加新词汇
new_tokens = ["new_word1", "new_word2"]
num_added_toks = tokenizer.add_tokens(new_tokens)

# 注意:添加新 token 后,需要调整模型的 embedding 层
model.resize_token_embeddings(len(tokenizer))

七、偏移映射(用于 NER 等任务)

python 复制代码
# 获取 token 在原始文本中的位置
text = "Hello, how are you?"
inputs = tokenizer(
    text,
    return_offsets_mapping=True,
    return_tensors="pt"
)

offsets = inputs["offset_mapping"][0]
tokens = tokenizer.convert_ids_to_tokens(inputs["input_ids"][0])

# 打印每个 token 的位置
for token, (start, end) in zip(tokens, offsets):
    print(f"{token:10s} -> {text[start:end]}")

八、自定义配置

python 复制代码
# 创建自定义 tokenizer 配置
from transformers import PreTrainedTokenizerFast

# 基于现有 tokenizer 创建
custom_tokenizer = PreTrainedTokenizerFast(
    tokenizer_object=tokenizer,
    unk_token="[UNK]",
    pad_token="[PAD]",
    cls_token="[CLS]",
    sep_token="[SEP]",
    mask_token="[MASK]",
    padding_side="right",  # 填充方向
    truncation_side="right",  # 截断方向
)

# 保存和加载自定义 tokenizer
custom_tokenizer.save_pretrained("./my_tokenizer")
loaded_tokenizer = AutoTokenizer.from_pretrained("./my_tokenizer")

九、性能优化技巧

python 复制代码
# 1. 启用快速 tokenizer(如果可用)
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased", use_fast=True)

# 2. 批量处理时预分配内存
batch_texts = ["text1"] * 1000

# 预计算最大长度
max_len = max(len(tokenizer.encode(t)) for t in batch_texts)

# 3. 使用缓存
tokenizer = AutoTokenizer.from_pretrained(
    "bert-base-uncased",
    cache_dir="./cache"  # 缓存下载的模型
)

# 4. 并行处理(使用 multiprocessing)
from multiprocessing import Pool
import functools

def process_text(text, tokenizer):
    return tokenizer(text, padding="max_length", max_length=512)

with Pool(4) as pool:
    processed = pool.map(
        functools.partial(process_text, tokenizer=tokenizer),
        batch_texts
    )

十、常见问题处理

python 复制代码
# 1. 处理特殊字符
text = "Line 1\nLine 2\tTab"
# 自动处理换行符和制表符
inputs = tokenizer(text)

# 2. 处理表情符号和 Unicode
text = "Hello 😊 World 🌍"
inputs = tokenizer(text)  # 大多数 tokenizer 能处理

# 3. 处理数字
text = "The price is 123.45 USD"
inputs = tokenizer(text)

# 4. 处理大小写(根据模型)
# bert-base-uncased: 全部小写
# bert-base-cased: 保留大小写
tokenizer_uncased = AutoTokenizer.from_pretrained("bert-base-uncased")
tokenizer_cased = AutoTokenizer.from_pretrained("bert-base-cased")

# 5. 处理 OOV(词汇表外)词汇
text = "supercalifragilisticexpialidocious"
inputs = tokenizer(text)
# 可能被分成子词或标记为 [UNK]

十一、调试信息

python 复制代码
# 查看 tokenizer 信息
print(f"词汇表大小: {tokenizer.vocab_size}")
print(f"最大长度: {tokenizer.model_max_length}")
print(f"所有特殊 token: {tokenizer.all_special_tokens}")
print(f"所有特殊 token ID: {tokenizer.all_special_ids}")

# 详细查看编码过程
text = "Hello world!"
# 逐步查看
tokens = tokenizer.tokenize(text)
print(f"Tokens: {tokens}")

ids = tokenizer.convert_tokens_to_ids(tokens)
print(f"IDs: {ids}")

# 验证解码
decoded_tokens = tokenizer.convert_ids_to_tokens(ids)
print(f"Decoded tokens: {decoded_tokens}")

十二、实际应用示例

python 复制代码
# 情感分析任务
def prepare_sentiment_data(texts, labels, tokenizer, max_length=128):
    """准备情感分析数据"""
    encodings = tokenizer(
        texts,
        truncation=True,
        padding=True,
        max_length=max_length,
        return_tensors="pt"
    )
    
    # 添加标签
    encodings['labels'] = torch.tensor(labels)
    return encodings

# NER 任务
def prepare_ner_data(texts, tags, tokenizer, max_length=256):
    """准备命名实体识别数据"""
    tokenized_inputs = tokenizer(
        texts,
        truncation=True,
        padding=True,
        max_length=max_length,
        is_split_into_words=True,  # 文本已预先分词
        return_tensors="pt"
    )
    
    # 对齐标签(考虑子词分词)
    aligned_labels = []
    for i, label in enumerate(tags):
        word_ids = tokenized_inputs.word_ids(batch_index=i)
        previous_word_idx = None
        label_ids = []
        
        for word_idx in word_ids:
            if word_idx is None:
                label_ids.append(-100)  # 忽略特殊 token
            elif word_idx != previous_word_idx:
                label_ids.append(label[word_idx])
            else:
                # 子词,使用 -100 或相同的标签
                label_ids.append(-100)
            previous_word_idx = word_idx
        
        aligned_labels.append(label_ids)
    
    tokenized_inputs["labels"] = torch.tensor(aligned_labels)
    return tokenized_inputs

通过掌握这些用法,你可以高效地使用 Transformers 的 Tokenizer 处理各种 NLP 任务。

相关推荐
xhyyvr1 小时前
一次虚拟碰撞,一生安全警示——VR卡丁车安全驾驶模拟
人工智能·vr
CV爱数码1 小时前
【宝藏数据集】LUMOS:腰椎多模态骨质疏松症筛查专用
人工智能·python·深度学习·机器学习·计算机视觉·数据集
GalaxySpaceX1 小时前
OpenCV+YOLOv11+LabelStudio
人工智能·opencv·计算机视觉
程序边界1 小时前
AI实战狂飙!Excel图表制作彻底解放双手:从数据清洗到智能预测全攻略
人工智能·excel
deephub1 小时前
LlamaIndex检索调优实战:七个能落地的技术细节
人工智能·python·大语言模型·rag·llamaindex
围炉聊科技1 小时前
从像素到语义:图像分割技术的演进与实践
人工智能
悟纤1 小时前
Suno赋予照片声音灵魂 | 从零开始用Suno Ai | 第3篇
人工智能·suno·suno ai·suno api·ai music
技术小黑1 小时前
Pytorch学习系列07 | VGG-16算法实现马铃薯病害识别
pytorch·深度学习·神经网络·cnn
王中阳Go1 小时前
Go后端 vs Go AI应用开发重点关注什么?怎么学?怎么面试?
人工智能·面试·golang