RuntimeError: value cannot be converted to type at::BFloat16 without overflow
我用的是transformers==4.42.3,出错文件是model_qwen2.py 1127行,当Qwen2 bfloat16时不出错,量化后出错,训练和推理都是。
然而服务器和本地对比出错部分的代码,发现俩版本都是4.42.3,结果文件不一样。可能和linux和windows环境不同有关。
第一次重装后,运行通过,第二次运行又出现该错误,观察model_qwen2.py发现又是错误代码。遂二度重装,这次长了个心眼,盯紧了这个文件,结果跟薛定谔的猫一样,一直看着就没问题,文件也和本地的一样了,不是错误的那个版本了。
吃屎一样。
总之,重装transformers,怀疑是老版本Qwen2代码的bug。
试了一个新方法,把min_dtype改成自定义的1e-4就通过了,怀疑是默认的min_dtype是float16的,最小值够不到bfloat16的最小值,而它现在要被转成bfloat16,因此不overflow就不行,这可能导致问题,因此报错。而1e-4是一个足够大的值,对softmax不相关的值也有很好的屏蔽作用,因此也能凑活用。
Pytorch RuntimeError: Expected tensor for argument #1 ‘indices’ to have one of the following scalar types: Long, Int; but got torch.FloatTenso instead
这句错在loss计算中从检查点重新计算embedding的过程。
敬告,所有数值错误,管他输出多少,先把输出打印出来看看错误值,硬扣脑袋改永远不知道问题在哪。
我出错的代码在某个embedding函数,传参好几个。报错说第1个有问题,那就是第2个传参,我这里叫input。一打印,输出个空list。
问题找到了,是我读数据时会删除过长的数据,但是写错代码了,出错就会硬返回一个初始化的空list。
突然出现一个CUDA out of memory 大到300多G
错误代码在casual_attention处,意识到是数据处理出错了,肯定有一个巨tm长的句子。经检查果然。
所以说防御性编程很重要,按MAX_LENGTH分割完文本了,最后再写代码检查一遍是很重要的。
RuntimeError: probability tensor contains either inf
, nan
or element < 0
这是我在量化Qwen2-7B的base到int4的时候,输出采用
self.model.generate(**model_inputs, do_sample=True)
的时候出现的错误。我输出了出错代码的前面的一些相关变量,发现由于logits也是使用的int4,导致output_logits全部变成inf,那么即使过softmax也全都是inf,然后就出现了上述错误。
之前看别人代码,他们把lm_head层的输出专门变成float32,原来是这么个原因。
output_layer = getattr(model, "lm_head")
if isinstance(output_layer, torch.nn.Linear) and output_layer.weight.dtype != torch.float32:
def fp32_forward_post_hook(module: torch.nn.Module, args: Tuple[torch.Tensor], output: torch.Tensor):
return output.to(torch.float32)
# 在这一层,设置一个hook。该hook在该层forward之后,接收固定参数,并返回null或一个修改后的output。
output_layer.register_forward_hook(fp32_forward_post_hook)
另外,如果我让do_sample=False了,虽然可以正常输出,但是显然采样不会正常,测试完输出全是叹号,连基本的续写都没了。
LoRA训练代码训练完直接inference,output像随机输出一样乱,然而再次读取checkpoint又变成高性能
应该是我代码写的有问题,但是暂时找不到原因。先贴在这儿等以后查出来了再记录。
# FineTuning
class LoRAFT:
train_result = None
eval_result = None
def __init__(self,
model,
tokenizer,
device=None,
train_dataset=None,
eval_dataset=None,
output_dir=None,
train_strategy: str="lora",
lora_r: int=32,
create_lora:bool=True,
train_samples:int=None):
self.is_train = True if train_dataset else False
self.device = device if device else model.device
self.tokenizer = tokenizer
if train_dataset:
train_dataset = train_dataset.shuffle()
if train_samples:
train_dataset = train_dataset.select(range(train_samples))
self.model, self.trainer = self.set_train(train_strategy, model, train_dataset, eval_dataset, output_dir, create_lora, lora_r)
else:
self.model = model
self.print_trainable_parameters()
self.output_hook()
def output_hook(self):
output_layer = getattr(self.model, "lm_head")
if isinstance(output_layer, torch.nn.Linear) and output_layer.weight.dtype != torch.float32:
def fp32_forward_post_hook(module: torch.nn.Module, args: Tuple[torch.Tensor], output: torch.Tensor):
if self.is_train:
output = output.to(torch.float32)
# print("see output:\n", output)
return output
# 在这一层设置一个hook。该hook在该层forward之后,接收固定参数,并返回null或一个修改后的output。
output_layer.register_forward_hook(fp32_forward_post_hook)
def set_train(self, train_strategy, model, train_dataset, eval_dataset=None, output_dir