vLLM-Omni 在线服务 Lance:基于 OpenAI 兼容 Chat Completions API 的图文生成实战指南
2026/9/17 18:28:46 网站建设 项目流程

vLLM-Omni 在线服务 Lance:基于 OpenAI 兼容 Chat Completions API 的图文生成实战指南

【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni

Lance(ByteDance 开源的 3B 统一自回归 + 扩散多模态模型)在 vLLM-Omni 中可以通过 OpenAI 兼容的/v1/chat/completions接口直接对外服务,支持文生图(text2img)、图像编辑(img2img)以及视频类负载。本文以仓库中的 在线服务示例 为主线,讲解如何一键拉起 Lance 服务端、如何配置单阶段部署参数、如何使用共享客户端发送多模态请求,并深入源码揭示请求在 OpenAI 接口层与 Lance 扩散管线中的完整流转,帮助你快速搭建可复用、可验证的 Lance 在线推理服务。

Lance 与 vLLM-Omni 的集成背景

Lance 属于 BAGEL 技术谱系(Qwen2-MoT 统一 AR + 扩散架构)。从源码注释看(pipeline_lance.py),vLLM-Omni 复用了 BAGEL 的 transformer 核心与整套生成/前向机制,仅在三个局部做了 Lance 特化:

  1. Checkpoint 布局:HF 仓库bytedance-research/Lance在同一仓库内打包了Lance_3B/(图像)与Lance_3B_Video/(视频)LLM 权重、Qwen2.5-VL-ViT/(理解用 ViT)以及Wan2.2_VAE.pth(VAE);由于没有 BAGEL 风格的一级config.json,这些几何/采样常量由LANCE_DEFAULTS硬编码(如latent_patch_size_spatial=1max_latent_size=64timestep_shift=3.5num_timesteps=30cfg_text_scale=4.0)。
  2. 理解 ViT:使用随仓库捆绑的 Qwen2.5-VL 视觉塔(Qwen2.5-VL-ViT/vit.safetensors)替代 BAGEL 的 SigLIP,并以 NaViT 风格包装(见 lance_transformer.py)。
  3. VAE:使用 Wan2.2(Wan2.2_VAE.pth)替代 BAGEL 的自编码器。

在在线服务场景下,Lance 以单阶段扩散管线(无多阶段编排)暴露给 OpenAI 兼容接口,这就是 deploy 配置 存在的原因——Lance 的 HFconfig.json只是描述性元数据(没有model_type),加载器无法仅凭模型目录自动探测管线类型,需要 YAML 显式告知"使用 Lance 管线"。

启动 Lance 服务端

仓库在 examples/online_serving/lance 目录下提供了现成的启动脚本 run_server.sh 与 OpenAI 兼容客户端 openai_chat_client.py。

默认方式启动

bash examples/online_serving/lance/run_server.sh

脚本内部等价于执行(run_server.sh):

vllm serve "bytedance-research/Lance" --omni \ --deploy-config "vllm_omni/deploy/lance.yaml" \ --port "8091"

其中--omni开启 omni 多模态服务模式,--deploy-config指定部署配置,--port指定监听端口(默认 8091)。

通过环境变量覆盖启动

脚本支持三个环境变量覆盖默认值(run_server.sh):

MODEL=bytedance-research/Lance \ DEPLOY_CONFIG=vllm_omni/deploy/lance.yaml \ PORT=8091 \ bash examples/online_serving/lance/run_server.sh
环境变量默认值说明
MODELbytedance-research/Lance模型名或本地 checkpoint 路径
DEPLOY_CONFIGvllm_omni/deploy/lance.yaml部署配置文件路径
PORT8091HTTP 服务监听端口

视频负载的部署配置选择

README 明确指出:默认 deploy 配置是单阶段的lance.yaml;对于video_edittext2video负载,应把DEPLOY_CONFIG指向视频 checkpoint 配置(或直接给run_server.sh--model bytedance-research/Lance/Lance_3B_Video)。这是因为视频路径需要加载 3-D 潜变量位置编码表(LancePositionEmbedding3Dlatent_pos_embed.pos_embed形状为(31*64*64, 2048))以及 Wan2.2 的多帧 VAE 解码路径(pipeline_lance.py)。

单阶段部署配置详解

vllm_omni/deploy/lance.yaml 是 Lance 在线服务的关键配置。其核心作用是充当"管线选择器"——仅告知加载器使用 Lance 管线,单阶段、无多阶段编排:

