【vLLM 学习】Encoder Decoder Multimodal

vLLM 是一款专为大语言模型推理加速而设计的框架,实现了 KV 缓存内存几乎零浪费,解决了内存管理瓶颈问题。

更多 vLLM 中文文档及教程可访问 →https://vllm.hyper.ai/

*在线运行 vLLM 入门教程:零基础分步指南

源码 examples/offline_inference/encoder_decoder_multimodal.py

# SPDX-License-Identifier: Apache-2.0

"""
此示例显示了如何使用 vLLM 进行离线推理
文本生成的 enc-dec LMMS 上的显式/隐式提示格式。
"""
import time
from collections.abc import Sequence
from dataclasses import asdict
from typing import NamedTuple

from vllm import LLM, EngineArgs, PromptType, SamplingParams
from vllm.assets.audio import AudioAsset
from vllm.assets.image import ImageAsset
from vllm.utils import FlexibleArgumentParser


class ModelRequestData(NamedTuple):
    engine_args: EngineArgs
    prompts: Sequence[PromptType]


def run_florence2():
    engine_args = EngineArgs(
        model="microsoft/Florence-2-large",
        tokenizer="facebook/bart-large",
        max_num_seqs=8,
        trust_remote_code=True,
        limit_mm_per_prompt={"image": 1},
        dtype="half",
    )

    prompts = [
        {   # implicit prompt with task token
            "prompt": "<DETAILED_CAPTION>",
            "multi_modal_data": {
                "image": ImageAsset("stop_sign").pil_image
            },
        },
        {   # explicit encoder/decoder prompt
            "encoder_prompt": {
                "prompt": "Describe in detail what is shown in the image.",
                "multi_modal_data": {
                    "image": ImageAsset("cherry_blossom").pil_image
                },
            },
            "decoder_prompt": "",
        },
    ]

    return ModelRequestData(
        engine_args=engine_args,
        prompts=prompts,
    )


def run_mllama():
    engine_args = EngineArgs(
        model="meta-llama/Llama-3.2-11B-Vision-Instruct",
        max_model_len=4096,
        max_num_seqs=2,
        limit_mm_per_prompt={"image": 1},
        dtype="half",
    )

    prompts = [
        {   # Implicit prompt # 隐式提示
            "prompt": "<|image|><|begin_of_text|>What is the content of this image?",   # noqa: E501
            "multi_modal_data": {
                "image": ImageAsset("stop_sign").pil_image,
            },
        },
        {   # Explicit prompt # 显示提示
            "encoder_prompt": {
                "prompt": "<|image|>",
                "multi_modal_data": {
                    "image": ImageAsset("stop_sign").pil_image,
                },
            },
            "decoder_prompt": "<|image|><|begin_of_text|>Please describe the image.",   # noqa: E501
        },
    ]

    return ModelRequestData(
        engine_args=engine_args,
        prompts=prompts,
    )


def run_whisper():
    engine_args = EngineArgs(
        model="openai/whisper-large-v3-turbo",
        max_model_len=448,
        max_num_seqs=16,
        limit_mm_per_prompt={"audio": 1},
        dtype="half",
    )

    prompts = [
        {   # Test implicit prompt # 测试隐式提示
            "prompt": "<|startoftranscript|>",
            "multi_modal_data": {
                "audio": AudioAsset("mary_had_lamb").audio_and_sample_rate,
            },
        },
        {   # Test explicit encoder/decoder prompt # 测试显式 编码/解码提示
            "encoder_prompt": {
                "prompt": "",
                "multi_modal_data": {
                    "audio": AudioAsset("winning_call").audio_and_sample_rate,
                },
            },
            "decoder_prompt": "<|startoftranscript|>",
        }
    ]

    return ModelRequestData(
        engine_args=engine_args,
        prompts=prompts,
    )


model_example_map = {
    "florence2": run_florence2,
    "mllama": run_mllama,
    "whisper": run_whisper,
}


