当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > Transformers Trainer怎样保留自定义字段传入模型

Transformers Trainer怎样保留自定义字段传入模型

来源:17golang原创 2026-11-04 13:22:13 0浏览 收藏

如果你在 Hugging Face Transformers 的 Trainer 中加入了 sample_weight、group_id 之类的自定义列,却发现它们没有出现在模型输入里,先检查 remove_unused_columns。Trainer 默认会根据模型 forward() 的参数名裁剪数据集列;要保留字段,通常有两条路:关闭这一步裁剪,并让模型能接收该字段;或者直接把字段写进自定义模型的 forward() 签名。

官方地址:https://huggingface.co/docs/transformers/main_classes/trainer

排查的关键不是“数据集有没有这一列”,而是“Trainer 准备 batch 时认为模型需要哪些参数”。字段在数据集里存在,不等于它会自动传给模型。

用Transformers库的Trainer做模型微调时,默认只会把模型forward方法入参声明过的字段传入,想要自己新增的自定义字段也能顺利传到模型内部,只要调整数据处理、训练流程的对应环节适配就能实现。

不需要修改Trainer核心源码,优先通过自定义数据整理函数过滤保留需要的自定义字段,再配合覆写compute_loss或者训练步骤的逻辑,就能把自定义字段透传给模型。

先确认字段在哪一步消失

先把问题拆成三层:数据集原始列、Trainer 组装后的 batch,以及模型 forward() 实际接收的关键字参数。官方文档说明,传入普通 Dataset 时,不被 model.forward() 接受的列会被自动移除。假设数据集有 input_ids、attention_mask、labels 和 sample_weight,而模型签名只有前三个参数,那么 sample_weight 可能在进入 data collator 或模型之前就不见了。

Transformers Trainer 按 forward 参数保留或移除数据集列的静态结构说明图
图1:Trainer 数据集列裁剪的结构说明图,展示自定义字段为何可能在进入模型前被移除;这是静态说明图,不是运行截图。

可以先用一个最小的 batch 检查列名,但不要把“打印数据集列名”当成最终结论。真正有用的对照是:模型参数列表里有没有同名参数,以及训练参数是否允许未使用列继续流转。

改法一:关闭自动列裁剪

如果你希望自定义字段完整保留到 data collator 和模型调用阶段,可以在 TrainingArguments 中设置 remove_unused_columns=False。但这个选项只负责“不删除”,不会替你修改模型签名。模型仍然要能接收传入的关键字,否则下一步会变成 unexpected keyword argument。

from transformers import TrainingArguments

# 保留数据集中的自定义列,后续由模型决定如何处理
training_args = TrainingArguments(
    output_dir="./runs/weighted",
    remove_unused_columns=False,
    per_device_train_batch_size=8,
)

# 数据集中的 sample_weight 会继续留在 batch 中
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
)

这条路适合 data collator 还要使用额外列,或者模型接口本来就准备接收多个扩展字段的场景。代价是所有列都会更容易流到模型调用处,字段命名、类型和清理责任要由你自己承担。

改法二:让 forward 显式接收自定义字段

如果只想让某个字段进入模型,通常更清晰的方式是把它加入自定义模型的 forward()。Trainer 会根据参数名识别它,列裁剪仍然可以保持默认行为。下面用加权分类损失示意,sample_weight 被声明为可选参数,然后在模型内部参与 loss 计算。

import torch
import torch.nn.functional as F
from transformers.modeling_outputs import SequenceClassifierOutput

class WeightedClassifier(torch.nn.Module):
    def __init__(self, base_model):
        super().__init__()
        self.base_model = base_model

    def forward(self, input_ids=None, attention_mask=None,
                labels=None, sample_weight=None):
        # 只把基础模型需要的标准字段传下去,避免额外字段继续扩散
        outputs = self.base_model(
            input_ids=input_ids,
            attention_mask=attention_mask,
        )
        if labels is None:
            # 预测阶段没有标签时,直接返回 logits
            return SequenceClassifierOutput(logits=outputs.logits)

        # 逐样本计算损失,便于应用自定义权重
        per_item_loss = F.cross_entropy(outputs.logits, labels, reduction="none")
        if sample_weight is None:
            loss = per_item_loss.mean()
        else:
            # 权重要放到同一设备,并防止权重总和为零
            weights = sample_weight.to(per_item_loss.device).float()
            loss = (per_item_loss * weights).sum() / weights.sum().clamp_min(1e-8)
        return SequenceClassifierOutput(loss=loss, logits=outputs.logits)

这里的重点是参数名完全匹配:数据集列叫 sample_weight,forward() 也叫 sample_weight。若列名是 weight,就要同步调整签名或在数据整理阶段完成一次明确的重命名,不要依赖位置顺序猜测。

关闭列裁剪和扩展 forward 参数两种保留自定义字段路径的静态说明图
图2:自定义字段传入模型的两种配置路径说明图,比较关闭列裁剪与显式声明 forward 参数;这是静态说明图,不是运行截图。

按现象排查配置和签名

字段消失和字段报错是两个不同阶段的问题。字段消失通常说明 Trainer 仍在按默认规则裁剪;字段报错则常见于关闭裁剪后,模型没有对应参数。可以按下面的顺序排查:

现象优先检查处理方向
batch 中没有自定义列remove_unused_columns 是否仍为默认值关闭裁剪,或把字段写入 forward 签名
出现 unexpected keyword argument模型 forward 是否能接收该列名增加同名可选参数,或不要关闭全量裁剪
字段到了模型但 loss 不变自定义字段是否真正参与计算确认权重、掩码或辅助特征在 forward 内被使用
训练阶段正常、预测阶段异常labels 或自定义字段是否被无条件使用为无标签分支返回合法的 logits 或 ModelOutput

实际选择上,如果扩展字段只服务一个明确模型,优先显式写进 forward();如果字段还要经过自定义 collator 或多个模型层级,才考虑关闭自动列裁剪。无论采用哪条路,都要让数据列名、collator 输出键和 forward 参数保持一致。

常见问题

只设置 remove_unused_columns=False 就一定能传入字段吗?

不一定。它只是不再提前删除列;如果模型不接受这个关键字,调用时仍会报参数错误。还需要扩展模型签名,或者在 collator 中把该字段转换为模型已经支持的输入。

可以把 sample_weight 写成 **kwargs 接收吗?

可以作为兜底,但不如显式参数直观。Trainer 是按签名判断列是否被使用的,明确写出 sample_weight=None 更容易让列裁剪保留它,也更方便读代码的人确认字段用途。

参考地址:https://huggingface.co/docs/transformers/main_classes/trainer

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
vLLM prefix caching怎样减少重复提示词延迟vLLM prefix caching怎样减少重复提示词延迟
上一篇
vLLM prefix caching怎样减少重复提示词延迟
Ollama embeddings怎样为本地文档生成向量
下一篇
Ollama embeddings怎样为本地文档生成向量
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    880次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    877次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    960次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    941次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    768次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码