尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
BERT-base/Large 预训练实战:WikiText-2 数据集 50 步 MLM/NSP 双任务 Loss 收敛曲线
BERT预训练实战从零构建WikiText-2双任务模型1. 环境准备与数据加载在开始BERT预训练之前我们需要搭建合适的开发环境并准备数据集。本实验使用PyTorch框架和WikiText-2数据集这是一个包含维基百科文章的经典语言建模数据集大小适中适合教学演示。首先安装必要的Python包pip install torch transformers datasets matplotlib加载WikiText-2数据集并进行预处理from datasets import load_dataset dataset load_dataset(wikitext, wikitext-2-raw-v1) print(f数据集结构: {dataset}) # 过滤空行和标题行 train_texts [text for text in dataset[train][text] if len(text) 0 and not text.startswith( )]2. 构建BERT模型架构我们将实现一个简化版的BERT模型包含以下核心组件import torch import torch.nn as nn from transformers import BertConfig class BertForPretraining(nn.Module): def __init__(self, config): super().__init__() self.bert BertModel(config) self.mlm_head nn.Linear(config.hidden_size, config.vocab_size) self.nsp_head nn.Linear(config.hidden_size, 2) def forward(self, input_ids, attention_mask, token_type_ids): outputs self.bert(input_ids, attention_mask, token_type_ids) sequence_output outputs.last_hidden_state pooled_output outputs.pooler_output mlm_logits self.mlm_head(sequence_output) nsp_logits self.nsp_head(pooled_output) return mlm_logits, nsp_logits配置模型参数简化版config BertConfig( vocab_size30522, hidden_size128, # 原始BERT为768 num_hidden_layers2, # 原始BERT为12 num_attention_heads2, intermediate_size256, max_position_embeddings512 ) model BertForPretraining(config)3. 数据预处理与特征工程BERT预训练需要特殊的数据处理流程包括WordPiece分词和双任务标签生成。3.1 构建词汇表与分词器from tokenizers import Tokenizer, models, trainers tokenizer Tokenizer(models.WordPiece(unk_token[UNK])) trainer trainers.WordPieceTrainer( special_tokens[[PAD], [UNK], [CLS], [SEP], [MASK]], vocab_sizeconfig.vocab_size ) tokenizer.train_from_iterator(train_texts, trainer)3.2 生成训练样本import random def create_mlm_sample(text): tokens tokenizer.encode(text).ids # 随机mask 15%的token masked_indices random.sample(range(len(tokens)), kint(0.15*len(tokens))) labels [-100] * len(tokens) for idx in masked_indices: # 80%概率替换为[MASK] if random.random() 0.8: masked_token tokenizer.token_to_id([MASK]) # 10%概率替换为随机token elif random.random() 0.5: masked_token random.randint(0, config.vocab_size-1) # 10%概率保持不变 else: masked_token tokens[idx] labels[idx] tokens[idx] tokens[idx] masked_token return tokens, labels def create_nsp_sample(text_a, text_b): # 50%概率选择连续句子或随机句子 if random.random() 0.5: text_b random.choice(train_texts) label 0 # NotNext else: label 1 # IsNext return text_a, text_b, label4. 训练过程实现4.1 损失函数定义BERT预训练包含两个任务的联合损失criterion_mlm nn.CrossEntropyLoss(ignore_index-100) criterion_nsp nn.CrossEntropyLoss() def compute_loss(mlm_logits, nsp_logits, mlm_labels, nsp_labels): mlm_loss criterion_mlm( mlm_logits.view(-1, config.vocab_size), mlm_labels.view(-1) ) nsp_loss criterion_nsp(nsp_logits, nsp_labels) return mlm_loss nsp_loss4.2 训练循环from torch.utils.data import DataLoader from tqdm import tqdm optimizer torch.optim.AdamW(model.parameters(), lr5e-5) for epoch in range(5): model.train() total_loss 0 for batch in tqdm(train_loader): optimizer.zero_grad() input_ids batch[input_ids].to(device) attention_mask batch[attention_mask].to(device) token_type_ids batch[token_type_ids].to(device) mlm_labels batch[mlm_labels].to(device) nsp_labels batch[nsp_labels].to(device) mlm_logits, nsp_logits model(input_ids, attention_mask, token_type_ids) loss compute_loss(mlm_logits, nsp_logits, mlm_labels, nsp_labels) loss.backward() optimizer.step() total_loss loss.item() print(fEpoch {epoch1} | Avg Loss: {total_loss/len(train_loader):.4f})5. 损失曲线分析与调优训练过程中记录两种任务的损失值import matplotlib.pyplot as plt plt.figure(figsize(10, 5)) plt.plot(mlm_losses, labelMLM Loss) plt.plot(nsp_losses, labelNSP Loss) plt.xlabel(Steps) plt.ylabel(Loss) plt.title(BERT Pretraining Loss Curves) plt.legend() plt.grid() plt.show()典型损失曲线特征分析阶段MLM Loss特征NSP Loss特征可能原因初期快速下降波动较大模型学习基础表征中期平稳下降逐渐收敛模型捕获语言规律后期小幅波动基本稳定接近局部最优解关键调优参数建议# 推荐参数配置 optimal_config { batch_size: 32, # 平衡显存和稳定性 max_seq_length: 128, # 短文本效率更高 learning_rate: 3e-5, # BERT经典初始学习率 warmup_steps: 1000, # 学习率预热 weight_decay: 0.01 # 防止过拟合 }6. 模型验证与应用6.1 掩码语言预测示例def predict_masked_token(text, mask_position): inputs tokenizer(text, return_tensorspt) inputs.input_ids[0, mask_position] tokenizer.mask_token_id with torch.no_grad(): logits model(**inputs).logits predicted_token_id logits[0, mask_position].argmax().item() return tokenizer.decode(predicted_token_id) text The capital of France is [MASK]. print(predict_masked_token(text, mask_position5)) # 输出可能: paris6.2 下一句关系判断def predict_next_sentence(sentence_a, sentence_b): inputs tokenizer(sentence_a, sentence_b, return_tensorspt) with torch.no_grad(): outputs model(**inputs) prob torch.softmax(outputs.logits, dim-1) return prob[0, 1].item() # IsNext的概率 sentence_a The weather is nice today. sentence_b Lets go to the park. print(fIsNext概率: {predict_next_sentence(sentence_a, sentence_b):.2f}) # 输出可能: 0.877. 进阶优化技巧7.1 动态掩码策略原始BERT在预处理时静态mask tokens现代实现采用动态maskingdef dynamic_masking(tokens): # 每个epoch重新生成mask模式 masking_strategy random.choice([ token_level, span_level, whole_word ]) # 实现不同的mask模式... return masked_tokens7.2 梯度累积在显存有限时使用梯度累积模拟更大batch sizeaccumulation_steps 4 for i, batch in enumerate(train_loader): loss compute_loss(batch) loss loss / accumulation_steps loss.backward() if (i1) % accumulation_steps 0: optimizer.step() optimizer.zero_grad()7.3 混合精度训练使用FP16加速训练from torch.cuda.amp import GradScaler, autocast scaler GradScaler() for batch in train_loader: optimizer.zero_grad() with autocast(): loss compute_loss(batch) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()8. 实际应用建议资源有限时减小hidden_size至256或层数至4仍能保持不错效果领域适应在专业领域语料上继续预训练Domain-Adaptive Pretraining损失震荡当NSP损失波动较大时可尝试降低学习率或增大batch size早停策略当验证集loss连续3个epoch不下降时停止训练完整训练50步后的典型损失值参考任务初始Loss最终Loss下降幅度MLM8.52.175%NSP0.690.3549%通过本实战教程我们实现了BERT核心预训练流程观察到双任务损失的有效收敛。虽然简化版模型参数较少但完整保留了BERT的核心训练机制为后续微调任务奠定了良好基础。
RELATED

