You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Hugging Face pipeline获取损失以微调问答模型?

如何获取QA模型的损失并进行微调

我使用deepset/roberta-base-squad2模型做问答任务时,能通过pipeline得到预测结果,但不知道怎么计算损失来微调模型。比如测试案例中,真实答案是freedom to the user,但模型预测出了gives freedom to the user。

问答任务的损失计算和文本分类不同,QA模型需要的是答案在上下文文本中的起始和结束token位置作为标签,而非直接传入答案文本。以下是具体实现步骤:

1. 导入依赖并加载模型、分词器

import torch
from transformers import AutoModelForQuestionAnswering, AutoTokenizer

model_name = "deepset/roberta-base-squad2"
model = AutoModelForQuestionAnswering.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)

2. 定义输入数据与真实答案

question = "Why is model conversion important?"
context = "The option to convert models between FARM and transformers gives freedom to the user and let people easily switch between frameworks."
true_answer = "freedom to the user"

3. 编码输入并对齐真实答案的token位置

首先用分词器编码问题和上下文,同时获取offset_mapping来对齐原始文本和token的位置关系,再通过原始文本中真实答案的索引,找到对应的token位置:

# 编码输入,返回offset_mapping用于对齐原始文本与token
encoding = tokenizer(question, context, return_tensors="pt", return_offsets_mapping=True)
offset_mapping = encoding.pop("offset_mapping")  # 模型不需要该参数,单独取出

# 找到真实答案在原始context中的起止索引
start_idx = context.find(true_answer)
end_idx = start_idx + len(true_answer)

# 遍历offset_mapping,找到对应token的起止位置
start_positions = None
end_positions = None

# 先找精确匹配
for idx, (token_start, token_end) in enumerate(offset_mapping[0]):
    if token_start == start_idx:
        start_positions = idx
    if token_end == end_idx:
        end_positions = idx

# 若没有精确匹配,找包含答案的token位置
if start_positions is None:
    for idx, (token_start, token_end) in enumerate(offset_mapping[0]):
        if token_start <= start_idx < token_end:
            start_positions = idx
            break
if end_positions is None:
    for idx, (token_start, token_end) in enumerate(offset_mapping[0]):
        if token_start < end_idx <= token_end:
            end_positions = idx
            break

4. 计算损失并执行反向传播

将找到的start_positions和end_positions传入模型,即可得到损失并进行微调:

# 加入标签参数
encoding["start_positions"] = torch.tensor([start_positions])
encoding["end_positions"] = torch.tensor([end_positions])

# 前向传播计算损失
outputs = model(**encoding)
loss = outputs.loss

# 初始化优化器并执行反向传播
optimizer = torch.optim.AdamW(model.parameters(), lr=5e-5)
loss.backward()
optimizer.step()

说明

QA模型的forward方法会基于预测的起止位置logits,与传入的真实start_positions、end_positions计算交叉熵损失。批量处理时,只需将每个样本的起止位置整理成批量tensor即可。

内容的提问来源于stack exchange,提问作者Penguin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:35:18