如何基于自有数据在Hugging Face构建问答模型?新手求助
基于自有Excel数据构建Hugging Face问答模型的实现方案
问题分析
你之前直接将表格数据转为连续文本调用预训练SQUAD模型效果不佳,核心原因是结构化表格信息被打散后,模型难以精准定位对应字段的答案。针对这类场景,更适合通过生成结构化问答对+微调预训练模型的方式实现,下面是完整的示例代码和步骤。
前置依赖安装
首先安装所需工具包:
pip install pandas transformers torch datasets openpyxl
完整示例代码
1. 读取Excel并生成训练数据
将表格数据转换为SQUAD格式的问答样本(每个样本包含上下文、问题、答案位置信息):
import pandas as pd from datasets import Dataset # 读取Excel数据(需根据你的表格列名调整字段) df = pd.read_excel("s_o_data.xlsx") # 将每行表格数据转为问答样本 def build_training_sample(row): # 构造自然语言上下文 context = f"Im Jahr {row['Jahr']} betrugen die Aufwendungen für FuE-Personal im Bereich '{row['Bereich']}' {row['Aufwendungen_FuE_Personal']} VZÄ." # 构造对应问题 question = f"Wie hoch waren die Aufwendungen für FuE-Personal im Bereich '{row['Bereich']}' im Jahr {row['Jahr']}?" # 提取答案及起始位置 answer_text = f"{row['Aufwendungen_FuE_Personal']} VZÄ" answer_start = context.find(answer_text) return { "context": context, "question": question, "answers": { "text": [answer_text], "answer_start": [answer_start] } } # 生成所有训练样本并转为Hugging Face Dataset格式 train_samples = df.apply(build_training_sample, axis=1).tolist() train_dataset = Dataset.from_list(train_samples)
2. 加载模型与预处理数据
选用针对德语优化的预训练问答模型,并对数据进行分词处理:
from transformers import AutoTokenizer, AutoModelForQuestionAnswering, TrainingArguments, Trainer import torch # 德语专用预训练问答模型 model_name = "deepset/bert-base-german-cased-finetuned-squad" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForQuestionAnswering.from_pretrained(model_name) # 数据分词与位置映射转换 def preprocess_data(examples): questions = [q.strip() for q in examples["question"]] contexts = [c.strip() for c in examples["context"]] # 对问题和上下文进行分词 inputs = tokenizer( questions, contexts, max_length=384, truncation="only_second", return_offsets_mapping=True, padding="max_length", ) offset_mapping = inputs.pop("offset_mapping") start_positions = [] end_positions = [] for i, offset in enumerate(offset_mapping): answer = examples["answers"][i] start_char = answer["answer_start"][0] end_char = start_char + len(answer["text"][0]) sequence_ids = inputs.sequence_ids(i) # 定位上下文对应的token区间 idx = 0 while sequence_ids[idx] != 1: idx += 1 context_start = idx while sequence_ids[idx] == 1: idx += 1 context_end = idx - 1 # 将字符位置转换为token位置 start_token = None end_token = None for j in range(context_start, context_end + 1): if offset[j][0] <= start_char and offset[j][1] >= start_char: start_token = j if offset[j][0] <= end_char and offset[j][1] >= end_char: end_token = j start_positions.append(start_token if start_token is not None else 0) end_positions.append(end_token if end_token is not None else 0) inputs["start_positions"] = start_positions inputs["end_positions"] = end_positions return inputs # 处理训练数据集 tokenized_train = train_dataset.map(preprocess_data, batched=True)
3. 微调模型
设置训练参数并启动微调:
# 训练参数配置 training_args = TrainingArguments( output_dir="./german_fue_qa_model", per_device_train_batch_size=8, num_train_epochs=3, logging_dir="./logs", logging_steps=10, learning_rate=2e-5, weight_decay=0.01, save_total_limit=2, ) # 初始化训练器并开始微调 trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_train, ) trainer.train() # 保存微调后的模型与分词器 model.save_pretrained("./german_fue_qa_model") tokenizer.save_pretrained("./german_fue_qa_model")
4. 使用微调后的模型预测
def get_answer(question, context): inputs = tokenizer.encode_plus(question, context, return_tensors="pt") with torch.no_grad(): outputs = model(**inputs) answer_start = torch.argmax(outputs.start_logits) answer_end = torch.argmax(outputs.end_logits) + 1 answer = tokenizer.convert_tokens_to_string(tokenizer.convert_ids_to_tokens(inputs["input_ids"][0][answer_start:answer_end])) return answer # 测试示例 test_context = "Im Jahr 2011 betrugen die Aufwendungen für FuE-Personal im Bereich 'H.v. DV-Geräten, elektronischen u. opt. Erzeugnissen' 54647 VZÄ." test_question = "Wie hoch waren die Aufwendungen für FuE-Personal im Bereich 'H.v. DV-Geräten, elektronischen u. opt. Erzeugnissen' im Jahr 2011?" print(f"问题:{test_question}") print(f"答案:{get_answer(test_question, test_context)}")
关键说明
- 选用
deepset/bert-base-german-cased-finetuned-squad模型,该模型是专门针对德语问答任务优化的预训练模型,比通用英文模型更适配你的数据场景。 - 通过将表格行数据转为自然语言上下文+对应问题的方式,让模型学习从指定语境中抽取精准答案,解决了原始连续文本方案的信息混乱问题。
内容的提问来源于stack exchange,提问作者Cheroff_Faces
相关产品推荐
相关产品推荐

