IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

NVIDIA vient de lâcher une bombe : son nouveau modèle d'IA multimodale NVLM 1.0 72B est ouvert, massif et prêt à rivaliser avec GPT-4
Le modèle est à poids ouvert avec une licence non commerciale cc-by-nc-4.0

Le , par Anthony

49PARTAGES

5  0 
NVIDIA a publié son puissant modèle d'intelligence artificielle (IA) open-source qui pourrait surpasser le GPT-4 d'OpenAI. La nouvelle famille NVLM 1.0 de grands modèles de langage (LLM) multimodaux open-source de la société, dont le modèle phare, NVLM-D-72B, compte environ 72 milliards de paramètres.

Selon l'équipe de recherche de NVIDIA, le nouveau modèle d'IA excelle dans les tâches de vision-langage tout en maintenant et même en améliorant les performances en texte seul par rapport à leurs LLM de base. Dans leur article, les chercheurs déclarent : « Nous présentons le NVLM 1.0, une famille de grands modèles de langage multimodaux d'avant garde qui obtiennent des résultats de pointe dans les tâches de vision-langage, rivalisant avec les principaux modèles propriétaires (par exemple, GPT-4o) et les modèles en libre accès. »


Contrairement à d'autres modèles propriétaires dont les performances textuelles diminuent considérablement avec le temps, le modèle NVLM-D-72B a augmenté sa précision de 4,3 points en moyenne sur les principaux benchmarks textuels.

Le LLM a également été capable d'interpréter des graphiques et des tableaux, d'analyser des images, de comprendre des mèmes, de coder des logiciels et de résoudre des problèmes mathématiques. Les poids du modèle sont accessibles au public sur Hugging Face et NVIDIA indique qu'elle publiera ultérieurement le code d'entraînement.


Détails du modèle

Le 17 septembre 2024, NVIDIA a présenté le NVLM 1.0, une famille de grands modèles de langage (LLM) multimodaux d'avant-garde qui obtiennent des résultats de pointe sur les tâches vision-langage, rivalisant avec les principaux modèles propriétaires (par exemple, GPT-4o) et les modèles en accès libre (par exemple, Llama 3-V 405B et InternVL 2). Fait remarquable, le NVLM 1.0 présente des performances améliorées pour le texte seul par rapport à son homologue LLM après une formation multimodale.

En termes de conception de modèle, NVIDIA a effectué une comparaison complète entre les LLM multimodaux à décodeur uniquement (par exemple, LLaVA) et les modèles basés sur l'attention croisée (par exemple, Flamingo). En se basant sur les forces et les faiblesses des deux approches, NVIDIA a proposé une nouvelle architecture qui améliore à la fois l'efficacité de l'entraînement et les capacités de raisonnement multimodal.


En outre, NVIDIA a introduit une conception 1-D tile-tagging pour les images à haute résolution dynamique à base de tuiles, ce qui améliore considérablement les performances sur le raisonnement multimodal et les tâches liées à la reconnaissance optique des caractères (OCR).

En ce qui concerne les données d'entraînement, NVIDIA a méticuleusement préparé et fourni des informations détaillées sur ses ensembles de données multimodales de pré-entraînement et de mise au point supervisée. Leurs conclusions indiquent que la qualité des ensembles de données et la diversité des tâches sont plus importantes que l'échelle, même pendant la phase de pré-entraînement, sur toutes les architectures. Ils ont notamment développé une multimodalité de niveau production pour les modèles NVLM-1.0, leur permettant d'exceller dans les tâches de vision et de langage tout en maintenant et même en améliorant les performances pour le texte seul par rapport à leurs modèles LLM.


Pour y parvenir, NVIDIA a conçu et intégré un ensemble de données textuelles de haute qualité dans la formation multimodale, ainsi qu'une quantité substantielle de données mathématiques et de raisonnement multimodales, ce qui a permis d'améliorer les capacités mathématiques et de codage dans les différents modes.

Pour faire avancer la recherche dans ce domaine, NVIDIA a publié les poids du modèle et ouvrira le code à la communauté : https://nvlm-project.github.io/. Le modèle NVLM-1.0-D-72B (architecture à décodeur uniquement), les poids du modèle à décodeur uniquement et le code sont également mis à la disposition de la communauté sur Hugging Face.

Résultats des tests de référence

NVIDIA a formé son modèle avec l'ancien Megatron-LM et a adapté la base de code à Huggingface pour l'hébergement du modèle, la reproductibilité et l'inférence. NVIDIA a observé des différences numériques entre les bases de code Megatron et Huggingface, qui se situent dans la fourchette de variation attendue. Les résultats de la base de code Huggingface et de la base de code Megatron sont fournis à des fins de reproductibilité et de comparaison avec d'autres modèles.

Les résultats (au 17 septembre 2024) dans les benchmarks multimodaux sont les suivants :


Comment l'utiliser

Lors de la conversion du point de contrôle Megatron en Huggingface, la base de code InternVL est adaptée pour supporter le chargement du modèle et l'inférence multi-GPU dans HF. Pour la formation, il faut se référer à Megatron-LM (bientôt disponible).

Préparer l'environnement

Un fichier de construction Docker est fourni dans le Dockerfile pour la reproduction.

L'image docker est basée sur nvcr.io/nvidia/pytorch:23.09-py3.

Note : Nous observons que différentes versions de transformateur / versions CUDA / versions de docker peuvent conduire à de légères différences dans les numéros de référence. Il est recommandé d'utiliser le Dockerfile ci-dessus pour une reproduction précise.