# Lance (ByteDance) — single-stage diffusion pipeline selector. # # Lance's HF config.json is descriptive metadata (no ``model_type``), # so the loader can't auto-detect from the model dir alone. This YAML # only tells the loader "use the Lance pipeline" — one stage, no multi- # stage orchestration. pipeline: lance async_chunk: false stages: - stage_id: 0 max_num_batched_tokens: 32768 max_num_seqs: 1 enforce_eager: true trust_remote_code: true enable_prefix_caching: false devices: "0" default_sampling_params: seed: 42

各字段含义与源码依据如下:

  • pipeline: lance:顶层管线选择器。vLLM-Omni 通过pipeline_registry等机制根据该字段解析并实例化LancePipeline(在 diffusion/registry.py 中注册)。Lance 的 HFconfig.json没有model_type,无法自动探测,必须显式指定。
  • async_chunk: false:关闭异步分块。端到端测试 test_lance.py 中对应的 CLI 旗标是--no-async-chunk
  • stages[0].stage_id: 0:单阶段编排,仅一个 stage。
  • max_num_batched_tokens: 32768:单个 batch 的最大 token 数上限(CLI 对应--max-num-batched-tokens 32768)。由于扩散去噪阶段通常同时只处理一个请求的 token 序列,该值给得比较宽裕。
  • max_num_seqs: 1:最大并发序列数为 1——Lance 单阶段扩散管线一次只服务一个生成请求,这与客户端requests.post(...)同步等待返回的使用方式是匹配的。
  • enforce_eager: true:强制 eager 模式执行,关闭 CUDA graph 捕获,规避扩散管线中动态形状带来的编译开销与兼容问题(CLI 对应--enforce-eager)。
  • trust_remote_code: true:允许加载远程自定义代码(CLI 对应--trust-remote-code),这是加载 Lance 这类携带自定义建模代码的 checkpoint 所必需的。
  • enable_prefix_caching: false:关闭前缀缓存(CLI 对应--no-enable-prefix-caching)。Lance 是单阶段扩散负载,请求间共享前缀收益有限。
  • devices: "0":指定使用 GPU 0。
  • default_sampling_params.seed: 42:默认采样种子 42,保证可复现。

如果不想使用 YAML 文件,端到端测试展示了完全等价的 CLI 写法(test_lance.py):

vllm-omni serve "bytedance-research/Lance" --omni \ --pipeline lance --enforce-eager --trust-remote-code --port 8091

发送多模态请求

服务启动后,即可使用仓库提供的 openai_chat_client.py 发送请求。该客户端与 BAGEL 共享同一套实现——相同的 OpenAI 消息格式、相同的modalitiesnum_inference_steps/seed/height/width旋钮。

文生图(text2img)

python examples/online_serving/lance/openai_chat_client.py \ --prompt "A cute corgi astronaut on the moon, cinematic" \ --modality text2img \ --output corgi.png

图像编辑(img2img)

python examples/online_serving/lance/openai_chat_client.py \ --prompt "Convert this into a vibrant cartoon-style illustration" \ --modality img2img \ --image-url path/to/photo.png \ --output edited.png

完整命令行参数

客户端通过argparse暴露以下参数(openai_chat_client.py):

参数短选项默认值说明
--prompt-pA cute cat文本提示词
--output-obagel_output.png图像输出文件路径
--server-shttp://localhost:8091服务端地址
--image-url-i输入图片 URL 或本地路径(img2img / img2text 用)
--modality-mtext2img任务模态:text2img/img2img/img2text/text2text
--height512图像高度(像素)
--width512图像宽度(像素)
--steps25去噪推理步数
--seed42随机种子
--negative负向提示词

客户端请求构造原理

理解客户端的请求构造,可以让你不依赖该脚本、直接用curl或任意 HTTP 工具复现同样的请求:

  1. 消息内容:将提示词包装为{"type": "text", "text": f"<|im_start|>{prompt}<|im_end|>"}结构;若指定了--image-url,则追加一个image_url内容块。本地图片路径会被读取并 base64 编码为data:image/jpeg;base64,...格式(openai_chat_client.py)。
  2. 顶层参数而非 extra_body:代码注释明确指出 "vLLM ignores extra_body, so we put parameters directly in the payload"(openai_chat_client.py)。modalitiesheightwidthnum_inference_stepsseednegative_prompt全部直接放在 payload 顶层。
  3. 模态映射text2img/img2imgpayload["modalities"] = ["image"]img2text/text2textpayload["modalities"] = ["text"](openai_chat_client.py)。
  4. 请求发送:POST 到{server_url}/v1/chat/completionsContent-Type: application/json,超时 300 秒(openai_chat_client.py)。
  5. 响应解析:先遍历所有choices寻找message.content列表中带image_url且以data:image开头的图像输出并解码为字节;若无图像,再回退提取字符串文本输出(openai_chat_client.py)。这意味着服务端可能返回多个 choice(例如 text 在choices[0]、image 在choices[1]),客户端对两者都做了兼容。

