0. 引言

Sakana AI 提出了一种称为进化模型合并的方法,并使用该方法创建大规模语言模型(LLM )、视觉语言模型(VLM)和图像生成模型,他们创建了具有各种功能的合并模型。这次,他们发布了一个新的日本 VLM,Llama-3-EvoVLM-JP-v2,它利用进化模型合并来实现多个图像的问答。此外,为了评估构建的模型,他们还将发布一个数据集:日语多图像视觉问答(JA-Multi-Image-VQA),以评估用日语回答有关多个图像的问题的能力。

1. 关于 Llama-3-EvoVLM-JP-v2

VLM研究LLM它是发展最快的领域之一。最近,VLM的研究不断取得进展,不仅提高了单图像描绘和问答的性能,而且还具备处理视频和多图像的能力。另一方面,这种新型的VLM主要是在英语国家开发的,在非英语国家仍然基本上不存在。日语也是如此;虽然已经开发了几种日语VLM,但这种类型的尖端VLM仍然不多。因此,Sakana AI 使用进化模型融合来创建这种新型的英语 VLM 和日语 VLM。他们认为通过合并这些LLM,他们可以快速构建一个尖端的日本 VLM。

在构建新的VLM时,底层模型是开源模型。LLM其中,他们选择了Llama-3,它具有高性能,并且各种额外训练的模型都是公开的。有几种使用 Llama-3 创建的高性能 VLM,但Mantis-8B-SigLIP-Llama-3是一种前所未有的 VLM,可以将输入图像放置在我选择的输入文本中的任何位置。高性能日语培训,帮助学生获得日语能力。LLM他们使用Llama-3-ELYZA-JP-8B 。首先,通过合并这两个模型,他们成功构建了“可以处理多个图像的日本 VLM”。此外,他们还添加了一个名为Bunny-v1.1-Llama-3-8B-V的高性能英文VLM来增强图像渲染能力。LLM这些部件也被添加到合并中。

2. 本地部署

2-0. 克隆代码

git clone https://huggingface.co/spaces/SakanaAI/Llama-3-EvoVLM-JP-v2; cd Llama-3-EvoVLM-JP-v2

2-1. 安装依赖模块

pip install git+https://github.com/TIGER-AI-Lab/Mantis.git

2-2. 创建 Web UI

# webui.py
import gradio as gr
import time
import subprocess

import torch

from models.mllava import (
    MLlavaProcessor,
    LlavaForConditionalGeneration,
    prepare_inputs,
)
from models.conversation import Conversation, SeparatorStyle
from transformers import TextIteratorStreamer
from transformers.utils import is_flash_attn_2_available
from threading import Thread

device = "cuda" if torch.cuda.is_available() else "cpu"
IMAGE_TOKEN = "<image>"
generation_kwargs = {
    "max_new_tokens": 1024,
    "num_beams": 1,
    "do_sample": False,
    "no_repeat_ngram_size": 3,
}

if not is_flash_attn_2_available():
    subprocess.run('pip install flash-attn --no-build-isolation', env={'FLASH_ATTENTION_SKIP_CUDA_BUILD': "TRUE"},
                   shell=True)

processor = MLlavaProcessor.from_pretrained("TIGER-Lab/Mantis-8B-siglip-llama3")
processor.tokenizer.pad_token = processor.tokenizer.eos_token

model = LlavaForConditionalGeneration.from_pretrained(
    "SakanaAI/Llama-3-EvoVLM-JP-v2",
    torch_dtype=torch.float16,
    attn_implementation="flash_attention_2",
    device_map=device,
).eval()

# Set the system prompt
conv_template = Conversation(
    system="<|start_header_id|>system<|end_header_id|>\n\nあなたは誠実で優秀な日本人のアシスタントです。特に指示が無い場合は、常に日本語で回答してください。",
    roles=("user", "assistant"),
    messages=(),
    offset=0,
    sep_style=SeparatorStyle.LLAMA_3,
    sep="<|eot_id|>",
)


