Open ywm12345 opened 1 year ago
说明里面没有写支持多卡。尝试将ChatGLM-6B里面的utils.py复制过来,按照ChatGLM-6B的方式,将Web_demo_hf.py改多卡,会报错。
说明里面没有写支持多卡。尝试将ChatGLM-6B里面的utils.py复制过来,按照ChatGLM-6B的方式,将Web_demo_hf.py改多卡,会报错。
是的,我也这么操作了,报错各种参数不存在什么的,应该需要重新写生成device_map这个方法,
说明里面没有写支持多卡。尝试将ChatGLM-6B里面的utils.py复制过来,按照ChatGLM-6B的方式,将Web_demo_hf.py改多卡,会报错。
能不能指定多卡中的某个卡部署呀
多卡inference可以通过改变设备的device,如果不想理解并改动代码,可以通过在外面设定CUDA_VISIBLE_DEVICES 环境变量启动使用不同卡的多个进程实现。
多卡inference可以通过改变设备的device,如果不想理解并改动代码,可以通过在外面设定CUDA_VISIBLE_DEVICES 环境变量启动使用不同卡的多个进程实现。
我看了chatglm-6b的那个device_map也就是把层数分到机器的各个gpu块上,但visualglm中的层数我看了config.json,也没有准确看出有多少层,且还有类似device_map = {'transformer.word_embeddings': 0, 'transformer.final_layernorm': 0, 'lm_head': 0}这种参数也不知道有哪些参数,所以我也不知道该如何去定义device_map,有没有例子或教程什么的
稍微分享一下:
根据代码,可以知道 VisualGLM 大概是根据 BLIP-2 的方式训练出来的。(参阅BLIP-2论文)
目前的尝试是,把 ChatGLM-6B 里的 utils 里的 load_model_on_gpus 和 auto_configure_device_map 两个函数复制到这边。然后直接使用 load_model_on_gpus 函数加载模型,然后运行。
在这种情况下,模型会报出几百行错误,具体内容为:我们的 device_map 并没有给模型的各种层各种权重(比如Qformer和ViT的各种Layer还有从Visual Prompt到LLM的投影层之类的)指定所在的device. 根据报错信息列出的所有内容,可以得知BLIP-2中的Q-Former包括12层(0-11)和一个Final_layernorm,以及WordEmbedding,同理还有图像编码器ViT的39层和几个Embedding。所以把这些内容全部添加到device_map里就行了,需要改写一些逻辑。
def auto_configure_device_map(num_gpus: int) -> Dict[str, int]:
# transformer.word_embeddings 占用1层
# transformer.final_layernorm 和 lm_head 占用1层
# transformer.layers 占用 28 层
# 总共30层分配到num_gpus张卡上
num_trans_layers = 28
# bugfix: 在linux中调用torch.embedding传入的weight,input不在同一device上,导致RuntimeError
# windows下 model.device 会被设置成 transformer.word_embeddings.device
# linux下 model.device 会被设置成 lm_head.device
# 在调用chat或者stream_chat时,input_ids会被放到model.device上
# 如果transformer.word_embeddings.device和model.device不同,则会导致RuntimeError
# 因此这里将transformer.word_embeddings,transformer.final_layernorm,lm_head都放到第一张卡上
# bugfix[TreemanCHou]
# 对于采用BLIP的 VisualGLM,其包括39层的ViT和12层的Qformer.
# Qformer包括一个final_layernorm层。
# 除此之外,还包括VitTransformer 的Wordembedding和positionembedding
# 以及 VItMixin的patchEmbedding和cls.ln_vision(虽然暂时不知道是干啥的)
# 如果把独立的层全部放在第一个卡里,会报OOM. 所以把一部分层放到最后一卡,
# 并且把used以及总layers - 1 。
# 在这样做之后,DEVICE 0 会突然OOM。怀疑是因为各种Word的Embedding太大了。
# 所以把他挪到最后一卡去。
device_map = {
'transformer.word_embeddings': num_gpus - 1,
'transformer.final_layernorm': num_gpus - 1,
'lm_head': num_gpus - 1,
'image_encoder.qformer.transformer.final_layernorm': 0,
'image_encoder.vit.mixins.patch_embedding.proj': num_gpus - 1,
'image_encoder.vit.mixins.cls.ln_vision': num_gpus - 1,
'image_encoder.vit.transformer.word_embeddings': num_gpus - 1,
'image_encoder.vit.transformer.position_embeddings': num_gpus - 1,
'image_encoder.qformer.transformer.word_embeddings': num_gpus - 1,
'image_encoder.glm_proj': 0,
}
num_vit_layers = 39
num_qf_layers = 12
per_gpu_layers = (num_qf_layers + num_trans_layers + num_vit_layers + 10) / num_gpus
used = 10 - 8 # 因为挪了8个到最后一卡
gpu_target = 0
for i in range(num_trans_layers + num_vit_layers + num_qf_layers):
if used >= per_gpu_layers:
gpu_target += 1
used = 0
assert gpu_target < num_gpus
if i < num_trans_layers:
device_map[f'transformer.layers.{i}'] = gpu_target
elif i < num_trans_layers + num_vit_layers:
device_map[f'image_encoder.vit.transformer.layers.{i - num_trans_layers}'] = gpu_target
elif i < num_trans_layers + num_vit_layers + num_qf_layers:
device_map[f'image_encoder.qformer.transformer.layers.{i - num_trans_layers - num_vit_layers }'] = gpu_target
used += 1
return device_map
这样做了之后是可以运行的,观察各个卡的性能,在开始阶段,模型也的确均匀地分布在多卡上加载了。但唯独GPU-0会别的多一些,然后再Out Of Memory 。尽管做了如代码中的修改和量化,仍然会发生如我在注释里描述的那样的错误,即:在最后突然GPU-0的显存占用急速增加然后OOM. 不过我的服务器性能有限,只有8卡12g,具体能否在更大的单卡上成功运行我也没机会测试了,大家有进展的话记得踢我一脚(
多卡部署,参考chatGLM-6B ,报错Expected all tensors to be on the same device, but found at least two devices, cuda:1 and cuda:0! (when checking argument for argument index in method wrapper__index_select)
通过手动自定gpu 搞定: pre_txt_emb = pre_txt_emb.to('cuda:0') image_embeds = image_embeds.to('cuda:0') post_txt_emb = post_txt_emb.to('cuda:0') inputs_embeds = torch.cat([pre_txt_emb, image_embeds, post_txt_emb], dim=1)
稍微分享一下:
根据代码,可以知道 VisualGLM 大概是根据 BLIP-2 的方式训练出来的。(参阅BLIP-2论文)
目前的尝试是,把 ChatGLM-6B 里的 utils 里的 load_model_on_gpus 和 auto_configure_device_map 两个函数复制到这边。然后直接使用 load_model_on_gpus 函数加载模型,然后运行。
在这种情况下,模型会报出几百行错误,具体内容为:我们的 device_map 并没有给模型的各种层各种权重(比如Qformer和ViT的各种Layer还有从Visual Prompt到LLM的投影层之类的)指定所在的device. 根据报错信息列出的所有内容,可以得知BLIP-2中的Q-Former包括12层(0-11)和一个Final_layernorm,以及WordEmbedding,同理还有图像编码器ViT的39层和几个Embedding。所以把这些内容全部添加到device_map里就行了,需要改写一些逻辑。
def auto_configure_device_map(num_gpus: int) -> Dict[str, int]: # transformer.word_embeddings 占用1层 # transformer.final_layernorm 和 lm_head 占用1层 # transformer.layers 占用 28 层 # 总共30层分配到num_gpus张卡上 num_trans_layers = 28 # bugfix: 在linux中调用torch.embedding传入的weight,input不在同一device上,导致RuntimeError # windows下 model.device 会被设置成 transformer.word_embeddings.device # linux下 model.device 会被设置成 lm_head.device # 在调用chat或者stream_chat时,input_ids会被放到model.device上 # 如果transformer.word_embeddings.device和model.device不同,则会导致RuntimeError # 因此这里将transformer.word_embeddings,transformer.final_layernorm,lm_head都放到第一张卡上 # bugfix[TreemanCHou] # 对于采用BLIP的 VisualGLM,其包括39层的ViT和12层的Qformer. # Qformer包括一个final_layernorm层。 # 除此之外,还包括VitTransformer 的Wordembedding和positionembedding # 以及 VItMixin的patchEmbedding和cls.ln_vision(虽然暂时不知道是干啥的) # 如果把独立的层全部放在第一个卡里,会报OOM. 所以把一部分层放到最后一卡, # 并且把used以及总layers - 1 。 # 在这样做之后,DEVICE 0 会突然OOM。怀疑是因为各种Word的Embedding太大了。 # 所以把他挪到最后一卡去。 device_map = { 'transformer.word_embeddings': num_gpus - 1, 'transformer.final_layernorm': num_gpus - 1, 'lm_head': num_gpus - 1, 'image_encoder.qformer.transformer.final_layernorm': 0, 'image_encoder.vit.mixins.patch_embedding.proj': num_gpus - 1, 'image_encoder.vit.mixins.cls.ln_vision': num_gpus - 1, 'image_encoder.vit.transformer.word_embeddings': num_gpus - 1, 'image_encoder.vit.transformer.position_embeddings': num_gpus - 1, 'image_encoder.qformer.transformer.word_embeddings': num_gpus - 1, 'image_encoder.glm_proj': 0, } num_vit_layers = 39 num_qf_layers = 12 per_gpu_layers = (num_qf_layers + num_trans_layers + num_vit_layers + 10) / num_gpus used = 10 - 8 # 因为挪了8个到最后一卡 gpu_target = 0 for i in range(num_trans_layers + num_vit_layers + num_qf_layers): if used >= per_gpu_layers: gpu_target += 1 used = 0 assert gpu_target < num_gpus if i < num_trans_layers: device_map[f'transformer.layers.{i}'] = gpu_target elif i < num_trans_layers + num_vit_layers: device_map[f'image_encoder.vit.transformer.layers.{i - num_trans_layers}'] = gpu_target elif i < num_trans_layers + num_vit_layers + num_qf_layers: device_map[f'image_encoder.qformer.transformer.layers.{i - num_trans_layers - num_vit_layers }'] = gpu_target used += 1 return device_map
这样做了之后是可以运行的,观察各个卡的性能,在开始阶段,模型也的确均匀地分布在多卡上加载了。但唯独GPU-0会别的多一些,然后再Out Of Memory 。尽管做了如代码中的修改和量化,仍然会发生如我在注释里描述的那样的错误,即:在最后突然GPU-0的显存占用急速增加然后OOM. 不过我的服务器性能有限,只有8卡12g,具体能否在更大的单卡上成功运行我也没机会测试了,大家有进展的话记得踢我一脚(
没必要搞得这么麻烦,我开始也是这样的,后来直接
device_map = {'transformer.word_embeddings': 0,
'transformer.final_layernorm': 0, 'lm_head': 0,
'image_encoder': 1
}
image的层就都别的GPU了
@bennyyu79, 老哥,想问问怎么手动修改pre_txt_emb = pre_txt_emb.to('cuda:0') image_embeds = image_embeds.to('cuda:0') post_txt_emb = post_txt_emb.to('cuda:0') inputs_embeds = torch.cat([pre_txt_emb, image_embeds, post_txt_emb], dim=1),我下载了模型权重文件,指定了对应路径,但是加载权重文件的模型还是用缓存里的模型文件,导致每次修改的都不生效
请官方团队出个方案给解决下呗
使用最新版github的sat
git clone https://github.com/THUDM/SwissArmyTransformer
cd SwissArmyTransformer
pip install .
然后
torchrun --nnode 1 --nproc-per-node 2 cli_demo_mp.py
如果之前下载过checkpoint,需要手动删掉重新下载。(因为权重文件为了适配model parallel更新了)
使用最新版github的sat
git clone https://github.com/THUDM/SwissArmyTransformer cd SwissArmyTransformer pip install .
然后
torchrun --nnode 1 --nproc-per-node 2 cli_demo_mp.py
如果之前下载过checkpoint,需要手动删掉重新下载。(因为权重文件为了适配model parallel更新了)
AttributeError: 'Namespace' object has no attribute 'pad_token_id'. Did you mean: 'bos_token_id'?为什么会显示这错误,我已经最新版了
需要保证本地的sat和VisualGLM-6B的代码都是最新的,重新pull一下github代码吧,别用旧版本
pip install SwissArmyTransformer --upgrade
git clone https://github.com/THUDM/VisualGLM-6B
你这个错误应该是checkpoint是旧版的,需要重新下载一下新的checkpoint
但是下载新的checkpoint需要两个前提:
rm -r ~/.sat_models/visualglm-6b
总之一句话:sat、visualglm-6b代码、visualglm-6b的checkpoint,三者都需要是新版本的。
+1 目前单卡推理也太慢了 30w的数据批量产出 24h还没解决。