shuxueslpi / chatGLM-6B-QLoRA

使用peft库,对chatGLM-6B/chatGLM2-6B实现4bit的QLoRA高效微调,并做lora model和base model的merge及4bit的量化(quantize)。
350 stars 46 forks source link

合并问题 #2

Closed ShayDuane closed 1 year ago

ShayDuane commented 1 year ago

我看peft仓库里源码,量化加载的模型没法直接merge合并吧,所以要想合并的话必须全精度加载训练完之后合并,然后再用glm官方的量化脚本进行量化的嘛,那我看到你train里面的代码是量化加载的吧,这种情况下想合并应该要对lora layer的weight进行反量化才可以吧

shuxueslpi commented 1 year ago

@RuSignalFlag 训练过程加载的量化模型是base model,真正的lora adapter其实不是量化的,所以保存的adapter也不是量化的。 然后在merge的时候,加载的base model是fp16的,和adapter合并之后再量化。 所以真正的反量化应该是发生在训练/推理时的模型4bit矩阵乘法和fp16乘法的结果合并时,可以看我参考的关于这部分用时间换空间的文档。 下面是训练加载量化模型,再调用peft后得到的peft model的张量打印,可以看到lora部分确实不是量化的:

# qkv量化部分
In [12]: model.base_model.model.transformer.layers[0].attention.query_key_value.weight
Out[12]: 
Parameter containing:
Parameter(Params4bit([[184],
            [215],
            [183],
            ...,
            [148],
            [ 54],
            [249]], device='cuda:0', dtype=torch.uint8))

# lora部分,非量化
In [17]: model.base_model.model.transformer.layers[0].attention.query_key_value.lora_A.default.weight
Out[17]: 
Parameter containing:
tensor([[-0.0144,  0.0076, -0.0096,  ...,  0.0113, -0.0150,  0.0060],
        [-0.0096,  0.0049, -0.0014,  ..., -0.0060, -0.0140,  0.0115],
        [-0.0101,  0.0134, -0.0066,  ..., -0.0097,  0.0116, -0.0127],
        [-0.0054,  0.0090, -0.0131,  ...,  0.0082,  0.0068,  0.0122]],
       device='cuda:0', requires_grad=True)

In [18]: model.base_model.model.transformer.layers[0].attention.query_key_value.lora_A.default.weight.dtype
Out[18]: torch.float32
ShayDuane commented 1 year ago

@shuxueslpi 后来看代码看明白了,谢谢。保存的只是adapter,合并的时候重新load全精度的基础模型然后应用这个训练好的adapter实例化peftmodel,这个peftmodel Lora层的原始权重是fp16,lora_a和lora_b都是fp32,这个时候就可以相加了。