Chargement du modèle

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
import torch
from transformers import AutoModel

path = "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()

Plusieurs GPU

Le modèle peut être chargé sur plusieurs GPU comme suit :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import torch
import math
from transformers import AutoModel

def 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_size
    num_layers_per_gpu[0] = math.ceil(num_layers_per_gpu[0] * 0.5)
    layer_cnt = 0
    for i, num_layer in enumerate(num_layers_per_gpu):
        for j in range(num_layer):
            device_map[f'language_model.model.layers.{layer_cnt}'] = i
            layer_cnt += 1
    device_map['vision_model'] = 0
    device_map['mlp1'] = 0
    device_map['language_model.model.tok_embeddings'] = 0
    device_map['language_model.model.embed_tokens'] = 0
    device_map['language_model.output'] = 0
    device_map['language_model.model.norm'] = 0
    device_map['language_model.lm_head'] = 0
    device_map[f'language_model.model.layers.{num_layers - 1}'] = 0

    return device_map

path = "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()

Inférence

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import torch
from transformers import AutoTokenizer, AutoModel
import math
from PIL import Image
import torchvision.transforms as T
from torchvision.transforms.functional import InterpolationMode


def 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_size
    num_layers_per_gpu[0] = math.ceil(num_layers_per_gpu[0] * 0.5)
    layer_cnt = 0
    for i, num_layer in enumerate(num_layers_per_gpu):
        for j in range(num_layer):
            device_map[f'language_model.model.layers.{layer_cnt}'] = i
            layer_cnt += 1
    device_map['vision_model'] = 0
    device_map['mlp1'] = 0
    device_map['language_model.model.tok_embeddings'] = 0
    device_map['language_model.model.embed_tokens'] = 0
    device_map['language_model.output'] = 0
    device_map['language_model.model.norm'] = 0
    device_map['language_model.lm_head'] = 0
    device_map[f'language_model.model.layers.{num_layers - 1}'] = 0

    return device_map


IMAGENET_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_STD
    transform = 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 transform


def find_closest_aspect_ratio(aspect_ratio, target_ratios, width, height, image_size):
    best_ratio_diff = float('inf')
    best_ratio = (1, 1)
    area = width * height
    for 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_diff
            best_ratio = ratio
        elif ratio_diff == best_ratio_diff:
            if area > 0.5 * image_size * image_size * ratio[0] * ratio[1]:
                best_ratio = ratio
    return best_ratio


def dynamic_preprocess(image, min_num=1, max_num=12, image_size=448, use_thumbnail=False):
    orig_width, orig_height = image.size
    aspect_ratio = orig_width / orig_height

    # calculate the existing image aspect ratio
    target_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) if
        i * 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 target
    target_aspect_ratio = find_closest_aspect_ratio(
        aspect_ratio, target_ratios, orig_width, orig_height, image_size)

    # calculate the target width and height
    target_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 image
    resized_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 image
        split_img = resized_img.crop(box)
        processed_images.append(split_img)
    assert len(processed_images) == blocks
    if use_thumbnail and len(processed_images) != 1:
        thumbnail_img = image.resize((image_size, image_size))
        processed_images.append(thumbnail_img)
    return processed_images


def 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_values

path = "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}')

Licence

L'utilisation de ce modèle est régie par la licence cc-by-nc-4.0

Source : "NVLM: Open Frontier-Class Multimodal LLMs" (NVIDIA)

Et vous ?

Quel est votre avis sur le sujet ?
Que pensez-vous des performances de cette famille de modèles d'IA de NVIDIA ?
Trouvez-vous les résultats de cette étude crédibles ou pertinents ?
Avez-vous utilisé cet outil ou un outil similaire pour votre usage ou le développement d'applications, et si oui, qu'en pensez-vous ?

Voir aussi :

Mistral AI et NVIDIA dévoilent Mistral NeMo 12B, un modèle d'IA d'entreprise que les développeurs peuvent personnaliser et déployer pour des applications prenant en charge les chatbots et autres tâches

ChatRTX, le chatbot IA expérimental de Nvidia, prend en charge davantage de modèles d'IA comme Gemma de Google, les requêtes vocales, et fonctionne localement sur un PC Windows équipé d'un GPU RTX

NVIDIA introduit l'IA dans le monde physique à la CVPR, avec NVIDIA Omniverse Cloud Sensor RTX, un nouvel ensemble de microservices, et JeDi qui simplifie la génération d'images personnalisées

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de Fluxgraveon
Membre habitué https://www.developpez.com
Le 07/10/2024 à 16:09
Châteaux de sable
0  0 
Avatar de onilink_
Membre émérite https://www.developpez.com
Le 07/10/2024 à 17:31
En quoi permettre l'accès aux poids d'une boite noire plus incompréhensible qu'un binaire exécutable est qualifiable d'open source ?

Ne faudrait-il pas donner accès au dataset utilisé lors de l'entrainement pour être qualifié de cette façon?
0  0 
Avatar de Fluxgraveon
Membre habitué https://www.developpez.com
Le 08/10/2024 à 10:33
En quoi permettre l'accès aux poids d'une boite noire plus incompréhensible qu'un binaire exécutable est qualifiable d'open source ?
Peut-être pour se réserver un accès "propriétaire" tout en faisant accroire que ce n'est pas le cas ?
Cela dit, ça reste un château de données sur les plages du Big Data.
0  0