def get_chat_messages(history):
    chat_history = []
    user_role = conv_template.roles[0]
    assistant_role = conv_template.roles[1]
    for i, message in enumerate(history):
        if isinstance(message[0], str):
            chat_history.append({"role": user_role, "text": message[0]})
            if i != len(history) - 1:
                assert message[1], "The bot message is not provided, internal error"
                chat_history.append({"role": assistant_role, "text": message[1]})
            else:
                assert not message[1], "the bot message internal error, get: {}".format(
                    message[1]
                )
                chat_history.append({"role": assistant_role, "text": ""})
    return chat_history


def get_chat_images(history):
    images = []
    for message in history:
        if isinstance(message[0], tuple):
            images.extend(message[0])
    return images


def add_message(history, message):
    return history, gr.MultimodalTextbox(interactive=False)


def bot(history, message):
    images = message["files"] if message["files"] else None
    text = message["text"].strip()
    if not text:
        raise gr.Error("You must enter a message!")
    num_image_tokens = text.count(IMAGE_TOKEN)
    # modify text
    if images and num_image_tokens < len(images):
        if num_image_tokens != 0:
            gr.Warning(
                "The number of images uploaded is more than the number of <image> placeholders in the text. Will automatically prepend <image> to the text."
            )
        # prefix image tokens
        text = IMAGE_TOKEN * (len(images) - num_image_tokens) + text
    if images and num_image_tokens > len(images):
        raise gr.Error(
            "The number of images uploaded is less than the number of <image> placeholders in the text!"
        )

    current_messages = []
    if images:
        current_messages += [[(image,), None] for image in images]
    if text:
        current_messages += [[text, None]]
    current_history = history + current_messages

    # chat_messages = get_chat_messages(current_history)
    # chat_images = get_chat_images(current_history)
    chat_messages = get_chat_messages(current_messages)
    chat_images = get_chat_images(current_messages)

    # Generate!
    inputs = prepare_inputs(None, chat_images, model, processor, history=chat_messages, **generation_kwargs)
    streamer = TextIteratorStreamer(processor, skip_prompt=True, skip_special_tokens=True)
    inputs["streamer"] = streamer
    thread = Thread(target=model.generate, kwargs=inputs)
    thread.start()
    buffer = ""
    for new_text in streamer:
        buffer += new_text
        time.sleep(0.01)
        # yield buffer
        current_history[-1] = (current_history[-1][0], buffer)
        yield current_history


examples = [
    {
        "text": "1番目と2番目の画像に写っている動物の違いは何ですか?簡潔に説明してください。",
        "files": ["./examples/image_0.jpg", "./examples/image_1.jpg"],
    },
    {
        "text": "2枚の写真について、簡単にそれぞれ説明してください。",
        "files": ["./examples/image_2.jpg", "./examples/image_3.jpg"],
    },
]

with gr.Blocks(fill_height=True) as demo:
    chatbot = gr.Chatbot(
        elem_id="chatbot",
        bubble_full_width=False,
        scale=1,
    )

    chat_input = gr.MultimodalTextbox(
        interactive=True,
        file_types=["image"],
        placeholder="Enter message or upload images. Please use <image> to indicate the position of uploaded images",
        show_label=True,
        render=True,
    )

    examples = gr.Examples(examples, [chat_input], [])

    chat_msg = chat_input.submit(add_message, [chatbot, chat_input], [chatbot, chat_input])
    bot_msg = chat_msg.then(bot, [chatbot, chat_input], chatbot, api_name="bot_response")
    bot_msg.then(lambda: gr.MultimodalTextbox(value=None, interactive=True), None, [chat_input])

demo.queue().launch()

2-3.启动 Web UI

python webui.py

2-4. 访问 Web UI

使用浏览器打开 http://localhost:7860

在这里插入图片描述
完结!

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部