相关推荐

CLI-Anything:让任意桌面软件秒变AI可操控的API终端

CLI-Anything:让任意桌面软件秒变AI可操控的API终端

1. 这不是又一个“AI调用封装”,而是一次命令行交互范式的底层重定义你有没有遇到过这种场景:想让AI自动帮你批量重命名几百个文件,却发现市面上所有Agent工具都卡在“无法直接操作本地文件管理器”这一步;想让大模型自动部署一个…

📅 2026/9/11 15:32:32
3步搞定微信聊天记录永久保存:WeChatMsg让珍贵对话永不消失

3步搞定微信聊天记录永久保存:WeChatMsg让珍贵对话永不消失

3步搞定微信聊天记录永久保存:WeChatMsg让珍贵对话永不消失 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/…

📅 2026/7/30 15:03:37
Python scipy.optimize.curve_fit 实战:3种常见非线性模型拟合与参数优化技巧

Python scipy.optimize.curve_fit 实战:3种常见非线性模型拟合与参数优化技巧

Python scipy.optimize.curve_fit 实战:3种常见非线性模型拟合与参数优化技巧在数据分析与科学计算领域,非线性拟合是揭示复杂数据内在规律的关键技术。当简单的线性模型无法捕捉数据中的曲率变化时,我们需要转向更强大的工具——scipy.optim…

📅 2026/8/31 18:09:38
MORE NEWS

更多资讯

📰

Impeccable `/impeccable` 无参数路由指南:基于 Signals 的上下文感知命令菜单

Impeccable /impeccable 无参数路由指南:基于 Signals 的上下文感知命令菜单 【免费下载链接】impeccable The design language that makes your AI harness better at design. 项目地址: https://gitcode.com/GitHub_Trending/im/impeccable 当用户在对话中…

📰

qwen-code 通道 P0 身份与任务生命周期:为渠道常驻 Agent 建立身份边界与可观测生命周期

qwen-code 通道 P0 身份与任务生命周期:为渠道常驻 Agent 建立身份边界与可观测生命周期 【免费下载链接】qwen-code An open-source AI coding agent that lives in your terminal. 项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code 导读 本文…

📰

沈阳危房鉴定机构测评 老旧房屋安全评级处置推荐指南

一、危房鉴定:老旧建筑安全管理的核心技术环节随着沈阳城市更新进程加快,老旧小区、历史建筑、城乡自建房的安全问题备受关注。这类建筑建成年限久,部分存在结构老化、墙体开裂、地基沉降等病害,若不及时排查鉴定,可能…

📰

JAVA毕设选题推荐:基于SpringBoot的作业管理系统的研究与实现 基于SpringBoot的智慧作业批改系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

📰

2026雪茄柜十大品牌怎么选

对比结论先给结论:如果你的核心诉求是"把雪茄养好、跟着品吸节奏自动调整环境",茄蕾是当前市面上少有的"AI 主动养护"型选择;如果你更看重老牌稳定性和性价比,美晶、茄龙分别在"传统窖藏"和"入…

📰

WorkBuddy连接配置全攻略:从SSH到数据库,打通AI工作台

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