个人设计网站论文摘要,全网营销代理加盟,wordpress站安装百度商桥,网站备案资料下载vLLM 多模态输入#xff1a;图像、视频与音频处理全解析
在生成式 AI 快速演进的今天#xff0c;单一文本推理已无法满足复杂应用场景的需求。从智能客服中的图文问答#xff0c;到教育平台上的音视频内容理解#xff0c;再到工业质检中的视觉分析——多模态能力正成为大模…vLLM 多模态输入图像、视频与音频处理全解析在生成式 AI 快速演进的今天单一文本推理已无法满足复杂应用场景的需求。从智能客服中的图文问答到教育平台上的音视频内容理解再到工业质检中的视觉分析——多模态能力正成为大模型落地的关键一环。vLLM 作为高性能推理引擎不仅在纯文本场景下表现出色更通过深度优化支持图像、视频和音频等多种输入形式在保证低延迟的同时实现高吞吐量服务。这一切的核心源于PagedAttention架构对传统注意力机制内存瓶颈的突破。不同于标准 Transformer 将所有 key-value 缓存连续存储的方式vLLM 借鉴操作系统的虚拟内存分页管理思想将 KV Cache 切分为固定大小的“页面”按需分配与交换。这种设计使得显存利用率大幅提升尤其在处理长序列或多模态输入时优势显著。结合连续批处理continuous batching和动态内存调度vLLM 能够轻松应对图文混合、多帧视频甚至跨模态检索等复杂任务。目前主流开源多模态模型如Qwen-VL、LLaVA系列、Phi-3.5-vision以及语音交互模型Ultravox均已在 vLLM 中得到良好支持。更重要的是它内置了 OpenAI 兼容 API 接口这意味着你无需重写现有应用逻辑即可将强大的多模态推理能力无缝集成进生产系统。如何高效传入多模态数据vLLM 的多模态输入遵循统一的数据结构规范核心由两部分组成文本提示prompt和多模态字典multi_modal_data。其中后者是一个类型为MultiModalDataDict的嵌套结构用于传递图像、音频或预计算 embedding 等非文本信息。一个常被忽视但极具实用价值的功能是UUID 缓存机制。当你需要对同一张图片发起多次查询比如不同问题的视觉问答重复传输原始像素数据显然不经济。vLLM 允许你为媒体指定稳定 IDmulti_modal_uuids后续请求中只需提供 UUID 即可复用已缓存的特征表示from vllm import LLM from PIL import Image llm LLM(modelQwen/Qwen2.5-VL-3B-Instruct) img_a Image.open(/path/to/product.jpg) img_b Image.open(/path/to/updated_version.jpg) outputs llm.generate({ prompt: USER: imageimage\n比较这两款产品的外观差异。\nASSISTANT:, multi_modal_data: {image: [img_a, img_b]}, multi_modal_uuids: {image: [sku_1001, None]} # 第一张图使用缓存标识 })下次再问关于sku_1001的问题时即便只传第二张图也能触发缓存命中# 只更新变化的部分节省带宽与编码开销 outputs llm.generate({ prompt: USER: imageimage\n新款有哪些改进\nASSISTANT:, multi_modal_data: {image: [None, Image.open(new_model.jpg)]}, multi_modal_uuids: {image: [sku_1001, sku_1002]} })当然这个机制依赖于前缀缓存prefix caching开启若显式关闭则每次都会重新计算。图像处理从单图到多帧序列最基础的应用莫过于单张图像的理解。使用 PIL 加载后直接注入multi_modal_data[image]字段即可import PIL.Image from vllm import LLM llm LLM(modelllava-hf/llava-1.5-7b-hf) image PIL.Image.open(example.jpg) outputs llm.generate({ prompt: USER: image\n这张图里有什么\nASSISTANT:, multi_modal_data: {image: image} }) print(outputs[0].outputs[0].text)对于批量处理多个独立图文对的任务可以一次性提交列表形式的请求vLLM 会自动进行批调度以提升 GPU 利用率requests [ { prompt: USER: image\n这是什么动物\nASSISTANT:, multi_modal_data: {image: PIL.Image.open(tiger.jpg)} }, { prompt: USER: image\n这个建筑风格属于哪个时期\nASSISTANT:, multi_modal_data: {image: PIL.Image.open(cathedral.jpg)} } ] outputs llm.generate(requests)当涉及多图理解——例如对比两张商品图、拼接多个监控画面或模拟视频帧流——则可通过列表传入多张图像。注意某些模型默认限制每轮对话最多处理 4 张图需通过limit_mm_per_prompt参数调整llm LLM( modelmicrosoft/Phi-3.5-vision-instruct, max_model_len4096, limit_mm_per_prompt{image: 4} ) images [PIL.Image.open(fframe_{i}.jpg) for i in range(2)] prompt |user|\n|image_1||image_2|\n请分别描述每张图的内容。|end|\n|assistant| outputs llm.generate({ prompt: prompt, multi_modal_data: {image: images} })值得一提的是vLLM 的chat()接口提供了更贴近真实对话的消息格式允许你在一条消息中混合文本、图像 URL、PIL 对象乃至预计算 embeddingfrom vllm.assets.image import ImageAsset import torch image_url https://picsum.photos/id/32/512/512 image_pil ImageAsset(cherry_blossom).pil_image image_embeds torch.load(precomputed_embeds.pt) conversation [ {role: system, content: 你是一个多模态助手}, {role: user, content: [ {type: image_url, image_url: {url: image_url}}, {type: image_pil, image_pil: image_pil}, {type: image_embeds, image_embeds: image_embeds}, {type: text, text: 这些图像中有哪些共同主题} ]} ] outputs llm.chat(conversation)对于透明 PNG 图像默认情况下 vLLM 使用白色填充 alpha 通道区域。如果你的应用界面偏暗色系可能会导致边缘失真。此时可通过media_io_kwargs自定义背景色llm LLM( modelllava-hf/llava-1.5-7b-hf, media_io_kwargs{image: {rgba_background_color: (0, 0, 0)}} # 黑底 )值接受 RGB 元组或列表范围 0–255未设置时默认(255, 255, 255)。至于视频理解虽然并非所有模型都原生支持.mp4输入但你可以将其视为一组关键帧来处理。例如 Qwen2-VL 支持通过采样若干帧并依次插入image标签实现粗粒度视频分析from vllm.utils import encode_image video_frames load_video_frames(sample.mp4, num_frames6) message {role: user, content: [{type: text, text: 请描述这段视频的情节发展。}]} for frame in video_frames: base64_img encode_image(frame) message[content].append({ type: image_url, image_url: {url: fdata:image/jpeg;base64,{base64_img}} }) outputs llm.chat([message])这种方式虽简单有效但在时间连贯性建模上存在局限。真正的解决方案在于原生视频支持。视频与音频动态内容的端到端接入随着 LLaVA-OneVision、Qwen2.5-VL 等模型的出现vLLM 开始具备真正意义上的视频理解能力。这类模型内部集成了时空注意力模块能够捕捉帧间运动模式。使用方式也极为直观直接传入视频 URL 或本地路径即可。以下是以 Qwen2.5-VL 为例的服务调用流程from transformers import AutoProcessor from vllm import LLM, SamplingParams from qwen_vl_utils import process_vision_info model_path Qwen/Qwen2.5-VL-3B-Instruct video_url https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4 llm LLM( modelmodel_path, gpu_memory_utilization0.8, enforce_eagerTrue, limit_mm_per_prompt{video: 1} ) messages [ {role: user, content: [ {type: text, text: 请描述这个视频的内容}, { type: video, video: video_url, total_pixels: 20480 * 28 * 28, min_pixels: 16 * 28 * 28 } ]} ] processor AutoProcessor.from_pretrained(model_path) prompt processor.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue) _, video_inputs process_vision_info(messages) mm_data {video: video_inputs} if video_inputs else {} outputs llm.generate([{ prompt: prompt, multi_modal_data: mm_data }], sampling_paramsSamplingParams(max_tokens1024)) print(outputs[0].outputs[0].text)这里的关键工具process_vision_info是 Qwen 官方提供的辅助函数负责提取消息中的多媒体字段并转换为模型所需的张量格式。其他架构的模型可能需要自行实现类似逻辑。音频方面vLLM 支持将(numpy_array, sampling_rate)元组作为输入适用于fixie-ai/ultravox-*系列模型import librosa llm LLM(modelfixie-ai/ultravox-v0_5-llama-3_2-1b) audio_array, sr librosa.load(speech.wav, sr16000) outputs llm.generate({ prompt: USER: audio\n请转录并总结这段语音内容。\nASSISTANT:, multi_modal_data: {audio: (audio_array, sr)} })客户端也可通过 base64 编码上传音频片段response client.chat.completions.create( messages[{ role: user, content: [ {type: text, text: 请转录并总结这段音频}, { type: input_audio, input_audio: { data: base64.b64encode(audio_bytes).decode(), format: wav } } ] }], modelfixie-ai/ultravox-v0_5-llama-3_2-1b )或直接引用远程 URL{ type: audio_url, audio_url: {url: https://example.com/audio.wav} }各类媒体下载均有默认超时控制- 图像5 秒可通过VLLM_IMAGE_FETCH_TIMEOUT修改- 视频30 秒VLLM_VIDEO_FETCH_TIMEOUT- 音频10 秒VLLM_AUDIO_FETCH_TIMEOUT建议根据网络环境适当调整。预计算 Embedding跳过编码器的极致优化在某些高并发场景下重复运行视觉编码器如 CLIP ViT会造成不必要的算力浪费。如果前端系统已经完成了特征提取完全可以通过注入 embedding 实现“零成本”图像输入。假设你已有保存好的图像特征张量import torch image_embeds torch.load(image_features.pt) # shape: (1, N, hidden_size) outputs llm.generate({ prompt: USER: image\n基于此图像 embedding 回答问题。\nASSISTANT:, multi_modal_data: {image: image_embeds} })部分模型还需额外元信息。例如 Qwen2-VL 要求提供image_grid_thw描述空间布局mm_data { image: { image_embeds: image_embeds, image_grid_thw: torch.tensor([[1, 6, 6]]) # T x H x W } }MiniCPM-V 则需要原始尺寸列表mm_data { image: { image_embeds: image_embeds, image_sizes: [(512, 512), (256, 256)] } }在线服务中同样支持该模式。只需将 embedding 序列化为 base64 字符串上传import io embed_buf io.BytesIO() torch.save(image_embeds, embed_buf) embed_b64 base64.b64encode(embed_buf.getvalue()).decode() response client.chat.completions.create( messages[{ role: user, content: [ {type: text, text: 基于此图像特征回答问题}, {type: image_embeds, image_embeds: embed_b64, uuid: cached_img_001} ] }], modelllava-hf/llava-1.5-7b-hf )这一机制特别适合构建分级缓存体系冷数据走原始图像解码热数据直接加载 embedding实现性能与灵活性的平衡。在线部署OpenAI 兼容 API 的无缝集成vLLM 内置的 OpenAI 兼容接口极大简化了多模态服务上线流程。只需启动服务并指定模型路径即可获得/v1/chat/completions标准端点vllm serve microsoft/Phi-3.5-vision-instruct \ --trust-remote-code \ --max-model-len 4096 \ --limit-mm-per-prompt {image: 2}客户端使用标准openaiSDK 即可调用from openai import OpenAI client OpenAI(api_keyEMPTY, base_urlhttp://localhost:8000/v1) response client.chat.completions.create( modelmicrosoft/Phi-3.5-vision-instruct, messages[{ role: user, content: [ {type: text, text: 图中有什么}, {type: image_url, image_url: {url: https://example.com/nature.jpg}} ] }] )值得注意的是文本中无需手动添加image占位符系统会自动根据 content 数组顺序拼接上下文。图像还可穿插在文本中间实现细粒度控制content: [ {type: text, text: 左边是}, {type: image_url, image_url: {url: left.jpg}}, {type: text, text: 右边是}, {type: image_url, image_url: {url: right.jpg}} ]安全方面强烈建议启用域名白名单防止 SSRF 攻击--allowed-media-domains upload.wikimedia.org github.com同时可在容器环境中禁用 HTTP 重定向export VLLM_MEDIA_URL_ALLOW_REDIRECTS0对于本地文件访问可通过--allowed-local-media-path限定可读目录并使用file://协议调用vllm serve llava-hf/llava-1.5-7b-hf --allowed-local-media-path /data/images/{type: image_url, image_url: {url: file:///data/images/test.jpg}}整个架构的设计哲学很清晰既保持与生态兼容又不失底层可控性。无论是离线批量处理还是在线高并发服务vLLM 都提供了足够灵活且高效的多模态支持方案。这种高度集成的推理范式正在推动智能应用向更自然、更丰富的交互形态演进。创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考