SamChen567's picture
Add model card
c3b18fc verified
|
Raw History Blame Contribute Delete
4.91 kB
metadata
library_name: transformers
base_model: DAMO-NLP-SG/VideoLLaMA3-7B
tags:
  - video
  - token-compression
  - videollama3

phase1_qbase_internvid (native-res, video-only, 2 epochs)

Phase 1 of the qbase video-token compressor curriculum: a learned-query compressor ("qbase") inserted between the frozen SigLIP-NaViT vision encoder and the frozen Qwen2-7B LLM of VideoLLaMA3-7B, trained with caption cross-entropy.

This repo was re-used. The repo name previously referred to an older Phase-1 run (16384-token video budget, 40 % still images, 3 epochs / 3,441 steps); no weights from that run were ever uploaded here. Everything in this repo is the run described below.

This checkpoint needs the custom code in the training repository (videollama3/model, Videollama3Qwen2ForCausalLM with token_compressor); it does not load with stock transformers alone.

What is trained

module status
vision encoder (SigLIP-NaViT) frozen
token_compressor (qbase, 170M) trained
mm_projector (mlp2x_gelu, 17M) trained
<|compression_start|> / <|compression_end|> embedding rows trained (all other rows frozen)
LLM (Qwen2-7B) + lm_head frozen

Warm start: SamChen567/compressor_pretrain_video_norm (qbase + projector + the two embedding rows).

Compressor

  • transformer_decoder_flat: 8 layers, 8 heads, hidden 1152, K = 64 learned queries (+ sin/cos position encoding); cross-attention onto the segment's encoder tokens with (t, h, w) RoPE.
  • Adaptive segmentation (non-learned): N = ⌊T/4βŒ‹ + 1 segments per video, a forced cut every 8 frames, remaining cuts at the largest consecutive-frame cosine distance of the per-frame mean encoder feature. Each segment is 1–8 frames. Deterministic top-k (segment_sample_tau = 0).
  • Option A (match_encoder_scale): output rescaled to the encoder tokens' per-dim mean/std, then a learnable per-channel Ξ³/Ξ².
  • Option B (distr_loss_weight = 0.05): CORAL-style distribution-match auxiliary loss (see the note on its effective weight below).

Input layout seen by the LLM

Each segment carries its own time range (segment_time_marks = True); the per-frame Time X.0s: text of the uncompressed template is removed:

<|im_start|>user
Time:0s-3s:<|compression_start|>[64]<|compression_end|>Time:4s-4s:<|compression_start|>[64]<|compression_end|> ... 
{prompt}<|im_end|>
<|im_start|>assistant
{caption}<|im_end|>

Seconds are integers (first / last frame of the segment). Example: a 120 s clip at 1 fps β†’ 31 segments β†’ 1,984 compressed tokens (vs. 35,880 uncompressed at 640Γ—360). Checkpoints trained before 2026-10-12 used one whole-video range instead; build the layout from this checkpoint's config.json.

Data

  • InternVid clips < 180 s, 264,186 samples, video only (no still images).
  • Captions re-generated by Qwen3-VL-8B-Instruct at 1 fps, native resolution, with several prompt styles (baseline_default, scene_shift, motion_scene, ...).
  • One turn per sample: <video>\n{prompt} β†’ caption. Loss on the assistant caption only.

Vision geometry

  • fps = 1, max_frames = 180.
  • Native resolution: per-video budget 53,820 merged tokens (180 Γ— 299), per-frame cap 2048, per-frame floor 64. 640Γ—360 β†’ 299 tokens/frame (patch 14, merge 2).

Training

epochs / steps 2 / 1,376
global batch 384 (2 per device Γ— 8 GPUs Γ— 24 grad-acc, flattened B = 1 sequences)
LR qbase 2e-5, projector 5e-6; 10 % warmup, cosine; weight decay 0
precision / parallel bf16, DeepSpeed ZeRO-1, gradient checkpointing
wall time 11.5 h

The exact launcher is included as launcher.sh (env overrides used for this run: EPOCHS=2 COMPRESSOR_LR=2e-5 PER_DEVICE_BATCH=2, data anno_data/internvid_qwen3vl_lt180.json). The full loss curve is in trainer_state.json.

Loss

steps logged loss β‰ˆ per-token CE (Γ—8, see note)
1–25 0.2312 1.85
664–688 (end of epoch 1) 0.1790 1.43
689–713 (start of epoch 2) 0.1779 1.42
1352–1376 (end) 0.1733 1.39

No NaN, no skipped samples; grad norm stayed in 0.15–0.33. These are training losses only β€” no held-out evaluation is reported here.

Notes on loss scaling (known quirk of the training code)

  • The custom compute_loss divides the CE sum by the token count gathered across all 8 GPUs but does not multiply back by the number of processes, so the logged loss is β‰ˆ per-token CE / 8. AdamW is nearly scale-invariant, so this mostly affects the readout; with these small gradients max_grad_norm = 1.0 never clips.
  • The Option-B term is divided only by grad-accum steps, not by 8, so relative to CE its effective weight is β‰ˆ 0.05 Γ— 8 = 0.4, not the configured 0.05. Earlier Phase-1/2 runs from the same code share this behaviour.