Signed-off-by: lishunyang <lishunyang03@gmail.com> Signed-off-by: lishunyang12 <lishunyang12@163.com> Signed-off-by: WeiQing Chen <david6666666@users.noreply.github.com> Co-authored-by: lishunyang <lishunyang03@gmail.com> Co-authored-by: Haco <923390377@qq.com>
122 lines
5.0 KiB
Python
122 lines
5.0 KiB
Python
# SPDX-License-Identifier: Apache-2.0
|
|
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
|
"""Lance chat / system prompts.
|
|
|
|
Matches the upstream Lance training distribution (see
|
|
``bytedance/Lance/data/system_prompt_render.py`` and
|
|
``data/common.py::generate_system_prompt``):
|
|
|
|
* each task has a specific system prompt describing what to attend to;
|
|
* the prompt is wrapped in the Qwen chat template
|
|
``<|im_start|>system\\n…<|im_end|>\\n<|im_start|>user\\n…<|im_end|>\\n``
|
|
``<|im_start|>assistant\\n``;
|
|
* vision tokens are framed by ``<|vision_start|><|video_pad|><|vision_end|>``
|
|
(upstream uses ``<|video_pad|>`` even for image type by default).
|
|
|
|
These are pure string formatting helpers — the runtime pipeline still does
|
|
the actual VAE / ViT prefill separately.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
# Task-specific system prompts (verbatim from upstream's
|
|
# ``generate_system_prompt`` — first variant of each pool).
|
|
SYSTEM_PROMPTS: dict[tuple[str, str], str] = {
|
|
# (task, vision_type) -> system prompt
|
|
("t2i", "image"): (
|
|
"Describe the image by detailing the color, quantity, text, shape, "
|
|
"size, texture, spatial relationships of the objects and background:"
|
|
),
|
|
("t2v", "video"): (
|
|
"Describe the video by detailing the color, quantity, visible text, "
|
|
"shape, size, texture, spatial relationships and motion/camera "
|
|
"movements of the objects and background:"
|
|
),
|
|
# i2v reuses the t2v system prompt (matches upstream Lance PR #33's
|
|
# ``data/common.py`` where ``system_prompt_type in ("t2v", "i2v")``
|
|
# selects the same prompt pool).
|
|
("i2v", "video"): (
|
|
"Describe the video by detailing the color, quantity, visible text, "
|
|
"shape, size, texture, spatial relationships and motion/camera "
|
|
"movements of the objects and background:"
|
|
),
|
|
("image_edit", "image"): (
|
|
"Describe the key features of the input image (color, shape, size, "
|
|
"texture, objects, background), then explain how the user's text "
|
|
"instruction should alter or modify the image. Generate a new image "
|
|
"that meets the user's requirements while maintaining consistency "
|
|
"with the original input where appropriate."
|
|
),
|
|
("video_edit", "video"): (
|
|
"Describe the key features of the input video (color, shape, size, "
|
|
"texture, objects, background), then explain how the user's text "
|
|
"instruction should alter or modify the video. Generate a new video "
|
|
"that meets the user's requirements while maintaining consistency "
|
|
"with the original input where appropriate."
|
|
),
|
|
("x2t_image", "image"): (
|
|
"Generate a detailed and accurate description of the image, including all the key moments and visual details."
|
|
),
|
|
("x2t_video", "video"): (
|
|
"Generate a detailed and accurate description of the video, including all the key moments and visual details."
|
|
),
|
|
}
|
|
|
|
# Vision-content placeholders (Qwen2.5-VL convention). Upstream uses
|
|
# ``<|video_pad|>`` for image inputs too unless ``force_video_pad=False``
|
|
# (counter-intuitively named; see ``render_qwenvl_prompt`` upstream).
|
|
VISION_START = "<|vision_start|>"
|
|
VISION_END = "<|vision_end|>"
|
|
VIDEO_PAD = "<|video_pad|>"
|
|
IMAGE_PAD = "<|image_pad|>"
|
|
|
|
|
|
def render_lance_prompt(
|
|
task: str,
|
|
user_text: str,
|
|
*,
|
|
vision_token: str | None = None,
|
|
system_prompt: str | None = None,
|
|
) -> str:
|
|
"""Render a Lance-compatible user-side prompt.
|
|
|
|
``task`` is one of ``t2i``, ``t2v``, ``image_edit``, ``video_edit``,
|
|
``x2t_image``, ``x2t_video``. ``vision_token`` should be the visual
|
|
placeholder to embed inside the user message (e.g. ``VIDEO_PAD`` or a
|
|
``VISION_START + VIDEO_PAD + VISION_END`` block); pass ``None`` for
|
|
text-only inputs. ``system_prompt`` overrides the default task system
|
|
prompt — required for x2t QA examples whose upstream JSON carries a
|
|
per-example instruction (e.g. ``"Look at the image carefully and answer
|
|
the question."``); without it x2t falls back to the caption-style
|
|
default and the model describes instead of answering.
|
|
|
|
Returns a single string ready to be tokenized; no further wrapping is
|
|
needed by the caller.
|
|
"""
|
|
# ``t2v`` / ``x2t_video`` / ``video_edit`` use video system prompts;
|
|
# the rest are image.
|
|
vision_type = "video" if task in {"t2v", "i2v", "x2t_video", "video_edit"} else "image"
|
|
sys_prompt = (
|
|
system_prompt if system_prompt else SYSTEM_PROMPTS.get((task, vision_type), "You are a helpful assistant.")
|
|
)
|
|
|
|
if vision_token is None:
|
|
user_msg = user_text
|
|
else:
|
|
# Upstream concatenates the vision block immediately before the text.
|
|
user_msg = f"{vision_token}{user_text}"
|
|
|
|
return (
|
|
f"<|im_start|>system\n{sys_prompt}<|im_end|>\n<|im_start|>user\n{user_msg}<|im_end|>\n<|im_start|>assistant\n"
|
|
)
|
|
|
|
|
|
__all__ = [
|
|
"IMAGE_PAD",
|
|
"SYSTEM_PROMPTS",
|
|
"VIDEO_PAD",
|
|
"VISION_END",
|
|
"VISION_START",
|
|
"render_lance_prompt",
|
|
]
|