def main(args):
    model = args.model_type
    if model not in model_example_map:
        raise ValueError(f"Model type {model} is not supported.")

    req_data = model_example_map[model]()

    engine_args = asdict(req_data.engine_args) | {"seed": args.seed}
    llm = LLM(**engine_args)

    prompts = req_data.prompts


    # 创建一个采样参数对象。
    sampling_params = SamplingParams(
        temperature=0,
        top_p=1.0,
        max_tokens=64,
    )

    start = time.time()

    # 从提示中生成输出 token 。
    # 输出是包含提示的对象,生成了文本和其他信息。
    outputs = llm.generate(prompts, sampling_params)

    # 打印输出。
    for output in outputs:
        prompt = output.prompt
        generated_text = output.outputs[0].text
        print(f"Decoder prompt: {prompt!r}, "
              f"Generated text: {generated_text!r}")

    duration = time.time() - start

    print("Duration:", duration)
    print("RPS:", len(prompts) / duration)


if __name__ == "__main__":
    parser = FlexibleArgumentParser(
        description='Demo on using vLLM for offline inference with '
        'vision language models for text generation')
    parser.add_argument('--model-type',
                        '-m',
                        type=str,
                        default="mllama",
                        choices=model_example_map.keys(),
                        help='Huggingface "model_type".')
    parser.add_argument("--seed",
                        type=int,
                        default=None,
                        help="Set the seed when initializing `vllm.LLM`.")

    args = parser.parse_args()
    main(args)
