LiveVLM: Efficient Online Video Understanding via Streaming-Oriented KV Cache and Retrieval

Authors: Zhenyu Ning, Guangda Liu, Qihao Jin, Wenchao Ding, Minyi Guo, Jieru Zhao Affiliations: Shanghai Jiao Tong University, Fudan University Venue: arXiv 2505.15269, May 2025

1. Motivation (研究动机)

1.1 核心问题

当前 Video LLM 主要面向 离线 (offline) 场景设计:用户提问后才处理整个视频。这在流式视频(自动驾驶、机器人、AR)场景中存在三大挑战:

  1. 视觉信息保留 (Performance):现有方法对 visual features 进行高压缩导致细粒度信息丢失
  2. 显存开销 (Overhead):长视频的 KV cache 随帧数增长呈 复杂度,极易 OOM
  3. 实时交互速度 (Speed):离线方法需等待用户提问后重新处理视频,响应延迟大

1.2 现有方法的不足

方法类别代表工作局限
Sparse sampling / Token mergingVideoLLM-online, LLaVA-OneVision高压缩损失细粒度信息
Query-guided 检索MovieChat+仅支持单轮对话,不保留长期记忆
KV 预计算ReKV不压缩完整 KV → 显存溢出后 offload 到 CPU,通信开销大
可学习模块Flash-VStream, Dispider需要额外训练,高压缩下性能下降

核心 insight:与压缩 visual features 相比,压缩 KV tensors 包含更多冗余信息,可以在更高压缩比下保持性能。

Figure 1 解读:上图 (a) 对比了传统在线 Video LLM 与 LiveVLM 的架构差异。传统方法将所有 visual features 和 text tokens 一起送入 LLM,计算复杂度为 。LiveVLM 在视频流处理阶段就预计算并压缩 KV,问答时只检索相关 KV chunks,复杂度降至约 。图 (b) 展示随帧数增加,ReKV 因 OOM 需 offload 到 CPU 导致延迟急剧上升,而 LiveVLM 保持稳定的显存占用和低延迟。


2. Idea (核心思想)

LiveVLM 是一个 training-free 的流式在线视频理解框架,核心思路:

  1. Streaming-Oriented KV Cache:视频流处理阶段持续编码并 压缩 video KV,存入长期记忆
  2. Video-Specific KV Compression:结合 attention-based pruning + frame-wise merging 的两阶段压缩策略,消除 70% 冗余 KV
  3. Online Question-Answering:问答时从长期记忆中 检索 query-relevant KV chunks,结合短期记忆(滑动窗口),提供给 LLM 生成回答
  4. Relative Positional Embedding:对选中的 tokens 使用相对位置编码,避免 RoPE 在长视频中对远距离 token 的注意力衰减

关键指标

  • 同设备可处理帧数提升 44x(32 → 1400+ 帧)
  • 响应速度提升 5x(对比 256 帧输入的 SoTA 方法)
  • 显存降低 2.6x

3. Method (方法)

Figure 2 解读:LiveVLM 整体工作流程。左侧展示视频流处理流程:输入帧被分成 video clips → visual encoder 编码 → 生成 video KV → 经过 Compression Module(先 attention-based 剪枝再 frame-wise 合并)→ 压缩后的 KV chunks 存入 Streaming-oriented KV Cache 作为长期记忆。同时最新帧保存在 Read Buffer 作为短期记忆。右侧展示问答流程:用户提问后,从长期记忆检索相关 KV chunks,结合短期记忆送入 VLM 生成回答。

3.1 Streaming Video Encoding

LiveVLM 以 video clip(默认 8 帧)为单位处理视频流。对第 个 clip ,计算注意力时利用之前所有已压缩的 KV:

其中 是 clip 的 QKV 向量, 是注意力输出用于计算下一层的 QKV。 为之前 clips 的压缩 KV。

# Streaming Video Encoding
# Input: video_stream, clip_size=8
# Output: streaming_kv_cache
 
kv_cache = []  # 长期记忆
short_term_buffer = Queue(maxsize=8)  # 短期记忆,最近 8 帧
 
