模型概述
模型特點
模型能力
使用案例
🚀 ViCA-7B:視覺空間認知助手
ViCA-7B 是一款專門為室內視頻環境中的視覺空間推理而微調的視覺語言模型。它基於 LLaVA-Video-7B-Qwen2 架構構建,使用了新提出的 ViCA-322K 數據集進行訓練,該數據集強調結構化空間註釋和基於複雜指令的推理任務。ViCA-7B 在 VSI-Bench 基準測試中取得了最先進的性能,超越了包括 GPT-4o 和 Gemini-1.5 Pro 在內的專有模型以及更大的開源基線模型。

你可能也對我們的另一個項目 ViCA2 感興趣。請參考以下鏈接:
🚀 快速開始
ViCA-7B 是一個強大的視覺語言模型,可用於室內視頻環境中的視覺空間推理任務。你可以按照下面的推理示例代碼,快速體驗 ViCA-7B 在 VSI-Bench 問題上的應用。
✨ 主要特性
- 先進架構:基於 LLaVA-NeXT 框架,採用 Qwen2-7B 作為語言骨幹,SigLIP 作為視覺編碼器。
- 高效訓練:採用固定長度的視覺標記化、輕量級投影器進行多模態對齊、使用 DeepSpeed 進行高效分佈式訓練以及混合精度計算(fp16)等策略。
- 優質數據集:在 ViCA-322K 和 ViCA-thinking-2.68k 兩個互補數據集上進行微調,提升空間推理和逐步推理能力。
- 卓越性能:在 VSI-Bench 基準測試中取得了最佳的整體性能,超越了多個基線模型。
📦 安裝指南
運行推理代碼前,你需要安裝必要的依賴庫:
pip install git+https://github.com/LLaVA-VL/LLaVA-NeXT.git
💻 使用示例
基礎用法
# This inference script is adapted from:
# https://huggingface.co/lmms-lab/LLaVA-Video-7B-Qwen2
# pip install git+https://github.com/LLaVA-VL/LLaVA-NeXT.git
from llava.model.builder import load_pretrained_model
from llava.mm_utils import get_model_name_from_path, process_images, tokenizer_image_token
from llava.constants import IMAGE_TOKEN_INDEX, DEFAULT_IMAGE_TOKEN, DEFAULT_IM_START_TOKEN, DEFAULT_IM_END_TOKEN, IGNORE_INDEX
from llava.conversation import conv_templates, SeparatorStyle
from PIL import Image
import requests
import copy
import torch
import sys
import warnings
from decord import VideoReader, cpu
import numpy as np
import json
from tqdm import tqdm
import os
warnings.filterwarnings("ignore")
def load_video(video_path, max_frames_num,fps=1,force_sample=False):
if max_frames_num == 0:
return np.zeros((1, 336, 336, 3))
vr = VideoReader(video_path, ctx=cpu(0),num_threads=1)
total_frame_num = len(vr)
video_time = total_frame_num / vr.get_avg_fps()
fps = round(vr.get_avg_fps()/fps)
frame_idx = [i for i in range(0, len(vr), fps)]
frame_time = [i/fps for i in frame_idx]
if len(frame_idx) > max_frames_num or force_sample:
sample_fps = max_frames_num
uniform_sampled_frames = np.linspace(0, total_frame_num - 1, sample_fps, dtype=int)
frame_idx = uniform_sampled_frames.tolist()
frame_time = [i/vr.get_avg_fps() for i in frame_idx]
frame_time = ",".join([f"{i:.2f}s" for i in frame_time])
spare_frames = vr.get_batch(frame_idx).asnumpy()
# import pdb;pdb.set_trace()
return spare_frames,frame_time,video_time
pretrained = 'nkkbr/ViCA'
model_name = "llava_qwen"
device = "cuda"
device_map = "auto"
tokenizer, model, image_processor, max_length = load_pretrained_model(pretrained, None, model_name, torch_dtype="bfloat16", device_map=device_map) # Add any other thing you want to pass in llava_model_args
model.eval()
from datasets import load_dataset
vsi_bench = load_dataset("nyu-visionx/VSI-Bench")
vsi_bench = vsi_bench['test']
data_curr = vsi_bench[1000]
video_path = f"[VIDEO PATH]"
max_frames_num = 64
video,frame_time,video_time = load_video(video_path, max_frames_num, 1, force_sample=True)
video = image_processor.preprocess(video, return_tensors="pt")["pixel_values"].cuda().to(torch.bfloat16)
video = [video]
conv_template = "qwen_1_5"
# time_instruciton = f"The video lasts for {video_time:.2f} seconds, and {len(video[0])} frames are uniformly sampled from it. These frames are located at {frame_time}.Please answer the following questions related to this video."
time_instruciton = ""
question = DEFAULT_IMAGE_TOKEN + f"\n{time_instruciton}\n\n"
question += f"These are frames of a video.\n\n"
question += f"Question: {data_curr['question']}\n"
if data_curr['options'] is not None:
question += '\n'.join(data_curr['options']) + "\n"
question += f"Answer with the option’s letter from the given choices directly.\n"
else:
question += f"Please answer the question using a single word or phrase.\n"
print(f"Prompt:\n{question}")
conv = copy.deepcopy(conv_templates[conv_template])
conv.append_message(conv.roles[0], question)
conv.append_message(conv.roles[1], None)
prompt_question = conv.get_prompt()
input_ids = tokenizer_image_token(prompt_question, tokenizer, IMAGE_TOKEN_INDEX, return_tensors="pt").unsqueeze(0).to(device)
cont = model.generate(
input_ids,
images=video,
modalities= ["video"],
do_sample=False,
temperature=0,
max_new_tokens=1024,
)
text_outputs = tokenizer.batch_decode(cont, skip_special_tokens=True)[0].strip()
print(repr(text_outputs))
📚 詳細文檔
模型架構與訓練策略
ViCA-7B 基於 LLaVA-NeXT 框架構建,使用 Qwen2-7B 作為語言骨幹,SigLIP 作為視覺編碼器。
關鍵訓練特性
- 固定長度的視覺標記化:每個視頻統一採樣為 64 幀,每幀編碼為 210 個視覺標記,每個示例共 13,440 個視覺標記,確保跨批次的一致內存使用和穩定優化。
- 通過輕量級投影器進行多模態對齊:一個簡單的基於 MLP 的投影器將視覺嵌入映射到語言嵌入空間,實現視頻內容和文本提示在訓練和推理過程中的有效融合。
- 使用 DeepSpeed 進行高效分佈式訓練:使用 DeepSpeed ZeRO-3 Offload 在 8× NVIDIA H100 80GB GPU 上進行訓練,對全參數和優化器狀態進行跨設備分區,支持大批次大小並最小化 GPU 內存開銷。
- 混合精度計算(fp16):採用 混合精度訓練(fp16) 加速計算並減少內存使用,同時結合 ZeRO-3 分區進一步提高訓練可擴展性。
訓練持續了 55 小時,涵蓋了基礎和複雜空間推理子集。
訓練動態
圖 2: ViCA-7B 微調期間的訓練損失、學習率調度和梯度範數曲線。這些曲線展示了在 DeepSpeed ZeRO-3 設置下的穩定優化過程和順利收斂。
數據集
ViCA-7B 在兩個互補的數據集上進行微調:
- ViCA-322K:一個大規模數據集,涵蓋了基礎空間推理任務(如對象距離、大小、數量、出現順序)和涉及自然語言問題與場景理解的複雜空間推理任務。該數據集是模型空間推理能力的核心。
- ViCA-thinking-2.68k:一個專注於指令調整的數據集,用於增強模型在輸出最終答案之前生成逐步推理軌跡的能力,支持更具可解釋性和認知一致性的響應生成。
有關詳細信息,請參考上述鏈接的各個數據集頁面。
評估:VSI-BENCH 基準測試
圖 3: ViCA-7B 和基線模型在 VSI-Bench 上的定量比較。ViCA-7B 在數值和多項選擇任務中均取得了最佳的整體性能。
複雜空間推理(CSR)數據的影響
配置 | 平均得分 |
---|---|
僅基礎數據 (281K) | 55.35 |
包含 CSR 的完整數據 (322K) | 60.56 |
CSR(複雜空間推理)增強了模型的泛化能力並 加速了學習,在中間檢查點有顯著的性能提升(例如,在 50 - 55% 時提升 2.02)。
數據規模與性能
在使用 5% → 60% 的數據時,性能顯著提升。在 80% 之後,性能提升趨於平穩,表明數據集與模型容量匹配良好。
圖 4: ViCA-7B 在不同訓練數據規模(從 5% 到 100%)下的性能。完整數據集(包括複雜空間推理,CSR)始終優於僅使用基礎數據的配置。值得注意的是,增強了 CSR 的模型在 50% 到 55% 之間得分提升了 2.02,在全規模下最終性能提升了 4.75。超過 80% 後性能趨於平穩,表明數據集與模型容量相匹配。
中間檢查點和評估輸出
為了支持詳細分析和可重複性,我們提供了兩組中間檢查點,這些檢查點在訓練數據每增加 5% 時保存。這些模型進行了單輪訓練,有助於理解訓練過程中性能的演變。
我們還發布了每個檢查點對應的 原始評估輸出(例如,.json
預測文件)。用於生成這些輸出的評估腳本可在我們的 GitHub 倉庫 中找到。
完整數據集(ViCA-322K:基礎 + CSR)
該系列對應於完整的訓練集,包括基礎空間推理和複雜空間推理(CSR):
數據使用比例 | 檢查點 | 數據使用比例 | 檢查點 |
---|---|---|---|
5% | nkkbr/ViCA-5p |
55% | nkkbr/ViCA-55p |
10% | nkkbr/ViCA-10p |
60% | nkkbr/ViCA-60p |
15% | nkkbr/ViCA-15p |
65% | nkkbr/ViCA-65p |
20% | nkkbr/ViCA-20p |
70% | nkkbr/ViCA-70p |
25% | nkkbr/ViCA-25p |
75% | nkkbr/ViCA-75p |
30% | nkkbr/ViCA-30p |
80% | nkkbr/ViCA-80p |
35% | nkkbr/ViCA-35p |
85% | nkkbr/ViCA-85p |
40% | nkkbr/ViCA-40p |
90% | nkkbr/ViCA-90p |
45% | nkkbr/ViCA-45p |
95% | nkkbr/ViCA-95p |
50% | nkkbr/ViCA-50p |
100% (本倉庫) | nkkbr/ViCA |
原始評估輸出可在 此處 找到。
僅基礎子集(ViCA-322K:基礎)
該系列僅在 ViCA-322K 的基礎空間推理子集上進行訓練,不包含任何 CSR 示例:
數據使用比例 | 檢查點 | 數據使用比例 | 檢查點 |
---|---|---|---|
5% | nkkbr/ViCA-base-5p |
55% | nkkbr/ViCA-base-55p |
10% | nkkbr/ViCA-base-10p |
60% | nkkbr/ViCA-base-60p |
15% | nkkbr/ViCA-base-15p |
65% | nkkbr/ViCA-base-65p |
20% | nkkbr/ViCA-base-20p |
70% | nkkbr/ViCA-base-70p |
25% | nkkbr/ViCA-base-25p |
75% | nkkbr/ViCA-base-75p |
30% | nkkbr/ViCA-base-30p |
80% | nkkbr/ViCA-base-80p |
35% | nkkbr/ViCA-base-35p |
85% | nkkbr/ViCA-base-85p |
40% | nkkbr/ViCA-base-40p |
90% | nkkbr/ViCA-base-90p |
45% | nkkbr/ViCA-base-45p |
95% | nkkbr/ViCA-base-95p |
50% | nkkbr/ViCA-base-50p |
100% | nkkbr/ViCA-base |
原始評估輸出可在 此處 找到。
按數據源的檢查點
雖然完整的 ViCA-322K 數據集由我們整理,但底層視頻和相關元數據來自三個不同的室內視頻數據集:
為了更好地理解每個數據源對模型性能的貢獻,我們在 ViCA-322K 的子集上對 ViCA-7B 進行了微調,這些子集僅使用每個數據源的數據。對於每個子集,我們提供了使用可用數據的 10% 增量 進行訓練的檢查點,從 10% 到 100%。
所有檢查點也提供了相應的 原始評估輸出(例如,.json
預測文件)。
ARKitScenes 僅數據源檢查點
數據使用比例 | 檢查點 | 數據使用比例 | 檢查點 |
---|---|---|---|
10% | nkkbr/ViCA-ARKitScenes-10p |
60% | nkkbr/ViCA-ARKitScenes-60p |
20% | nkkbr/ViCA-ARKitScenes-20p |
70% | nkkbr/ViCA-ARKitScenes-70p |
30% | nkkbr/ViCA-ARKitScenes-30p |
80% | nkkbr/ViCA-ARKitScenes-80p |
40% | nkkbr/ViCA-ARKitScenes-40p |
90% | nkkbr/ViCA-ARKitScenes-90p |
50% | nkkbr/ViCA-ARKitScenes-50p |
100% | nkkbr/ViCA-ARKitScenes |
📄 原始評估輸出:ARKitScenes 結果
ScanNet++ 僅數據源檢查點
數據使用比例 | 檢查點 | 數據使用比例 | 檢查點 |
---|---|---|---|
10% | nkkbr/ViCA-ScanNetPP-10p |
60% | nkkbr/ViCA-ScanNetPP-60p |
20% | nkkbr/ViCA-ScanNetPP-20p |
70% | nkkbr/ViCA-ScanNetPP-70p |
30% | nkkbr/ViCA-ScanNetPP-30p |
80% | nkkbr/ViCA-ScanNetPP-80p |
40% | nkkbr/ViCA-ScanNetPP-40p |
90% | nkkbr/ViCA-ScanNetPP-90p |
50% | nkkbr/ViCA-ScanNetPP-50p |
100% | nkkbr/ViCA-ScanNetPP |
📄 原始評估輸出:ScanNet++ 結果
ScanNet 僅數據源檢查點
數據使用比例 | 檢查點 | 數據使用比例 | 檢查點 |
---|---|---|---|
10% | nkkbr/ViCA-ScanNet-10p |
60% | nkkbr/ViCA-ScanNet-60p |
20% | nkkbr/ViCA-ScanNet-20p |
70% | nkkbr/ViCA-ScanNet-70p |
30% | nkkbr/ViCA-ScanNet-30p |
80% | nkkbr/ViCA-ScanNet-80p |
40% | nkkbr/ViCA-ScanNet-40p |
90% | nkkbr/ViCA-ScanNet-90p |
50% | nkkbr/ViCA-ScanNet-50p |
100% | nkkbr/ViCA-ScanNet |
📄 原始評估輸出:ScanNet 結果
額外探索
時間指令
在提示中包含 64 幀的時間戳會略微 降低 性能,這表明模型未能有效利用時間對齊,並且受到指令冗長的負面影響。
圖 5: 在 VSI-Bench 上,添加明確的幀時間戳(64 個值)會降低模型性能,表明模型無法利用時間對齊,並且對提示長度敏感。
更多幀
將輸入從 64 幀增加到 128 幀,視覺標記數量翻倍(從 13,440 到 26,880),但 性能沒有提升,這凸顯了模型對固定標記長度的過擬合和架構的靈活性不足。
圖 6: 64 幀和 128 幀輸入的比較。儘管視覺標記數量翻倍,但性能保持不變,表明模型對固定長度輸入過擬合,並且對可變長度序列的適應性有限。
🔧 技術細節
模型指標
屬性 | 詳情 |
---|---|
模型類型 | 視覺語言模型 |
訓練數據 | ViCA-322K、ViCA-thinking-2.68k |
基礎模型 | lmms-lab/LLaVA-Video-7B-Qwen2 |
評估基準 | VSI-Bench |
評估結果
ViCA-7B 在 VSI-Bench 基準測試中的評估結果如下:
任務類型 | 數據集 | 指標 | 值 | 名稱 | 驗證狀態 |
---|---|---|---|---|---|
視覺問答 | VSI-Bench | 得分 | 60.56 | 平均 | 未驗證 |
視覺問答 | VSI-Bench | MRA | 68.81 | 對象數量 | - |
視覺問答 | VSI-Bench | MRA | 57.01 | 絕對距離 | - |
視覺問答 | VSI-Bench | MRA | 79.17 | 對象大小 | - |
視覺問答 | VSI-Bench | MRA | 75.14 | 房間大小 | - |
視覺問答 | VSI-Bench | 準確率 | 58.45 | 相對距離 | - |
視覺問答 | VSI-Bench | 準確率 | 42.56 | 相對方向 | - |
視覺問答 | VSI-Bench | 準確率 | 34.54 | 路線規劃 | - |
視覺問答 | VSI-Bench | 準確率 | 68.77 | 出現順序 | - |
📄 許可證
本項目採用 Apache-2.0 許可證。
💡 潛在應用
ViCA-7B 支持廣泛的基於空間的多模態應用:
- 室內導航助手
- 機器人規劃和空間查詢
- 智能房間佈置和 AR 佈局分析
- 具身 AI 智能體的場景理解
⚠️ 已知侷限性
- 時間推理有限:無法有效利用時間指令。
- 幀縮放問題:模型期望固定的輸入長度。
- 不支持深度/點雲:僅支持 RGB 視頻輸入。
- 零樣本泛化能力良好,但並非與任務無關。










