共计 1935 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点
传统词嵌入方法如 Word2Vec 和 GloVe 在自然语言处理(NLP)任务中表现出色,但它们存在一个主要缺陷:无法捕捉上下文相关的语义信息。这意味着同一个词在不同上下文中总是具有相同的向量表示,这在处理多义词或复杂语境时效果不佳。

相比之下,BERT(Bidirectional Encoder Representations from Transformers)通过双向 Transformer 架构,能够生成动态的词嵌入,即同一个词在不同上下文中会有不同的向量表示。这种能力使得 BERT 在语义理解任务中表现卓越,成为现代 NLP 系统的基石。
技术对比
| 特性 | BERT | ELMo | GPT |
|---|---|---|---|
| 双向编码 | ✓ | ✓ | ✗ |
| 位置敏感 | ✓ | ✓ | ✓ |
| 动态词嵌入 | ✓ | ✓ | ✓ |
| 预训练目标 | MLM + NSP | LM | LM |
| 上下文长度 | 512 tokens | 不限 | 不限 |
核心实现
PyTorch 实现 BERT-base 词嵌入提取
import torch
from transformers import BertModel, BertTokenizer
# 初始化模型和分词器
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)
# 输入文本
text = "BERT provides contextualized word embeddings."
# 分词和编码
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
# 获取词嵌入
with torch.no_grad():
outputs = model(**inputs)
# [CLS] token 的嵌入(用于句子级任务)cls_embedding = outputs.last_hidden_state[:, 0, :]
# token-level 的嵌入(用于词级任务)token_embeddings = outputs.last_hidden_state
关键参数说明:
– return_tensors="pt": 返回 PyTorch 张量
– padding=True: 自动填充到相同长度
– truncation=True: 超过 512token 自动截断
生产优化
HuggingFace Pipeline 缓存机制
使用 HuggingFace 的 pipeline 时可以启用缓存,避免重复计算相同输入的嵌入:
from transformers import pipeline
# 启用缓存的 embedding pipeline
embedder = pipeline('feature-extraction', model=model_name, device=0,
framework="pt", return_tensors=True,
caching_dir="./embedding_cache")
量化部署方案
将 BERT 模型量化为 FP16 或 INT8 可以显著减少内存占用和加速推理:
from transformers import BertModel
import torch
# 加载模型
model = BertModel.from_pretrained('bert-base-uncased')
# FP16 量化
model.half()
# 或者使用动态 INT8 量化
quantized_model = torch.quantization.quantize_dynamic(model, {torch.nn.Linear}, dtype=torch.qint8
)
性能数据(V100 GPU, batch_size=32):
– FP16: 推理速度提升 1.8 倍,内存占用减少 50%
– INT8: 推理速度提升 2.5 倍,内存占用减少 75%(精度损失约 2 -3%)
避坑指南
处理长文本的分段策略
当文本超过 512token 时,可以采用以下策略:
1. 滑动窗口法:以 256token 为窗口,步长 128token
2. 关键句提取:先提取关键句子,再分别嵌入
3. 段落聚合:分别嵌入各段落后平均或最大池化
跨语言 Embedding 对齐
对于多语言任务,可以使用:
1. bert-base-multilingual-cased等多语言模型
2. 使用 LASER 或 VecMap 进行嵌入空间对齐
3. 在目标语言上微调最后一层适配器
延伸思考
实验表明,不同层的 BERT 嵌入对下游任务效果不同:
– 底层(1- 3 层):更多语法信息
– 中层(4- 8 层):混合语法和语义
– 高层(9-12 层):更多语义信息
建议对不同任务尝试不同层的组合,例如:
– NER 任务:第 4 层 + 第 8 层拼接
– 文本分类:第 12 层 [CLS] 向量
– 语义相似度:所有层平均
