OFA-Sys / Chinese-CLIP

Chinese version of CLIP which achieves Chinese cross-modal retrieval and representation generation.
MIT License
4.48k stars 462 forks source link

导入CLIP模型Finetune,clip_model.encode_text()输出Nan #64

Closed Qiaojiao-225 closed 1 year ago

Qiaojiao-225 commented 1 year ago

您好,我通过以下代码导入模型后想要微调CLIP模型,我先冻结了CLIP的参数,添加了全连接层在我的任务上训练, 之后再解冻CLIP部分参数,但是CLIP模型输出为Nan,请问我应该如何微调CLIP模型呢?

model, preprocess = load_from_name("ViT-B-16", device=device, download_root='./')
DtYXs commented 1 year ago

您好,根据您的描述您应该是在Chinese-CLIP的基础上添加一些层然后在自己的任务上进行训练。请问您一开始冻结CLIP时是正常训练,解冻CLIP之后出现的问题吗? 由于不知道您具体的代码,建议您先检查一下您输入数据中是否存在问题,如果输入数据中包含NaN或无穷大的值,则模型输出也可能为NaN。 另外需要注意使用归一化后的图文特征用于下游任务: text_features = model.encode_text(text) text_features /= text_features.norm(dim=-1, keepdim=True) 您还可以尝试适当减小一下对CLIP的学习率,看看能否解决问题

Qiaojiao-225 commented 1 year ago

冻结CLIP训练时是正常的, 解冻CLIP后, model.encode_text(clip_tokens)会输出NaN. 我在forward()中添加了类似assert not torch.isnan(clip_tokens).any(), "Nan"assert not torch.isinf(clip_tokens).any(), "Inf"对输入数据检查, 输入数据中没有包含NaN和Inf. 调小学习率1e-8仍然会输出NaN. 我的任务是文本二分类, 难道是这个任务不适合进行微调吗?

Qiaojiao-225 commented 1 year ago

但是,我调用Huggingface transformers的Chinese CLIP模型可以在我的任务上训练,只有clip模型引入和调用的方式不同,其他代码完全一样,我不知道是什么原因.

from transformers import ChineseCLIPModel
self.clip_model = ChineseCLIPModel.from_pretrained("OFA-Sys/chinese-clip-vit-base-patch16")
DtYXs commented 1 year ago

您好,请问是训练一段时间后出现Nan的情况吗,您方便提供训练的log以及输出为Nan时的输入文本原始数据吗

Qiaojiao-225 commented 1 year ago

您好,请问是训练一段时间后出现Nan的情况吗,您方便提供训练的log以及输出为Nan时的输入文本原始数据吗

是第1个batch更新参数后, 第2个batch里clip_encode_text()输出Nan. 方便, 给我您的邮箱吧.

DtYXs commented 1 year ago

您好,请问是训练一段时间后出现Nan的情况吗,您方便提供训练的log以及输出为Nan时的输入文本原始数据吗

是第1个batch更新参数后, 第2个batch里clip_encode_text()输出Nan. 方便, 给我您的邮箱吧.

好的,您可以发送到panjunshu.pjs@alibaba-inc.com哈

DtYXs commented 1 year ago

冻结CLIP训练时是正常的, 解冻CLIP后, model.encode_text(clip_tokens)会输出NaN. 我在forward()中添加了类似assert not torch.isnan(clip_tokens).any(), "Nan"assert not torch.isinf(clip_tokens).any(), "Inf"对输入数据检查, 输入数据中没有包含NaN和Inf. 调小学习率1e-8仍然会输出NaN. 我的任务是文本二分类, 难道是这个任务不适合进行微调吗?

您好,问题似乎是由于在您的二分类任务上,同时应用Adam优化器和半精度浮点训练数值不稳定,导致clip中bert的word embedding层参数在第一次梯度更新后变为nan。 您可以参考以下任一方式解决问题: 1.将CLIP模型设置为单精度浮点,例如在CLIP模型初始化时设置clip_model = clip_model.float() 2.将Adam优化器的eps参数指定为1e-3,例如optimizer = torch.optim.Adam(model.parameters(), lr=xxx, eps=1e-3) 3.将Adam优化器更换为SGD优化器

Qiaojiao-225 commented 1 year ago

您好,问题似乎是由于在您的二分类任务上,同时应用Adam优化器和半精度浮点训练数值不稳定,导致clip中bert的word embedding层参数在第一次梯度更新后变为nan。 您可以参考以下任一方式解决问题: 1.将CLIP模型设置为单精度浮点,例如在CLIP模型初始化时设置clip_model = clip_model.float() 2.将Adam优化器的eps参数指定为1e-3,例如optimizer = torch.optim.Adam(model.parameters(), lr=xxx, eps=1e-3) 3.将Adam优化器更换为SGD优化器

好的!我的问题解决了。真的很感谢您在这个问题上的投入和耐心解答,像您这样有经验的开发者为我们提供了无价的帮助,感谢您为开源社区做出的贡献。

Dinosaurcubs commented 5 months ago

冻结CLIP训练时是正常的, 解冻CLIP后, model.encode_text(clip_tokens)会输出NaN. 我在forward()中添加了类似assert not torch.isnan(clip_tokens).any(), "Nan"assert not torch.isinf(clip_tokens).any(), "Inf"对输入数据检查, 输入数据中没有包含NaN和Inf. 调小学习率1e-8仍然会输出NaN. 我的任务是文本二分类, 难道是这个任务不适合进行微调吗?

您好,问题似乎是由于在您的二分类任务上,同时应用Adam优化器和半精度浮点训练数值不稳定,导致clip中bert的word embedding层参数在第一次梯度更新后变为nan。 您可以参考以下任一方式解决问题: 1.将CLIP模型设置为单精度浮点,例如在CLIP模型初始化时设置clip_model = clip_model.float() 2.将Adam优化器的eps参数指定为1e-3,例如optimizer = torch.optim.Adam(model.parameters(), lr=xxx, eps=1e-3) 3.将Adam优化器更换为SGD优化器

你好,我最近微调clip训练自己网络也遇到nan问题,检索相关信息找到了您这篇工作,请问作者方便解答下我的问题吗?