求解决问题:请使用Bert语言模型,在cmrc2018阅读理解数据集上进行微调,使模型能够完成简单的抽取式阅读理解任务,即问答任务。
说明:
1、需要在autodl服务器上配置运行,推荐显卡配置3090
2、使用精准匹配度EM和模糊匹配度F1作为评估指标,并进行展示(F1需大于80%)
在autodl服务器上完成数据集的微调
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
4条回答 默认 最新
檀越@新空间 2025-09-12 14:55关注下午好🌅🌅🌅
本答案参考通义千问在AutoDL服务器上使用 BERT 模型对 CMRC2018 数据集进行微调,以完成抽取式阅读理解任务(问答任务),是一个典型的NLP任务。以下是详细的步骤说明和代码示例。
📌 一、环境准备
1. 登录 AutoDL 服务器
- 访问 AutoDL 官网,创建一个实例。
- 推荐配置:选择 3090 显卡 的实例(如
A100或RTX 3090),内存建议 24G+。
2. 安装必要的依赖库
在终端中执行以下命令:
# 安装 PyTorch(根据显卡型号选择版本) pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu118 # 安装 transformers 库 pip install transformers # 安装 datasets 和 evaluate 用于评估 pip install datasets evaluate # 安装 sentencepiece(用于 BERT tokenizer) pip install sentencepiece
🧠 二、数据准备(CMRC2018)
1. 下载 CMRC2018 数据集
你可以从 CMRC2018 官方地址 获取数据,或通过 Hugging Face 加载:
from datasets import load_dataset dataset = load_dataset("cmrc2018") train_dataset = dataset["train"] validation_dataset = dataset["validation"] test_dataset = dataset["test"]注意:如果无法直接加载,可以手动下载并上传到 AutoDL 服务器,然后用
load_from_disk()加载。
🤖 三、模型加载与预处理
1. 加载 BERT 模型和 Tokenizer
from transformers import BertTokenizer, BertForQuestionAnswering model_name = "bert-base-chinese" tokenizer = BertTokenizer.from_pretrained(model_name) model = BertForQuestionAnswering.from_pretrained(model_name)2. 数据预处理函数
def preprocess_function(examples): questions = [q.strip() for q in examples["question"]] contexts = [c.strip() for c in examples["context"]] answers = examples["answer"] # 将答案转换为起始和结束位置 tokenized = tokenizer( questions, contexts, truncation="only_second", padding="max_length", max_length=512, return_offsets_mapping=True, return_tensors="pt" ) # 找到答案的起始和结束索引 start_positions = [] end_positions = [] for i in range(len(answers)): answer = answers[i] if not answer: start_positions.append(0) end_positions.append(0) continue # 将答案文本转为token的位置 answer_start = answer["answer_start"] answer_text = answer["text"] # 获取 offset mapping offset_mapping = tokenized.offset_mapping[i] # 找到答案对应的token起始和结束位置 start_idx = None end_idx = None for j, (start, end) in enumerate(offset_mapping): if start == answer_start: start_idx = j if end == answer_start + len(answer_text): end_idx = j if start_idx is None or end_idx is None: start_positions.append(0) end_positions.append(0) else: start_positions.append(start_idx) end_positions.append(end_idx) tokenized["start_positions"] = start_positions tokenized["end_positions"] = end_positions return tokenized3. 应用预处理
tokenized_datasets = train_dataset.map(preprocess_function, batched=True) val_tokenized = validation_dataset.map(preprocess_function, batched=True)
🛠 四、训练模型
1. 设置 Trainer 参数
from transformers import TrainingArguments, Trainer training_args = TrainingArguments( output_dir="./results", evaluation_strategy="epoch", learning_rate=2e-5, per_device_train_batch_size=16, num_train_epochs=3, weight_decay=0.01, save_strategy="epoch", load_best_model_at_end=True, ) trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_datasets, eval_dataset=val_tokenized, )2. 开始训练
trainer.train()
🔍 五、模型评估(EM & F1)
1. 使用
evaluate库计算指标from evaluate import load em = load("exact_match") f1 = load("f1") def compute_metrics(p): predictions, labels = p # 取出预测的 start 和 end 位置 start_logits, end_logits = predictions # 转换为预测的答案 predicted_answers = [] for i in range(len(start_logits)): start_idx = start_logits[i].argmax() end_idx = end_logits[i].argmax() predicted_answers.append(tokenizer.decode(tokenized_datasets[i]["input_ids"][start_idx:end_idx+1])) # 原始答案 original_answers = [example["answer"]["text"] for example in validation_dataset] em_score = em.compute(predictions=predicted_answers, references=original_answers) f1_score = f1.compute(predictions=predicted_answers, references=original_answers) return { "exact_match": em_score["exact_match"], "f1": f1_score["f1"] } # 在验证集上评估 metrics = trainer.evaluate() print(f"EM: {metrics['exact_match']}, F1: {metrics['f1']}")
✅ 六、结果要求
- F1 分数需大于 80%
- EM 分数越高越好
🧪 七、优化建议(可选)
| 优化项 | 说明 | |--------|------| | 学习率调整 | 可尝试
1e-5或5e-5| | 批量大小 | 若显存不足,可降低per_device_train_batch_size| | 模型结构 | 可尝试bert-large-chinese提升性能 | | 早停机制 | 在TrainingArguments中添加early_stopping_patience|
📦 八、完整代码(简化版)
from transformers import BertTokenizer, BertForQuestionAnswering, TrainingArguments, Trainer from datasets import load_dataset from evaluate import load # 1. 加载数据 dataset = load_dataset("cmrc2018") train_dataset = dataset["train"] val_dataset = dataset["validation"] # 2. 加载模型和 tokenizer tokenizer = BertTokenizer.from_pretrained("bert-base-chinese") model = BertForQuestionAnswering.from_pretrained("bert-base-chinese") # 3. 预处理函数 def preprocess_function(examples): # ... (同上文) # 4. 应用预处理 tokenized_datasets = train_dataset.map(preprocess_function, batched=True) val_tokenized = val_dataset.map(preprocess_function, batched=True) # 5. 训练器设置 training_args = TrainingArguments(...) trainer = Trainer(...) # 6. 训练 trainer.train() # 7. 评估 def compute_metrics(p): # ... (同上文) metrics = trainer.evaluate() print(f"EM: {metrics['exact_match']}, F1: {metrics['f1']}")
📌 总结
✅ 完成目标的关键点如下:
- 正确加载 CMRC2018 数据集
- 使用 BERT 模型进行微调
- 实现抽取式 QA 的预处理逻辑
- 使用 EM 和 F1 作为评估指标
- 确保 F1 > 80%
如果你需要我帮你生成完整的 Python 脚本文件或提供进一步的调试帮助,请告诉我!
解决 无用评论 打赏 举报