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

使用PEFT的LoRA微调NV-Embed-v2时遇inputs_embeds参数错误咨询

问题描述

使用PEFT库的LoRA微调Hugging Face上的nvidia/NV-Embed-v2模型时,触发错误:

TypeError: NVEmbedModel.forward() got an unexpected keyword argument 'inputs_embeds'

已确认模型本身应支持inputs_embeds参数,当前使用FEATURE_EXTRACTION任务类型,通过AutoModel以8bit量化加载模型,相关代码如下:

from transformers import AutoTokenizer, AutoModel, TrainingArguments, Trainer
from peft import LoraConfig, get_peft_model, TaskType
import pandas as pd
from datasets import Dataset

# load the base model
model_name = "nvidia/NV-Embed-v2"
base_model = AutoModel.from_pretrained(model_name, trust_remote_code=True, load_in_8bit=True)
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)

# define lora config
lora_config = LoraConfig(
    r=8,
    lora_alpha=16,
    lora_dropout=0.1,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
    bias="none",
    task_type=TaskType.FEATURE_EXTRACTION
)

peft_model = get_peft_model(base_model, lora_config)

# load the data
df = pd.DataFrame([['tomato', 'tomato ketchup heinz', 1], ['tomato', '500gm salted chips', 0], ['tomato', 'tomato 500gm', 1], ['strawberry', 'strawberry ripe 200gm', 1]], columns=['search_term', 'product_string', 'score'])
data = Dataset.from_pandas(df)
data = data.train_test_split(test_size=0.25)

train_dataset = data["train"]
test_dataset = data["test"]


def preprocess_function(examples):
    return tokenizer(examples["product_string"], examples["search_term"], truncation=True, padding="max_length", max_length=128)

train_dataset_final = train_dataset.map(preprocess_function, batched=True)

train_dataset_final.set_format(
    type="torch", columns=["input_ids", "attention_mask", "score"]
)

# Train the model
training_args = TrainingArguments(
    output_dir='lora-nvembedv2',
    auto_find_batch_size=True,
    learning_rate= 3e-2,
    num_train_epochs=1
)

trainer = Trainer(
    model=peft_model,
    args=training_args,
    train_dataset=train_dataset_final,
)

trainer.train()
解决方案

1. 修改PEFT任务类型

FEATURE_EXTRACTION任务类型会触发PEFT和Trainer的特定逻辑,自动传递inputs_embeds参数,而NVEmbedModel的forward方法不兼容该参数。将任务类型改为SEQ_CLS(序列分类),匹配你的打分任务本质:

lora_config = LoraConfig(
    r=8,
    lora_alpha=16,
    lora_dropout=0.1,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
    bias="none",
    task_type=TaskType.SEQ_CLS  # 替换任务类型
)

2. 包装模型过滤不支持的参数

如果必须保留FEATURE_EXTRACTION类型,通过包装PEFT模型,在forward时移除inputs_embeds参数:

from peft import PeftModel

class WrappedNVEmbedModel(PeftModel):
    def forward(self, **kwargs):
        # 移除模型不支持的inputs_embeds参数
        kwargs.pop("inputs_embeds", None)
        return super().forward(**kwargs)

# 替换原peft_model初始化代码
peft_model = WrappedNVEmbedModel(base_model, lora_config)

3. 自定义Trainer的损失计算逻辑

重写Trainer的compute_loss方法,直接使用input_ids和attention_mask调用模型,避免Trainer自动生成inputs_embeds:

import torch

class CustomTrainer(Trainer):
    def compute_loss(self, model, inputs, return_outputs=False):
        # 分离任务标签
        labels = inputs.pop("score")
        # 用模型支持的参数调用forward
        outputs = model(**inputs)
        # 根据任务类型选择损失函数,这里用MSE适配0/1打分任务
        loss = torch.nn.functional.mse_loss(outputs.last_hidden_state[:, 0, :].mean(dim=-1), labels.float())
        return (loss, outputs) if return_outputs else loss

# 使用自定义Trainer替代原Trainer
trainer = CustomTrainer(
    model=peft_model,
    args=training_args,
    train_dataset=train_dataset_final,
)

4. 确认模型forward参数

查看NVEmbedModel的forward方法签名,确保只传递模型明确支持的参数(如input_ids、attention_mask),避免Trainer触发自动生成inputs_embeds的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:50:20