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

微调T5模型不收敛求助:文本转结构化JSON任务优化

问题

作为Transformer与NLP领域新手,在针对特定任务微调T5模型时遇到性能瓶颈。任务目标是让模型接收输入文本,输出包含相关信息的JSON字符串,共有3种响应格式,示例如下:

输入:Hey, can you give one hundred dollars to John?
预期输出:'{"action": "T", "data": {"name": "John", "amount": 100, "currency": "USD"}}'
输入:I want to add Benjamin Franklin to my contacts. He has an account on citibank, with number 412389124.
预期输出:'{"action": "A", "data": {"name": "Benjamin Franklin", "account_no": 412389124, "entity": "Citibank", "id_num": null}}'
输入:Hey, what's the weather gonna be tonight?
预期输出:'{"accion": "N", "datos": {}}'

使用Python生成20000条随机数据点,基于google/t5-base模型,通过PyTorch Trainer训练,核心代码如下:

model_name_huggingface = "google/t5-base"

tokenizer = T5Tokenizer.from_pretrained(model_name_huggingface)
model = T5ForConditionalGeneration.from_pretrained(model_name_huggingface)

分词后设置训练参数:

batch_size = 16

training_args = Seq2SeqTrainingArguments(
    output_dir="models/chimi-mt5-base",
    evaluation_strategy="steps",
    eval_steps=100,
    logging_strategy="steps",
    logging_steps=100,
    save_strategy="steps",
    save_steps=200,
    optim="adafactor",
    learning_rate=5e-4,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    predict_with_generate=True,
    weight_decay=0.05,
    save_total_limit=3,
    num_train_epochs=2,
    metric_for_best_model="exact_match",
    load_best_model_at_end=True
)

数据处理与指标计算:

data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=base_model)
cer = evaluate.load("cer", module_type="metric")
exact_match = evaluate.load("exact_match", module_type="metric")
import numpy as np

def compute_metrics(eval_pred):
    predictions, labels = eval_pred
    decoded_preds = tokenizer.batch_decode(predictions, skip_special_tokens=True)

    # Replace -100 in the labels as we can't decode them.
    labels = np.where(labels != -100, labels, tokenizer.pad_token_id)
    decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)

    result = {}

    # Compute CER
    result["cer"] = cer.compute(predictions=decoded_preds, references=decoded_labels)

    # Compute Exact Match
    exact_match_res = exact_match.compute(predictions=decoded_preds, references=decoded_labels, ignore_case=True)
    result["exact_match"] = exact_match_res["exact_match"]

    return {k: round(v, 4) for k, v in result.items()}

训练执行:

trainer = Seq2SeqTrainer(
    model=base_model,
    args=training_args,
    train_dataset=tokenized_chimi_dataset["train"],
    eval_dataset=tokenized_chimi_dataset["validation"],
    data_collator=data_collator,
    tokenizer=tokenizer,
    compute_metrics=compute_metrics
)

result = trainer.train()

训练后,训练损失降至0.054后不再提升,验证损失降至0.034后不再提升;CER指标最低0.4875,Exact Match最高0.3089。测试发现模型能输出正确JSON格式,action字段通常正确,但JSON内的数据常出错。已尝试平衡数据集、调优超参数,性能无明显提升,寻求可行的优化方案。

优化方案

1. 优化数据集构建

  • 增强数据质量:手动校验随机生成的样本,确保输入文本与输出JSON的映射完全准确;补充真实场景的指令样本(而非纯随机生成),提升模型对真实表述的泛化能力。
  • 统一输出格式:将输出JSON的键名统一(比如第三个示例的accion/datos改为与前两个一致的action/data),减少模型的学习负担;确保所有JSON的语法规范完全统一(引号、逗号、括号使用一致)。
  • 数据增强:对输入文本进行同义改写(替换同义词、调整句式),生成更多变体样本,同时保持输出JSON不变,提升模型对同语义不同表述的识别能力。

2. 调整训练策略

  • 增加训练轮次与学习率调度:将训练轮次提升至5-8轮,同时使用cosine或linear学习率衰减策略;初始学习率降至1e-4或2e-4,避免大学习率导致的训练不稳定。
  • 分层冻结训练:先冻结T5编码器的前6层,仅训练顶层和解码器,1-2轮后再解冻全部层微调,让模型先保留预训练的通用语言能力,再适配特定任务。
  • 切换更大模型:尝试google/t5-large或google/t5-xl,更大的模型容量能更好地学习细粒度的数据抽取规则(需注意硬件资源是否支持)。

3. 优化训练目标与评价指标

  • 自定义加权损失:针对JSON的data字段设置加权损失,对name、amount等关键字段的预测错误赋予更高权重,引导模型关注细粒度信息。
  • 添加字段级评价指标:除Exact Match外,新增action字段准确率、data内各字段准确率、JSON结构合规率等指标,精准定位模型薄弱环节,针对性优化。
  • 推理时使用束搜索:设置num_beams=3或5进行生成,替代贪心搜索,提升输出文本的准确性和一致性。

4. 输入输出的任务提示优化

  • 添加固定任务前缀:在输入文本前添加"extract information to JSON: "这类固定前缀,明确告知模型任务类型,提升任务针对性。
  • 标准化输出顺序:训练时固定JSON字段的生成顺序(比如先action,再data内的name、amount等),减少模型的决策空间,提升抽取准确性。

内容的提问来源于stack exchange,提问作者Enzo De Filippis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:30:01