Add multi-GPU Ego4D local feature extraction without symlinks

This commit is contained in:
Xin Wang
2026-08-28 01:01:25 +08:00
parent 9bd204b468
commit 5fd285e369
8 changed files with 552 additions and 16 deletions
+69 -1
View File
@@ -50,6 +50,9 @@ LOCAL_ARGS=(
```
原始输入应存在:`v1/clips/<uid>.mp4`、`v1/annotations/av_train.json` 和 `av_val.json`。
全局特征既支持 `<feature-root>/<uid>.pt`,也直接支持原批量提取器的
`<feature-root>/train/<uid>.pt`、`<feature-root>/test/<uid>.pt`;无需复制或建立软链接。
提取、训练、推理使用同一个路径解析器;同一 UID 在这几个位置存在多份文件会报错,避免误读旧特征。
这里 `av_val.json` 是原 AVD 标注的文件名,不意味着把它直接当作本实验的 test 划分;
train/test 始终按 EgoSpeak manifest。非标准导出路径可加 `--ego4d-annotations <path1> <path2>`。
局部编码器支持现有 Transformers 4.57.6,也支持 4.52.3;同一次实验所有 clips 应统一版本。
@@ -117,6 +120,70 @@ checkpoint 的 ID 是用户声明,不是权重文件校验和:不要在同
索引是**先按 split 过滤,再按 manifest 顺序的 1-based 闭区间**;不传 split 时保留整个文件的行顺序。
如果自行在多卡不同终端运行,必须选择互不重叠的区间和同一套编码器配置;默认不启动后台任务。
### L20 机器:8 卡并行提取,不使用软链接
下面使用已经检查过框的原始视频,以及原 8s 全局特征目录。不要再传旧的占位符 `LOCAL_ARGS`,
不要带 `--preview-only`、`--preview-with-boxes` 或 `--max-steps`。新入口会自动添加校验后续跑。
```bash
cd /data1/yfzx/wangx/Code/icassp2027-experiment
MULTIGPU_ARGS=(
--gpus 0 1 2 3 4 5 6 7
--cpu-threads 4
--data-root /data1/yfzx/wangx/Datasets/ego4d
--manifest /data1/yfzx/wangx/Datasets/ego4d/ego4d_egospeak.tsv
--feature-root /data1/yfzx/wangx/Datasets/ego4d/omni_features/open_stream_2fps_8s_decord
--target-root /data1/yfzx/wangx/Datasets/ego4d/ego4d_target_frame
--output-root /data1/yfzx/wangx/Datasets/ego4d/omni_features/local_qwen_1s
--model-id /data1/yfzx/wangx/Models/Qwen2.5-Omni-3B
--dtype bfloat16 --flash-attention-2
--video-fps 2 --visual-window-seconds 1 --audio-window-seconds 1
--decoder-backend decord --decoder-threads 1
--log-root logs/ego4d_local_8gpu
)
# 只检查路径和分片,不加载 Qwen、启动 GPU 任务或写日志。
python extract_ego4d_local_multigpu.py "${MULTIGPU_ARGS[@]}" --dry-run
# 确认分片和路径后,前台管理 8 个独立 worker。
python extract_ego4d_local_multigpu.py "${MULTIGPU_ARGS[@]}"
```
默认 433 clips 分配为 55/54/54/54/54/54/54/54,按 manifest 顺序轮转,每个 UID 只属于一个 worker。
每个 worker 用 `CUDA_VISIBLE_DEVICES=<指定卡号>` 隔离到一张卡,内部 `--device cuda:0`;
会覆盖父 shell 遗留的 GPU mask。GPU 编号必须是当前容器暴露的卡,而不是另一个容器的编号。
这不是 DDP;每张卡独立处理 clips,不需要 GPU 间同步。全量数据默认每个 worker 至多加载一次编码器。
如使用 `--limit`,少于 GPU 数量时只启动有任务的卡。
主进程打印每卡状态,详细的逐帧/逐 state 进度位于启动时打印的
`logs/ego4d_local_8gpu/<时间_PID>/gpu0.log` 至 `gpu7.log`。每次运行另建日志目录,不覆盖旧日志;
同目录的 `launch_plan.json` 保存每卡 UID 和命令。可在另一个终端查看指定卡:
```bash
tail -f logs/ego4d_local_8gpu/<本次时间_PID>/gpu0.log
```
不用 `nohup` 或 shell 的 `&`,主命令会一直等待;Ctrl+C 或一个 worker 失败时,会停止本次启动的其他
worker 及其进程组,不杀无关训练。已完成的 `.pt` 保留,重跑同一命令会校验后跳过;
失败时先读对应日志。不要同时另开同输出根的重复提取任务。
最终输出是实体文件 `local_qwen_1s/<uid>.pt`,每个文件同时含 A/V,不需要第二个音频任务。
无框帧仍保留在 5Hz 特征/标签网格中,不能按预览筛选删除。
8 workers 也会增加 CPU、主机 RAM、磁盘 I/O 和标注 JSON 的解析开销;不要预设能达到 8 倍速度。
主机内存不足时改为 `--gpus 0 1 2 3` 并重跑,完成的文件仍可复用;不同次分片也不会改写已完成特征。
提取完成后,原训练入口也直接用同一个原始全局特征根,无需 flat 索引:
```bash
CUDA_VISIBLE_DEVICES=0 OMP_NUM_THREADS=4 MKL_NUM_THREADS=4 OPENBLAS_NUM_THREADS=4 \
python run_ego4d_local_baselines.py \
--data-root /data1/yfzx/wangx/Datasets/ego4d \
--feature-root /data1/yfzx/wangx/Datasets/ego4d/omni_features/open_stream_2fps_8s_decord \
--local-feature-root /data1/yfzx/wangx/Datasets/ego4d/omni_features/local_qwen_1s \
--seeds 0 --dry-run
```
## 4. 跑 seed0 四组
```bash
@@ -180,9 +247,10 @@ python summarize_local_baselines.py \
## 回归测试
```bash
python -m unittest -q test_easycom_head_objectives test_local_turn_features test_ego4d_local_workflow
python -m unittest -q test_easycom_head_objectives test_local_turn_features test_ego4d_local_workflow test_ego4d_local_multigpu
```
CPU 回归包括 manifest 顺序/防交叉重复、完整批量提取的模型复用、断点文件校验、
单层/多层全局特征、测试集输入预检,以及合成 Ego4D 上四组各 4 epochs 的训练/推理与增量汇总。
另测试原 train/test 目录、433 clips 的 8 卡完整互斥分片、GPU mask、独立日志、失败/中断时清理自有进程。
真实 Ego4D 像素、提供框和 3B/L20 提取仍需按上面的 preview/smoke 步骤验证。