Modular runtime for NVIDIA LocateAnything-3B — a Vision-Language Grounding model that emits bounding boxes via Parallel Box Decoding (PBD). This repo refactors the original Colab notebook into a navigable Python package: ONNX export, TensorRT engine build, an orchestrator that mirrors the canonical generate(), and image/video inference pipelines.
pixel_values (1,3,H,W) input_ids (1,S)
│ │
┌─────────────────▼──────────────────┐ │
│ MoonViT-SO-400M (vision engine) │ │
│ patch=14 · 27L · d=1152 · 16H │ │
│ 2-D RoPE (real) │ │
│ flash_attn → SDPA + block mask │ │
└─────────────────┬──────────────────┘ │
│ (L_post, 4608) │
┌─────────────────▼──────────────────┐ │
│ MLP projector (LN→Lin→GELU→Lin) │ │
└─────────────────┬──────────────────┘ │
│ scatter @image_token_index │
▼ ▼
┌──────────────────────────────────────────────────┐
│ Qwen2.5-3B-Instruct LLM (prefill + decode) │
│ 36L · d2048 · GQA 16/2 · vocab 152681 · PBD │
└──────────────────┬───────────────────────────────┘
│ logits (1, K, V)
▼
┌──────────────────────────────────────────────┐
│ PBD orchestrator (Python) │
│ MTP-fast │ MTP+AR hybrid │ pure AR slow │
│ parse <box><x1><y1><x2><y2></box> │
└──────────────────────────────────────────────┘
git clone https://github.com/deanofthewebb/lrai_locate_anything
cd lrai_locate_anything
pip install -e .
from lrai_locate_anything import LocateAnythingRunner
runner = LocateAnythingRunner.from_pretrained(
model_id='nvidia/LocateAnything-3B',
workdir='/content/locany',
auto_export=True, # exports ONNX + builds TRT engines on first run
)
boxes = runner.detect(
image='cats.jpg',
prompt='Detect all cats. Return bounding boxes.',
)
# Video inference
from lrai_locate_anything.pipelines import run_video
run_video(runner, 'demo.mp4', 'demo_boxed.mp4',
prompt='Detect people and luggage.', max_frames=60)
| Module | Responsibility |
|---|---|
lrai_locate_anything.config | Workdir/env detection, model constants |
lrai_locate_anything.shims | transformers ≥ 4.55 compat shims (DynamicCache, _tied_weights_keys, mark_tied_weights_as_initialized) |
lrai_locate_anything.patches | ONNX-hostile op replacements: sdpa_packed, apply_rope_real, Rope2DReal + the apply-to-live-model helper |
lrai_locate_anything.model_loader | Download from HF, rehydrate config, install shims, load model, apply patches |
lrai_locate_anything.parse | parse_boxes, IoU, python_patch_merger |
lrai_locate_anything.export.vision | VisionForExport (fixed-resolution, baked pos_emb + grid_hws) |
lrai_locate_anything.export.projector | ProjectorForExport |
lrai_locate_anything.export.llm | LLMPrefill / LLMDecode (canonical input_ids + visual_features contract) + export_with_external_data |
lrai_locate_anything.export.int4 | Optional INT4 AWQ via NVIDIA modelopt |
lrai_locate_anything.trt.engine | TRTEngine wrapper around tensorrt.IExecutionContext |
lrai_locate_anything.trt.build | build_engine + per-graph optimization profiles |
lrai_locate_anything.orchestrator | LocateAnythingRunner — the public API; mirrors the canonical generate() with MTP↔AR hybrid |
lrai_locate_anything.pipelines | run_image, run_video, run_compare side-by-side multi-runtime |
lrai_locate_anything.benchmark | bench_text_runtimes, bench_image, bench_video_compare — apples-to-apples latency tables |
lrai_locate_anything.trtllm | Optional TRT-LLM parallel path: install_trtllm, dump_qwen2_lm_only, convert_and_build, TRTLLMRunner |
lrai_locate_anything.trt.plugins | packed_varlen_attn_plugin.cu + BUILD.md — FlashAttention-2 varlen plugin source for >2.5K-resolution vision |
These are documented inline in the source but are worth knowing up-front because they crashed the build many times during the original notebook iteration:
Qwen2Model.forward rejects both input_ids and inputs_embeds (line 1200 of vendored modeling_qwen2.py). The LM wrappers pass input_ids + visual_features + image_token_index; vision features get scattered internally via image_processing().(ENG_IMG_W, ENG_IMG_H) = (grid_w*14, grid_h*14) before the processor sees them, AND processor.image_processor.min_pixels = max_pixels = ENG_IMG_W * ENG_IMG_H must be set so the processor's smart_resize doesn't undo the resize.flash_attn_varlen_func returns (L, H, D) — the canonical caller does .flatten(start_dim=-2). Our sdpa_packed replacement bakes that flatten into the return value.apply_rope unsqueezes freqs_cis at dim −2 so (L, head_dim/2) broadcasts against (L, num_heads, head_dim/2). The real-valued replacement does the same.input_names exactly. build_serialized_network returns None silently on mismatch with no log entry at any verbosity level.DequantizeLinear rejects (kBLOCKED requires kINT4). Use modelopt.onnx.quantization.quantize_static or TRT-LLM for real INT4 deployment.The pip install fetches Python-side deps. NVIDIA stack (TensorRT, cuda-python, optionally modelopt, optionally tensorrt-llm) is installed on first import via lrai_locate_anything.config.ensure_nvidia_stack() — torch-version-aware so the right wheels are pulled.
GPU requirements:
| Notebook | Purpose |
|---|---|
docs/lrai_locate_anything_demo.ipynb | The one-click demo. ~10 cells: install package, load model, run image/video, optional benchmark, optional TRT-LLM. Use this. |
docs/LocateAnything_3B_TensorRT.ipynb | The original 60-cell development notebook, preserved for reference (every iteration log + audit trail lives in this file). |
from lrai_locate_anything.trtllm import install_trtllm, dump_qwen2_lm_only, convert_and_build, TRTLLMRunner
if install_trtllm():
qwen_dir = dump_qwen2_lm_only(runner.model, runner.tokenizer, runner.config)
engine_dir = convert_and_build(qwen_dir)
trtllm = TRTLLMRunner(engine_dir, runner.tokenizer)
print(trtllm.generate_text('Detect cats: ', max_new_tokens=64))
The install_trtllm() helper probes torch's version and picks a TRT-LLM wheel that matches the libtorch ABI. AR-only at the moment — porting PBD/MTP into TRT-LLM's speculative-decoding hooks is a separate ~200 LOC effort.
from lrai_locate_anything.benchmark import bench_text_runtimes, print_text_table, bench_video_compare
# Text-only AR latency table across PyTorch / Plain TRT / TRT-LLM
results = bench_text_runtimes(runner, trtllm_runner=trtllm)
print_text_table(results)
# Side-by-side video panels (TRT+MTP vs TRT-AR vs PyTorch) with cross-runtime IoU
metrics = bench_video_compare(runner, 'luggage.mp4', 'compare.mp4',
prompt='Detect roller bags and shoulder bags.', max_frames=30)
For inference at >2.5 K image resolution, the SDPA fallback's O(L²) mask materialisation dominates wall-clock. lrai_locate_anything/trt/plugins/packed_varlen_attn_plugin.cu is a TensorRT 10 plugin that wraps FlashAttention-2's flash_attn_varlen_fwd; build + load instructions are in BUILD.md.
MIT for this wrapper. The underlying model is nvidia/LocateAnything-3B (NVIDIA license — non-commercial); MoonViT-SO-400M (MIT); Qwen2.5-3B-Instruct (Qwen Research License).
109 commits
Python
95.4%
Shell
3.5%
Cuda
1.1%
Modular runtime for NVIDIA LocateAnything-3B — a Vision-Language Grounding model that emits bounding boxes via Parallel Box Decoding (PBD). This repo refactors the original Colab notebook into a navigable Python package: ONNX export, TensorRT engine build, an orchestrator that mirrors the canonical generate(), and image/video inference pipelines.
pixel_values (1,3,H,W) input_ids (1,S)
│ │
┌─────────────────▼──────────────────┐ │
│ MoonViT-SO-400M (vision engine) │ │
│ patch=14 · 27L · d=1152 · 16H │ │
│ 2-D RoPE (real) │ │
│ flash_attn → SDPA + block mask │ │
└─────────────────┬──────────────────┘ │
│ (L_post, 4608) │
┌─────────────────▼──────────────────┐ │
│ MLP projector (LN→Lin→GELU→Lin) │ │
└─────────────────┬──────────────────┘ │
│ scatter @image_token_index │
▼ ▼
┌──────────────────────────────────────────────────┐
│ Qwen2.5-3B-Instruct LLM (prefill + decode) │
│ 36L · d2048 · GQA 16/2 · vocab 152681 · PBD │
└──────────────────┬───────────────────────────────┘
│ logits (1, K, V)
▼
┌──────────────────────────────────────────────┐
│ PBD orchestrator (Python) │
│ MTP-fast │ MTP+AR hybrid │ pure AR slow │
│ parse <box><x1><y1><x2><y2></box> │
└──────────────────────────────────────────────┘
git clone https://github.com/deanofthewebb/lrai_locate_anything
cd lrai_locate_anything
pip install -e .
from lrai_locate_anything import LocateAnythingRunner
runner = LocateAnythingRunner.from_pretrained(
model_id='nvidia/LocateAnything-3B',
workdir='/content/locany',
auto_export=True, # exports ONNX + builds TRT engines on first run
)
boxes = runner.detect(
image='cats.jpg',
prompt='Detect all cats. Return bounding boxes.',
)
# Video inference
from lrai_locate_anything.pipelines import run_video
run_video(runner, 'demo.mp4', 'demo_boxed.mp4',
prompt='Detect people and luggage.', max_frames=60)
| Module | Responsibility |
|---|---|
lrai_locate_anything.config | Workdir/env detection, model constants |
lrai_locate_anything.shims | transformers ≥ 4.55 compat shims (DynamicCache, _tied_weights_keys, mark_tied_weights_as_initialized) |
lrai_locate_anything.patches | ONNX-hostile op replacements: sdpa_packed, apply_rope_real, Rope2DReal + the apply-to-live-model helper |
lrai_locate_anything.model_loader | Download from HF, rehydrate config, install shims, load model, apply patches |
lrai_locate_anything.parse | parse_boxes, IoU, python_patch_merger |
lrai_locate_anything.export.vision | VisionForExport (fixed-resolution, baked pos_emb + grid_hws) |
lrai_locate_anything.export.projector | ProjectorForExport |
lrai_locate_anything.export.llm | LLMPrefill / LLMDecode (canonical input_ids + visual_features contract) + export_with_external_data |
lrai_locate_anything.export.int4 | Optional INT4 AWQ via NVIDIA modelopt |
lrai_locate_anything.trt.engine | TRTEngine wrapper around tensorrt.IExecutionContext |
lrai_locate_anything.trt.build | build_engine + per-graph optimization profiles |
lrai_locate_anything.orchestrator | LocateAnythingRunner — the public API; mirrors the canonical generate() with MTP↔AR hybrid |
lrai_locate_anything.pipelines | run_image, run_video, run_compare side-by-side multi-runtime |
lrai_locate_anything.benchmark | bench_text_runtimes, bench_image, bench_video_compare — apples-to-apples latency tables |
lrai_locate_anything.trtllm | Optional TRT-LLM parallel path: install_trtllm, dump_qwen2_lm_only, convert_and_build, TRTLLMRunner |
lrai_locate_anything.trt.plugins | packed_varlen_attn_plugin.cu + BUILD.md — FlashAttention-2 varlen plugin source for >2.5K-resolution vision |
These are documented inline in the source but are worth knowing up-front because they crashed the build many times during the original notebook iteration:
Qwen2Model.forward rejects both input_ids and inputs_embeds (line 1200 of vendored modeling_qwen2.py). The LM wrappers pass input_ids + visual_features + image_token_index; vision features get scattered internally via image_processing().(ENG_IMG_W, ENG_IMG_H) = (grid_w*14, grid_h*14) before the processor sees them, AND processor.image_processor.min_pixels = max_pixels = ENG_IMG_W * ENG_IMG_H must be set so the processor's smart_resize doesn't undo the resize.flash_attn_varlen_func returns (L, H, D) — the canonical caller does .flatten(start_dim=-2). Our sdpa_packed replacement bakes that flatten into the return value.apply_rope unsqueezes freqs_cis at dim −2 so (L, head_dim/2) broadcasts against (L, num_heads, head_dim/2). The real-valued replacement does the same.input_names exactly. build_serialized_network returns None silently on mismatch with no log entry at any verbosity level.DequantizeLinear rejects (kBLOCKED requires kINT4). Use modelopt.onnx.quantization.quantize_static or TRT-LLM for real INT4 deployment.The pip install fetches Python-side deps. NVIDIA stack (TensorRT, cuda-python, optionally modelopt, optionally tensorrt-llm) is installed on first import via lrai_locate_anything.config.ensure_nvidia_stack() — torch-version-aware so the right wheels are pulled.
GPU requirements:
| Notebook | Purpose |
|---|---|
docs/lrai_locate_anything_demo.ipynb | The one-click demo. ~10 cells: install package, load model, run image/video, optional benchmark, optional TRT-LLM. Use this. |
docs/LocateAnything_3B_TensorRT.ipynb | The original 60-cell development notebook, preserved for reference (every iteration log + audit trail lives in this file). |
from lrai_locate_anything.trtllm import install_trtllm, dump_qwen2_lm_only, convert_and_build, TRTLLMRunner
if install_trtllm():
qwen_dir = dump_qwen2_lm_only(runner.model, runner.tokenizer, runner.config)
engine_dir = convert_and_build(qwen_dir)
trtllm = TRTLLMRunner(engine_dir, runner.tokenizer)
print(trtllm.generate_text('Detect cats: ', max_new_tokens=64))
The install_trtllm() helper probes torch's version and picks a TRT-LLM wheel that matches the libtorch ABI. AR-only at the moment — porting PBD/MTP into TRT-LLM's speculative-decoding hooks is a separate ~200 LOC effort.
from lrai_locate_anything.benchmark import bench_text_runtimes, print_text_table, bench_video_compare
# Text-only AR latency table across PyTorch / Plain TRT / TRT-LLM
results = bench_text_runtimes(runner, trtllm_runner=trtllm)
print_text_table(results)
# Side-by-side video panels (TRT+MTP vs TRT-AR vs PyTorch) with cross-runtime IoU
metrics = bench_video_compare(runner, 'luggage.mp4', 'compare.mp4',
prompt='Detect roller bags and shoulder bags.', max_frames=30)
For inference at >2.5 K image resolution, the SDPA fallback's O(L²) mask materialisation dominates wall-clock. lrai_locate_anything/trt/plugins/packed_varlen_attn_plugin.cu is a TensorRT 10 plugin that wraps FlashAttention-2's flash_attn_varlen_fwd; build + load instructions are in BUILD.md.
MIT for this wrapper. The underlying model is nvidia/LocateAnything-3B (NVIDIA license — non-commercial); MoonViT-SO-400M (MIT); Qwen2.5-3B-Instruct (Qwen Research License).
109 commits
Python
95.4%
Shell
3.5%
Cuda
1.1%