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

小数据集微调BERT MLM模型效果差及子词拆分问题求助

微调BEREL_2.0模型的问题排查与修正

问题1:训练损失过高(6.2156)

核心原因

  1. 数据量严重不足:你提供的训练样本仅10条左右,却强行设置train_size=1_000,实际会重复采样数据,导致模型无法学到有效语义,损失居高不下。
  2. 训练参数配置错误:
    • metric_for_best_model='f1'不适用MLM任务,MLM的核心评估指标是损失(loss),该设置会导致Trainer无法识别有效指标,无法加载最优模型。
    • 对于小数据集,batch_size=64过大,每个批次的样本多样性不足,模型训练不稳定。
    • 学习率2e-5可能过高,小数据微调易破坏预训练模型的已有知识。

修正步骤

  1. 调整数据使用策略:

    • 去掉train_test_split中的train_size=1_000,直接使用全部可用训练数据:
      downsampled_dataset = lm_datasets["train"].train_test_split(
          test_size=0.1, seed=42
      )
      
    • 若数据量仍不足,可做希伯来语文本增强:比如同义词替换、随机插入虚词、句子顺序打乱(需保证语义通顺)。
  2. 修正训练参数:

    • 将metric_for_best_model改为'eval_loss',并添加早停回调监控损失:
      training_args = TrainingArguments(
          output_dir=f"{model_name}-finetuned-sam-v1",
          overwrite_output_dir=True,
          evaluation_strategy=IntervalStrategy.STEPS,
          eval_steps=50,
          save_total_limit=5,
          learning_rate=5e-6,  # 降低学习率
          weight_decay=0.01,
          per_device_train_batch_size=8,  # 减小batch size
          per_device_eval_batch_size=8,
          num_train_epochs=3,  # 减少训练轮次
          push_to_hub=True,
          fp16=True,
          logging_steps=logging_steps,
          metric_for_best_model='eval_loss',  # 改用损失作为最优模型指标
          load_best_model_at_end=True
      )
      
      # 添加早停回调
      trainer = Trainer(
          model=model,
          args=training_args,
          train_dataset=downsampled_dataset["train"],
          eval_dataset=downsampled_dataset["test"],
          data_collator=data_collator,
          tokenizer=tokenizer,
          callbacks=[EarlyStoppingCallback(early_stopping_patience=3)]  # 3步无提升则停止
      )
      

问题2:推理输出出现子词拆分(如##ת、##ה)

核心原因

你的group_texts函数中错误地将训练目标列命名为text,而非MLM任务要求的labels。DataCollatorForLanguageModeling需要labels列来处理掩码后的训练目标,错误的列名导致模型训练时的目标逻辑混乱,最终学会预测子词而非完整词汇。

修正步骤

修改group_texts函数中的目标列命名:

def group_texts(examples):
    # Concatenate all texts
    concatenated_examples = {k: sum(examples[k], []) for k in examples.keys()}
    # Compute length of concatenated texts
    total_length = len(concatenated_examples[list(examples.keys())[0]])
    # We drop the last chunk if it's smaller than chunk_size
    total_length = (total_length // chunk_size) * chunk_size
    # Split by chunks of max_len
    result = {
        k: [t[i : i + chunk_size] for i in range(0, total_length, chunk_size)]
        for k, t in concatenated_examples.items()
    }
    # 修正:将目标列命名为labels,而非text
    result["labels"] = result["input_ids"].copy()
    return result

此外,推理时若仍有子词问题,可手动用tokenizer解码预测的token:

from transformers import AutoTokenizer, AutoModelForMaskedLM
import torch

tokenizer = AutoTokenizer.from_pretrained("johnlockejrr/BEREL_2.0-finetuned-sam-v1")
model = AutoModelForMaskedLM.from_pretrained("johnlockejrr/BEREL_2.0-finetuned-sam-v1")

text = "ואלין שמהת בני [MASK] דעלו למצרים עם יעקב גבר וביתה עלו"
inputs = tokenizer(text, return_tensors="pt")
mask_index = torch.where(inputs["input_ids"] == tokenizer.mask_token_id)[1]

with torch.no_grad():
    outputs = model(**inputs)
logits = outputs.logits
top_5_tokens = torch.topk(logits[0, mask_index], 5).indices[0].tolist()

for token in top_5_tokens:
    # 手动解码,自动合并子词
    filled_text = text.replace("[MASK]", tokenizer.decode(token))
    print(f">>> {filled_text}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 02:07:11