图文模型LLaVA的部署使用

相关地址

项目简介

Visual and Language Understanding

LLaVA模型类似于ChatGPT Vision版本,支持图文内容的输入,有着更广的使用场景,LLaVA作为开源模型,个人部署后值得一试

部署说明

最简单方式: 使用 Ollama 部署 llava

更新于 2023.12.15

基本跟随 官方的Git 描述就可以,不过涉及到一些网络不通的问题,需要对一些依赖的模型参数做手动下载和存放

项目基础准备

拉取项目

git clone https://github.com/haotian-liu/LLaVA.git
cd LLaVA

安装相关依赖 (我们不做训练,所以训练相关的依赖就不安装了,不在此列出)

conda create -n llava python=3.10 -y
conda activate llava
pip install --upgrade pip  # enable PEP 660 support
pip install -e .

再确认一次是最新代码

git pull
pip install -e .

模型下载

使用以下两个模型

操作

  • Step 1 在 LLaVA 目录下新建 weights 目录然后在里面新建 llava-v1.5-7b 目录 和 lip-vit-large-patch14-336 目录
  • Step 2 打开链接 llava-v1.5-7b 点击 Files and version 然后下载所有文件并放到 llava-v1.5-7b 目录 下
  • Step 3 同理打开 clip-vit-large-patch14-336 下载所有模型文件并放到 lip-vit-large-patch14-336 目录
  • Step 4 打开 llava-v1.5-7b 中的 config.json , 修改 mm_vision_tower 的值为 clip-vit-large-patch14-336 的绝对路径

备注

  • 可以使用的模型基本在 Model Zoo 这个链接中能看到
  • 目前主要使用 LLaVA-v1.5 版本

模型使用

cli 模式使用

在 LLaVA 目录下运行 (图片可以是本地地址,也可以是网络链接 https开头)

目前试下来,7B版本的 load-4bitload-8bit 在最基础的GPU上均能较快运行

python -m llava.serve.cli \
    --model-path weights/llava-v1.5-7b \
    --image-file "Image2.png" \
    --load-4bit

批量调用模式

LLAVA/llava/eval 目录下增加一个脚本 比如取名为 run_llava_reuse.py

基于 run_llava.py 修改代码 (原始代码中每次推断都加载模型,并且默认不加载量化版本)

增加 load_model 函数

def load_model(model_path,load_4bit = True,load_8bit = False):
    disable_torch_init()
    tokenizer, model, image_processor, context_len = load_pretrained_model(
            model_path=model_path,
            model_base=None,
            model_name=get_model_name_from_path(model_path),
            load_4bit = load_4bit,load_8bit = load_8bit
    )
    return tokenizer,model,image_processor,context_len

eval_model 函数从

def eval_model(args):
    # Model
    disable_torch_init()
    model_name = get_model_name_from_path(args.model_path)
    tokenizer, model, image_processor, context_len = load_pretrained_model(
        args.model_path, args.model_base, model_name)
    qs = args.query
    ......

修改为

def eval_model(tokenizer,model,image_processor,context_len,args):
    # Model
    disable_torch_init()
    model_name = get_model_name_from_path(args.model_path)
	qs = args.query
	......

run_llava_reuse.py 文件写好后 运行

pip install -e .

然后就可以使用了,使用方式如下(当前案例是在LLAVA目录下运行)

主要参数

  • prompt 为输入的文本
  • image_file 为输入的图片(支持图片链接)
from llava.model.builder import load_pretrained_model
from llava.mm_utils import get_model_name_from_path
from llava.eval.run_llava_reuse import eval_model,load_model


# ============== load model once ==============

model_path = "weights/llava-v1.5-7b"

tokenizer, model, image_processor, context_len = load_model(model_path,load_4bit = True,load_8bit = False)

# ============== loop here to eval more example ==============

prompt = "What do you see"
image_file = "Image.png"

args = type('Args', (), {
    "model_path": model_path,
    "query": prompt,
    "conv_mode": None,
    "image_file": image_file,
    "sep": ",",
    "temperature":0.2,
    "top_p":None,
    "num_beams":1,
    "max_new_tokens":512
})()

eval_model(tokenizer, model, image_processor, context_len,args)

案例

prompt = "What do you see"
image_file = [The Image Below]

Image

Output

The image depicts a serene scene of a lake surrounded by trees, with a foggy atmosphere. The foggy conditions create a mystical and peaceful ambiance. The lake is located near a village, with several houses and buildings situated around it.

备注

  • llava模型语言推断的效果还是逊色于GPT,追求整体任务的准确度,可以考虑使用llava提取图片信息,然后在下游调用GPT等模型
  • 当然也把llava当作普通语言模型使用,推断时不使用图片信息可以修改代码如下
def eval_model(tokenizer,model,image_processor,context_len,args,use_image = True):
    # Model
    disable_torch_init()
    
    model_name = get_model_name_from_path(args.model_path)
    
    qs = args.query
    image_token_se = DEFAULT_IM_START_TOKEN + DEFAULT_IMAGE_TOKEN + DEFAULT_IM_END_TOKEN
    if use_image:
        if IMAGE_PLACEHOLDER in qs:
            if model.config.mm_use_im_start_end:
                qs = re.sub(IMAGE_PLACEHOLDER, image_token_se, qs)
            else:
                qs = re.sub(IMAGE_PLACEHOLDER, DEFAULT_IMAGE_TOKEN, qs)
        else:
            if model.config.mm_use_im_start_end:
                qs = image_token_se + "\n" + qs
            else:
                qs = DEFAULT_IMAGE_TOKEN + "\n" + qs
	....

这样可以减少模型在内存中的加载(如果所有模型都在本地运行)

扩展阅读

其他相关模型

  • BakLLaVA
  • Qwen-VL
  • CogVLM
  • GPT-4V