Qwen变体新成员加一,英伟达训练 NVLM-D-72B 视觉大模型

news/2024/12/21 22:11:36/

在这里插入图片描述
今天(2024 年 9 月 17 日),我们推出了前沿级多模态大语言模型(LLM)系列 NVLM 1.0,它在视觉语言任务上取得了最先进的结果,可与领先的专有模型(如 GPT-4o)和开放存取模型(如 Llama 3-V 405B 和 InternVL 2)相媲美。值得注意的是,NVLM 1.0 在多模态训练后的纯文本性能比其 LLM 骨干模型有所提高。

在此版本库中,我们将向社区开源 NVLM-1.0-D-72B(纯解码器架构)、纯解码器模型权重和代码。

我们使用传统的 Megatron-LM 训练我们的模型,并将代码库调整为 Huggingface,以实现模型托管、可重现性和推理。我们观察到 Megatron 代码库和 Huggingface 代码库之间存在数值差异,这些差异在预期的变化范围之内。我们提供 Huggingface 代码库和 Megatron 代码库的结果,以便与其他模型进行重现和比较。

视觉语言基准

BenchmarkMMMU (val / test)MathVistaOCRBenchAI2DChartQADocVQATextVQARealWorldQAVQAv2
NVLM-D 1.0 72B (Huggingface)58.7 / 54.965.285294.286.092.682.669.585.4
NVLM-D 1.0 72B (Megatron)59.7 / 54.665.285394.286.092.682.169.785.4
Llama 3.2 90B60.3 / -57.3-92.385.590.1--78.1
Llama 3-V 70B60.6 / ---93.083.292.283.4-79.1
Llama 3-V 405B64.5 / ---94.185.892.684.8-80.2
InternVL2-Llama3-76B55.2 / -65.583994.888.494.184.472.2-
GPT-4V56.8 / 55.749.964578.278.588.478.061.477.2
GPT-4o69.1 / -63.873694.285.792.8---
Claude 3.5 Sonnet68.3 / -67.778894.790.895.2---
Gemini 1.5 Pro (Aug 2024)62.2 / -63.975494.487.293.178.770.480.2

纯文字基准

TasksBackbone LLMMMLUGSM8KMATHHumanEvalAvg. Accuracy
Proprietary
GPT-4.0N/A88.7-76.690.2-
Gemini Pro 1.5 (Aug 2024)N/A85.990.867.784.182.1
Claude 3.5 SonnetN/A88.796.471.192.087.0
Open LLM
(a) Nous-Hermes-2-Yi-34BN/A75.578.621.843.354.8
(b) Qwen-72B-InstructN/A82.391.159.786.079.8
(c) Llama-3-70B-InstructN/A82.093.051.081.776.6
(d) Llama-3.1-70B-InstructN/A83.695.168.080.581.8
(e) Llama-3.1-405B-InstructN/A87.396.873.889.086.7
Open Multimodal LLM
VILA-1.5 40B(a)73.367.516.834.1🥶 47.9 (-6.9)
LLaVA-OneVision 72B(b)80.689.949.274.4🥶 73.5 (-6.3)
InternVL-2-Llama3-76B(c)78.587.142.571.3🥶 69.9 (-6.7)
*Llama 3-V 70B(d)83.695.168.080.5🙂 81.8 (0)
*Llama 3-V 405B(e)87.396.873.889.0🙂 86.7 (0)
NVLM-D 1.0 72B (Megatron)(b)82.092.973.188.4🥳 84.1 (+4.3)
NVLM-D 1.0 72B (Huggingface)(b)81.793.273.189.0🥳 84.3 (+4.5)

在将 Megatron checkpoint 转换为 Huggingface 时,我们调整了 InternVL 代码库,以支持 HF 中的模型加载和多 GPU 推理。在将 Qwen2.5-72B-Instruct 中的标记符转换为 Huggingface 时,我们还使用了 Qwen2.5-72B-Instruct 中的标记符,因为它包含用于视觉任务的额外特殊标记符,例如 <|vision_pad|>。我们在 Qwen2-72B-Instruct 纯文本模型和 InternViT-6B-448px-V1-5 ViT 模型的基础上,利用大规模高质量多模态数据集训练 NVLM-1.0-D-72B。有关训练代码,请参阅 Megatron-LM(即将发布)。

准备环境

我们在 Dockerfile 中提供了一个用于复制的 docker 生成文件。

该 docker 映像基于 nvcr.io/nvidia/pytorch:23.09-py3。

注:我们注意到,不同的转换器版本/CUDA 版本/docker 版本会导致基准数略有不同。我们建议使用上述 Dockerfile 进行精确还原。

