LLM大模型在Transformer做推理是,如何根据GPU的显卡做多卡加载模型呢?通常会使用device_map做参数,device_map
是AutoModel.from_pretrained()
方法中的一个重要参数,它用于指定模型的各个部件应加载到哪个具体的计算设备上,以实现资源的有效分配和利用。这个参数在进行模型并行或分布式训练时特别有用。
device_map参数主要有如下4种选项:”auto”,”balanced”,”balanced_low_0″,”sequential”
- “auto” 和 “balanced” 将会在所有的GPU上平衡切分模型。主要是有可能发现更高效的分配策略。“balanced” 参数的功能则保持稳定。(个人不推荐使用)
- “balanced_low_0” 会在除了第一个GPU上的其它GPU上平衡划分模型,并且在第一个 GPU 上占据较少资源。这个选项符合需要在第一个 GPU 上进行额外操作的需求,例如需要在第一个 GPU 执行 generate 函数(迭代过程)。(墙裂推荐使用)
- “sequential” 按照GPU的顺序分配模型分片,从 GPU 0 开始,直到最后的 GPU(那么最后的 GPU 往往不会被占满,和 “balanced_low_0” 的区别就是第一个还是最后一个,以及非均衡填充),但是我在实际使用当中GPU 0 会直接爆显存了(直接别用了)
示例代码:
model = AutoModel.from_pretrained(path, # 模型本地路径torch_dtype=torch.bfloat16,trust_remote_code=True,device_map=device_map).eval()
device_map可以是字符串 “auto”,”balanced”,”balanced_low_0″,”sequential”
也可以手动配置,指定GPU device
如果是单卡:device = “cuda:2”
model = AutoModel.from_pretrained(model_path, trust_remote_code=True, device_map=device)
如果是多卡:(以internal-vl-40B为例)
def split_model(model_name): #根据卡的数量和模型的层数做均分device_map = {}world_size = torch.cuda.device_count()world_size = 2 #使用两张卡,序号从6开始print(world_size)num_layers = {‘InternVL2-1B’: 24, ‘InternVL2-2B’: 24, ‘InternVL2-4B’: 32, ‘InternVL2-8B’: 32,‘InternVL2-26B’: 48, ‘InternVL2-40B’: 60, ‘InternVL2-Llama3-76B’: 80}[model_name]# Since the first GPU will be used for ViT, treat it as half a GPU.num_layers_per_gpu = math.ceil(num_layers / (world_size – 0.5))num_layers_per_gpu = [num_layers_per_gpu] * world_sizenum_layers_per_gpu[0] = math.ceil(num_layers_per_gpu[0] * 0.5)print(num_layers_per_gpu)layer_cnt = 0for i, num_layer in enumerate(num_layers_per_gpu):i += 6for j in range(num_layer):device_map[f’language_model.model.layers.{layer_cnt}’] = i# print(f’layer_cnt: {layer_cnt}—-{i}’)layer_cnt += 1print(i) # i=6,7first_gpu = i – 1 #把其他配置都使用第一张卡device_map[‘vision_model’] = first_gpudevice_map[‘mlp1’] = first_gpudevice_map[‘language_model.model.tok_embeddings’] = first_gpudevice_map[‘language_model.model.embed_tokens’] = first_gpudevice_map[‘language_model.output’] = first_gpudevice_map[‘language_model.model.norm’] = first_gpudevice_map[‘language_model.lm_head’] = first_gpudevice_map[f’language_model.model.layers.{num_layers – 1}’] = first_gpureturn device_mapdevice = split_model(“InternVL2-40B“)model = AutoModel.from_pretrained(model_path, trust_remote_code=True, device_map=device)
如果是用多卡做推理加载模型,需要考虑模型大小以及每张卡的内存情况
沟通交流合作请加微信!