Qwen3-VL Vision-Language Model

repository·main·Indexed 12 days ago

https://github.com/qwenlm/qwen3-vl

A high-performance vision-language model series featuring advanced visual reasoning, spatial perception, long-context video understanding, and GUI interaction capabilities. The documentation covers installation and evaluation workflows for Instruct and Thinking models across benchmarks including MathVision, MMMU, and ODinW-13, utilizing vLLM for high-speed inference.

Tokens
29.8K
Snippets
75
Records
94
Agent score
97%

What's inside Qwen3-VL

  1. Overview of Qwen3-VL capabilities

    main

    Qwen3-VL is a vision-language model series designed for advanced multimodal tasks. Key capabilities include:

    • Visual Agent: Ability to operate PC/mobile GUIs by recognizing elements, understanding functions, and invoking tools.
    • Visual Coding: Generation of Draw.io, HTML, CSS, and JS from visual inputs.
    • Spatial Perception: 2D and 3D grounding, judging object positions, viewpoints, and occlusions.
    • Long Context & Video: Native 256K context (expandable to 1M) for processing books and long-duration videos.
    • Multimodal Reasoning: Strong performance in STEM and Math through causal and logical analysis.
    • Advanced OCR: Support for 32 languages with robustness against low light, blur, and tilt.
    • Architectures: Available in Dense and MoE (Mixture-of-Experts) formats, with both Instruct and Thinking (reasoning-enhanced) editions.
  2. Add Vision IDs to Multi-Visual Conversations

    main

    When a conversation contains multiple images or videos, you can use add_vision_id=True in apply_chat_template to automatically insert labels (e.g., "Picture 1:", "Video 1:") before the visual tokens. This helps the model better reference specific visual inputs in its response.

    # add ids to help model reference multiple visual inputs
    prompt_with_id = processor.apply_chat_template(
        conversation,
        add_generation_prompt=True,
        add_vision_id=True
    )
  3. Understand MathVision output formats

    main

    Inference Output (JSONL)

    Each line contains the question metadata, the task, and the model's result:

    • result.gen: The final answer.
    • result.gen_raw: The raw output (includes <think> tags for thinking models).

    Evaluation Output

    The evaluation produces three types of files:

    1. *_eval_results.xlsx: Raw predictions with metadata.
    2. *_eval_results_eval.xlsx: Detailed results including extracted answers (res), logs, and extraction flags.
    3. *_eval_results_eval_score.csv: A summary of accuracy (acc) broken down by category (e.g., Algebra, Geometry).
  4. Control Visual Token Budget via Official Processor

    main

    The AutoProcessor allows you to control the pixel budget for images and videos independently using the size parameter.

    • Image Processor: size['longest_edge'] defines the maximum pixels (H × W) and size['shortest_edge'] defines the minimum pixels.
    • Video Processor: size['longest_edge'] represents the maximum total pixels across all frames (T × H × W), and size['shortest_edge'] sets the minimum total pixel budget.

    You can also control video sampling via fps or num_frames in apply_chat_template.

    processor = AutoProcessor.from_pretrained("Qwen/Qwen3-VL-235B-A22B-Instruct")
    
    # budget for image processor
    processor.image_processor.size = {"longest_edge": 1280*32*32, "shortest_edge": 256*32*32}
    
    # budget for video processor
    processor.video_processor.size = {"longest_edge": 16384*32*32*2, "shortest_edge": 256*32*32*2}
    
    # Example: setting fps in apply_chat_template
    inputs = processor.apply_chat_template(
        messages,
        tokenize=True,
        add_generation_prompt=True,
        return_dict=True,
        return_tensors="pt",
        fps=4
    )
  5. Understand ODinW inference and evaluation output formats

    main

    Inference Output (.jsonl)

    Each line contains:

    • question_id: ID of the question
    • annotation: Ground truth annotations
    • extra_info: Metadata including dataset_name, img_id, img_path, and image dimensions
    • result: Contains gen (JSON string of bounding boxes and labels) and gen_raw (the raw model output)
    • messages: Conversation history

    Evaluation Output (.json)

    A JSON object containing metrics for each dataset and an overall average:

    • mAP: Mean Average Precision at IoU 0.5:0.95
    • mAP_50: mAP at IoU 0.5
    • mAP_75: mAP at IoU 0.75
    • mAP_s: mAP for small objects (area < 32²)
    • mAP_m: mAP for medium objects (32² < area < 96²)
    • mAP_l: mAP for large objects (area > 96²)
  6. Understand MMMU inference and evaluation output formats

    main

    Inference Output (JSONL)

    Each line contains:

    • question_id: ID of the question
    • annotation: Original question data (index, question, options, answer)
    • task: Dataset name
    • result: Contains gen (final answer) and gen_raw (raw output including thinking process)
    • messages: Conversation history

    Evaluation Output

    1. CSV file (*_eval_results.csv): Detailed per-sample results including index, question, prediction, extracted_answer, extraction_method, gt (ground truth), hit, and split.
    2. JSON file (*_eval_results_acc.json): Accuracy summary containing overall_accuracy and accuracy_by_split.
  7. Format custom datasets in JSON

    main

    Datasets must follow a specific JSON structure. Media files are referenced via image or video keys, and conversations are stored in a conversations list. Use special tokens <image> and <video> within the human prompt to indicate where media should be processed.

    Key Rules:

    • One <image> tag must correspond to exactly one image file.
    • <video> tags must correspond to video files.
    • These special tokens should not appear in the answer text.
    • For grounding tasks, the model output should be a JSON string containing bbox_2d coordinates.
    // Single Image Example
    {
        "image": "images/001.jpg",
        "conversations": [
            {
                "from": "human",
                "value": "<image>\nWhat's the main object in this picture?"
            },
            {
                "from": "gpt",
                "value": "A red apple on a wooden table"
            }
        ]
    }
    
    // Video Example
    {
        "video": "videos/005.mp4",
        "conversations": [
            {
                "from": "human",
                "value": "<video>\nWhat caused the blue object to move?"
            },
            {
                "from": "gpt",
                "value": "Answer: (B) Collision"
            }
        ]
    }
    
    // Grounding Example
    {
        "image": "demo/COCO_train2014_000000580957.jpg",
        "conversations": [
            {
                "from": "human",
                "value": "<image>\nLocate house in this image and output the bbox coordinates in JSON format."
            },
            {
                "from": "gpt",
                "value": "{\n\"bbox_2d\": [135, 114, 1016, 672]\n}"
            }
        ]
    }
  8. Format images as Base64 for API or Inference

    main

    When passing images to the model (either via local inference or an OpenAI-compatible API), images must be converted to Base64 strings. The data URI format must include the correct MIME type.

    Supported formats:

    • PNG: f"data:image/png;base64,{base64_image}"
    • JPEG: f"data:image/jpeg;base64,{base64_image}"
    • WEBP: f"data:image/webp;base64,{base64_image}"
    import base64
    from io import BytesIO
    
    def image_to_base64(img, format="PNG"):
        buffered = BytesIO()
        img.save(buffered, format=format)
        img_bytes = buffered.getvalue()
        img_base64 = base64.b64encode(img_bytes).decode('utf-8')
        return img_base64
    
    # Usage in content list:
    # "image_url": {"url": f"data:image/png;base64,{base64_image}"}
  9. Customize VideoMME evaluation logic

    main

    The evaluation process uses a two-stage approach: rule-based extraction followed by LLM-based extraction (using a judge like GPT-4) for ambiguous cases. To customize this logic, modify eval_utils.py:

    • can_infer_option(): Modify rules for extracting options (e.g., A/B/C/D).
    • can_infer_text(): Modify text matching logic.
    • build_prompt(): Customize the prompt used by the LLM judge.
  10. Qwen3-VL Model Architectures and Technical Features

    main

    Qwen3-VL introduces several architectural improvements for enhanced multimodal processing:

    • Interleaved-MRoPE: Uses robust positional embeddings with full-frequency allocation over time, width, and height to improve long-horizon video reasoning.
    • DeepStack: Fuses multi-level ViT (Vision Transformer) features to capture fine-grained details and improve image-text alignment.
    • Text–Timestamp Alignment: Enables precise, timestamp-grounded event localization for improved video temporal modeling (moving beyond T-RoPE).
  11. Run inference on RealWorldQA

    main

    Perform inference using run_realworldqa.py with the infer command. You can use standard instruct models or thinking models (which require different generation parameters).

    Instruct Model Example:

    python run_realworldqa.py infer \
        --model-path /path/to/Qwen3-VL-Instruct \
        --data-dir /path/to/data \
        --dataset RealWorldQA \
        --output-file results/predictions.jsonl \
        --max-new-tokens 32768 \
        --temperature 0.7 \
        --top-p 0.8 \
        --top-k 20 \
        --repetition-penalty 1.0 \
        --presence-penalty 1.5

    Thinking Model Parameters: For models like Qwen3-VL-2B-Thinking, use these adjusted parameters for better reasoning:

    • --max-new-tokens 32768
    • --temperature 0.6
    • --top-p 0.95
    • --top-k 20
    • --repetition-penalty 1.0
    • --presence-penalty 0.0
  12. Run Qwen3-VL using Docker

    main

    Use the official qwenllm/qwenvl Docker image to simplify deployment. You will need to have the NVIDIA driver installed and download the model files to your local environment.

    docker run --gpus all --ipc=host --network=host --rm --name qwen3vl -it qwenllm/qwenvl:qwen3vl-cu128 bash