微调Mistral LLM触发AssertionError:No inf checks...该如何解决?
解决PyTorch AMP微调Mistral-7B-Instruct-v0.1-GPTQ时的"No inf checks were recorded for this optimizer"错误
当你用PyTorch自动混合精度(AMP)微调Mistral-7B-Instruct-v0.1-GPTQ模型时,遇到AssertionError: No inf checks were recorded for this optimizer,设置peft_config.inference_mode = False后能跑13步但仍报错,且仅在自有数据集上出现,以下是可行的解决方法:
1. 关闭AMP的梯度Inf/Nan检查触发逻辑
这个错误源于AMP梯度缩放器在优化器更新前,未找到对应的Inf/Nan检查记录。可以通过以下方式绕过:
- 在
TrainingArguments里添加fp16_full_eval=False,同时调整梯度检查点参数:
training_arguments = TrainingArguments( # 保留原有参数 fp16=True, fp16_full_eval=False, gradient_checkpointing_kwargs={"use_reentrant": False} )
- 或者手动实例化不带严格Inf检查的GradScaler,传给Trainer:
scaler = torch.cuda.amp.GradScaler(enabled=True) trainer = SFTTrainer( # 其他参数 scaler=scaler )
2. 调整PEFT版本与配置
这个问题确实和PEFT版本强相关,尤其是4bit量化+AMP+LoRA的组合场景:
- 要么降级PEFT到
0.4.0(该版本对4bit训练兼容性更好),要么升级到最新稳定版:
pip install peft==0.4.0 # 或者升级 pip install --upgrade peft
- 调用
prepare_model_for_kbit_training时显式开启梯度检查点支持:
model = prepare_model_for_kbit_training(model, use_gradient_checkpointing=True)
3. 排查自有数据集的异常
既然只有自有数据会触发问题,大概率是数据里存在异常样本:
- 过滤掉长度超过
max_seq_length的样本,避免分词后梯度爆炸:
tokenizer = AutoTokenizer.from_pretrained("TheBloke/Mistral-7B-Instruct-v0.1-GPTQ") data = data.filter(lambda x: len(tokenizer(x["text"])["input_ids"]) <= 512)
- 预处理时清理空值、特殊字符:
data_df = data_df.dropna(subset=["Category", "Description"]) data_df["Category"] = data_df["Category"].str.strip() data_df["Description"] = data_df["Description"].str.strip()
4. 更换优化器并调整训练参数
paged_adamw_32bit和AMP的兼容性在某些场景下不佳,换成标准AdamW试试:
training_arguments = TrainingArguments( # 保留原有参数 optim="adamw_torch", learning_rate=1e-4 # 适当降学习率,减少梯度异常概率 )
整合修改后的代码示例
def finetune_mistral_7b(): data_df = pd.read_csv("Book1.csv") # 数据清洗 data_df = data_df.dropna(subset=["Category", "Description"]) data_df["Category"] = data_df["Category"].str.strip() data_df["Description"] = data_df["Description"].str.strip() data_df["text"] = data_df[["Category", "Description"]].apply( lambda x: "<human>: What description does the category" + x["Category"] + "have?" + "\n<assistant>" + x["Description"], axis=1 ) data = Dataset.from_pandas(data_df) # 过滤超长样本 tokenizer = AutoTokenizer.from_pretrained("TheBloke/Mistral-7B-Instruct-v0.1-GPTQ") data = data.filter(lambda x: len(tokenizer(x["text"])["input_ids"]) <= 512) tokenizer.pad_token = tokenizer.eos_token tokenizer.padding_side = 'right' quantization_config_loading = GPTQConfig(bits=4, disable_exllama=True, tokenizer=tokenizer) model = AutoModelForCausalLM.from_pretrained( "TheBloke/Mistral-7B-Instruct-v0.1-GPTQ", quantization_config=quantization_config_loading, device_map="auto" ) model.config.use_cache=False model.config.pretraining_tp=1 model.gradient_checkpointing_enable() model = prepare_model_for_kbit_training(model, use_gradient_checkpointing=True) peft_config = LoraConfig( r=16, lora_alpha=16, lora_dropout=0.05, bias="none", task_type="CAUSAL_LM", target_modules=["q_proj", "v_proj"] ) peft_config.inference_mode = False model = get_peft_model(model, peft_config) training_arguments = TrainingArguments( output_dir="mistral-finetuned-samsum", per_device_train_batch_size=8, gradient_accumulation_steps=1, optim="adamw_torch", learning_rate=1e-4, lr_scheduler_type="cosine", save_strategy="epoch", logging_steps=10, num_train_epochs=1, max_steps=250, fp16=True, fp16_full_eval=False, push_to_hub=True ) scaler = torch.cuda.amp.GradScaler(enabled=True) trainer = SFTTrainer( model=model, train_dataset=data, peft_config=peft_config, dataset_text_field="text", args=training_arguments, tokenizer=tokenizer, packing=False, max_seq_length=512, scaler=scaler ) trainer.train() trainer.push_to_hub()
内容的提问来源于stack exchange,提问作者BunningSnag
相关产品推荐
相关产品推荐