服务端处理链:从 OpenAI 请求到 Lance 管线

当请求到达/v1/chat/completions后,vLLM-Omni 将请求解析为带modalitiesmulti_modal_data的扩散请求,最终进入 LancePipeline.forward 进行模态分发:

  • modalities == ["video"]且带first_frame→ 图像转视频(i2v);
  • modalities == ["video"]且带video→ 视频编辑(video_edit);
  • modalities == ["video"]→ 文生视频(t2v),走_forward_t2v(3-D 潜变量 +LanceWanVAE.decode_video);
  • modalities == ["text"]且带video→ 视频理解(x2t_video);
  • modalities == ["text"]且带image→ 图像理解(x2t_image);
  • modalities == ["image"]且带img2img/image→ 图像编辑(image_edit);
  • 其余情况(t2i)落到 BAGEL 父类BagelPipeline.forward,并注入 Lance 默认值cfg_img_scale=1.0(对应上游cfg_vit_scale=1.0)。

其中 t2i 分支对应文生图请求:文本提示先经prepare_prompts填充 KV cache,然后generate_image执行带 CFG(cfg_text_scale=4.0)的去噪循环,最后经 Wan2.2 VAE 解码为PIL.Image输出。README 中提到的 t2i 已在 B300 上端到端验证(1024×1024 图像约 6 秒、0 缺失权重,见 pipeline_lance.py)。图像编辑(img2img)则按上游顺序构建 6 段 prefill:系统提示头、ViT(ref)、VAE(ref)、用户指令、分隔符、噪声 QUERY——其中参考图像的 mRoPE 位置与生成噪声块共享同一空间网格,这是模型实现"编辑"语义的关键归纳偏置(pipeline_lance.py)。

验证:端到端在线服务测试

仓库提供了可复现的端到端测试 tests/e2e/online_serving/test_lance.py,它等价于手动执行"启动服务 + 发送请求"两步:

  1. 通过OmniServerParamsbytedance-research/Lance模型和--pipeline lance等 CLI 参数拉起服务(test_lance.py),stage_init_timeout=300
  2. test_lance_text2img_online构造文生图消息(modalities=["image"]num_inference_steps=2seed=42、512×512)并通过 OpenAI 兼容接口发送(test_lance.py);
  3. test_lance_img2img_online将本地 JPEG 图片 base64 编码后随image_url内容块发送图像编辑请求(test_lance.py)。

测试标记了@hardware_test(res={"cuda": "H100"})core_model/advanced_model/diffusion标记,需要 GPU 环境。手动验证命令:

pytest -s -v tests/e2e/online_serving/test_lance.py

实战注意事项

  • 视频负载需切换 checkpoint:任何视频路径(text2video / video2video)都应使用Lance_3B_Video子目录权重(通过MODEL=bytedance-research/Lance/Lance_3B_Video--model指定),以加载 3-Dlatent_pos_embed表;图像与理解路径可指向仓库顶层,由管线自动解析对应子 checkpoint(pipeline_lance.py)。
  • 图像尺寸约束:t2i 的宽高受max_latent_size * latent_downsample限制(64 × 16 = 1024 像素量级),图像编辑的参考图会被自动缩放到 latent_downsample 的整数倍;t2v 的帧数上限由max_num_video_latent_frames=31与 Wan2.2 时间下采样(downsample_temporal=4)共同决定,超限会抛出明确的 ValueError(pipeline_lance.py)。
  • 生成默认值对齐上游:去噪步数默认 30、timestep_shift=3.5、文本 CFG 4.0、种子 42,与上游inference_lance.sh一致(参见 recipes/ByteDance/Lance.md);客户端--steps默认 25,实际服务端会以请求参数为准。
  • 单并发模型max_num_seqs: 1意味着同一时刻仅处理一个生成请求,高并发场景需按需调整部署配置。

延伸阅读

  • Lance 部署配置:单阶段管线选择器 YAML
  • Lance 管线实现:模态分发、t2v / image_edit 前向路径与权重加载
  • Lance transformer 组件:Qwen2.5-VL ViT 包装、3-D 位置编码与 mRoPE 常量
  • Lance 官方配方:硬件支持、离线推理命令与更完整的模态矩阵
  • 端到端测试:OpenAI 兼容接口的文生图 / 图像编辑验证
  • 在线服务启动脚本 与 共享客户端

【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询