【大模型RAG生成式AI开发实战】《大模型RAG生成式AI开发实战》_95.[第10章 视频RAG应用] 视频嵌入方法:时序特征提取

还在把视频当成PPT来检索?时序特征提取——这才是视频RAG的「灵魂引擎」。本文将彻底讲透从帧级到片段级的嵌入方法论,带你避开「截图式RAG」的深坑,手把手构建真正理解「时间流动」的生成式视频AI。读完这篇,你的视频助手终于能看懂电影剧情、学会操作步骤、理解赛事转折,而不是对着一堆静态画面瞎猜。
本文目录:
- 要点1:时序信息的不可替代性——别让RAG变成「高级截图工具」
- 要点2:从3D卷积到Video Transformer——时序特征提取的技术演进与选型
- 要点3:RAG场景的时序分块策略——滑动窗口与语义边界的艺术
- 要点4:多模态时序对齐——音视频联合嵌入与字幕时间轴绑定
- 要点5:时序感知的向量索引设计——层次化存储与检索优化
嗨,大家好呀,我是你的老朋友精通代码大仙。接下来我们一起学习 《大模型RAG生成式AI开发实战》95.[第10章 视频RAG应用] 视频嵌入方法:时序特征提取
“看视频只看封面,等于吃饭只闻香味——永远尝不到真滋味。”
这句话放在咱们程序员做视频RAG上,简直是一针见血。你是不是也这样?接到一个视频理解的需求,第一反应就是写个脚本抽帧,把视频变成一堆JPG,然后通通丢进CLIP做图像嵌入,最后信心满满地说:哥的视频RAG搞定了!结果呢?用户问一句"第三步操作是什么",你的系统要么返回第一步的画面,要么干脆丢过来一个片头Logo。为啥?因为你把视频最珍贵的东西给扔了——时间。
对于刚入行或者转型做大模型应用的新手来说,视频RAG绝对是个看起来简单、做起来全是暗坑的战场。图像RAG那套逻辑照搬过来?行不通。视频不是图片幻灯片,它是流动的信息河,是状态连续变化的过程记录。如果你搞不定时序特征提取,你的大模型就永远是个对着静态画面瞎猜的"憨憨"。今天这篇,咱们就死磕这一个核心命门,带你从坑里爬出来,真正打通视频RAG的任督二脉。
要点1:时序信息的不可替代性——别让RAG变成「高级截图工具」
咱们先来一个灵魂拷问:视频和图片最本质的区别到底是什么?
是分辨率更高吗?显然不是。是文件体积更大吗?那只是表象。真正的答案是:时间维度。一张照片定格的是一个瞬间,而一段视频记录的是状态流转、动作演进和因果链条。你在做RAG嵌入的时候,如果把视频简单粗暴地抽成十几张图,分别编码后扔进向量库,那你本质上做的是"图库检索",跟视频理解八竿子打不着。
举个例子你就明白了。假设用户上传了一个五分钟的做菜视频,然后提问:"主播是什么时候把糖色炒糊的?"如果你的系统每秒抽一帧,它可能抽到的是:空锅、倒油、下糖、装盘、成品。你发现问题了吗?那个"糖从透明变黄再变褐最后发苦冒烟"的关键动态过程,在孤立的帧里完全被抹平了。检索出来的要么是正常炒糖的画面,要么是已经糊掉的成品特写,中间那个导致失败的时序因果关系,彻底断了。你的大模型拿到这种素材,除了瞎编还能干啥?
这个坑,很多新手甚至一些工作了两三年的兄弟都会掉进去。我管它叫"截图思维陷阱"。大家的惯性思维是:视频嘛,无非就是很多张图片快速播放。我用OpenCV每秒钟抽一帧,然后拿CLIP或者多模态大模型对每一帧做image embedding,存进Milvus、Faiss或者Pgvector,这不就齐活了吗?
来看看这个极具代表性的错误思路:
import cv2
import torch
import clip
from PIL import Image
# 加载CLIP模型
model, preprocess = clip.load("ViT-B/32")
video = cv2.VideoCapture("cooking.mp4")
fps = int(video.get(cv2.CAP_PROP_FPS))
frame_embeddings = []
while True:
ret, frame = video.read()
if not ret:
break
# 每秒抽一帧
if int(video.get(cv2.CAP_PROP_POS_FRAMES)) % fps == 0:
pil_img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
image_input = preprocess(pil_img).unsqueeze(0)
with torch.no_grad():
emb = model.encode_image(image_input)
frame_embeddings.append(emb)
vector_db.add(emb, metadata={"type": "frame"})
看出问题在哪了吗?每一帧的embedding都是独立计算的。CLIP看到的只是一张张孤立的静态图片。它知道"这是一口锅",“这是一块肉”,但它完全感知不到"肉正在下锅"还是"锅铲正在翻面"。更致命的是,时序上的先后关系、因果关系在这种表示下荡然无存。你的RAG系统检索出来的,永远是"视觉上最像查询的一张图",而不是"语义上最相关的一个过程"。
难怪用户会暴躁:“我问的是怎么修好的,你给我返回个坏零件的特写图是啥意思?!” 这种体验翻车,根子就在你根本没做时序特征提取。
那正确的姿势应该是什么?咱们得让模型看见运动(Motion),看见变化。
最基础的改进,是从"帧级"(Frame-level)升级到"片段级"(Clip-level)。不要抽单帧,而是截取连续的N帧(比如16帧、32帧甚至64帧),把它们作为一个整体输入到时序编码器。这个编码器可以是经典的3D卷积网络,也可以是现在主流的Video Transformer。它的核心目标只有一个:输出一个能够概括"这N帧内到底发生了什么动作"的向量。
哪怕你的算力有限,做不了太重的模型,至少也应该引入光流(Optical Flow)或者简单的帧间差分,给模型补充"这里像素在动,而且是这样动"的线索。
看看修正后的核心思路:
def extract_temporal_clips(video_path, window_size=16, stride=8):
reader = cv2.VideoCapture(video_path)
frames = []
while True:
ret, frame = reader.read()
if not ret:
break
frames.append(preprocess_frame(frame))
clips = []
for i in range(0, len(frames) - window_size, stride):
# 关键:提取连续帧组成三维片段 [T, H, W, C]
clip = frames[i : i + window_size]
clips.append((i, np.stack(clip)))
return clips
for start_idx, clip in clips:
# clip 输入时序编码器,内部使用时序卷积或时序自注意力
temporal_embedding = video_encoder(clip)
vector_db.add(
temporal_embedding,
metadata={
"start_frame": start_idx,
"end_frame": start_idx + window_size,
"type": "temporal_clip"
}
)
这样做的好处是立竿见影的。模型在编码时,看到的是一段连续的时间切片。它能感知到"手在移动"、“水在沸腾”、“球在飞行”、“糖色在变化”。这种Motion-aware的向量一旦进入RAG链路,检索和生成的质量立马脱胎换骨。用户再问起"糖色怎么炒糊的",系统就能精准定位到那个连续变色、冒烟、发苦的动态片段,给大模型提供完整的证据链。
小结:视频RAG的灵魂不在单帧画质,而在时间流动的连贯性。丢掉时序,你的系统就是个高级截图工具,永远也长不出理解过程的眼睛。
要点2:从3D卷积到Video Transformer——时序特征提取的技术演进与选型
搞清楚"必须做时序"之后,下一个头疼的问题来了:市面上这么多视频理解模型,我到底该用哪个来做嵌入?选错了,要么效果拉胯,要么成本爆炸。
视频时序特征提取的技术路线,这些年经历了一场从"暴力堆叠"到"精巧设计"的进化。最早大家用3D卷积(C3D),直接把2D卷积扩展一个时间维度,简单粗暴但有效。后来出现了双流网络(Two-Stream),一路做RGB特征,一路做光流特征,最后融合。再后来,(2+1)D卷积、I3D、SlowFast各种架构百花齐放。到了Transformer时代,TimeSformer把自注意力从空间扩展到时间,Video Swin Transformer则用滑动窗口做高效时序建模。再往后,多模态大一统模型如Video-LLaMA、InternVid更是试图把视频、音频、文本全部塞进一个统一空间。
听起来很美好对吧?但坑就在这里。新手最容易犯的两大极端错误,我在太多人身上见过了。
第一种叫"盲目炼丹型"。看了几篇顶会论文,热血沸腾,非要在自己的视频RAG项目里上TimeSformer或者Video Swin Transformer。结果本地就一张3090,batch_size设成1还爆显存,推理一段十分钟的视频要等半小时。明明只是做个视频检索和问答,硬生生搞成了"科研项目",上线遥遥无期。这是典型的杀鸡用牛刀,场景错配。
第二种叫"考古坚守型"。不知道从哪抄来的C3D代码,训练了好几天,效果被现成预训练模型吊打,还自我安慰说"视频理解本来准确度就不高"。这就好比2026年了还在用VGG16做图像特征提取,不是不能用,是纯属给自己找不痛快。
更隐蔽的错误是"模态错配型"。有些兄弟直接用CLIP做视频,把视频当成独立帧处理,却忽略了视频领域专门的多模态对齐模型,比如CLIP4Clip、ViCLIP。这些模型专门在视频-文本对上做了对比学习,生成的嵌入天然适合RAG的语义检索场景。
那到底怎么选?我给你画一张清晰的选型地图,对号入座就行:
- 边缘端/移动端,算力极度紧张:选MoViNet、X3D这种轻量级3D CNN,或者干脆用传统光流+双流网络。它们参数量小,推理快,虽然精度不是最顶,但够用的基础上能跑得动。
- 云端通用场景,追求性价比:直接用预训练的TimeSformer或Video Swin Transformer。不用从头训练,拿来当特征提取器(Feature Extractor)就行。记住,你是做RAG嵌入,不是刷Kinetics准确率榜,冻结骨干网络,只取倒数第二层的特征,足够了。
- 强语义检索,需要视频-文本对齐:无脑上CLIP4Clip或ViCLIP。这类模型在数百万视频-文本对上练过,向量空间里视频和 query 的距离度量非常靠谱,RAG召回率极高。
看看云端的正确打开方式:
from transformers import AutoModel, AutoProcessor
import torch
# 使用预训练的Video Swin作为时序特征提取器
model = AutoModel.from_pretrained("microsoft/swin-tiny-patch4-window7-224")
processor = AutoProcessor.from_pretrained("microsoft/swin-tiny-patch4-window7-224")
# 假设 video_clip 是采样好的连续帧张量 [batch, T, 3, H, W]
inputs = processor(video_clip, return_tensors="pt")
with torch.no_grad():
# 提取隐藏状态,取时间维度上的聚合
outputs = model(**inputs, output_hidden_states=True)
# 取最后一层隐藏层,在时空维度做全局平均池化
hidden_states = outputs.hidden_states[-1]
temporal_embedding = hidden_states.mean(dim=[1, 2, 3]) # 压成向量
vector_db.add(temporal_embedding, metadata={"source": "video_swin"})
如果你做的是多模态RAG,视频和文本要在一个空间里检索,那更省事的方案是:
# CLIP4Clip 风格:统一视频-文本嵌入空间
text_emb = text_model.encode_text(query)
video_emb = video_model.encode_video(temporal_clip)
# 在同一个向量空间做近邻搜索,天生对齐
results = vector_db.similarity_search(video_emb, top_k=5)
核心原则就一条:不要重复造轮子,更不要为了炫技而炫技。 视频时序模型发展到现在,HuggingFace上大把的预训练权重。你的任务是选对底座,把它的时序表征能力注入到RAG管线里,而不是从零开始炼一个视频理解模型。
小结:技术没有绝对的好坏,只有合不合适。选型跟着场景和预算走,预训练模型是你最好的朋友,别跟它客气。
要点3:RAG场景的时序分块策略——滑动窗口与语义边界的艺术
有了时序编码器,下一个绕不开的工程难题是:怎么把视频切成块(Chunking)?
文本RAG里,分块策略已经被讨论烂了,按Token切、按句子切、按语义切,各有各的招。但视频RAG的分块,远比文本复杂。因为你切的不只是一维字符串,而是三维时空数据。切错了,动作断裂,语义稀碎;切得太碎,向量库爆炸,检索噪声淹没信号。
我见过最粗暴的做法,是直接用固定时长切分。比如配置文件里赫然写着:
video_chunking:
strategy: "fixed_time"
interval: 10s
看上去很有道理对吧?每十秒一段,整整齐齐。但现实会狠狠地给你一巴掌。还是那个做菜的例子:“把鸡蛋打进碗里"这个动作发生在第9秒到第11秒,一刀切的十秒分块直接把它拦腰砍断。第一段结尾是"举起鸡蛋”,第二段开头是"碗里蛋液",中间那个"磕开蛋壳"的关键动作,丢了。用户检索"怎么打鸡蛋",系统返回的片段永远是残缺的,大模型看了也只能懵逼。
另一种极端是"帧海战术",每秒钟甚至每帧都生成一个向量。十分钟的视频能存出上万个向量。检索的时候,海量噪声向量把真正相关的片段淹没了,而且存储成本直线飙升。
那正确的分块姿势是什么?记住三个关键词:重叠、边界、多粒度。
第一,用重叠滑动窗口(Overlapping Sliding Window)。窗口可以设3秒或5秒,但步长要小于窗口长度,比如窗口5秒,步长2秒。这样相邻片段之间有重叠缓冲区,一个完整的动作至少会在某一个窗口内被完整捕获,不会被切断。这会带来一些冗余存储,但RAG的召回率比这点存储成本重要得多。
第二,基于场景边界(Scene Boundary)做自适应切分。视频不是均匀的信息流,它由一个个镜头(Shot)和场景(Scene)组成。利用PySceneDetect这样的工具,或者简单的帧间直方图差异,检测镜头切换点,在切换点处切分。这样保证每一个块内部是同一个场景,语义高度一致。
第三,多粒度分块(Hierarchical Chunking)。粗粒度层面,按场景切,每个场景生成一个"主题向量",用于快速过滤。细粒度层面,在场景内部用滑动窗口生成"动作向量",用于精准定位。检索时先粗后细,既能保证速度,又能保证精度。
看看工程上的实现思路:
from scenedetect import detect, ContentDetector
# 第一步:检测场景边界
scene_list = detect("input.mp4", ContentDetector())
clips_metadata = []
for scene in scene_list:
start, end = scene[0].get_seconds(), scene[1].get_seconds()
# 第二步:在场景内部使用重叠滑动窗口
window, stride = 3.0, 1.5 # 单位:秒
current = start
while current + window <= end:
clip_start = current
clip_end = current + window
# 提取该时间段的连续帧
temporal_clip = extract_frames_between(video, clip_start, clip_end)
emb = temporal_encoder(temporal_clip)
clips_metadata.append({
"embedding": emb,
"start": clip_start,
"end": clip_end,
"scene_id": scene.index,
"level": "fine"
})
current += stride
# 同时存储场景级粗粒度向量
for scene in scene_list:
scene_clip = extract_frames_between(video, start, end)
coarse_emb = temporal_encoder(scene_clip) # 可以用更大的窗口或降采样
vector_db.add(coarse_emb, level="coarse", time=(start, end))
这种策略下,用户的查询"打鸡蛋的步骤"会先命中粗粒度的厨房场景,然后在场景内部精确定位到那个3秒钟的打蛋滑动窗口片段。既避免了跨场景噪声,又保证了动作完整性。
小结:时序分块不是切蛋糕,而是要在保证语义完整的前提下,用重叠和边界检测为RAG提供最优质的检索单元。
要点4:多模态时序对齐——音视频联合嵌入与字幕时间轴绑定
做视频RAG,千万别只盯着画面看。真实世界的视频是多媒体的综合体:画面、声音、背景音乐、人物对话、字幕条,信息密度极高。如果你只做视频画面的时序嵌入,而忽略了音轨和ASR文本,那等于自断一臂。更惨的是,如果你分别处理各模态,却不好好做时间轴对齐,那检索出来的结果就是"画面说东,文本说西",惨不忍睹。
新手最容易踩的坑,就是把视频和音频当成两个完全独立的项目来处理。视频流抽帧做Video Embedding,音频流扔给Whisper做ASR,然后ASR文本再单独做Text Embedding。最后向量库里有两套毫不相干的向量,一套是画面的,一套是文本的。检索的时候各查各的,强行拼接结果。
看看这个典型的"各玩各的"错误示范:
# 视频Embedding:按帧/片段处理
video_embs = extract_video_embeddings(video)
# 存储时的时间戳是视频帧号
# ASR文本Embedding:按句子处理
asr_results = whisper_model.transcribe(audio) # 返回文本,但时间戳精度粗糙
text_embs = [text_encoder(seg["text"]) for seg in asr_results["segments"]]
# 存储时的时间戳是音频秒数
# 完蛋了:两套时间基准,检索时根本对不上
问题在哪?视频编码器的时间步可能是以帧为单位(0, 1, 2…),而ASR返回的时间戳可能只有秒级甚至句级精度。当你检索到一个文本片段说"接下来我们看第三步",想找到对应的画面,时间戳偏差个两三秒,画面可能早就切到别的内容了。用户在页面上看到文字描述和播放区画面完全对不上,体验直接崩盘。
正确的做法,核心就四个字:统一时间轴。
首先,在预处理阶段,必须把所有模态都归一化到同一个时间基准上,最好是毫秒级的视频时间轴。ASR的结果要强制对齐到视频时间戳,而不是音频时间戳。如果有字幕文件(SRT/VTT),它天然带有时间码,但要验证其是否与视频画面严格对齐,很多内嵌字幕存在0.5秒到2秒的漂移。
其次,在嵌入阶段,做真正的多模态融合。有两种思路:
- 早期融合(Early Fusion):在特征层面就把音视频揉在一起。比如把视频帧序列和音频频谱图同时输入一个多模态编码器(类似Video-LLaMA的Q-Former对齐层),让它自己学到音画关联,输出一个联合向量。
- 晚期融合(Late Fusion):分别编码画面和文本,然后在向量层面做加权融合或拼接。比如视频片段embedding和对应的ASR文本embedding各取一半权重相加,或者投影到同一个空间后做池化。
对于RAG应用,晚期融合往往更实用,因为它灵活、可解释、好调试。看看这个对齐与融合的实现思路:
# 假设已完成ASR,结果是精确对齐的片段列表
asr_segments = [
{"start": 12.5, "end": 16.8, "text": "接下来把糖色炒至琥珀色"},
# ...
]
for seg in asr_segments:
t0, t1 = seg["start"], seg["end"]
# 严格按ASR时间段截取视频画面
video_clip = extract_video_clip(video_path, t0, t1)
visual_emb = video_encoder(video_clip) # [D]
# 编码对应文本
text_emb = text_encoder(seg["text"]) # [D]
# 晚期融合:投影到统一维度后加权平均
fused_emb = 0.6 * visual_projection(visual_emb) + \
0.4 * text_projection(text_emb)
vector_db.add(
fused_emb,
metadata={
"start_time": t0,
"end_time": t1,
"text": seg["text"],
"modality": "fused"
}
)
这么做的好处是什么?当用户查询"炒糖色要注意什么"时,检索到的向量既包含了画面里锅铲翻动的视觉信息,又包含了"炒至琥珀色"的文本语义。生成模型拿到这种多模态证据,回答的准确性和丰富度直接起飞。而且因为有精确的时间戳,前端播放时可以精准seek到对应片段,音画严丝合缝。
如果还有音频特征(比如环境音、背景音乐情绪),也可以一并编码进来。但在大多数RAG场景下,视觉+ASR文本已经覆盖了90%的信息需求,不必过度设计。
小结:单模态的时序理解是信息孤岛,多模态时间轴对齐才能形成完整的视频语义大陆。记住,对齐精度决定体验上限。
要点5:时序感知的向量索引设计——层次化存储与检索优化
提取了漂亮的时序特征,做好了多模态融合,如果倒在存储和检索的最后一公里,那就太冤了。视频RAG的向量索引设计,和文本RAG有本质不同,因为你处理的是一个既有高维语义、又有严格先后顺序的时空序列。
新手在这里常犯两个极端错误,我称之为"一镜到底"和"帧海战术"。
“一镜到底"型选手,把整个视频当作文档,所有帧的特征平均池化成一个向量。十分钟的视频就一个embedding。用户问"第三分钟讲了什么”,检索出来的是整个视频的向量,定位能力为零。大模型只能基于全局信息泛泛而谈,完全给不出精准的时间点。
"帧海战术"型选手走向另一个极端。每帧都存一个向量,十分钟的视频如果每秒30帧,就是18000个向量。检索的时候,Top-K结果可能分散在视频的各个角落,东边一帧西边一帧,时间连续性完全破坏。更糟糕的是,向量库体积爆炸,检索延迟高到无法接受。
那正确的索引架构应该怎么搭?答案是层次化时序索引。
第一层,视频级摘要向量。对每个视频抽取一个全局表征,用于快速判断"哪个视频可能包含答案"。这在多视频库场景下尤为重要,先把无关视频筛掉。
第二层,场景级主题向量。基于前面提到的场景检测,每个场景生成一个向量,代表这段内容的主题(比如"准备食材"、“热锅下油”、“调味出锅”)。检索时先定位到相关场景。
第三层,片段级精细向量。在场景内部,用滑动窗口生成的时序嵌入做精准召回。这是真正回答用户问题的"弹药库"。
存储的时候,每个向量必须携带丰富的时间戳元数据:start_time、end_time、scene_id、video_id。这不仅是检索后的定位需要,也是做时序重排(Temporal Re-ranking)的基础。
说到检索优化,还有一个大招:时序邻近重排。初筛拿到Top-K个片段向量后,不要直接丢给大模型。先检查这些片段在时间轴上的分布。如果两个片段相邻或高度重叠,说明它们属于同一个连续事件,应该合并成一个更长的证据块。如果Top-K结果在时间轴上跳来跳去(比如第1秒、第50秒、第3秒),那很可能有噪声,需要做时间一致性过滤,优先返回连续区域的片段。
看看这个层次化检索的工程实现:
# 存储阶段:多级写入
def index_video(video_path):
video_id = hash(video_path)
# L1: 视频级全局向量
global_emb = extract_global_video_embedding(video_path)
db.add(global_emb, level="video", video_id=video_id)
scenes = detect_scenes(video_path)
for scene in scenes:
s0, s1 = scene.start, scene.end
# L2: 场景级向量
scene_emb = extract_scene_embedding(video_path, s0, s1)
db.add(scene_emb, level="scene", video_id=video_id,
time_range=(s0, s1), scene_id=scene.index)
# L3: 片段级精细向量(重叠窗口)
for clip_start, clip_end in sliding_window(s0, s1, window=3, stride=1):
clip_emb = extract_temporal_clip_embedding(video_path, clip_start, clip_end)
db.add(clip_emb, level="clip", video_id=video_id,
scene_id=scene.index, time_range=(clip_start, clip_end))
# 检索阶段:由粗到细 + 时序合并
def search_video(query, top_k=5):
query_emb = encode_query(query)
# Step 1: 粗筛相关视频(多视频库场景)
candidate_videos = db.search(query_emb, level="video", top_k=3)
all_clips = []
for vid in candidate_videos:
# Step 2: 在相关视频内找候选场景
candidate_scenes = db.search(
query_emb, level="scene",
filter={"video_id": vid.id}, top_k=3
)
for sc in candidate_scenes:
# Step 3: 在场景内精排片段
clips = db.search(
query_emb, level="clip",
filter={"scene_id": sc.scene_id}, top_k=5
)
all_clips.extend(clips)
# Step 4: 时序合并——按时间排序,合并相邻片段
all_clips.sort(key=lambda x: x.start_time)
merged = merge_adjacent_clips(all_clips, gap_threshold=2.0)
return merged[:top_k]
在这个架构下,存储成本可控(片段数量远小于帧数,但又远小于一个视频一个向量),检索精度极高,而且返回的结果天然带有连续的时间范围,前端可以直接播放完整的证据片段。
另外,如果向量库支持元数据过滤(比如Milvus的表达式过滤、Pinecone的metadata filter),你可以在检索时直接加时间范围条件,比如"只查第三分钟到第五分钟的内容",这在长视频问答里超级实用。
小结:时序特征的存储结构决定了检索的精度上限。向量库设计必须尊重时间的层次性和连续性,才能发挥出视频RAG的真正威力。
写在最后
咱们今天从"为什么必须做时序"讲到"怎么做技术选型",从"怎么切分视频"聊到"怎么对齐音画",最后落地到"怎么存怎么查"。这条链路走下来,你应该能感觉到:视频RAG绝不是图像RAG的简单扩展,它是一个独立的工程体系,而时序特征提取就是这个体系的脊梁骨。
很多新手觉得视频理解难,其实难的不是某个算法,而是思维方式的转变。你要从"看图片"的习惯里跳出来,建立起"看过程"的直觉。视频里的信息是流淌的,是动态的,是有因果的。只有你的嵌入向量 capture 到了这种流动性,大模型才能真正看懂视频,而不是对着几张漂亮截图胡言乱语。
编程这条路,从来都是不断打破惯性思维的过程。图像RAG你搞通了,那是很好的基础;但视频RAG这个新世界,有新的规则、新的坑、新的风景。别怕踩坑,每一个坑都是你理解这个领域的台阶。保持好奇,持续动手,把今天讲的这些要点落地到你的项目里,反复调试,你一定能做出让人眼前一亮的视频AI应用。
记住,大模型时代,竞争的不是谁调参更厉害,而是谁对数据理解得更深。时序特征提取,就是你理解视频数据的那个"胜负手"。去练吧,我看好你。
关注私信备注:“资料代找获取”,全网计算机学习资料代找:例如:
《课程:2026 年多模态大模型实战训练营》
《课程:AI 大模型工程师系统课程 (22 章完整版 持续更新)》
《课程:AI 大模型系统实战课第四期 (2026 年开课 持续更新)》
《课程:2026 年 AGI 大模型系统课 23 期》
《课程:2026 年 AGI 大模型系统课 21 期》
《课程:AI 大模型实战课 8 期 (2026 年 2 月最新完结版)》
《课程:AI 大模型系统实战课三期》
《课程:AI 大模型系统课程 (2026 年 2 月开课 持续更新)》
《课程:AI 大模型全阶课程 (2025 年 12 月开课 2026 年 6 月结课)》
《课程:AI 大模型工程师全阶课程 (2025 年 10 月开课 2026 年 4 月结课)》
《课程:2026 年最新大模型 Agent 开发系统课 (持续更新)》
《课程:LLM 多模态视觉大模型系统课》
《课程:大模型 AI 应用开发企业级项目实战课 (2026 年 1 月开课)》
《课程:大模型智能体线上速成班 V2.0》
《课程:Java+AI 大模型智能应用开发全阶课》
《课程:Python+AI 大模型实战视频教程》
《书籍:软件工程 3.0: 大模型驱动的研发新范式.pdf》
《课程:人工智能大模型系统课 (2026 年 1 月底完结版)》
《课程:AI 大模型零基础到商业实战全栈课第五期》
《课程:Vue3.5+Electron + 大模型跨平台 AI 桌面聊天应用实战 (2025)》
《课程:AI 大模型实战训练营 从入门到实战轻松上手》
《课程:2026 年 AI 大模型 RAG 与 Agent 智能体项目实战开发课》
《课程:大模型训练营配套补充资料》
更多推荐




所有评论(0)