for clip_i in split_into_clips(video_stream, clip_size):
    # Step 1: 编码当前 clip
    Q_i, K_i, V_i = visual_encoder(clip_i)
 
    # 利用之前已压缩的 KV 计算当前 clip 的注意力
    K_prev = concat([chunk.K for chunk in kv_cache])
    V_prev = concat([chunk.V for chunk in kv_cache])
    O_i = Attention(Q_i, concat(K_prev, K_i), concat(V_prev, V_i))
 
    # Step 2: 压缩当前 clip 的 KV (详见 3.2)
    K_i_c, V_i_c, m_i = compress_kv(Q_i, K_i, V_i)
 
    # Step 3: 存入长期记忆
    if len(kv_cache) >= max_capacity:
        kv_cache.pop(0)  # FIFO 策略
    kv_cache.append(KVChunk(K=K_i_c, V=V_i_c, mean_key=m_i))
 
    # 更新短期记忆
    short_term_buffer.push(clip_i)

3.2 Video-Specific KV Compression

压缩包含两个阶段:

Stage 1: Attention-based Token Discarding

由于最新 Video LLM 使用 FlashAttention,注意力分数不会显式计算。LiveVLM 使用最后 个 visual tokens 的 query 向量计算部分注意力分数:

其中 是 chunk 中第 个 token 的 query 向量, 是 visual tokens 数量, 个 query tokens 的分数, 是 pooled score。根据 的排名丢弃低分 KV tokens。

计算开销:仅增加不到 1% 的额外计算和显存。

Stage 2: Frame-wise KV Merging

将每帧的剩余 KV 向量合并为 单个 KV tuple(frame-wise representation),插入到压缩序列中对应帧的末尾位置

# Video-Specific KV Compression
# Input: Q_i, K_i, V_i (当前 clip 的 QKV), compression_ratio=0.7
# Output: K_i_c, V_i_c, m_i
 
def compress_kv(Q_i, K_i, V_i):
    N_v = K_i.shape[0]  # visual tokens 总数
    r = last_r_tokens  # 用于计算注意力分数的 query token 数
 
    # Stage 1: Attention-based pruning
    # 用最后 r 个 query tokens 计算部分注意力
    W_i = softmax(Q_i[N_v-r:N_v] @ K_i.T)  # [r, N_v]
    S_i = mean_pool(W_i, dim=0)             # [N_v]
 
    # 保留 top (1-ratio) 的 tokens
    keep_count = int(N_v * (1 - compression_ratio))
    top_indices = topk(S_i, keep_count)
    K_pruned = K_i[top_indices]
    V_pruned = V_i[top_indices]
 
    # Stage 2: Frame-wise merging
    # 对每帧的 KV 做 mean pooling 得到单个 KV tuple
    K_merged, V_merged = [], []
    for frame_idx in range(num_frames):
        frame_mask = get_frame_tokens(top_indices, frame_idx)
        K_merged.append(mean(K_pruned[frame_mask], dim=0))
        V_merged.append(mean(V_pruned[frame_mask], dim=0))
 
    # 将 merged KV tuple 插入到每帧末尾
    K_i_c = interleave(K_pruned, K_merged)  # 按帧位置插入
    V_i_c = interleave(V_pruned, V_merged)
 
    # 计算 mean-pooled key 用于后续检索
    m_i = mean(K_i_c, dim=0)
 
    return K_i_c, V_i_c, m_i

Table 1: Frame-wise merging 的效果(MSVD / TGIF accuracy %)

方法压缩比MSVDTGIF
w/o merging↓40%73.475.8
w/o merging↓60%73.676.8
w/o merging↓80%75.877.0
w. merging↓40%74.676.6
w. merging↓60%78.076.6
w. merging↓80%76.677.2

3.3 Online Question-Answering

Figure 3 解读:在线问答过程示意图。长期记忆 KV cache 中每个 chunk 都有一个 Mean Pooled K 向量。用户提问后,先计算 question tokens 的 Mean Pooled Q 向量,然后与每个 chunk 的 Mean Pooled K 做点积计算相关性分数,选择 top-k 个高分 chunks。选中的 chunks 与短期记忆帧一起,使用 相对位置 的 RoPE 编码送入 LLM。注意选中的 chunks 被视为连续序列,位置从 1 开始重新编号。

