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

基于Alpaca-LoRA无监督微调报错AssertionError求助

基于Alpaca-LoRA做无监督MLM微调时的AssertionError排查

修改内容

基于Alpaca-LoRA的finetune.py做无监督领域掩码语言建模,主要做了两处修改:

1. 加载Alpaca-LoRA权重替代Llama基础权重

from peft import (
    # LoraConfig,
    PeftModel,
    get_peft_model,
    get_peft_model_state_dict,
    prepare_model_for_int8_training,
    set_peft_model_state_dict,
)
# 注释原LoraConfig初始化代码
# config = LoraConfig(
#     r=lora_r,
#     lora_alpha=lora_alpha,
#     target_modules=lora_target_modules,
#     lora_dropout=lora_dropout,
#     bias="none",
#     task_type="CAUSAL_LM",
# )
# model = get_peft_model(model, config)

# 替换为加载Alpaca-LoRA权重
LORA_WEIGHTS = "tloen/alpaca-lora-7b"
model = PeftModel.from_pretrained(
    model,
    LORA_WEIGHTS,
    torch_dtype=torch.float16,
)

2. 自定义无监督数据集生成逻辑

def chunk_text(data):
    concantenated_text = ''
    all_result = []
    for i in range(data['train'].num_rows):
        concantenated_text += data['train']['combined'][i]
    tokenized_concantenated_text = tokenizer.encode(concantenated_text)[1:]
    tokenized_prompt = tokenizer.encode("### Text: ")[1:]
    full_length = len(tokenized_concantenated_text)
    for i in range(0, full_length, chunk_size):
        text = tokenized_concantenated_text[i: i+chunk_size+overlap_size] 
        text = tokenized_prompt + text
        text = tokenizer.decode(text)
        
        result = tokenizer(text, padding=False)
        if result["input_ids"][-1] != tokenizer.eos_token_id:
            result["input_ids"].append(tokenizer.eos_token_id)
            result["attention_mask"].append(1)

        result["labels"] = result["input_ids"].copy()

        all_result.append(result)
    return all_result

