零标注V-JEPA实战:视频自监督预训练完整指南
【免费下载链接】jepaPyTorch code and models for V-JEPA self-supervised learning from video.项目地址: https://gitcode.com/GitHub_Trending/je/jepa
V-JEPA是Meta AI提出的视频自监督学习框架与官方PyTorch实现:模型只需看未标注视频即可学出通用视觉表征,省掉标注与骨干精调两步。冻结编码器加一层轻量attentive probe,K400 top-1可达82.0%。本文给出从环境搭建到预训练、冻结评测的最短可运行路径。
一、🚀 快速上手:环境搭建到最小可运行
1.1 三步装好环境
git clone https://gitcode.com/GitHub_Trending/je/jepa cd jepa conda create -n jepa python=3.9 pip conda activate jepa python setup.py install依赖清单见 requirements.txt:torch>=2、decord(视频解码)、webdataset、timm、submitit等。视频链路能否跑通,关键就看 decord 装没装成功。
1.2 制作 CSV 数据索引
视频数据不需要目录结构,只要一个 CSV:每行「绝对路径 整数标签」。预训练是无监督的,标签列会被直接忽略,填 0 即可;只有跑监督评测时才需要填真实标签。
/absolute/path/video1.mp4 0 /absolute/path/video2.mp4 0 /absolute/path/video3.mp4 0加载逻辑在 src/datasets/data_manager.py:dataset_type: VideoDataset走视频分支,ImageNet/iNat21/Places205走图像分支。
1.3 改配置占位符再启动
整个仓库「所有实验参数只放 YAML,不走命令行」。以 configs/pretrain/vitl16.yaml 为例,启动前必须替换两类占位符:
data.datasets:你的 CSV 索引文件列表(官方复现用了 Kinetics710 + SSv2 + HowTo100M 三份)logging.folder:日志与 checkpoint 保存目录
1.4 最短可运行路径
单机多卡(入口 app/main.py,适合调试管线):
python -m app.main \ --fname configs/pretrain/vitl16.yaml \ --devices cuda:0 cuda:1SLURM 集群(入口 app/main_distributed.py,基于 submitit 提交):
python -m app.main_distributed \ --fname configs/pretrain/vitl16.yaml \ --folder /path/to/submitit_logs \ --partition your_partition配置里nodes: 16, tasks_per_node: 8是官方复现规模(128 卡,单卡 batch 24,全局 batch 3072,90K 步)。本地验证时改成nodes: 1, tasks_per_node: 1,换一份小 CSV 即可先跑通。
预训练产出的jepa-latest.pth.tar直接用于冻结评测:
python -m evals.main \ --fname configs/evals/vitl16_k400_16x8x3.yaml \ --devices cuda:0 cuda:1把评测配置里pretrain.folder指向预训练目录、pretrain.checkpoint设为jepa-latest.pth.tar。整条链路:
二、🔍 原理拆解:为什么这套设计有效
先打个比方:传统重建式方法(VAE、像素级 masked reconstruction)相当于让学生逐字默写原文,得分靠背细节;V-JEPA 只考「遮住一段,说出这段话讲什么」,答案在特征空间比对,不还原一个像素。
训练循环(见 app/vjepa/train.py)里实际有三份网络:
| 角色 | 说明 |
|---|---|
| encoder | 只看可见区域(masks_enc),输出上下文特征 |
| target encoder | encoder 的 EMA 副本,动量 0.998→1.0,产出掩码区域的预测目标 |
| predictor | 轻量 ViT(pred_depth: 12、pred_embed_dim: 384),在潜空间预测被掩特征 |
损失是 L1 距离(loss_exp: 1.0),且目标特征先做 layer norm 再取掩码,防止特征幅值塌缩。predictor 只有 12 层,远小于编码器,预测本身几乎不增加计算负担。
最能体现设计意图的是 configs/pretrain/vitl16.yaml 的mask:段,配合 src/masks/multiblock3d.py 生成多尺度时空块掩码:
mask: - num_blocks: 8 # 8个小块,上下文信息充裕 spatial_scale: [0.15, 0.15] temporal_scale: [1.0, 1.0] # 覆盖全部16帧 - num_blocks: 2 # 2个大块,上下文只剩15%左右 spatial_scale: [0.7, 0.7] temporal_scale: [1.0, 1.0]每个 step 随机抽两组掩码:一组「多上下文猜小块」,一组「少上下文猜大块」。同一批数据被迫同时学会局部细节和全局结构,表征在不同语义粒度上更稳。掩码还受aspect_ratio(默认 0.75~1.5)约束,长宽比随机采样,避免只学会遮某一种形状。
三、🎬 场景实战:冻结骨干的三个落地姿势
场景一:视频动作识别(K400 / SSv2)
痛点一句话:新动作类别标注样本难攒,监督模型每加一个类别都要重训骨干。
落地流程(以 K400 为例,配置 configs/evals/vitl16_k400_16x8x3.yaml):
- 准备 K400 的 train/val 两份 CSV(此处标签列填真实类别号)
- 改
data.dataset_train/data.dataset_val与pretrain.folder python -m evals.main --fname configs/evals/vitl16_k400_16x8x3.yaml --devices cuda:0
官方 probe 成绩(骨干完全冻结,只训 src/models/attentive_pooler.py 的AttentiveClassifier,深度 1 层):
| 数据集 | ViT-L/16 224 | ViT-H/16 224 | ViT-H/16 384 |
|---|---|---|---|
| K400 (16x8x3) | 80.8 | 82.0 | 81.9 |
| SSv2 (16x2x3) | 69.5 | 71.4 | 72.2 |
配置里的num_segments: 8、num_views_per_segment: 3、frames_per_clip: 16、frame_step: 4就是「16x8x3」的含义:每段 16 帧、8 个时间段、每段 3 个空间视角,attend_across_segments: true让 probe 跨段聚合。20 个 epoch、lr 1e-3 即可收敛。
场景二:视频模型直接做图像任务
痛点一句话:视频预训练成本高,担心学出的表征只适配视频、图像任务白搭。
V-JEPA 的冻结特征在纯图像任务上同样直接可用,连数据格式都不用改——标准 PyTorch ImageFolder(train/val 下按类分子目录),由 src/datasets/image_dataset.py 加载。换一份配置就能切任务:configs/evals/下vitl16_in1k.yaml、vitl16_places.yaml、vitl16_inat.yaml与视频评测配置一一对应。
| 图像任务 | ViT-L/16 224 | ViT-H/16 224 | ViT-H/16 384 |
|---|---|---|---|
| ImageNet-1K | 74.8 | 75.9 | 77.4 |
| Places205 | 60.3 | 61.7 | 62.8 |
| iNat21 | 67.8 | 67.9 | 72.6 |
注意 iNat21 从 224 到 384 涨了 4.7 个点,是三个任务里最大的单项收益——自然场景图像更吃空间细节,分辨率红利最明显。
场景三:用自己的视频数据从零预训练
痛点一句话:私有领域数据(产线、监控、特定行业录像)找不到合适的公开模型,而标注又做不起。
这正是仓库的主用途:configs/pretrain/ 下三份配置对应三种规格。
复现成本参考(README Model Zoo 口径):
| 规格 | iters | 全局 batch | 数据 |
|---|---|---|---|
| ViT-L/16 224 | 90K | 3072 | VideoMix2M |
| ViT-H/16 224 | 90K | 3072 | VideoMix2M |
| ViT-H/16 384 | 90K | 2400 | VideoMix2M |
自数据小规模起步时,把nodes/tasks_per_node/batch_size调小即可,观察指标看日志 CSV 里的loss-jepa列(每步由 src/utils/logging.py 的CSVLogger落盘)。
四、⚙️ 进阶调优:参数、精度与速度
4.1 训练超参怎么读
optimization: epochs: 300 warmup: 40 start_lr: 0.0002 lr: 0.000625 final_lr: 1.0e-06 clip_grad: 10.0 weight_decay: 0.04 final_weight_decay: 0.4 ema: [0.998, 1.0]几个不直观的点:
- 学习率与权重衰减各走一条余弦:
WarmupCosineSchedule与CosineWDSchedule(src/utils/schedulers.py),且 weight decay 是升温到 0.4 收尾(final_weight_decay),不是降到 0 - 梯度裁剪只在 warmup 结束后生效(train.py 里
if (epoch > warmup) and (clip_grad is not None)),前 40 个 epoch 靠start_lr: 0.0002的小起点稳住 - EMA 动量从 0.998 线性升到 1.0:太早到 1.0,目标编码器与 encoder 完全同步,预测目标不断漂移;太小的话目标更新过慢,任务变简单
4.2 精度:上 384 分辨率
data: crop_size: 384 batch_size: 10 # 224配置是24,384降到10官方 384 配置 configs/pretrain/vith16_384.yaml 用 30 节点。评测侧同理,iNat21 384 下 72.6 为全表最高。显存不够时优先确认下面两项已开启,再降batch_size。
4.3 速度:精度、IO 两条线
meta: use_sdpa: true # 缩放点积注意力 dtype: bfloat16 # 混合精度- 数据侧:
num_workers: 12配合集群端cpus_per_task=12;decode_one_clip: true只解码需要的帧;pin_mem: true减少 H2D 拷贝 - 诊断:每步 CSV 日志同时记录
gpu-time(ms)与wall-time(ms),wall 远大于 gpu 就是 IO 瓶颈;src/utils/monitoring.py 另有资源监控线程可开 - 长视频素材多的场景,可用
filter_short_videos/clip_duration控制采样窗口,减少无效解码
五、🛡️ 避坑指南:高频故障排查
1. 症状:配置加载成功,一进入数据循环就崩可能原因:README 明确要求启动前替换配置里的路径,/your_path_to_...占位符还在。 解法:grep -rn "your_path" configs/全量检查;CSV 里必须是绝对路径,「路径 标签」两列空格分隔,别多逗号(它是按空格解析的)。
2. 症状:GPU 利用率锯齿波动,wall time 远大于 gpu time可能原因:视频解码瓶颈,worker 数与 CPU 配额不匹配。 解法:对照 CSV 日志里 gpu/wall 两列比值判断;num_workers与cpus_per_task对齐(默认都是 12);确认decode_one_clip: true没被关掉。
3. 症状:OOM 直接退出可能原因:分辨率升级后batch_size没跟着降(官方 384 配置是 10,224 是 24),或dtype写成了 float32。 解法:先开bfloat16 + use_sdpa,再降batch_size或crop_size;集群端 CPU 侧内存默认slurm_mem_per_gpu='55G'(见 app/main_distributed.py),视频数据大时注意调高。
4. 症状:loss 变 NaN,或断点续训后参数没恢复可能原因:warmup 期学习率过大(此阶段无梯度裁剪);或评测时checkpoint_key与 checkpoint 内键不匹配(评测默认读target_encoder,预训练 checkpoint 同时存encoder和target_encoder)。 解法:学习率组合别乱改,跟随官方start_lr/lr/final_lr/clip_grad;续训日志确认loaded ... from epoch一行,加载失败时代码会静默回退到从头开始,务必肉眼核对。
5. 症状:多卡/集群提交报错,设备号冲突可能原因:CUDA_VISIBLE_DEVICES未按进程隔离。单机 app/main.py 会按 rank 自动设置;app/vjepa/train.py 顶部注释明确警告:非 SLURM 集群必须保证每个进程只看到 1 张卡(代码默认读SLURM_LOCALID)。 解法:坚持用官方入口起任务,不要自行套 torchrun;--partition换成集群真实存在的分区名。
六、📌 小结与延伸
V-JEPA 的三根支柱是潜空间特征预测、EMA 目标编码器、多尺度时空掩码,标注用量为 0。冻结骨干加一层 attentive probe,K400 拿到 82.0% top-1,且同一套表征直接通吃图像分类。想动手就从 README.md 的 Setup 节开始,核心资料:预训练配置 configs/pretrain/、评测配置 configs/evals/、模型定义 src/models/、掩码生成 src/masks/、训练循环 app/vjepa/train.py。
【免费下载链接】jepaPyTorch code and models for V-JEPA self-supervised learning from video.项目地址: https://gitcode.com/GitHub_Trending/je/jepa
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考