模型加载

import torch
from transformers import AutoModelpath = "nvidia/NVLM-D-72B"
model = AutoModel.from_pretrained(path,torch_dtype=torch.bfloat16,low_cpu_mem_usage=True,use_flash_attn=False,trust_remote_code=True).eval()

多显卡

import torch
import math
from transformers import AutoModeldef split_model():device_map = {}world_size = torch.cuda.device_count()num_layers = 80# 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)layer_cnt = 0for i, num_layer in enumerate(num_layers_per_gpu):for j in range(num_layer):device_map[f'language_model.model.layers.{layer_cnt}'] = ilayer_cnt += 1device_map['vision_model'] = 0device_map['mlp1'] = 0device_map['language_model.model.tok_embeddings'] = 0device_map['language_model.model.embed_tokens'] = 0device_map['language_model.output'] = 0device_map['language_model.model.norm'] = 0device_map['language_model.lm_head'] = 0device_map[f'language_model.model.layers.{num_layers - 1}'] = 0return device_mappath = "nvidia/NVLM-D-72B"
device_map = split_model()
model = AutoModel.from_pretrained(path,torch_dtype=torch.bfloat16,low_cpu_mem_usage=True,use_flash_attn=False,trust_remote_code=True,device_map=device_map).eval()

推理

import torch
from transformers import AutoTokenizer, AutoModel
import math
from PIL import Image
import torchvision.transforms as T
from torchvision.transforms.functional import InterpolationModedef split_model():device_map = {}world_size = torch.cuda.device_count()num_layers = 80# 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)layer_cnt = 0for i, num_layer in enumerate(num_layers_per_gpu):for j in range(num_layer):device_map[f'language_model.model.layers.{layer_cnt}'] = ilayer_cnt += 1device_map['vision_model'] = 0device_map['mlp1'] = 0device_map['language_model.model.tok_embeddings'] = 0device_map['language_model.model.embed_tokens'] = 0device_map['language_model.output'] = 0device_map['language_model.model.norm'] = 0device_map['language_model.lm_head'] = 0device_map[f'language_model.model.layers.{num_layers - 1}'] = 0return device_mapIMAGENET_MEAN = (0.485, 0.456, 0.406)
IMAGENET_STD = (0.229, 0.224, 0.225)def build_transform(input_size):MEAN, STD = IMAGENET_MEAN, IMAGENET_STDtransform = T.Compose([T.Lambda(lambda img: img.convert('RGB') if img.mode != 'RGB' else img),T.Resize((input_size, input_size), interpolation=InterpolationMode.BICUBIC),T.ToTensor(),T.Normalize(mean=MEAN, std=STD)])return transformdef find_closest_aspect_ratio(aspect_ratio, target_ratios, width, height, image_size):best_ratio_diff = float('inf')best_ratio = (1, 1)area = width * heightfor ratio in target_ratios:target_aspect_ratio = ratio[0] / ratio[1]ratio_diff = abs(aspect_ratio - target_aspect_ratio)if ratio_diff < best_ratio_diff:best_ratio_diff = ratio_diffbest_ratio = ratioelif ratio_diff == best_ratio_diff:if area > 0.5 * image_size * image_size * ratio[0] * ratio[1]:best_ratio = ratioreturn best_ratiodef dynamic_preprocess(image, min_num=1, max_num=12, image_size=448, use_thumbnail=False):orig_width, orig_height = image.sizeaspect_ratio = orig_width / orig_height# calculate the existing image aspect ratiotarget_ratios = set((i, j) for n in range(min_num, max_num + 1) for i in range(1, n + 1) for j in range(1, n + 1) ifi * j <= max_num and i * j >= min_num)target_ratios = sorted(target_ratios, key=lambda x: x[0] * x[1])# find the closest aspect ratio to the targettarget_aspect_ratio = find_closest_aspect_ratio(aspect_ratio, target_ratios, orig_width, orig_height, image_size)# calculate the target width and heighttarget_width = image_size * target_aspect_ratio[0]target_height = image_size * target_aspect_ratio[1]blocks = target_aspect_ratio[0] * target_aspect_ratio[1]# resize the imageresized_img = image.resize((target_width, target_height))processed_images = []for i in range(blocks):box = ((i % (target_width // image_size)) * image_size,(i // (target_width // image_size)) * image_size,((i % (target_width // image_size)) + 1) * image_size,((i // (target_width // image_size)) + 1) * image_size)# split the imagesplit_img = resized_img.crop(box)processed_images.append(split_img)assert len(processed_images) == blocksif use_thumbnail and len(processed_images) != 1:thumbnail_img = image.resize((image_size, image_size))processed_images.append(thumbnail_img)return processed_imagesdef load_image(image_file, input_size=448, max_num=12):image = Image.open(image_file).convert('RGB')transform = build_transform(input_size=input_size)images = dynamic_preprocess(image, image_size=input_size, use_thumbnail=True, max_num=max_num)pixel_values = [transform(image) for image in images]pixel_values = torch.stack(pixel_values)return pixel_valuespath = "nvidia/NVLM-D-72B"
device_map = split_model()
model = AutoModel.from_pretrained(path,torch_dtype=torch.bfloat16,low_cpu_mem_usage=True,use_flash_attn=False,trust_remote_code=True,device_map=device_map).eval()print(model)tokenizer = AutoTokenizer.from_pretrained(path, trust_remote_code=True, use_fast=False)
generation_config = dict(max_new_tokens=1024, do_sample=False)# pure-text conversation
question = 'Hello, who are you?'
response, history = model.chat(tokenizer, None, question, generation_config, history=None, return_history=True)
print(f'User: {question}\nAssistant: {response}')# single-image single-round conversation
pixel_values = load_image('path/to/your/example/image.jpg', max_num=6).to(torch.bfloat16)
question = '<image>\nPlease describe the image shortly.'
response = model.chat(tokenizer, pixel_values, question, generation_config)
print(f'User: {question}\nAssistant: {response}')