报错信息

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ in <cell line: 2>:2                                                                              │
│                                                                                                  │
│ /usr/local/lib/python3.9/dist-packages/transformers/trainer.py:1662 in train                     │
│                                                                                                  │
│   1659 │   │   inner_training_loop = find_executable_batch_size(                                 │
│   1660 │   │   │   self._inner_training_loop, self._train_batch_size, args.auto_find_batch_size  │
│   1661 │   │   )                                                                                 │
│ ❱ 1662 │   │   return inner_training_loop(                                                       │
│   1663 │   │   │   args=args,                                                                    │
│   1664 │   │   │   resume_from_checkpoint=resume_from_checkpoint,                                │
│   1665 │   │   │   trial=trial,                                                                  │
│                                                                                                  │
│ /usr/local/lib/python3.9/dist-packages/transformers/trainer.py:1991 in _inner_training_loop      │
│                                                                                                  │
│   1988 │   │   │   │   │   │   │   xm.optimizer_step(self.optimizer)                             │
│   1989 │   │   │   │   │   elif self.do_grad_scaling:                                            │
│   1990 │   │   │   │   │   │   scale_before = self.scaler.get_scale()                            │
│ ❱ 1991 │   │   │   │   │   │   self.scaler.step(self.optimizer)                                  │
│   1992 │   │   │   │   │   │   self.scaler.update()                                              │
│   1993 │   │   │   │   │   │   scale_after = self.scaler.get_scale()                             │
│   1994 │   │   │   │   │   │   optimizer_was_run = scale_before <= scale_after                   │
│                                                                                                  │
│ /usr/local/lib/python3.9/dist-packages/torch/cuda/amp/grad_scaler.py:368 in step                 │
│                                                                                                  │
│   365 │   │   if optimizer_state["stage"] is OptState.READY:                                     │
│   366 │   │   │   self.unscale_(optimizer)                                                       │
│   367 │   │                                                                                      │
│ ❱ 368 │   │   assert len(optimizer_state["found_inf_per_device"]) > 0, "No inf checks were rec   │
│   369 │   │                                                                                      │
│   370 │   │   retval = self._maybe_opt_step(optimizer, optimizer_state, *args, **kwargs)         │
│   371                                                                                            │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
AssertionError: No inf checks were recorded for this optimizer.

环境信息

  • Python 3.9
  • CUDA 11.8

解决方案

1. 修正混合精度配置与模型加载逻辑

该报错核心是GradScaler未检测到梯度缩放操作,通常因混合精度配置不匹配导致:

  • 确保基础模型加载时的精度与Peft模型一致,且开启int8/fp16训练:
# 基础模型加载修正
model = AutoModelForCausalLM.from_pretrained(
    base_model_path,  # 替换为你的Llama基础模型路径
    load_in_8bit=True,  # 若不用int8则设为float16=True
    torch_dtype=torch.float16,
    device_map="auto",
)
# 加载Alpaca-LoRA
LORA_WEIGHTS = "tloen/alpaca-lora-7b"
model = PeftModel.from_pretrained(
    model,
    LORA_WEIGHTS,
    torch_dtype=torch.float16,
)
# 强制设置模型为训练模式
model.train()
  • 确保TrainerArguments中开启fp16=True:
training_args = TrainingArguments(
    ...
    fp16=True,
    ...
)

2. 修复MLM任务的标签逻辑

当前数据集代码将labels直接复制input_ids,是自回归任务的逻辑,而非MLM任务。MLM需要对输入token随机掩码,并仅保留掩码位置的标签,其他位置设为-100(跳过损失计算):

import random

def chunk_text(data):
    all_result = []
    chunk_size = 512  # 根据你的硬件调整
    overlap_size = 64
    mask_ratio = 0.15

    for i in range(data['train'].num_rows):
        text = data['train']['combined'][i]
        tokenized_text = tokenizer.encode(text, add_special_tokens=False)
        tokenized_prompt = tokenizer.encode("### Text: ", add_special_tokens=False)
        full_length = len(tokenized_text)

        # 单条文本分块,避免拼接所有文本导致内存溢出
        for j in range(0, full_length, chunk_size - overlap_size):
            chunk_tokens = tokenized_text[j:j+chunk_size]
            input_tokens = tokenized_prompt + chunk_tokens + [tokenizer.eos_token_id]
            labels = input_tokens.copy()

            # 生成掩码位置(仅对正文部分掩码,跳过prompt和eos)
            mask_start = len(tokenized_prompt)
            mask_end = len(input_tokens) - 1
            mask_count = max(1, int(mask_ratio * (mask_end - mask_start)))
            mask_indices = random.sample(range(mask_start, mask_end), mask_count)

            # 执行MLM掩码规则:80%掩码,10%随机token,10%保留原token
            for idx in mask_indices:
                rand_val = random.random()
                if rand_val < 0.8:
                    input_tokens[idx] = tokenizer.mask_token_id
                elif rand_val < 0.9:
                    input_tokens[idx] = random.choice(list(tokenizer.vocab.values()))
                # 剩余10%保留原token,labels不变

            # 非掩码位置设为-100,不参与损失计算
            for idx in range(len(labels)):
                if idx not in mask_indices:
                    labels[idx] = -100

            all_result.append({
                "input_ids": input_tokens,
                "attention_mask": [1]*len(input_tokens),
                "labels": labels
            })
    return all_result

3. 调整依赖库版本

部分版本的transformers/peft/torch存在兼容性问题,可尝试:

  • 升级依赖库:
pip install --upgrade transformers peft bitsandbytes torch
  • 若仍报错,降级torch到与CUDA11.8兼容的稳定版本:
pip install torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 --index-url https://download.pytorch.org/whl/cu118

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:44:54