背景
为了高效满足公众号头图的需求,我近期使用了Playground-v2.5模型批量生成了大量1280x512分辨率的优质头图。但考虑到这些图片仅为自己所用,未免有些资源浪费。因此,我计划将它们分享至网络,供其他公众号作者使用,以充分发挥这些图片的价值。然而,随着图片数量的增加,搜索功能的实现变得必要,这就需要对图片进行标签化处理。于是,我打算利用目前的多模态大模型来完成这一任务。之前,我曾尝试使用通义千问的Qwen-VL-Plus和Qwen-VL-Max的API为图片生成提示语,效果非常出色。但鉴于这次处理的图片数量较多,且可能需要长期使用,我决定尝试开源版的模型,并借此机会体验其当前的性能水平。
展示几张头图效果
考虑到显卡资源有限,这里选择了 Qwen-VL-Chat-Int4 模型,这是一个量化模型,在显卡资源有限的情况更高效的运行。按照官方的数据,显存使用情况如下:
Quantization | Peak Usage for Encoding 2048 Tokens | Peak Usage for Generating 8192 Tokens |
---|---|---|
BF16 | 22.60GB | 28.01GB |
Int4 | 11.82GB | 17.23GB |
实现方法
前置条件
在使用通义千问 Qwen-VL-Chat-Int4 模型之前,我们需要进行一些基本的环境配置。首先,确保已经安装了 Nvidia 显卡驱动和 cuda 库。其次,安装 Python 环境,推荐使用 Miniconda 进行安装。本人使用的是 Python3.11 版本。
安装依赖库
1
2
3
4
5
6
7
8
9
10
# 安装 pytorch
pip install torch==2.2.0 torchvision==0.17.0 torchaudio==2.2.0 xformers==0.0.24 --index-url https://download.pytorch.org/whl/cu121
# 可选安装 flash-attention 库,可提升性能
pip install flash-attn --no-build-isolation
# 根据 https://www.modelscope.cn/models/qwen/Qwen-VL-Chat-Int4/summary 说明,安装部署量化模型有关的库
pip install optimum
pip install auto-gptq
pip install transformers_stream_generator
模型加载和准备
通义千问 Qwen-VL-Chat-Int4 模型的加载和准备非常简单,只需要通过 Python 代码自动从 Modelscope 下载模型即可。具体的加载代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from modelscope import snapshot_download, AutoModelForCausalLM, AutoTokenizer, GenerationConfig
from auto_gptq import AutoGPTQForCausalLM
import matplotlib.pyplot as plt
from PIL import Image
import time
model_dir = snapshot_download("qwen/Qwen-VL-Chat-Int4", revision='v1.0.0')
import torch
torch.manual_seed(1234)
# Note: The default behavior now has injection attack prevention off.
tokenizer = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True)
# use cuda device
model = AutoModelForCausalLM.from_pretrained(model_dir, device_map="cuda", trust_remote_code=True,use_safetensors=True).eval()
破解滑块验证码
通义千问 Qwen-VL-Chat-Int4 模型可以轻松破解滑块验证码。本人是在 jupyter 上运行模型,并将图片展示在了 jupyter 上。如果是在命令行运行,可以把图片保存到本地,然后用图片查看器打开。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 显示图片
image_path = 'input_images/20200508214523118.jpg'
img = Image.open(image_path)
plt.imshow(img)
plt.show()
query = tokenizer.from_list_format([
{'image': image_path},
{'text': '图片中有两个拼图块形状的图形,请给我分别标注出两个滑块的检测框的坐标,拼图块有两个,left,right'}
])
start_time = time.time()
response, history = model.chat(tokenizer, query=query, history=None)
image = tokenizer.draw_bbox_on_latest_picture(response, history)
img = image.get_image()
# 显示图片
plt.imshow(img)
plt.show()
print(f'输出: {response}')
print(f"耗时: {time.time()-start_time} 秒")
输出结果,模型会给出滑块的坐标。为了方便展示,我们也可以将坐标标注到图片上。
使用通义千问 Qwen-VL-Chat 来破解验证码确实显得有些过于强大,且成本相对较高。相比之下,这种方法更适合于数据标注,尤其是结合 Yolo 系列模型进行训练,以构建识别模型。这种组合不仅能够提供优越的性能,还能有效控制成本。过去,我使用传统的视觉类模型成功破解过多种市面上的验证码,并且成功率极高。这一过程的关键在于预先准确标注数据,而通义千问 Qwen-VL-Chat 在这方面提供了极大的便利,使其成为标注数据的一个理想选择。
根据图片内容提取关键词
通义千问 Qwen-VL-Chat-Int4 模型根据图片内容提取关键词
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 显示图片
image_path = 'input_images/20240314-114544-1024x1024.png'
img = Image.open(image_path)
plt.imshow(img)
plt.show()
query = tokenizer.from_list_format([
{'image': image_path},
{'text': '根据画面内容及表现出的情绪, 总结最能代表这幅画面的 5 到 10 个关键词,不需要给我坐标等无关信息,只需要给我关键词并以逗号分割'},
])
start_time = time.time()
response, history = model.chat(tokenizer, query=query, history=None)
print(f'关键词: {response}')
print(f"耗时: {time.time()-start_time} 秒")
模型输出结果很好地总结了图片的内容。此时,我们可以将关键词保存到数据库,方便图片的搜索。当然,也可以调整提示词,让大模型描述画面内容,或者按照要求写一篇文案,甚至编一个小故事,都是可以尝试的,需要做的只是尝试用不同的提示词即可。