Ouzhang's picture
Add files using upload-large-folder tool
3a464db verified
Raw
History Blame Contribute Delete
3.6 kB
"""Fast-dVLM command-line chatbot with speculative block-causal decoding."""
import argparse
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, AutoProcessor
from qwen_vl_utils import process_vision_info
def build_messages(image, prompt):
content = []
if image:
content.append({"type": "image", "image": image})
content.append({"type": "text", "text": prompt})
return [{"role": "user", "content": content}]
def run_inference(model, processor, image, prompt, args):
messages = build_messages(image, prompt)
text = processor.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True,
)
image_inputs, video_inputs = process_vision_info(messages)
inputs = processor(
text=[text],
images=image_inputs,
videos=video_inputs,
padding=True,
return_tensors="pt",
).to(model.device)
mask_id = processor.tokenizer.encode(args.mask_token)[0]
gen_kwargs = {
"input_ids": inputs.input_ids,
"tokenizer": processor.tokenizer,
"block_size": args.block_size,
"max_tokens": args.max_tokens,
"mask_id": mask_id,
}
if hasattr(inputs, "pixel_values"):
gen_kwargs["pixel_values"] = inputs.pixel_values
if hasattr(inputs, "image_grid_thw"):
gen_kwargs["image_grid_thw"] = inputs.image_grid_thw
generated_ids = model.generate(**gen_kwargs)
generated_ids_trimmed = [
out[len(inp):] for inp, out in zip(inputs.input_ids, generated_ids)
]
return processor.batch_decode(
generated_ids_trimmed, skip_special_tokens=True,
)[0]
def main():
parser = argparse.ArgumentParser(description="Fast-dVLM chatbot")
parser.add_argument(
"--model-name", default="Efficient-Large-Model/Fast_dVLM_3B",
help="HuggingFace model id or local path.",
)
parser.add_argument(
"--image", default=None,
help="Image URL or local path. Leave empty for text-only.",
)
parser.add_argument(
"--prompt", default=None,
help="Text prompt. If omitted, enters interactive mode.",
)
parser.add_argument("--block-size", type=int, default=32)
parser.add_argument("--max-tokens", type=int, default=512)
parser.add_argument("--mask-token", default="|<MASK>|")
parser.add_argument("--device", default="cuda")
args = parser.parse_args()
print("Loading model...")
model = AutoModelForCausalLM.from_pretrained(
args.model_name,
torch_dtype=torch.bfloat16,
device_map="auto",
trust_remote_code=True,
)
tokenizer = AutoTokenizer.from_pretrained(args.model_name)
processor = AutoProcessor.from_pretrained(args.model_name, use_fast=False)
processor.tokenizer = tokenizer
if args.prompt:
image = args.image or "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg"
output = run_inference(model, processor, image, args.prompt, args)
print(f"\n{output}")
else:
print("Interactive mode. Type 'exit' to quit, 'clear' to reset.")
while True:
prompt = input("\nYou: ").strip()
if prompt.lower() == "exit":
break
if prompt.lower() == "clear":
print("History cleared.")
continue
if not prompt:
continue
image = args.image
output = run_inference(model, processor, image, prompt, args)
print(f"\nAssistant: {output}")
if __name__ == "__main__":
main()