KV Retrieval from Long-term Memory

  1. 计算 question 的 mean-pooled query 向量:

其中 是 question 中的 token 数。

  1. 计算 与每个 chunk 的 mean key vector 的注意力分数

  2. 选择 top-k 个最相关的 KV chunks(默认

Relative Positional Embedding

问题:RoPE 在处理长视频(1 小时以上)时,会显著衰减远距离 visual tokens 的注意力分数,导致早期信息难以被检索到。

解决方案

  • RoPE 仅应用于被选中参与注意力计算的 tokens
  • 选中的 tokens 被视为 连续序列,使用相对位置而非绝对位置
  • 避免因绝对位置过大导致的注意力衰减和幻觉
# Online Question-Answering
# Input: question, kv_cache, short_term_buffer, top_k=20
# Output: answer
 
def online_qa(question, kv_cache, short_term_buffer, top_k=20):
    # 1. 编码 question
    q_tokens = tokenizer(question)  # [N_q, D]
 
    # 2. 计算 mean-pooled query
    q_mean = mean(q_tokens, dim=0)  # [D]
 
    # 3. 检索相关 KV chunks
    scores = []
    for chunk in kv_cache:
        score = dot(q_mean, chunk.mean_key)  # 标量
        scores.append(score)
 
    top_k_indices = topk(scores, k=top_k)
    retrieved_KV = [kv_cache[i] for i in top_k_indices]
 
    # 4. 获取短期记忆 KV
    short_term_KV = encode_frames(short_term_buffer)
 
    # 5. 组合并应用 relative RoPE
    all_KV = concat(retrieved_KV, short_term_KV)
    # 重新编号位置: 0, 1, 2, ... (相对位置)
    all_KV = apply_relative_rope(all_KV)
 
    # 6. LLM 生成回答
    answer = LLM(query=q_tokens, kv_cache=all_KV)
    return answer

4. Experimental Setup (实验设置)

4.1 基础模型与硬件

项目配置
基础模型LLaVA-OneVision-Qwen2-7B-OV
每帧 visual tokens196
GPUNVIDIA 4090D (24 GB)
Video clip 大小8 帧/clip
压缩比70%(丢弃 70% KV tokens)
检索 chunks 数20(默认)
短期记忆窗口最近 8 帧
在线处理帧率0.5 FPS(每 2 秒 1 帧)
离线长视频帧率0.5 FPS(<30min),0.2 FPS(>30min)

4.2 评测基准

在线 (Online):

  • StreamingBench: 流式视频理解综合基准,包含 18 个子任务,分 3 大类:Real-Time Visual Understanding (10)、Omni-Source Understanding (4)、Contextual Understanding (4)

离线 (Offline):

  • EgoSchema: 5000+ 视频,每个约 3 分钟,第一人称视角
  • MLVU: 长度从几分钟到数小时
  • VideoMME: 长度从几分钟到数小时,含 Medium / Long 分组

4.3 对比方法

Proprietary: Gemini 1.5 Pro, GPT-4o, Claude 3.5 Sonnet

开源离线: Video-LLaMA2-7B, VILA-1.5-8B, Video-CCAM-14B, LongVA-7B, InternVL-V2-8B, Kangaroo-7B, LLaVA-NeXT-Video-32B, MiniCPM-V-2.6-8B, LLaVA-OneVision-7B

开源在线: Flash-VStream-7B, VideoLLM-online-8B, Dispider-7B, ReKV-7B


5. Experimental Results (实验结果)

5.1 StreamingBench 在线视频理解

Real-Time Visual Understanding(10 子任务):

ModelFramesOPCRCSATPEUTRPRSUACPCTAll
Flash-VStream-7B-25.8943.5724.9123.8727.3313.0818.5225.2023.8748.7023.23
VideoLLM-online-8B2 fps39.0740.0634.4931.0545.9632.4031.4834.1642.4927.8935.99
Dispider-7B1 fps74.9275.5374.1073.0874.4459.9276.1462.9162.1645.8067.63
ReKV-7B0.5 fps74.3978.9178.5577.1268.3267.9167.5962.6064.3144.5669.08
LiveVLM-7B0.5 fps81.4778.1383.2879.0869.5774.1475.0069.1167.7140.4172.92 (+1.80)

Omni-Source Understanding & Contextual Understanding:

ModelFramesERSCUSDMAOmni AllACUMCUSQAPOCtx All
ReKV-7B0.5 fps38.8024.8039.6046.4037.4031.2030.4030.4030.8030.70
LiveVLM-7B0.5 fps44.4030.4048.8060.8046.10 (+7.70)38.8036.8032.0032.4035.00 (+2.26)

亮点:在 Multimodal Alignment (MA) 子任务上达到 60.80%,超越 GPT-4o (56.00%) 和 Claude-3.5-Sonnet (48.80%),比 LLaVA-OneVision baseline 提升 +16.00%

5.2 实时响应效率

Figure 4 解读:左图为显存占用对比,右图为 Time-to-First-Token (TTFT) 对比。在 256 帧时:Dispider 显存约 48 GB(OOM),ReKV 约 36 GB;LiveVLM 仅约 12 GB。TTFT 方面:Dispider 在 256 帧时超过 1.2 秒,ReKV 约 0.8 秒(因 offload 到 CPU),LiveVLM 保持约 0.2 秒。LiveVLM 实现 2.6x 显存降低5x 延迟加速

5.3 离线长视频理解

ModelFramesEgoSchemaMLVU-devVideoMME MediumVideoMME LongVideoMME All
LLaVA-OneVision-7B3258.564.754.746.2-
VideoXL-7B128-64.953.249.255.5
MovieChat-7B204853.525.8-33.438.2
Dispider-7B1 fps55.661.753.749.756.5
LiveVLM0.5/0.2 fps59.0 (+0.5)66.3 (+1.6)56.4 (+1.7)48.8 (+2.6)57.3 (+0.4)

关键发现:LiveVLM 在 长视频 上优势最明显 — VideoMME Long 提升 +2.6%,MLVU-dev 提升 +1.6%

5.4 消融实验

检索 chunks 数量

Figure 5a 解读:EgoSchema 上检索 chunks 数量与准确率的关系。Full set 和 Subset 两条曲线都在约 8-12 个 chunks 时达到峰值,之后缓慢下降,说明过多 chunks 引入噪声。

Figure 5b 解读:MLVU 上的消融。Overall 和 Single Detail 两条曲线走势不同:Overall 在约 20 chunks 时最优,Single Detail 在 16 左右达峰后略降。

Figure 5c 解读:VideoMME 上的消融。Overall 和 Medium 曲线在 20 chunks 附近表现最佳,验证了默认 的合理性。

KV 压缩比消融(MLVU)

方法FramesTokensHolistic (TR/AR)Single Detail (NQA/ER/PQA)Multi Detail (AO/AC)All
LiveVLM (↓30%)0.5 fps~13888.6 / 74.070.7 / 65.7 / 71.146.7 / 34.066.1
LiveVLM (↓70%)0.5 fps~6087.8 / 74.071.3 / 65.4 / 71.646.3 / 35.466.3
LiveVLM (↓90%)0.5 fps~2187.5 / 72.067.9 / 63.4 / 67.544.8 / 32.563.7

关键发现:压缩比从 30% 提升到 90%,性能仅下降 2.4 个百分点(66.1 → 63.7),证实视觉 token 表示存在 内在稀疏性。70% 压缩比在性能与效率间取得最佳平衡。


源码对应关系

论文组件功能描述对应代码
Streaming Video Encoding以 clip 为单位编码视频流,利用历史压缩 KV 计算注意力暂无开源代码
Attention-based Token Discarding用最后 个 query tokens 计算部分注意力分数,丢弃低分 KV暂无开源代码
Frame-wise KV Merging每帧 KV 合并为单个 KV tuple,保留时序语义暂无开源代码
Long-term Memory (FIFO)压缩 KV chunks 的存储与管理,维护 mean-pooled key暂无开源代码
KV Retrievalmean-pooled query 与 mean-pooled key 点积计算相关性,top-k 检索暂无开源代码
Relative Positional Embedding选中 tokens 使用相对 RoPE 位置编码暂无开源代码

:截至 2026-03-12,本文暂未发现公开的官方代码仓库。