LocateAnything:基于并行框解码的快速高质量视觉语言定位
LocateAnything: Fast and High-Quality Vision-Language Grounding with Parallel Box Decoding
https://huggingface.co/nvidia/LocateAnything-3B

论文
演示
https://huggingface.co/spaces/nvidia/LocateAnything
代码
https://github.com/NVlabs/Eagle/tree/main/Embodied

英伟达实验室 https://github.com/NVlabs/Eagle
Research at NVIDIA | Advancing the Latest Technology | NVIDIA
LocateAnything 是一个视觉语言模型,专为快速、高质量的视觉定位而设计,能够在企业智能(Enterprise Intelligence)和物理 AI(Physical AI)的多样化场景中实现精确的目标定位、密集检测和基于点的定位。该模型采用通用化设计,支持指代表达定位、多目标检测、GUI 元素定位和文本定位等任务,在复杂和杂乱场景中表现出色。
其核心创新在于并行框解码(Parallel Box Decoding,PBD),它通过单次并行步骤直接预测完整的边界框坐标,而非逐 token 的自回归解码,从而在保持几何一致性的同时提升效率。与以往方法相比,该机制可实现最高 2.5 倍的吞吐量提升。
该模型在大规模多领域数据集(1200 万张图像、1.38 亿以上查询、7.85 亿个边界框)上训练,覆盖自然场景、机器人、自动驾驶、GUI 交互和文档理解等领域。它作为通用多模态感知的基础模型,已被集成到 NVIDIA 前沿的生产级视觉语言模型中,例如 Nemotron 3 Nano Omni,支持定位、GUI 理解以及多模态智能体能力。
LocateAnything 是 Eagle VLM 模型家族的一部分。本次发布的模型仅用于研究与开发。此外,LocateAnything 作为计算机使用(Computer Use)和视觉定位(Visual Grounding)功能的一部分,为 Nemotron 和 Cosmos 做出了贡献。我们特别感谢 Nemotron 和 Cosmos 团队在产品集成方面付出的时间和努力。

