多模态数据处理¶
为了在vLLM中启用各种优化功能,例如chunked prefill和prefix caching,我们使用BaseMultiModalProcessor来根据HF处理器的输出,提供占位符特征标记(例如)与多模态输入(例如原始输入图像)之间的对应关系。
以下是BaseMultiModalProcessor的主要功能:
提示更新检测¶
HF处理器的主要职责之一是用占位符令牌更新提示词。例如:
- 在字符串开头插入特征占位符(例如
,其数量等于特征尺寸)。... - 将现有的输入占位符标记(例如单张图片的
)替换为特征占位符标记(例如,其数量等于特征尺寸)。...
关于哪些令牌已被更新的信息,对于找到占位符特征令牌与多模态输入之间的对应关系至关重要。
在vLLM中,这些信息是通过_get_prompt_updates中的PromptUpdate来指定的。我们可以通过检查更新后的token是否存在,自动检测HF是否已更新提示词。
标记化提示输入¶
为了在独立进程中启用分词功能,我们支持将输入token ID与多模态数据一起传递。
问题¶
考虑到HF处理器遵循以下主要步骤:
- 对文本进行分词
- 处理多模态输入
- 执行提示更新
我们要求:
- 对于文本+多模态输入,应用所有步骤1-3。
- 对于已分词+多模态输入,仅应用步骤2-3。
如果不重写HF处理器,我们如何实现这一点?可以尝试在不同输入上多次调用HF处理器:
- 对于文本+多模态输入,直接调用HF处理器即可。
- 对于已分词+多模态输入,仅对多模态输入调用处理器。
虽然HF处理器原生支持文本+多模态输入,但对于已分词+多模态输入则不然:如果输入占位符令牌的数量与多模态输入的数量不匹配,则会抛出错误。
此外,由于经过分词处理的文本并未通过HF处理器,我们必须自行执行步骤3,以确保输出token与多模态数据保持一致。
虚拟文本¶
我们通过要求每个模型定义如何基于多模态输入的数量生成虚拟文本来解决第一个问题,具体通过get_dummy_text实现。这使我们能够生成与多模态输入相对应的虚拟文本,并将它们一起输入以获取处理后的多模态数据。
自动提示更新¶
我们通过在_apply_prompt_updates中实现与模型无关的代码来解决第二个问题,该代码会根据_get_prompt_updates输出的规范,自动使用特征占位符令牌更新提示。
概述¶
借助虚拟文本和自动提示更新功能,我们的多模态处理器最终可以同时接受文本和令牌提示以及多模态数据。详细逻辑请参见_apply_hf_processor_main。
处理器输出缓存¶
某些HF处理器(例如Qwen2-VL使用的处理器)速度非常缓慢。为缓解此问题,我们缓存了HF处理器的多模态输出,以避免重复处理相同的多模态输入(如图像)。
当有新数据传入时,我们首先检查哪些条目已在缓存中,哪些缺失。缺失的条目会以单批次形式传入HF处理器进行处理并缓存,最后与缓存中的现有条目合并。
由于我们仅处理缺失的多模态数据项,输入占位符的数量不再与多模态输入的数量对应,因此它们无法与文本提示一起传递给HF处理器。为此,我们分别处理文本和多模态输入,使用虚拟文本来避免HF错误。由于这跳过了HF的提示更新代码,我们在后续应用自动提示更新以保持输出标记与多模态数据相互一致。