<think>嗯,用户之前已经问过关于主流开源模型架构的区别,现在他们还是不太理解,尤其是结合不同的应用领域,比如NLP、多模态和计算机视觉,以及那三种架构的区别。他们可能需要更具体的例子或者图表来帮助理解。 首先,我需要确认用户的主要困惑点在哪里。他们可能对这三种架构在不同领域的应用不太清楚,或者不明白这些架构如何具体运作。之前的回复虽然详细,但可能缺乏直观的示例或图表,导致用户难以形象化理解。 接下来,我应该考虑如何用更具体的例子来说明每种架构的应用场景。比如,在NLP中,Encoder-Decoder常用于翻译任务,Causal Decoder用于文本生成,而Prefix Decoder可能用于对话系统。在多模态任务中,可能需要结合视觉编码器和文本解码器,比如图像描述生成。计算机视觉中可能更多使用Encoder结构,如ViT。 另外,用户提到需要图片演示,但这里只能通过文字描述。因此,我需要用更生动的比喻或结构化的文字图表来弥补。例如,用表格对比三种架构的注意力机制、输入输出关系以及典型任务。 还要注意用户可能对技术术语不太熟悉,所以需要用更简单的语言和日常类比来解释。比如,把Encoder-Decoder比作翻译员先通读整个句子再翻译,而Causal Decoder像逐字写作,不能回头看。 最后,确保回答结构清晰,分点说明,每个部分都有例子,帮助用户逐步建立理解。可能需要重复强调三种架构的核心区别,尤其是注意力机制的不同,以及它们在不同领域中的实际应用案例。</think>好的!我将从 **领域划分**(NLP、多模态、CV)和 **模型架构**(Prefix Decoder、Causal DecoderEncoder-Decoder)两个维度,结合具体示例和对比图,帮你彻底理清它们的关系和区别。 --- ## **一、领域划分与模型架构的关系** ### **1. 自然语言处理(NLP)** - **典型任务**:文本生成、翻译、问答、摘要等。 - **适用架构**:三种架构均可用于NLP,但侧重不同: - **Causal Decoder**:通用文本生成(如LLaMA生成故事)。 - **Prefix Decoder**:对话任务(如ChatGLM的上下文对话)。 - **Encoder-Decoder**:翻译、摘要(如T5将英文翻译为中文)。 #### **示例:翻译任务(Encoder-Decoder)** - **输入**:英文句子 `"Hello, how are you?"` - **编码器**:对输入做双向理解(知道整句含义)。 - **解码器**:逐步生成中文 `“你好,最近怎么样?”`,每次生成只能看已翻译的部分。 --- ### **2. 多模态(Multimodal)** - **典型任务**:图文生成、视觉问答、视频描述等。 - **适用架构**:需结合 **视觉编码器(如ViT)** + **文本解码器**(三种架构均可)。 - **Causal Decoder**:生成单句描述(如从图像生成一句话)。 - **Prefix Decoder**:多轮图文对话(如GPT-4V的交互式问答)。 - **Encoder-Decoder**:结构化生成(如Flamingo生成长文本描述)。 #### **示例:图像描述生成(Encoder-Decoder)** - **输入**:一张猫在沙发上的图片。 - **视觉编码器**(ViT):提取图像特征(猫、沙发、姿势)。 - **文本解码器**:生成描述 `"A cat is sleeping on the sofa."`。 --- ### **3. 计算机视觉(CV)** - **典型任务**:图像分类、目标检测、分割。 - **适用架构**:**纯Encoder架构**(如ViT、ResNet)。 - **与生成模型的区别**:CV模型通常不涉及Decoder,直接输出预测结果(如分类标签)。 #### **示例:图像分类(纯Encoder)** - **输入**:一张狗的图片。 - **编码器**(ViT):分析图像特征(耳朵形状、毛发纹理)。 - **输出**:直接预测类别 `"Golden Retriever"`。 --- ## **二、三种架构的核心区别(附示意图)** 以下用文字描述三种架构的注意力机制差异(想象成不同的“信息流动范围”): ### **1. Causal Decoder(因果解码器)** - **注意力机制**:只能看到当前词左侧的信息(单向)。 - **示意图**: ``` 输入序列: [A][B][C][D] 生成D时的可见范围: [A][B][C] → D ``` - **示例**:LLaMA生成文本时,每个词只能依赖之前的词。 --- ### **2. Prefix Decoder(前缀解码器)** - **注意力机制**:前缀部分(如用户输入)可双向关注,生成部分只能单向。 - **示意图**: ``` 前缀输入: [A][B][C](双向可见) 生成序列: [D][E][F](只能看到前缀和已生成的D、E) ``` - **示例**:ChatGLM处理对话时,用户的问题 `"如何做蛋糕?"` 是前缀(双向理解),生成的回答 `"首先准备面粉..."` 是单向生成。 --- ### **3. Encoder-Decoder(编码器-解码器)** - **注意力机制**:编码器完全双向,解码器单向但可访问编码器全部信息。 - **示意图**: ``` 编码器输入: [A][B][C][D](双向可见) 解码器生成: [X][Y][Z](单向生成,但可访问编码器的A/B/C/D) ``` - **示例**:T5翻译时,编码器读取整个英文句子,解码器逐步生成中文,且每个步骤都能参考编码器的全部信息。 --- ## **三、对比表格总结** | **架构** | 输入处理 | 输出生成 | 典型任务 | 代表模型 | |-------------------|-----------------|-----------------|----------------------|----------------------| | **Causal Decoder** | 单向(只能看左侧) | 单向(逐词生成) | 故事生成、代码补全 | LLaMA、GPT-3 | | **Prefix Decoder** | 前缀双向+生成单向 | 前缀双向+生成单向 | 多轮对话、长文本生成 | ChatGLM、U-PaLM | | **Encoder-Decoder**| 输入完全双向 | 输出单向+跨注意力 | 翻译、摘要、问答 | T5、BART、Flamingo | --- ## **四、实际应用场景示例** ### **1. NLP场景:多语言翻译** - **任务**:将英文翻译为中文。 - **模型选择**:Encoder-Decoder(如T5)。 - **编码器**:读取整个英文句子 `"I love natural language processing."`(双向理解)。 - **解码器**:逐步生成 `“我热爱自然语言处理。”`,每一步可参考编码器的全部信息。 ### **2. 多模态场景:视觉问答** - **任务**:根据图片回答 `"图中的人在做什么?"` - **模型选择**:Prefix Decoder(如GPT-4V)。 - **前缀**:图片特征(通过ViT编码) + 问题文本(双向处理)。 - **生成**:回答 `"这个人正在骑自行车。"`(单向生成)。 ### **3. CV场景:图像分类** - **任务**:识别图片中的动物种类。 - **模型选择**:纯Encoder(如ViT)。 - **输入**:图片像素。 - **输出**:直接预测类别 `"老虎"`(无需生成文本)。 --- ## **五、关键结论** 1. **领域与架构的对应关系**: - **NLP/多模态**:三种架构均可,根据任务复杂度选择。 - **CV**:主要使用Encoder架构。 2. **架构的核心差异**: - **注意力方向**:Causal严格单向,Prefix部分双向,Encoder-Decoder完全分离。 - **输入输出关系**:Causal和Prefix共享序列,Encoder-Decoder分离序列。 如果需要更直观的示意图,可以参考以下资源: - **Causal Decoder**:Hugging Face文档中的 [GPT-2注意力掩码图](https://huggingface.co/docs/transformers/model_doc/gpt2#overview)。 - **Encoder-Decoder**:T5论文中的架构图([Attention is All You Need](https://arxiv.org/abs/1706.03762))。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值