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

微调microsoft/deberta-v3-base遇ValueError:无变量梯度可用求助

问题分析与解决方案

核心问题

你遇到的ValueError: No gradients provided for any variable本质是模型编译时未指定损失函数,导致反向传播无法计算梯度,同时代码中还有几处模型加载和训练流程的错误放大了这个问题。

关键错误点

  1. 未指定损失函数:model.compile(optimizer=optimizer)仅传入优化器,没有定义损失函数,TensorFlow无法计算参数梯度。
  2. 错误加载基础模型:用TFAutoModelForSequenceClassification加载模型是带分类头的,你需要的是纯Transformer编码器(取隐藏状态),应该用TFAutoModel。
  3. 冗余模型定义:初始定义的model = TFAutoModelForSequenceClassification.from_pretrained(...)完全未被使用,属于无效代码。
  4. 训练步数未正确定义:num_steps未赋值,导致create_optimizer的参数错误。
  5. 标签处理冗余:class_encode_column已经将标签转为整数编码,无需再用to_categorical,用SparseCategoricalCrossentropy更高效。

修正后的完整代码

import tensorflow as tf
from transformers import TFAutoModel, create_optimizer
from datasets import Dataset
import numpy as np

# 数据集处理
train_dataset = Dataset.from_pandas(df_tr[['text', 'label']]).class_encode_column("label")
val_dataset = Dataset.from_pandas(df_tes[['text', 'label']]).class_encode_column("label")

train_tok_dataset = train_dataset.map(tokenizer_func, batched=True, remove_columns=('text'))
val_tok_dataset = val_dataset.map(tokenizer_func, batched=True, remove_columns=('text'))

# 加载纯Transformer编码器模型,输出隐藏状态
transformer_model = TFAutoModel.from_pretrained(config.model_name, output_hidden_states=True)

# 构建自定义模型结构
input_ids = tf.keras.Input(shape=(config.max_len, ), dtype='int32')
attention_mask = tf.keras.Input(shape=(config.max_len, ), dtype='int32')

# 获取Transformer输出的隐藏状态(TFAutoModel输出顺序:last_hidden_state, pooler_output, hidden_states)
transformer_outputs = transformer_model([input_ids, attention_mask])    
hidden_states = transformer_outputs[2]

# 拼接最后4层隐藏状态
hidden_states_size = 4
selected_hidden_states = tf.keras.layers.concatenate([hidden_states[i] for i in range(-hidden_states_size, 0)])

# 自定义分类头
output = tf.keras.layers.Dense(128, activation='relu')(selected_hidden_states)
output = tf.keras.layers.Flatten()(output)
output = tf.keras.layers.Dense(3, activation='softmax')(output)

model = tf.keras.models.Model(inputs=[input_ids, attention_mask], outputs=output)

# 计算训练步数
batch_size = 8
num_epochs = config.epochs
batches_per_epoch = len(train_tok_dataset) // batch_size
total_train_steps = batches_per_epoch * num_epochs

# 创建优化器
optimizer, schedule = create_optimizer(init_lr=2e-5, num_warmup_steps=0, num_train_steps=total_train_steps)

# 编译模型:添加损失函数与评估指标
model.compile(
    optimizer=optimizer,
    loss=tf.keras.losses.CategoricalCrossentropy(),
    metrics=['accuracy']
)

# 启动训练
with tf.device('GPU:0'):
    model.fit(
        x=[np.array(train_tok_dataset["input_ids"]), np.array(train_tok_dataset["attention_mask"])],
        y=tf.keras.utils.to_categorical(train_dataset["label"], num_classes=3),
        validation_data=(
            [np.array(val_tok_dataset["input_ids"]), np.array(val_tok_dataset["attention_mask"])],
            tf.keras.utils.to_categorical(val_dataset["label"], num_classes=3)
        ),
        epochs=config.epochs,
        class_weight={0:0.57, 1:0.18, 2:0.39}
    )

关键修改说明

  1. 模型加载:用TFAutoModel替代TFAutoModelForSequenceClassification,确保拿到纯Transformer编码器的隐藏状态,而非带分类头的输出。
  2. 隐藏状态索引:TFAutoModel的输出元组中,隐藏状态是第3个元素(索引2),修正原代码的索引错误。
  3. 损失函数:添加CategoricalCrossentropy(对应独热标签),让TensorFlow能计算参数梯度。若想简化标签处理,可替换为SparseCategoricalCrossentropy(from_logits=False),此时无需调用to_categorical,直接传入整数标签即可。
  4. 训练步数:基于训练集大小和批次大小计算正确的总训练步数,保证优化器调度逻辑正常。
  5. 标签一致性:直接使用数据集内置的标签列,避免y_train/y_test可能存在的不匹配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:24:29