wangyuxinwhy / uniem

unified embedding model
Apache License 2.0
814 stars 61 forks source link

微调的方法是否支持仅微调部分参数 #90

Closed Xls1994 closed 1 year ago

Xls1994 commented 1 year ago

🚀 The feature

您好,从您的代码来看,提供了PrefixTraining的训练策略,我理解是只会微调这一些token的embedding表示。 第一个问题,从的我理解来看,预训练的BERT模型是有好多层的,您这个代码是没有冻结参数,全部做了微调,不知道这个理解有没有问题。 第二个问题是,如果您这个代码是微调了所有层的参数,有没有考虑过只微调部分层看一下效果呢

wangyuxinwhy commented 1 year ago

冻结参数的代码在 training_strategy 文件中,如下所示

def apply_model(self, model: T) -> T:
    embedder = model.embedder
    if not isinstance(embedder, UniemEmbedder):
        raise ValueError('Prefix training is only supported for UniemEmbedder')
    embedder = cast(UniemEmbedder, embedder)

    embedder.encoder.resize_token_embeddings(len(self.tokenizer))
    hook = functools.partial(
        partial_freeze_gradients,
        train_indices=torch.tensor(self.additional_special_token_ids),
    )
    if self.only_train_additional_special_tokens:
        for param in model.parameters():
            param.requires_grad = False
        embedding_layer_weight = embedder.encoder.get_input_embeddings().weight
        embedding_layer_weight = cast(torch.nn.Parameter, embedding_layer_weight)
        embedding_layer_weight.requires_grad = True
        embedding_layer_weight.register_hook(hook)
    return model

在 Embedding 层新增几个 Token,并只微调这几个 Token 的参数,其余参数保持不变,这样的好处是在不改变 Passage embedding 的情况下,微调 query 。

只更新新增 Token Ebedding 参数的方法通过 hook 来实现,如下所示

def partial_freeze_gradients(grad, train_indices: torch.Tensor):
    train_indices_grad = grad[train_indices, :]
    grad.zero_()
    grad[train_indices, :] = train_indices_grad
    return grad
Xls1994 commented 1 year ago

感谢您的回答,我继续研究一下