项目文件夹

文件
wehub-resource-sync 542cfa195c
CI / Frontend build (push) Failing after 9m6s
CI / Plugin validate (push) Failing after 9m27s
CI / Python lint (push) Failing after 16m1s
CI / Tests (push) Successful in 18m0s
Deploy / deploy (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:27 +08:00

4.3 KiB

Training Report — 2026-04-02

Summary

Ran contrastive fine-tuning of Qwen3-VL-Embedding-2B with GradCache + hard negatives. Fixed 3 bugs in the training pipeline, ran ablation experiments on hyperparameters, and completed a 1000-step training run.

Bug Fixes

1. NCCL Deadlock (critical)

prefetched() used a ThreadPoolExecutor for background data loading. Background threads conflicted with NCCL all-reduce, causing random deadlocks in multi-GPU training.

Fix: Removed prefetch, iterate train_loader directly. No performance impact (~8.2s/step before and after).

2. Processor max_pixels Misconfigured

--max-num-visual-tokens default was 1024, and we added code to set processor.image_processor.max_pixels = max_num_visual_tokens * 784. However, the processor's grid alignment means it doesn't strictly enforce this limit: an 875×1024 image produces 3000 tokens regardless of the setting.

The default of 1024 actually degraded image quality slightly (3000 vs 3456 tokens) without achieving precise token control.

Fix: Changed default to 4096. At this value, 875×1024 images produce 3456 tokens (same as processor default), so no quality loss.

3. Retrieval Eval NCCL Timeout

--test-max-pairs defaulted to 0 (unlimited). With large test sets (e.g., 4575 queries × 36430 docs), retrieval eval runs only on rank 0 while other ranks wait at a barrier. This exceeded the 60-minute NCCL timeout.

Fix: Changed --test-max-pairs default from 0 to 500.

1000-Step Training Run

Config: 2×H100, batch_size=16, lr=1e-5, cosine schedule, warmup=20, 5 hard negatives per sample.

Data: 2400 pairs from train_hn.jsonl (1833 with hard negatives).

Checkpoints: output_1000steps/checkpoint-{100..1000}

Step Eval Loss Eval Acc
50 0.613 80.6%
100 0.502 82.5%
200 0.445 82.8%
300 0.428 83.4%
400 0.421 84.4%
500 0.418 83.8%
600 0.414 83.8%
700 0.411 84.4%
800 0.410 84.4%
900 0.406 84.1%
1000 0.407 83.8%

Eval loss converges around step 400–500. Eval acc saturates at ~84.4% (step 400/700/800). Best checkpoint region: step 400–700.

wandb: https://wandb.ai/andylizf-university-of-california-berkeley/wiki-screenshot-training/runs/jswdrobj

Note: No retrieval eval (R@1/R@5) was run — we had no test.jsonl and used --test-eval-steps 0. Eval acc is contrastive accuracy on the validation set, not retrieval recall.

Ablation Experiments (200 steps)

All compared against baseline: batch_size=16, lr=1e-5, temp=0.07, 2×H100.

Experiment Change Eval Loss Eval Acc Verdict
baseline 0.489 82.5% best
bigbatch batch 16→32 0.670 80.0% worse (lr too low for larger batch)
lowlr lr 1e-5→3e-6 0.609 81.3% slightly worse
hightemp temp 0.07→0.15 1.091 78.1% worst

wandb links:

Train Loss Oscillation

Train loss oscillates between 1.5–6.0 throughout training without a clear downward trend. This is expected in contrastive learning with small batches — each step's loss depends heavily on which hard negatives are sampled. Eval loss (averaged over 20 batches) is the stable metric and decreases monotonically.

Increasing batch size did not reduce oscillation (and hurt accuracy, likely because lr wasn't scaled up).

Open Questions

  1. No retrieval eval done — eval acc measures contrastive accuracy, not actual retrieval performance (R@1 etc.). Need to run retrieval eval on checkpoints to confirm real-world improvement.
  2. max_num_visual_tokens doesn't precisely control token count due to processor grid alignment. The parameter is approximate at best.
  3. Data scale — we trained on 2400 pairs. Wang Yichuan is training on 76K+. Results may differ significantly at scale.