Transformer 库中的 models
创建Transformer 模型
from transformers import AutoModel
model = AutoModel.from_pretrained("bert-base-cased")
AutoModel 是一个 auto 类,意味着它会为你猜测合适的模型架构并实例化正确的模型类。如果你知道你想使用的模型类型,可以直接使用它来定义其架构的类,比如我确定我要使用BERT模型,则可以这样:
from transformers import BertModel
model = BertModel.from_pretrained("bert-base-cased")
save models
save_pretrained() 方法保存模型的权重和架构配置:
model.save_pretrained("directory_on_my_computer") 会保存模型到指定路径。内容包含 config.json 和 pytorch_model.bin。
config.json构建模型架构所需的所有必要属性,还包括checkpoint的来源,以及那时是使用的transformer 的版本。pytorch_model.bin文件被称为 state dictionary, 它包含你模型的所有权重。
这两个文件协同工作:配置文件用于了解模型架构,而模型权重是模型的参数。
load saved models
要重用保存的模型,再次使用 from_pretrained() 方法:
from transformers import AutoModel
model = AutoModel.from_pretrained("directory_on_my_computer")
分享你的模型或 embedding
Encoding text
已经知道 tokenizer 将文本分割成 tokens,然后将这些标记转换为数字 input IDs。可以观察这种转换:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
encoded_input = tokenizer("How are you?", "I'm fine, thank you!", return_tensors="pt")
print(encoded_input)
{'input_ids':
tensor([[101, 1731, 1132, 1128, 136, 102],
[101, 1045, 1005, 1049, 2503, 117, 5763, 1128,136, 102]]),
'token_type_ids':
tensor([[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), # wrong?为什么都是0,分明是两个batch?
'attention_mask':
tensor([[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}
input_ids: token 转化为数值表示token_type_ids: 些告诉模型输入的哪部分是句子 A,哪部分是句子 B。为句子 A 的 token 分配 0,为句子 B 的 token 分配 1,帮助模型理解两部分的边界和关系。attention_mask: 这表示哪些标记应该被关注,哪些不应该。
tokenizer() 方法这里有几个参数:
return_tensors="pt"将输出转化为 PyTorch tensors。padding=True/False将输入填充。truncation=True如果输入太长,则截断它们。
1. Padding 输入填充
encoded_input = tokenizer(
["How are you?", "I'm fine, thank you!"], # 一组,所以是一个句子
padding=True,
return_tensors="pt"
)
print(encoded_input)
{'input_ids':
tensor([[101,1731,1132,1128, 136, 102, 0, 0, 0, 0],
[101,1045,1005,1049,2503, 117,5763,1128, 136, 102]]),
'token_type_ids':
tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]), # 一组,所以是一个句子
'attention_mask':
tensor([[1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}
为什么要 Padding 成长度一样的?
答:因为 Transformer 模型要求输入张量形状一致(批量处理时需要固定维度),便于并行计算和高效处理不同长度的输入。
2. Truncating inputs 截断输入
张量可能会太大以至于无法被模型处理。例如,BERT 只预训练了最多 512 个 token 的序列,所以它无法处理更长的序列。如果你有超过模型处理能力的序列,你需要使用 truncation 参数来截断它们。 通过结合padding 和 truncation 参数,你可以确保你的张量具有你需要的精确大小:
encoded_input = tokenizer(
["How are you?", "I'm fine, thank you!"], # 一组,所以是一个句子
padding=True,
truncation=True,
max_length=5,
return_tensors="pt",
)
print(encoded_input)
{'input_ids':
tensor([[ 101, 1731, 1132, 1128, 102],
[ 101, 1045, 1005, 1049, 102]]),
'token_type_ids':
tensor([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]), # 一组,所以是一个句子
'attention_mask':
tensor([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])}
tokenizer 之后的 input ids 即 token的数量一般大于原始句子中的单词数量,为什么?
原因有以下:
Transformer 模型的 tokenizer(如 BERT、Qwen 的 tokenizer)通常使用具体的tokenizer 方法如 WordPiece、BPE 或 SentencePiece,将句子拆分为更小的单元(subword tokens)
Tokenizer 会添加特殊 token,如
[CLS](分类标记)、[SEP](句子分隔符)或[PAD](填充标记)标点符号(如
?、!、.) 通常被单独编码为 token。
所以token数量多于单词数量。那么如何查看token分别是啥? 可以通过 decode input id 反过来得到原始文本:
tokenizer.decode(encoded_input["input_ids"][0])
"[CLS] How are you? [SEP]"
看,第一句话有6个token,但是只有3个单词。
那么其中的特殊 token 是什么?
添加特殊tokens
特殊 Tokens 对 BERT 及其衍生模型尤为重要。这些标记被添加以更好地表示句子边界,例如句子的开始( [CLS] )或句子之间的分隔符( [SEP] )。
这些 Tokens 由 tokenizer 自动添加。并非所有模型都需要特殊标记。模型在预训练时使用了这些标记,所以你使用预训练模型时,也需要使用这些特殊 token 的。
最后 encoded_input 会作为模型的输入。
Stay curious and keep asking questions! 🧠✨