OpenGVLab / InternVL

[CVPR 2024 Oral] InternVL Family: A Pioneering Open-Source Alternative to GPT-4o. 接近GPT-4o表现的开源多模态对话模型
https://internvl.readthedocs.io/en/latest/
MIT License
5.62k stars 438 forks source link

是否支持中文 image caption #88

Closed daicver closed 5 months ago

daicver commented 5 months ago

请问是否支持中文 image caption,如果支持,prompt应该如何写?

czczup commented 5 months ago

您问的是OpenGVLab/InternVL-14B-224px模型是否支持中文的image caption吗?

下面是这个模型的代码示例,如果修改prompt中的 “English caption”为“Chinese caption”,是可以做中文caption的,但效果可能不是很好,因为预训练中使用的wukong数据集的中文质量不是很高。

如果您问的是Chat模型,做好中文caption肯定是没问题的,您可以在我们的在线demo中尝试一下。

import torch
from PIL import Image
from transformers import AutoModel, CLIPImageProcessor
from transformers import AutoTokenizer

model = AutoModel.from_pretrained(
    'OpenGVLab/InternVL-14B-224px',
    torch_dtype=torch.bfloat16,
    low_cpu_mem_usage=True,
    trust_remote_code=True).cuda().eval()

image_processor = CLIPImageProcessor.from_pretrained('OpenGVLab/InternVL-14B-224px')

tokenizer = AutoTokenizer.from_pretrained(
    'OpenGVLab/InternVL-14B-224px', use_fast=False, add_eos_token=True)
tokenizer.pad_token_id = 0  # set pad_token_id to 0

images = [
    Image.open('./examples/image1.jpg').convert('RGB'),
    Image.open('./examples/image2.jpg').convert('RGB'),
    Image.open('./examples/image3.jpg').convert('RGB')
]
prefix = 'summarize:'
texts = [
    prefix + 'a photo of a red panda',  # English
    prefix + '一张熊猫的照片',  # Chinese
    prefix + '二匹の猫の写真'  # Japanese
]

pixel_values = image_processor(images=images, return_tensors='pt').pixel_values
pixel_values = pixel_values.to(torch.bfloat16).cuda()
input_ids = tokenizer(texts, return_tensors='pt', max_length=80,
                      truncation=True, padding='max_length').input_ids.cuda()

# InternVL-C
logits_per_image, logits_per_text = model(
    image=pixel_values, text=input_ids, mode='InternVL-C')
probs = logits_per_image.softmax(dim=-1)
# tensor([[9.9609e-01, 5.2185e-03, 6.0070e-08],
#         [2.2949e-02, 9.7656e-01, 5.9903e-06],
#         [3.2932e-06, 7.4863e-05, 1.0000e+00]], device='cuda:0',
#        dtype=torch.bfloat16, grad_fn=<SoftmaxBackward0>)

# InternVL-G
logits_per_image, logits_per_text = model(
    image=pixel_values, text=input_ids, mode='InternVL-G')
probs = logits_per_image.softmax(dim=-1)
# tensor([[9.9609e-01, 3.1738e-03, 3.6322e-08],
#         [8.6060e-03, 9.9219e-01, 2.8759e-06],
#         [1.7583e-06, 3.1233e-05, 1.0000e+00]], device='cuda:0',
#        dtype=torch.bfloat16, grad_fn=<SoftmaxBackward0>)

# please set add_eos_token to False for generation
tokenizer.add_eos_token = False
image = Image.open('./examples/image1.jpg').convert('RGB')
pixel_values = image_processor(images=image, return_tensors='pt').pixel_values
pixel_values = pixel_values.to(torch.bfloat16).cuda()

tokenized = tokenizer("Chinese caption:", return_tensors='pt')  # change to Chinese caption
pred = model.generate(
    pixel_values=pixel_values,
    input_ids=tokenized.input_ids.cuda(),
    attention_mask=tokenized.attention_mask.cuda(),
    num_beams=5,
    min_new_tokens=8,
)
caption = tokenizer.decode(pred[0].cpu(), skip_special_tokens=True).strip()
print(caption)
daicver commented 5 months ago

您问的是OpenGVLab/InternVL-14B-224px模型是否支持中文的image caption吗?

下面是这个模型的代码示例,如果修改prompt中的 “English caption”为“Chinese caption”,是可以做中文caption的,但效果可能不是很好,因为预训练中使用的wukong数据集的中文质量不是很高。

如果您问的是Chat模型,做好中文caption肯定是没问题的,您可以在我们的在线demo中尝试一下。

import torch
from PIL import Image
from transformers import AutoModel, CLIPImageProcessor
from transformers import AutoTokenizer

model = AutoModel.from_pretrained(
    'OpenGVLab/InternVL-14B-224px',
    torch_dtype=torch.bfloat16,
    low_cpu_mem_usage=True,
    trust_remote_code=True).cuda().eval()

image_processor = CLIPImageProcessor.from_pretrained('OpenGVLab/InternVL-14B-224px')

