← 返回首页
🧠

BERT系列模型详解

📂 llm ⏱ 2 min 383 words

--- title: "BERT系列模型详解" description: "深入理解BERT及其变体(RoBERTa、ALBERT、DeBERTa)的架构和应用" tags: ["BERT", "预训练", "NLP", "双向编码器"] category: "llm" icon: "🧠"

BERT系列模型详解

BERT简介

BERT(Bidirectional Encoder Representations from Transformers)是 Google 于 2018 年提出的预训练语言模型。与 GPT 的单向生成不同,BERT 采用双向编码器架构,更适合文本理解任务。

BERT的核心创新

1. 双向上下文

传统语言模型只能看到单方向的上下文,而 BERT 通过掩码语言模型(MLM)实现了真正的双向理解:

# BERT的MLM训练示例
original_text = "我喜欢吃苹果"
masked_text = "我喜欢吃[MASK]"  # 掩盖"苹果"

# BERT利用左右双向上下文预测被掩盖的词
# 左上下文: "我喜欢吃"
# 右上下文: [无]
# 模型需要预测: "苹果"

2. 掩码语言模型(MLM)

import torch
from transformers import BertTokenizer, BertForMaskedLM

tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
model = BertForMaskedLM.from_pretrained('bert-base-chinese')

def predict_masked_word(text, mask_token='[MASK]'):
    """预测被掩盖的词"""
    inputs = tokenizer(text, return_tensors='pt')
    mask_index = torch.where(inputs['input_ids'] == tokenizer.mask_token_id)[1]
    
    with torch.no_grad():
        outputs = model(**inputs)
        predictions = outputs.logits
    
    # 获取mask位置的预测
    mask_predictions = predictions[0, mask_index]
    top_k = torch.topk(mask_predictions, k=5, dim=-1)
    
    for idx in top_k.indices[0]:
        token = tokenizer.decode(idx)
        print(f"预测: {token}")
    
    return tokenizer.decode(top_k.indices[0][0])

# 示例
result = predict_masked_word("今天天气[MASK]适合出去玩")
# 预测结果可能是: "很"、"真"、"挺"等

3. 下一句预测(NSP)

BERT 还通过下一句预测任务学习句子间的关系:

def create_nsp_examples(sentences):
    """创建NSP训练样本"""
    examples = []
    for i in range(len(sentences) - 1):
        # 正例:相邻句子
        examples.append({
            'sentence_a': sentences[i],
            'sentence_b': sentences[i+1],
            'label': 'IsNext'
        })
        # 负例:随机配对
        j = (i + 2) % len(sentences)
        examples.append({
            'sentence_a': sentences[i],
            'sentence_b': sentences[j],
            'label': 'NotNext'
        })
    return examples

BERT模型架构

BERT 有两种主要规格:

配置 参数量 层数 隐藏维度 注意力头数
BERT-Base 1.1亿 12 768 12
BERT-Large 3.4亿 24 1024 16

BERT的应用场景

文本分类

from transformers import pipeline

# 使用预训练管道进行情感分析
classifier = pipeline('sentiment-analysis', model='bert-base-chinese')

text = "这部电影真的很精彩!"
result = classifier(text)
print(result)  # [{'label': 'positive', 'score': 0.9998}]

命名实体识别

ner_pipeline = pipeline('ner', model='bert-base-chinese', grouped_entities=True)

text = "张三是北京大学的教授"
entities = ner_pipeline(text)
# [{'entity_group': 'PER', 'word': '张三', 'score': 0.98},
#  {'entity_group': 'ORG', 'word': '北京大学', 'score': 0.97}]

问答系统

qa_pipeline = pipeline('question-answering', model='bert-base-chinese')

context = "BERT是Google开发的预训练语言模型,用于自然语言处理任务。"
question = "BERT是谁开发的?"
answer = qa_pipeline(question=question, context=context)
print(answer['answer'])  # "Google"

BERT变体

RoBERTa

RoBERTa(Robustly Optimized BERT Pretraining Approach)改进了 BERT 的训练策略:

  1. 去除 NSP 任务
  2. 使用更多数据和更长的训练
  3. 动态掩码(每个epoch重新掩码)
# RoBERTa 使用示例
from transformers import RobertaTokenizer, RobertaForSequenceClassification

tokenizer = RobertaTokenizer.from_pretrained('roberta-base')
model = RobertaForSequenceClassification.from_pretrained('roberta-base')

ALBERT

ALBERT(A Lite BERT)通过参数共享减少模型大小:

# ALBERT 参数量对比
configs = {
    'ALBERT-xxlarge': 235M,  # 参数量
    'BERT-Large': 340M,       # 对比
}
# ALBERT-xxlarge 性能接近 BERT-Large,但参数量更少

DeBERTa

DeBERTa(Decoding-enhanced BERT with disentangled attention)引入了两个关键改进:

  1. 解耦注意力机制:将内容和位置信息分别处理
  2. 增强型掩码解码器:在微调时使用绝对位置信息
from transformers import DebertaTokenizer, DebertaForSequenceClassification

tokenizer = DebertaTokenizer.from_pretrained('microsoft/deberta-base')
model = DebertaForSequenceClassification.from_pretrained('microsoft/deberta-base')

BERT vs GPT 对比

特性 BERT GPT
架构 双向编码器 单向解码器
预训练任务 MLM + NSP 自回归语言模型
擅长任务 理解任务(分类、NER) 生成任务(文本生成、对话)
上下文 双向 单向(左到右)
微调方式 添加任务头 Prompt + Few-shot

使用BERT进行文本相似度计算

from sentence_transformers import SentenceTransformer, util

# 加载BERT用于句子嵌入
model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')

sentences1 = ["我喜欢机器学习", "深度学习很有趣"]
sentences2 = ["机器学习让我着迷", "我对AI很感兴趣"]

# 计算嵌入
embeddings1 = model.encode(sentences1)
embeddings2 = model.encode(sentences2)

# 计算相似度
similarity = util.cos_sim(embeddings1, embeddings2)
print("相似度矩阵:")
print(similarity)

总结

BERT 系列模型开创了预训练双向语言模型的范式,在文本理解任务上表现出色。尽管 GPT 系列在生成任务上更为突出,BERT 及其变体仍然是许多 NLP 应用的首选模型。理解 BERT 的原理和变体,对于构建高效的文本理解系统至关重要。