LocateAnything is a vision-language model for fast and high-quality visual grounding, enabling precise object localization, dense detection, and point-based localization across diverse domains in both Enterprise Intelligence and Physical AI. The model adopts a generalist design, supporting tasks such as referring expression grounding, multi-object detection, GUI element grounding, and text localization, with strong performance in complex and cluttered scenes.
Its core innovation, Parallel Box Decoding (PBD), predicts complete bounding box coordinates in a single parallel step rather than autoregressive token-by-token decoding, improving efficiency while preserving geometric consistency. This enables up to 2.5× higher throughput compared to prior approaches.
The model is trained on a large-scale multi-domain dataset (12M images, 138M+ queries, 785M bounding boxes) spanning natural scenes, robotics, driving, GUI interaction, and document understanding. It serves as a foundation for generalist multimodal perception and has been integrated into NVIDIA’s frontier production-grade vision-language models, such as Nemotron 3 Nano Omni, supporting grounding, GUI understanding, and multimodal agentic capabilities.
LocateAnything is developed as part of the Eagle VLM model family. This released model is for research and development only. In addition, LocateAnything contributed to Nemotron and Cosmos as part of the Computer Use and Visual Grounding features. We give special thanks the Nemotron and Cosmos Teams for time and efforts in product integration.
--
import re
import torch
from PIL import Image
from transformers import AutoModel, AutoTokenizer, AutoProcessor
class LocateAnythingWorker:
"""Stateful worker that loads the model once and serves perception queries."""
def __init__(self, model_path: str, device: str = "cuda", dtype=torch.bfloat16):
self.device = device
self.dtype = dtype
self.tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
self.processor = AutoProcessor.from_pretrained(model_path, trust_remote_code=True)
self.model = AutoModel.from_pretrained(
model_path,
torch_dtype=dtype,
trust_remote_code=True,
).to(device).eval()
@torch.no_grad()
def predict(
self,
image: Image.Image,
question: str,
generation_mode: str = "hybrid", # "fast" (MTP) | "slow" (NTP/AR) | "hybrid"
max_new_tokens: int = 2048,
temperature: float = 0.7,
verbose: bool = True,
) -> dict:
messages = [
{"role": "user", "content": [
{"type": "image", "image": image},
{"type": "text", "text": question},
]}
]
text = self.processor.py_apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
images, videos = self.processor.process_vision_info(messages)
inputs = self.processor(
text=[text], images=images, videos=videos, return_tensors="pt"
).to(self.device)
pixel_values = inputs["pixel_values"].to(self.dtype)
input_ids = inputs["input_ids"]
image_grid_hws = inputs.get("image_grid_hws", None)
response = self.model.generate(
pixel_values=pixel_values,
input_ids=input_ids,
attention_mask=inputs["attention_mask"],
image_grid_hws=image_grid_hws,
tokenizer=self.tokenizer,
max_new_tokens=max_new_tokens,
use_cache=True,
generation_mode=generation_mode,
temperature=temperature,
do_sample=True,
top_p=0.9,
repetition_penalty=1.1,
verbose=verbose,
)
result = {"answer": response[0] if isinstance(response, tuple) else response}
if isinstance(response, tuple) and len(response) >= 3:
result["history"] = response[1]
result["stats"] = response[2]
return result
# ---- Convenience methods for each task ----
def detect(self, image: Image.Image, categories: list[str], **kwargs) -> dict:
"""Object detection / document layout analysis."""
cats = "</c>".join(categories)
prompt = f"Locate all the instances that matches the following description: {cats}."
return self.predict(image, prompt, **kwargs)
def ground_single(self, image: Image.Image, phrase: str, **kwargs) -> dict:
"""Phrase grounding — single instance."""
prompt = f"Locate a single instance that matches the following description: {phrase}."
return self.predict(image, prompt, **kwargs)
def ground_multi(self, image: Image.Image, phrase: str, **kwargs) -> dict:
"""Phrase grounding — multiple instances."""
prompt = f"Locate all the instances that match the following description: {phrase}."
return self.predict(image, prompt, **kwargs)
def ground_text(self, image: Image.Image, phrase: str, **kwargs) -> dict:
"""Text grounding."""
prompt = f"Please locate the text referred as {phrase}."
return self.predict(image, prompt, **kwargs)
def detect_text(self, image: Image.Image, **kwargs) -> dict:
"""Scene text detection."""
prompt = "Detect all the text in box format."
return self.predict(image, prompt, **kwargs)
def ground_gui(self, image: Image.Image, phrase: str, output_type: str = "box", **kwargs) -> dict:
"""GUI grounding (box or point)."""
if output_type == "point":
prompt = f"Point to: {phrase}."
else:
prompt = f"Locate the region that matches the following description: {phrase}."
return self.predict(image, prompt, **kwargs)
def point(self, image: Image.Image, phrase: str, **kwargs) -> dict:
"""Pointing."""
prompt = f"Point to: {phrase}."
return self.predict(image, prompt, **kwargs)
# ---- Utility: parse model output ----
@staticmethod
def parse_boxes(answer: str, image_width: int, image_height: int) -> list[dict]:
"""Parse model output into pixel-coordinate bounding boxes.
Coordinates in model output are normalized integers in [0, 1000].
"""
boxes = []
for m in re.finditer(r"<box><(\d+)><(\d+)><(\d+)><(\d+)></box>", answer):
x1, y1, x2, y2 = [int(g) for g in m.groups()]
boxes.append({
"x1": x1 / 1000 * image_width,
"y1": y1 / 1000 * image_height,
"x2": x2 / 1000 * image_width,
"y2": y2 / 1000 * image_height,
})
return boxes
@staticmethod
def parse_points(answer: str, image_width: int, image_height: int) -> list[dict]:
"""Parse model output into pixel-coordinate points."""
points = []
for m in re.finditer(r"<box><(\d+)><(\d+)></box>", answer):
x, y = int(m.group(1)), int(m.group(2))
points.append({
"x": x / 1000 * image_width,
"y": y / 1000 * image_height,
})
return points

1万+

被折叠的 条评论
为什么被折叠?



