AsianPlayer's picture
Add VLAlert code
1e05592 verified
Raw
History Blame Contribute Delete
4.57 kB
#!/usr/bin/env python3
"""
Pretrain V2 β€” Path C configuration
====================================
Stage-A : BDD100K β†’ calibrated risk vocabulary (risk 1-2/5, no binary crash bias)
Stage-B : DADA-2000 + NEXAR β†’ TTA-labeled 2s windows (matches SFT inference)
"""
from dataclasses import dataclass, field
from typing import List, Optional
# ── Absolute paths ────────────────────────────────────────────────────────────
MODEL_PATH = "PROJECT_ROOT/models/Qwen2.5-VL-3B-Instruct"
BDD100K_IMAGES_DIR = "PROJECT_ROOT/BDD-100K/bdd100k/images/100k"
BDD100K_LABELS_DIR = "PROJECT_ROOT/BDD-100K/bdd100k/labels/100k"
NEXAR_DATASET_DIR = "PROJECT_ROOT/NEXAR_COLLISION/dataset"
DADA_DATASET_DIR = "PROJECT_ROOT/DADA-2000"
DATA_OUTPUT_DIR = "PROJECT_ROOT/data/pretrain_v2"
CKPT_BASE_DIR = "PROJECT_ROOT/checkpoints/pretrain_v2"
STAGE_A_CKPT_DIR = f"{CKPT_BASE_DIR}/stage_a"
STAGE_B_CKPT_DIR = f"{CKPT_BASE_DIR}/stage_b"
# ── Generated data files ──────────────────────────────────────────────────────
STAGE_A_TRAIN_JSON = f"{DATA_OUTPUT_DIR}/stage_a_train.json"
STAGE_A_VAL_JSON = f"{DATA_OUTPUT_DIR}/stage_a_val.json"
STAGE_B_TRAIN_JSON = f"{DATA_OUTPUT_DIR}/stage_b_train.json"
STAGE_B_VAL_JSON = f"{DATA_OUTPUT_DIR}/stage_b_val.json"
# ── TTA clipping (matches SFT) ────────────────────────────────────────────────
TTA_MIN = 0.1
TTA_MAX = 10.0
def tta_to_risk(tta_s: float) -> int:
"""Map TTA in seconds to risk level 1-5."""
if tta_s < 1.0:
return 5
if tta_s < 2.0:
return 4
if tta_s < 4.0:
return 3
if tta_s < 6.0:
return 2
return 1
# ── Data preparation config ───────────────────────────────────────────────────
@dataclass
class DataPrepConfig:
# Stage-A BDD100K
stage_a_max_per_task: int = 25_000 # 25k Γ— 3 tasks = 75k training samples
stage_a_val_ratio: float = 0.05
# Stage-B TTA windows
tta_deltas: List[float] = field(
default_factory=lambda: [0.5, 1.0, 1.5, 2.0, 3.0, 4.5, 6.0]
)
window_duration_s: float = 2.0 # 2s window β†’ 40 frames at 20fps
n_frames_per_window: int = 8 # evenly sampled from 2s window
dada_conservative_shift_s: float = 1.0 # paper Β§4.4: DADA annotations conservative
stage_b_val_ratio: float = 0.10
seed: int = 42
# ── LoRA config ───────────────────────────────────────────────────────────────
@dataclass
class LoraConfig:
r: int = 32
alpha: int = 32
dropout: float = 0.05
target_modules: List[str] = field(default_factory=lambda: [
"q_proj", "v_proj", "k_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",
])
# ── Training config (shared, override per stage) ──────────────────────────────
@dataclass
class TrainConfig:
# Model
model_path: str = MODEL_PATH
lora: LoraConfig = field(default_factory=LoraConfig)
# Processor pixel budgets. Stage-A (single image): keep default.
# Stage-B (8 frames): reduce to fit within GPU memory.
# 128Γ—28Γ—28=100352 px/frame β†’ ~120 tokens/frame Γ— 8 frames β‰ˆ 960 image tokens
max_pixels_single: int = 768 * 28 * 28 # Stage-A: one image, can afford high res
max_pixels_sequence: int = 128 * 28 * 28 # Stage-B: 8 frames, must be small
# Loop
num_epochs: int = 1
batch_size: int = 1
gradient_accumulation_steps: int = 8
learning_rate: float = 2e-5
weight_decay: float = 0.01
warmup_ratio: float = 0.05
max_grad_norm: float = 1.0
# Logging / saving
logging_steps: int = 20
eval_steps: int = 500
save_steps: int = 500
save_total_limit: int = 2
# AMP
bf16: bool = True
# Wandb
use_wandb: bool = True
wandb_project: str = "lkalert-pretrain-v2"
wandb_run_name: Optional[str] = None
# Paths (set by train_stage_*.py)
output_dir: str = CKPT_BASE_DIR
pretrained_lora_path: Optional[str] = None # Stage-B: path to Stage-A best_model