http://www.ppmy.cn/news/1536840.html

相关文章

42 C 语言 typedef:为基本数据类型、数组、指针、结构体、共用体起别名

目录 1 typedef 介绍 2 为某个基本类型起别名 2.1 为 int 类型起别名 Integer 2.2 为 unsigned char 类型起别名 Byte 2.3 为基本类型一次起多个别名 3 为结构体、共用体起别名 3.1 为结构体起别名 3.1.1 分开定义结构体和别名 3.1.2 与结构体定义一起使用 typedef 3…

认证技术原理与应用

目录 原理 依据 类型 方法 应用 原理 认证技术主要是确认一个实体&#xff08;如人、设备&#xff09;是否为其所声称的身份。这通常通过以下步骤实现&#xff1a; 身份识别&#xff1a;确定被认证对象的身份标识&#xff0c;如用户名、ID号等。 身份验证&#xff1a;验…

算法知识点————【DFS】【BFS】【树】【图】

** 深度优先搜索 ** DFS 用于遍历树和图的算法&#xff0c;过程中深入到不能深入为止&#xff0c;每个结点遍历一次。 ** 广度优先搜索 ** BFS 用于 从根结点开始遍历&#xff0c;遍历根结点下面的所有孩子结点&#xff0c;然后从孩子结点在进行宽度搜索&#xff0c;直到所有的…

Redis: 集群环境搭建,集群状态检查,分析主从日志,查看集群信息

集群环境搭建 在 Redis 5版本以前是用 Ruby 来搭建集群&#xff0c;在后面的版本中仍保留了相关功能可以再源码src目录中&#xff0c;看到 redis-trib.rb 这个东西&#xff0c;只是现在用这种方式搭建的少了我们看新的版本是怎样搭建集群的&#xff0c;新版构建集群的方式简单…

前端面试:项目细节重难点问题分享(17)

更多详情&#xff1a;爱米的前端小笔记&#xff08;csdn~xitujuejin~zhiHu~Baidu~小红shu&#xff09;同步更新&#xff0c;等你来看&#xff01;都是利用下班时间整理的&#xff0c;整理不易&#xff0c;大家多多&#x1f44d;&#x1f49b;➕&#x1f914;哦&#xff01;你们…

zabbix -rockylinux安装

文章目录 一、环境配置1.1、修改主机名1.2、修改静态ip地址1.3、系统更新1.4、安装epel仓库 二、安装zabbix2.1、添加zabbix仓库2.2、配置数据库2.3、配置zabbix服务器2.4、启动zabbix服务 一、环境配置 1.1、修改主机名 [rootecs-204824 /]# vi /etc/hostname [rootecs-2048…

诸葛亮的传奇人生,对后世有哪些深远的影响?

诸葛亮&#xff0c;字孔明&#xff0c;号卧龙&#xff0c;生于东汉光和四年&#xff08;公元181年&#xff09;&#xff0c;卒于蜀汉建兴十二年&#xff08;公元234年&#xff09;&#xff0c;是中国历史上一位卓越的政治家、军事家、战略家、文学家、发明家。他的一生充满了传…

大学生就业市场:Spring Boot招聘系统的设计与实现

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…