Ovis简介
Ovis是阿里国际AI团队开源的多模态大模型,看新闻介绍效果不错,在多个场景的测试下都能达到SOTA,其中的Ovis1.6-Gemma2-9B在30B参数以下的模型中取得了综合排名第一,赶超MiniCPM-V-2.6等行业优秀大模型。所以我也部署一个看看效果,是否能够帮我提升工作效率。
Ovis 1.6 Gemma2-9B 适用于多种场景,包括但不限于:
- 数学推理问答: 能够准确回答数学问题。
- 物体识别: 识别花的品种等物体。
- 文本提取: 支持多种语言的文本提取。
- 复杂任务决策: 例如识别手写字体和复杂的数学公式。
- 图像描述生成: 通过对图片的识别处理能够给出菜谱。
- 视觉问答: 在图像理解任务上表现出色。
使用环境
操作系统: Ubuntu22.04
部署步骤
PIP库安装
1.克隆 Ovis
项目。如果 git clone 失败,可以直接下载 .ZIP
压缩包 Ovis项目地址
git clone git@github.com:AIDC-AI/Ovis.git
2.创建环境,安装依赖。
conda create -n ovis python=3.10 -y
conda activate ovis
cd Ovis
pip install -r requirements.txt
pip install -e .
报错批注:
在执行 pip install -r requirements.txt
时我遇到了下面的报错。
解决方法为,先执行下面的代码,再执行 pip install -r requirements.txt
,实践可解决问题。
pip install setuptools_scm
模型下载
项目提供如图所示的三种参数大小的模型。我这里选择使用9B大小的 Ovis1.6-Gemma2-9B
。(9B适合个人本地部署使用,根据自己的情况选择) 更多链接见项目
1.考虑的下载速度和稳定性,我这里使用 HuggingFace-Mirror 进行模型的下载。
git clone https://hf-mirror.com/AIDC-AI/Ovis1.6-Gemma2-9B
模型推理
该项目提供了两种推理方式,对应的程序都位于 /ovis/serve
目录中。
1.使用 runner.py
进行模型推理,需修改 runner.py
代码内容后,运行即可得到推理结果。
# 修改 runner.py 的这部分代码来实现推理
# 修改:
# - <model_path>
# - <image_path>
# - <prompt>if __name__ == '__main__':runner_args = RunnerArguments(model_path='<model_path>')runner = OvisRunner(runner_args)image = Image.open('<image_path>')text = '<prompt>'response = runner.run([image, text])print(response['output'])
修改内容后,执行代码的效果如下。
上传的图片如下:
2.运行 server.py
, 基于 Gradio 界面进行推理。
python ovis/serve/server.py --model_path MODEL_PATH --port PORT
执行命令后会产生下面的界面。
server.py
的完整代码如下(我加上了中文注释)
import argparse
import os.pathimport gradio as gr
from gradio.components import Textbox, Image
from ovis.serve.runner import RunnerArguments, OvisRunnerclass Server:"""Server 类用于封装 OvisRunner 实例,并提供一个可调用接口来处理图像和文本输入。它会接收来自 Gradio 界面的请求,将这些请求传递给 OvisRunner 进行推理,并返回结果。"""def __init__(self, runner: OvisRunner):"""初始化 Server 类实例时,传入一个已经配置好的 OvisRunner 实例。:param runner: 已经初始化并准备就绪的 OvisRunner 实例。"""self.runner = runnerdef __call__(self, image, text):"""当 Server 实例被像函数一样调用时,此方法会被执行。接收图像和文本作为输入参数,调用 runner.run 方法执行模型推理,并返回模型输出的结果。:param image: 用户上传的 PIL 图像对象。:param text: 用户输入的文本字符串。:return: 模型推理得到的结果字符串。"""response = self.runner.run([image, text]) # 执行模型推理output = response["output"] # 获取推理结果中的 "output" 字段return outputif __name__ == '__main__':parser = argparse.ArgumentParser(description='启动 Ovis 模型的服务端')# 添加命令行参数解析器选项parser.add_argument('--model_path', type=str, required=True,help='指定 Ovis 模型文件或目录的路径。')parser.add_argument('--flagging_dir', type=str, default=os.path.expanduser('~/ovis-flagged'),help='设置保存用户提交数据副本(标记)的目录,默认为 ~/ovis-flagged。')parser.add_argument('--max_partition', type=int, default=9,help='设置模型的最大分区数,这可能与模型分片有关,默认为 9。')parser.add_argument('--port', type=int, required=True,help='指定服务监听的端口号。')args = parser.parse_args() # 解析命令行参数# 确保标记目录存在,如果不存在则创建它os.makedirs(args.flagging_dir, exist_ok=True)# 创建 RunnerArguments 对象,用于配置 OvisRunnerrunner_args = RunnerArguments(model_path=args.model_path,max_partition=args.max_partition)# 使用 OvisRunner 和 Server 包装函数来创建 Gradio 应用程序界面demo = gr.Interface(fn=Server(OvisRunner(runner_args)), # 函数:接收图像和文本,返回模型输出inputs=[Image(type='pil', label='图片'), # 输入组件1:用于上传图片Textbox(placeholder='在这里输入文本...', label='提示')], # 输入组件2:用于输入文本outputs=gr.Markdown(), # 输出组件:以 Markdown 格式显示模型输出title=args.model_path.split('/')[-1], # 应用标题:通常是模型路径的最后一部分flagging_dir=args.flagging_dir # 标记目录:保存用户提交的数据副本)# 启动 Gradio 应用程序,监听指定端口demo.launch(server_port=args.port)
推理实测
注: 这里测评的是 Ovis 1.6 Gemma2-9B
,没有大规模的严谨测试,仅从使用角度上纯主观分享感受。
虽然我们可以看到各种说该模型的效果很强的帖子,但是实测下来存在几个问题.
1.显存占用,我使用的设备为24G显存,可以正常执行纯文本任务。在输入图片时,正常大小的图片都会导致炸显存 (只测试到 400*400及以上)。使用时需要考虑设备的显存大小。
2.文本提取,文本提取功能效果一般,效果如下所示。当图中有干扰的图像时不是很准确。