tokenizer = AutoTokenizer.from_pretrained(
    'OpenGVLab/InternVL-14B-224px', use_fast=False, add_eos_token=True)
tokenizer.pad_token_id = 0  # set pad_token_id to 0

images = [
    Image.open('./examples/image1.jpg').convert('RGB'),
    Image.open('./examples/image2.jpg').convert('RGB'),
    Image.open('./examples/image3.jpg').convert('RGB')
]
prefix = 'summarize:'
texts = [
    prefix + 'a photo of a red panda',  # English
    prefix + '一张熊猫的照片',  # Chinese
    prefix + '二匹の猫の写真'  # Japanese
]

pixel_values = image_processor(images=images, return_tensors='pt').pixel_values
pixel_values = pixel_values.to(torch.bfloat16).cuda()
input_ids = tokenizer(texts, return_tensors='pt', max_length=80,
                      truncation=True, padding='max_length').input_ids.cuda()

# InternVL-C
logits_per_image, logits_per_text = model(
    image=pixel_values, text=input_ids, mode='InternVL-C')
probs = logits_per_image.softmax(dim=-1)
# tensor([[9.9609e-01, 5.2185e-03, 6.0070e-08],
#         [2.2949e-02, 9.7656e-01, 5.9903e-06],
#         [3.2932e-06, 7.4863e-05, 1.0000e+00]], device='cuda:0',
#        dtype=torch.bfloat16, grad_fn=<SoftmaxBackward0>)

# InternVL-G
logits_per_image, logits_per_text = model(
    image=pixel_values, text=input_ids, mode='InternVL-G')
probs = logits_per_image.softmax(dim=-1)
# tensor([[9.9609e-01, 3.1738e-03, 3.6322e-08],
#         [8.6060e-03, 9.9219e-01, 2.8759e-06],
#         [1.7583e-06, 3.1233e-05, 1.0000e+00]], device='cuda:0',
#        dtype=torch.bfloat16, grad_fn=<SoftmaxBackward0>)

# please set add_eos_token to False for generation
tokenizer.add_eos_token = False
image = Image.open('./examples/image1.jpg').convert('RGB')
pixel_values = image_processor(images=image, return_tensors='pt').pixel_values
pixel_values = pixel_values.to(torch.bfloat16).cuda()

tokenized = tokenizer("Chinese caption:", return_tensors='pt')  # change to Chinese caption
pred = model.generate(
    pixel_values=pixel_values,
    input_ids=tokenized.input_ids.cuda(),
    attention_mask=tokenized.attention_mask.cuda(),
    num_beams=5,
    min_new_tokens=8,
)
caption = tokenizer.decode(pred[0].cpu(), skip_special_tokens=True).strip()
print(caption)

感谢您的回复,确实是这样的。我使用OpenGVLab/InternVL-14B-224px模型,提示词设置为“Chinese caption”,但是效果比较差。其次,我还有一个疑问,请问你们有没有对Chat模型做中文caption时的泛化性能做测试呀。因为,Chat模型在最终SFT阶段所见到的数据应该比InternVL-14B-224px模型见到的数据少,泛化性能会不会降低呀?

czczup commented 5 months ago

您说的泛化性能测试是怎么测试呢,因为Chat阶段用的数据质量更好,所以Chat模型的中文Caption性能会更好。

daicver commented 5 months ago

您说的泛化性能测试是怎么测试呢,因为Chat阶段用的数据质量更好,所以Chat模型的中文Caption性能会更好。

比如说,我想生成一个几百Million的中文图文对数据集。InternVL-14B-224px的训练数据是1.03B(论文中的stage2),Chat-v1.2-plus(stage3)只有12M。我担心由于Chat模型在微调阶段(stage3)会发生遗忘。当遇到了新的图片(在stage1,stage2,stage3均未出现),会出现胡言乱语,理论上性能不如InternVL-14B-224px(stage2),因为stage2见过更多的图片。假设有一个比较好的InternVL-14B-224px(stage2)模型。

czczup commented 5 months ago

噢噢,理解您的意思了。虽然我们stage2的模型InternVL-14B-224px使用了1B的caption数据进行训练,但这批数据的质量远没有stage3的12M好。

stage2的1B的主要来源还是Laion, COYO, Wukong, CC12M这些数据集,大头的caption都是互联网爬取的句子,可读性和连贯性都不是很好;而stage3的12M是上百个VQA/Caption小数据集的组合,domain比Stage2的数据更加丰富。我个人建议还是直接使用Stage3的模型。

感觉直接生成几百M需要的算力挺夸张的,您要生成这么大批量吗😂 我们现在开源的Stage3模型有InternVL-Chat-V1.1 (19B),InternVL-Chat-V1.2-Plus (40B),还要最新开源的InternVL-Chat-V1.5 (25.5B),您可以根据算力做选择。这些模型都支持中文的长caption和短caption。

daicver commented 5 months ago

感谢您的回复,几百M是一个假设,方便您能理解我的问题,感谢您的回复。我们是希望能获得一些高质量的,规模比较大的中文图文对数据。