Após um ano de esforços incansáveis, hoje estamos entusiasmados em lançar o Qwen2-VL ! Qwen2-VL é a versão mais recente dos modelos de linguagem de visão nas famílias de modelos Qwen.
Compreensão SoTA de imagens de várias resoluções e proporções : Qwen2-VL atinge desempenho de última geração em benchmarks de compreensão visual, incluindo MathVista, DocVQA, RealWorldQA, MTVQA, etc.
Compreensão de vídeos de 20 minutos ou mais : com os recursos de streaming on-line, o Qwen2-VL pode entender vídeos com mais de 20 minutos por meio de respostas a perguntas, diálogos, criação de conteúdo com base em vídeo de alta qualidade, etc.
Agente que pode operar seus celulares, robôs, etc .: com habilidades de raciocínio complexo e tomada de decisão, o Qwen2-VL pode ser integrado a dispositivos como telefones celulares, robôs, etc., para operação automática baseada em ambiente visual e instruções de texto.
Suporte multilíngue : para atender usuários globais, além de inglês e chinês, o Qwen2-VL agora suporta a compreensão de textos em diferentes idiomas dentro de imagens, incluindo a maioria dos idiomas europeus, japonês, coreano, árabe, vietnamita, etc.
Resolução dinâmica ingênua : Ao contrário de antes, Qwen2-VL pode lidar com resoluções de imagem arbitrárias, mapeando-as em um número dinâmico de tokens visuais, oferecendo uma experiência de processamento visual mais humana.
Incorporação de posição rotativa multimodal (M-ROPE) : Decompõe a incorporação posicional em partes para capturar informações posicionais textuais 1D, visuais 2D e de vídeo 3D, aprimorando seus recursos de processamento multimodal.
Temos modelos Qwen2-VL de código aberto, incluindo Qwen2-VL-2B e Qwen2-VL-7B sob a licença Apache 2.0, bem como Qwen2-VL-72B sob a licença Qwen. Esses modelos agora estão integrados com Hugging Face Transformers, vLLM e outras estruturas de terceiros. Esperamos que você goste de usá-los!
2024.09.19: O modelo Qwen2-VL-72B ajustado por instrução e sua versão quantizada [AWQ, GPTQ-Int4, GPTQ-Int8] já estão disponíveis. Também lançamos o artigo Qwen2-VL simultaneamente.
30/08/2024: Lançamos a série Qwen2-VL. Os modelos 2B e 7B já estão disponíveis, e o modelo 72B para código aberto estará disponível em breve. Para mais detalhes, confira nosso blog!
Referência | SoTA anterior (LVLM de código aberto) | Soneto Claude-3.5 | GPT-4o | Qwen2-VL-72B (? ? | Qwen2-VL-7B (? ?) | Qwen2-VL-2B (??) |
---|---|---|---|---|---|---|
Valor MMMU | 58,3 | 68,3 | 69,1 | 64,5 | 54.1 | 41.1 |
MMMU-Pro | 46,9 | 51,5 | 51,9 | 46,2 | 43,5 | 37,6 |
Teste DocVQA | 94,1 | 95,2 | 92,8 | 96,5 | 94,5 | 90,1 |
Teste InfoVQA | 82,0 | - | - | 84,5 | 76,5 | 65,5 |
Teste ChartQA | 88,4 | 90,8 | 85,7 | 88,3 | 83,0 | 73,5 |
TextoVQA val | 84,4 | - | - | 85,5 | 84,3 | 79,7 |
OCRBench | 852 | 788 | 736 | 877 | 845 | 794 |
MTVQA | 17.3 | 25,7 | 27,8 | 30,9 | 25,6 | 18.1 |
Videocassete fácil | 84,67 | 63,85 | 91,55 | 91,93 | 89,70 | 81,45 |
Videocassete zh fácil | 22.09 | 1,0 | 14,87 | 65,37 | 59,94 | 46.16 |
Controle de qualidade do mundo real | 72,2 | 60,1 | 75,4 | 77,8 | 70,1 | 62,9 |
Soma MME | 2414,7 | 1920,0 | 2328,7 | 2482,7 | 2326,8 | 1872,0 |
Teste MMBench-EN | 86,5 | 79,7 | 83,4 | 86,5 | 83,0 | 74,9 |
Teste MMBench-CN | 86,3 | 80,7 | 82,1 | 86,6 | 80,5 | 73,5 |
Teste MMBench-V1.1 | 85,5 | 78,5 | 82,2 | 85,9 | 80,7 | 72,2 |
Teste de bancada MMT | 63,4 | - | 65,5 | 71,7 | 63,7 | 54,5 |
MMStar | 67,1 | 62,2 | 63,9 | 68,3 | 60,7 | 48,0 |
MMVet GPT-4-Turbo | 65,7 | 66,0 | 69,1 | 74,0 | 62,0 | 49,5 |
Média do HallBench | 55,2 | 49,9 | 55,0 | 58,1 | 50,6 | 41,7 |
Teste MathVista mini | 67,5 | 67,7 | 63,8 | 70,5 | 58,2 | 43,0 |
Visão Matemática | 16,97 | - | 30,4 | 25,9 | 16.3 | 12.4 |
Referência | SoTA anterior (LVLM de código aberto) | Gêmeos 1.5-Pro | GPT-4o | Qwen2-VL-72B (? ?) | Qwen2-VL-7B (? ?) | Qwen2-VL-2B (??) |
---|---|---|---|---|---|---|
MVBench | 69,6 | - | - | 73,6 | 67,0 | 63,2 |
Teste de teste de percepção | 66,9 | - | - | 68,0 | 62,3 | 53,9 |
Teste EgoSchema | 62,0 | 63,2 | 72,2 | 77,9 | 66,7 | 54,9 |
Vídeo-MME (seis/com substitutos) | 66,3/69,6 | 75,0 / 81,3 | 71,9/77,2 | 71,2/77,8 | 63,3/69,0 | 55,6/60,4 |
Referência | Métrica | SoTA anterior | GPT-4o | Qwen2-VL-72B | |
---|---|---|---|---|---|
Em geral | FnChamar [1] | MT | - | 90,2 | 93,1 |
EM | - | 50,0 | 53,2 | ||
Jogo | Linha Numérica | RS | 89,4 [2] | 91,5 | 100,0 |
BlackJack | RS | 40.2 [2] | 34,5 | 42,6 | |
Ponto EZ | RS | 50,0 [2] | 85,5 | 100,0 | |
Ponto24 | RS | 2.6 [2] | 3,0 | 4,5 | |
Android | AITZ | MT | 83,0 [3] | 70,0 | 89,6 |
EM | 47,7 [3] | 35,3 | 72,1 | ||
AI2THOR | ALFRED válido-invisível | RS | 67,7 [4] | - | 67,8 |
CG | 75,3 [4] | - | 75,8 | ||
VLN | R2R válido-invisível | RS | 79,0 | 43,7 [5] | 51,7 |
REVERIE válido-invisível | RS | 61,0 | 31,6 [5] | 31,0 |
SR, GC, TM e EM são abreviaturas de taxa de sucesso, sucesso de condição de objetivo, correspondência de tipo e correspondência exata. ALFRED é apoiado pelo SAM [6] .
Benchmark de chamada de função autocurado pela equipe Qwen
Ajustando grandes modelos de linguagem visual como agentes de tomada de decisão por meio de aprendizado por reforço
Android no zoológico: pensamento em cadeia de ação para agentes GUI
ThinkBot: instrução incorporada seguindo com raciocínio em cadeia de pensamento
MapGPT: solicitação guiada por mapa com planejamento de caminho adaptativo para navegação por visão e idioma
Segmente qualquer coisa.
Modelos | RA | DE | França | ISTO | JÁ | Nocaute | Ru | º | VI | Média |
---|---|---|---|---|---|---|---|---|---|---|
Qwen2-VL-72B | 20,7 | 36,5 | 44,1 | 42,8 | 21.6 | 37,4 | 15.6 | 17,7 | 41,6 | 30,9 |
GPT-4o | 20.2 | 34,2 | 41.2 | 32,7 | 20,0 | 33,9 | 11,5 | 22,5 | 34,2 | 27,8 |
Claude3 Opus | 15.1 | 33,4 | 40,6 | 34,4 | 19.4 | 27.2 | 13,0 | 19,5 | 29.1 | 25,7 |
Gêmeos Ultra | 14,7 | 32,3 | 40,0 | 31,8 | 12.3 | 17.2 | 11.8 | 20.3 | 28,6 | 23.2 |
Estes resultados são avaliados no benchmark da MTVQA.
Abaixo, fornecemos exemplos simples para mostrar como usar Qwen2-VL com? ModelScope e ? Transformadores.
O código do Qwen2-VL está nos últimos transformadores Hugging Face e recomendamos que você construa a partir do código-fonte com o comando:
pip install git+https://github.com/huggingface/transformers@21fac7abba2a37fae86106f87fcf9974fd1e3830 accelerate
ou você pode encontrar o seguinte erro:
KeyError: 'qwen2_vl'
NOTA : A versão mais recente dos transformers
tem um bug ao carregar a configuração do Qwen2-VL, então você precisa instalar uma versão específica dos transformadores como acima.
Oferecemos um kit de ferramentas para ajudá-lo a lidar com vários tipos de entrada visual de forma mais conveniente, como se você estivesse usando uma API. Isso inclui base64, URLs e imagens e vídeos intercalados. Você pode instalá-lo usando o seguinte comando:
# É altamente recomendado usar o recurso `[decord]` para carregamento de vídeo mais rápido.pip install qwen-vl-utils[decord]
Se você não estiver usando Linux, talvez não consiga instalar decord
do PyPI. Nesse caso, você pode usar pip install qwen-vl-utils
que voltará a usar o torchvision para processamento de vídeo. No entanto, você ainda pode instalar o registro da fonte para que o registro seja usado ao carregar o vídeo.
Aqui mostramos um trecho de código para mostrar como usar o modelo de chat com transformers
e qwen_vl_utils
:
from transformers import Qwen2VLForConditionalGeneration, AutoTokenizer, AutoProcessorfrom qwen_vl_utils import process_vision_info# default: Carregue o modelo no(s) dispositivo(s) disponível(is) model = Qwen2VLForConditionalGeneration.from_pretrained("Qwen/Qwen2-VL-7B-Instruct", torch_dtype="auto", device_map= "auto")# Recomendamos ativar flash_attention_2 para melhor aceleração e economia de memória, especialmente em cenários de múltiplas imagens e vídeo.# model = Qwen2VLForConditionalGeneration.from_pretrained(# "Qwen/Qwen2-VL-7B-Instruct",# torch_dtype=torch. bfloat16,# attn_implementation="flash_attention_2",# device_map="auto",# )# default processerprocessor = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-7B-Instruct")# O intervalo padrão para o número de tokens visuais por imagem no modelo é 4-16384.# Você pode definir min_pixels e max_pixels de acordo com suas necessidades, como um intervalo de token de 256-1280, para equilibrar desempenho e custo.# min_pixels = 256*28*28# max_pixels = 1280*28 *28# processador = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-7B-Instruct", min_pixels=min_pixels, max_pixels=max_pixels)messages = [ {"role": "usuário","conteúdo": [ {"type": "imagem","imagem": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg", }, {"type": "text", "text": "Descreva esta imagem."}, ], } ]# Preparação para inferênciatexto = processador.apply_chat_template(messages, tokenize=False, add_generação_prompt=True)image_inputs, video_inputs = process_vision_info(messages)inputs = processador(text=[text],images=image_inputs,videos=video_inputs,padding=True, return_tensores="pt", )inputs = inputs.to("cuda")# Inferência: Geração do outputgenerated_ids = model.generate(**inputs, max_new_tokens=128)generated_ids_trimmed = [out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs .input_ids, gerado_ids) ]output_text = processador.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)print(output_text)
# Mensagens contendo múltiplas imagens e um texto querymessages = [ {"role": "usuário","conteúdo": [ {"type": "imagem", "imagem": "arquivo:///caminho/para/image1.jpg"}, {"type": "imagem", "imagem": "arquivo:///caminho/para/image2.jpg"}, {"type": "text", "text": "Identifique as semelhanças entre essas imagens."}, ], } ]# Preparação para inferênciatexto = processador.apply_chat_template(messages, tokenize=False, add_generação_prompt=True)image_inputs, video_inputs = process_vision_info(messages)inputs = processador(text=[text],images=image_inputs,videos=video_inputs,padding=True, return_tensores="pt", )inputs = inputs.to("cuda")# Inferencegenerated_ids = model.generate(**inputs, max_new_tokens=128)generated_ids_trimmed = [out_ids[len(in_ids) :] para in_ids, out_ids em zip(inputs.input_ids, generate_ids) ]output_text = processador.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)print(output_text)
# Mensagens contendo uma lista de imagens como um vídeo e um texto querymessages = [ {"role": "usuário","conteúdo": [ {"type": "vídeo","vídeo": ["arquivo:///caminho/para/frame1.jpg","arquivo:///caminho/para/frame2.jpg","arquivo:/// caminho/para/frame3.jpg","arquivo:///caminho/para/frame4.jpg", ], }, {"type": "text", "text": "Descreva este vídeo."}, ], } ]# Mensagens contendo um caminho de vídeo local e um texto querymessages = [ {"role": "usuário","conteúdo": [ {"type": "video","video": "file:///path/to/video1.mp4","max_pixels": 360 * 420,"fps": 1.0, }, {"type": "text", "text": "Descreva este vídeo."}, ], } ]# Mensagens contendo um URL de vídeo e um texto querymessages = [ {"role": "usuário","conteúdo": [ {"type": "vídeo","vídeo": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-VL/space_woaudio.mp4", }, {"type": "text", "text": "Descreva este vídeo."}, ], } ]# Preparação para inferênciatexto = processador.apply_chat_template(messages, tokenize=False, add_generação_prompt=True)image_inputs, video_inputs = process_vision_info(messages)inputs = processador(text=[text],images=image_inputs,videos=video_inputs,padding=True, return_tensores="pt", )inputs = inputs.to("cuda")# Inferencegenerated_ids = model.generate(**inputs, max_new_tokens=128)generated_ids_trimmed = [out_ids[len(in_ids) :] para in_ids, out_ids em zip(inputs.input_ids, generate_ids) ]output_text = processador.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)print(output_text)
A compatibilidade do URL do vídeo depende muito da versão da biblioteca de terceiros. Os detalhes estão na tabela abaixo. altere o backend por FORCE_QWENVL_VIDEO_READER=torchvision
ou FORCE_QWENVL_VIDEO_READER=decord
se preferir não usar o padrão.
Back-end | HTTP | HTTPS |
---|---|---|
visão da tocha >= 0.19.0 | ✅ | ✅ |
visão da tocha <0.19.0 | ❌ | ❌ |
registro | ✅ | ❌ |
# Mensagens de exemplo para mensagens de inferência em lote1 = [ {"role": "usuário","conteúdo": [ {"type": "imagem", "imagem": "arquivo:///caminho/para/image1.jpg"}, {"type": "imagem", "imagem": "arquivo:///caminho/para/image2.jpg"}, {"type": "text", "text": "Quais são os elementos comuns nessas imagens?"}, ], } ]mensagens2 = [ {"role": "system", "content": "Você é um assistente útil."}, {"role": "usuário", "content": "Quem é você?"}, ]# Combine mensagens para processamento em lotemessages = [messages1, messages2]# Preparação para inferência em lotetexts = [processor.apply_chat_template(msg, tokenize=False, add_generation_prompt=True)para msg em mensagens]image_inputs, video_inputs = process_vision_info(messages)inputs = processador (text=textos,images=image_inputs,videos=video_inputs,padding=True,return_tensors="pt", )inputs = inputs.to("cuda")# Batch Inferencegenerated_ids = model.generate(**inputs, max_new_tokens=128)generated_ids_trimmed = [out_ids[len(in_ids) :] para in_ids, out_ids em zip(inputs.input_ids, generate_ids ) ]output_texts = processador.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)print(output_texts)
Aconselhamos fortemente os usuários, especialmente aqueles na China continental, a usarem o ModelScope. snapshot_download
pode ajudá-lo a resolver problemas relacionados ao download de pontos de verificação.
Para imagens de entrada, oferecemos suporte a arquivos locais, base64 e URLs. Para vídeos, atualmente oferecemos suporte apenas a arquivos locais.
# Você pode inserir diretamente um caminho de arquivo local, um URL ou uma imagem codificada em base64 na posição desejada no texto.## Local file pathmessages = [ {"role": "usuário","conteúdo": [ {"type": "image", "image": "file:///path/to/your/image.jpg"}, {"type": "text", "text": "Descreva esta imagem."}, ], } ]## URL da imagemmensagens = [ {"role": "usuário","conteúdo": [ {"type": "image", "image": "http://path/to/your/image.jpg"}, {"type": "text", "text": "Descreva esta imagem."}, ], } ]## Mensagens de imagem codificadas em Base64 = [ {"role": "usuário","conteúdo": [ {"type": "imagem", "imagem": "data:image;base64,/9j/..."}, {"type": "text", "text": "Descreva esta imagem."}, ], } ]
O modelo suporta uma ampla gama de entradas de resolução. Por padrão, ele usa a resolução nativa para entrada, mas resoluções mais altas podem melhorar o desempenho ao custo de mais computação. Os usuários podem definir o número mínimo e máximo de pixels para obter uma configuração ideal para suas necessidades, como um intervalo de contagem de tokens de 256 a 1280, para equilibrar a velocidade e o uso de memória.
min_pixels = 256 * 28 * 28max_pixels = 1280 * 28 * 28processador = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-7B-Instruct", min_pixels=min_pixels, max_pixels=max_pixels)
Além disso, fornecemos dois métodos para controle refinado sobre a entrada do tamanho da imagem no modelo:
Especifique as dimensões exatas: defina diretamente resized_height
e resized_width
. Esses valores serão arredondados para o múltiplo de 28 mais próximo.
Defina min_pixels e max_pixels: As imagens serão redimensionadas para manter sua proporção dentro do intervalo de min_pixels e max_pixels.
# resized_height e resized_widthmessages = [ {"role": "usuário","conteúdo": [ {"type": "image","image": "file:///path/to/your/image.jpg","resized_height": 280,"resized_width": 420, }, {"type": "text", "text": "Descreva esta imagem."}, ], } ]# min_pixels e max_pixelsmessages = [ {"role": "usuário","conteúdo": [ {"type": "image","image": "file:///path/to/your/image.jpg","min_pixels": 50176,"max_pixels": 50176, }, {"type": "text", "text": "Descreva esta imagem."}, ], } ]
Por padrão, as imagens e o conteúdo de vídeo são incluídos diretamente na conversa. Ao lidar com várias imagens, é útil adicionar rótulos às imagens e vídeos para melhor referência. Os usuários podem controlar esse comportamento com as seguintes configurações:
conversa = [ {"role": "user","content": [{"type": "image"}, {"type": "text", "text": "Olá, como vai você?"}], }, {"role": "assistant","content": "Estou bem, obrigado por perguntar. Como posso ajudá-lo hoje?", }, {"role": "usuário","conteúdo": [ {"type": "text", "text": "Você pode descrever essas imagens e vídeos?"}, {"tipo": "imagem"}, {"tipo": "imagem"}, {"tipo": "vídeo"}, {"type": "text", "text": "Estas são das minhas férias."}, ], }, {"role": "assistant","content": "Terei prazer em descrever as imagens e o vídeo para você. Você poderia fornecer mais contexto sobre suas férias?", }, {"role": "user","content": "Foi uma viagem às montanhas. Você consegue ver os detalhes nas imagens e no vídeo?", }, ]# padrão:prompt_without_id = processador.apply_chat_template(conversation, add_generation_prompt=True)# Saída excluída: '<|im_start|>systemnVocê é um assistente útil.<|im_end|>n<|im_start|>usern<|vision_start|>< |image_pad|><|vision_end|>Olá, como vai você?<|im_end|>n<|im_start|>assistentenEstou bem, obrigado por perguntar. Como posso ajudá-lo hoje?<|im_end|>n<|im_start|>usernVocê pode descrever essas imagens e vídeos?<|vision_start|><|image_pad|><|vision_end|><|vision_start|><|image_pad| ><|vision_end|><|vision_start|><|video_pad|><|vision_end|>Estas são das minhas férias.<|im_end|>n<|im_start|>assistenteFicaria feliz em descrever as imagens e o vídeo para você. Você poderia fornecer mais contexto sobre suas férias?<|im_end|>n<|im_start|>usernFoi uma viagem às montanhas. Você consegue ver os detalhes nas imagens e no vídeo?<|im_end|>n<|im_start|>assistantn'# add idsprompt_with_id = processador.apply_chat_template(conversation, add_generation_prompt=True, add_vision_id=True)# Exceted output: '<|im_start |>systemnVocê é um assistente prestativo.<|im_end|>n<|im_start|>usernImagem 1: <|vision_start|><|image_pad|><|vision_end|>Olá, como vai você?<|im_end|>n< |im_start|>assistentenEstou bem, obrigado por perguntar. Como posso ajudá-lo hoje?<|im_end|>n<|im_start|>usernVocê pode descrever essas imagens e vídeos?Figura 2: <|vision_start|><|image_pad|><|vision_end|>Figura 3: <|vision_start |><|image_pad|><|vision_end|>Vídeo 1: <|vision_start|><|video_pad|><|vision_end|>Estes são das minhas férias.<|im_end|>n<|im_start|>assistenteEu gostaria fique feliz em descrever as imagens e o vídeo para você. Você poderia fornecer mais contexto sobre suas férias?<|im_end|>n<|im_start|>usernFoi uma viagem às montanhas. Você consegue ver os detalhes nas imagens e no vídeo?<|im_end|>n<|im_start|>assistentn'
Primeiro, certifique-se de instalar a versão mais recente do Flash Attention 2:
pip install -U flash-attn --no-build-isolation
Além disso, você deve ter um hardware compatível com Flash-Attention 2. Leia mais sobre isso na documentação oficial do repositório flash Attention. FlashAttention-2 só pode ser usado quando um modelo é carregado em torch.float16
ou torch.bfloat16
.
Para carregar e executar um modelo usando Flash Attention-2, basta adicionar attn_implementation="flash_attention_2"
ao carregar o modelo da seguinte maneira:
de transformadores importar Qwen2VLForConditionalGenerationmodel =