VLAlert / tools /run_qwen3_cache_fast.py
AsianPlayer's picture
Add VLAlert code
1e05592 verified
Raw
History Blame Contribute Delete
3.24 kB
"""Run make_cot_belief_cache with patched Qwen3VLVisionPatchEmbed.
Replaces the Conv3d patch projection with an equivalent Linear layer (math
identical, but ~64Γ— faster because of a cuDNN slow-path bug for tiny Conv3d
on bf16). Saves whole-cache time from ~6 days to ~2 hours.
Usage: identical to make_cot_belief_cache, just call this instead.
python tools/run_qwen3_cache_fast.py \\
--ckpt_dir checkpoints/VLA/qwen3vl4b_cot_belief_perframe/best \\
--base_model models/Qwen3-VL-4B-Instruct \\
--split val \\
--out data/belief_cache_perframe_qwen3vl4b/multisrc_val.pt \\
--n_frames 8 --sampling last_biased --source_filter all \\
--batch_size 8 --num_workers 4 --chunk_size 2000
"""
import sys
sys.path.insert(0, ".")
import torch
import torch.nn as nn
from transformers.models.qwen3_vl.modeling_qwen3_vl import Qwen3VLVisionPatchEmbed
# ─── Lazy-replacement: first forward call replaces Conv3d with Linear ─────
_PATCH_APPLIED = {}
def _fast_patch_embed_forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
"""Mathematically equivalent to original Conv3d-based forward, but
routes through nn.Linear (which avoids the cuDNN slow-path bug on tiny
Conv3d inputs)."""
target_dtype = self.proj.weight.dtype
# First call on this instance: convert Conv3d β†’ Linear in place.
if isinstance(self.proj, nn.Conv3d):
conv = self.proj
out_dim = conv.out_channels
in_dim = (conv.in_channels * conv.kernel_size[0]
* conv.kernel_size[1] * conv.kernel_size[2])
# Conv3d weight: (out, in, k_t, k_h, k_w) β†’ flatten last 4 dims
w_flat = conv.weight.detach().reshape(out_dim, in_dim).contiguous()
bias = conv.bias.detach().clone() if conv.bias is not None else None
new_proj = nn.Linear(in_dim, out_dim, bias=bias is not None)
new_proj.weight.data.copy_(w_flat)
if bias is not None:
new_proj.bias.data.copy_(bias)
new_proj.to(device=conv.weight.device, dtype=conv.weight.dtype)
self.proj = new_proj
if id(self) not in _PATCH_APPLIED:
_PATCH_APPLIED[id(self)] = True
print(f"[fast_patch] patched Qwen3VLVisionPatchEmbed @ id={id(self)}: "
f"Conv3d({in_dim}β†’{out_dim}) β†’ Linear({in_dim}β†’{out_dim})",
flush=True)
# Now self.proj is nn.Linear. Input may be (N, 1536) flat or (N, 3, 2, 16, 16).
if hidden_states.dim() > 2 or hidden_states.shape[-1] != self.proj.in_features:
hidden_states = hidden_states.reshape(-1, self.proj.in_features)
hidden_states = hidden_states.to(dtype=target_dtype)
return self.proj(hidden_states)
# Apply class-level patch BEFORE any model is instantiated
Qwen3VLVisionPatchEmbed.forward = _fast_patch_embed_forward
print("[fast_patch] Qwen3VLVisionPatchEmbed.forward replaced "
"(lazy Conv3d β†’ Linear conversion)", flush=True)
# Hand off to the original cache builder ───────────────────────────────────
from training.Policy import make_cot_belief_cache # noqa: E402
if __name__ == "__main__":
sys.exit(make_cot_belief_cache.main())