预训练语言模型
预训练语言模型(Pre-trained Language Model)是现代 NLP 的核心技术。通过在大规模语料上进行预训练,模型学习到通用的语言知识,然后通过微调适应下游任务。
预训练语言模型的发展
发展历程
| 年份 | 模型 | 特点 |
|---|---|---|
| 2018 | ELMo | 基于双向 LSTM 的动态词向量 |
| 2018 | GPT-1 | 基于 Transformer 解码器的生成模型 |
| 2018 | BERT | 基于 Transformer 编码器的双向模型 |
| 2019 | GPT-2 | 更大规模的生成模型 |
| 2019 | RoBERTa | 优化的 BERT 训练方法 |
| 2019 | XLNet | 排列语言模型 |
| 2019 | ALBERT | 轻量化 BERT |
| 2020 | GPT-3 | 1750 亿参数的大模型 |
| 2020 | T5 | 文本到文本统一框架 |
| 2021 | DeBERTa | 解耦注意力机制 |
| 2022 | ChatGPT | 对话优化的 GPT |
| 2023 | GPT-4 | 多模态大模型 |
| 2023 | LLaMA | 开源大语言模型系列 |
预训练范式
预训练语言模型主要有两种范式:
特征提取(Feature-based):如 ELMo,预训练模型作为特征提取器,输出用于下游任务。
微调(Fine-tuning):如 BERT、GPT,在预训练模型基础上添加任务特定层,端到端微调。
BERT
BERT(Bidirectional Encoder Representations from Transformers)是预训练语言模型的里程碑,由 Google 于 2018 年提出。
BERT 架构
BERT 基于 Transformer 编码器,使用双向上下文来学习词的表示。
from transformers import BertModel, BertTokenizer
import torch
# 加载 BERT 模型
model_name = "bert-base-chinese"
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)
# 查看模型结构
print(f"BERT 层数: {model.config.num_hidden_layers}")
print(f"隐藏层维度: {model.config.hidden_size}")
print(f"注意力头数: {model.config.num_attention_heads}")
print(f"词汇表大小: {model.config.vocab_size}")
# 获取词向量
text = "自然语言处理很有趣"
inputs = tokenizer(text, return_tensors="pt")
with torch.no_grad():
outputs = model(**inputs)
# last_hidden_state: (batch_size, seq_len, hidden_size)
# pooler_output: (batch_size, hidden_size) - [CLS] token 的表示
print(f"序列输出形状: {outputs.last_hidden_state.shape}")
print(f"池化输出形状: {outputs.pooler_output.shape}")
BERT 预训练任务
BERT 使用两个预训练任务:
掩码语言模型(MLM):随机遮盖 15% 的词,预测被遮盖的词。
下一句预测(NSP):判断两个句子是否连续。
from transformers import BertForMaskedLM
# 加载 MLM 模型
model = BertForMaskedLM.from_pretrained("bert-base-chinese")
# 填空任务
text = "自然语言处理是人工[MASK]能的重要分支。"
inputs = tokenizer(text, return_tensors="pt")
with torch.no_grad():
outputs = model(**inputs)
# 获取预测结果
mask_token_index = torch.where(inputs["input_ids"] == tokenizer.mask_token_id)[1]
predicted_token_id = outputs.logits[0, mask_token_index].argmax(axis=-1)
predicted_token = tokenizer.decode(predicted_token_id)
print(f"原文: {text}")
print(f"预测: {text.replace('[MASK]', predicted_token)}")
BERT 微调
from transformers import BertForSequenceClassification, Trainer, TrainingArguments
# 加载分类模型
model = BertForSequenceClassification.from_pretrained(
"bert-base-chinese",
num_labels=2 # 二分类
)
# 微调代码示例(需要准备数据集)
training_args = TrainingArguments(
output_dir="./results",
num_train_epochs=3,
per_device_train_batch_size=16,
learning_rate=2e-5
)
# trainer = Trainer(
# model=model,
# args=training_args,
# train_dataset=train_dataset,
# eval_dataset=val_dataset
# )
# trainer.train()
GPT
GPT(Generative Pre-trained Transformer)系列是 OpenAI 开发的生成式预训练模型。
GPT 架构
GPT 基于 Transformer 解码器,使用自回归方式生成文本。
from transformers import GPT2LMHeadModel, GPT2Tokenizer
# 加载 GPT-2 模型
model_name = "gpt2"
tokenizer = GPT2Tokenizer.from_pretrained(model_name)
model = GPT2LMHeadModel.from_pretrained(model_name)
# 文本生成
def generate_text(prompt, max_length=100):
inputs = tokenizer.encode(prompt, return_tensors="pt")
outputs = model.generate(
inputs,
max_length=max_length,
num_return_sequences=1,
temperature=0.7,
top_k=50,
top_p=0.95,
do_sample=True
)
return tokenizer.decode(outputs[0], skip_special_tokens=True)
# 生成文本
prompt = "Natural language processing is"
generated = generate_text(prompt)
print(generated)
中文 GPT 模型
from transformers import BertTokenizer, GPT2LMHeadModel
# 使用中文 GPT 模型
model_name = "uer/gpt2-chinese-cluecorpussmall"
tokenizer = BertTokenizer.from_pretrained(model_name)
model = GPT2LMHeadModel.from_pretrained(model_name)
def generate_chinese_text(prompt, max_length=100):
inputs = tokenizer.encode(prompt, return_tensors="pt")
outputs = model.generate(
inputs,
max_length=max_length,
num_return_sequences=1,
temperature=0.8,
top_p=0.9,
do_sample=True,
pad_token_id=tokenizer.eos_token_id
)
return tokenizer.decode(outputs[0], skip_special_tokens=True)
# 生成中文文本
prompt = "自然语言处理是"
generated = generate_chinese_text(prompt)
print(generated)
其他预训练模型
RoBERTa
RoBERTa 是 BERT 的优化版本,通过更大的数据和更长的训练获得更好的效果。
from transformers import RobertaModel, RobertaTokenizer
model_name = "roberta-base"
tokenizer = RobertaTokenizer.from_pretrained(model_name)
model = RobertaModel.from_pretrained(model_name)
ALBERT
ALBERT 通过参数共享和分解嵌入减少参数量。
from transformers import AlbertModel, AlbertTokenizer
model_name = "albert-base-v2"
tokenizer = AlbertTokenizer.from_pretrained(model_name)
model = AlbertModel.from_pretrained(model_name)
DeBERTa
DeBERTa 使用解耦注意力机制,效果优于 BERT。
from transformers import DebertaModel, DebertaTokenizer
model_name = "microsoft/deberta-base"
tokenizer = DebertaTokenizer.from_pretrained(model_name)
model = DebertaModel.from_pretrained(model_name)
大语言模型(LLM)
LLaMA
LLaMA 是 Meta 开源的大语言模型系列,支持多种规模。
from transformers import LlamaTokenizer, LlamaForCausalLM
# 需要先申请访问权限
model_name = "meta-llama/Llama-2-7b-hf"
# tokenizer = LlamaTokenizer.from_pretrained(model_name)
# model = LlamaForCausalLM.from_pretrained(model_name)
# 生成文本
def generate_with_llama(prompt, max_new_tokens=100):
inputs = tokenizer(prompt, return_tensors="pt")
outputs = model.generate(
**inputs,
max_new_tokens=max_new_tokens,
temperature=0.7,
top_p=0.9,
do_sample=True
)
return tokenizer.decode(outputs[0], skip_special_tokens=True)
使用 Hugging Face Pipeline
from transformers import pipeline
# 文本生成
generator = pipeline("text-generation", model="gpt2")
result = generator(
"Once upon a time",
max_length=100,
num_return_sequences=1
)
print(result[0]['generated_text'])
# 对话模型
chatbot = pipeline("text-generation", model="microsoft/DialoGPT-medium")
# 问答
qa = pipeline("question-answering", model="deepset/roberta-base-squad2")
result = qa(
question="什么是自然语言处理?",
context="自然语言处理是人工智能的一个分支,致力于让计算机理解和生成人类语言。"
)
print(f"答案: {result['answer']}, 置信度: {result['score']:.4f}")
模型微调技术
全参数微调
from transformers import AutoModelForSequenceClassification, AutoTokenizer
from transformers import Trainer, TrainingArguments
model_name = "bert-base-chinese"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)
# 训练参数
training_args = TrainingArguments(
output_dir="./fine_tuned_model",
num_train_epochs=3,
per_device_train_batch_size=16,
learning_rate=2e-5,
evaluation_strategy="epoch",
save_strategy="epoch"
)
# trainer = Trainer(
# model=model,
# args=training_args,
# train_dataset=train_dataset,
# eval_dataset=val_dataset
# )
# trainer.train()
LoRA 微调
LoRA(Low-Rank Adaptation)是一种参数高效的微调方法,只训练少量参数。
from peft import LoraConfig, get_peft_model, TaskType
# 配置 LoRA
lora_config = LoraConfig(
task_type=TaskType.SEQ_CLS,
r=8, # 低秩矩阵的秩
lora_alpha=32,
lora_dropout=0.1,
target_modules=["query", "value"]
)
# 应用 LoRA
model = AutoModelForSequenceClassification.from_pretrained("bert-base-chinese", num_labels=2)
model = get_peft_model(model, lora_config)
# 查看可训练参数
model.print_trainable_parameters()
# 输出类似: trainable params: 294,912 || all params: 109,774,084 || trainable%: 0.2686
Prompt Tuning
from peft import PromptTuningConfig, get_peft_model, TaskType
# 配置 Prompt Tuning
prompt_config = PromptTuningConfig(
task_type=TaskType.SEQ_CLS,
num_virtual_tokens=20,
token_dim=768,
num_transformer_submodules=1,
num_attention_heads=12,
num_layers=12
)
model = AutoModelForSequenceClassification.from_pretrained("bert-base-chinese", num_labels=2)
model = get_peft_model(model, prompt_config)
model.print_trainable_parameters()
模型量化
量化可以减少模型大小和推理时间。
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
# 4-bit 量化配置
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True
)
# 加载量化模型
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
quantization_config=quantization_config,
device_map="auto"
)
模型部署
使用 ONNX 导出
from transformers import AutoModel, AutoTokenizer
from transformers.onnx import FeaturesManager
model_name = "bert-base-chinese"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name)
# 导出为 ONNX 格式
# from transformers.onnx import export
# export(tokenizer, model, FeaturesManager.get_supported_features_for_model_type("bert")[0], "bert.onnx")
使用 FastAPI 部署
from fastapi import FastAPI
from pydantic import BaseModel
from transformers import pipeline
app = FastAPI()
# 加载模型
classifier = pipeline("sentiment-analysis", model="bert-base-chinese")
class TextRequest(BaseModel):
text: str
@app.post("/classify")
async def classify_text(request: TextRequest):
result = classifier(request.text)
return {
"text": request.text,
"label": result[0]["label"],
"score": result[0]["score"]
}
# 运行: uvicorn app:app --reload
总结
预训练语言模型是现代 NLP 的核心技术,本章介绍了:
- BERT:双向编码器模型,适合理解任务
- GPT:自回归生成模型,适合生成任务
- 其他模型:RoBERTa、ALBERT、DeBERTa 等
- 大语言模型:LLaMA 等开源模型
- 微调技术:全参数微调、LoRA、Prompt Tuning
- 模型优化:量化、部署
预训练语言模型的发展推动了 NLP 领域的巨大进步,掌握这些技术对于现代 NLP 开发至关重要。