Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- approach/ape_stage.py +150 -0
- approach/llm/__init__.py +0 -0
- approach/llm/gpt.py +90 -0
- approach/llm/gpt_polling.py +268 -0
- approach/method.py +732 -0
- approach/method_claude.py +656 -0
- approach/method_fastuse.py +736 -0
- approach/ovod/APE/demo/__init__.py +0 -0
- approach/ovod/APE/demo/pre-requirements.txt +4 -0
- approach/ovod/APE/demo/predictor_lazy.py +429 -0
- approach/ovod/APE/demo/requirements.txt +11 -0
- approach/ovod/GroundingDINO/.gitignore +146 -0
- approach/ovod/GroundingDINO/LICENSE +201 -0
- approach/ovod/GroundingDINO/README.md +367 -0
- approach/ovod/GroundingDINO/gdino.py +23 -0
- approach/ovod/GroundingDINO/requirements.txt +10 -0
- approach/ovod/GroundingDINO/setup.py +208 -0
- approach/ovod/GroundingDINO/test.ipynb +55 -0
- approach/ovod/d-cube/.gitignore +164 -0
- approach/ovod/d-cube/README.md +134 -0
- approach/ovod/d-cube/qa.md +24 -0
- approach/ovod/d-cube/requirements.txt +4 -0
- approach/ovod/d-cube/setup.py +30 -0
- approach/ovod/detectron2/.clang-format +85 -0
- approach/ovod/detectron2/.flake8 +15 -0
- approach/ovod/detectron2/.gitignore +53 -0
- approach/ovod/detectron2/GETTING_STARTED.md +79 -0
- approach/ovod/detectron2/INSTALL.md +261 -0
- approach/ovod/detectron2/LICENSE +202 -0
- approach/ovod/detectron2/MODEL_ZOO.md +1052 -0
- approach/ovod/detectron2/README.md +68 -0
- approach/ovod/detectron2/setup.cfg +26 -0
- approach/ovod/detectron2/setup.py +212 -0
- approach/ovod/gdino.py +23 -0
- approach/pipeline_utils.py +176 -0
- approach/run_ape.py +291 -0
- approach/util/test.py +35 -0
- approach/vlm/LLaVA/.gitignore +29 -0
- approach/vlm/LLaVA/LICENSE +201 -0
- approach/vlm/LLaVA/README.md +366 -0
- approach/vlm/LLaVA/pyproject.toml +39 -0
- approach/vlm/gpt4v/cu_gpt4v.py +25 -0
- approach/vlm/gpt4v/gpt4v.py +148 -0
- configs/model_profiles.yaml +31 -0
- dataset/statistics/app_genre.csv +101 -0
- dataset/statistics/app_tag.csv +101 -0
- dataset/statistics/plot.py +179 -0
- docs/ASSETS.md +59 -0
- docs/ENVIRONMENT.md +93 -0
- docs/MODEL_MANIFEST.md +11 -0
approach/ape_stage.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import string
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
from typing import Callable, Dict, Iterable, List, Mapping, Optional, Tuple
|
| 5 |
+
|
| 6 |
+
from approach.pipeline_utils import (
|
| 7 |
+
enrich_ape_results,
|
| 8 |
+
parse_orienter_image_name,
|
| 9 |
+
resolve_image_path,
|
| 10 |
+
write_json_atomic,
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
InferenceFn = Callable[..., List[dict]]
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def extract_image_id(image_name: str) -> int:
|
| 18 |
+
return parse_orienter_image_name(Path(image_name).name)[2]
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def build_referring_expressions(objects: Mapping[str, object]) -> List[str]:
|
| 22 |
+
translator = str.maketrans("", "", string.punctuation)
|
| 23 |
+
expressions = []
|
| 24 |
+
for name, description in objects.items():
|
| 25 |
+
if isinstance(description, str):
|
| 26 |
+
text = description
|
| 27 |
+
elif isinstance(description, Mapping):
|
| 28 |
+
text = " ".join(str(value) for value in description.values())
|
| 29 |
+
else:
|
| 30 |
+
text = str(description)
|
| 31 |
+
expressions.append(f"{name}: {text.translate(translator)}")
|
| 32 |
+
return expressions
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def _load_existing(output_path: Path) -> List[dict]:
|
| 36 |
+
if not output_path.exists():
|
| 37 |
+
return []
|
| 38 |
+
with output_path.open() as file:
|
| 39 |
+
data = json.load(file)
|
| 40 |
+
if not isinstance(data, list):
|
| 41 |
+
raise ValueError(f"Existing prediction file must contain a list: {output_path}")
|
| 42 |
+
return data
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def _completed_image_ids(results: Iterable[dict]) -> set:
|
| 46 |
+
return {item["image_id"] for item in results if "image_id" in item}
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def _progress_path(output_path: Path) -> Path:
|
| 50 |
+
return output_path.with_name(f"{output_path.stem}.progress.json")
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def _load_progress(output_path: Path) -> set:
|
| 54 |
+
path = _progress_path(output_path)
|
| 55 |
+
if not path.exists():
|
| 56 |
+
return set()
|
| 57 |
+
with path.open() as file:
|
| 58 |
+
data = json.load(file)
|
| 59 |
+
return set(data.get("completed_image_ids", []))
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def _get_question(questions: Mapping[object, Mapping[str, object]], question_id):
|
| 63 |
+
if question_id in questions:
|
| 64 |
+
return questions[question_id]
|
| 65 |
+
question_id_str = str(question_id)
|
| 66 |
+
if question_id_str in questions:
|
| 67 |
+
return questions[question_id_str]
|
| 68 |
+
try:
|
| 69 |
+
question_id_int = int(question_id)
|
| 70 |
+
except (TypeError, ValueError):
|
| 71 |
+
question_id_int = None
|
| 72 |
+
if question_id_int in questions:
|
| 73 |
+
return questions[question_id_int]
|
| 74 |
+
raise KeyError(question_id)
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def run_ape_stage(
|
| 78 |
+
records: Iterable[dict],
|
| 79 |
+
questions: Mapping[object, Mapping[str, object]],
|
| 80 |
+
images_dir,
|
| 81 |
+
output_path,
|
| 82 |
+
inference: InferenceFn,
|
| 83 |
+
inference_kwargs: Optional[Dict[str, object]] = None,
|
| 84 |
+
error_path=None,
|
| 85 |
+
resume: bool = True,
|
| 86 |
+
) -> Tuple[List[dict], List[dict]]:
|
| 87 |
+
output_path = Path(output_path)
|
| 88 |
+
error_path = Path(error_path) if error_path is not None else None
|
| 89 |
+
images_dir = Path(images_dir)
|
| 90 |
+
inference_kwargs = dict(inference_kwargs or {})
|
| 91 |
+
results = _load_existing(output_path) if resume else []
|
| 92 |
+
completed = _completed_image_ids(results)
|
| 93 |
+
if resume:
|
| 94 |
+
completed.update(_load_progress(output_path))
|
| 95 |
+
errors = []
|
| 96 |
+
write_json_atomic(str(output_path), results)
|
| 97 |
+
write_json_atomic(
|
| 98 |
+
str(_progress_path(output_path)),
|
| 99 |
+
{"completed_image_ids": sorted(completed)},
|
| 100 |
+
)
|
| 101 |
+
|
| 102 |
+
for record in records:
|
| 103 |
+
question_id = record["question_id"]
|
| 104 |
+
question = _get_question(questions, question_id)
|
| 105 |
+
image_name = question["image"]
|
| 106 |
+
image_id = extract_image_id(image_name)
|
| 107 |
+
if image_id in completed:
|
| 108 |
+
continue
|
| 109 |
+
|
| 110 |
+
text = record.get("text")
|
| 111 |
+
if not text:
|
| 112 |
+
continue
|
| 113 |
+
objects = text["objects"]
|
| 114 |
+
expressions = build_referring_expressions(objects)
|
| 115 |
+
image_path = resolve_image_path(images_dir, image_name)
|
| 116 |
+
|
| 117 |
+
try:
|
| 118 |
+
ape_results = inference(
|
| 119 |
+
input_path=str(image_path),
|
| 120 |
+
text_prompt=", ".join(expressions),
|
| 121 |
+
**inference_kwargs,
|
| 122 |
+
)
|
| 123 |
+
enriched = enrich_ape_results(ape_results, image_name, extract_image_id)
|
| 124 |
+
results.extend(enriched)
|
| 125 |
+
completed.add(image_id)
|
| 126 |
+
write_json_atomic(str(output_path), results)
|
| 127 |
+
write_json_atomic(
|
| 128 |
+
str(_progress_path(output_path)),
|
| 129 |
+
{"completed_image_ids": sorted(completed)},
|
| 130 |
+
)
|
| 131 |
+
except Exception as exc:
|
| 132 |
+
errors.append(
|
| 133 |
+
{
|
| 134 |
+
"question_id": question_id,
|
| 135 |
+
"image": image_name,
|
| 136 |
+
"error_type": type(exc).__name__,
|
| 137 |
+
"message": str(exc),
|
| 138 |
+
}
|
| 139 |
+
)
|
| 140 |
+
if error_path is not None:
|
| 141 |
+
write_json_atomic(str(error_path), errors)
|
| 142 |
+
|
| 143 |
+
write_json_atomic(str(output_path), results)
|
| 144 |
+
write_json_atomic(
|
| 145 |
+
str(_progress_path(output_path)),
|
| 146 |
+
{"completed_image_ids": sorted(completed)},
|
| 147 |
+
)
|
| 148 |
+
if error_path is not None:
|
| 149 |
+
write_json_atomic(str(error_path), errors)
|
| 150 |
+
return results, errors
|
approach/llm/__init__.py
ADDED
|
File without changes
|
approach/llm/gpt.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import json
|
| 3 |
+
import time
|
| 4 |
+
import requests
|
| 5 |
+
from bs4 import BeautifulSoup
|
| 6 |
+
from approach.config import get_model_profile
|
| 7 |
+
from approach.pipeline_utils import write_json_atomic
|
| 8 |
+
from approach.providers import OpenAICompatibleChatClient
|
| 9 |
+
|
| 10 |
+
DEFAULT_PROFILE = os.environ.get("ORIENT_MODEL_PROFILE", "default")
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def get_steam_app_data(app_id, image_name):
|
| 14 |
+
url = f"https://store.steampowered.com/app/{app_id}"
|
| 15 |
+
|
| 16 |
+
try:
|
| 17 |
+
response = requests.get(url, timeout=30)
|
| 18 |
+
response.raise_for_status() # Raise an HTTPError if the HTTP request returned an unsuccessful status code
|
| 19 |
+
|
| 20 |
+
soup = BeautifulSoup(response.content, "html.parser")
|
| 21 |
+
|
| 22 |
+
app_name = soup.find("div", {"id": "appHubAppName"}).get_text(strip=True)
|
| 23 |
+
short_desc = soup.find("div", class_="game_description_snippet").get_text(strip=True)
|
| 24 |
+
long_desc = soup.find("div", {"id": "game_area_description"}).get_text(strip=True)
|
| 25 |
+
|
| 26 |
+
return app_name, short_desc + " " + long_desc
|
| 27 |
+
except Exception as e:
|
| 28 |
+
print(f"Error fetching app data for app_id {app_id} of image {image_name}. Error: {e}")
|
| 29 |
+
return "", ""
|
| 30 |
+
|
| 31 |
+
def generate_prompt(app_name, app_description, app_current_view):
|
| 32 |
+
return (f"You are a virtual reality game player. Currently, you are playing a game named {app_name} "
|
| 33 |
+
f"with the following description: {app_description}. Now in your field of view, you can see that: {app_current_view}. "
|
| 34 |
+
"Please infer what virtual objects you can see currently based on the current view and the app description.")
|
| 35 |
+
|
| 36 |
+
def infer_object_candidates(
|
| 37 |
+
vlm_question_path,
|
| 38 |
+
vlm_answer_path,
|
| 39 |
+
llm_candidate_path,
|
| 40 |
+
model_profile=DEFAULT_PROFILE,
|
| 41 |
+
):
|
| 42 |
+
profile = get_model_profile(model_profile)
|
| 43 |
+
client = OpenAICompatibleChatClient(profile)
|
| 44 |
+
# Read and process the two jsonl files
|
| 45 |
+
with open(vlm_answer_path, "r") as f_a:
|
| 46 |
+
file_a_data = [json.loads(line) for line in f_a.readlines()]
|
| 47 |
+
|
| 48 |
+
with open(vlm_question_path, "r") as f_b:
|
| 49 |
+
file_b_data = {json.loads(line)["question_id"]: json.loads(line) for line in f_b.readlines()}
|
| 50 |
+
# file_b_dict = {json.loads(line)["question_id"]: json.loads(line)["image"].split("_")[0] for line in f_b.readlines()}
|
| 51 |
+
|
| 52 |
+
results = {}
|
| 53 |
+
|
| 54 |
+
index = 0
|
| 55 |
+
for line_data_a in file_a_data:
|
| 56 |
+
print(index)
|
| 57 |
+
index += 1
|
| 58 |
+
|
| 59 |
+
question_id = line_data_a["question_id"]
|
| 60 |
+
app_current_view = line_data_a["text"]
|
| 61 |
+
|
| 62 |
+
line_data_b = file_b_data.get(question_id, {})
|
| 63 |
+
app_id = line_data_b.get("image", "").split("_")[0]
|
| 64 |
+
# app_id = file_b_dict.get(question_id, "")
|
| 65 |
+
# line_data_b = file_b_dict.get(question_id, {})
|
| 66 |
+
|
| 67 |
+
if app_id:
|
| 68 |
+
app_name, app_description = get_steam_app_data(app_id, line_data_b.get("image", ""))
|
| 69 |
+
message_content = generate_prompt(app_name, app_description, app_current_view)
|
| 70 |
+
try:
|
| 71 |
+
payload = client.build_payload(message_content)
|
| 72 |
+
completion = client.chat_completion(payload)
|
| 73 |
+
content = completion["choices"][0]["message"]["content"].strip()
|
| 74 |
+
inferred_objects = [item.strip() for item in content.split(";") if item.strip()]
|
| 75 |
+
|
| 76 |
+
results[question_id] = {
|
| 77 |
+
"vlm_question": line_data_a,
|
| 78 |
+
"vlm_answer": line_data_b,
|
| 79 |
+
"app_name": app_name,
|
| 80 |
+
"app_description": app_description,
|
| 81 |
+
"app_current_view": app_current_view,
|
| 82 |
+
"inferred_object_candidates": inferred_objects
|
| 83 |
+
}
|
| 84 |
+
except Exception as e:
|
| 85 |
+
print(f"Error generating completion for question_id {question_id}. Error: {e}")
|
| 86 |
+
|
| 87 |
+
time.sleep(20)
|
| 88 |
+
|
| 89 |
+
# Save the results to a json file
|
| 90 |
+
write_json_atomic(llm_candidate_path, results)
|
approach/llm/gpt_polling.py
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import json
|
| 3 |
+
import time
|
| 4 |
+
import requests
|
| 5 |
+
from bs4 import BeautifulSoup
|
| 6 |
+
from approach.config import get_model_profile
|
| 7 |
+
from approach.providers import OpenAICompatibleChatClient
|
| 8 |
+
|
| 9 |
+
DEFAULT_PROFILE = os.environ.get("ORIENT_MODEL_PROFILE", "default")
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def get_steam_app_data(app_id, image_name):
|
| 13 |
+
url = f"https://store.steampowered.com/app/{app_id}"
|
| 14 |
+
|
| 15 |
+
try:
|
| 16 |
+
response = requests.get(url, timeout=30)
|
| 17 |
+
response.raise_for_status()
|
| 18 |
+
|
| 19 |
+
soup = BeautifulSoup(response.content, "html.parser")
|
| 20 |
+
|
| 21 |
+
app_name = soup.find("div", {"id": "appHubAppName"}).get_text(strip=True)
|
| 22 |
+
short_desc = soup.find("div", class_="game_description_snippet").get_text(strip=True)
|
| 23 |
+
long_desc = soup.find("div", {"id": "game_area_description"}).get_text(strip=True)
|
| 24 |
+
|
| 25 |
+
return app_name, short_desc + " " + long_desc
|
| 26 |
+
except Exception as e:
|
| 27 |
+
print(f"Error fetching app data for app_id {app_id} of image {image_name}. Error: {e}")
|
| 28 |
+
return "", ""
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def save_results_to_file(llm_candidate_path, results):
|
| 32 |
+
"""Utility function to save results to a file."""
|
| 33 |
+
with open(llm_candidate_path, "w") as out_file:
|
| 34 |
+
json.dump(results, out_file, indent=4)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def generate_prompt(app_name, app_description, app_current_view, ablation):
|
| 38 |
+
# return (f"You are a virtual reality game player. Currently, you are playing a game named {app_name} "
|
| 39 |
+
# f"with the following description: . Now in your field of view, you can see that: {app_current_view}. "
|
| 40 |
+
# "Please infer what virtual objects you can see currently based on the current view and the app description. Let's think step by step.\n"
|
| 41 |
+
# "List the virtual objects one by one, seperated by semicolons"
|
| 42 |
+
# f"App description: {app_description}")
|
| 43 |
+
|
| 44 |
+
# return f'''
|
| 45 |
+
# ** Context and Task **
|
| 46 |
+
# You are a virtual reality game player. Currently, you are playing a game named {app_name} with the following description. Now in your field of view from the VR headset, you can see that: {app_current_view}. Please infer what virtual objects you can see currently based on the current view and the app description.\n
|
| 47 |
+
# Output the inferred objects one by one, seperated by semicolons, strictly following the format: object1;object2. E.g., "door;desk"\n
|
| 48 |
+
# NO DOT OUTPUT any other content.\n
|
| 49 |
+
|
| 50 |
+
# ** Chain-of-Thought Reasoning Demonstration **
|
| 51 |
+
# (1) For a tree object in a tree-planting game, the users need to pick up and plant the tree, thus the object is interactable.
|
| 52 |
+
# (2) But for a tree object appeard in the background scenery of a fishing-only game, the object is highly likely non-interactable.\n
|
| 53 |
+
|
| 54 |
+
# ** Data **
|
| 55 |
+
# The description of the app:
|
| 56 |
+
# <app_description>.
|
| 57 |
+
# '''
|
| 58 |
+
|
| 59 |
+
# return f'''
|
| 60 |
+
# ** Context and Task **
|
| 61 |
+
# You are a virtual reality game player. Currently, you are playing a game named {app_name} with the following description. Now in your field of view from the VR headset, you can see that: {app_current_view}. Please extract information and infer what virtual objects you can see currently based on the current view and the app description.\n
|
| 62 |
+
# Output the inferred objects one by one, seperated by semicolons, strictly following the format: object1;object2. E.g., "door;desk"\n
|
| 63 |
+
# NO DOT OUTPUT any other content.\n
|
| 64 |
+
|
| 65 |
+
# ** Data **
|
| 66 |
+
# The description of the app:
|
| 67 |
+
# <app_description>.
|
| 68 |
+
# '''
|
| 69 |
+
|
| 70 |
+
if ablation:
|
| 71 |
+
return f'''
|
| 72 |
+
Please extract objects from the following description: {app_current_view}
|
| 73 |
+
Output the extracted objects in JSON format: {{"objects": ["object1", "object2"]}}. E.g., {{"objects": ["door", "desk"]}}\n
|
| 74 |
+
NO DOT OUTPUT any other content besides JSON.\n
|
| 75 |
+
'''
|
| 76 |
+
elif not ablation:
|
| 77 |
+
return f'''
|
| 78 |
+
--- Context and Task ---
|
| 79 |
+
You are a virtual reality game player. Currently, you are playing a game named {app_name} with the following description. Now in your field of view from the VR headset, you can see the current VR scenario: {app_current_view}. Please extract information and infer what virtual objects you can see currently based on the current view and the app description.\n
|
| 80 |
+
|
| 81 |
+
--- Instructions and Demonstrations ---
|
| 82 |
+
(1) If there are multiple similar objects, please output all objects one by one. E.g., if there are several pens on the table, please output several "pen" instead of a single "pens".
|
| 83 |
+
(2) Provide detailed object description with texts on them (if any). For example, for a button or option with text on it (e.g., begin), you need to output "begin button" or "begin option".
|
| 84 |
+
(3) Ignore the virtual objects of user-controlled VR devices, e.g., controllers, hands and gloves, which are near the users in screenshot.
|
| 85 |
+
(4) Format: Output the inferred objects in JSON format: {{"objects": ["object1", "object2"]}}. E.g., {{"objects": ["door", "desk"]}}\n
|
| 86 |
+
NO DOT OUTPUT any other content besides JSON.\n
|
| 87 |
+
|
| 88 |
+
--- Data ---
|
| 89 |
+
The description of the app:
|
| 90 |
+
{app_description}.
|
| 91 |
+
'''
|
| 92 |
+
|
| 93 |
+
def generate_i_prompt(inferred_objects, app_current_view, ablation):
|
| 94 |
+
if ablation:
|
| 95 |
+
return f'''
|
| 96 |
+
For the following objects: {inferred_objects}. Please identify those user-interactable objects in VR games.
|
| 97 |
+
Output the extracted objects in JSON format: {{"objects": ["object1", "object2"]}}. E.g., {{"objects": ["door", "desk"]}}\n
|
| 98 |
+
NO DOT OUTPUT any other content besides JSON.\n
|
| 99 |
+
'''
|
| 100 |
+
elif not ablation:
|
| 101 |
+
return f'''
|
| 102 |
+
--- Context and Task ---
|
| 103 |
+
You are a virtual reality game player. From your previous response, you find that the following objects exist in the screenshot: {inferred_objects}.
|
| 104 |
+
Please perform reasoning to identify the user-interactable objects, with which users can use VR devices like handheld controllers to interact, in the current VR scene screenshot. Please perform reasoning based on the app description and current VR scenario.\n
|
| 105 |
+
|
| 106 |
+
--- Instructions and Demonstrations ---
|
| 107 |
+
(1) For a tree object in a tree-planting game, the users need to pick up and plant the tree, thus the object is interactable.
|
| 108 |
+
(2) But for a tree object appeard in the background scenery of a fishing-only game, the object is highly likely non-interactable.\n
|
| 109 |
+
Output the interactable objects in JSON format: {{"objects": ["object1", "object2"]}}. E.g., {{"objects": ["door", "desk"]}}\n
|
| 110 |
+
NO DOT OUTPUT any other content besides JSON.\n
|
| 111 |
+
|
| 112 |
+
--- Data ---
|
| 113 |
+
The current VR scenario in the screenshot:
|
| 114 |
+
{app_current_view}
|
| 115 |
+
'''
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
# def infer_object_candidates(vlm_question_path, vlm_answer_path, llm_candidate_path):
|
| 119 |
+
def infer_objects(vlm_question_path, vlm_answer_path, llm_candidate_path, ablation, model_profile=DEFAULT_PROFILE):
|
| 120 |
+
profile = get_model_profile(model_profile)
|
| 121 |
+
client = OpenAICompatibleChatClient(profile)
|
| 122 |
+
|
| 123 |
+
with open(vlm_answer_path, "r") as f_a:
|
| 124 |
+
file_a_data = [json.loads(line) for line in f_a.readlines()]
|
| 125 |
+
|
| 126 |
+
with open(vlm_question_path, "r") as f_b:
|
| 127 |
+
file_b_data = {json.loads(line)["question_id"]: json.loads(line) for line in f_b.readlines()}
|
| 128 |
+
|
| 129 |
+
results = {}
|
| 130 |
+
index = 0
|
| 131 |
+
|
| 132 |
+
for line_data_a in file_a_data:
|
| 133 |
+
print(index)
|
| 134 |
+
index += 1
|
| 135 |
+
|
| 136 |
+
# TODO: Proxy pool
|
| 137 |
+
# proxy = get_proxy()
|
| 138 |
+
# if not proxy:
|
| 139 |
+
# print("Failed to fetch proxy.")
|
| 140 |
+
# continue
|
| 141 |
+
|
| 142 |
+
question_id = line_data_a["question_id"]
|
| 143 |
+
app_current_view = line_data_a["text"]
|
| 144 |
+
line_data_b = file_b_data.get(question_id, {})
|
| 145 |
+
app_id = line_data_b.get("image", "").split("_")[0]
|
| 146 |
+
|
| 147 |
+
if app_id:
|
| 148 |
+
app_name, app_description = get_steam_app_data(app_id, line_data_b.get("image", ""))
|
| 149 |
+
message_content = generate_prompt(app_name, app_description, app_current_view, ablation)
|
| 150 |
+
# switch_api_key() # Use the next API key in the list
|
| 151 |
+
try:
|
| 152 |
+
# TODO: Proxy pool (f"http://{proxy}")
|
| 153 |
+
completion = client.complete_json(message_content)
|
| 154 |
+
inferred_objects = completion["objects"]
|
| 155 |
+
inferred_objects = [io.strip() for io in inferred_objects]
|
| 156 |
+
|
| 157 |
+
# wrong_flag = False
|
| 158 |
+
# for io in inferred_objects:
|
| 159 |
+
# if io.startswith('Based on') or len(io) > 70:
|
| 160 |
+
# print('Based on')
|
| 161 |
+
# wrong_flag = True
|
| 162 |
+
# break
|
| 163 |
+
# if wrong_flag:
|
| 164 |
+
# continue
|
| 165 |
+
print(inferred_objects)
|
| 166 |
+
|
| 167 |
+
i_completion = client.complete_json_messages([
|
| 168 |
+
{'role': 'user', 'content': message_content},
|
| 169 |
+
{'role': 'assistant', 'content': json.dumps(completion)},
|
| 170 |
+
{'role': 'user', 'content': generate_i_prompt(inferred_objects, app_current_view, ablation)}
|
| 171 |
+
])
|
| 172 |
+
interactable_objects = i_completion["objects"]
|
| 173 |
+
interactable_objects = [io.strip() for io in interactable_objects]
|
| 174 |
+
# TODO: !!
|
| 175 |
+
if len(interactable_objects) == 0:
|
| 176 |
+
interactable_objects = ['\n']
|
| 177 |
+
print(interactable_objects)
|
| 178 |
+
|
| 179 |
+
results[question_id] = {
|
| 180 |
+
"vlm_question": line_data_a,
|
| 181 |
+
"vlm_answer": line_data_b,
|
| 182 |
+
"app_name": app_name,
|
| 183 |
+
"app_description": app_description,
|
| 184 |
+
"app_current_view": app_current_view,
|
| 185 |
+
"inferred_object_candidates": inferred_objects,
|
| 186 |
+
"interactable_objects": interactable_objects
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
# Save the updated results to file after each successful API call
|
| 190 |
+
save_results_to_file(llm_candidate_path, results)
|
| 191 |
+
|
| 192 |
+
except Exception as e:
|
| 193 |
+
print(f"Error generating completion for question_id {question_id}. Error: {e}")
|
| 194 |
+
|
| 195 |
+
time.sleep(3) # Sleep for 2 seconds before switching to the next API key
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
# def infer_interactable_object(vlm_question_path, vlm_answer_path, llm_candidate_path):
|
| 199 |
+
# with open(vlm_answer_path, "r") as f_a:
|
| 200 |
+
# file_a_data = [json.loads(line) for line in f_a.readlines()]
|
| 201 |
+
|
| 202 |
+
# with open(vlm_question_path, "r") as f_b:
|
| 203 |
+
# file_b_data = {json.loads(line)["question_id"]: json.loads(line) for line in f_b.readlines()}
|
| 204 |
+
|
| 205 |
+
# results = {}
|
| 206 |
+
# index = 0
|
| 207 |
+
|
| 208 |
+
# for line_data_a in file_a_data:
|
| 209 |
+
# print(index)
|
| 210 |
+
# index += 1
|
| 211 |
+
|
| 212 |
+
# # TODO: Proxy pool
|
| 213 |
+
# # proxy = get_proxy()
|
| 214 |
+
# # if not proxy:
|
| 215 |
+
# # print("Failed to fetch proxy.")
|
| 216 |
+
# # continue
|
| 217 |
+
|
| 218 |
+
# question_id = line_data_a["question_id"]
|
| 219 |
+
# app_current_view = line_data_a["text"]
|
| 220 |
+
# line_data_b = file_b_data.get(question_id, {})
|
| 221 |
+
# app_id = line_data_b.get("image", "").split("_")[0]
|
| 222 |
+
|
| 223 |
+
# if app_id:
|
| 224 |
+
# app_name, app_description = get_steam_app_data(app_id, line_data_b.get("image", ""))
|
| 225 |
+
# message_content = generate_prompt(app_name, app_description, app_current_view)
|
| 226 |
+
# # switch_api_key() # Use the next API key in the list
|
| 227 |
+
# try:
|
| 228 |
+
# # TODO: Proxy pool (f"http://{proxy}")
|
| 229 |
+
# completion = openai.ChatCompletion.create(
|
| 230 |
+
# model='gemini-3-flash-preview-nothinking',
|
| 231 |
+
# temperature=0,
|
| 232 |
+
# messages=[{'role': 'user', 'content': message_content}]
|
| 233 |
+
# )
|
| 234 |
+
# print(completion)
|
| 235 |
+
# # inferred_objects = completion['choices'][0]['message']['content'].strip().split(";")
|
| 236 |
+
# inferred_objects = json.loads(completion['choices'][0]['message']['content'].strip())['objects']
|
| 237 |
+
# inferred_objects = [io.strip() for io in inferred_objects]
|
| 238 |
+
|
| 239 |
+
# # wrong_flag = False
|
| 240 |
+
# # for io in inferred_objects:
|
| 241 |
+
# # if io.startswith('Based on') or len(io) > 70:
|
| 242 |
+
# # print('Based on')
|
| 243 |
+
# # wrong_flag = True
|
| 244 |
+
# # break
|
| 245 |
+
# # if wrong_flag:
|
| 246 |
+
# # continue
|
| 247 |
+
# print(inferred_objects)
|
| 248 |
+
|
| 249 |
+
# results[question_id] = {
|
| 250 |
+
# "vlm_question": line_data_a,
|
| 251 |
+
# "vlm_answer": line_data_b,
|
| 252 |
+
# "app_name": app_name,
|
| 253 |
+
# "app_description": app_description,
|
| 254 |
+
# "app_current_view": app_current_view,
|
| 255 |
+
# "inferred_object_candidates": inferred_objects
|
| 256 |
+
# }
|
| 257 |
+
|
| 258 |
+
# # Save the updated results to file after each successful API call
|
| 259 |
+
# save_results_to_file(llm_candidate_path, results)
|
| 260 |
+
|
| 261 |
+
# except Exception as e:
|
| 262 |
+
# print(f"Error generating completion for question_id {question_id}. Error: {e}")
|
| 263 |
+
|
| 264 |
+
# time.sleep(0.5) # Sleep for 2 seconds before switching to the next API key
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
if __name__ == "__main__":
|
| 268 |
+
infer_object_candidates("path_to_vlm_question", "path_to_vlm_answer", "path_to_llm_candidate")
|
approach/method.py
ADDED
|
@@ -0,0 +1,732 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
import json
|
| 4 |
+
import time
|
| 5 |
+
import random
|
| 6 |
+
import string
|
| 7 |
+
import argparse
|
| 8 |
+
import copy
|
| 9 |
+
import logging
|
| 10 |
+
from tqdm import tqdm
|
| 11 |
+
import PIL
|
| 12 |
+
from PIL import ImageFile
|
| 13 |
+
PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True
|
| 14 |
+
|
| 15 |
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| 16 |
+
sys.path.append(BASE_DIR)
|
| 17 |
+
from approach.pipeline_utils import (
|
| 18 |
+
enrich_ape_results,
|
| 19 |
+
output_path_for_selection,
|
| 20 |
+
run_optional_reflection,
|
| 21 |
+
select_jsonl_lines,
|
| 22 |
+
write_json_atomic,
|
| 23 |
+
)
|
| 24 |
+
|
| 25 |
+
os.environ['TORCH_HOME'] = './.cache'
|
| 26 |
+
os.environ['HF_HOME'] = './.cache'
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
vlm = 'llava7b'
|
| 30 |
+
llm = 'gpt_3.5_turbo'
|
| 31 |
+
ovod = 'grounding_dino'
|
| 32 |
+
|
| 33 |
+
vlm_prompt = ''
|
| 34 |
+
|
| 35 |
+
### Configurable
|
| 36 |
+
host_device = os.getenv('ORIENTER_LEGACY_HOST', 'local')
|
| 37 |
+
perspective = 'all_perspective'
|
| 38 |
+
# perspective = 'direct_back'
|
| 39 |
+
# perspective = 'direct_front'
|
| 40 |
+
# perspective = 'direct_side'
|
| 41 |
+
# perspective = 'direct_top'
|
| 42 |
+
# perspective = 'eyelevel'
|
| 43 |
+
# perspective = 'overlook'
|
| 44 |
+
### Configurable
|
| 45 |
+
|
| 46 |
+
llava_path = os.path.join(BASE_DIR, 'approach/vlm/LLaVA/llava/eval')
|
| 47 |
+
grounding_dino_path = os.path.join(BASE_DIR, 'approach/ovod/GroundingDINO')
|
| 48 |
+
ape_path = os.path.join(BASE_DIR, 'approach/ovod/APE')
|
| 49 |
+
# TODO: data on the CUHK server
|
| 50 |
+
# images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_merged/images/interactable')
|
| 51 |
+
# icse
|
| 52 |
+
# images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_merged/images/test_set_merged')
|
| 53 |
+
# icse_rebuttal
|
| 54 |
+
# images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_angleview/images/all_perspective')
|
| 55 |
+
# fse
|
| 56 |
+
images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_det/images/union3')
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
# def generate_grounding_dino_command(ovod_image_path, ovod_output_dir, ovod_candidates):
|
| 60 |
+
# gdino_object_str = ' . '.join(ovod_candidates)
|
| 61 |
+
|
| 62 |
+
# gdino_command = f'''
|
| 63 |
+
# python demo/inference_on_a_image.py \
|
| 64 |
+
# -c groundingdino/config/GroundingDINO_SwinT_OGC.py \
|
| 65 |
+
# -p weights/groundingdino_swint_ogc.pth \
|
| 66 |
+
# -i {ovod_image_path} \
|
| 67 |
+
# -o "{ovod_output_dir}" \
|
| 68 |
+
# -t "{gdino_object_str}"
|
| 69 |
+
# '''
|
| 70 |
+
# return gdino_command
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def generate_question_file(img_folder, dst_path):
|
| 74 |
+
# Ensure the directory exists
|
| 75 |
+
if not os.path.exists(img_folder):
|
| 76 |
+
print(f"Error: Directory {img_folder} does not exist.")
|
| 77 |
+
return
|
| 78 |
+
|
| 79 |
+
# List all files in the directory
|
| 80 |
+
all_files = os.listdir(img_folder)
|
| 81 |
+
|
| 82 |
+
# Filter out files that are not images (based on extension). You can add more if needed.
|
| 83 |
+
image_extensions = [".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff"]
|
| 84 |
+
image_files = [f for f in all_files if any(f.lower().endswith(ext) for ext in image_extensions)]
|
| 85 |
+
|
| 86 |
+
# Open the output file for writing
|
| 87 |
+
with open(dst_path, 'w') as out_file:
|
| 88 |
+
for index, img_file in enumerate(image_files):
|
| 89 |
+
data = {
|
| 90 |
+
"question_id": index,
|
| 91 |
+
"image": img_file,
|
| 92 |
+
"text": vlm_prompt,
|
| 93 |
+
"category": "detail"
|
| 94 |
+
}
|
| 95 |
+
out_file.write(json.dumps(data) + '\n')
|
| 96 |
+
|
| 97 |
+
print(f"Processed {len(image_files)} images. Output saved to {dst_path}.")
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def generate_answer_id(length=20):
|
| 101 |
+
# Define the characters that can be used in the string
|
| 102 |
+
characters = string.ascii_letters + string.digits
|
| 103 |
+
# Generate a random string of the specified length
|
| 104 |
+
answer_id = ''.join(random.choice(characters) for _ in range(length))
|
| 105 |
+
return answer_id
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
def method(
|
| 109 |
+
vlm=vlm,
|
| 110 |
+
llm=llm,
|
| 111 |
+
ovod=ovod,
|
| 112 |
+
start_index=None,
|
| 113 |
+
end_index=None,
|
| 114 |
+
shard_index=None,
|
| 115 |
+
num_shards=None,
|
| 116 |
+
enable_reflection=False,
|
| 117 |
+
reflection_profile="default",
|
| 118 |
+
max_reflection_iterations=10,
|
| 119 |
+
questions_path=None,
|
| 120 |
+
candidates_path=None,
|
| 121 |
+
images_path=None,
|
| 122 |
+
output_path=None,
|
| 123 |
+
ape_root=None,
|
| 124 |
+
ape_checkpoint=None,
|
| 125 |
+
):
|
| 126 |
+
images_dir = images_path or globals()["images_dir"]
|
| 127 |
+
active_ape_path = ape_root or globals()["ape_path"]
|
| 128 |
+
active_ape_checkpoint = ape_checkpoint or "./ape_d_model_final.pth"
|
| 129 |
+
# vlm_question_path = os.path.join(BASE_DIR, 'approach/vlm/sampled_vlm_questions.jsonl')
|
| 130 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_test_set_merged_vlm_questions_from671.jsonl')
|
| 131 |
+
# icse
|
| 132 |
+
# complete_vlm_question_abl_i_path = os.path.join(BASE_DIR, f'approach/vlm/icse_test_set_merged_complete_vlm_questions_ablation_interactability.jsonl')
|
| 133 |
+
|
| 134 |
+
# icse
|
| 135 |
+
# complete_vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_test_set_merged_complete_vlm_questions.jsonl')
|
| 136 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/gpt4v_failure_questions.jsonl')
|
| 137 |
+
# icse_rebuttal
|
| 138 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_vlm_questions.jsonl')
|
| 139 |
+
# complete_vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_complete_vlm_questions.jsonl')
|
| 140 |
+
# fse
|
| 141 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/fse_union3_{vlm}_questions.jsonl')
|
| 142 |
+
complete_vlm_question_path = questions_path or os.path.join(BASE_DIR, f'approach/vlm/realfse_union3_complete_{vlm}_questions.jsonl')
|
| 143 |
+
vlm_question_path = complete_vlm_question_path
|
| 144 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/gpt4v_failure_questions.jsonl')
|
| 145 |
+
# playground/data/coco2014_val_qa_eval/qa90_questions.jsonl
|
| 146 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer_slowerspeed_1.jsonl')
|
| 147 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer_higherspeed_r3_1_from195.jsonl')
|
| 148 |
+
|
| 149 |
+
# icse
|
| 150 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/cuhk_icse_test_set_merged_{vlm}_answer.jsonl')
|
| 151 |
+
# llava_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer.jsonl')
|
| 152 |
+
# gemini_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer_ablation_no_interactability_r1_0.jsonl')
|
| 153 |
+
# gpt4_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_cuhk_icse_test_set_merged_gpt4v_answer_higherspeed_r3_0.jsonl')
|
| 154 |
+
# interactability_abl_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_hit_icse_test_set_merged_gemini_answer_ablation_no_interactability_r1_0.jsonl')
|
| 155 |
+
# icse_rebuttal
|
| 156 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_{vlm}_answer.jsonl')
|
| 157 |
+
# llava_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_rbt_{perspective}_{vlm}_answer.jsonl')
|
| 158 |
+
# gemini_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_rbt_{perspective}_{vlm}_answer.jsonl')
|
| 159 |
+
# fse
|
| 160 |
+
vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/realfse_uninon3_{vlm}_answer.jsonl')
|
| 161 |
+
llava_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_fse_uninon3_{vlm}_answer.jsonl')
|
| 162 |
+
gemini_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/realfse_union3_{vlm}_answer.jsonl')
|
| 163 |
+
|
| 164 |
+
# icse
|
| 165 |
+
# gpt4_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_icse_rbt_{perspective}_gpt4v_answer.jsonl')
|
| 166 |
+
# icse_rebuttal
|
| 167 |
+
# gpt4_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_{vlm}_answer_265_528.jsonl')
|
| 168 |
+
# fse
|
| 169 |
+
gpt4_results_answer_path = candidates_path or os.path.join(BASE_DIR, f'approach/vlm/realfse_uninon3_gpt4v_answer.jsonl')
|
| 170 |
+
# print(gpt4_results_answer_path)
|
| 171 |
+
# interactability_abl_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_icse_rbt_{perspective}_answer.jsonl')
|
| 172 |
+
|
| 173 |
+
# icse
|
| 174 |
+
# # /path/to/answer-file-our.jsonl
|
| 175 |
+
# # llm_candidate_path = os.path.join(BASE_DIR, f'approach/llm/{vlm}_{llm}_cancidate_objects.json')
|
| 176 |
+
# interactable_object_path = os.path.join(BASE_DIR, f'approach/llm/icse_test_set_merged_{vlm}_{llm}_interactable_objects.json')
|
| 177 |
+
# ovod_output_dir = os.path.join(BASE_DIR, f'approach/ovod/output/icse_test_set_merged_{ovod}')
|
| 178 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_object_bbox_gpu3_2.json')
|
| 179 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_ablation_no_interactability_object_bbox_gpu0.json')
|
| 180 |
+
# oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_ablation_no_feedback_object_bbox_gpu2.json')
|
| 181 |
+
|
| 182 |
+
# icse_rebuttal
|
| 183 |
+
# interactable_object_path = os.path.join(BASE_DIR, f'approach/llm/icse_rbt_{perspective}_{vlm}_{llm}_interactable_objects.json')
|
| 184 |
+
# ovod_output_dir = os.path.join(BASE_DIR, f'approach/ovod/output/icse_rbt_{perspective}_{ovod}')
|
| 185 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_object_bbox_gpu3_2.json')
|
| 186 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_ablation_no_interactability_object_bbox_gpu0.json')
|
| 187 |
+
# oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_rbt_{perspective}_{vlm}_{llm}_{ovod}_object_bbox_gpu3_265_528.json')
|
| 188 |
+
|
| 189 |
+
gpu = '1-3'
|
| 190 |
+
# fse
|
| 191 |
+
interactable_object_path = candidates_path or os.path.join(BASE_DIR, f'approach/llm/realfse_union3_{vlm}_{llm}_interactable_objects.json') # TODO: Tentatively unused
|
| 192 |
+
ovod_output_dir = os.path.join(BASE_DIR, f'approach/ovod/output/realfse_union3_{ovod}')
|
| 193 |
+
# GPU 0
|
| 194 |
+
base_output_path = output_path or os.path.join(BASE_DIR, f'approach/ovod/realfse_union3_{vlm}_{ovod}_object_bbox_gpu{gpu}.json')
|
| 195 |
+
oovd_object_bbox_path = output_path_for_selection(
|
| 196 |
+
base_output_path,
|
| 197 |
+
start_index=start_index,
|
| 198 |
+
end_index=end_index,
|
| 199 |
+
shard_index=shard_index,
|
| 200 |
+
num_shards=num_shards,
|
| 201 |
+
)
|
| 202 |
+
|
| 203 |
+
llava7b_model_path = os.path.join(BASE_DIR, 'approach/vlm/LLaVA/checkpoints/llava-v1.5-7b')
|
| 204 |
+
llava7b_cmd = f'''
|
| 205 |
+
python model_vqa.py \
|
| 206 |
+
--model-path {llava7b_model_path} \
|
| 207 |
+
--question-file \
|
| 208 |
+
{complete_vlm_question_path} \
|
| 209 |
+
--image-folder \
|
| 210 |
+
{images_dir} \
|
| 211 |
+
--answers-file \
|
| 212 |
+
{llava_vlm_answer_path}
|
| 213 |
+
'''
|
| 214 |
+
|
| 215 |
+
# STEP #0
|
| 216 |
+
# First time of running
|
| 217 |
+
# TODO: Check whether it is first-time running
|
| 218 |
+
# generate_question_file(images_dir, vlm_question_path)
|
| 219 |
+
|
| 220 |
+
# STEP #1
|
| 221 |
+
# VLM - Get local context
|
| 222 |
+
# print(f'VLM {vlm} analysis begins ...')
|
| 223 |
+
# vlm_start_time = time.time()
|
| 224 |
+
# logging.info(f'STEP #1 VLM {vlm} analysis started at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 225 |
+
# if vlm == 'llava7b':
|
| 226 |
+
# original_path = os.path.dirname(__file__)
|
| 227 |
+
# os.chdir(llava_path)
|
| 228 |
+
# os.system(llava7b_cmd)
|
| 229 |
+
# os.chdir(original_path)
|
| 230 |
+
# elif vlm == 'generate_q_file':
|
| 231 |
+
# from approach.vlm.gpt4v.gpt4v import process_image_q
|
| 232 |
+
# with open(vlm_question_path, 'r') as q_file, open(complete_vlm_question_path, 'w') as cq_file: # Open answer file in append mode
|
| 233 |
+
# qfile_lines = q_file.readlines()
|
| 234 |
+
# key_idx = 0
|
| 235 |
+
# for line in tqdm(qfile_lines):
|
| 236 |
+
# key_idx = (key_idx + 1) % 4
|
| 237 |
+
|
| 238 |
+
# ans_item = {}
|
| 239 |
+
|
| 240 |
+
# line_data = json.loads(line)
|
| 241 |
+
# image_path = os.path.join(images_dir, line_data['image'])
|
| 242 |
+
# image_question = line_data['text']
|
| 243 |
+
|
| 244 |
+
# if vlm == 'gpt4v_abl':
|
| 245 |
+
# gpt4v_ablation = True
|
| 246 |
+
# elif vlm == 'gpt4v':
|
| 247 |
+
# gpt4v_ablation = False
|
| 248 |
+
# gpt4v_q = process_image_q(image_question, image_path, key_idx)
|
| 249 |
+
# data = {
|
| 250 |
+
# "question_id": line_data['question_id'],
|
| 251 |
+
# "image": line_data['image'],
|
| 252 |
+
# "text": gpt4v_q,
|
| 253 |
+
# "category": "detail"
|
| 254 |
+
# }
|
| 255 |
+
# cq_file.write(json.dumps(data) + '\n')
|
| 256 |
+
# elif vlm == 'gpt4v' or vlm == 'gpt4v_abl' or vlm == 'claude35sonnet' or vlm == 'gemini15pro':
|
| 257 |
+
# from approach.vlm.gpt4v.gpt4v import process_image
|
| 258 |
+
# with open(vlm_question_path, 'r') as q_file, open(vlm_answer_path, 'a') as a_file: # Open answer file in append mode
|
| 259 |
+
# qfile_lines = q_file.readlines()
|
| 260 |
+
# key_idx = 0
|
| 261 |
+
# for line in tqdm(qfile_lines):
|
| 262 |
+
# key_idx = (key_idx + 1) % 4
|
| 263 |
+
|
| 264 |
+
# ans_item = {}
|
| 265 |
+
|
| 266 |
+
# line_data = json.loads(line)
|
| 267 |
+
# image_path = os.path.join(images_dir, line_data['image'])
|
| 268 |
+
# image_question = line_data['text']
|
| 269 |
+
|
| 270 |
+
# gpt4v_ablation = False
|
| 271 |
+
# if vlm == 'gpt4v_abl':
|
| 272 |
+
# gpt4v_ablation = True
|
| 273 |
+
# elif vlm == 'gpt4v':
|
| 274 |
+
# gpt4v_ablation = False
|
| 275 |
+
# gpt4v_res = process_image(vlm, image_question, image_path, gpt4v_ablation, key_idx)
|
| 276 |
+
# print(gpt4v_res)
|
| 277 |
+
# # time.sleep(3)
|
| 278 |
+
|
| 279 |
+
# ans_item = {
|
| 280 |
+
# "question_id": line_data['question_id'],
|
| 281 |
+
# "prompt": '',
|
| 282 |
+
# "text": gpt4v_res,
|
| 283 |
+
# "answer_id": generate_answer_id(),
|
| 284 |
+
# "model_id": vlm,
|
| 285 |
+
# "metadata": {}
|
| 286 |
+
# }
|
| 287 |
+
|
| 288 |
+
# a_file.write(json.dumps(ans_item) + '\n')
|
| 289 |
+
# a_file.flush()
|
| 290 |
+
# elif vlm == 'bing':
|
| 291 |
+
# from approach.vlm.bing.bing import context_conversation
|
| 292 |
+
# with open(vlm_question_path, 'r') as q_file, open(vlm_answer_path, 'a') as a_file: # Open answer file in append mode
|
| 293 |
+
# for line in tqdm(q_file):
|
| 294 |
+
# ans_item = {}
|
| 295 |
+
|
| 296 |
+
# line_data = json.loads(line)
|
| 297 |
+
# image_path = os.path.join(images_dir, line_data['image'])
|
| 298 |
+
# image_question = line_data['text']
|
| 299 |
+
|
| 300 |
+
# bing_res = context_conversation(image_question, image_path)
|
| 301 |
+
# print(bing_res)
|
| 302 |
+
# time.sleep(15)
|
| 303 |
+
|
| 304 |
+
# ans_item = {
|
| 305 |
+
# "question_id": line_data['question_id'],
|
| 306 |
+
# "prompt": image_question,
|
| 307 |
+
# "text": bing_res,
|
| 308 |
+
# "answer_id": generate_answer_id(),
|
| 309 |
+
# "model_id": vlm,
|
| 310 |
+
# "metadata": {}
|
| 311 |
+
# }
|
| 312 |
+
|
| 313 |
+
# a_file.write(json.dumps(ans_item) + '\n')
|
| 314 |
+
# elif vlm == 'gemini':
|
| 315 |
+
# import pathlib
|
| 316 |
+
# import textwrap
|
| 317 |
+
|
| 318 |
+
# import google.generativeai as genai
|
| 319 |
+
|
| 320 |
+
# GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY", "[GOOGLE_API_KEY]")
|
| 321 |
+
# genai.configure(api_key=GOOGLE_API_KEY)
|
| 322 |
+
|
| 323 |
+
# safety_settings = [
|
| 324 |
+
# {
|
| 325 |
+
# "category": "HARM_CATEGORY_DANGEROUS",
|
| 326 |
+
# "threshold": "BLOCK_NONE",
|
| 327 |
+
# },
|
| 328 |
+
# {
|
| 329 |
+
# "category": "HARM_CATEGORY_HARASSMENT",
|
| 330 |
+
# "threshold": "BLOCK_NONE",
|
| 331 |
+
# },
|
| 332 |
+
# {
|
| 333 |
+
# "category": "HARM_CATEGORY_HATE_SPEECH",
|
| 334 |
+
# "threshold": "BLOCK_NONE",
|
| 335 |
+
# },
|
| 336 |
+
# {
|
| 337 |
+
# "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
| 338 |
+
# "threshold": "BLOCK_NONE",
|
| 339 |
+
# },
|
| 340 |
+
# {
|
| 341 |
+
# "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
| 342 |
+
# "threshold": "BLOCK_NONE",
|
| 343 |
+
# },
|
| 344 |
+
# ]
|
| 345 |
+
|
| 346 |
+
# # before fse
|
| 347 |
+
# # model = genai.GenerativeModel('gemini-pro-vision')
|
| 348 |
+
# # fse
|
| 349 |
+
# model = genai.GenerativeModel('gemini-1.5-pro')
|
| 350 |
+
|
| 351 |
+
# with open(vlm_question_path, 'r') as q_file, open(gemini_vlm_answer_path, 'a') as a_file: # Open answer file in append mode
|
| 352 |
+
# qfile_lines = q_file.readlines()[0:2]
|
| 353 |
+
# for line in tqdm(qfile_lines):
|
| 354 |
+
|
| 355 |
+
# ans_item = {}
|
| 356 |
+
|
| 357 |
+
# line_data = json.loads(line)
|
| 358 |
+
# image_path = os.path.join(images_dir, line_data['image'])
|
| 359 |
+
# image_question = line_data['text']
|
| 360 |
+
|
| 361 |
+
# gemini_response = model.generate_content([image_question, PIL.Image.open(image_path)], safety_settings=safety_settings)
|
| 362 |
+
# gemini_response.resolve()
|
| 363 |
+
# try:
|
| 364 |
+
# gemini_response = gemini_response.text
|
| 365 |
+
# ans_item = {
|
| 366 |
+
# "question_id": line_data['question_id'],
|
| 367 |
+
# "prompt": image_question,
|
| 368 |
+
# "text": gemini_response,
|
| 369 |
+
# "answer_id": generate_answer_id(),
|
| 370 |
+
# "model_id": vlm,
|
| 371 |
+
# "metadata": {}
|
| 372 |
+
# }
|
| 373 |
+
|
| 374 |
+
# a_file.write(json.dumps(ans_item) + '\n')
|
| 375 |
+
# a_file.flush()
|
| 376 |
+
# except Exception as e:
|
| 377 |
+
# print(f"Error for image {image_path}. Error: {e}")
|
| 378 |
+
# # print(gemini_response)
|
| 379 |
+
# time.sleep(30)
|
| 380 |
+
|
| 381 |
+
|
| 382 |
+
|
| 383 |
+
# elif vlm.endswith('_pass'):
|
| 384 |
+
# print(f'Passing VLM {vlm} ...')
|
| 385 |
+
# else:
|
| 386 |
+
# raise Exception('Unrecognized VLM!')
|
| 387 |
+
|
| 388 |
+
# logging.info(f'STEP #1 VLM {vlm} analysis completed at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 389 |
+
# logging.info(f'STEP #1 VLM {vlm} analysis total time taken: {time.time() - vlm_start_time} seconds')
|
| 390 |
+
|
| 391 |
+
|
| 392 |
+
|
| 393 |
+
|
| 394 |
+
|
| 395 |
+
# Get label candidates
|
| 396 |
+
# if llm == 'gpt_3.5_turbo':
|
| 397 |
+
# from approach.llm.gpt_polling import infer_object_candidates
|
| 398 |
+
# elif llm == 'llama2':
|
| 399 |
+
# from approach.llm.llama import infer_object_candidates
|
| 400 |
+
|
| 401 |
+
|
| 402 |
+
# STEP #3
|
| 403 |
+
# if llm == 'gpt_3.5_turbo' or llm == 'gpt_3.5_turbo_abl':
|
| 404 |
+
# from approach.llm.gpt_polling import infer_objects
|
| 405 |
+
|
| 406 |
+
# if llm == 'gpt_3.5_turbo_abl':
|
| 407 |
+
# gpt35_ablation = True
|
| 408 |
+
# elif llm == 'gpt_3.5_turbo':
|
| 409 |
+
# gpt35_ablation = False
|
| 410 |
+
# infer_objects(vlm_question_path, vlm_answer_path, interactable_object_path, gpt35_ablation)
|
| 411 |
+
# elif llm == 'llama2':
|
| 412 |
+
# from approach.llm.llama import infer_objects
|
| 413 |
+
# exit(0)
|
| 414 |
+
# elif llm.endswith('_pass'):
|
| 415 |
+
# print(f'Passing LLM {llm} ...')
|
| 416 |
+
# else:
|
| 417 |
+
# raise Exception('Unrecognized LLM!')
|
| 418 |
+
|
| 419 |
+
|
| 420 |
+
|
| 421 |
+
|
| 422 |
+
|
| 423 |
+
|
| 424 |
+
# STEP #2
|
| 425 |
+
# Open-vocabulary object detection
|
| 426 |
+
ovod_start_time = time.time()
|
| 427 |
+
logging.info(f'STEP #2 OVOD {ovod} analysis started at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 428 |
+
vlm_questions = {}
|
| 429 |
+
with open(complete_vlm_question_path, 'r') as q_file:
|
| 430 |
+
for line in q_file:
|
| 431 |
+
line_data = json.loads(line)
|
| 432 |
+
vlm_questions[line_data['question_id']] = line_data
|
| 433 |
+
# print(line_data['question_id'])
|
| 434 |
+
|
| 435 |
+
if ovod == 'grounding_dino':
|
| 436 |
+
from approach.ovod.GroundingDINO.demo.inference_on_a_image import process_grounding_dino
|
| 437 |
+
|
| 438 |
+
original_path = os.path.dirname(__file__)
|
| 439 |
+
os.chdir(grounding_dino_path)
|
| 440 |
+
|
| 441 |
+
# with open(llm_candidate_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 442 |
+
with open(interactable_object_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 443 |
+
llm_candidate = json.load(llm_candidate_file)
|
| 444 |
+
all_oovd_res = {}
|
| 445 |
+
for image_index in llm_candidate.keys():
|
| 446 |
+
print(image_index)
|
| 447 |
+
# TODO:
|
| 448 |
+
if (image_index != '1160'):
|
| 449 |
+
ovod_image_path = os.path.join(images_dir, vlm_questions[int(image_index)]["image"])
|
| 450 |
+
ovod_candidates = llm_candidate[image_index]['interactable_objects']
|
| 451 |
+
# grounding_dino_command = generate_grounding_dino_command(ovod_image_path, ovod_output_dir, ovod_candidates)
|
| 452 |
+
# print(grounding_dino_command)
|
| 453 |
+
# os.system(grounding_dino_command)
|
| 454 |
+
|
| 455 |
+
gdino_res = process_grounding_dino(
|
| 456 |
+
config_file='groundingdino/config/GroundingDINO_SwinT_OGC.py',
|
| 457 |
+
checkpoint_path='weights/groundingdino_swint_ogc.pth',
|
| 458 |
+
image_path=ovod_image_path,
|
| 459 |
+
ovod_candidates=ovod_candidates,
|
| 460 |
+
output_dir=ovod_output_dir,
|
| 461 |
+
box_threshold=0.3,
|
| 462 |
+
text_threshold=0.25,
|
| 463 |
+
token_spans=None,
|
| 464 |
+
cpu_only=False
|
| 465 |
+
)
|
| 466 |
+
# print(gdino_res)
|
| 467 |
+
|
| 468 |
+
object_oovd_item = copy.deepcopy(llm_candidate[image_index])
|
| 469 |
+
object_oovd_item['oovd_result'] = gdino_res
|
| 470 |
+
print(object_oovd_item)
|
| 471 |
+
all_oovd_res[image_index] = object_oovd_item
|
| 472 |
+
|
| 473 |
+
json.dump(all_oovd_res, oovd_file, indent=4)
|
| 474 |
+
|
| 475 |
+
|
| 476 |
+
os.chdir(original_path)
|
| 477 |
+
|
| 478 |
+
elif ovod == 'ape_d' or ovod == 'ape_d_abl':
|
| 479 |
+
from approach.ovod.APE.demo.ape_inference import run_ape_model_inference
|
| 480 |
+
|
| 481 |
+
original_path = os.path.dirname(__file__)
|
| 482 |
+
os.chdir(active_ape_path)
|
| 483 |
+
|
| 484 |
+
all_ape_res = []
|
| 485 |
+
reflection_traces = []
|
| 486 |
+
# General
|
| 487 |
+
# with open(vlm_answer_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 488 |
+
# GPT-4 eval
|
| 489 |
+
with open(gpt4_results_answer_path, 'r') as llm_candidate_file:
|
| 490 |
+
# Gemini abl i eval
|
| 491 |
+
# with open(interactability_abl_results_answer_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 492 |
+
|
| 493 |
+
# llm_candidate = json.load(llm_candidate_file)
|
| 494 |
+
all_oovd_res = {}
|
| 495 |
+
|
| 496 |
+
candidate_lines = select_jsonl_lines(
|
| 497 |
+
llm_candidate_file.readlines(),
|
| 498 |
+
start_index=start_index,
|
| 499 |
+
end_index=end_index,
|
| 500 |
+
shard_index=shard_index,
|
| 501 |
+
num_shards=num_shards,
|
| 502 |
+
)
|
| 503 |
+
|
| 504 |
+
for line in tqdm(candidate_lines):
|
| 505 |
+
ans_item = {}
|
| 506 |
+
|
| 507 |
+
line_data = json.loads(line)
|
| 508 |
+
|
| 509 |
+
# for image_index in llm_candidate.keys():
|
| 510 |
+
# print(image_index)
|
| 511 |
+
# TODO:
|
| 512 |
+
# if (image_index != '1160'):
|
| 513 |
+
# image_index = line_data['question_id']
|
| 514 |
+
|
| 515 |
+
image_name = vlm_questions[line_data['question_id']]["image"]
|
| 516 |
+
ovod_image_path = os.path.join(images_dir, image_name)
|
| 517 |
+
|
| 518 |
+
# General
|
| 519 |
+
# try:
|
| 520 |
+
# if line_data['text'].startswith(" ```json"):
|
| 521 |
+
# ovod_candidates = json.loads(line_data['text'][8:-4])['objects']
|
| 522 |
+
# elif line_data['text'].startswith(' {\"objects\"'):
|
| 523 |
+
# ovod_candidates = json.loads(line_data['text'])['objects']
|
| 524 |
+
# else:
|
| 525 |
+
# print(f"Error for decoding IVO json for {image_name}.")
|
| 526 |
+
# except Exception as e:
|
| 527 |
+
# print(f"Error for decoding IVO json for image {image_name}. Error: {e}")
|
| 528 |
+
# continue
|
| 529 |
+
|
| 530 |
+
|
| 531 |
+
# GPT-4v
|
| 532 |
+
if line_data['text']:
|
| 533 |
+
ovod_candidates = line_data['text']['objects']
|
| 534 |
+
else:
|
| 535 |
+
continue
|
| 536 |
+
all_res = []
|
| 537 |
+
for ocd in ovod_candidates.keys():
|
| 538 |
+
referring_expr_str = ovod_candidates[ocd]
|
| 539 |
+
|
| 540 |
+
translator = str.maketrans('', '', string.punctuation)
|
| 541 |
+
if type(referring_expr_str) is str:
|
| 542 |
+
referring_expr_str = referring_expr_str.translate(translator)
|
| 543 |
+
else:
|
| 544 |
+
# dict
|
| 545 |
+
referring_expr_str = ' '.join(referring_expr_str.values())
|
| 546 |
+
referring_expr_str = referring_expr_str.translate(translator)
|
| 547 |
+
referring_expr_str = f'{ocd}: {referring_expr_str}'
|
| 548 |
+
# print(image_name, referring_expr_str)
|
| 549 |
+
all_res.append(referring_expr_str)
|
| 550 |
+
|
| 551 |
+
if ovod == 'ape_d':
|
| 552 |
+
ape_threshold = 0.15
|
| 553 |
+
elif ovod == 'ape_d_abl':
|
| 554 |
+
ape_threshold = 0.1
|
| 555 |
+
|
| 556 |
+
ape_res = []
|
| 557 |
+
try:
|
| 558 |
+
ape_res = run_ape_model_inference(
|
| 559 |
+
config_file='configs/LVISCOCOCOCOSTUFF_O365_OID_VGR_SA1B_REFCOCO_GQA_PhraseCut_Flickr30k/ape_deta/ape_deta_vitl_eva02_clip_vlf_lsj1024_cp_16x4_1080k.py',
|
| 560 |
+
input_path=ovod_image_path,
|
| 561 |
+
# GPU 0
|
| 562 |
+
output_path=f'./realfse_{vlm}_{ovod}_gpu0123',
|
| 563 |
+
confidence_threshold=ape_threshold,
|
| 564 |
+
text_prompt=', '.join(all_res),
|
| 565 |
+
with_box=True,
|
| 566 |
+
with_mask=False,
|
| 567 |
+
with_sseg=False,
|
| 568 |
+
opts=[
|
| 569 |
+
f"train.init_checkpoint='{active_ape_checkpoint}'",
|
| 570 |
+
"model.model_language.cache_dir=''",
|
| 571 |
+
"model.model_vision.select_box_nums_for_evaluation=500",
|
| 572 |
+
"model.model_vision.text_feature_bank_reset=True",
|
| 573 |
+
"model.model_vision.backbone.net.xattn=False",
|
| 574 |
+
"model.model_vision.transformer.encoder.pytorch_attn=True",
|
| 575 |
+
"model.model_vision.transformer.decoder.pytorch_attn=True"
|
| 576 |
+
]
|
| 577 |
+
)
|
| 578 |
+
except Exception as e:
|
| 579 |
+
print(f"Error for image {image_name}. Error: {e}")
|
| 580 |
+
|
| 581 |
+
def reflection_detector(candidates, previous):
|
| 582 |
+
if not candidates:
|
| 583 |
+
return previous
|
| 584 |
+
try:
|
| 585 |
+
refined = run_ape_model_inference(
|
| 586 |
+
config_file='configs/LVISCOCOCOCOSTUFF_O365_OID_VGR_SA1B_REFCOCO_GQA_PhraseCut_Flickr30k/ape_deta/ape_deta_vitl_eva02_clip_vlf_lsj1024_cp_16x4_1080k.py',
|
| 587 |
+
input_path=ovod_image_path,
|
| 588 |
+
output_path=f'./realfse_{vlm}_{ovod}_gpu0123',
|
| 589 |
+
confidence_threshold=ape_threshold,
|
| 590 |
+
text_prompt=', '.join(candidates),
|
| 591 |
+
with_box=True,
|
| 592 |
+
with_mask=False,
|
| 593 |
+
with_sseg=False,
|
| 594 |
+
opts=[
|
| 595 |
+
f"train.init_checkpoint='{active_ape_checkpoint}'",
|
| 596 |
+
"model.model_language.cache_dir=''",
|
| 597 |
+
"model.model_vision.select_box_nums_for_evaluation=500",
|
| 598 |
+
"model.model_vision.text_feature_bank_reset=True",
|
| 599 |
+
"model.model_vision.backbone.net.xattn=False",
|
| 600 |
+
"model.model_vision.transformer.encoder.pytorch_attn=True",
|
| 601 |
+
"model.model_vision.transformer.decoder.pytorch_attn=True"
|
| 602 |
+
]
|
| 603 |
+
)
|
| 604 |
+
return previous + refined
|
| 605 |
+
except Exception as e:
|
| 606 |
+
print(f"Error during reflection redetection for {image_name}. Error: {e}")
|
| 607 |
+
return previous
|
| 608 |
+
|
| 609 |
+
reflection_result = run_optional_reflection(
|
| 610 |
+
ovod_image_path,
|
| 611 |
+
ape_res,
|
| 612 |
+
detector=reflection_detector,
|
| 613 |
+
enabled=enable_reflection,
|
| 614 |
+
model_profile=reflection_profile,
|
| 615 |
+
max_iterations=max_reflection_iterations,
|
| 616 |
+
)
|
| 617 |
+
if reflection_result is not None:
|
| 618 |
+
ape_res = reflection_result["detections"]
|
| 619 |
+
reflection_traces.append(
|
| 620 |
+
{
|
| 621 |
+
"image": image_name,
|
| 622 |
+
"image_id": extract_image_id(image_name),
|
| 623 |
+
"trace": reflection_result["trace"],
|
| 624 |
+
"max_iterations_reached": reflection_result["max_iterations_reached"],
|
| 625 |
+
}
|
| 626 |
+
)
|
| 627 |
+
|
| 628 |
+
all_ape_res.extend(enrich_ape_results(ape_res, image_name, extract_image_id))
|
| 629 |
+
# object_oovd_item = copy.deepcopy(llm_candidate[image_index])
|
| 630 |
+
# object_oovd_item['ape_result'] = all_ape_res
|
| 631 |
+
# # print(object_oovd_item)
|
| 632 |
+
# all_oovd_res[image_index] = object_oovd_item
|
| 633 |
+
|
| 634 |
+
write_json_atomic(oovd_object_bbox_path, all_ape_res)
|
| 635 |
+
if enable_reflection:
|
| 636 |
+
write_json_atomic(f"{oovd_object_bbox_path}.reflection.json", reflection_traces)
|
| 637 |
+
|
| 638 |
+
|
| 639 |
+
os.chdir(original_path)
|
| 640 |
+
|
| 641 |
+
elif ovod.endswith('_pass'):
|
| 642 |
+
print(f'Passing OVOD {ovod} ...')
|
| 643 |
+
else:
|
| 644 |
+
raise Exception('Unrecognized OVOD!')
|
| 645 |
+
|
| 646 |
+
logging.info(f'STEP #2 OVOD {ovod} analysis completed at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 647 |
+
logging.info(f'STEP #2 OVOD {ovod} analysis total time taken: {time.time() - ovod_start_time} seconds')
|
| 648 |
+
# icse & fse
|
| 649 |
+
def extract_image_id(image_name):
|
| 650 |
+
# Split the image name into parts and form the image_id accordingly
|
| 651 |
+
parts = image_name.split('_')
|
| 652 |
+
print(image_name)
|
| 653 |
+
base, extension = parts[1].split('.')
|
| 654 |
+
return int(parts[0] + base.zfill(3))
|
| 655 |
+
# icse_rebuttal
|
| 656 |
+
# def extract_image_id(image_name):
|
| 657 |
+
# # Split the image name into parts by underscore
|
| 658 |
+
# parts = image_name.split('_')
|
| 659 |
+
# # Extracting the first part as the base and the numeric portion of the third part before the file extension
|
| 660 |
+
# base = parts[0] # This will give '625470'
|
| 661 |
+
# numeric_part = parts[2].split('.')[0] # This will give 'b3'
|
| 662 |
+
# # Removing non-numeric characters from 'b3'
|
| 663 |
+
# numeric_part = ''.join(filter(str.isdigit, numeric_part))
|
| 664 |
+
# # Zfill is used to ensure the numeric part has at least 3 digits, then combining with base
|
| 665 |
+
# print(int(base + numeric_part.zfill(3)))
|
| 666 |
+
# return int(base + numeric_part.zfill(3))
|
| 667 |
+
|
| 668 |
+
|
| 669 |
+
def main():
|
| 670 |
+
vlms = ['llava7b', 'bing', 'gpt4v']
|
| 671 |
+
llms = ['llama2', 'gpt_3.5_turbo']
|
| 672 |
+
ovods = ['grounding_dino', 'glip', 'ape_d']
|
| 673 |
+
|
| 674 |
+
|
| 675 |
+
# python method.py -v gpt4v -l gpt_3.5_turbo -o ape_d
|
| 676 |
+
# python method.py -v gpt4v -l gpt_3.5_turbo -o ape_d_abl
|
| 677 |
+
# python method.py -v claude35sonnet -l gpt_3.5_turbo -o ape_d
|
| 678 |
+
# python method.py -v gemini -l gpt_3.5_turbo -o ape_d
|
| 679 |
+
if __name__=='__main__':
|
| 680 |
+
# main()
|
| 681 |
+
|
| 682 |
+
parser = argparse.ArgumentParser("Method", add_help=True)
|
| 683 |
+
parser.add_argument("--vlm", "-v", type=str, required=True, help="vlm")
|
| 684 |
+
parser.add_argument("--llm", "-l", type=str, required=True, help="llm")
|
| 685 |
+
parser.add_argument("--ovod", "-o", type=str, required=True, help="ovod")
|
| 686 |
+
parser.add_argument("--start-index", type=int, default=None, help="first JSONL row to process")
|
| 687 |
+
parser.add_argument("--end-index", type=int, default=None, help="exclusive JSONL row end")
|
| 688 |
+
parser.add_argument("--shard-index", type=int, default=None, help="zero-based shard index")
|
| 689 |
+
parser.add_argument("--num-shards", type=int, default=None, help="total number of shards")
|
| 690 |
+
parser.add_argument("--enable-reflection", action="store_true", help="run PII.5/PII.6 advisor reflection loop")
|
| 691 |
+
parser.add_argument("--reflection-profile", default="default", help="model profile for the reflection advisor")
|
| 692 |
+
parser.add_argument("--max-reflection-iterations", type=int, default=10, help="max advisor reflection rounds")
|
| 693 |
+
parser.add_argument("--questions", dest="questions_path", help="question manifest JSONL")
|
| 694 |
+
parser.add_argument("--candidates", dest="candidates_path", help="candidate JSON/JSONL for the selected detector")
|
| 695 |
+
parser.add_argument("--images-dir", dest="images_path", help="directory containing XR screenshots")
|
| 696 |
+
parser.add_argument("--output", dest="output_path", help="prediction JSON path; selection suffixes are added automatically")
|
| 697 |
+
parser.add_argument("--ape-root", help="APE repository directory")
|
| 698 |
+
parser.add_argument("--ape-checkpoint", help="APE checkpoint path")
|
| 699 |
+
parser.add_argument("--log-file", help="optional log file; defaults to stderr")
|
| 700 |
+
args = parser.parse_args()
|
| 701 |
+
|
| 702 |
+
gpu = '1-3'
|
| 703 |
+
stage = '1'
|
| 704 |
+
idx = '0001'
|
| 705 |
+
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
|
| 706 |
+
datefmt='%m/%d/%Y %H:%M:%S',
|
| 707 |
+
level=logging.INFO,
|
| 708 |
+
filename=args.log_file,
|
| 709 |
+
)
|
| 710 |
+
|
| 711 |
+
method(
|
| 712 |
+
args.vlm,
|
| 713 |
+
args.llm,
|
| 714 |
+
args.ovod,
|
| 715 |
+
start_index=args.start_index,
|
| 716 |
+
end_index=args.end_index,
|
| 717 |
+
shard_index=args.shard_index,
|
| 718 |
+
num_shards=args.num_shards,
|
| 719 |
+
enable_reflection=args.enable_reflection,
|
| 720 |
+
reflection_profile=args.reflection_profile,
|
| 721 |
+
max_reflection_iterations=args.max_reflection_iterations,
|
| 722 |
+
questions_path=args.questions_path,
|
| 723 |
+
candidates_path=args.candidates_path,
|
| 724 |
+
images_path=args.images_path,
|
| 725 |
+
output_path=args.output_path,
|
| 726 |
+
ape_root=args.ape_root,
|
| 727 |
+
ape_checkpoint=args.ape_checkpoint,
|
| 728 |
+
)
|
| 729 |
+
|
| 730 |
+
# CUDA_VISIBLE_DEVICES=0 python method.py -v gpt4v -l gpt_3.5_turbo -o ape_d > ../log/realfse/240910_gpt4v_2_g0_0001.txt
|
| 731 |
+
# CUDA_VISIBLE_DEVICES=3 python method.py -v gpt4v -l gpt_3.5_turbo -o ape_d_abl > ../log/realfse/240910_gpt4v_ape_d_abl_2_g3_0001.txt
|
| 732 |
+
# CUDA_VISIBLE_DEVICES=3 python method.py -v gpt4v_abl -l gpt_3.5_turbo -o ape_d > ../log/realfse/240912_gpt4v_abl_1_g1-3_0001.txt
|
approach/method_claude.py
ADDED
|
@@ -0,0 +1,656 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import re
|
| 3 |
+
import sys
|
| 4 |
+
import json
|
| 5 |
+
import time
|
| 6 |
+
import random
|
| 7 |
+
import string
|
| 8 |
+
import argparse
|
| 9 |
+
import pandas as pd
|
| 10 |
+
import copy
|
| 11 |
+
import logging
|
| 12 |
+
from tqdm import tqdm
|
| 13 |
+
import PIL
|
| 14 |
+
from PIL import ImageFile
|
| 15 |
+
PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True
|
| 16 |
+
|
| 17 |
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| 18 |
+
sys.path.append(BASE_DIR)
|
| 19 |
+
from approach.pipeline_utils import (
|
| 20 |
+
enrich_ape_results,
|
| 21 |
+
output_path_for_selection,
|
| 22 |
+
select_jsonl_lines,
|
| 23 |
+
write_json_atomic,
|
| 24 |
+
)
|
| 25 |
+
|
| 26 |
+
os.environ['TORCH_HOME'] = './.cache'
|
| 27 |
+
os.environ['HF_HOME'] = './.cache'
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
vlm = 'llava7b'
|
| 31 |
+
llm = 'gpt_3.5_turbo'
|
| 32 |
+
ovod = 'grounding_dino'
|
| 33 |
+
|
| 34 |
+
vlm_prompt = ''
|
| 35 |
+
|
| 36 |
+
### Configurable
|
| 37 |
+
host_device = os.getenv('ORIENTER_LEGACY_HOST', 'local')
|
| 38 |
+
perspective = 'all_perspective'
|
| 39 |
+
# perspective = 'direct_back'
|
| 40 |
+
# perspective = 'direct_front'
|
| 41 |
+
# perspective = 'direct_side'
|
| 42 |
+
# perspective = 'direct_top'
|
| 43 |
+
# perspective = 'eyelevel'
|
| 44 |
+
# perspective = 'overlook'
|
| 45 |
+
### Configurable
|
| 46 |
+
|
| 47 |
+
llava_path = os.path.join(BASE_DIR, 'approach/vlm/LLaVA/llava/eval')
|
| 48 |
+
grounding_dino_path = os.path.join(BASE_DIR, 'approach/ovod/GroundingDINO')
|
| 49 |
+
ape_path = os.path.join(BASE_DIR, 'approach/ovod/APE')
|
| 50 |
+
# TODO: data on the CUHK server
|
| 51 |
+
# images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_merged/images/interactable')
|
| 52 |
+
# icse
|
| 53 |
+
# images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_merged/images/test_set_merged')
|
| 54 |
+
# icse_rebuttal
|
| 55 |
+
# images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_angleview/images/all_perspective')
|
| 56 |
+
# fse
|
| 57 |
+
images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_det/images/union3')
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
# def generate_grounding_dino_command(ovod_image_path, ovod_output_dir, ovod_candidates):
|
| 61 |
+
# gdino_object_str = ' . '.join(ovod_candidates)
|
| 62 |
+
|
| 63 |
+
# gdino_command = f'''
|
| 64 |
+
# python demo/inference_on_a_image.py \
|
| 65 |
+
# -c groundingdino/config/GroundingDINO_SwinT_OGC.py \
|
| 66 |
+
# -p weights/groundingdino_swint_ogc.pth \
|
| 67 |
+
# -i {ovod_image_path} \
|
| 68 |
+
# -o "{ovod_output_dir}" \
|
| 69 |
+
# -t "{gdino_object_str}"
|
| 70 |
+
# '''
|
| 71 |
+
# return gdino_command
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def generate_question_file(img_folder, dst_path):
|
| 75 |
+
# Ensure the directory exists
|
| 76 |
+
if not os.path.exists(img_folder):
|
| 77 |
+
print(f"Error: Directory {img_folder} does not exist.")
|
| 78 |
+
return
|
| 79 |
+
|
| 80 |
+
# List all files in the directory
|
| 81 |
+
all_files = os.listdir(img_folder)
|
| 82 |
+
|
| 83 |
+
# Filter out files that are not images (based on extension). You can add more if needed.
|
| 84 |
+
image_extensions = [".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff"]
|
| 85 |
+
image_files = [f for f in all_files if any(f.lower().endswith(ext) for ext in image_extensions)]
|
| 86 |
+
|
| 87 |
+
# Open the output file for writing
|
| 88 |
+
with open(dst_path, 'w') as out_file:
|
| 89 |
+
for index, img_file in enumerate(image_files):
|
| 90 |
+
data = {
|
| 91 |
+
"question_id": index,
|
| 92 |
+
"image": img_file,
|
| 93 |
+
"text": vlm_prompt,
|
| 94 |
+
"category": "detail"
|
| 95 |
+
}
|
| 96 |
+
out_file.write(json.dumps(data) + '\n')
|
| 97 |
+
|
| 98 |
+
print(f"Processed {len(image_files)} images. Output saved to {dst_path}.")
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def generate_answer_id(length=20):
|
| 102 |
+
# Define the characters that can be used in the string
|
| 103 |
+
characters = string.ascii_letters + string.digits
|
| 104 |
+
# Generate a random string of the specified length
|
| 105 |
+
answer_id = ''.join(random.choice(characters) for _ in range(length))
|
| 106 |
+
return answer_id
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def method(vlm=vlm, llm=llm, ovod=ovod, start_index=None, end_index=None, shard_index=None, num_shards=None):
|
| 110 |
+
# vlm_question_path = os.path.join(BASE_DIR, 'approach/vlm/sampled_vlm_questions.jsonl')
|
| 111 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_test_set_merged_vlm_questions_from671.jsonl')
|
| 112 |
+
# icse
|
| 113 |
+
# complete_vlm_question_abl_i_path = os.path.join(BASE_DIR, f'approach/vlm/icse_test_set_merged_complete_vlm_questions_ablation_interactability.jsonl')
|
| 114 |
+
|
| 115 |
+
# icse
|
| 116 |
+
# complete_vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_test_set_merged_complete_vlm_questions.jsonl')
|
| 117 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/gpt4v_failure_questions.jsonl')
|
| 118 |
+
# icse_rebuttal
|
| 119 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_vlm_questions.jsonl')
|
| 120 |
+
# complete_vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_complete_vlm_questions.jsonl')
|
| 121 |
+
# fse
|
| 122 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/fse_union3_{vlm}_questions.jsonl')
|
| 123 |
+
complete_vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/realfse_union3_complete_{vlm}_questions.jsonl')
|
| 124 |
+
vlm_question_path = complete_vlm_question_path
|
| 125 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/gpt4v_failure_questions.jsonl')
|
| 126 |
+
# playground/data/coco2014_val_qa_eval/qa90_questions.jsonl
|
| 127 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer_slowerspeed_1.jsonl')
|
| 128 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer_higherspeed_r3_1_from195.jsonl')
|
| 129 |
+
|
| 130 |
+
# icse
|
| 131 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/cuhk_icse_test_set_merged_{vlm}_answer.jsonl')
|
| 132 |
+
# llava_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer.jsonl')
|
| 133 |
+
# gemini_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer_ablation_no_interactability_r1_0.jsonl')
|
| 134 |
+
# gpt4_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_cuhk_icse_test_set_merged_gpt4v_answer_higherspeed_r3_0.jsonl')
|
| 135 |
+
# interactability_abl_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_hit_icse_test_set_merged_gemini_answer_ablation_no_interactability_r1_0.jsonl')
|
| 136 |
+
# icse_rebuttal
|
| 137 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_{vlm}_answer.jsonl')
|
| 138 |
+
# llava_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_rbt_{perspective}_{vlm}_answer.jsonl')
|
| 139 |
+
# gemini_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_rbt_{perspective}_{vlm}_answer.jsonl')
|
| 140 |
+
# fse
|
| 141 |
+
vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/realfse_uninon3_{vlm}_answer.jsonl')
|
| 142 |
+
llava_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_fse_uninon3_{vlm}_answer.jsonl')
|
| 143 |
+
gemini_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/realfse_union3_{vlm}_answer.jsonl')
|
| 144 |
+
|
| 145 |
+
# icse
|
| 146 |
+
# gpt4_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_icse_rbt_{perspective}_gpt4v_answer.jsonl')
|
| 147 |
+
# icse_rebuttal
|
| 148 |
+
# gpt4_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_{vlm}_answer_265_528.jsonl')
|
| 149 |
+
# fse
|
| 150 |
+
gpt4_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/realfse_uninon3_gpt4v_answer.jsonl')
|
| 151 |
+
# print(gpt4_results_answer_path)
|
| 152 |
+
# interactability_abl_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_icse_rbt_{perspective}_answer.jsonl')
|
| 153 |
+
|
| 154 |
+
# icse
|
| 155 |
+
# # /path/to/answer-file-our.jsonl
|
| 156 |
+
# # llm_candidate_path = os.path.join(BASE_DIR, f'approach/llm/{vlm}_{llm}_cancidate_objects.json')
|
| 157 |
+
# interactable_object_path = os.path.join(BASE_DIR, f'approach/llm/icse_test_set_merged_{vlm}_{llm}_interactable_objects.json')
|
| 158 |
+
# ovod_output_dir = os.path.join(BASE_DIR, f'approach/ovod/output/icse_test_set_merged_{ovod}')
|
| 159 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_object_bbox_gpu3_2.json')
|
| 160 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_ablation_no_interactability_object_bbox_gpu0.json')
|
| 161 |
+
# oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_ablation_no_feedback_object_bbox_gpu2.json')
|
| 162 |
+
|
| 163 |
+
# icse_rebuttal
|
| 164 |
+
# interactable_object_path = os.path.join(BASE_DIR, f'approach/llm/icse_rbt_{perspective}_{vlm}_{llm}_interactable_objects.json')
|
| 165 |
+
# ovod_output_dir = os.path.join(BASE_DIR, f'approach/ovod/output/icse_rbt_{perspective}_{ovod}')
|
| 166 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_object_bbox_gpu3_2.json')
|
| 167 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_ablation_no_interactability_object_bbox_gpu0.json')
|
| 168 |
+
# oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_rbt_{perspective}_{vlm}_{llm}_{ovod}_object_bbox_gpu3_265_528.json')
|
| 169 |
+
|
| 170 |
+
gpu = '2'
|
| 171 |
+
# fse
|
| 172 |
+
interactable_object_path = os.path.join(BASE_DIR, f'approach/llm/realfse_union3_{vlm}_{llm}_interactable_objects.json') # TODO: Tentatively unused
|
| 173 |
+
ovod_output_dir = os.path.join(BASE_DIR, f'approach/ovod/output/realfse_union3_{ovod}')
|
| 174 |
+
# GPU 0
|
| 175 |
+
oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/realfse_union3_{vlm}_{ovod}_object_bbox_gpu{gpu}.json')
|
| 176 |
+
oovd_object_bbox_path = output_path_for_selection(
|
| 177 |
+
oovd_object_bbox_path,
|
| 178 |
+
start_index=start_index,
|
| 179 |
+
end_index=end_index,
|
| 180 |
+
shard_index=shard_index,
|
| 181 |
+
num_shards=num_shards,
|
| 182 |
+
)
|
| 183 |
+
|
| 184 |
+
llava7b_model_path = os.path.join(BASE_DIR, 'approach/vlm/LLaVA/checkpoints/llava-v1.5-7b')
|
| 185 |
+
llava7b_cmd = f'''
|
| 186 |
+
python model_vqa.py \
|
| 187 |
+
--model-path {llava7b_model_path} \
|
| 188 |
+
--question-file \
|
| 189 |
+
{complete_vlm_question_path} \
|
| 190 |
+
--image-folder \
|
| 191 |
+
{images_dir} \
|
| 192 |
+
--answers-file \
|
| 193 |
+
{llava_vlm_answer_path}
|
| 194 |
+
'''
|
| 195 |
+
|
| 196 |
+
# STEP #0
|
| 197 |
+
# First time of running
|
| 198 |
+
# TODO: Check whether it is first-time running
|
| 199 |
+
# generate_question_file(images_dir, vlm_question_path)
|
| 200 |
+
|
| 201 |
+
# STEP #1
|
| 202 |
+
# VLM - Get local context
|
| 203 |
+
# print(f'VLM {vlm} analysis begins ...')
|
| 204 |
+
# vlm_start_time = time.time()
|
| 205 |
+
# logging.info(f'STEP #1 VLM {vlm} analysis started at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 206 |
+
# if vlm == 'llava7b':
|
| 207 |
+
# original_path = os.path.dirname(__file__)
|
| 208 |
+
# os.chdir(llava_path)
|
| 209 |
+
# os.system(llava7b_cmd)
|
| 210 |
+
# os.chdir(original_path)
|
| 211 |
+
# elif vlm == 'generate_q_file':
|
| 212 |
+
# from approach.vlm.gpt4v.gpt4v import process_image_q
|
| 213 |
+
# with open(vlm_question_path, 'r') as q_file, open(complete_vlm_question_path, 'w') as cq_file: # Open answer file in append mode
|
| 214 |
+
# qfile_lines = q_file.readlines()
|
| 215 |
+
# key_idx = 0
|
| 216 |
+
# for line in tqdm(qfile_lines):
|
| 217 |
+
# key_idx = (key_idx + 1) % 4
|
| 218 |
+
|
| 219 |
+
# ans_item = {}
|
| 220 |
+
|
| 221 |
+
# line_data = json.loads(line)
|
| 222 |
+
# image_path = os.path.join(images_dir, line_data['image'])
|
| 223 |
+
# image_question = line_data['text']
|
| 224 |
+
|
| 225 |
+
# if vlm == 'gpt4v_abl':
|
| 226 |
+
# gpt4v_ablation = True
|
| 227 |
+
# elif vlm == 'gpt4v':
|
| 228 |
+
# gpt4v_ablation = False
|
| 229 |
+
# gpt4v_q = process_image_q(image_question, image_path, key_idx)
|
| 230 |
+
# data = {
|
| 231 |
+
# "question_id": line_data['question_id'],
|
| 232 |
+
# "image": line_data['image'],
|
| 233 |
+
# "text": gpt4v_q,
|
| 234 |
+
# "category": "detail"
|
| 235 |
+
# }
|
| 236 |
+
# cq_file.write(json.dumps(data) + '\n')
|
| 237 |
+
# elif vlm == 'gpt4v' or vlm == 'gpt4v_abl' or vlm == 'claude35sonnet' or vlm == 'gemini15pro':
|
| 238 |
+
# from approach.vlm.gpt4v.gpt4v import process_image
|
| 239 |
+
# with open(vlm_question_path, 'r') as q_file, open(vlm_answer_path, 'a') as a_file: # Open answer file in append mode
|
| 240 |
+
# qfile_lines = q_file.readlines()
|
| 241 |
+
# key_idx = 0
|
| 242 |
+
# for line in tqdm(qfile_lines):
|
| 243 |
+
# key_idx = (key_idx + 1) % 4
|
| 244 |
+
|
| 245 |
+
# ans_item = {}
|
| 246 |
+
|
| 247 |
+
# line_data = json.loads(line)
|
| 248 |
+
# image_path = os.path.join(images_dir, line_data['image'])
|
| 249 |
+
# image_question = line_data['text']
|
| 250 |
+
|
| 251 |
+
# gpt4v_ablation = False
|
| 252 |
+
# if vlm == 'gpt4v_abl':
|
| 253 |
+
# gpt4v_ablation = True
|
| 254 |
+
# elif vlm == 'gpt4v':
|
| 255 |
+
# gpt4v_ablation = False
|
| 256 |
+
# gpt4v_res = process_image(vlm, image_question, image_path, gpt4v_ablation, key_idx)
|
| 257 |
+
# print(gpt4v_res)
|
| 258 |
+
# # time.sleep(3)
|
| 259 |
+
|
| 260 |
+
# ans_item = {
|
| 261 |
+
# "question_id": line_data['question_id'],
|
| 262 |
+
# "prompt": '',
|
| 263 |
+
# "text": gpt4v_res,
|
| 264 |
+
# "answer_id": generate_answer_id(),
|
| 265 |
+
# "model_id": vlm,
|
| 266 |
+
# "metadata": {}
|
| 267 |
+
# }
|
| 268 |
+
|
| 269 |
+
# a_file.write(json.dumps(ans_item) + '\n')
|
| 270 |
+
# a_file.flush()
|
| 271 |
+
# elif vlm == 'bing':
|
| 272 |
+
# from approach.vlm.bing.bing import context_conversation
|
| 273 |
+
# with open(vlm_question_path, 'r') as q_file, open(vlm_answer_path, 'a') as a_file: # Open answer file in append mode
|
| 274 |
+
# for line in tqdm(q_file):
|
| 275 |
+
# ans_item = {}
|
| 276 |
+
|
| 277 |
+
# line_data = json.loads(line)
|
| 278 |
+
# image_path = os.path.join(images_dir, line_data['image'])
|
| 279 |
+
# image_question = line_data['text']
|
| 280 |
+
|
| 281 |
+
# bing_res = context_conversation(image_question, image_path)
|
| 282 |
+
# print(bing_res)
|
| 283 |
+
# time.sleep(15)
|
| 284 |
+
|
| 285 |
+
# ans_item = {
|
| 286 |
+
# "question_id": line_data['question_id'],
|
| 287 |
+
# "prompt": image_question,
|
| 288 |
+
# "text": bing_res,
|
| 289 |
+
# "answer_id": generate_answer_id(),
|
| 290 |
+
# "model_id": vlm,
|
| 291 |
+
# "metadata": {}
|
| 292 |
+
# }
|
| 293 |
+
|
| 294 |
+
# a_file.write(json.dumps(ans_item) + '\n')
|
| 295 |
+
# elif vlm == 'gemini':
|
| 296 |
+
# import pathlib
|
| 297 |
+
# import textwrap
|
| 298 |
+
|
| 299 |
+
# import google.generativeai as genai
|
| 300 |
+
|
| 301 |
+
# GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY", "[GOOGLE_API_KEY]")
|
| 302 |
+
# genai.configure(api_key=GOOGLE_API_KEY)
|
| 303 |
+
|
| 304 |
+
# safety_settings = [
|
| 305 |
+
# {
|
| 306 |
+
# "category": "HARM_CATEGORY_DANGEROUS",
|
| 307 |
+
# "threshold": "BLOCK_NONE",
|
| 308 |
+
# },
|
| 309 |
+
# {
|
| 310 |
+
# "category": "HARM_CATEGORY_HARASSMENT",
|
| 311 |
+
# "threshold": "BLOCK_NONE",
|
| 312 |
+
# },
|
| 313 |
+
# {
|
| 314 |
+
# "category": "HARM_CATEGORY_HATE_SPEECH",
|
| 315 |
+
# "threshold": "BLOCK_NONE",
|
| 316 |
+
# },
|
| 317 |
+
# {
|
| 318 |
+
# "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
| 319 |
+
# "threshold": "BLOCK_NONE",
|
| 320 |
+
# },
|
| 321 |
+
# {
|
| 322 |
+
# "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
| 323 |
+
# "threshold": "BLOCK_NONE",
|
| 324 |
+
# },
|
| 325 |
+
# ]
|
| 326 |
+
|
| 327 |
+
# # before fse
|
| 328 |
+
# # model = genai.GenerativeModel('gemini-pro-vision')
|
| 329 |
+
# # fse
|
| 330 |
+
# model = genai.GenerativeModel('gemini-1.5-pro')
|
| 331 |
+
|
| 332 |
+
# with open(vlm_question_path, 'r') as q_file, open(gemini_vlm_answer_path, 'a') as a_file: # Open answer file in append mode
|
| 333 |
+
# qfile_lines = q_file.readlines()[0:2]
|
| 334 |
+
# for line in tqdm(qfile_lines):
|
| 335 |
+
|
| 336 |
+
# ans_item = {}
|
| 337 |
+
|
| 338 |
+
# line_data = json.loads(line)
|
| 339 |
+
# image_path = os.path.join(images_dir, line_data['image'])
|
| 340 |
+
# image_question = line_data['text']
|
| 341 |
+
|
| 342 |
+
# gemini_response = model.generate_content([image_question, PIL.Image.open(image_path)], safety_settings=safety_settings)
|
| 343 |
+
# gemini_response.resolve()
|
| 344 |
+
# try:
|
| 345 |
+
# gemini_response = gemini_response.text
|
| 346 |
+
# ans_item = {
|
| 347 |
+
# "question_id": line_data['question_id'],
|
| 348 |
+
# "prompt": image_question,
|
| 349 |
+
# "text": gemini_response,
|
| 350 |
+
# "answer_id": generate_answer_id(),
|
| 351 |
+
# "model_id": vlm,
|
| 352 |
+
# "metadata": {}
|
| 353 |
+
# }
|
| 354 |
+
|
| 355 |
+
# a_file.write(json.dumps(ans_item) + '\n')
|
| 356 |
+
# a_file.flush()
|
| 357 |
+
# except Exception as e:
|
| 358 |
+
# print(f"Error for image {image_path}. Error: {e}")
|
| 359 |
+
# # print(gemini_response)
|
| 360 |
+
# time.sleep(30)
|
| 361 |
+
|
| 362 |
+
|
| 363 |
+
|
| 364 |
+
# elif vlm.endswith('_pass'):
|
| 365 |
+
# print(f'Passing VLM {vlm} ...')
|
| 366 |
+
# else:
|
| 367 |
+
# raise Exception('Unrecognized VLM!')
|
| 368 |
+
|
| 369 |
+
# logging.info(f'STEP #1 VLM {vlm} analysis completed at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 370 |
+
# logging.info(f'STEP #1 VLM {vlm} analysis total time taken: {time.time() - vlm_start_time} seconds')
|
| 371 |
+
|
| 372 |
+
|
| 373 |
+
|
| 374 |
+
|
| 375 |
+
|
| 376 |
+
# Get label candidates
|
| 377 |
+
# if llm == 'gpt_3.5_turbo':
|
| 378 |
+
# from approach.llm.gpt_polling import infer_object_candidates
|
| 379 |
+
# elif llm == 'llama2':
|
| 380 |
+
# from approach.llm.llama import infer_object_candidates
|
| 381 |
+
|
| 382 |
+
|
| 383 |
+
# STEP #3
|
| 384 |
+
# if llm == 'gpt_3.5_turbo' or llm == 'gpt_3.5_turbo_abl':
|
| 385 |
+
# from approach.llm.gpt_polling import infer_objects
|
| 386 |
+
|
| 387 |
+
# if llm == 'gpt_3.5_turbo_abl':
|
| 388 |
+
# gpt35_ablation = True
|
| 389 |
+
# elif llm == 'gpt_3.5_turbo':
|
| 390 |
+
# gpt35_ablation = False
|
| 391 |
+
# infer_objects(vlm_question_path, vlm_answer_path, interactable_object_path, gpt35_ablation)
|
| 392 |
+
# elif llm == 'llama2':
|
| 393 |
+
# from approach.llm.llama import infer_objects
|
| 394 |
+
# exit(0)
|
| 395 |
+
# elif llm.endswith('_pass'):
|
| 396 |
+
# print(f'Passing LLM {llm} ...')
|
| 397 |
+
# else:
|
| 398 |
+
# raise Exception('Unrecognized LLM!')
|
| 399 |
+
|
| 400 |
+
|
| 401 |
+
|
| 402 |
+
|
| 403 |
+
|
| 404 |
+
|
| 405 |
+
# STEP #2
|
| 406 |
+
# Open-vocabulary object detection
|
| 407 |
+
ovod_start_time = time.time()
|
| 408 |
+
logging.info(f'STEP #2 OVOD {ovod} analysis started at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 409 |
+
vlm_questions = {}
|
| 410 |
+
with open(complete_vlm_question_path, 'r') as q_file:
|
| 411 |
+
for line in q_file:
|
| 412 |
+
line_data = json.loads(line)
|
| 413 |
+
vlm_questions[line_data['question_id']] = line_data
|
| 414 |
+
# print(line_data['question_id'])
|
| 415 |
+
|
| 416 |
+
if ovod == 'grounding_dino':
|
| 417 |
+
from approach.ovod.GroundingDINO.demo.inference_on_a_image import process_grounding_dino
|
| 418 |
+
|
| 419 |
+
original_path = os.path.dirname(__file__)
|
| 420 |
+
os.chdir(grounding_dino_path)
|
| 421 |
+
|
| 422 |
+
# with open(llm_candidate_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 423 |
+
with open(interactable_object_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 424 |
+
llm_candidate = json.load(llm_candidate_file)
|
| 425 |
+
all_oovd_res = {}
|
| 426 |
+
for image_index in llm_candidate.keys():
|
| 427 |
+
print(image_index)
|
| 428 |
+
# TODO:
|
| 429 |
+
if (image_index != '1160'):
|
| 430 |
+
ovod_image_path = os.path.join(images_dir, vlm_questions[int(image_index)]["image"])
|
| 431 |
+
ovod_candidates = llm_candidate[image_index]['interactable_objects']
|
| 432 |
+
# grounding_dino_command = generate_grounding_dino_command(ovod_image_path, ovod_output_dir, ovod_candidates)
|
| 433 |
+
# print(grounding_dino_command)
|
| 434 |
+
# os.system(grounding_dino_command)
|
| 435 |
+
|
| 436 |
+
gdino_res = process_grounding_dino(
|
| 437 |
+
config_file='groundingdino/config/GroundingDINO_SwinT_OGC.py',
|
| 438 |
+
checkpoint_path='weights/groundingdino_swint_ogc.pth',
|
| 439 |
+
image_path=ovod_image_path,
|
| 440 |
+
ovod_candidates=ovod_candidates,
|
| 441 |
+
output_dir=ovod_output_dir,
|
| 442 |
+
box_threshold=0.3,
|
| 443 |
+
text_threshold=0.25,
|
| 444 |
+
token_spans=None,
|
| 445 |
+
cpu_only=False
|
| 446 |
+
)
|
| 447 |
+
# print(gdino_res)
|
| 448 |
+
|
| 449 |
+
object_oovd_item = copy.deepcopy(llm_candidate[image_index])
|
| 450 |
+
object_oovd_item['oovd_result'] = gdino_res
|
| 451 |
+
print(object_oovd_item)
|
| 452 |
+
all_oovd_res[image_index] = object_oovd_item
|
| 453 |
+
|
| 454 |
+
json.dump(all_oovd_res, oovd_file, indent=4)
|
| 455 |
+
|
| 456 |
+
|
| 457 |
+
os.chdir(original_path)
|
| 458 |
+
|
| 459 |
+
elif ovod == 'ape_d' or ovod == 'ape_d_abl':
|
| 460 |
+
from approach.ovod.APE.demo.ape_inference import run_ape_model_inference
|
| 461 |
+
|
| 462 |
+
original_path = os.path.dirname(__file__)
|
| 463 |
+
os.chdir(ape_path)
|
| 464 |
+
|
| 465 |
+
# with open(llm_candidate_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 466 |
+
|
| 467 |
+
all_ape_res = []
|
| 468 |
+
# General
|
| 469 |
+
with open(vlm_answer_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 470 |
+
# GPT-4 eval
|
| 471 |
+
# with open(gpt4_results_answer_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 472 |
+
# Gemini abl i eval
|
| 473 |
+
# with open(interactability_abl_results_answer_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 474 |
+
|
| 475 |
+
# llm_candidate = json.load(llm_candidate_file)
|
| 476 |
+
all_oovd_res = {}
|
| 477 |
+
|
| 478 |
+
|
| 479 |
+
# candidate_lines = llm_candidate_file.readlines()[265:528]
|
| 480 |
+
# GPU 0
|
| 481 |
+
# candidate_lines = llm_candidate_file.readlines()[0:230]
|
| 482 |
+
# candidate_lines = llm_candidate_file.readlines()[230:460]
|
| 483 |
+
candidate_lines = select_jsonl_lines(
|
| 484 |
+
llm_candidate_file.readlines(),
|
| 485 |
+
start_index=start_index,
|
| 486 |
+
end_index=end_index,
|
| 487 |
+
shard_index=shard_index,
|
| 488 |
+
num_shards=num_shards,
|
| 489 |
+
)
|
| 490 |
+
# candidate_lines = llm_candidate_file.readlines()[690:919]
|
| 491 |
+
# candidate_lines = llm_candidate_file.readlines()
|
| 492 |
+
for line in tqdm(candidate_lines):
|
| 493 |
+
ans_item = {}
|
| 494 |
+
|
| 495 |
+
line_data = json.loads(line)
|
| 496 |
+
|
| 497 |
+
# for image_index in llm_candidate.keys():
|
| 498 |
+
# print(image_index)
|
| 499 |
+
# TODO:
|
| 500 |
+
# if (image_index != '1160'):
|
| 501 |
+
# image_index = line_data['question_id']
|
| 502 |
+
|
| 503 |
+
image_name = vlm_questions[line_data['question_id']]["image"]
|
| 504 |
+
ovod_image_path = os.path.join(images_dir, image_name)
|
| 505 |
+
|
| 506 |
+
# General
|
| 507 |
+
# try:
|
| 508 |
+
# if line_data['text'].startswith(" ```json"):
|
| 509 |
+
# ovod_candidates = json.loads(line_data['text'][8:-4])['objects']
|
| 510 |
+
# elif line_data['text'].startswith(' {\"objects\"'):
|
| 511 |
+
# ovod_candidates = json.loads(line_data['text'])['objects']
|
| 512 |
+
# else:
|
| 513 |
+
# print(f"Error for decoding IVO json for {image_name}.")
|
| 514 |
+
# except Exception as e:
|
| 515 |
+
# print(f"Error for decoding IVO json for image {image_name}. Error: {e}")
|
| 516 |
+
# continue
|
| 517 |
+
|
| 518 |
+
|
| 519 |
+
# GPT-4v
|
| 520 |
+
if line_data['text']:
|
| 521 |
+
ovod_candidates = line_data['text']['objects']
|
| 522 |
+
else:
|
| 523 |
+
continue
|
| 524 |
+
|
| 525 |
+
|
| 526 |
+
all_res = []
|
| 527 |
+
for ocd in ovod_candidates.keys():
|
| 528 |
+
referring_expr_str = ovod_candidates[ocd]
|
| 529 |
+
|
| 530 |
+
translator = str.maketrans('', '', string.punctuation)
|
| 531 |
+
if type(referring_expr_str) is str:
|
| 532 |
+
referring_expr_str = referring_expr_str.translate(translator)
|
| 533 |
+
else:
|
| 534 |
+
# dict
|
| 535 |
+
referring_expr_str = ' '.join(referring_expr_str.values())
|
| 536 |
+
referring_expr_str = referring_expr_str.translate(translator)
|
| 537 |
+
referring_expr_str = f'{ocd}: {referring_expr_str}'
|
| 538 |
+
# print(image_name, referring_expr_str)
|
| 539 |
+
all_res.append(referring_expr_str)
|
| 540 |
+
|
| 541 |
+
if ovod == 'ape_d':
|
| 542 |
+
ape_threshold = 0.15
|
| 543 |
+
elif ovod == 'ape_d_abl':
|
| 544 |
+
ape_threshold = 0.1
|
| 545 |
+
|
| 546 |
+
ape_res = []
|
| 547 |
+
try:
|
| 548 |
+
ape_res = run_ape_model_inference(
|
| 549 |
+
config_file='configs/LVISCOCOCOCOSTUFF_O365_OID_VGR_SA1B_REFCOCO_GQA_PhraseCut_Flickr30k/ape_deta/ape_deta_vitl_eva02_clip_vlf_lsj1024_cp_16x4_1080k.py',
|
| 550 |
+
input_path=ovod_image_path,
|
| 551 |
+
# GPU 0
|
| 552 |
+
output_path=f'./realfse_{vlm}_{ovod}_gpu0123',
|
| 553 |
+
confidence_threshold=ape_threshold,
|
| 554 |
+
text_prompt=', '.join(all_res),
|
| 555 |
+
with_box=True,
|
| 556 |
+
with_mask=False,
|
| 557 |
+
with_sseg=False,
|
| 558 |
+
opts=[
|
| 559 |
+
"train.init_checkpoint='./ape_d_model_final.pth'",
|
| 560 |
+
"model.model_language.cache_dir=''",
|
| 561 |
+
"model.model_vision.select_box_nums_for_evaluation=500",
|
| 562 |
+
"model.model_vision.text_feature_bank_reset=True",
|
| 563 |
+
"model.model_vision.backbone.net.xattn=False",
|
| 564 |
+
"model.model_vision.transformer.encoder.pytorch_attn=True",
|
| 565 |
+
"model.model_vision.transformer.decoder.pytorch_attn=True"
|
| 566 |
+
]
|
| 567 |
+
)
|
| 568 |
+
except Exception as e:
|
| 569 |
+
print(f"Error for image {image_name}. Error: {e}")
|
| 570 |
+
|
| 571 |
+
all_ape_res.extend(enrich_ape_results(ape_res, image_name, extract_image_id))
|
| 572 |
+
# object_oovd_item = copy.deepcopy(llm_candidate[image_index])
|
| 573 |
+
# object_oovd_item['ape_result'] = all_ape_res
|
| 574 |
+
# # print(object_oovd_item)
|
| 575 |
+
# all_oovd_res[image_index] = object_oovd_item
|
| 576 |
+
|
| 577 |
+
write_json_atomic(oovd_object_bbox_path, all_ape_res)
|
| 578 |
+
|
| 579 |
+
|
| 580 |
+
os.chdir(original_path)
|
| 581 |
+
|
| 582 |
+
elif ovod.endswith('_pass'):
|
| 583 |
+
print(f'Passing OVOD {ovod} ...')
|
| 584 |
+
else:
|
| 585 |
+
raise Exception('Unrecognized OVOD!')
|
| 586 |
+
|
| 587 |
+
logging.info(f'STEP #2 OVOD {ovod} analysis completed at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 588 |
+
logging.info(f'STEP #2 OVOD {ovod} analysis total time taken: {time.time() - ovod_start_time} seconds')
|
| 589 |
+
|
| 590 |
+
# icse & fse
|
| 591 |
+
def extract_image_id(image_name):
|
| 592 |
+
# Split the image name into parts and form the image_id accordingly
|
| 593 |
+
parts = image_name.split('_')
|
| 594 |
+
print(image_name)
|
| 595 |
+
base, extension = parts[1].split('.')
|
| 596 |
+
return int(parts[0] + base.zfill(3))
|
| 597 |
+
# icse_rebuttal
|
| 598 |
+
# def extract_image_id(image_name):
|
| 599 |
+
# # Split the image name into parts by underscore
|
| 600 |
+
# parts = image_name.split('_')
|
| 601 |
+
# # Extracting the first part as the base and the numeric portion of the third part before the file extension
|
| 602 |
+
# base = parts[0] # This will give '625470'
|
| 603 |
+
# numeric_part = parts[2].split('.')[0] # This will give 'b3'
|
| 604 |
+
# # Removing non-numeric characters from 'b3'
|
| 605 |
+
# numeric_part = ''.join(filter(str.isdigit, numeric_part))
|
| 606 |
+
# # Zfill is used to ensure the numeric part has at least 3 digits, then combining with base
|
| 607 |
+
# print(int(base + numeric_part.zfill(3)))
|
| 608 |
+
# return int(base + numeric_part.zfill(3))
|
| 609 |
+
|
| 610 |
+
|
| 611 |
+
def main():
|
| 612 |
+
vlms = ['llava7b', 'bing', 'gpt4v']
|
| 613 |
+
llms = ['llama2', 'gpt_3.5_turbo']
|
| 614 |
+
ovods = ['grounding_dino', 'glip', 'ape_d']
|
| 615 |
+
|
| 616 |
+
|
| 617 |
+
# python method.py -v gpt4v -l gpt_3.5_turbo -o ape_d
|
| 618 |
+
# python method.py -v gpt4v -l gpt_3.5_turbo -o ape_d_abl
|
| 619 |
+
# python method.py -v claude35sonnet -l gpt_3.5_turbo -o ape_d
|
| 620 |
+
# python method.py -v gemini -l gpt_3.5_turbo -o ape_d
|
| 621 |
+
if __name__=='__main__':
|
| 622 |
+
# main()
|
| 623 |
+
|
| 624 |
+
parser = argparse.ArgumentParser("Method", add_help=True)
|
| 625 |
+
parser.add_argument("--vlm", "-v", type=str, required=True, help="vlm")
|
| 626 |
+
parser.add_argument("--llm", "-l", type=str, required=True, help="llm")
|
| 627 |
+
parser.add_argument("--ovod", "-o", type=str, required=True, help="ovod")
|
| 628 |
+
parser.add_argument("--start-index", type=int, default=None, help="first JSONL row to process")
|
| 629 |
+
parser.add_argument("--end-index", type=int, default=None, help="exclusive JSONL row end")
|
| 630 |
+
parser.add_argument("--shard-index", type=int, default=None, help="zero-based shard index")
|
| 631 |
+
parser.add_argument("--num-shards", type=int, default=None, help="total number of shards")
|
| 632 |
+
args = parser.parse_args()
|
| 633 |
+
|
| 634 |
+
gpu = '2'
|
| 635 |
+
stage = '2'
|
| 636 |
+
idx = '0001'
|
| 637 |
+
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
|
| 638 |
+
datefmt='%m/%d/%Y %H:%M:%S',
|
| 639 |
+
level=logging.INFO,
|
| 640 |
+
# gpu
|
| 641 |
+
filename=f'../log/realfse/240910_{args.vlm}_{stage}_g{gpu}_{idx}.log'
|
| 642 |
+
)
|
| 643 |
+
|
| 644 |
+
method(
|
| 645 |
+
args.vlm,
|
| 646 |
+
args.llm,
|
| 647 |
+
args.ovod,
|
| 648 |
+
start_index=args.start_index,
|
| 649 |
+
end_index=args.end_index,
|
| 650 |
+
shard_index=args.shard_index,
|
| 651 |
+
num_shards=args.num_shards,
|
| 652 |
+
)
|
| 653 |
+
|
| 654 |
+
# CUDA_VISIBLE_DEVICES=0 python method.py -v gpt4v -l gpt_3.5_turbo -o ape_d > ../log/realfse/240910_gpt4v_2_g0_0001.txt
|
| 655 |
+
# CUDA_VISIBLE_DEVICES=3 python method_gemini.py -v gemini15pro -l gpt_3.5_turbo -o ape_d > ../log/realfse/240910_gemini15pro_2_g3_0001.txt
|
| 656 |
+
# CUDA_VISIBLE_DEVICES=2 python method_claude.py -v claude35sonnet -l gpt_3.5_turbo -o ape_d > ../log/realfse/240910_claude35sonnet_2_g2_0001.txt
|
approach/method_fastuse.py
ADDED
|
@@ -0,0 +1,736 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
import json
|
| 4 |
+
import time
|
| 5 |
+
import random
|
| 6 |
+
import string
|
| 7 |
+
import argparse
|
| 8 |
+
import copy
|
| 9 |
+
import logging
|
| 10 |
+
from tqdm import tqdm
|
| 11 |
+
import PIL
|
| 12 |
+
from PIL import ImageFile
|
| 13 |
+
PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True
|
| 14 |
+
|
| 15 |
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
| 16 |
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| 17 |
+
sys.path.append(BASE_DIR)
|
| 18 |
+
from approach.pipeline_utils import (
|
| 19 |
+
enrich_ape_results,
|
| 20 |
+
output_path_for_selection,
|
| 21 |
+
run_optional_reflection,
|
| 22 |
+
select_jsonl_lines,
|
| 23 |
+
write_json_atomic,
|
| 24 |
+
)
|
| 25 |
+
|
| 26 |
+
os.environ['TORCH_HOME'] = './.cache'
|
| 27 |
+
os.environ['HF_HOME'] = './.cache'
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
vlm = 'llava7b'
|
| 31 |
+
llm = 'gemini-3-flash-preview-nothinking'
|
| 32 |
+
ovod = 'ape_d'
|
| 33 |
+
|
| 34 |
+
vlm_prompt = ''
|
| 35 |
+
|
| 36 |
+
### Configurable
|
| 37 |
+
host_device = os.getenv('ORIENTER_LEGACY_HOST', 'local')
|
| 38 |
+
perspective = 'all_perspective'
|
| 39 |
+
# perspective = 'direct_back'
|
| 40 |
+
# perspective = 'direct_front'
|
| 41 |
+
# perspective = 'direct_side'
|
| 42 |
+
# perspective = 'direct_top'
|
| 43 |
+
# perspective = 'eyelevel'
|
| 44 |
+
# perspective = 'overlook'
|
| 45 |
+
### Configurable
|
| 46 |
+
|
| 47 |
+
llava_path = os.path.join(BASE_DIR, 'approach/vlm/LLaVA/llava/eval')
|
| 48 |
+
grounding_dino_path = os.path.join(BASE_DIR, 'approach/ovod/GroundingDINO')
|
| 49 |
+
ape_path = os.path.join(BASE_DIR, 'approach/ovod/APE')
|
| 50 |
+
# TODO: data on the CUHK server
|
| 51 |
+
# images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_merged/images/interactable')
|
| 52 |
+
# icse
|
| 53 |
+
# images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_merged/images/test_set_merged')
|
| 54 |
+
# icse_rebuttal
|
| 55 |
+
# images_dir = os.path.join(BASE_DIR, 'dataset/data/coco_angleview/images/all_perspective')
|
| 56 |
+
# fse
|
| 57 |
+
images_dir = os.path.join(BASE_DIR, 'fastimg')
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
# def generate_grounding_dino_command(ovod_image_path, ovod_output_dir, ovod_candidates):
|
| 61 |
+
# gdino_object_str = ' . '.join(ovod_candidates)
|
| 62 |
+
|
| 63 |
+
# gdino_command = f'''
|
| 64 |
+
# python demo/inference_on_a_image.py \
|
| 65 |
+
# -c groundingdino/config/GroundingDINO_SwinT_OGC.py \
|
| 66 |
+
# -p weights/groundingdino_swint_ogc.pth \
|
| 67 |
+
# -i {ovod_image_path} \
|
| 68 |
+
# -o "{ovod_output_dir}" \
|
| 69 |
+
# -t "{gdino_object_str}"
|
| 70 |
+
# '''
|
| 71 |
+
# return gdino_command
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def generate_question_file(img_folder, dst_path):
|
| 75 |
+
# Ensure the directory exists
|
| 76 |
+
if not os.path.exists(img_folder):
|
| 77 |
+
print(f"Error: Directory {img_folder} does not exist.")
|
| 78 |
+
return
|
| 79 |
+
|
| 80 |
+
# List all files in the directory
|
| 81 |
+
all_files = os.listdir(img_folder)
|
| 82 |
+
|
| 83 |
+
# Filter out files that are not images (based on extension). You can add more if needed.
|
| 84 |
+
image_extensions = [".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff"]
|
| 85 |
+
image_files = [f for f in all_files if any(f.lower().endswith(ext) for ext in image_extensions)]
|
| 86 |
+
|
| 87 |
+
# Open the output file for writing
|
| 88 |
+
with open(dst_path, 'w') as out_file:
|
| 89 |
+
for index, img_file in enumerate(image_files):
|
| 90 |
+
data = {
|
| 91 |
+
"question_id": index,
|
| 92 |
+
"image": img_file,
|
| 93 |
+
"text": vlm_prompt,
|
| 94 |
+
"category": "detail"
|
| 95 |
+
}
|
| 96 |
+
out_file.write(json.dumps(data) + '\n')
|
| 97 |
+
|
| 98 |
+
print(f"Processed {len(image_files)} images. Output saved to {dst_path}.")
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def generate_answer_id(length=20):
|
| 102 |
+
# Define the characters that can be used in the string
|
| 103 |
+
characters = string.ascii_letters + string.digits
|
| 104 |
+
# Generate a random string of the specified length
|
| 105 |
+
answer_id = ''.join(random.choice(characters) for _ in range(length))
|
| 106 |
+
return answer_id
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def method(
|
| 110 |
+
vlm=vlm,
|
| 111 |
+
llm=llm,
|
| 112 |
+
ovod=ovod,
|
| 113 |
+
start_index=None,
|
| 114 |
+
end_index=None,
|
| 115 |
+
shard_index=None,
|
| 116 |
+
num_shards=None,
|
| 117 |
+
enable_reflection=False,
|
| 118 |
+
reflection_profile="default",
|
| 119 |
+
max_reflection_iterations=10,
|
| 120 |
+
questions_path=None,
|
| 121 |
+
candidates_path=None,
|
| 122 |
+
images_path=None,
|
| 123 |
+
output_path=None,
|
| 124 |
+
ape_root=None,
|
| 125 |
+
ape_checkpoint=None,
|
| 126 |
+
):
|
| 127 |
+
images_dir = images_path or globals()["images_dir"]
|
| 128 |
+
active_ape_path = ape_root or globals()["ape_path"]
|
| 129 |
+
active_ape_checkpoint = ape_checkpoint or "./ape_d_model_final.pth"
|
| 130 |
+
# vlm_question_path = os.path.join(BASE_DIR, 'approach/vlm/sampled_vlm_questions.jsonl')
|
| 131 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_test_set_merged_vlm_questions_from671.jsonl')
|
| 132 |
+
# icse
|
| 133 |
+
# complete_vlm_question_abl_i_path = os.path.join(BASE_DIR, f'approach/vlm/icse_test_set_merged_complete_vlm_questions_ablation_interactability.jsonl')
|
| 134 |
+
|
| 135 |
+
# icse
|
| 136 |
+
# complete_vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_test_set_merged_complete_vlm_questions.jsonl')
|
| 137 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/gpt4v_failure_questions.jsonl')
|
| 138 |
+
# icse_rebuttal
|
| 139 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_vlm_questions.jsonl')
|
| 140 |
+
# complete_vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_complete_vlm_questions.jsonl')
|
| 141 |
+
# fse
|
| 142 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/fse_fastuse_{vlm}_questions.jsonl')
|
| 143 |
+
complete_vlm_question_path = questions_path or os.path.join(BASE_DIR, f'approach/vlm/realfse_fastuse_complete_{vlm}_questions.jsonl')
|
| 144 |
+
vlm_question_path = complete_vlm_question_path
|
| 145 |
+
# vlm_question_path = os.path.join(BASE_DIR, f'approach/vlm/gpt4v_failure_questions.jsonl')
|
| 146 |
+
# playground/data/coco2014_val_qa_eval/qa90_questions.jsonl
|
| 147 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer_slowerspeed_1.jsonl')
|
| 148 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer_higherspeed_r3_1_from195.jsonl')
|
| 149 |
+
|
| 150 |
+
# icse
|
| 151 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/cuhk_icse_test_set_merged_{vlm}_answer.jsonl')
|
| 152 |
+
# llava_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer.jsonl')
|
| 153 |
+
# gemini_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_test_set_merged_{vlm}_answer_ablation_no_interactability_r1_0.jsonl')
|
| 154 |
+
# gpt4_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_cuhk_icse_test_set_merged_gpt4v_answer_higherspeed_r3_0.jsonl')
|
| 155 |
+
# interactability_abl_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_hit_icse_test_set_merged_gemini_answer_ablation_no_interactability_r1_0.jsonl')
|
| 156 |
+
# icse_rebuttal
|
| 157 |
+
# vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_{vlm}_answer.jsonl')
|
| 158 |
+
# llava_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_rbt_{perspective}_{vlm}_answer.jsonl')
|
| 159 |
+
# gemini_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_icse_rbt_{perspective}_{vlm}_answer.jsonl')
|
| 160 |
+
# fse
|
| 161 |
+
vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/realfse_fastuse_{vlm}_answer.jsonl')
|
| 162 |
+
llava_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/{host_device}_fse_fastuse_{vlm}_answer.jsonl')
|
| 163 |
+
gemini_vlm_answer_path = os.path.join(BASE_DIR, f'approach/vlm/realfse_fastuse_{vlm}_answer.jsonl')
|
| 164 |
+
|
| 165 |
+
# icse
|
| 166 |
+
# gpt4_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_icse_rbt_{perspective}_gpt4v_answer.jsonl')
|
| 167 |
+
# icse_rebuttal
|
| 168 |
+
# gpt4_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/icse_rbt_{perspective}_{vlm}_answer_265_528.jsonl')
|
| 169 |
+
# fse
|
| 170 |
+
gpt4_results_answer_path = candidates_path or os.path.join(BASE_DIR, f'approach/vlm/realfse_fastuse_gpt4v_answer.jsonl')
|
| 171 |
+
# print(gpt4_results_answer_path)
|
| 172 |
+
# interactability_abl_results_answer_path = os.path.join(BASE_DIR, f'approach/vlm/aaa_icse_rbt_{perspective}_answer.jsonl')
|
| 173 |
+
|
| 174 |
+
# icse
|
| 175 |
+
# # /path/to/answer-file-our.jsonl
|
| 176 |
+
# # llm_candidate_path = os.path.join(BASE_DIR, f'approach/llm/{vlm}_{llm}_cancidate_objects.json')
|
| 177 |
+
# interactable_object_path = os.path.join(BASE_DIR, f'approach/llm/icse_test_set_merged_{vlm}_{llm}_interactable_objects.json')
|
| 178 |
+
# ovod_output_dir = os.path.join(BASE_DIR, f'approach/ovod/output/icse_test_set_merged_{ovod}')
|
| 179 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_object_bbox_gpu3_2.json')
|
| 180 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_ablation_no_interactability_object_bbox_gpu0.json')
|
| 181 |
+
# oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_ablation_no_feedback_object_bbox_gpu2.json')
|
| 182 |
+
|
| 183 |
+
# icse_rebuttal
|
| 184 |
+
# interactable_object_path = os.path.join(BASE_DIR, f'approach/llm/icse_rbt_{perspective}_{vlm}_{llm}_interactable_objects.json')
|
| 185 |
+
# ovod_output_dir = os.path.join(BASE_DIR, f'approach/ovod/output/icse_rbt_{perspective}_{ovod}')
|
| 186 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_object_bbox_gpu3_2.json')
|
| 187 |
+
# # oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_test_set_merged_{vlm}_{llm}_{ovod}_ablation_no_interactability_object_bbox_gpu0.json')
|
| 188 |
+
# oovd_object_bbox_path = os.path.join(BASE_DIR, f'approach/ovod/icse_rbt_{perspective}_{vlm}_{llm}_{ovod}_object_bbox_gpu3_265_528.json')
|
| 189 |
+
|
| 190 |
+
gemini31_results_answer_path = candidates_path or os.path.join(BASE_DIR, f'approach/vlm/realfse_fastuse_gemini31pro_answer.jsonl')
|
| 191 |
+
gpu = '1-3'
|
| 192 |
+
# fse
|
| 193 |
+
interactable_object_path = candidates_path or os.path.join(BASE_DIR, f'approach/llm/realfse_fastuse_{vlm}_{llm}_interactable_objects.json') # TODO: Tentatively unused
|
| 194 |
+
ovod_output_dir = os.path.join(BASE_DIR, f'approach/ovod/output/realfse_fastuse_{ovod}')
|
| 195 |
+
# GPU 0
|
| 196 |
+
base_output_path = output_path or os.path.join(BASE_DIR, f'approach/ovod/realfse_fastuse_{vlm}_{ovod}_object_bbox_gpu{gpu}.json')
|
| 197 |
+
oovd_object_bbox_path = output_path_for_selection(
|
| 198 |
+
base_output_path,
|
| 199 |
+
start_index=start_index,
|
| 200 |
+
end_index=end_index,
|
| 201 |
+
shard_index=shard_index,
|
| 202 |
+
num_shards=num_shards,
|
| 203 |
+
)
|
| 204 |
+
|
| 205 |
+
os.makedirs(ovod_output_dir, exist_ok=True)
|
| 206 |
+
llava7b_model_path = os.path.join(BASE_DIR, 'approach/vlm/LLaVA/checkpoints/llava-v1.5-7b')
|
| 207 |
+
llava7b_cmd = f'''
|
| 208 |
+
python model_vqa.py \
|
| 209 |
+
--model-path {llava7b_model_path} \
|
| 210 |
+
--question-file \
|
| 211 |
+
{complete_vlm_question_path} \
|
| 212 |
+
--image-folder \
|
| 213 |
+
{images_dir} \
|
| 214 |
+
--answers-file \
|
| 215 |
+
{llava_vlm_answer_path}
|
| 216 |
+
'''
|
| 217 |
+
|
| 218 |
+
# # STEP #0
|
| 219 |
+
# # First time of running
|
| 220 |
+
# # TODO: Check whether it is first-time running
|
| 221 |
+
generate_question_file(images_dir, vlm_question_path)
|
| 222 |
+
|
| 223 |
+
# STEP #1
|
| 224 |
+
# VLM - Get local context
|
| 225 |
+
print(f'VLM {vlm} analysis begins ...')
|
| 226 |
+
vlm_start_time = time.time()
|
| 227 |
+
logging.info(f'STEP #1 VLM {vlm} analysis started at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 228 |
+
if vlm == 'llava7b':
|
| 229 |
+
original_path = os.path.dirname(__file__)
|
| 230 |
+
os.chdir(llava_path)
|
| 231 |
+
os.system(llava7b_cmd)
|
| 232 |
+
os.chdir(original_path)
|
| 233 |
+
elif vlm == 'generate_q_file':
|
| 234 |
+
from approach.vlm.gpt4v.gpt4v import process_image_q
|
| 235 |
+
with open(vlm_question_path, 'r') as q_file, open(complete_vlm_question_path, 'w') as cq_file: # Open answer file in append mode
|
| 236 |
+
qfile_lines = q_file.readlines()
|
| 237 |
+
key_idx = 0
|
| 238 |
+
for line in tqdm(qfile_lines):
|
| 239 |
+
key_idx = (key_idx + 1) % 4
|
| 240 |
+
|
| 241 |
+
ans_item = {}
|
| 242 |
+
|
| 243 |
+
line_data = json.loads(line)
|
| 244 |
+
image_path = os.path.join(images_dir, line_data['image'])
|
| 245 |
+
image_question = line_data['text']
|
| 246 |
+
|
| 247 |
+
if vlm == 'gpt4v_abl':
|
| 248 |
+
gpt4v_ablation = True
|
| 249 |
+
elif vlm == 'gpt4v':
|
| 250 |
+
gpt4v_ablation = False
|
| 251 |
+
gpt4v_q = process_image_q(image_question, image_path, key_idx)
|
| 252 |
+
data = {
|
| 253 |
+
"question_id": line_data['question_id'],
|
| 254 |
+
"image": line_data['image'],
|
| 255 |
+
"text": gpt4v_q,
|
| 256 |
+
"category": "detail"
|
| 257 |
+
}
|
| 258 |
+
cq_file.write(json.dumps(data) + '\n')
|
| 259 |
+
elif vlm == 'gpt4v' or vlm == 'gpt4v_abl' or vlm == 'claude35sonnet' or vlm == 'gemini15pro' or vlm == 'gemini31pro':
|
| 260 |
+
from approach.vlm.gpt4v.gpt4v import process_image
|
| 261 |
+
with open(vlm_question_path, 'r') as q_file, open(vlm_answer_path, 'w') as a_file: # Open answer file in append mode
|
| 262 |
+
qfile_lines = q_file.readlines()
|
| 263 |
+
key_idx = 0
|
| 264 |
+
for line in tqdm(qfile_lines):
|
| 265 |
+
key_idx = (key_idx + 1) % 4
|
| 266 |
+
|
| 267 |
+
ans_item = {}
|
| 268 |
+
|
| 269 |
+
line_data = json.loads(line)
|
| 270 |
+
image_path = os.path.join(images_dir, line_data['image'])
|
| 271 |
+
image_question = line_data['text']
|
| 272 |
+
|
| 273 |
+
gpt4v_ablation = False
|
| 274 |
+
if vlm == 'gpt4v_abl':
|
| 275 |
+
gpt4v_ablation = True
|
| 276 |
+
elif vlm == 'gpt4v':
|
| 277 |
+
gpt4v_ablation = False
|
| 278 |
+
gpt4v_res = process_image(vlm, image_question, image_path, gpt4v_ablation, key_idx)
|
| 279 |
+
print(gpt4v_res)
|
| 280 |
+
# time.sleep(3)
|
| 281 |
+
|
| 282 |
+
ans_item = {
|
| 283 |
+
"question_id": line_data['question_id'],
|
| 284 |
+
"prompt": '',
|
| 285 |
+
"text": gpt4v_res,
|
| 286 |
+
"answer_id": generate_answer_id(),
|
| 287 |
+
"model_id": vlm,
|
| 288 |
+
"metadata": {}
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
a_file.write(json.dumps(ans_item) + '\n')
|
| 292 |
+
a_file.flush()
|
| 293 |
+
elif vlm == 'bing':
|
| 294 |
+
from approach.vlm.bing.bing import context_conversation
|
| 295 |
+
with open(vlm_question_path, 'r') as q_file, open(vlm_answer_path, 'a') as a_file: # Open answer file in append mode
|
| 296 |
+
for line in tqdm(q_file):
|
| 297 |
+
ans_item = {}
|
| 298 |
+
|
| 299 |
+
line_data = json.loads(line)
|
| 300 |
+
image_path = os.path.join(images_dir, line_data['image'])
|
| 301 |
+
image_question = line_data['text']
|
| 302 |
+
|
| 303 |
+
bing_res = context_conversation(image_question, image_path)
|
| 304 |
+
print(bing_res)
|
| 305 |
+
time.sleep(15)
|
| 306 |
+
|
| 307 |
+
ans_item = {
|
| 308 |
+
"question_id": line_data['question_id'],
|
| 309 |
+
"prompt": image_question,
|
| 310 |
+
"text": bing_res,
|
| 311 |
+
"answer_id": generate_answer_id(),
|
| 312 |
+
"model_id": vlm,
|
| 313 |
+
"metadata": {}
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
a_file.write(json.dumps(ans_item) + '\n')
|
| 317 |
+
elif vlm == 'gemini':
|
| 318 |
+
import pathlib
|
| 319 |
+
import textwrap
|
| 320 |
+
|
| 321 |
+
import google.generativeai as genai
|
| 322 |
+
|
| 323 |
+
GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY", "[GOOGLE_API_KEY]")
|
| 324 |
+
genai.configure(api_key=GOOGLE_API_KEY)
|
| 325 |
+
|
| 326 |
+
safety_settings = [
|
| 327 |
+
{
|
| 328 |
+
"category": "HARM_CATEGORY_DANGEROUS",
|
| 329 |
+
"threshold": "BLOCK_NONE",
|
| 330 |
+
},
|
| 331 |
+
{
|
| 332 |
+
"category": "HARM_CATEGORY_HARASSMENT",
|
| 333 |
+
"threshold": "BLOCK_NONE",
|
| 334 |
+
},
|
| 335 |
+
{
|
| 336 |
+
"category": "HARM_CATEGORY_HATE_SPEECH",
|
| 337 |
+
"threshold": "BLOCK_NONE",
|
| 338 |
+
},
|
| 339 |
+
{
|
| 340 |
+
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
| 341 |
+
"threshold": "BLOCK_NONE",
|
| 342 |
+
},
|
| 343 |
+
{
|
| 344 |
+
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
| 345 |
+
"threshold": "BLOCK_NONE",
|
| 346 |
+
},
|
| 347 |
+
]
|
| 348 |
+
|
| 349 |
+
# before fse
|
| 350 |
+
# model = genai.GenerativeModel('gemini-pro-vision')
|
| 351 |
+
# fse
|
| 352 |
+
model = genai.GenerativeModel('gemini-1.5-pro')
|
| 353 |
+
|
| 354 |
+
with open(vlm_question_path, 'r') as q_file, open(gemini_vlm_answer_path, 'w') as a_file: # Open answer file in append mode
|
| 355 |
+
qfile_lines = q_file.readlines()[0:2]
|
| 356 |
+
for line in tqdm(qfile_lines):
|
| 357 |
+
|
| 358 |
+
ans_item = {}
|
| 359 |
+
|
| 360 |
+
line_data = json.loads(line)
|
| 361 |
+
image_path = os.path.join(images_dir, line_data['image'])
|
| 362 |
+
image_question = line_data['text']
|
| 363 |
+
|
| 364 |
+
gemini_response = model.generate_content([image_question, PIL.Image.open(image_path)], safety_settings=safety_settings)
|
| 365 |
+
gemini_response.resolve()
|
| 366 |
+
try:
|
| 367 |
+
gemini_response = gemini_response.text
|
| 368 |
+
ans_item = {
|
| 369 |
+
"question_id": line_data['question_id'],
|
| 370 |
+
"prompt": image_question,
|
| 371 |
+
"text": gemini_response,
|
| 372 |
+
"answer_id": generate_answer_id(),
|
| 373 |
+
"model_id": vlm,
|
| 374 |
+
"metadata": {}
|
| 375 |
+
}
|
| 376 |
+
|
| 377 |
+
a_file.write(json.dumps(ans_item) + '\n')
|
| 378 |
+
a_file.flush()
|
| 379 |
+
except Exception as e:
|
| 380 |
+
print(f"Error for image {image_path}. Error: {e}")
|
| 381 |
+
# print(gemini_response)
|
| 382 |
+
time.sleep(30)
|
| 383 |
+
|
| 384 |
+
|
| 385 |
+
|
| 386 |
+
elif vlm.endswith('_pass'):
|
| 387 |
+
print(f'Passing VLM {vlm} ...')
|
| 388 |
+
else:
|
| 389 |
+
raise Exception('Unrecognized VLM!')
|
| 390 |
+
|
| 391 |
+
logging.info(f'STEP #1 VLM {vlm} analysis completed at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 392 |
+
logging.info(f'STEP #1 VLM {vlm} analysis total time taken: {time.time() - vlm_start_time} seconds')
|
| 393 |
+
|
| 394 |
+
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
|
| 398 |
+
# Get label candidates
|
| 399 |
+
# if llm == 'gemini-3-flash-preview-nothinking':
|
| 400 |
+
# from approach.llm.gpt_polling import infer_object_candidates
|
| 401 |
+
# elif llm == 'llama2':
|
| 402 |
+
# from approach.llm.llama import infer_object_candidates
|
| 403 |
+
|
| 404 |
+
|
| 405 |
+
# STEP #3
|
| 406 |
+
if llm == 'gemini-3-flash-preview-nothinking' or llm == 'gemini-3-flash-preview-nothinking_abl':
|
| 407 |
+
from approach.llm.gpt_polling import infer_objects
|
| 408 |
+
|
| 409 |
+
if llm == 'gemini-3-flash-preview-nothinking_abl':
|
| 410 |
+
gpt35_ablation = True
|
| 411 |
+
elif llm == 'gemini-3-flash-preview-nothinking':
|
| 412 |
+
gpt35_ablation = False
|
| 413 |
+
infer_objects(vlm_question_path, vlm_answer_path, interactable_object_path, gpt35_ablation)
|
| 414 |
+
elif llm == 'llama2':
|
| 415 |
+
from approach.llm.llama import infer_objects
|
| 416 |
+
exit(0)
|
| 417 |
+
elif llm.endswith('_pass'):
|
| 418 |
+
print(f'Passing LLM {llm} ...')
|
| 419 |
+
else:
|
| 420 |
+
raise Exception('Unrecognized LLM!')
|
| 421 |
+
|
| 422 |
+
|
| 423 |
+
|
| 424 |
+
|
| 425 |
+
|
| 426 |
+
|
| 427 |
+
# STEP #2
|
| 428 |
+
# Open-vocabulary object detection
|
| 429 |
+
ovod_start_time = time.time()
|
| 430 |
+
logging.info(f'STEP #2 OVOD {ovod} analysis started at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 431 |
+
vlm_questions = {}
|
| 432 |
+
with open(complete_vlm_question_path, 'r') as q_file:
|
| 433 |
+
for line in q_file:
|
| 434 |
+
line_data = json.loads(line)
|
| 435 |
+
vlm_questions[line_data['question_id']] = line_data
|
| 436 |
+
# print(line_data['question_id'])
|
| 437 |
+
|
| 438 |
+
if ovod == 'grounding_dino':
|
| 439 |
+
from approach.ovod.GroundingDINO.demo.inference_on_a_image import process_grounding_dino
|
| 440 |
+
|
| 441 |
+
original_path = os.path.dirname(__file__)
|
| 442 |
+
os.chdir(grounding_dino_path)
|
| 443 |
+
|
| 444 |
+
# with open(llm_candidate_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 445 |
+
with open(interactable_object_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 446 |
+
llm_candidate = json.load(llm_candidate_file)
|
| 447 |
+
all_oovd_res = {}
|
| 448 |
+
for image_index in llm_candidate.keys():
|
| 449 |
+
print(image_index)
|
| 450 |
+
# TODO:
|
| 451 |
+
if (image_index != '1160'):
|
| 452 |
+
ovod_image_path = os.path.join(images_dir, vlm_questions[int(image_index)]["image"])
|
| 453 |
+
ovod_candidates = llm_candidate[image_index]['interactable_objects']
|
| 454 |
+
# grounding_dino_command = generate_grounding_dino_command(ovod_image_path, ovod_output_dir, ovod_candidates)
|
| 455 |
+
# print(grounding_dino_command)
|
| 456 |
+
# os.system(grounding_dino_command)
|
| 457 |
+
|
| 458 |
+
gdino_res = process_grounding_dino(
|
| 459 |
+
config_file='groundingdino/config/GroundingDINO_SwinT_OGC.py',
|
| 460 |
+
checkpoint_path='weights/groundingdino_swint_ogc.pth',
|
| 461 |
+
image_path=ovod_image_path,
|
| 462 |
+
ovod_candidates=ovod_candidates,
|
| 463 |
+
output_dir=ovod_output_dir,
|
| 464 |
+
box_threshold=0.3,
|
| 465 |
+
text_threshold=0.25,
|
| 466 |
+
token_spans=None,
|
| 467 |
+
cpu_only=False
|
| 468 |
+
)
|
| 469 |
+
# print(gdino_res)
|
| 470 |
+
|
| 471 |
+
object_oovd_item = copy.deepcopy(llm_candidate[image_index])
|
| 472 |
+
object_oovd_item['oovd_result'] = gdino_res
|
| 473 |
+
print(object_oovd_item)
|
| 474 |
+
all_oovd_res[image_index] = object_oovd_item
|
| 475 |
+
|
| 476 |
+
json.dump(all_oovd_res, oovd_file, indent=4)
|
| 477 |
+
|
| 478 |
+
|
| 479 |
+
os.chdir(original_path)
|
| 480 |
+
|
| 481 |
+
elif ovod == 'ape_d' or ovod == 'ape_d_abl':
|
| 482 |
+
from approach.ovod.APE.demo.ape_inference import run_ape_model_inference
|
| 483 |
+
|
| 484 |
+
original_path = os.path.dirname(__file__)
|
| 485 |
+
os.chdir(active_ape_path)
|
| 486 |
+
|
| 487 |
+
all_ape_res = []
|
| 488 |
+
reflection_traces = []
|
| 489 |
+
# General
|
| 490 |
+
# with open(vlm_answer_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 491 |
+
# GPT-4 eval
|
| 492 |
+
with open(gemini31_results_answer_path, 'r') as llm_candidate_file:
|
| 493 |
+
# Gemini abl i eval
|
| 494 |
+
# with open(interactability_abl_results_answer_path, 'r') as llm_candidate_file, open(oovd_object_bbox_path, 'w') as oovd_file:
|
| 495 |
+
|
| 496 |
+
# llm_candidate = json.load(llm_candidate_file)
|
| 497 |
+
all_oovd_res = {}
|
| 498 |
+
|
| 499 |
+
candidate_lines = select_jsonl_lines(
|
| 500 |
+
llm_candidate_file.readlines(),
|
| 501 |
+
start_index=start_index,
|
| 502 |
+
end_index=end_index,
|
| 503 |
+
shard_index=shard_index,
|
| 504 |
+
num_shards=num_shards,
|
| 505 |
+
)
|
| 506 |
+
|
| 507 |
+
for line in tqdm(candidate_lines):
|
| 508 |
+
ans_item = {}
|
| 509 |
+
|
| 510 |
+
line_data = json.loads(line)
|
| 511 |
+
|
| 512 |
+
# for image_index in llm_candidate.keys():
|
| 513 |
+
# print(image_index)
|
| 514 |
+
# TODO:
|
| 515 |
+
# if (image_index != '1160'):
|
| 516 |
+
# image_index = line_data['question_id']
|
| 517 |
+
|
| 518 |
+
image_name = vlm_questions[line_data['question_id']]["image"]
|
| 519 |
+
ovod_image_path = os.path.join(images_dir, image_name)
|
| 520 |
+
|
| 521 |
+
# General
|
| 522 |
+
# try:
|
| 523 |
+
# if line_data['text'].startswith(" ```json"):
|
| 524 |
+
# ovod_candidates = json.loads(line_data['text'][8:-4])['objects']
|
| 525 |
+
# elif line_data['text'].startswith(' {\"objects\"'):
|
| 526 |
+
# ovod_candidates = json.loads(line_data['text'])['objects']
|
| 527 |
+
# else:
|
| 528 |
+
# print(f"Error for decoding IVO json for {image_name}.")
|
| 529 |
+
# except Exception as e:
|
| 530 |
+
# print(f"Error for decoding IVO json for image {image_name}. Error: {e}")
|
| 531 |
+
# continue
|
| 532 |
+
|
| 533 |
+
|
| 534 |
+
# GPT-4v
|
| 535 |
+
if line_data['text']:
|
| 536 |
+
ovod_candidates = line_data['text']['objects']
|
| 537 |
+
else:
|
| 538 |
+
continue
|
| 539 |
+
all_res = []
|
| 540 |
+
for ocd in ovod_candidates.keys():
|
| 541 |
+
referring_expr_str = ovod_candidates[ocd]
|
| 542 |
+
|
| 543 |
+
translator = str.maketrans('', '', string.punctuation)
|
| 544 |
+
if type(referring_expr_str) is str:
|
| 545 |
+
referring_expr_str = referring_expr_str.translate(translator)
|
| 546 |
+
else:
|
| 547 |
+
# dict
|
| 548 |
+
referring_expr_str = ' '.join(referring_expr_str.values())
|
| 549 |
+
referring_expr_str = referring_expr_str.translate(translator)
|
| 550 |
+
referring_expr_str = f'{ocd}: {referring_expr_str}'
|
| 551 |
+
# print(image_name, referring_expr_str)
|
| 552 |
+
all_res.append(referring_expr_str)
|
| 553 |
+
|
| 554 |
+
if ovod == 'ape_d':
|
| 555 |
+
ape_threshold = 0.1
|
| 556 |
+
elif ovod == 'ape_d_abl':
|
| 557 |
+
ape_threshold = 0.1
|
| 558 |
+
|
| 559 |
+
ape_res = []
|
| 560 |
+
try:
|
| 561 |
+
os.makedirs(f'./realfse_{vlm}_{ovod}_gpu0123', exist_ok=True)
|
| 562 |
+
ape_res = run_ape_model_inference(
|
| 563 |
+
config_file='configs/LVISCOCOCOCOSTUFF_O365_OID_VGR_SA1B_REFCOCO_GQA_PhraseCut_Flickr30k/ape_deta/ape_deta_vitl_eva02_clip_vlf_lsj1024_cp_16x4_1080k.py',
|
| 564 |
+
input_path=ovod_image_path,
|
| 565 |
+
# GPU 0
|
| 566 |
+
output_path=f'./realfse_{vlm}_{ovod}_gpu0123',
|
| 567 |
+
confidence_threshold=ape_threshold,
|
| 568 |
+
text_prompt=', '.join(all_res),
|
| 569 |
+
with_box=True,
|
| 570 |
+
with_mask=False,
|
| 571 |
+
with_sseg=False,
|
| 572 |
+
opts=[
|
| 573 |
+
f"train.init_checkpoint='{active_ape_checkpoint}'",
|
| 574 |
+
"model.model_language.cache_dir=''",
|
| 575 |
+
"model.model_vision.select_box_nums_for_evaluation=500",
|
| 576 |
+
"model.model_vision.text_feature_bank_reset=True",
|
| 577 |
+
"model.model_vision.backbone.net.xattn=False",
|
| 578 |
+
"model.model_vision.transformer.encoder.pytorch_attn=True",
|
| 579 |
+
"model.model_vision.transformer.decoder.pytorch_attn=True"
|
| 580 |
+
]
|
| 581 |
+
)
|
| 582 |
+
except Exception as e:
|
| 583 |
+
print(f"Error for image {image_name}. Error: {e}")
|
| 584 |
+
|
| 585 |
+
def reflection_detector(candidates, previous):
|
| 586 |
+
if not candidates:
|
| 587 |
+
return previous
|
| 588 |
+
try:
|
| 589 |
+
refined = run_ape_model_inference(
|
| 590 |
+
config_file='configs/LVISCOCOCOCOSTUFF_O365_OID_VGR_SA1B_REFCOCO_GQA_PhraseCut_Flickr30k/ape_deta/ape_deta_vitl_eva02_clip_vlf_lsj1024_cp_16x4_1080k.py',
|
| 591 |
+
input_path=ovod_image_path,
|
| 592 |
+
output_path=f'./realfse_{vlm}_{ovod}_gpu0123',
|
| 593 |
+
confidence_threshold=ape_threshold,
|
| 594 |
+
text_prompt=', '.join(candidates),
|
| 595 |
+
with_box=True,
|
| 596 |
+
with_mask=False,
|
| 597 |
+
with_sseg=False,
|
| 598 |
+
opts=[
|
| 599 |
+
f"train.init_checkpoint='{active_ape_checkpoint}'",
|
| 600 |
+
"model.model_language.cache_dir=''",
|
| 601 |
+
"model.model_vision.select_box_nums_for_evaluation=500",
|
| 602 |
+
"model.model_vision.text_feature_bank_reset=True",
|
| 603 |
+
"model.model_vision.backbone.net.xattn=False",
|
| 604 |
+
"model.model_vision.transformer.encoder.pytorch_attn=True",
|
| 605 |
+
"model.model_vision.transformer.decoder.pytorch_attn=True"
|
| 606 |
+
]
|
| 607 |
+
)
|
| 608 |
+
return previous + refined
|
| 609 |
+
except Exception as e:
|
| 610 |
+
print(f"Error during reflection redetection for {image_name}. Error: {e}")
|
| 611 |
+
return previous
|
| 612 |
+
|
| 613 |
+
reflection_result = run_optional_reflection(
|
| 614 |
+
ovod_image_path,
|
| 615 |
+
ape_res,
|
| 616 |
+
detector=reflection_detector,
|
| 617 |
+
enabled=enable_reflection,
|
| 618 |
+
model_profile=reflection_profile,
|
| 619 |
+
max_iterations=max_reflection_iterations,
|
| 620 |
+
)
|
| 621 |
+
if reflection_result is not None:
|
| 622 |
+
ape_res = reflection_result["detections"]
|
| 623 |
+
reflection_traces.append(
|
| 624 |
+
{
|
| 625 |
+
"image": image_name,
|
| 626 |
+
"image_id": extract_image_id(image_name),
|
| 627 |
+
"trace": reflection_result["trace"],
|
| 628 |
+
"max_iterations_reached": reflection_result["max_iterations_reached"],
|
| 629 |
+
}
|
| 630 |
+
)
|
| 631 |
+
|
| 632 |
+
all_ape_res.extend(enrich_ape_results(ape_res, image_name, extract_image_id))
|
| 633 |
+
# object_oovd_item = copy.deepcopy(llm_candidate[image_index])
|
| 634 |
+
# object_oovd_item['ape_result'] = all_ape_res
|
| 635 |
+
# # print(object_oovd_item)
|
| 636 |
+
# all_oovd_res[image_index] = object_oovd_item
|
| 637 |
+
|
| 638 |
+
write_json_atomic(oovd_object_bbox_path, all_ape_res)
|
| 639 |
+
if enable_reflection:
|
| 640 |
+
write_json_atomic(f"{oovd_object_bbox_path}.reflection.json", reflection_traces)
|
| 641 |
+
|
| 642 |
+
|
| 643 |
+
os.chdir(original_path)
|
| 644 |
+
|
| 645 |
+
elif ovod.endswith('_pass'):
|
| 646 |
+
print(f'Passing OVOD {ovod} ...')
|
| 647 |
+
else:
|
| 648 |
+
raise Exception('Unrecognized OVOD!')
|
| 649 |
+
|
| 650 |
+
logging.info(f'STEP #2 OVOD {ovod} analysis completed at %s', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
|
| 651 |
+
logging.info(f'STEP #2 OVOD {ovod} analysis total time taken: {time.time() - ovod_start_time} seconds')
|
| 652 |
+
# icse & fse
|
| 653 |
+
def extract_image_id(image_name):
|
| 654 |
+
# Split the image name into parts and form the image_id accordingly
|
| 655 |
+
parts = image_name.split('_')
|
| 656 |
+
print(image_name)
|
| 657 |
+
base, extension = parts[1].split('.')
|
| 658 |
+
return int(parts[0] + base.zfill(3))
|
| 659 |
+
# icse_rebuttal
|
| 660 |
+
# def extract_image_id(image_name):
|
| 661 |
+
# # Split the image name into parts by underscore
|
| 662 |
+
# parts = image_name.split('_')
|
| 663 |
+
# # Extracting the first part as the base and the numeric portion of the third part before the file extension
|
| 664 |
+
# base = parts[0] # This will give '625470'
|
| 665 |
+
# numeric_part = parts[2].split('.')[0] # This will give 'b3'
|
| 666 |
+
# # Removing non-numeric characters from 'b3'
|
| 667 |
+
# numeric_part = ''.join(filter(str.isdigit, numeric_part))
|
| 668 |
+
# # Zfill is used to ensure the numeric part has at least 3 digits, then combining with base
|
| 669 |
+
# print(int(base + numeric_part.zfill(3)))
|
| 670 |
+
# return int(base + numeric_part.zfill(3))
|
| 671 |
+
|
| 672 |
+
|
| 673 |
+
def main():
|
| 674 |
+
vlms = ['llava7b', 'bing', 'gpt4v']
|
| 675 |
+
llms = ['llama2', 'gemini-3-flash-preview-nothinking']
|
| 676 |
+
ovods = ['grounding_dino', 'glip', 'ape_d']
|
| 677 |
+
|
| 678 |
+
|
| 679 |
+
# python method.py -v gpt4v -l gemini-3-flash-preview-nothinking -o ape_d
|
| 680 |
+
# python method.py -v gpt4v -l gemini-3-flash-preview-nothinking -o ape_d_abl
|
| 681 |
+
# python method.py -v claude35sonnet -l gemini-3-flash-preview-nothinking -o ape_d
|
| 682 |
+
# python method.py -v gemini -l gemini-3-flash-preview-nothinking -o ape_d
|
| 683 |
+
if __name__=='__main__':
|
| 684 |
+
# main()
|
| 685 |
+
|
| 686 |
+
parser = argparse.ArgumentParser("Method", add_help=True)
|
| 687 |
+
parser.add_argument("--vlm", "-v", type=str, required=True, help="vlm")
|
| 688 |
+
parser.add_argument("--llm", "-l", type=str, required=True, help="llm")
|
| 689 |
+
parser.add_argument("--ovod", "-o", type=str, required=True, help="ovod")
|
| 690 |
+
parser.add_argument("--start-index", type=int, default=None, help="first JSONL row to process")
|
| 691 |
+
parser.add_argument("--end-index", type=int, default=None, help="exclusive JSONL row end")
|
| 692 |
+
parser.add_argument("--shard-index", type=int, default=None, help="zero-based shard index")
|
| 693 |
+
parser.add_argument("--num-shards", type=int, default=None, help="total number of shards")
|
| 694 |
+
parser.add_argument("--enable-reflection", action="store_true", help="run PII.5/PII.6 advisor reflection loop")
|
| 695 |
+
parser.add_argument("--reflection-profile", default="default", help="model profile for the reflection advisor")
|
| 696 |
+
parser.add_argument("--max-reflection-iterations", type=int, default=10, help="max advisor reflection rounds")
|
| 697 |
+
parser.add_argument("--questions", dest="questions_path", help="question manifest JSONL")
|
| 698 |
+
parser.add_argument("--candidates", dest="candidates_path", help="candidate JSON/JSONL for the selected detector")
|
| 699 |
+
parser.add_argument("--images-dir", dest="images_path", help="directory containing XR screenshots")
|
| 700 |
+
parser.add_argument("--output", dest="output_path", help="prediction JSON path; selection suffixes are added automatically")
|
| 701 |
+
parser.add_argument("--ape-root", help="APE repository directory")
|
| 702 |
+
parser.add_argument("--ape-checkpoint", help="APE checkpoint path")
|
| 703 |
+
parser.add_argument("--log-file", help="optional log file; defaults to stderr")
|
| 704 |
+
args = parser.parse_args()
|
| 705 |
+
|
| 706 |
+
gpu = '1-3'
|
| 707 |
+
stage = '1'
|
| 708 |
+
idx = '0001'
|
| 709 |
+
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
|
| 710 |
+
datefmt='%m/%d/%Y %H:%M:%S',
|
| 711 |
+
level=logging.INFO,
|
| 712 |
+
filename=args.log_file,
|
| 713 |
+
)
|
| 714 |
+
|
| 715 |
+
method(
|
| 716 |
+
args.vlm,
|
| 717 |
+
args.llm,
|
| 718 |
+
args.ovod,
|
| 719 |
+
start_index=args.start_index,
|
| 720 |
+
end_index=args.end_index,
|
| 721 |
+
shard_index=args.shard_index,
|
| 722 |
+
num_shards=args.num_shards,
|
| 723 |
+
enable_reflection=args.enable_reflection,
|
| 724 |
+
reflection_profile=args.reflection_profile,
|
| 725 |
+
max_reflection_iterations=args.max_reflection_iterations,
|
| 726 |
+
questions_path=args.questions_path,
|
| 727 |
+
candidates_path=args.candidates_path,
|
| 728 |
+
images_path=args.images_path,
|
| 729 |
+
output_path=args.output_path,
|
| 730 |
+
ape_root=args.ape_root,
|
| 731 |
+
ape_checkpoint=args.ape_checkpoint,
|
| 732 |
+
)
|
| 733 |
+
|
| 734 |
+
# CUDA_VISIBLE_DEVICES=0 python method.py -v gpt4v -l gemini-3-flash-preview-nothinking -o ape_d > ../log/realfse/240910_gpt4v_2_g0_0001.txt
|
| 735 |
+
# CUDA_VISIBLE_DEVICES=3 python method.py -v gpt4v -l gemini-3-flash-preview-nothinking -o ape_d_abl > ../log/realfse/240910_gpt4v_ape_d_abl_2_g3_0001.txt
|
| 736 |
+
# CUDA_VISIBLE_DEVICES=3 python method.py -v gpt4v_abl -l gemini-3-flash-preview-nothinking -o ape_d > ../log/realfse/240912_gpt4v_abl_1_g1-3_0001.txt
|
approach/ovod/APE/demo/__init__.py
ADDED
|
File without changes
|
approach/ovod/APE/demo/pre-requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
--index-url https://download.pytorch.org/whl/cu118
|
| 2 |
+
torch==2.0.1
|
| 3 |
+
torchvision==0.15.2
|
| 4 |
+
torchaudio==2.0.2
|
approach/ovod/APE/demo/predictor_lazy.py
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 2 |
+
import atexit
|
| 3 |
+
import bisect
|
| 4 |
+
import gc
|
| 5 |
+
import json
|
| 6 |
+
import multiprocessing as mp
|
| 7 |
+
import time
|
| 8 |
+
from collections import deque
|
| 9 |
+
|
| 10 |
+
import cv2
|
| 11 |
+
import numpy as np
|
| 12 |
+
import torch
|
| 13 |
+
|
| 14 |
+
from ape.engine.defaults import DefaultPredictor
|
| 15 |
+
from detectron2.data import MetadataCatalog
|
| 16 |
+
from detectron2.utils.video_visualizer import VideoVisualizer
|
| 17 |
+
from detectron2.utils.visualizer import ColorMode, Visualizer
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def filter_instances(instances, metadata):
|
| 21 |
+
# return instances
|
| 22 |
+
|
| 23 |
+
keep = []
|
| 24 |
+
keep_classes = []
|
| 25 |
+
|
| 26 |
+
sorted_idxs = np.argsort(-instances.scores)
|
| 27 |
+
instances = instances[sorted_idxs]
|
| 28 |
+
|
| 29 |
+
for i in range(len(instances)):
|
| 30 |
+
instance = instances[i]
|
| 31 |
+
pred_class = instance.pred_classes
|
| 32 |
+
if pred_class >= len(metadata.thing_classes):
|
| 33 |
+
continue
|
| 34 |
+
|
| 35 |
+
keep.append(i)
|
| 36 |
+
keep_classes.append(pred_class)
|
| 37 |
+
return instances[keep]
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def cuda_grabcut(img, masks, iter=5, gamma=50, iou_threshold=0.75):
|
| 41 |
+
gc.collect()
|
| 42 |
+
torch.cuda.empty_cache()
|
| 43 |
+
|
| 44 |
+
try:
|
| 45 |
+
import grabcut
|
| 46 |
+
except Exception as e:
|
| 47 |
+
print("*" * 60)
|
| 48 |
+
print("fail to import grabCut: ", e)
|
| 49 |
+
print("*" * 60)
|
| 50 |
+
return masks
|
| 51 |
+
GC = grabcut.GrabCut(iter)
|
| 52 |
+
|
| 53 |
+
img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
|
| 54 |
+
|
| 55 |
+
tic_0 = time.time()
|
| 56 |
+
for i in range(len(masks)):
|
| 57 |
+
mask = masks[i]
|
| 58 |
+
if mask.sum() > 10 * 10:
|
| 59 |
+
pass
|
| 60 |
+
else:
|
| 61 |
+
continue
|
| 62 |
+
|
| 63 |
+
# ----------------------------------------------------------------
|
| 64 |
+
fourmap = np.empty_like(mask, dtype=np.uint8)
|
| 65 |
+
fourmap[:, :] = 64
|
| 66 |
+
fourmap[mask == 0] = 64
|
| 67 |
+
fourmap[mask == 1] = 128
|
| 68 |
+
|
| 69 |
+
# Compute segmentation
|
| 70 |
+
tic = time.time()
|
| 71 |
+
seg = GC.estimateSegmentationFromFourmap(img, fourmap, gamma)
|
| 72 |
+
toc = time.time()
|
| 73 |
+
print("Time elapsed in GrabCut segmentation: " + str(toc - tic))
|
| 74 |
+
# ----------------------------------------------------------------
|
| 75 |
+
|
| 76 |
+
seg = torch.tensor(seg, dtype=torch.bool)
|
| 77 |
+
iou = (mask & seg).sum() / (mask | seg).sum()
|
| 78 |
+
if iou > iou_threshold:
|
| 79 |
+
masks[i] = seg
|
| 80 |
+
|
| 81 |
+
if toc - tic_0 > 10:
|
| 82 |
+
break
|
| 83 |
+
|
| 84 |
+
return masks
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
def opencv_grabcut(img, masks, iter=5):
|
| 88 |
+
|
| 89 |
+
for i in range(len(masks)):
|
| 90 |
+
mask = masks[i]
|
| 91 |
+
|
| 92 |
+
# ----------------------------------------------------------------
|
| 93 |
+
fourmap = np.empty_like(mask, dtype=np.uint8)
|
| 94 |
+
fourmap[:, :] = cv2.GC_PR_BGD
|
| 95 |
+
# fourmap[mask == 0] = cv2.GC_BGD
|
| 96 |
+
fourmap[mask == 0] = cv2.GC_PR_BGD
|
| 97 |
+
fourmap[mask == 1] = cv2.GC_PR_FGD
|
| 98 |
+
# fourmap[mask == 1] = cv2.GC_FGD
|
| 99 |
+
|
| 100 |
+
# Create GrabCut algo
|
| 101 |
+
bgd_model = np.zeros((1, 65), np.float64)
|
| 102 |
+
fgd_model = np.zeros((1, 65), np.float64)
|
| 103 |
+
seg = np.zeros_like(fourmap, dtype=np.uint8)
|
| 104 |
+
|
| 105 |
+
# Compute segmentation
|
| 106 |
+
tic = time.time()
|
| 107 |
+
seg, bgd_model, fgd_model = cv2.grabCut(
|
| 108 |
+
img, fourmap, None, bgd_model, fgd_model, iter, cv2.GC_INIT_WITH_MASK
|
| 109 |
+
)
|
| 110 |
+
toc = time.time()
|
| 111 |
+
print("Time elapsed in GrabCut segmentation: " + str(toc - tic))
|
| 112 |
+
|
| 113 |
+
seg = np.where((seg == 2) | (seg == 0), 0, 1).astype("bool")
|
| 114 |
+
|
| 115 |
+
# ----------------------------------------------------------------
|
| 116 |
+
|
| 117 |
+
seg = torch.tensor(seg, dtype=torch.bool)
|
| 118 |
+
iou = (mask & seg).sum() / (mask | seg).sum()
|
| 119 |
+
if iou > 0.75:
|
| 120 |
+
masks[i] = seg
|
| 121 |
+
|
| 122 |
+
if i > 10:
|
| 123 |
+
break
|
| 124 |
+
|
| 125 |
+
return masks
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
class VisualizationDemo(object):
|
| 129 |
+
def __init__(self, cfg, instance_mode=ColorMode.IMAGE, parallel=False, args=None):
|
| 130 |
+
"""
|
| 131 |
+
Args:
|
| 132 |
+
cfg (CfgNode):
|
| 133 |
+
instance_mode (ColorMode):
|
| 134 |
+
parallel (bool): whether to run the model in different processes from visualization.
|
| 135 |
+
Useful since the visualization logic can be slow.
|
| 136 |
+
"""
|
| 137 |
+
self.metadata = MetadataCatalog.get(
|
| 138 |
+
"__unused_" + "_".join([d for d in cfg.dataloader.train.dataset.names])
|
| 139 |
+
)
|
| 140 |
+
self.metadata.thing_classes = [
|
| 141 |
+
c
|
| 142 |
+
for d in cfg.dataloader.train.dataset.names
|
| 143 |
+
for c in MetadataCatalog.get(d).get("thing_classes", default=[])
|
| 144 |
+
+ MetadataCatalog.get(d).get("stuff_classes", default=["thing"])[1:]
|
| 145 |
+
]
|
| 146 |
+
self.metadata.stuff_classes = [
|
| 147 |
+
c
|
| 148 |
+
for d in cfg.dataloader.train.dataset.names
|
| 149 |
+
for c in MetadataCatalog.get(d).get("thing_classes", default=[])
|
| 150 |
+
+ MetadataCatalog.get(d).get("stuff_classes", default=["thing"])[1:]
|
| 151 |
+
]
|
| 152 |
+
|
| 153 |
+
# self.metadata = MetadataCatalog.get(
|
| 154 |
+
# "__unused_ape_" + "_".join([d for d in cfg.dataloader.train.dataset.names])
|
| 155 |
+
# )
|
| 156 |
+
# self.metadata.thing_classes = [
|
| 157 |
+
# c
|
| 158 |
+
# for d in ["coco_2017_train_panoptic_separated"]
|
| 159 |
+
# for c in MetadataCatalog.get(d).get("thing_classes", default=[])
|
| 160 |
+
# + MetadataCatalog.get(d).get("stuff_classes", default=["thing"])[1:]
|
| 161 |
+
# ]
|
| 162 |
+
# self.metadata.stuff_classes = [
|
| 163 |
+
# c
|
| 164 |
+
# for d in ["coco_2017_train_panoptic_separated"]
|
| 165 |
+
# for c in MetadataCatalog.get(d).get("thing_classes", default=[])
|
| 166 |
+
# + MetadataCatalog.get(d).get("stuff_classes", default=["thing"])[1:]
|
| 167 |
+
# ]
|
| 168 |
+
|
| 169 |
+
self.cpu_device = torch.device("cpu")
|
| 170 |
+
self.instance_mode = instance_mode
|
| 171 |
+
|
| 172 |
+
self.parallel = parallel
|
| 173 |
+
if parallel:
|
| 174 |
+
num_gpu = torch.cuda.device_count()
|
| 175 |
+
self.predictor = AsyncPredictor(cfg, num_gpus=num_gpu)
|
| 176 |
+
else:
|
| 177 |
+
self.predictor = DefaultPredictor(cfg)
|
| 178 |
+
|
| 179 |
+
print(args)
|
| 180 |
+
|
| 181 |
+
def run_on_image(
|
| 182 |
+
self,
|
| 183 |
+
image,
|
| 184 |
+
text_prompt=None,
|
| 185 |
+
mask_prompt=None,
|
| 186 |
+
with_box=True,
|
| 187 |
+
with_mask=True,
|
| 188 |
+
with_sseg=True,
|
| 189 |
+
):
|
| 190 |
+
"""
|
| 191 |
+
Args:
|
| 192 |
+
image (np.ndarray): an image of shape (H, W, C) (in BGR order).
|
| 193 |
+
This is the format used by OpenCV.
|
| 194 |
+
|
| 195 |
+
Returns:
|
| 196 |
+
predictions (dict): the output of the model.
|
| 197 |
+
vis_output (VisImage): the visualized image output.
|
| 198 |
+
"""
|
| 199 |
+
if text_prompt:
|
| 200 |
+
text_list = [x.strip() for x in text_prompt.split(",")]
|
| 201 |
+
text_list = [x for x in text_list if len(x) > 0]
|
| 202 |
+
metadata = MetadataCatalog.get("__unused_ape_" + text_prompt)
|
| 203 |
+
metadata.thing_classes = text_list
|
| 204 |
+
metadata.stuff_classes = text_list
|
| 205 |
+
else:
|
| 206 |
+
metadata = self.metadata
|
| 207 |
+
|
| 208 |
+
vis_output = None
|
| 209 |
+
predictions = self.predictor(image, text_prompt, mask_prompt)
|
| 210 |
+
|
| 211 |
+
if "instances" in predictions:
|
| 212 |
+
predictions["instances"] = filter_instances(
|
| 213 |
+
predictions["instances"].to(self.cpu_device), metadata
|
| 214 |
+
)
|
| 215 |
+
|
| 216 |
+
# Convert image from OpenCV BGR format to Matplotlib RGB format.
|
| 217 |
+
image = image[:, :, ::-1]
|
| 218 |
+
visualizer = Visualizer(image, metadata, instance_mode=self.instance_mode)
|
| 219 |
+
vis_outputs = []
|
| 220 |
+
if "panoptic_seg" in predictions and with_mask and with_sseg:
|
| 221 |
+
panoptic_seg, segments_info = predictions["panoptic_seg"]
|
| 222 |
+
vis_output = visualizer.draw_panoptic_seg_predictions(
|
| 223 |
+
panoptic_seg.to(self.cpu_device), segments_info
|
| 224 |
+
)
|
| 225 |
+
else:
|
| 226 |
+
if "sem_seg" in predictions and with_sseg:
|
| 227 |
+
# vis_output = visualizer.draw_sem_seg(
|
| 228 |
+
# predictions["sem_seg"].argmax(dim=0).to(self.cpu_device)
|
| 229 |
+
# )
|
| 230 |
+
|
| 231 |
+
sem_seg = predictions["sem_seg"].to(self.cpu_device)
|
| 232 |
+
# sem_seg = opencv_grabcut(image, sem_seg, iter=10)
|
| 233 |
+
# sem_seg = cuda_grabcut(image, sem_seg > 0.5, iter=5, gamma=10, iou_threshold=0.1)
|
| 234 |
+
sem_seg = torch.cat((sem_seg, torch.ones_like(sem_seg[0:1, ...]) * 0.1), dim=0)
|
| 235 |
+
sem_seg = sem_seg.argmax(dim=0)
|
| 236 |
+
vis_output = visualizer.draw_sem_seg(sem_seg)
|
| 237 |
+
if "instances" in predictions and (with_box or with_mask):
|
| 238 |
+
instances = predictions["instances"].to(self.cpu_device)
|
| 239 |
+
|
| 240 |
+
if not with_box:
|
| 241 |
+
instances.remove("pred_boxes")
|
| 242 |
+
if not with_mask:
|
| 243 |
+
instances.remove("pred_masks")
|
| 244 |
+
|
| 245 |
+
if with_mask and False:
|
| 246 |
+
# instances.pred_masks = opencv_grabcut(image, instances.pred_masks, iter=10)
|
| 247 |
+
instances.pred_masks = cuda_grabcut(
|
| 248 |
+
image, instances.pred_masks, iter=5, gamma=10, iou_threshold=0.75
|
| 249 |
+
)
|
| 250 |
+
|
| 251 |
+
vis_output = visualizer.draw_instance_predictions(predictions=instances)
|
| 252 |
+
|
| 253 |
+
# for i in range(len(instances)):
|
| 254 |
+
# visualizer = Visualizer(image, metadata, instance_mode=self.instance_mode)
|
| 255 |
+
# vis_outputs.append(visualizer.draw_instance_predictions(predictions=instances[i]))
|
| 256 |
+
|
| 257 |
+
elif "proposals" in predictions:
|
| 258 |
+
visualizer = Visualizer(image, None, instance_mode=self.instance_mode)
|
| 259 |
+
instances = predictions["proposals"].to(self.cpu_device)
|
| 260 |
+
instances.pred_boxes = instances.proposal_boxes
|
| 261 |
+
instances.scores = instances.objectness_logits
|
| 262 |
+
vis_output = visualizer.draw_instance_predictions(predictions=instances)
|
| 263 |
+
|
| 264 |
+
return predictions, vis_output, vis_outputs, metadata
|
| 265 |
+
|
| 266 |
+
def _frame_from_video(self, video):
|
| 267 |
+
while video.isOpened():
|
| 268 |
+
success, frame = video.read()
|
| 269 |
+
if success:
|
| 270 |
+
yield frame
|
| 271 |
+
else:
|
| 272 |
+
break
|
| 273 |
+
|
| 274 |
+
def run_on_video(self, video):
|
| 275 |
+
"""
|
| 276 |
+
Visualizes predictions on frames of the input video.
|
| 277 |
+
|
| 278 |
+
Args:
|
| 279 |
+
video (cv2.VideoCapture): a :class:`VideoCapture` object, whose source can be
|
| 280 |
+
either a webcam or a video file.
|
| 281 |
+
|
| 282 |
+
Yields:
|
| 283 |
+
ndarray: BGR visualizations of each video frame.
|
| 284 |
+
"""
|
| 285 |
+
video_visualizer = VideoVisualizer(self.metadata, self.instance_mode)
|
| 286 |
+
|
| 287 |
+
def process_predictions(frame, predictions):
|
| 288 |
+
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
| 289 |
+
if "panoptic_seg" in predictions and False:
|
| 290 |
+
panoptic_seg, segments_info = predictions["panoptic_seg"]
|
| 291 |
+
vis_frame = video_visualizer.draw_panoptic_seg_predictions(
|
| 292 |
+
frame, panoptic_seg.to(self.cpu_device), segments_info
|
| 293 |
+
)
|
| 294 |
+
elif "instances" in predictions and False:
|
| 295 |
+
predictions = predictions["instances"].to(self.cpu_device)
|
| 296 |
+
vis_frame = video_visualizer.draw_instance_predictions(frame, predictions)
|
| 297 |
+
elif "sem_seg" in predictions and False:
|
| 298 |
+
vis_frame = video_visualizer.draw_sem_seg(
|
| 299 |
+
frame, predictions["sem_seg"].argmax(dim=0).to(self.cpu_device)
|
| 300 |
+
)
|
| 301 |
+
|
| 302 |
+
if "sem_seg" in predictions:
|
| 303 |
+
vis_frame = video_visualizer.draw_sem_seg(
|
| 304 |
+
frame, predictions["sem_seg"].argmax(dim=0).to(self.cpu_device)
|
| 305 |
+
)
|
| 306 |
+
frame = vis_frame.get_image()
|
| 307 |
+
|
| 308 |
+
if "instances" in predictions:
|
| 309 |
+
predictions = predictions["instances"].to(self.cpu_device)
|
| 310 |
+
predictions = filter_instances(predictions, self.metadata)
|
| 311 |
+
vis_frame = video_visualizer.draw_instance_predictions(frame, predictions)
|
| 312 |
+
|
| 313 |
+
# Converts Matplotlib RGB format to OpenCV BGR format
|
| 314 |
+
vis_frame = cv2.cvtColor(vis_frame.get_image(), cv2.COLOR_RGB2BGR)
|
| 315 |
+
return vis_frame, predictions
|
| 316 |
+
|
| 317 |
+
frame_gen = self._frame_from_video(video)
|
| 318 |
+
if self.parallel:
|
| 319 |
+
buffer_size = self.predictor.default_buffer_size
|
| 320 |
+
|
| 321 |
+
frame_data = deque()
|
| 322 |
+
|
| 323 |
+
for cnt, frame in enumerate(frame_gen):
|
| 324 |
+
frame_data.append(frame)
|
| 325 |
+
self.predictor.put(frame)
|
| 326 |
+
|
| 327 |
+
if cnt >= buffer_size:
|
| 328 |
+
frame = frame_data.popleft()
|
| 329 |
+
predictions = self.predictor.get()
|
| 330 |
+
yield process_predictions(frame, predictions)
|
| 331 |
+
|
| 332 |
+
while len(frame_data):
|
| 333 |
+
frame = frame_data.popleft()
|
| 334 |
+
predictions = self.predictor.get()
|
| 335 |
+
yield process_predictions(frame, predictions)
|
| 336 |
+
else:
|
| 337 |
+
for frame in frame_gen:
|
| 338 |
+
yield process_predictions(frame, self.predictor(frame))
|
| 339 |
+
|
| 340 |
+
|
| 341 |
+
class AsyncPredictor:
|
| 342 |
+
"""
|
| 343 |
+
A predictor that runs the model asynchronously, possibly on >1 GPUs.
|
| 344 |
+
Because rendering the visualization takes considerably amount of time,
|
| 345 |
+
this helps improve throughput a little bit when rendering videos.
|
| 346 |
+
"""
|
| 347 |
+
|
| 348 |
+
class _StopToken:
|
| 349 |
+
pass
|
| 350 |
+
|
| 351 |
+
class _PredictWorker(mp.Process):
|
| 352 |
+
def __init__(self, cfg, task_queue, result_queue):
|
| 353 |
+
self.cfg = cfg
|
| 354 |
+
self.task_queue = task_queue
|
| 355 |
+
self.result_queue = result_queue
|
| 356 |
+
super().__init__()
|
| 357 |
+
|
| 358 |
+
def run(self):
|
| 359 |
+
predictor = DefaultPredictor(self.cfg)
|
| 360 |
+
|
| 361 |
+
while True:
|
| 362 |
+
task = self.task_queue.get()
|
| 363 |
+
if isinstance(task, AsyncPredictor._StopToken):
|
| 364 |
+
break
|
| 365 |
+
idx, data = task
|
| 366 |
+
result = predictor(data)
|
| 367 |
+
self.result_queue.put((idx, result))
|
| 368 |
+
|
| 369 |
+
def __init__(self, cfg, num_gpus: int = 1):
|
| 370 |
+
"""
|
| 371 |
+
Args:
|
| 372 |
+
cfg (CfgNode):
|
| 373 |
+
num_gpus (int): if 0, will run on CPU
|
| 374 |
+
"""
|
| 375 |
+
num_workers = max(num_gpus, 1)
|
| 376 |
+
self.task_queue = mp.Queue(maxsize=num_workers * 3)
|
| 377 |
+
self.result_queue = mp.Queue(maxsize=num_workers * 3)
|
| 378 |
+
self.procs = []
|
| 379 |
+
for gpuid in range(max(num_gpus, 1)):
|
| 380 |
+
cfg = cfg.clone()
|
| 381 |
+
cfg.defrost()
|
| 382 |
+
cfg.MODEL.DEVICE = "cuda:{}".format(gpuid) if num_gpus > 0 else "cpu"
|
| 383 |
+
self.procs.append(
|
| 384 |
+
AsyncPredictor._PredictWorker(cfg, self.task_queue, self.result_queue)
|
| 385 |
+
)
|
| 386 |
+
|
| 387 |
+
self.put_idx = 0
|
| 388 |
+
self.get_idx = 0
|
| 389 |
+
self.result_rank = []
|
| 390 |
+
self.result_data = []
|
| 391 |
+
|
| 392 |
+
for p in self.procs:
|
| 393 |
+
p.start()
|
| 394 |
+
atexit.register(self.shutdown)
|
| 395 |
+
|
| 396 |
+
def put(self, image):
|
| 397 |
+
self.put_idx += 1
|
| 398 |
+
self.task_queue.put((self.put_idx, image))
|
| 399 |
+
|
| 400 |
+
def get(self):
|
| 401 |
+
self.get_idx += 1 # the index needed for this request
|
| 402 |
+
if len(self.result_rank) and self.result_rank[0] == self.get_idx:
|
| 403 |
+
res = self.result_data[0]
|
| 404 |
+
del self.result_data[0], self.result_rank[0]
|
| 405 |
+
return res
|
| 406 |
+
|
| 407 |
+
while True:
|
| 408 |
+
# make sure the results are returned in the correct order
|
| 409 |
+
idx, res = self.result_queue.get()
|
| 410 |
+
if idx == self.get_idx:
|
| 411 |
+
return res
|
| 412 |
+
insert = bisect.bisect(self.result_rank, idx)
|
| 413 |
+
self.result_rank.insert(insert, idx)
|
| 414 |
+
self.result_data.insert(insert, res)
|
| 415 |
+
|
| 416 |
+
def __len__(self):
|
| 417 |
+
return self.put_idx - self.get_idx
|
| 418 |
+
|
| 419 |
+
def __call__(self, image):
|
| 420 |
+
self.put(image)
|
| 421 |
+
return self.get()
|
| 422 |
+
|
| 423 |
+
def shutdown(self):
|
| 424 |
+
for _ in self.procs:
|
| 425 |
+
self.task_queue.put(AsyncPredictor._StopToken())
|
| 426 |
+
|
| 427 |
+
@property
|
| 428 |
+
def default_buffer_size(self):
|
| 429 |
+
return len(self.procs) * 5
|
approach/ovod/APE/demo/requirements.txt
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
transformers
|
| 2 |
+
cython
|
| 3 |
+
opencv-python
|
| 4 |
+
scipy
|
| 5 |
+
einops
|
| 6 |
+
lvis
|
| 7 |
+
fairscale
|
| 8 |
+
git+https://github.com/facebookresearch/detectron2@017abbf
|
| 9 |
+
git+https://github.com/IDEA-Research/detrex@776058e
|
| 10 |
+
git+https://github.com/openai/CLIP.git@d50d76d
|
| 11 |
+
git+https://github.com/shenyunhang/ape
|
approach/ovod/GroundingDINO/.gitignore
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# IDE
|
| 2 |
+
.idea/
|
| 3 |
+
.vscode/
|
| 4 |
+
|
| 5 |
+
# Byte-compiled / optimized / DLL files
|
| 6 |
+
__pycache__/
|
| 7 |
+
*.py[cod]
|
| 8 |
+
*$py.class
|
| 9 |
+
|
| 10 |
+
# C extensions
|
| 11 |
+
*.so
|
| 12 |
+
|
| 13 |
+
# Distribution / packaging
|
| 14 |
+
.Python
|
| 15 |
+
build/
|
| 16 |
+
develop-eggs/
|
| 17 |
+
dist/
|
| 18 |
+
downloads/
|
| 19 |
+
eggs/
|
| 20 |
+
.eggs/
|
| 21 |
+
lib/
|
| 22 |
+
lib64/
|
| 23 |
+
parts/
|
| 24 |
+
sdist/
|
| 25 |
+
var/
|
| 26 |
+
wheels/
|
| 27 |
+
pip-wheel-metadata/
|
| 28 |
+
share/python-wheels/
|
| 29 |
+
*.egg-info/
|
| 30 |
+
.installed.cfg
|
| 31 |
+
*.egg
|
| 32 |
+
MANIFEST
|
| 33 |
+
|
| 34 |
+
# PyInstaller
|
| 35 |
+
# Usually these files are written by a python script from a template
|
| 36 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
| 37 |
+
*.manifest
|
| 38 |
+
*.spec
|
| 39 |
+
|
| 40 |
+
# Installer logs
|
| 41 |
+
pip-log.txt
|
| 42 |
+
pip-delete-this-directory.txt
|
| 43 |
+
|
| 44 |
+
# Unit test / coverage reports
|
| 45 |
+
htmlcov/
|
| 46 |
+
.tox/
|
| 47 |
+
.nox/
|
| 48 |
+
.coverage
|
| 49 |
+
.coverage.*
|
| 50 |
+
.cache
|
| 51 |
+
nosetests.xml
|
| 52 |
+
coverage.xml
|
| 53 |
+
*.cover
|
| 54 |
+
*.py,cover
|
| 55 |
+
.hypothesis/
|
| 56 |
+
.pytest_cache/
|
| 57 |
+
|
| 58 |
+
# Translations
|
| 59 |
+
*.mo
|
| 60 |
+
*.pot
|
| 61 |
+
|
| 62 |
+
# Django stuff:
|
| 63 |
+
*.log
|
| 64 |
+
local_settings.py
|
| 65 |
+
db.sqlite3
|
| 66 |
+
db.sqlite3-journal
|
| 67 |
+
|
| 68 |
+
# Flask stuff:
|
| 69 |
+
instance/
|
| 70 |
+
.webassets-cache
|
| 71 |
+
|
| 72 |
+
# Scrapy stuff:
|
| 73 |
+
.scrapy
|
| 74 |
+
|
| 75 |
+
# Sphinx documentation
|
| 76 |
+
docs/_build/
|
| 77 |
+
|
| 78 |
+
# PyBuilder
|
| 79 |
+
target/
|
| 80 |
+
|
| 81 |
+
# Jupyter Notebook
|
| 82 |
+
.ipynb_checkpoints
|
| 83 |
+
|
| 84 |
+
# IPython
|
| 85 |
+
profile_default/
|
| 86 |
+
ipython_config.py
|
| 87 |
+
|
| 88 |
+
# pyenv
|
| 89 |
+
.python-version
|
| 90 |
+
|
| 91 |
+
# pipenv
|
| 92 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
| 93 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
| 94 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
| 95 |
+
# install all needed dependencies.
|
| 96 |
+
#Pipfile.lock
|
| 97 |
+
|
| 98 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
| 99 |
+
__pypackages__/
|
| 100 |
+
|
| 101 |
+
# Celery stuff
|
| 102 |
+
celerybeat-schedule
|
| 103 |
+
celerybeat.pid
|
| 104 |
+
|
| 105 |
+
# SageMath parsed files
|
| 106 |
+
*.sage.py
|
| 107 |
+
|
| 108 |
+
# Environments
|
| 109 |
+
.env
|
| 110 |
+
.venv
|
| 111 |
+
env/
|
| 112 |
+
venv/
|
| 113 |
+
ENV/
|
| 114 |
+
env.bak/
|
| 115 |
+
venv.bak/
|
| 116 |
+
|
| 117 |
+
# Spyder project settings
|
| 118 |
+
.spyderproject
|
| 119 |
+
.spyproject
|
| 120 |
+
|
| 121 |
+
# Rope project settings
|
| 122 |
+
.ropeproject
|
| 123 |
+
|
| 124 |
+
# mkdocs documentation
|
| 125 |
+
/site
|
| 126 |
+
|
| 127 |
+
# mypy
|
| 128 |
+
.mypy_cache/
|
| 129 |
+
.dmypy.json
|
| 130 |
+
dmypy.json
|
| 131 |
+
|
| 132 |
+
# Pyre type checker
|
| 133 |
+
.pyre/
|
| 134 |
+
|
| 135 |
+
# vscode
|
| 136 |
+
.vscode/
|
| 137 |
+
output/
|
| 138 |
+
outputs/
|
| 139 |
+
subs/
|
| 140 |
+
logs/
|
| 141 |
+
|
| 142 |
+
grounding/config/configs
|
| 143 |
+
grounding/version.py
|
| 144 |
+
|
| 145 |
+
vis/
|
| 146 |
+
tmp/
|
approach/ovod/GroundingDINO/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Apache License
|
| 2 |
+
Version 2.0, January 2004
|
| 3 |
+
http://www.apache.org/licenses/
|
| 4 |
+
|
| 5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 6 |
+
|
| 7 |
+
1. Definitions.
|
| 8 |
+
|
| 9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 11 |
+
|
| 12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 13 |
+
the copyright owner that is granting the License.
|
| 14 |
+
|
| 15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 16 |
+
other entities that control, are controlled by, or are under common
|
| 17 |
+
control with that entity. For the purposes of this definition,
|
| 18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 19 |
+
direction or management of such entity, whether by contract or
|
| 20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 22 |
+
|
| 23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 24 |
+
exercising permissions granted by this License.
|
| 25 |
+
|
| 26 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 27 |
+
including but not limited to software source code, documentation
|
| 28 |
+
source, and configuration files.
|
| 29 |
+
|
| 30 |
+
"Object" form shall mean any form resulting from mechanical
|
| 31 |
+
transformation or translation of a Source form, including but
|
| 32 |
+
not limited to compiled object code, generated documentation,
|
| 33 |
+
and conversions to other media types.
|
| 34 |
+
|
| 35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 36 |
+
Object form, made available under the License, as indicated by a
|
| 37 |
+
copyright notice that is included in or attached to the work
|
| 38 |
+
(an example is provided in the Appendix below).
|
| 39 |
+
|
| 40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 41 |
+
form, that is based on (or derived from) the Work and for which the
|
| 42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 44 |
+
of this License, Derivative Works shall not include works that remain
|
| 45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 46 |
+
the Work and Derivative Works thereof.
|
| 47 |
+
|
| 48 |
+
"Contribution" shall mean any work of authorship, including
|
| 49 |
+
the original version of the Work and any modifications or additions
|
| 50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 54 |
+
means any form of electronic, verbal, or written communication sent
|
| 55 |
+
to the Licensor or its representatives, including but not limited to
|
| 56 |
+
communication on electronic mailing lists, source code control systems,
|
| 57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 59 |
+
excluding communication that is conspicuously marked or otherwise
|
| 60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 61 |
+
|
| 62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
| 64 |
+
subsequently incorporated within the Work.
|
| 65 |
+
|
| 66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 71 |
+
Work and such Derivative Works in Source or Object form.
|
| 72 |
+
|
| 73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 76 |
+
(except as stated in this section) patent license to make, have made,
|
| 77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 78 |
+
where such license applies only to those patent claims licensable
|
| 79 |
+
by such Contributor that are necessarily infringed by their
|
| 80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 82 |
+
institute patent litigation against any entity (including a
|
| 83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 84 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 85 |
+
or contributory patent infringement, then any patent licenses
|
| 86 |
+
granted to You under this License for that Work shall terminate
|
| 87 |
+
as of the date such litigation is filed.
|
| 88 |
+
|
| 89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 90 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 91 |
+
modifications, and in Source or Object form, provided that You
|
| 92 |
+
meet the following conditions:
|
| 93 |
+
|
| 94 |
+
(a) You must give any other recipients of the Work or
|
| 95 |
+
Derivative Works a copy of this License; and
|
| 96 |
+
|
| 97 |
+
(b) You must cause any modified files to carry prominent notices
|
| 98 |
+
stating that You changed the files; and
|
| 99 |
+
|
| 100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 101 |
+
that You distribute, all copyright, patent, trademark, and
|
| 102 |
+
attribution notices from the Source form of the Work,
|
| 103 |
+
excluding those notices that do not pertain to any part of
|
| 104 |
+
the Derivative Works; and
|
| 105 |
+
|
| 106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 107 |
+
distribution, then any Derivative Works that You distribute must
|
| 108 |
+
include a readable copy of the attribution notices contained
|
| 109 |
+
within such NOTICE file, excluding those notices that do not
|
| 110 |
+
pertain to any part of the Derivative Works, in at least one
|
| 111 |
+
of the following places: within a NOTICE text file distributed
|
| 112 |
+
as part of the Derivative Works; within the Source form or
|
| 113 |
+
documentation, if provided along with the Derivative Works; or,
|
| 114 |
+
within a display generated by the Derivative Works, if and
|
| 115 |
+
wherever such third-party notices normally appear. The contents
|
| 116 |
+
of the NOTICE file are for informational purposes only and
|
| 117 |
+
do not modify the License. You may add Your own attribution
|
| 118 |
+
notices within Derivative Works that You distribute, alongside
|
| 119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 120 |
+
that such additional attribution notices cannot be construed
|
| 121 |
+
as modifying the License.
|
| 122 |
+
|
| 123 |
+
You may add Your own copyright statement to Your modifications and
|
| 124 |
+
may provide additional or different license terms and conditions
|
| 125 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 126 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 127 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 128 |
+
the conditions stated in this License.
|
| 129 |
+
|
| 130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 132 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 133 |
+
this License, without any additional terms or conditions.
|
| 134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 135 |
+
the terms of any separate license agreement you may have executed
|
| 136 |
+
with Licensor regarding such Contributions.
|
| 137 |
+
|
| 138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 140 |
+
except as required for reasonable and customary use in describing the
|
| 141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 142 |
+
|
| 143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 144 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 147 |
+
implied, including, without limitation, any warranties or conditions
|
| 148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 150 |
+
appropriateness of using or redistributing the Work and assume any
|
| 151 |
+
risks associated with Your exercise of permissions under this License.
|
| 152 |
+
|
| 153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 154 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 155 |
+
unless required by applicable law (such as deliberate and grossly
|
| 156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 157 |
+
liable to You for damages, including any direct, indirect, special,
|
| 158 |
+
incidental, or consequential damages of any character arising as a
|
| 159 |
+
result of this License or out of the use or inability to use the
|
| 160 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 161 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 162 |
+
other commercial damages or losses), even if such Contributor
|
| 163 |
+
has been advised of the possibility of such damages.
|
| 164 |
+
|
| 165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 168 |
+
or other liability obligations and/or rights consistent with this
|
| 169 |
+
License. However, in accepting such obligations, You may act only
|
| 170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 171 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 172 |
+
defend, and hold each Contributor harmless for any liability
|
| 173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 174 |
+
of your accepting any such warranty or additional liability.
|
| 175 |
+
|
| 176 |
+
END OF TERMS AND CONDITIONS
|
| 177 |
+
|
| 178 |
+
APPENDIX: How to apply the Apache License to your work.
|
| 179 |
+
|
| 180 |
+
To apply the Apache License to your work, attach the following
|
| 181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 182 |
+
replaced with your own identifying information. (Don't include
|
| 183 |
+
the brackets!) The text should be enclosed in the appropriate
|
| 184 |
+
comment syntax for the file format. We also recommend that a
|
| 185 |
+
file or class name and description of purpose be included on the
|
| 186 |
+
same "printed page" as the copyright notice for easier
|
| 187 |
+
identification within third-party archives.
|
| 188 |
+
|
| 189 |
+
Copyright 2023 - present, IDEA Research.
|
| 190 |
+
|
| 191 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 192 |
+
you may not use this file except in compliance with the License.
|
| 193 |
+
You may obtain a copy of the License at
|
| 194 |
+
|
| 195 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 196 |
+
|
| 197 |
+
Unless required by applicable law or agreed to in writing, software
|
| 198 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 199 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 200 |
+
See the License for the specific language governing permissions and
|
| 201 |
+
limitations under the License.
|
approach/ovod/GroundingDINO/README.md
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<div align="center">
|
| 2 |
+
<img src="./.asset/grounding_dino_logo.png" width="30%">
|
| 3 |
+
</div>
|
| 4 |
+
|
| 5 |
+
# :sauropod: Grounding DINO
|
| 6 |
+
|
| 7 |
+
[](https://paperswithcode.com/sota/zero-shot-object-detection-on-mscoco?p=grounding-dino-marrying-dino-with-grounded) [](https://paperswithcode.com/sota/zero-shot-object-detection-on-odinw?p=grounding-dino-marrying-dino-with-grounded) \
|
| 8 |
+
[](https://paperswithcode.com/sota/object-detection-on-coco-minival?p=grounding-dino-marrying-dino-with-grounded) [](https://paperswithcode.com/sota/object-detection-on-coco?p=grounding-dino-marrying-dino-with-grounded)
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
**[IDEA-CVR, IDEA-Research](https://github.com/IDEA-Research)**
|
| 12 |
+
|
| 13 |
+
[Shilong Liu](http://www.lsl.zone/), [Zhaoyang Zeng](https://scholar.google.com/citations?user=U_cvvUwAAAAJ&hl=zh-CN&oi=ao), [Tianhe Ren](https://rentainhe.github.io/), [Feng Li](https://scholar.google.com/citations?user=ybRe9GcAAAAJ&hl=zh-CN), [Hao Zhang](https://scholar.google.com/citations?user=B8hPxMQAAAAJ&hl=zh-CN), [Jie Yang](https://github.com/yangjie-cv), [Chunyuan Li](https://scholar.google.com/citations?user=Zd7WmXUAAAAJ&hl=zh-CN&oi=ao), [Jianwei Yang](https://jwyang.github.io/), [Hang Su](https://scholar.google.com/citations?hl=en&user=dxN1_X0AAAAJ&view_op=list_works&sortby=pubdate), [Jun Zhu](https://scholar.google.com/citations?hl=en&user=axsP38wAAAAJ), [Lei Zhang](https://www.leizhang.org/)<sup>:email:</sup>.
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
[[`Paper`](https://arxiv.org/abs/2303.05499)] [[`Demo`](https://huggingface.co/spaces/ShilongLiu/Grounding_DINO_demo)] [[`BibTex`](#black_nib-citation)]
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
PyTorch implementation and pretrained models for Grounding DINO. For details, see the paper **[Grounding DINO: Marrying DINO with Grounded Pre-Training for Open-Set Object Detection](https://arxiv.org/abs/2303.05499)**.
|
| 20 |
+
|
| 21 |
+
## :sun_with_face: Helpful Tutorial
|
| 22 |
+
|
| 23 |
+
- :grapes: [[Read our arXiv Paper](https://arxiv.org/abs/2303.05499)]
|
| 24 |
+
- :apple: [[Watch our simple introduction video on YouTube](https://youtu.be/wxWDt5UiwY8)]
|
| 25 |
+
- :blossom: [[Try the Colab Demo](https://colab.research.google.com/github/roboflow-ai/notebooks/blob/main/notebooks/zero-shot-object-detection-with-grounding-dino.ipynb)]
|
| 26 |
+
- :sunflower: [[Try our Official Huggingface Demo](https://huggingface.co/spaces/ShilongLiu/Grounding_DINO_demo)]
|
| 27 |
+
- :maple_leaf: [[Watch the Step by Step Tutorial about GroundingDINO by Roboflow AI](https://youtu.be/cMa77r3YrDk)]
|
| 28 |
+
- :mushroom: [[GroundingDINO: Automated Dataset Annotation and Evaluation by Roboflow AI](https://youtu.be/C4NqaRBz_Kw)]
|
| 29 |
+
- :hibiscus: [[Accelerate Image Annotation with SAM and GroundingDINO by Roboflow AI](https://youtu.be/oEQYStnF2l8)]
|
| 30 |
+
- :white_flower: [[Autodistill: Train YOLOv8 with ZERO Annotations based on Grounding-DINO and Grounded-SAM by Roboflow AI](https://github.com/autodistill/autodistill)]
|
| 31 |
+
|
| 32 |
+
<!-- Grounding DINO Methods |
|
| 33 |
+
[](https://arxiv.org/abs/2303.05499)
|
| 34 |
+
[](https://youtu.be/wxWDt5UiwY8) -->
|
| 35 |
+
|
| 36 |
+
<!-- Grounding DINO Demos |
|
| 37 |
+
[](https://colab.research.google.com/github/roboflow-ai/notebooks/blob/main/notebooks/zero-shot-object-detection-with-grounding-dino.ipynb) -->
|
| 38 |
+
<!-- [](https://youtu.be/cMa77r3YrDk)
|
| 39 |
+
[](https://huggingface.co/spaces/ShilongLiu/Grounding_DINO_demo)
|
| 40 |
+
[](https://youtu.be/oEQYStnF2l8)
|
| 41 |
+
[](https://youtu.be/C4NqaRBz_Kw) -->
|
| 42 |
+
|
| 43 |
+
## :sparkles: Highlight Projects
|
| 44 |
+
|
| 45 |
+
- [Semantic-SAM: a universal image segmentation model to enable segment and recognize anything at any desired granularity.](https://github.com/UX-Decoder/Semantic-SAM),
|
| 46 |
+
- [DetGPT: Detect What You Need via Reasoning](https://github.com/OptimalScale/DetGPT)
|
| 47 |
+
- [Grounded-SAM: Marrying Grounding DINO with Segment Anything](https://github.com/IDEA-Research/Grounded-Segment-Anything)
|
| 48 |
+
- [Grounding DINO with Stable Diffusion](demo/image_editing_with_groundingdino_stablediffusion.ipynb)
|
| 49 |
+
- [Grounding DINO with GLIGEN for Controllable Image Editing](demo/image_editing_with_groundingdino_gligen.ipynb)
|
| 50 |
+
- [OpenSeeD: A Simple and Strong Openset Segmentation Model](https://github.com/IDEA-Research/OpenSeeD)
|
| 51 |
+
- [SEEM: Segment Everything Everywhere All at Once](https://github.com/UX-Decoder/Segment-Everything-Everywhere-All-At-Once)
|
| 52 |
+
- [X-GPT: Conversational Visual Agent supported by X-Decoder](https://github.com/microsoft/X-Decoder/tree/xgpt)
|
| 53 |
+
- [GLIGEN: Open-Set Grounded Text-to-Image Generation](https://github.com/gligen/GLIGEN)
|
| 54 |
+
- [LLaVA: Large Language and Vision Assistant](https://github.com/haotian-liu/LLaVA)
|
| 55 |
+
|
| 56 |
+
<!-- Extensions | [Grounding DINO with Segment Anything](https://github.com/IDEA-Research/Grounded-Segment-Anything); [Grounding DINO with Stable Diffusion](demo/image_editing_with_groundingdino_stablediffusion.ipynb); [Grounding DINO with GLIGEN](demo/image_editing_with_groundingdino_gligen.ipynb) -->
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
<!-- Official PyTorch implementation of [Grounding DINO](https://arxiv.org/abs/2303.05499), a stronger open-set object detector. Code is available now! -->
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
## :bulb: Highlight
|
| 64 |
+
|
| 65 |
+
- **Open-Set Detection.** Detect **everything** with language!
|
| 66 |
+
- **High Performancce.** COCO zero-shot **52.5 AP** (training without COCO data!). COCO fine-tune **63.0 AP**.
|
| 67 |
+
- **Flexible.** Collaboration with Stable Diffusion for Image Editting.
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
## :fire: News
|
| 73 |
+
- **`2023/07/18`**: We release [Semantic-SAM](https://github.com/UX-Decoder/Semantic-SAM), a universal image segmentation model to enable segment and recognize anything at any desired granularity. **Code** and **checkpoint** are available!
|
| 74 |
+
- **`2023/06/17`**: We provide an example to evaluate Grounding DINO on COCO zero-shot performance.
|
| 75 |
+
- **`2023/04/15`**: Refer to [CV in the Wild Readings](https://github.com/Computer-Vision-in-the-Wild/CVinW_Readings) for those who are interested in open-set recognition!
|
| 76 |
+
- **`2023/04/08`**: We release [demos](demo/image_editing_with_groundingdino_gligen.ipynb) to combine [Grounding DINO](https://arxiv.org/abs/2303.05499) with [GLIGEN](https://github.com/gligen/GLIGEN) for more controllable image editings.
|
| 77 |
+
- **`2023/04/08`**: We release [demos](demo/image_editing_with_groundingdino_stablediffusion.ipynb) to combine [Grounding DINO](https://arxiv.org/abs/2303.05499) with [Stable Diffusion](https://github.com/Stability-AI/StableDiffusion) for image editings.
|
| 78 |
+
- **`2023/04/06`**: We build a new demo by marrying GroundingDINO with [Segment-Anything](https://github.com/facebookresearch/segment-anything) named **[Grounded-Segment-Anything](https://github.com/IDEA-Research/Grounded-Segment-Anything)** aims to support segmentation in GroundingDINO.
|
| 79 |
+
- **`2023/03/28`**: A YouTube [video](https://youtu.be/cMa77r3YrDk) about Grounding DINO and basic object detection prompt engineering. [[SkalskiP](https://github.com/SkalskiP)]
|
| 80 |
+
- **`2023/03/28`**: Add a [demo](https://huggingface.co/spaces/ShilongLiu/Grounding_DINO_demo) on Hugging Face Space!
|
| 81 |
+
- **`2023/03/27`**: Support CPU-only mode. Now the model can run on machines without GPUs.
|
| 82 |
+
- **`2023/03/25`**: A [demo](https://colab.research.google.com/github/roboflow-ai/notebooks/blob/main/notebooks/zero-shot-object-detection-with-grounding-dino.ipynb) for Grounding DINO is available at Colab. [[SkalskiP](https://github.com/SkalskiP)]
|
| 83 |
+
- **`2023/03/22`**: Code is available Now!
|
| 84 |
+
|
| 85 |
+
<details open>
|
| 86 |
+
<summary><font size="4">
|
| 87 |
+
Description
|
| 88 |
+
</font></summary>
|
| 89 |
+
<a href="https://arxiv.org/abs/2303.05499">Paper</a> introduction.
|
| 90 |
+
<img src=".asset/hero_figure.png" alt="ODinW" width="100%">
|
| 91 |
+
Marrying <a href="https://github.com/IDEA-Research/GroundingDINO">Grounding DINO</a> and <a href="https://github.com/gligen/GLIGEN">GLIGEN</a>
|
| 92 |
+
<img src="https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/GD_GLIGEN.png" alt="gd_gligen" width="100%">
|
| 93 |
+
</details>
|
| 94 |
+
|
| 95 |
+
## :star: Explanations/Tips for Grounding DINO Inputs and Outputs
|
| 96 |
+
- Grounding DINO accepts an `(image, text)` pair as inputs.
|
| 97 |
+
- It outputs `900` (by default) object boxes. Each box has similarity scores across all input words. (as shown in Figures below.)
|
| 98 |
+
- We defaultly choose the boxes whose highest similarities are higher than a `box_threshold`.
|
| 99 |
+
- We extract the words whose similarities are higher than the `text_threshold` as predicted labels.
|
| 100 |
+
- If you want to obtain objects of specific phrases, like the `dogs` in the sentence `two dogs with a stick.`, you can select the boxes with highest text similarities with `dogs` as final outputs.
|
| 101 |
+
- Note that each word can be split to **more than one** tokens with different tokenlizers. The number of words in a sentence may not equal to the number of text tokens.
|
| 102 |
+
- We suggest separating different category names with `.` for Grounding DINO.
|
| 103 |
+

|
| 104 |
+

|
| 105 |
+
|
| 106 |
+
## :label: TODO
|
| 107 |
+
|
| 108 |
+
- [x] Release inference code and demo.
|
| 109 |
+
- [x] Release checkpoints.
|
| 110 |
+
- [x] Grounding DINO with Stable Diffusion and GLIGEN demos.
|
| 111 |
+
- [ ] Release training codes.
|
| 112 |
+
|
| 113 |
+
## :hammer_and_wrench: Install
|
| 114 |
+
|
| 115 |
+
**Note:**
|
| 116 |
+
|
| 117 |
+
0. If you have a CUDA environment, please make sure the environment variable `CUDA_HOME` is set. It will be compiled under CPU-only mode if no CUDA available.
|
| 118 |
+
|
| 119 |
+
Please make sure following the installation steps strictly, otherwise the program may produce:
|
| 120 |
+
```bash
|
| 121 |
+
NameError: name '_C' is not defined
|
| 122 |
+
```
|
| 123 |
+
|
| 124 |
+
If this happened, please reinstalled the groundingDINO by reclone the git and do all the installation steps again.
|
| 125 |
+
|
| 126 |
+
#### how to check cuda:
|
| 127 |
+
```bash
|
| 128 |
+
echo $CUDA_HOME
|
| 129 |
+
```
|
| 130 |
+
If it print nothing, then it means you haven't set up the path/
|
| 131 |
+
|
| 132 |
+
Run this so the environment variable will be set under current shell.
|
| 133 |
+
```bash
|
| 134 |
+
export CUDA_HOME=/path/to/cuda-11.3
|
| 135 |
+
```
|
| 136 |
+
|
| 137 |
+
Notice the version of cuda should be aligned with your CUDA runtime, for there might exists multiple cuda at the same time.
|
| 138 |
+
|
| 139 |
+
If you want to set the CUDA_HOME permanently, store it using:
|
| 140 |
+
|
| 141 |
+
```bash
|
| 142 |
+
echo 'export CUDA_HOME=/path/to/cuda' >> ~/.bashrc
|
| 143 |
+
```
|
| 144 |
+
after that, source the bashrc file and check CUDA_HOME:
|
| 145 |
+
```bash
|
| 146 |
+
source ~/.bashrc
|
| 147 |
+
echo $CUDA_HOME
|
| 148 |
+
```
|
| 149 |
+
|
| 150 |
+
In this example, /path/to/cuda-11.3 should be replaced with the path where your CUDA toolkit is installed. You can find this by typing **which nvcc** in your terminal:
|
| 151 |
+
|
| 152 |
+
For instance,
|
| 153 |
+
if the output is /usr/local/cuda/bin/nvcc, then:
|
| 154 |
+
```bash
|
| 155 |
+
export CUDA_HOME=/usr/local/cuda
|
| 156 |
+
```
|
| 157 |
+
**Installation:**
|
| 158 |
+
|
| 159 |
+
1.Clone the GroundingDINO repository from GitHub.
|
| 160 |
+
|
| 161 |
+
```bash
|
| 162 |
+
git clone https://github.com/IDEA-Research/GroundingDINO.git
|
| 163 |
+
```
|
| 164 |
+
|
| 165 |
+
2. Change the current directory to the GroundingDINO folder.
|
| 166 |
+
|
| 167 |
+
```bash
|
| 168 |
+
cd GroundingDINO/
|
| 169 |
+
```
|
| 170 |
+
|
| 171 |
+
3. Install the required dependencies in the current directory.
|
| 172 |
+
|
| 173 |
+
```bash
|
| 174 |
+
pip install -e .
|
| 175 |
+
```
|
| 176 |
+
|
| 177 |
+
4. Download pre-trained model weights.
|
| 178 |
+
|
| 179 |
+
```bash
|
| 180 |
+
mkdir weights
|
| 181 |
+
cd weights
|
| 182 |
+
wget -q https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha/groundingdino_swint_ogc.pth
|
| 183 |
+
cd ..
|
| 184 |
+
```
|
| 185 |
+
|
| 186 |
+
## :arrow_forward: Demo
|
| 187 |
+
Check your GPU ID (only if you're using a GPU)
|
| 188 |
+
|
| 189 |
+
```bash
|
| 190 |
+
nvidia-smi
|
| 191 |
+
```
|
| 192 |
+
Replace `{GPU ID}`, `image_you_want_to_detect.jpg`, and `"dir you want to save the output"` with appropriate values in the following command
|
| 193 |
+
```bash
|
| 194 |
+
CUDA_VISIBLE_DEVICES={GPU ID} python demo/inference_on_a_image.py \
|
| 195 |
+
-c groundingdino/config/GroundingDINO_SwinT_OGC.py \
|
| 196 |
+
-p weights/groundingdino_swint_ogc.pth \
|
| 197 |
+
-i image_you_want_to_detect.jpg \
|
| 198 |
+
-o "dir you want to save the output" \
|
| 199 |
+
-t "chair"
|
| 200 |
+
[--cpu-only] # open it for cpu mode
|
| 201 |
+
```
|
| 202 |
+
|
| 203 |
+
If you would like to specify the phrases to detect, here is a demo:
|
| 204 |
+
```bash
|
| 205 |
+
CUDA_VISIBLE_DEVICES={GPU ID} python demo/inference_on_a_image.py \
|
| 206 |
+
-c groundingdino/config/GroundingDINO_SwinT_OGC.py \
|
| 207 |
+
-p ./groundingdino_swint_ogc.pth \
|
| 208 |
+
-i .asset/cat_dog.jpeg \
|
| 209 |
+
-o logs/1111 \
|
| 210 |
+
-t "There is a cat and a dog in the image ." \
|
| 211 |
+
--token_spans "[[[9, 10], [11, 14]], [[19, 20], [21, 24]]]"
|
| 212 |
+
[--cpu-only] # open it for cpu mode
|
| 213 |
+
```
|
| 214 |
+
The token_spans specify the start and end positions of a phrases. For example, the first phrase is `[[9, 10], [11, 14]]`. `"There is a cat and a dog in the image ."[9:10] = 'a'`, `"There is a cat and a dog in the image ."[11:14] = 'cat'`. Hence it refers to the phrase `a cat` . Similarly, the `[[19, 20], [21, 24]]` refers to the phrase `a dog`.
|
| 215 |
+
|
| 216 |
+
See the `demo/inference_on_a_image.py` for more details.
|
| 217 |
+
|
| 218 |
+
**Running with Python:**
|
| 219 |
+
|
| 220 |
+
```python
|
| 221 |
+
from groundingdino.util.inference import load_model, load_image, predict, annotate
|
| 222 |
+
import cv2
|
| 223 |
+
|
| 224 |
+
model = load_model("groundingdino/config/GroundingDINO_SwinT_OGC.py", "weights/groundingdino_swint_ogc.pth")
|
| 225 |
+
IMAGE_PATH = "weights/dog-3.jpeg"
|
| 226 |
+
TEXT_PROMPT = "chair . person . dog ."
|
| 227 |
+
BOX_TRESHOLD = 0.35
|
| 228 |
+
TEXT_TRESHOLD = 0.25
|
| 229 |
+
|
| 230 |
+
image_source, image = load_image(IMAGE_PATH)
|
| 231 |
+
|
| 232 |
+
boxes, logits, phrases = predict(
|
| 233 |
+
model=model,
|
| 234 |
+
image=image,
|
| 235 |
+
caption=TEXT_PROMPT,
|
| 236 |
+
box_threshold=BOX_TRESHOLD,
|
| 237 |
+
text_threshold=TEXT_TRESHOLD
|
| 238 |
+
)
|
| 239 |
+
|
| 240 |
+
annotated_frame = annotate(image_source=image_source, boxes=boxes, logits=logits, phrases=phrases)
|
| 241 |
+
cv2.imwrite("annotated_image.jpg", annotated_frame)
|
| 242 |
+
```
|
| 243 |
+
**Web UI**
|
| 244 |
+
|
| 245 |
+
We also provide a demo code to integrate Grounding DINO with Gradio Web UI. See the file `demo/gradio_app.py` for more details.
|
| 246 |
+
|
| 247 |
+
**Notebooks**
|
| 248 |
+
|
| 249 |
+
- We release [demos](demo/image_editing_with_groundingdino_gligen.ipynb) to combine [Grounding DINO](https://arxiv.org/abs/2303.05499) with [GLIGEN](https://github.com/gligen/GLIGEN) for more controllable image editings.
|
| 250 |
+
- We release [demos](demo/image_editing_with_groundingdino_stablediffusion.ipynb) to combine [Grounding DINO](https://arxiv.org/abs/2303.05499) with [Stable Diffusion](https://github.com/Stability-AI/StableDiffusion) for image editings.
|
| 251 |
+
|
| 252 |
+
## COCO Zero-shot Evaluations
|
| 253 |
+
|
| 254 |
+
We provide an example to evaluate Grounding DINO zero-shot performance on COCO. The results should be **48.5**.
|
| 255 |
+
|
| 256 |
+
```bash
|
| 257 |
+
CUDA_VISIBLE_DEVICES=0 \
|
| 258 |
+
python demo/test_ap_on_coco.py \
|
| 259 |
+
-c groundingdino/config/GroundingDINO_SwinT_OGC.py \
|
| 260 |
+
-p weights/groundingdino_swint_ogc.pth \
|
| 261 |
+
--anno_path /path/to/annoataions/ie/instances_val2017.json \
|
| 262 |
+
--image_dir /path/to/imagedir/ie/val2017
|
| 263 |
+
```
|
| 264 |
+
|
| 265 |
+
|
| 266 |
+
## :luggage: Checkpoints
|
| 267 |
+
|
| 268 |
+
<!-- insert a table -->
|
| 269 |
+
<table>
|
| 270 |
+
<thead>
|
| 271 |
+
<tr style="text-align: right;">
|
| 272 |
+
<th></th>
|
| 273 |
+
<th>name</th>
|
| 274 |
+
<th>backbone</th>
|
| 275 |
+
<th>Data</th>
|
| 276 |
+
<th>box AP on COCO</th>
|
| 277 |
+
<th>Checkpoint</th>
|
| 278 |
+
<th>Config</th>
|
| 279 |
+
</tr>
|
| 280 |
+
</thead>
|
| 281 |
+
<tbody>
|
| 282 |
+
<tr>
|
| 283 |
+
<th>1</th>
|
| 284 |
+
<td>GroundingDINO-T</td>
|
| 285 |
+
<td>Swin-T</td>
|
| 286 |
+
<td>O365,GoldG,Cap4M</td>
|
| 287 |
+
<td>48.4 (zero-shot) / 57.2 (fine-tune)</td>
|
| 288 |
+
<td><a href="https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha/groundingdino_swint_ogc.pth">GitHub link</a> | <a href="https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/groundingdino_swint_ogc.pth">HF link</a></td>
|
| 289 |
+
<td><a href="https://github.com/IDEA-Research/GroundingDINO/blob/main/groundingdino/config/GroundingDINO_SwinT_OGC.py">link</a></td>
|
| 290 |
+
</tr>
|
| 291 |
+
<tr>
|
| 292 |
+
<th>2</th>
|
| 293 |
+
<td>GroundingDINO-B</td>
|
| 294 |
+
<td>Swin-B</td>
|
| 295 |
+
<td>COCO,O365,GoldG,Cap4M,OpenImage,ODinW-35,RefCOCO</td>
|
| 296 |
+
<td>56.7 </td>
|
| 297 |
+
<td><a href="https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha2/groundingdino_swinb_cogcoor.pth">GitHub link</a> | <a href="https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/groundingdino_swinb_cogcoor.pth">HF link</a>
|
| 298 |
+
<td><a href="https://github.com/IDEA-Research/GroundingDINO/blob/main/groundingdino/config/GroundingDINO_SwinB.cfg.py">link</a></td>
|
| 299 |
+
</tr>
|
| 300 |
+
</tbody>
|
| 301 |
+
</table>
|
| 302 |
+
|
| 303 |
+
## :medal_military: Results
|
| 304 |
+
|
| 305 |
+
<details open>
|
| 306 |
+
<summary><font size="4">
|
| 307 |
+
COCO Object Detection Results
|
| 308 |
+
</font></summary>
|
| 309 |
+
<img src=".asset/COCO.png" alt="COCO" width="100%">
|
| 310 |
+
</details>
|
| 311 |
+
|
| 312 |
+
<details open>
|
| 313 |
+
<summary><font size="4">
|
| 314 |
+
ODinW Object Detection Results
|
| 315 |
+
</font></summary>
|
| 316 |
+
<img src=".asset/ODinW.png" alt="ODinW" width="100%">
|
| 317 |
+
</details>
|
| 318 |
+
|
| 319 |
+
<details open>
|
| 320 |
+
<summary><font size="4">
|
| 321 |
+
Marrying Grounding DINO with <a href="https://github.com/Stability-AI/StableDiffusion">Stable Diffusion</a> for Image Editing
|
| 322 |
+
</font></summary>
|
| 323 |
+
See our example <a href="https://github.com/IDEA-Research/GroundingDINO/blob/main/demo/image_editing_with_groundingdino_stablediffusion.ipynb">notebook</a> for more details.
|
| 324 |
+
<img src=".asset/GD_SD.png" alt="GD_SD" width="100%">
|
| 325 |
+
</details>
|
| 326 |
+
|
| 327 |
+
|
| 328 |
+
<details open>
|
| 329 |
+
<summary><font size="4">
|
| 330 |
+
Marrying Grounding DINO with <a href="https://github.com/gligen/GLIGEN">GLIGEN</a> for more Detailed Image Editing.
|
| 331 |
+
</font></summary>
|
| 332 |
+
See our example <a href="https://github.com/IDEA-Research/GroundingDINO/blob/main/demo/image_editing_with_groundingdino_gligen.ipynb">notebook</a> for more details.
|
| 333 |
+
<img src=".asset/GD_GLIGEN.png" alt="GD_GLIGEN" width="100%">
|
| 334 |
+
</details>
|
| 335 |
+
|
| 336 |
+
## :sauropod: Model: Grounding DINO
|
| 337 |
+
|
| 338 |
+
Includes: a text backbone, an image backbone, a feature enhancer, a language-guided query selection, and a cross-modality decoder.
|
| 339 |
+
|
| 340 |
+

|
| 341 |
+
|
| 342 |
+
|
| 343 |
+
## :hearts: Acknowledgement
|
| 344 |
+
|
| 345 |
+
Our model is related to [DINO](https://github.com/IDEA-Research/DINO) and [GLIP](https://github.com/microsoft/GLIP). Thanks for their great work!
|
| 346 |
+
|
| 347 |
+
We also thank great previous work including DETR, Deformable DETR, SMCA, Conditional DETR, Anchor DETR, Dynamic DETR, DAB-DETR, DN-DETR, etc. More related work are available at [Awesome Detection Transformer](https://github.com/IDEACVR/awesome-detection-transformer). A new toolbox [detrex](https://github.com/IDEA-Research/detrex) is available as well.
|
| 348 |
+
|
| 349 |
+
Thanks [Stable Diffusion](https://github.com/Stability-AI/StableDiffusion) and [GLIGEN](https://github.com/gligen/GLIGEN) for their awesome models.
|
| 350 |
+
|
| 351 |
+
|
| 352 |
+
## :black_nib: Citation
|
| 353 |
+
|
| 354 |
+
If you find our work helpful for your research, please consider citing the following BibTeX entry.
|
| 355 |
+
|
| 356 |
+
```bibtex
|
| 357 |
+
@article{liu2023grounding,
|
| 358 |
+
title={Grounding dino: Marrying dino with grounded pre-training for open-set object detection},
|
| 359 |
+
author={Liu, Shilong and Zeng, Zhaoyang and Ren, Tianhe and Li, Feng and Zhang, Hao and Yang, Jie and Li, Chunyuan and Yang, Jianwei and Su, Hang and Zhu, Jun and others},
|
| 360 |
+
journal={arXiv preprint arXiv:2303.05499},
|
| 361 |
+
year={2023}
|
| 362 |
+
}
|
| 363 |
+
```
|
| 364 |
+
|
| 365 |
+
|
| 366 |
+
|
| 367 |
+
|
approach/ovod/GroundingDINO/gdino.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from groundingdino.util.inference import load_model, load_image, predict, annotate
|
| 2 |
+
import cv2
|
| 3 |
+
|
| 4 |
+
model = load_model("./groundingdino/config/GroundingDINO_SwinT_OGC.py", "weights/groundingdino_swint_ogc.pth")
|
| 5 |
+
|
| 6 |
+
def peform_ovod(image_path, text_prompt, box_threshold, text_threshold):
|
| 7 |
+
image_path = "weights/dog.jpg"
|
| 8 |
+
text_prompt = "chair . person . dog ."
|
| 9 |
+
box_threshold = 0.35
|
| 10 |
+
text_threshold = 0.25
|
| 11 |
+
|
| 12 |
+
image_source, image = load_image(image_path)
|
| 13 |
+
|
| 14 |
+
boxes, logits, phrases = predict(
|
| 15 |
+
model=model,
|
| 16 |
+
image=image,
|
| 17 |
+
caption=text_prompt,
|
| 18 |
+
box_threshold=box_threshold,
|
| 19 |
+
text_threshold=text_threshold
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
annotated_frame = annotate(image_source=image_source, boxes=boxes, logits=logits, phrases=phrases)
|
| 23 |
+
cv2.imwrite("annotated_image.jpg", annotated_frame)
|
approach/ovod/GroundingDINO/requirements.txt
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
torch
|
| 2 |
+
torchvision
|
| 3 |
+
transformers
|
| 4 |
+
addict
|
| 5 |
+
yapf
|
| 6 |
+
timm
|
| 7 |
+
numpy
|
| 8 |
+
opencv-python
|
| 9 |
+
supervision==0.6.0
|
| 10 |
+
pycocotools
|
approach/ovod/GroundingDINO/setup.py
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2022 The IDEA Authors. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
# ------------------------------------------------------------------------------------------------
|
| 16 |
+
# Modified from
|
| 17 |
+
# https://github.com/fundamentalvision/Deformable-DETR/blob/main/models/ops/setup.py
|
| 18 |
+
# https://github.com/facebookresearch/detectron2/blob/main/setup.py
|
| 19 |
+
# https://github.com/open-mmlab/mmdetection/blob/master/setup.py
|
| 20 |
+
# https://github.com/Oneflow-Inc/libai/blob/main/setup.py
|
| 21 |
+
# ------------------------------------------------------------------------------------------------
|
| 22 |
+
|
| 23 |
+
import glob
|
| 24 |
+
import os
|
| 25 |
+
import subprocess
|
| 26 |
+
|
| 27 |
+
import torch
|
| 28 |
+
from setuptools import find_packages, setup
|
| 29 |
+
from torch.utils.cpp_extension import CUDA_HOME, CppExtension, CUDAExtension
|
| 30 |
+
|
| 31 |
+
# groundingdino version info
|
| 32 |
+
version = "0.1.0"
|
| 33 |
+
package_name = "groundingdino"
|
| 34 |
+
cwd = os.path.dirname(os.path.abspath(__file__))
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
sha = "Unknown"
|
| 38 |
+
try:
|
| 39 |
+
sha = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=cwd).decode("ascii").strip()
|
| 40 |
+
except Exception:
|
| 41 |
+
pass
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def write_version_file():
|
| 45 |
+
version_path = os.path.join(cwd, "groundingdino", "version.py")
|
| 46 |
+
with open(version_path, "w") as f:
|
| 47 |
+
f.write(f"__version__ = '{version}'\n")
|
| 48 |
+
# f.write(f"git_version = {repr(sha)}\n")
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
requirements = ["torch", "torchvision"]
|
| 52 |
+
|
| 53 |
+
torch_ver = [int(x) for x in torch.__version__.split(".")[:2]]
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def get_extensions():
|
| 57 |
+
this_dir = os.path.dirname(os.path.abspath(__file__))
|
| 58 |
+
extensions_dir = os.path.join(this_dir, "groundingdino", "models", "GroundingDINO", "csrc")
|
| 59 |
+
|
| 60 |
+
main_source = os.path.join(extensions_dir, "vision.cpp")
|
| 61 |
+
sources = glob.glob(os.path.join(extensions_dir, "**", "*.cpp"))
|
| 62 |
+
source_cuda = glob.glob(os.path.join(extensions_dir, "**", "*.cu")) + glob.glob(
|
| 63 |
+
os.path.join(extensions_dir, "*.cu")
|
| 64 |
+
)
|
| 65 |
+
|
| 66 |
+
sources = [main_source] + sources
|
| 67 |
+
|
| 68 |
+
extension = CppExtension
|
| 69 |
+
|
| 70 |
+
extra_compile_args = {"cxx": []}
|
| 71 |
+
define_macros = []
|
| 72 |
+
|
| 73 |
+
if CUDA_HOME is not None and (torch.cuda.is_available() or "TORCH_CUDA_ARCH_LIST" in os.environ):
|
| 74 |
+
print("Compiling with CUDA")
|
| 75 |
+
extension = CUDAExtension
|
| 76 |
+
sources += source_cuda
|
| 77 |
+
define_macros += [("WITH_CUDA", None)]
|
| 78 |
+
extra_compile_args["nvcc"] = [
|
| 79 |
+
"-DCUDA_HAS_FP16=1",
|
| 80 |
+
"-D__CUDA_NO_HALF_OPERATORS__",
|
| 81 |
+
"-D__CUDA_NO_HALF_CONVERSIONS__",
|
| 82 |
+
"-D__CUDA_NO_HALF2_OPERATORS__",
|
| 83 |
+
]
|
| 84 |
+
else:
|
| 85 |
+
print("Compiling without CUDA")
|
| 86 |
+
define_macros += [("WITH_HIP", None)]
|
| 87 |
+
extra_compile_args["nvcc"] = []
|
| 88 |
+
return None
|
| 89 |
+
|
| 90 |
+
sources = [os.path.join(extensions_dir, s) for s in sources]
|
| 91 |
+
include_dirs = [extensions_dir]
|
| 92 |
+
|
| 93 |
+
ext_modules = [
|
| 94 |
+
extension(
|
| 95 |
+
"groundingdino._C",
|
| 96 |
+
sources,
|
| 97 |
+
include_dirs=include_dirs,
|
| 98 |
+
define_macros=define_macros,
|
| 99 |
+
extra_compile_args=extra_compile_args,
|
| 100 |
+
)
|
| 101 |
+
]
|
| 102 |
+
|
| 103 |
+
return ext_modules
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
def parse_requirements(fname="requirements.txt", with_version=True):
|
| 107 |
+
"""Parse the package dependencies listed in a requirements file but strips
|
| 108 |
+
specific versioning information.
|
| 109 |
+
|
| 110 |
+
Args:
|
| 111 |
+
fname (str): path to requirements file
|
| 112 |
+
with_version (bool, default=False): if True include version specs
|
| 113 |
+
|
| 114 |
+
Returns:
|
| 115 |
+
List[str]: list of requirements items
|
| 116 |
+
|
| 117 |
+
CommandLine:
|
| 118 |
+
python -c "import setup; print(setup.parse_requirements())"
|
| 119 |
+
"""
|
| 120 |
+
import re
|
| 121 |
+
import sys
|
| 122 |
+
from os.path import exists
|
| 123 |
+
|
| 124 |
+
require_fpath = fname
|
| 125 |
+
|
| 126 |
+
def parse_line(line):
|
| 127 |
+
"""Parse information from a line in a requirements text file."""
|
| 128 |
+
if line.startswith("-r "):
|
| 129 |
+
# Allow specifying requirements in other files
|
| 130 |
+
target = line.split(" ")[1]
|
| 131 |
+
for info in parse_require_file(target):
|
| 132 |
+
yield info
|
| 133 |
+
else:
|
| 134 |
+
info = {"line": line}
|
| 135 |
+
if line.startswith("-e "):
|
| 136 |
+
info["package"] = line.split("#egg=")[1]
|
| 137 |
+
elif "@git+" in line:
|
| 138 |
+
info["package"] = line
|
| 139 |
+
else:
|
| 140 |
+
# Remove versioning from the package
|
| 141 |
+
pat = "(" + "|".join([">=", "==", ">"]) + ")"
|
| 142 |
+
parts = re.split(pat, line, maxsplit=1)
|
| 143 |
+
parts = [p.strip() for p in parts]
|
| 144 |
+
|
| 145 |
+
info["package"] = parts[0]
|
| 146 |
+
if len(parts) > 1:
|
| 147 |
+
op, rest = parts[1:]
|
| 148 |
+
if ";" in rest:
|
| 149 |
+
# Handle platform specific dependencies
|
| 150 |
+
# http://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-platform-specific-dependencies
|
| 151 |
+
version, platform_deps = map(str.strip, rest.split(";"))
|
| 152 |
+
info["platform_deps"] = platform_deps
|
| 153 |
+
else:
|
| 154 |
+
version = rest # NOQA
|
| 155 |
+
info["version"] = (op, version)
|
| 156 |
+
yield info
|
| 157 |
+
|
| 158 |
+
def parse_require_file(fpath):
|
| 159 |
+
with open(fpath, "r") as f:
|
| 160 |
+
for line in f.readlines():
|
| 161 |
+
line = line.strip()
|
| 162 |
+
if line and not line.startswith("#"):
|
| 163 |
+
for info in parse_line(line):
|
| 164 |
+
yield info
|
| 165 |
+
|
| 166 |
+
def gen_packages_items():
|
| 167 |
+
if exists(require_fpath):
|
| 168 |
+
for info in parse_require_file(require_fpath):
|
| 169 |
+
parts = [info["package"]]
|
| 170 |
+
if with_version and "version" in info:
|
| 171 |
+
parts.extend(info["version"])
|
| 172 |
+
if not sys.version.startswith("3.4"):
|
| 173 |
+
# apparently package_deps are broken in 3.4
|
| 174 |
+
platform_deps = info.get("platform_deps")
|
| 175 |
+
if platform_deps is not None:
|
| 176 |
+
parts.append(";" + platform_deps)
|
| 177 |
+
item = "".join(parts)
|
| 178 |
+
yield item
|
| 179 |
+
|
| 180 |
+
packages = list(gen_packages_items())
|
| 181 |
+
return packages
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
if __name__ == "__main__":
|
| 185 |
+
print(f"Building wheel {package_name}-{version}")
|
| 186 |
+
|
| 187 |
+
with open("LICENSE", "r", encoding="utf-8") as f:
|
| 188 |
+
license = f.read()
|
| 189 |
+
|
| 190 |
+
write_version_file()
|
| 191 |
+
|
| 192 |
+
setup(
|
| 193 |
+
name="groundingdino",
|
| 194 |
+
version="0.1.0",
|
| 195 |
+
author="International Digital Economy Academy, Shilong Liu",
|
| 196 |
+
url="https://github.com/IDEA-Research/GroundingDINO",
|
| 197 |
+
description="open-set object detector",
|
| 198 |
+
license=license,
|
| 199 |
+
install_requires=parse_requirements("requirements.txt"),
|
| 200 |
+
packages=find_packages(
|
| 201 |
+
exclude=(
|
| 202 |
+
"configs",
|
| 203 |
+
"tests",
|
| 204 |
+
)
|
| 205 |
+
),
|
| 206 |
+
ext_modules=get_extensions(),
|
| 207 |
+
cmdclass={"build_ext": torch.utils.cpp_extension.BuildExtension},
|
| 208 |
+
)
|
approach/ovod/GroundingDINO/test.ipynb
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": null,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [],
|
| 8 |
+
"source": [
|
| 9 |
+
"from groundingdino.util.inference import load_model, load_image, predict, annotate\n",
|
| 10 |
+
"import cv2\n",
|
| 11 |
+
"\n",
|
| 12 |
+
"model = load_model(\"groundingdino/config/GroundingDINO_SwinT_OGC.py\", \"../04-06-segment-anything/weights/groundingdino_swint_ogc.pth\")\n",
|
| 13 |
+
"IMAGE_PATH = \".asset/cat_dog.jpeg\"\n",
|
| 14 |
+
"TEXT_PROMPT = \"chair . person . dog .\"\n",
|
| 15 |
+
"BOX_TRESHOLD = 0.35\n",
|
| 16 |
+
"TEXT_TRESHOLD = 0.25\n",
|
| 17 |
+
"\n",
|
| 18 |
+
"image_source, image = load_image(IMAGE_PATH)\n",
|
| 19 |
+
"\n",
|
| 20 |
+
"boxes, logits, phrases = predict(\n",
|
| 21 |
+
" model=model,\n",
|
| 22 |
+
" image=image,\n",
|
| 23 |
+
" caption=TEXT_PROMPT,\n",
|
| 24 |
+
" box_threshold=BOX_TRESHOLD,\n",
|
| 25 |
+
" text_threshold=TEXT_TRESHOLD\n",
|
| 26 |
+
")\n",
|
| 27 |
+
"\n",
|
| 28 |
+
"annotated_frame = annotate(image_source=image_source, boxes=boxes, logits=logits, phrases=phrases)\n",
|
| 29 |
+
"cv2.imwrite(\"annotated_image.jpg\", annotated_frame)"
|
| 30 |
+
]
|
| 31 |
+
}
|
| 32 |
+
],
|
| 33 |
+
"metadata": {
|
| 34 |
+
"kernelspec": {
|
| 35 |
+
"display_name": "base",
|
| 36 |
+
"language": "python",
|
| 37 |
+
"name": "python3"
|
| 38 |
+
},
|
| 39 |
+
"language_info": {
|
| 40 |
+
"codemirror_mode": {
|
| 41 |
+
"name": "ipython",
|
| 42 |
+
"version": 3
|
| 43 |
+
},
|
| 44 |
+
"file_extension": ".py",
|
| 45 |
+
"mimetype": "text/x-python",
|
| 46 |
+
"name": "python",
|
| 47 |
+
"nbconvert_exporter": "python",
|
| 48 |
+
"pygments_lexer": "ipython3",
|
| 49 |
+
"version": "3.8.10"
|
| 50 |
+
},
|
| 51 |
+
"orig_nbformat": 4
|
| 52 |
+
},
|
| 53 |
+
"nbformat": 4,
|
| 54 |
+
"nbformat_minor": 2
|
| 55 |
+
}
|
approach/ovod/d-cube/.gitignore
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Byte-compiled / optimized / DLL files
|
| 2 |
+
__pycache__/
|
| 3 |
+
*.py[cod]
|
| 4 |
+
*$py.class
|
| 5 |
+
.vscode/*
|
| 6 |
+
|
| 7 |
+
# C extensions
|
| 8 |
+
*.so
|
| 9 |
+
|
| 10 |
+
# Distribution / packaging
|
| 11 |
+
.Python
|
| 12 |
+
build/
|
| 13 |
+
develop-eggs/
|
| 14 |
+
dist/
|
| 15 |
+
downloads/
|
| 16 |
+
eggs/
|
| 17 |
+
.eggs/
|
| 18 |
+
lib/
|
| 19 |
+
lib64/
|
| 20 |
+
parts/
|
| 21 |
+
sdist/
|
| 22 |
+
var/
|
| 23 |
+
wheels/
|
| 24 |
+
share/python-wheels/
|
| 25 |
+
*.egg-info/
|
| 26 |
+
.installed.cfg
|
| 27 |
+
*.egg
|
| 28 |
+
MANIFEST
|
| 29 |
+
|
| 30 |
+
# PyInstaller
|
| 31 |
+
# Usually these files are written by a python script from a template
|
| 32 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
| 33 |
+
*.manifest
|
| 34 |
+
*.spec
|
| 35 |
+
|
| 36 |
+
# Installer logs
|
| 37 |
+
pip-log.txt
|
| 38 |
+
pip-delete-this-directory.txt
|
| 39 |
+
|
| 40 |
+
# Unit test / coverage reports
|
| 41 |
+
htmlcov/
|
| 42 |
+
.tox/
|
| 43 |
+
.nox/
|
| 44 |
+
.coverage
|
| 45 |
+
.coverage.*
|
| 46 |
+
.cache
|
| 47 |
+
nosetests.xml
|
| 48 |
+
coverage.xml
|
| 49 |
+
*.cover
|
| 50 |
+
*.py,cover
|
| 51 |
+
.hypothesis/
|
| 52 |
+
.pytest_cache/
|
| 53 |
+
cover/
|
| 54 |
+
|
| 55 |
+
# Translations
|
| 56 |
+
*.mo
|
| 57 |
+
*.pot
|
| 58 |
+
|
| 59 |
+
# Django stuff:
|
| 60 |
+
*.log
|
| 61 |
+
local_settings.py
|
| 62 |
+
db.sqlite3
|
| 63 |
+
db.sqlite3-journal
|
| 64 |
+
|
| 65 |
+
# Flask stuff:
|
| 66 |
+
instance/
|
| 67 |
+
.webassets-cache
|
| 68 |
+
|
| 69 |
+
# Scrapy stuff:
|
| 70 |
+
.scrapy
|
| 71 |
+
|
| 72 |
+
# Sphinx documentation
|
| 73 |
+
docs/_build/
|
| 74 |
+
|
| 75 |
+
# PyBuilder
|
| 76 |
+
.pybuilder/
|
| 77 |
+
target/
|
| 78 |
+
|
| 79 |
+
# Jupyter Notebook
|
| 80 |
+
.ipynb_checkpoints
|
| 81 |
+
|
| 82 |
+
# IPython
|
| 83 |
+
profile_default/
|
| 84 |
+
ipython_config.py
|
| 85 |
+
|
| 86 |
+
# pyenv
|
| 87 |
+
# For a library or package, you might want to ignore these files since the code is
|
| 88 |
+
# intended to run in multiple environments; otherwise, check them in:
|
| 89 |
+
# .python-version
|
| 90 |
+
|
| 91 |
+
# pipenv
|
| 92 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
| 93 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
| 94 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
| 95 |
+
# install all needed dependencies.
|
| 96 |
+
#Pipfile.lock
|
| 97 |
+
|
| 98 |
+
# poetry
|
| 99 |
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
| 100 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
| 101 |
+
# commonly ignored for libraries.
|
| 102 |
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
| 103 |
+
#poetry.lock
|
| 104 |
+
|
| 105 |
+
# pdm
|
| 106 |
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
| 107 |
+
#pdm.lock
|
| 108 |
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
| 109 |
+
# in version control.
|
| 110 |
+
# https://pdm.fming.dev/#use-with-ide
|
| 111 |
+
.pdm.toml
|
| 112 |
+
|
| 113 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
| 114 |
+
__pypackages__/
|
| 115 |
+
|
| 116 |
+
# Celery stuff
|
| 117 |
+
celerybeat-schedule
|
| 118 |
+
celerybeat.pid
|
| 119 |
+
|
| 120 |
+
# SageMath parsed files
|
| 121 |
+
*.sage.py
|
| 122 |
+
|
| 123 |
+
# Environments
|
| 124 |
+
.env
|
| 125 |
+
.venv
|
| 126 |
+
env/
|
| 127 |
+
venv/
|
| 128 |
+
ENV/
|
| 129 |
+
env.bak/
|
| 130 |
+
venv.bak/
|
| 131 |
+
|
| 132 |
+
# Spyder project settings
|
| 133 |
+
.spyderproject
|
| 134 |
+
.spyproject
|
| 135 |
+
|
| 136 |
+
# Rope project settings
|
| 137 |
+
.ropeproject
|
| 138 |
+
|
| 139 |
+
# mkdocs documentation
|
| 140 |
+
/site
|
| 141 |
+
|
| 142 |
+
# mypy
|
| 143 |
+
.mypy_cache/
|
| 144 |
+
.dmypy.json
|
| 145 |
+
dmypy.json
|
| 146 |
+
|
| 147 |
+
# Pyre type checker
|
| 148 |
+
.pyre/
|
| 149 |
+
|
| 150 |
+
# pytype static type analyzer
|
| 151 |
+
.pytype/
|
| 152 |
+
|
| 153 |
+
# Cython debug symbols
|
| 154 |
+
cython_debug/
|
| 155 |
+
|
| 156 |
+
# PyCharm
|
| 157 |
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
| 158 |
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
| 159 |
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
| 160 |
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
| 161 |
+
#.idea/
|
| 162 |
+
|
| 163 |
+
# mac system
|
| 164 |
+
*.DS_Store
|
approach/ovod/d-cube/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!-- PROJECT LOGO -->
|
| 2 |
+
<br />
|
| 3 |
+
<p align="center">
|
| 4 |
+
<a href="#">
|
| 5 |
+
<img src=".assets/d-cube_logo.png" alt="Logo" width="310"></a>
|
| 6 |
+
<h4 align="center">A detection/segmentation dataset with class names characterized by intricate and flexible expressions</h4>
|
| 7 |
+
<p align="center">
|
| 8 |
+
The repo is the toolbox for <b>D<sup>3</sup></b>
|
| 9 |
+
<br />
|
| 10 |
+
<a href="doc.md"><strong> [Doc 📚]</strong></a>
|
| 11 |
+
<!-- <a href="https://huggingface.co/datasets/zbrl/d-cube"><strong> [HuggingFace 🤗]</strong></a> -->
|
| 12 |
+
<a href="https://arxiv.org/abs/2307.12813"><strong> [Paper (DOD) 📄] </strong></a>
|
| 13 |
+
<a href="https://arxiv.org/abs/2305.12452"><strong> [Paper (GRES) 📄] </strong></a>
|
| 14 |
+
<a href="https://github.com/Charles-Xie/awesome-described-object-detection"><strong> [Awesome-DOD 🕶️] </strong></a>
|
| 15 |
+
<br />
|
| 16 |
+
</p>
|
| 17 |
+
</p>
|
| 18 |
+
|
| 19 |
+
***
|
| 20 |
+
Description Detection Dataset ($D^3$, /dikju:b/) is an attempt at creating a next-generation object detection dataset. Unlike traditional detection datasets, the class names of the objects are no longer simple nouns or noun phrases, but rather complex and descriptive, such as `a dog not being held by a leash`. For each image in the dataset, any object that matches the description is annotated. The dataset provides annotations such as bounding boxes and finely crafted instance masks. We believe it will contribute to computer vision and vision-language communities.
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
# News
|
| 25 |
+
- [02/14/2024] Evaluation on several SOTA methods (SPHNX (the first MLLM evaluated!), G-DINO, UNINEXT, etc.) are released, together with a [leaderboard](https://github.com/shikras/d-cube/tree/main/eval_sota) for $D^3$. :fire::fire:
|
| 26 |
+
|
| 27 |
+
- [10/12/2023] We released an [awesome-described-object-detection](https://github.com/Charles-Xie/awesome-described-object-detection) list to collect and track related works.
|
| 28 |
+
|
| 29 |
+
- [09/22/2023] Our DOD [paper](https://arxiv.org/abs/2307.12813) just got accepted by NeurIPS 2023! :fire:
|
| 30 |
+
|
| 31 |
+
- [07/25/2023] This toolkit is available on PyPI now. You can install this repo with `pip install ddd-dataset`.
|
| 32 |
+
|
| 33 |
+
- [07/25/2023] The [paper preprint](https://arxiv.org/abs/2307.12813) introducing the DOD task and the $D^3$ dataset, is available on arxiv. Check it out!
|
| 34 |
+
|
| 35 |
+
- [07/18/2023] We have released our Description Detection Dataset ($D^3$) and the first version of $D^3$ toolbox. You can download it now for your project.
|
| 36 |
+
|
| 37 |
+
- [07/14/2023] Our GRES [paper](https://arxiv.org/abs/2305.12452) has been accepted by ICCV 2023.
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
# Contents
|
| 42 |
+
- [Dataset Highlight](#task-and-dataset-highlight)
|
| 43 |
+
- [Download](#download)
|
| 44 |
+
- [Installation](#installation)
|
| 45 |
+
- [Usage](#usage)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
# Task and Dataset Highlight
|
| 50 |
+
|
| 51 |
+
The $D^3$ dataset is meant for the Described Object Detection (DOD) task. In the image below we show the difference between Referring Expression Comprehension (REC), Object Detection/Open-Vocabulary Detection (OVD) and Described Object Detection (DOD). OVD detect object based on category name, and each category can have zero to multiple instances; REC grounds one region based on a language description, whether the object truly exits or not; DOD detect all instances on each image in the dataset, based on a flexible reference. Related works are tracked in the [awesome-DOD](https://github.com/Charles-Xie/awesome-described-object-detection) list.
|
| 52 |
+
|
| 53 |
+

|
| 54 |
+
|
| 55 |
+
For more information on the characteristics of this dataset, please refer to our paper.
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
# Download
|
| 60 |
+
Currently we host the $D^3$ dataset on cloud drives. You can download the dataset from [Google Drive](https://drive.google.com/drive/folders/11kfY12NzKPwsliLEcIYki1yUqt7PbMEi?usp=sharing) or [Baidu Pan]().
|
| 61 |
+
|
| 62 |
+
After downloading the `d3_images.zip` (images in the dataset), `d3_pkl.zip` (dataset information for this toolkit) and `d3_json.zip` (annotation for evaluation), please extract these 3 zip files to your custom `IMG_ROOT`, `PKL_PATH` and `JSON_ANNO_PATH` directory. These paths will be used when you perform inference or evaluation on this dataset.
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
# Installation
|
| 67 |
+
|
| 68 |
+
## Prerequisites
|
| 69 |
+
This toolkit requires a few python packages like `numpy` and `pycocotools`. Other packages like `matplotlib` and `opencv-python` may also be required if you want to utilize the visualization scripts.
|
| 70 |
+
|
| 71 |
+
<!-- There are three ways to install $D^3$ toolbox, and the third one (with huggingface) is currently in the works and will be available soon. -->
|
| 72 |
+
|
| 73 |
+
There are multiple ways to install $D^3$ toolbox, as listed below:
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
## Install with pip
|
| 77 |
+
```bash
|
| 78 |
+
pip install ddd-dataset
|
| 79 |
+
```
|
| 80 |
+
|
| 81 |
+
## Install from source
|
| 82 |
+
```bash
|
| 83 |
+
git clone https://github.com/shikra/d-cube.git
|
| 84 |
+
# option 1: install it as a python package
|
| 85 |
+
cd d-cube
|
| 86 |
+
python -m pip install .
|
| 87 |
+
# done
|
| 88 |
+
|
| 89 |
+
# option 2: just put the d-cube/d_cube directory in the root directory of your local repository
|
| 90 |
+
```
|
| 91 |
+
|
| 92 |
+
<!-- ## Via HuggingFace Datasets 🤗
|
| 93 |
+
```bash
|
| 94 |
+
coming soon
|
| 95 |
+
``` -->
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
# Usage
|
| 100 |
+
Please refer to the [documentation 📚](doc.md) for more details.
|
| 101 |
+
Our toolbox is similar to [cocoapi](https://github.com/cocodataset/cocoapi) in style.
|
| 102 |
+
|
| 103 |
+
Here is a quick example of how to use $D^3$.
|
| 104 |
+
```python
|
| 105 |
+
from d_cube import D3
|
| 106 |
+
d3 = D3(IMG_ROOT, PKL_ANNO_PATH)
|
| 107 |
+
all_img_ids = d3.get_img_ids() # get the image ids in the dataset
|
| 108 |
+
all_img_info = d3.load_imgs(all_img_ids) # load images by passing a list of some image ids
|
| 109 |
+
img_path = all_img_info[0]["file_name"] # obtain one image path so you can load it and inference
|
| 110 |
+
```
|
| 111 |
+
|
| 112 |
+
Some frequently asked questions are answered in [this Q&A file](./qa.md).
|
| 113 |
+
|
| 114 |
+
# Citation
|
| 115 |
+
|
| 116 |
+
If you use our $D^3$ dataset, this toolbox, or otherwise find our work valuable, please cite [our paper](https://arxiv.org/abs/2307.12813):
|
| 117 |
+
|
| 118 |
+
```bibtex
|
| 119 |
+
@inproceedings{xie2023DOD,
|
| 120 |
+
title={Described Object Detection: Liberating Object Detection with Flexible Expressions},
|
| 121 |
+
author={Xie, Chi and Zhang, Zhao and Wu, Yixuan and Zhu, Feng and Zhao, Rui and Liang, Shuang},
|
| 122 |
+
booktitle={Thirty-seventh Conference on Neural Information Processing Systems (NeurIPS)},
|
| 123 |
+
year={2023}
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
@inproceedings{wu2023gres,
|
| 127 |
+
title={Advancing Referring Expression Segmentation Beyond Single Image},
|
| 128 |
+
author={Wu, Yixuan and Zhang, Zhao and Xie, Chi and Zhu, Feng and Zhao, Rui},
|
| 129 |
+
booktitle={International Conference on Computer Vision (ICCV)},
|
| 130 |
+
year={2023}
|
| 131 |
+
}
|
| 132 |
+
```
|
| 133 |
+
|
| 134 |
+
More works related to Described Object Detection are tracked in this list: [awesome-described-object-detection](https://github.com/Charles-Xie/awesome-described-object-detection).
|
approach/ovod/d-cube/qa.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Frequently Asked Questions
|
| 2 |
+
|
| 3 |
+
Q:
|
| 4 |
+
What's the difference between Intra-Group and Inter-Group setting in [the DOD paper](https://arxiv.org/abs/2307.12813), and how to set them?
|
| 5 |
+
|
| 6 |
+
A:
|
| 7 |
+
Please see [this explanation in the document](./doc.md#intra--or-inter-group-settings).
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
Q:
|
| 12 |
+
What's the meaning of and difference between FULL, PRES, and ABS?
|
| 13 |
+
|
| 14 |
+
A:
|
| 15 |
+
Please see [this explanation in the document](./doc.md#full-pres-and-abs).
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
Q:
|
| 20 |
+
How do I perform a visualization of ground truth or prediction on a image?
|
| 21 |
+
|
| 22 |
+
A:
|
| 23 |
+
You can use `d3.get_anno_ids` function and pass the `img_id` you choose as parameter to get the annotation ids for a image.
|
| 24 |
+
After this, you can obtain the annotation details (class ids, bboxes) with `d3.load_annos`.
|
approach/ovod/d-cube/requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
numpy
|
| 2 |
+
pycocotools
|
| 3 |
+
opencv-python
|
| 4 |
+
matplotlib
|
approach/ovod/d-cube/setup.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import setuptools
|
| 2 |
+
|
| 3 |
+
setuptools.setup(
|
| 4 |
+
name='ddd-dataset',
|
| 5 |
+
version='0.1.1',
|
| 6 |
+
author='Chi Xie',
|
| 7 |
+
author_email='chixie.personal@gmail.com',
|
| 8 |
+
description='Toolkit for Description Detection Dataset ($D^3$)',
|
| 9 |
+
long_description='Toolkit for Description Detection Dataset ($D^3$): A detection dataset with class names characterized by intricate and flexible expressions, for the Described Object Detection (DOD) task.',
|
| 10 |
+
long_description_content_type='text/markdown',
|
| 11 |
+
license='CC BY-NC 4.0',
|
| 12 |
+
packages=['d_cube'],
|
| 13 |
+
package_dir={"d_cube": "d_cube"},
|
| 14 |
+
url='https://github.com/shikras/d-cube',
|
| 15 |
+
project_urls={
|
| 16 |
+
"Bug Tracker": "https://github.com/shikras/d-cube/issues",
|
| 17 |
+
},
|
| 18 |
+
install_requires=['numpy', 'pycocotools', 'opencv-python', 'matplotlib'],
|
| 19 |
+
|
| 20 |
+
classifiers=[
|
| 21 |
+
'Development Status :: 4 - Beta',
|
| 22 |
+
'Intended Audience :: Science/Research',
|
| 23 |
+
'Intended Audience :: Developers',
|
| 24 |
+
'Intended Audience :: Education',
|
| 25 |
+
'Operating System :: MacOS',
|
| 26 |
+
'Operating System :: Microsoft :: Windows',
|
| 27 |
+
'Operating System :: POSIX :: Linux',
|
| 28 |
+
'Programming Language :: Python :: 3',
|
| 29 |
+
],
|
| 30 |
+
)
|
approach/ovod/detectron2/.clang-format
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
AccessModifierOffset: -1
|
| 2 |
+
AlignAfterOpenBracket: AlwaysBreak
|
| 3 |
+
AlignConsecutiveAssignments: false
|
| 4 |
+
AlignConsecutiveDeclarations: false
|
| 5 |
+
AlignEscapedNewlinesLeft: true
|
| 6 |
+
AlignOperands: false
|
| 7 |
+
AlignTrailingComments: false
|
| 8 |
+
AllowAllParametersOfDeclarationOnNextLine: false
|
| 9 |
+
AllowShortBlocksOnASingleLine: false
|
| 10 |
+
AllowShortCaseLabelsOnASingleLine: false
|
| 11 |
+
AllowShortFunctionsOnASingleLine: Empty
|
| 12 |
+
AllowShortIfStatementsOnASingleLine: false
|
| 13 |
+
AllowShortLoopsOnASingleLine: false
|
| 14 |
+
AlwaysBreakAfterReturnType: None
|
| 15 |
+
AlwaysBreakBeforeMultilineStrings: true
|
| 16 |
+
AlwaysBreakTemplateDeclarations: true
|
| 17 |
+
BinPackArguments: false
|
| 18 |
+
BinPackParameters: false
|
| 19 |
+
BraceWrapping:
|
| 20 |
+
AfterClass: false
|
| 21 |
+
AfterControlStatement: false
|
| 22 |
+
AfterEnum: false
|
| 23 |
+
AfterFunction: false
|
| 24 |
+
AfterNamespace: false
|
| 25 |
+
AfterObjCDeclaration: false
|
| 26 |
+
AfterStruct: false
|
| 27 |
+
AfterUnion: false
|
| 28 |
+
BeforeCatch: false
|
| 29 |
+
BeforeElse: false
|
| 30 |
+
IndentBraces: false
|
| 31 |
+
BreakBeforeBinaryOperators: None
|
| 32 |
+
BreakBeforeBraces: Attach
|
| 33 |
+
BreakBeforeTernaryOperators: true
|
| 34 |
+
BreakConstructorInitializersBeforeComma: false
|
| 35 |
+
BreakAfterJavaFieldAnnotations: false
|
| 36 |
+
BreakStringLiterals: false
|
| 37 |
+
ColumnLimit: 80
|
| 38 |
+
CommentPragmas: '^ IWYU pragma:'
|
| 39 |
+
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
| 40 |
+
ConstructorInitializerIndentWidth: 4
|
| 41 |
+
ContinuationIndentWidth: 4
|
| 42 |
+
Cpp11BracedListStyle: true
|
| 43 |
+
DerivePointerAlignment: false
|
| 44 |
+
DisableFormat: false
|
| 45 |
+
ForEachMacros: [ FOR_EACH, FOR_EACH_R, FOR_EACH_RANGE, ]
|
| 46 |
+
IncludeCategories:
|
| 47 |
+
- Regex: '^<.*\.h(pp)?>'
|
| 48 |
+
Priority: 1
|
| 49 |
+
- Regex: '^<.*'
|
| 50 |
+
Priority: 2
|
| 51 |
+
- Regex: '.*'
|
| 52 |
+
Priority: 3
|
| 53 |
+
IndentCaseLabels: true
|
| 54 |
+
IndentWidth: 2
|
| 55 |
+
IndentWrappedFunctionNames: false
|
| 56 |
+
KeepEmptyLinesAtTheStartOfBlocks: false
|
| 57 |
+
MacroBlockBegin: ''
|
| 58 |
+
MacroBlockEnd: ''
|
| 59 |
+
MaxEmptyLinesToKeep: 1
|
| 60 |
+
NamespaceIndentation: None
|
| 61 |
+
ObjCBlockIndentWidth: 2
|
| 62 |
+
ObjCSpaceAfterProperty: false
|
| 63 |
+
ObjCSpaceBeforeProtocolList: false
|
| 64 |
+
PenaltyBreakBeforeFirstCallParameter: 1
|
| 65 |
+
PenaltyBreakComment: 300
|
| 66 |
+
PenaltyBreakFirstLessLess: 120
|
| 67 |
+
PenaltyBreakString: 1000
|
| 68 |
+
PenaltyExcessCharacter: 1000000
|
| 69 |
+
PenaltyReturnTypeOnItsOwnLine: 200
|
| 70 |
+
PointerAlignment: Left
|
| 71 |
+
ReflowComments: true
|
| 72 |
+
SortIncludes: true
|
| 73 |
+
SpaceAfterCStyleCast: false
|
| 74 |
+
SpaceBeforeAssignmentOperators: true
|
| 75 |
+
SpaceBeforeParens: ControlStatements
|
| 76 |
+
SpaceInEmptyParentheses: false
|
| 77 |
+
SpacesBeforeTrailingComments: 1
|
| 78 |
+
SpacesInAngles: false
|
| 79 |
+
SpacesInContainerLiterals: true
|
| 80 |
+
SpacesInCStyleCastParentheses: false
|
| 81 |
+
SpacesInParentheses: false
|
| 82 |
+
SpacesInSquareBrackets: false
|
| 83 |
+
Standard: Cpp11
|
| 84 |
+
TabWidth: 8
|
| 85 |
+
UseTab: Never
|
approach/ovod/detectron2/.flake8
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This is an example .flake8 config, used when developing *Black* itself.
|
| 2 |
+
# Keep in sync with setup.cfg which is used for source packages.
|
| 3 |
+
|
| 4 |
+
[flake8]
|
| 5 |
+
ignore = W503, E203, E221, C901, C408, E741, C407, B017, F811, C101, EXE001, EXE002
|
| 6 |
+
max-line-length = 100
|
| 7 |
+
max-complexity = 18
|
| 8 |
+
select = B,C,E,F,W,T4,B9
|
| 9 |
+
exclude = build
|
| 10 |
+
per-file-ignores =
|
| 11 |
+
**/__init__.py:F401,F403,E402
|
| 12 |
+
**/configs/**.py:F401,E402
|
| 13 |
+
configs/**.py:F401,E402
|
| 14 |
+
**/tests/config/**.py:F401,E402
|
| 15 |
+
tests/config/**.py:F401,E402
|
approach/ovod/detectron2/.gitignore
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# output dir
|
| 2 |
+
output
|
| 3 |
+
instant_test_output
|
| 4 |
+
inference_test_output
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
*.png
|
| 8 |
+
*.json
|
| 9 |
+
*.diff
|
| 10 |
+
*.jpg
|
| 11 |
+
!/projects/DensePose/doc/images/*.jpg
|
| 12 |
+
|
| 13 |
+
# compilation and distribution
|
| 14 |
+
__pycache__
|
| 15 |
+
_ext
|
| 16 |
+
*.pyc
|
| 17 |
+
*.pyd
|
| 18 |
+
*.so
|
| 19 |
+
*.dll
|
| 20 |
+
*.egg-info/
|
| 21 |
+
build/
|
| 22 |
+
dist/
|
| 23 |
+
wheels/
|
| 24 |
+
|
| 25 |
+
# pytorch/python/numpy formats
|
| 26 |
+
*.pth
|
| 27 |
+
*.pkl
|
| 28 |
+
*.npy
|
| 29 |
+
*.ts
|
| 30 |
+
model_ts*.txt
|
| 31 |
+
|
| 32 |
+
# ipython/jupyter notebooks
|
| 33 |
+
*.ipynb
|
| 34 |
+
**/.ipynb_checkpoints/
|
| 35 |
+
|
| 36 |
+
# Editor temporaries
|
| 37 |
+
*.swn
|
| 38 |
+
*.swo
|
| 39 |
+
*.swp
|
| 40 |
+
*~
|
| 41 |
+
|
| 42 |
+
# editor settings
|
| 43 |
+
.idea
|
| 44 |
+
.vscode
|
| 45 |
+
_darcs
|
| 46 |
+
|
| 47 |
+
# project dirs
|
| 48 |
+
/detectron2/model_zoo/configs
|
| 49 |
+
/datasets/*
|
| 50 |
+
!/datasets/*.*
|
| 51 |
+
/projects/*/datasets
|
| 52 |
+
/models
|
| 53 |
+
/snippet
|
approach/ovod/detectron2/GETTING_STARTED.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## Getting Started with Detectron2
|
| 2 |
+
|
| 3 |
+
This document provides a brief intro of the usage of builtin command-line tools in detectron2.
|
| 4 |
+
|
| 5 |
+
For a tutorial that involves actual coding with the API,
|
| 6 |
+
see our [Colab Notebook](https://colab.research.google.com/drive/16jcaJoc6bCFAQ96jDe2HwtXj7BMD_-m5)
|
| 7 |
+
which covers how to run inference with an
|
| 8 |
+
existing model, and how to train a builtin model on a custom dataset.
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
### Inference Demo with Pre-trained Models
|
| 12 |
+
|
| 13 |
+
1. Pick a model and its config file from
|
| 14 |
+
[model zoo](MODEL_ZOO.md),
|
| 15 |
+
for example, `mask_rcnn_R_50_FPN_3x.yaml`.
|
| 16 |
+
2. We provide `demo.py` that is able to demo builtin configs. Run it with:
|
| 17 |
+
```
|
| 18 |
+
cd demo/
|
| 19 |
+
python demo.py --config-file ../configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml \
|
| 20 |
+
--input input1.jpg input2.jpg \
|
| 21 |
+
[--other-options]
|
| 22 |
+
--opts MODEL.WEIGHTS detectron2://COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x/137849600/model_final_f10217.pkl
|
| 23 |
+
```
|
| 24 |
+
The configs are made for training, therefore we need to specify `MODEL.WEIGHTS` to a model from model zoo for evaluation.
|
| 25 |
+
This command will run the inference and show visualizations in an OpenCV window.
|
| 26 |
+
|
| 27 |
+
For details of the command line arguments, see `demo.py -h` or look at its source code
|
| 28 |
+
to understand its behavior. Some common arguments are:
|
| 29 |
+
* To run __on your webcam__, replace `--input files` with `--webcam`.
|
| 30 |
+
* To run __on a video__, replace `--input files` with `--video-input video.mp4`.
|
| 31 |
+
* To run __on cpu__, add `MODEL.DEVICE cpu` after `--opts`.
|
| 32 |
+
* To save outputs to a directory (for images) or a file (for webcam or video), use `--output`.
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
### Training & Evaluation in Command Line
|
| 36 |
+
|
| 37 |
+
We provide two scripts in "tools/plain_train_net.py" and "tools/train_net.py",
|
| 38 |
+
that are made to train all the configs provided in detectron2. You may want to
|
| 39 |
+
use it as a reference to write your own training script.
|
| 40 |
+
|
| 41 |
+
Compared to "train_net.py", "plain_train_net.py" supports fewer default
|
| 42 |
+
features. It also includes fewer abstraction, therefore is easier to add custom
|
| 43 |
+
logic.
|
| 44 |
+
|
| 45 |
+
To train a model with "train_net.py", first
|
| 46 |
+
setup the corresponding datasets following
|
| 47 |
+
[datasets/README.md](./datasets/README.md),
|
| 48 |
+
then run:
|
| 49 |
+
```
|
| 50 |
+
cd tools/
|
| 51 |
+
./train_net.py --num-gpus 8 \
|
| 52 |
+
--config-file ../configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml
|
| 53 |
+
```
|
| 54 |
+
|
| 55 |
+
The configs are made for 8-GPU training.
|
| 56 |
+
To train on 1 GPU, you may need to [change some parameters](https://arxiv.org/abs/1706.02677), e.g.:
|
| 57 |
+
```
|
| 58 |
+
./train_net.py \
|
| 59 |
+
--config-file ../configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml \
|
| 60 |
+
--num-gpus 1 SOLVER.IMS_PER_BATCH 2 SOLVER.BASE_LR 0.0025
|
| 61 |
+
```
|
| 62 |
+
|
| 63 |
+
To evaluate a model's performance, use
|
| 64 |
+
```
|
| 65 |
+
./train_net.py \
|
| 66 |
+
--config-file ../configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml \
|
| 67 |
+
--eval-only MODEL.WEIGHTS /path/to/checkpoint_file
|
| 68 |
+
```
|
| 69 |
+
For more options, see `./train_net.py -h`.
|
| 70 |
+
|
| 71 |
+
### Use Detectron2 APIs in Your Code
|
| 72 |
+
|
| 73 |
+
See our [Colab Notebook](https://colab.research.google.com/drive/16jcaJoc6bCFAQ96jDe2HwtXj7BMD_-m5)
|
| 74 |
+
to learn how to use detectron2 APIs to:
|
| 75 |
+
1. run inference with an existing model
|
| 76 |
+
2. train a builtin model on a custom dataset
|
| 77 |
+
|
| 78 |
+
See [detectron2/projects](https://github.com/facebookresearch/detectron2/tree/main/projects)
|
| 79 |
+
for more ways to build your project on detectron2.
|
approach/ovod/detectron2/INSTALL.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
## Installation
|
| 2 |
+
|
| 3 |
+
### Requirements
|
| 4 |
+
- Linux or macOS with Python ≥ 3.7
|
| 5 |
+
- PyTorch ≥ 1.8 and [torchvision](https://github.com/pytorch/vision/) that matches the PyTorch installation.
|
| 6 |
+
Install them together at [pytorch.org](https://pytorch.org) to make sure of this
|
| 7 |
+
- OpenCV is optional but needed by demo and visualization
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
### Build Detectron2 from Source
|
| 11 |
+
|
| 12 |
+
gcc & g++ ≥ 5.4 are required. [ninja](https://ninja-build.org/) is optional but recommended for faster build.
|
| 13 |
+
After having them, run:
|
| 14 |
+
```
|
| 15 |
+
python -m pip install 'git+https://github.com/facebookresearch/detectron2.git'
|
| 16 |
+
# (add --user if you don't have permission)
|
| 17 |
+
|
| 18 |
+
# Or, to install it from a local clone:
|
| 19 |
+
git clone https://github.com/facebookresearch/detectron2.git
|
| 20 |
+
python -m pip install -e detectron2
|
| 21 |
+
|
| 22 |
+
# On macOS, you may need to prepend the above commands with a few environment variables:
|
| 23 |
+
CC=clang CXX=clang++ ARCHFLAGS="-arch x86_64" python -m pip install ...
|
| 24 |
+
```
|
| 25 |
+
|
| 26 |
+
To __rebuild__ detectron2 that's built from a local clone, use `rm -rf build/ **/*.so` to clean the
|
| 27 |
+
old build first. You often need to rebuild detectron2 after reinstalling PyTorch.
|
| 28 |
+
|
| 29 |
+
### Install Pre-Built Detectron2 (Linux only)
|
| 30 |
+
|
| 31 |
+
Choose from this table to install [v0.6 (Oct 2021)](https://github.com/facebookresearch/detectron2/releases):
|
| 32 |
+
|
| 33 |
+
<table class="docutils"><tbody><th width="80"> CUDA </th><th valign="bottom" align="left" width="100">torch 1.10</th><th valign="bottom" align="left" width="100">torch 1.9</th><th valign="bottom" align="left" width="100">torch 1.8</th> <tr><td align="left">11.3</td><td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 34 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cu113/torch1.10/index.html
|
| 35 |
+
</code></pre> </details> </td> <td align="left"> </td> <td align="left"> </td> </tr> <tr><td align="left">11.1</td><td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 36 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cu111/torch1.10/index.html
|
| 37 |
+
</code></pre> </details> </td> <td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 38 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cu111/torch1.9/index.html
|
| 39 |
+
</code></pre> </details> </td> <td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 40 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cu111/torch1.8/index.html
|
| 41 |
+
</code></pre> </details> </td> </tr> <tr><td align="left">10.2</td><td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 42 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cu102/torch1.10/index.html
|
| 43 |
+
</code></pre> </details> </td> <td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 44 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cu102/torch1.9/index.html
|
| 45 |
+
</code></pre> </details> </td> <td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 46 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cu102/torch1.8/index.html
|
| 47 |
+
</code></pre> </details> </td> </tr> <tr><td align="left">10.1</td><td align="left"> </td> <td align="left"> </td> <td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 48 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cu101/torch1.8/index.html
|
| 49 |
+
</code></pre> </details> </td> </tr> <tr><td align="left">cpu</td><td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 50 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cpu/torch1.10/index.html
|
| 51 |
+
</code></pre> </details> </td> <td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 52 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cpu/torch1.9/index.html
|
| 53 |
+
</code></pre> </details> </td> <td align="left"><details><summary> install </summary><pre><code>python -m pip install detectron2 -f \
|
| 54 |
+
https://dl.fbaipublicfiles.com/detectron2/wheels/cpu/torch1.8/index.html
|
| 55 |
+
</code></pre> </details> </td> </tr></tbody></table>
|
| 56 |
+
|
| 57 |
+
Note that:
|
| 58 |
+
1. The pre-built packages have to be used with corresponding version of CUDA and the official package of PyTorch.
|
| 59 |
+
Otherwise, please build detectron2 from source.
|
| 60 |
+
2. New packages are released every few months. Therefore, packages may not contain latest features in the main
|
| 61 |
+
branch and may not be compatible with the main branch of a research project that uses detectron2
|
| 62 |
+
(e.g. those in [projects](projects)).
|
| 63 |
+
|
| 64 |
+
### Common Installation Issues
|
| 65 |
+
|
| 66 |
+
Click each issue for its solutions:
|
| 67 |
+
|
| 68 |
+
<details>
|
| 69 |
+
<summary>
|
| 70 |
+
Undefined symbols that looks like "TH..","at::Tensor...","torch..."
|
| 71 |
+
</summary>
|
| 72 |
+
<br/>
|
| 73 |
+
|
| 74 |
+
This usually happens when detectron2 or torchvision is not
|
| 75 |
+
compiled with the version of PyTorch you're running.
|
| 76 |
+
|
| 77 |
+
If the error comes from a pre-built torchvision, uninstall torchvision and pytorch and reinstall them
|
| 78 |
+
following [pytorch.org](http://pytorch.org). So the versions will match.
|
| 79 |
+
|
| 80 |
+
If the error comes from a pre-built detectron2, check [release notes](https://github.com/facebookresearch/detectron2/releases),
|
| 81 |
+
uninstall and reinstall the correct pre-built detectron2 that matches pytorch version.
|
| 82 |
+
|
| 83 |
+
If the error comes from detectron2 or torchvision that you built manually from source,
|
| 84 |
+
remove files you built (`build/`, `**/*.so`) and rebuild it so it can pick up the version of pytorch currently in your environment.
|
| 85 |
+
|
| 86 |
+
If the above instructions do not resolve this problem, please provide an environment (e.g. a dockerfile) that can reproduce the issue.
|
| 87 |
+
</details>
|
| 88 |
+
|
| 89 |
+
<details>
|
| 90 |
+
<summary>
|
| 91 |
+
Missing torch dynamic libraries, OR segmentation fault immediately when using detectron2.
|
| 92 |
+
</summary>
|
| 93 |
+
This usually happens when detectron2 or torchvision is not
|
| 94 |
+
compiled with the version of PyTorch you're running. See the previous common issue for the solution.
|
| 95 |
+
</details>
|
| 96 |
+
|
| 97 |
+
<details>
|
| 98 |
+
<summary>
|
| 99 |
+
Undefined C++ symbols (e.g. "GLIBCXX..") or C++ symbols not found.
|
| 100 |
+
</summary>
|
| 101 |
+
<br/>
|
| 102 |
+
Usually it's because the library is compiled with a newer C++ compiler but run with an old C++ runtime.
|
| 103 |
+
|
| 104 |
+
This often happens with old anaconda.
|
| 105 |
+
It may help to run `conda update libgcc` to upgrade its runtime.
|
| 106 |
+
|
| 107 |
+
The fundamental solution is to avoid the mismatch, either by compiling using older version of C++
|
| 108 |
+
compiler, or run the code with proper C++ runtime.
|
| 109 |
+
To run the code with a specific C++ runtime, you can use environment variable `LD_PRELOAD=/path/to/libstdc++.so`.
|
| 110 |
+
|
| 111 |
+
</details>
|
| 112 |
+
|
| 113 |
+
<details>
|
| 114 |
+
<summary>
|
| 115 |
+
"nvcc not found" or "Not compiled with GPU support" or "Detectron2 CUDA Compiler: not available".
|
| 116 |
+
</summary>
|
| 117 |
+
<br/>
|
| 118 |
+
CUDA is not found when building detectron2.
|
| 119 |
+
You should make sure
|
| 120 |
+
|
| 121 |
+
```
|
| 122 |
+
python -c 'import torch; from torch.utils.cpp_extension import CUDA_HOME; print(torch.cuda.is_available(), CUDA_HOME)'
|
| 123 |
+
```
|
| 124 |
+
|
| 125 |
+
print `(True, a directory with cuda)` at the time you build detectron2.
|
| 126 |
+
|
| 127 |
+
Most models can run inference (but not training) without GPU support. To use CPUs, set `MODEL.DEVICE='cpu'` in the config.
|
| 128 |
+
</details>
|
| 129 |
+
|
| 130 |
+
<details>
|
| 131 |
+
<summary>
|
| 132 |
+
"invalid device function" or "no kernel image is available for execution".
|
| 133 |
+
</summary>
|
| 134 |
+
<br/>
|
| 135 |
+
Two possibilities:
|
| 136 |
+
|
| 137 |
+
* You build detectron2 with one version of CUDA but run it with a different version.
|
| 138 |
+
|
| 139 |
+
To check whether it is the case,
|
| 140 |
+
use `python -m detectron2.utils.collect_env` to find out inconsistent CUDA versions.
|
| 141 |
+
In the output of this command, you should expect "Detectron2 CUDA Compiler", "CUDA_HOME", "PyTorch built with - CUDA"
|
| 142 |
+
to contain cuda libraries of the same version.
|
| 143 |
+
|
| 144 |
+
When they are inconsistent,
|
| 145 |
+
you need to either install a different build of PyTorch (or build by yourself)
|
| 146 |
+
to match your local CUDA installation, or install a different version of CUDA to match PyTorch.
|
| 147 |
+
|
| 148 |
+
* PyTorch/torchvision/Detectron2 is not built for the correct GPU SM architecture (aka. compute capability).
|
| 149 |
+
|
| 150 |
+
The architecture included by PyTorch/detectron2/torchvision is available in the "architecture flags" in
|
| 151 |
+
`python -m detectron2.utils.collect_env`. It must include
|
| 152 |
+
the architecture of your GPU, which can be found at [developer.nvidia.com/cuda-gpus](https://developer.nvidia.com/cuda-gpus).
|
| 153 |
+
|
| 154 |
+
If you're using pre-built PyTorch/detectron2/torchvision, they have included support for most popular GPUs already.
|
| 155 |
+
If not supported, you need to build them from source.
|
| 156 |
+
|
| 157 |
+
When building detectron2/torchvision from source, they detect the GPU device and build for only the device.
|
| 158 |
+
This means the compiled code may not work on a different GPU device.
|
| 159 |
+
To recompile them for the correct architecture, remove all installed/compiled files,
|
| 160 |
+
and rebuild them with the `TORCH_CUDA_ARCH_LIST` environment variable set properly.
|
| 161 |
+
For example, `export TORCH_CUDA_ARCH_LIST="6.0;7.0"` makes it compile for both P100s and V100s.
|
| 162 |
+
</details>
|
| 163 |
+
|
| 164 |
+
<details>
|
| 165 |
+
<summary>
|
| 166 |
+
Undefined CUDA symbols; Cannot open libcudart.so
|
| 167 |
+
</summary>
|
| 168 |
+
<br/>
|
| 169 |
+
The version of NVCC you use to build detectron2 or torchvision does
|
| 170 |
+
not match the version of CUDA you are running with.
|
| 171 |
+
This often happens when using anaconda's CUDA runtime.
|
| 172 |
+
|
| 173 |
+
Use `python -m detectron2.utils.collect_env` to find out inconsistent CUDA versions.
|
| 174 |
+
In the output of this command, you should expect "Detectron2 CUDA Compiler", "CUDA_HOME", "PyTorch built with - CUDA"
|
| 175 |
+
to contain cuda libraries of the same version.
|
| 176 |
+
|
| 177 |
+
When they are inconsistent,
|
| 178 |
+
you need to either install a different build of PyTorch (or build by yourself)
|
| 179 |
+
to match your local CUDA installation, or install a different version of CUDA to match PyTorch.
|
| 180 |
+
</details>
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
<details>
|
| 184 |
+
<summary>
|
| 185 |
+
C++ compilation errors from NVCC / NVRTC, or "Unsupported gpu architecture"
|
| 186 |
+
</summary>
|
| 187 |
+
<br/>
|
| 188 |
+
A few possibilities:
|
| 189 |
+
|
| 190 |
+
1. Local CUDA/NVCC version has to match the CUDA version of your PyTorch. Both can be found in `python collect_env.py`
|
| 191 |
+
(download from [here](./detectron2/utils/collect_env.py)).
|
| 192 |
+
When they are inconsistent, you need to either install a different build of PyTorch (or build by yourself)
|
| 193 |
+
to match your local CUDA installation, or install a different version of CUDA to match PyTorch.
|
| 194 |
+
|
| 195 |
+
2. Local CUDA/NVCC version shall support the SM architecture (a.k.a. compute capability) of your GPU.
|
| 196 |
+
The capability of your GPU can be found at [developer.nvidia.com/cuda-gpus](https://developer.nvidia.com/cuda-gpus).
|
| 197 |
+
The capability supported by NVCC is listed at [here](https://gist.github.com/ax3l/9489132).
|
| 198 |
+
If your NVCC version is too old, this can be workaround by setting environment variable
|
| 199 |
+
`TORCH_CUDA_ARCH_LIST` to a lower, supported capability.
|
| 200 |
+
|
| 201 |
+
3. The combination of NVCC and GCC you use is incompatible. You need to change one of their versions.
|
| 202 |
+
See [here](https://gist.github.com/ax3l/9489132) for some valid combinations.
|
| 203 |
+
Notably, CUDA<=10.1.105 doesn't support GCC>7.3.
|
| 204 |
+
|
| 205 |
+
The CUDA/GCC version used by PyTorch can be found by `print(torch.__config__.show())`.
|
| 206 |
+
|
| 207 |
+
</details>
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
<details>
|
| 211 |
+
<summary>
|
| 212 |
+
"ImportError: cannot import name '_C'".
|
| 213 |
+
</summary>
|
| 214 |
+
<br/>
|
| 215 |
+
Please build and install detectron2 following the instructions above.
|
| 216 |
+
|
| 217 |
+
Or, if you are running code from detectron2's root directory, `cd` to a different one.
|
| 218 |
+
Otherwise you may not import the code that you installed.
|
| 219 |
+
</details>
|
| 220 |
+
|
| 221 |
+
|
| 222 |
+
<details>
|
| 223 |
+
<summary>
|
| 224 |
+
Any issue on windows.
|
| 225 |
+
</summary>
|
| 226 |
+
<br/>
|
| 227 |
+
|
| 228 |
+
Detectron2 is continuously built on windows with [CircleCI](https://app.circleci.com/pipelines/github/facebookresearch/detectron2?branch=main).
|
| 229 |
+
However we do not provide official support for it.
|
| 230 |
+
PRs that improves code compatibility on windows are welcome.
|
| 231 |
+
</details>
|
| 232 |
+
|
| 233 |
+
<details>
|
| 234 |
+
<summary>
|
| 235 |
+
ONNX conversion segfault after some "TraceWarning".
|
| 236 |
+
</summary>
|
| 237 |
+
<br/>
|
| 238 |
+
The ONNX package is compiled with a too old compiler.
|
| 239 |
+
|
| 240 |
+
Please build and install ONNX from its source code using a compiler
|
| 241 |
+
whose version is closer to what's used by PyTorch (available in `torch.__config__.show()`).
|
| 242 |
+
</details>
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
<details>
|
| 246 |
+
<summary>
|
| 247 |
+
"library not found for -lstdc++" on older version of MacOS
|
| 248 |
+
</summary>
|
| 249 |
+
<br/>
|
| 250 |
+
|
| 251 |
+
See [this stackoverflow answer](https://stackoverflow.com/questions/56083725/macos-build-issues-lstdc-not-found-while-building-python-package).
|
| 252 |
+
|
| 253 |
+
</details>
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
### Installation inside specific environments:
|
| 257 |
+
|
| 258 |
+
* __Colab__: see our [Colab Tutorial](https://colab.research.google.com/drive/16jcaJoc6bCFAQ96jDe2HwtXj7BMD_-m5)
|
| 259 |
+
which has step-by-step instructions.
|
| 260 |
+
|
| 261 |
+
* __Docker__: The official [Dockerfile](docker) installs detectron2 with a few simple commands.
|
approach/ovod/detectron2/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Apache License
|
| 2 |
+
Version 2.0, January 2004
|
| 3 |
+
http://www.apache.org/licenses/
|
| 4 |
+
|
| 5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 6 |
+
|
| 7 |
+
1. Definitions.
|
| 8 |
+
|
| 9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 11 |
+
|
| 12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 13 |
+
the copyright owner that is granting the License.
|
| 14 |
+
|
| 15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 16 |
+
other entities that control, are controlled by, or are under common
|
| 17 |
+
control with that entity. For the purposes of this definition,
|
| 18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 19 |
+
direction or management of such entity, whether by contract or
|
| 20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 22 |
+
|
| 23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 24 |
+
exercising permissions granted by this License.
|
| 25 |
+
|
| 26 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 27 |
+
including but not limited to software source code, documentation
|
| 28 |
+
source, and configuration files.
|
| 29 |
+
|
| 30 |
+
"Object" form shall mean any form resulting from mechanical
|
| 31 |
+
transformation or translation of a Source form, including but
|
| 32 |
+
not limited to compiled object code, generated documentation,
|
| 33 |
+
and conversions to other media types.
|
| 34 |
+
|
| 35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 36 |
+
Object form, made available under the License, as indicated by a
|
| 37 |
+
copyright notice that is included in or attached to the work
|
| 38 |
+
(an example is provided in the Appendix below).
|
| 39 |
+
|
| 40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 41 |
+
form, that is based on (or derived from) the Work and for which the
|
| 42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 44 |
+
of this License, Derivative Works shall not include works that remain
|
| 45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 46 |
+
the Work and Derivative Works thereof.
|
| 47 |
+
|
| 48 |
+
"Contribution" shall mean any work of authorship, including
|
| 49 |
+
the original version of the Work and any modifications or additions
|
| 50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 54 |
+
means any form of electronic, verbal, or written communication sent
|
| 55 |
+
to the Licensor or its representatives, including but not limited to
|
| 56 |
+
communication on electronic mailing lists, source code control systems,
|
| 57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 59 |
+
excluding communication that is conspicuously marked or otherwise
|
| 60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 61 |
+
|
| 62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
| 64 |
+
subsequently incorporated within the Work.
|
| 65 |
+
|
| 66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 71 |
+
Work and such Derivative Works in Source or Object form.
|
| 72 |
+
|
| 73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 76 |
+
(except as stated in this section) patent license to make, have made,
|
| 77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 78 |
+
where such license applies only to those patent claims licensable
|
| 79 |
+
by such Contributor that are necessarily infringed by their
|
| 80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 82 |
+
institute patent litigation against any entity (including a
|
| 83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 84 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 85 |
+
or contributory patent infringement, then any patent licenses
|
| 86 |
+
granted to You under this License for that Work shall terminate
|
| 87 |
+
as of the date such litigation is filed.
|
| 88 |
+
|
| 89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 90 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 91 |
+
modifications, and in Source or Object form, provided that You
|
| 92 |
+
meet the following conditions:
|
| 93 |
+
|
| 94 |
+
(a) You must give any other recipients of the Work or
|
| 95 |
+
Derivative Works a copy of this License; and
|
| 96 |
+
|
| 97 |
+
(b) You must cause any modified files to carry prominent notices
|
| 98 |
+
stating that You changed the files; and
|
| 99 |
+
|
| 100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 101 |
+
that You distribute, all copyright, patent, trademark, and
|
| 102 |
+
attribution notices from the Source form of the Work,
|
| 103 |
+
excluding those notices that do not pertain to any part of
|
| 104 |
+
the Derivative Works; and
|
| 105 |
+
|
| 106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 107 |
+
distribution, then any Derivative Works that You distribute must
|
| 108 |
+
include a readable copy of the attribution notices contained
|
| 109 |
+
within such NOTICE file, excluding those notices that do not
|
| 110 |
+
pertain to any part of the Derivative Works, in at least one
|
| 111 |
+
of the following places: within a NOTICE text file distributed
|
| 112 |
+
as part of the Derivative Works; within the Source form or
|
| 113 |
+
documentation, if provided along with the Derivative Works; or,
|
| 114 |
+
within a display generated by the Derivative Works, if and
|
| 115 |
+
wherever such third-party notices normally appear. The contents
|
| 116 |
+
of the NOTICE file are for informational purposes only and
|
| 117 |
+
do not modify the License. You may add Your own attribution
|
| 118 |
+
notices within Derivative Works that You distribute, alongside
|
| 119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 120 |
+
that such additional attribution notices cannot be construed
|
| 121 |
+
as modifying the License.
|
| 122 |
+
|
| 123 |
+
You may add Your own copyright statement to Your modifications and
|
| 124 |
+
may provide additional or different license terms and conditions
|
| 125 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 126 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 127 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 128 |
+
the conditions stated in this License.
|
| 129 |
+
|
| 130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 132 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 133 |
+
this License, without any additional terms or conditions.
|
| 134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 135 |
+
the terms of any separate license agreement you may have executed
|
| 136 |
+
with Licensor regarding such Contributions.
|
| 137 |
+
|
| 138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 140 |
+
except as required for reasonable and customary use in describing the
|
| 141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 142 |
+
|
| 143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 144 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 147 |
+
implied, including, without limitation, any warranties or conditions
|
| 148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 150 |
+
appropriateness of using or redistributing the Work and assume any
|
| 151 |
+
risks associated with Your exercise of permissions under this License.
|
| 152 |
+
|
| 153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 154 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 155 |
+
unless required by applicable law (such as deliberate and grossly
|
| 156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 157 |
+
liable to You for damages, including any direct, indirect, special,
|
| 158 |
+
incidental, or consequential damages of any character arising as a
|
| 159 |
+
result of this License or out of the use or inability to use the
|
| 160 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 161 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 162 |
+
other commercial damages or losses), even if such Contributor
|
| 163 |
+
has been advised of the possibility of such damages.
|
| 164 |
+
|
| 165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 168 |
+
or other liability obligations and/or rights consistent with this
|
| 169 |
+
License. However, in accepting such obligations, You may act only
|
| 170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 171 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 172 |
+
defend, and hold each Contributor harmless for any liability
|
| 173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 174 |
+
of your accepting any such warranty or additional liability.
|
| 175 |
+
|
| 176 |
+
END OF TERMS AND CONDITIONS
|
| 177 |
+
|
| 178 |
+
APPENDIX: How to apply the Apache License to your work.
|
| 179 |
+
|
| 180 |
+
To apply the Apache License to your work, attach the following
|
| 181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 182 |
+
replaced with your own identifying information. (Don't include
|
| 183 |
+
the brackets!) The text should be enclosed in the appropriate
|
| 184 |
+
comment syntax for the file format. We also recommend that a
|
| 185 |
+
file or class name and description of purpose be included on the
|
| 186 |
+
same "printed page" as the copyright notice for easier
|
| 187 |
+
identification within third-party archives.
|
| 188 |
+
|
| 189 |
+
Copyright [yyyy] [name of copyright owner]
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 193 |
+
you may not use this file except in compliance with the License.
|
| 194 |
+
You may obtain a copy of the License at
|
| 195 |
+
|
| 196 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 197 |
+
|
| 198 |
+
Unless required by applicable law or agreed to in writing, software
|
| 199 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 200 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 201 |
+
See the License for the specific language governing permissions and
|
| 202 |
+
limitations under the License.
|
approach/ovod/detectron2/MODEL_ZOO.md
ADDED
|
@@ -0,0 +1,1052 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Detectron2 Model Zoo and Baselines
|
| 2 |
+
|
| 3 |
+
## Introduction
|
| 4 |
+
|
| 5 |
+
This file documents a large collection of baselines trained
|
| 6 |
+
with detectron2 in Sep-Oct, 2019.
|
| 7 |
+
All numbers were obtained on [Big Basin](https://engineering.fb.com/data-center-engineering/introducing-big-basin-our-next-generation-ai-hardware/)
|
| 8 |
+
servers with 8 NVIDIA V100 GPUs & NVLink. The speed numbers are periodically updated with latest PyTorch/CUDA/cuDNN versions.
|
| 9 |
+
You can access these models from code using [detectron2.model_zoo](https://detectron2.readthedocs.io/modules/model_zoo.html) APIs.
|
| 10 |
+
|
| 11 |
+
In addition to these official baseline models, you can find more models in [projects/](projects/).
|
| 12 |
+
|
| 13 |
+
#### How to Read the Tables
|
| 14 |
+
* The "Name" column contains a link to the config file. Models can be reproduced using `tools/train_net.py` with the corresponding yaml config file,
|
| 15 |
+
or `tools/lazyconfig_train_net.py` for python config files.
|
| 16 |
+
* Training speed is averaged across the entire training.
|
| 17 |
+
We keep updating the speed with latest version of detectron2/pytorch/etc.,
|
| 18 |
+
so they might be different from the `metrics` file.
|
| 19 |
+
Training speed for multi-machine jobs is not provided.
|
| 20 |
+
* Inference speed is measured by `tools/train_net.py --eval-only`, or [inference_on_dataset()](https://detectron2.readthedocs.io/modules/evaluation.html#detectron2.evaluation.inference_on_dataset),
|
| 21 |
+
with batch size 1 in detectron2 directly.
|
| 22 |
+
Measuring it with custom code may introduce other overhead.
|
| 23 |
+
Actual deployment in production should in general be faster than the given inference
|
| 24 |
+
speed due to more optimizations.
|
| 25 |
+
* The *model id* column is provided for ease of reference.
|
| 26 |
+
To check downloaded file integrity, any model on this page contains its md5 prefix in its file name.
|
| 27 |
+
* Training curves and other statistics can be found in `metrics` for each model.
|
| 28 |
+
|
| 29 |
+
#### Common Settings for COCO Models
|
| 30 |
+
* All COCO models were trained on `train2017` and evaluated on `val2017`.
|
| 31 |
+
* The default settings are __not directly comparable__ with Detectron's standard settings.
|
| 32 |
+
For example, our default training data augmentation uses scale jittering in addition to horizontal flipping.
|
| 33 |
+
|
| 34 |
+
To make fair comparisons with Detectron's settings, see
|
| 35 |
+
[Detectron1-Comparisons](configs/Detectron1-Comparisons/) for accuracy comparison,
|
| 36 |
+
and [benchmarks](https://detectron2.readthedocs.io/notes/benchmarks.html)
|
| 37 |
+
for speed comparison.
|
| 38 |
+
* For Faster/Mask R-CNN, we provide baselines based on __3 different backbone combinations__:
|
| 39 |
+
* __FPN__: Use a ResNet+FPN backbone with standard conv and FC heads for mask and box prediction,
|
| 40 |
+
respectively. It obtains the best
|
| 41 |
+
speed/accuracy tradeoff, but the other two are still useful for research.
|
| 42 |
+
* __C4__: Use a ResNet conv4 backbone with conv5 head. The original baseline in the Faster R-CNN paper.
|
| 43 |
+
* __DC5__ (Dilated-C5): Use a ResNet conv5 backbone with dilations in conv5, and standard conv and FC heads
|
| 44 |
+
for mask and box prediction, respectively.
|
| 45 |
+
This is used by the Deformable ConvNet paper.
|
| 46 |
+
* Most models are trained with the 3x schedule (~37 COCO epochs).
|
| 47 |
+
Although 1x models are heavily under-trained, we provide some ResNet-50 models with the 1x (~12 COCO epochs)
|
| 48 |
+
training schedule for comparison when doing quick research iteration.
|
| 49 |
+
|
| 50 |
+
#### ImageNet Pretrained Models
|
| 51 |
+
|
| 52 |
+
It's common to initialize from backbone models pre-trained on ImageNet classification tasks. The following backbone models are available:
|
| 53 |
+
|
| 54 |
+
* [R-50.pkl](https://dl.fbaipublicfiles.com/detectron2/ImageNetPretrained/MSRA/R-50.pkl): converted copy of [MSRA's original ResNet-50](https://github.com/KaimingHe/deep-residual-networks) model.
|
| 55 |
+
* [R-101.pkl](https://dl.fbaipublicfiles.com/detectron2/ImageNetPretrained/MSRA/R-101.pkl): converted copy of [MSRA's original ResNet-101](https://github.com/KaimingHe/deep-residual-networks) model.
|
| 56 |
+
* [X-101-32x8d.pkl](https://dl.fbaipublicfiles.com/detectron2/ImageNetPretrained/FAIR/X-101-32x8d.pkl): ResNeXt-101-32x8d model trained with Caffe2 at FB.
|
| 57 |
+
* [R-50.pkl (torchvision)](https://dl.fbaipublicfiles.com/detectron2/ImageNetPretrained/torchvision/R-50.pkl): converted copy of [torchvision's ResNet-50](https://pytorch.org/docs/stable/torchvision/models.html#torchvision.models.resnet50) model.
|
| 58 |
+
More details can be found in [the conversion script](tools/convert-torchvision-to-d2.py).
|
| 59 |
+
|
| 60 |
+
Note that the above models have __different__ format from those provided in Detectron: we do not fuse BatchNorm into an affine layer.
|
| 61 |
+
Pretrained models in Detectron's format can still be used. For example:
|
| 62 |
+
* [X-152-32x8d-IN5k.pkl](https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/25093814/X-152-32x8d-IN5k.pkl):
|
| 63 |
+
ResNeXt-152-32x8d model trained on ImageNet-5k with Caffe2 at FB (see ResNeXt paper for details on ImageNet-5k).
|
| 64 |
+
* [R-50-GN.pkl](https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/47261647/R-50-GN.pkl):
|
| 65 |
+
ResNet-50 with Group Normalization.
|
| 66 |
+
* [R-101-GN.pkl](https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/47592356/R-101-GN.pkl):
|
| 67 |
+
ResNet-101 with Group Normalization.
|
| 68 |
+
|
| 69 |
+
These models require slightly different settings regarding normalization and architecture. See the model zoo configs for reference.
|
| 70 |
+
|
| 71 |
+
#### License
|
| 72 |
+
|
| 73 |
+
All models available for download through this document are licensed under the
|
| 74 |
+
[Creative Commons Attribution-ShareAlike 3.0 license](https://creativecommons.org/licenses/by-sa/3.0/).
|
| 75 |
+
|
| 76 |
+
### COCO Object Detection Baselines
|
| 77 |
+
|
| 78 |
+
#### Faster R-CNN:
|
| 79 |
+
<!--
|
| 80 |
+
(fb only) To update the table in vim:
|
| 81 |
+
1. Remove the old table: d}
|
| 82 |
+
2. Copy the below command to the place of the table
|
| 83 |
+
3. :.!bash
|
| 84 |
+
|
| 85 |
+
./gen_html_table.py --config 'COCO-Detection/faster*50*'{1x,3x}'*' 'COCO-Detection/faster*101*' --name R50-C4 R50-DC5 R50-FPN R50-C4 R50-DC5 R50-FPN R101-C4 R101-DC5 R101-FPN X101-FPN --fields lr_sched train_speed inference_speed mem box_AP
|
| 86 |
+
-->
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
<table><tbody>
|
| 90 |
+
<!-- START TABLE -->
|
| 91 |
+
<!-- TABLE HEADER -->
|
| 92 |
+
<th valign="bottom">Name</th>
|
| 93 |
+
<th valign="bottom">lr<br/>sched</th>
|
| 94 |
+
<th valign="bottom">train<br/>time<br/>(s/iter)</th>
|
| 95 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 96 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 97 |
+
<th valign="bottom">box<br/>AP</th>
|
| 98 |
+
<th valign="bottom">model id</th>
|
| 99 |
+
<th valign="bottom">download</th>
|
| 100 |
+
<!-- TABLE BODY -->
|
| 101 |
+
<!-- ROW: faster_rcnn_R_50_C4_1x -->
|
| 102 |
+
<tr><td align="left"><a href="configs/COCO-Detection/faster_rcnn_R_50_C4_1x.yaml">R50-C4</a></td>
|
| 103 |
+
<td align="center">1x</td>
|
| 104 |
+
<td align="center">0.551</td>
|
| 105 |
+
<td align="center">0.102</td>
|
| 106 |
+
<td align="center">4.8</td>
|
| 107 |
+
<td align="center">35.7</td>
|
| 108 |
+
<td align="center">137257644</td>
|
| 109 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_C4_1x/137257644/model_final_721ade.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_C4_1x/137257644/metrics.json">metrics</a></td>
|
| 110 |
+
</tr>
|
| 111 |
+
<!-- ROW: faster_rcnn_R_50_DC5_1x -->
|
| 112 |
+
<tr><td align="left"><a href="configs/COCO-Detection/faster_rcnn_R_50_DC5_1x.yaml">R50-DC5</a></td>
|
| 113 |
+
<td align="center">1x</td>
|
| 114 |
+
<td align="center">0.380</td>
|
| 115 |
+
<td align="center">0.068</td>
|
| 116 |
+
<td align="center">5.0</td>
|
| 117 |
+
<td align="center">37.3</td>
|
| 118 |
+
<td align="center">137847829</td>
|
| 119 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_DC5_1x/137847829/model_final_51d356.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_DC5_1x/137847829/metrics.json">metrics</a></td>
|
| 120 |
+
</tr>
|
| 121 |
+
<!-- ROW: faster_rcnn_R_50_FPN_1x -->
|
| 122 |
+
<tr><td align="left"><a href="configs/COCO-Detection/faster_rcnn_R_50_FPN_1x.yaml">R50-FPN</a></td>
|
| 123 |
+
<td align="center">1x</td>
|
| 124 |
+
<td align="center">0.210</td>
|
| 125 |
+
<td align="center">0.038</td>
|
| 126 |
+
<td align="center">3.0</td>
|
| 127 |
+
<td align="center">37.9</td>
|
| 128 |
+
<td align="center">137257794</td>
|
| 129 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_FPN_1x/137257794/model_final_b275ba.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_FPN_1x/137257794/metrics.json">metrics</a></td>
|
| 130 |
+
</tr>
|
| 131 |
+
<!-- ROW: faster_rcnn_R_50_C4_3x -->
|
| 132 |
+
<tr><td align="left"><a href="configs/COCO-Detection/faster_rcnn_R_50_C4_3x.yaml">R50-C4</a></td>
|
| 133 |
+
<td align="center">3x</td>
|
| 134 |
+
<td align="center">0.543</td>
|
| 135 |
+
<td align="center">0.104</td>
|
| 136 |
+
<td align="center">4.8</td>
|
| 137 |
+
<td align="center">38.4</td>
|
| 138 |
+
<td align="center">137849393</td>
|
| 139 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_C4_3x/137849393/model_final_f97cb7.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_C4_3x/137849393/metrics.json">metrics</a></td>
|
| 140 |
+
</tr>
|
| 141 |
+
<!-- ROW: faster_rcnn_R_50_DC5_3x -->
|
| 142 |
+
<tr><td align="left"><a href="configs/COCO-Detection/faster_rcnn_R_50_DC5_3x.yaml">R50-DC5</a></td>
|
| 143 |
+
<td align="center">3x</td>
|
| 144 |
+
<td align="center">0.378</td>
|
| 145 |
+
<td align="center">0.070</td>
|
| 146 |
+
<td align="center">5.0</td>
|
| 147 |
+
<td align="center">39.0</td>
|
| 148 |
+
<td align="center">137849425</td>
|
| 149 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_DC5_3x/137849425/model_final_68d202.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_DC5_3x/137849425/metrics.json">metrics</a></td>
|
| 150 |
+
</tr>
|
| 151 |
+
<!-- ROW: faster_rcnn_R_50_FPN_3x -->
|
| 152 |
+
<tr><td align="left"><a href="configs/COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml">R50-FPN</a></td>
|
| 153 |
+
<td align="center">3x</td>
|
| 154 |
+
<td align="center">0.209</td>
|
| 155 |
+
<td align="center">0.038</td>
|
| 156 |
+
<td align="center">3.0</td>
|
| 157 |
+
<td align="center">40.2</td>
|
| 158 |
+
<td align="center">137849458</td>
|
| 159 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_FPN_3x/137849458/model_final_280758.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_50_FPN_3x/137849458/metrics.json">metrics</a></td>
|
| 160 |
+
</tr>
|
| 161 |
+
<!-- ROW: faster_rcnn_R_101_C4_3x -->
|
| 162 |
+
<tr><td align="left"><a href="configs/COCO-Detection/faster_rcnn_R_101_C4_3x.yaml">R101-C4</a></td>
|
| 163 |
+
<td align="center">3x</td>
|
| 164 |
+
<td align="center">0.619</td>
|
| 165 |
+
<td align="center">0.139</td>
|
| 166 |
+
<td align="center">5.9</td>
|
| 167 |
+
<td align="center">41.1</td>
|
| 168 |
+
<td align="center">138204752</td>
|
| 169 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_101_C4_3x/138204752/model_final_298dad.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_101_C4_3x/138204752/metrics.json">metrics</a></td>
|
| 170 |
+
</tr>
|
| 171 |
+
<!-- ROW: faster_rcnn_R_101_DC5_3x -->
|
| 172 |
+
<tr><td align="left"><a href="configs/COCO-Detection/faster_rcnn_R_101_DC5_3x.yaml">R101-DC5</a></td>
|
| 173 |
+
<td align="center">3x</td>
|
| 174 |
+
<td align="center">0.452</td>
|
| 175 |
+
<td align="center">0.086</td>
|
| 176 |
+
<td align="center">6.1</td>
|
| 177 |
+
<td align="center">40.6</td>
|
| 178 |
+
<td align="center">138204841</td>
|
| 179 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_101_DC5_3x/138204841/model_final_3e0943.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_101_DC5_3x/138204841/metrics.json">metrics</a></td>
|
| 180 |
+
</tr>
|
| 181 |
+
<!-- ROW: faster_rcnn_R_101_FPN_3x -->
|
| 182 |
+
<tr><td align="left"><a href="configs/COCO-Detection/faster_rcnn_R_101_FPN_3x.yaml">R101-FPN</a></td>
|
| 183 |
+
<td align="center">3x</td>
|
| 184 |
+
<td align="center">0.286</td>
|
| 185 |
+
<td align="center">0.051</td>
|
| 186 |
+
<td align="center">4.1</td>
|
| 187 |
+
<td align="center">42.0</td>
|
| 188 |
+
<td align="center">137851257</td>
|
| 189 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_101_FPN_3x/137851257/model_final_f6e8b1.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_R_101_FPN_3x/137851257/metrics.json">metrics</a></td>
|
| 190 |
+
</tr>
|
| 191 |
+
<!-- ROW: faster_rcnn_X_101_32x8d_FPN_3x -->
|
| 192 |
+
<tr><td align="left"><a href="configs/COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x.yaml">X101-FPN</a></td>
|
| 193 |
+
<td align="center">3x</td>
|
| 194 |
+
<td align="center">0.638</td>
|
| 195 |
+
<td align="center">0.098</td>
|
| 196 |
+
<td align="center">6.7</td>
|
| 197 |
+
<td align="center">43.0</td>
|
| 198 |
+
<td align="center">139173657</td>
|
| 199 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x/139173657/model_final_68b088.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x/139173657/metrics.json">metrics</a></td>
|
| 200 |
+
</tr>
|
| 201 |
+
</tbody></table>
|
| 202 |
+
|
| 203 |
+
#### RetinaNet:
|
| 204 |
+
<!--
|
| 205 |
+
./gen_html_table.py --config 'COCO-Detection/retina*50*' 'COCO-Detection/retina*101*' --name R50 R50 R101 --fields lr_sched train_speed inference_speed mem box_AP
|
| 206 |
+
-->
|
| 207 |
+
|
| 208 |
+
<table><tbody>
|
| 209 |
+
<!-- START TABLE -->
|
| 210 |
+
<!-- TABLE HEADER -->
|
| 211 |
+
<th valign="bottom">Name</th>
|
| 212 |
+
<th valign="bottom">lr<br/>sched</th>
|
| 213 |
+
<th valign="bottom">train<br/>time<br/>(s/iter)</th>
|
| 214 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 215 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 216 |
+
<th valign="bottom">box<br/>AP</th>
|
| 217 |
+
<th valign="bottom">model id</th>
|
| 218 |
+
<th valign="bottom">download</th>
|
| 219 |
+
<!-- TABLE BODY -->
|
| 220 |
+
<!-- ROW: retinanet_R_50_FPN_1x -->
|
| 221 |
+
<tr><td align="left"><a href="configs/COCO-Detection/retinanet_R_50_FPN_1x.yaml">R50</a></td>
|
| 222 |
+
<td align="center">1x</td>
|
| 223 |
+
<td align="center">0.205</td>
|
| 224 |
+
<td align="center">0.041</td>
|
| 225 |
+
<td align="center">4.1</td>
|
| 226 |
+
<td align="center">37.4</td>
|
| 227 |
+
<td align="center">190397773</td>
|
| 228 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/retinanet_R_50_FPN_1x/190397773/model_final_bfca0b.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/retinanet_R_50_FPN_1x/190397773/metrics.json">metrics</a></td>
|
| 229 |
+
</tr>
|
| 230 |
+
<!-- ROW: retinanet_R_50_FPN_3x -->
|
| 231 |
+
<tr><td align="left"><a href="configs/COCO-Detection/retinanet_R_50_FPN_3x.yaml">R50</a></td>
|
| 232 |
+
<td align="center">3x</td>
|
| 233 |
+
<td align="center">0.205</td>
|
| 234 |
+
<td align="center">0.041</td>
|
| 235 |
+
<td align="center">4.1</td>
|
| 236 |
+
<td align="center">38.7</td>
|
| 237 |
+
<td align="center">190397829</td>
|
| 238 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/retinanet_R_50_FPN_3x/190397829/model_final_5bd44e.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/retinanet_R_50_FPN_3x/190397829/metrics.json">metrics</a></td>
|
| 239 |
+
</tr>
|
| 240 |
+
<!-- ROW: retinanet_R_101_FPN_3x -->
|
| 241 |
+
<tr><td align="left"><a href="configs/COCO-Detection/retinanet_R_101_FPN_3x.yaml">R101</a></td>
|
| 242 |
+
<td align="center">3x</td>
|
| 243 |
+
<td align="center">0.291</td>
|
| 244 |
+
<td align="center">0.054</td>
|
| 245 |
+
<td align="center">5.2</td>
|
| 246 |
+
<td align="center">40.4</td>
|
| 247 |
+
<td align="center">190397697</td>
|
| 248 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/retinanet_R_101_FPN_3x/190397697/model_final_971ab9.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/retinanet_R_101_FPN_3x/190397697/metrics.json">metrics</a></td>
|
| 249 |
+
</tr>
|
| 250 |
+
</tbody></table>
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
#### RPN & Fast R-CNN:
|
| 254 |
+
<!--
|
| 255 |
+
./gen_html_table.py --config 'COCO-Detection/rpn*' 'COCO-Detection/fast_rcnn*' --name "RPN R50-C4" "RPN R50-FPN" "Fast R-CNN R50-FPN" --fields lr_sched train_speed inference_speed mem box_AP prop_AR
|
| 256 |
+
-->
|
| 257 |
+
|
| 258 |
+
<table><tbody>
|
| 259 |
+
<!-- START TABLE -->
|
| 260 |
+
<!-- TABLE HEADER -->
|
| 261 |
+
<th valign="bottom">Name</th>
|
| 262 |
+
<th valign="bottom">lr<br/>sched</th>
|
| 263 |
+
<th valign="bottom">train<br/>time<br/>(s/iter)</th>
|
| 264 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 265 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 266 |
+
<th valign="bottom">box<br/>AP</th>
|
| 267 |
+
<th valign="bottom">prop.<br/>AR</th>
|
| 268 |
+
<th valign="bottom">model id</th>
|
| 269 |
+
<th valign="bottom">download</th>
|
| 270 |
+
<!-- TABLE BODY -->
|
| 271 |
+
<!-- ROW: rpn_R_50_C4_1x -->
|
| 272 |
+
<tr><td align="left"><a href="configs/COCO-Detection/rpn_R_50_C4_1x.yaml">RPN R50-C4</a></td>
|
| 273 |
+
<td align="center">1x</td>
|
| 274 |
+
<td align="center">0.130</td>
|
| 275 |
+
<td align="center">0.034</td>
|
| 276 |
+
<td align="center">1.5</td>
|
| 277 |
+
<td align="center"></td>
|
| 278 |
+
<td align="center">51.6</td>
|
| 279 |
+
<td align="center">137258005</td>
|
| 280 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/rpn_R_50_C4_1x/137258005/model_final_450694.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/rpn_R_50_C4_1x/137258005/metrics.json">metrics</a></td>
|
| 281 |
+
</tr>
|
| 282 |
+
<!-- ROW: rpn_R_50_FPN_1x -->
|
| 283 |
+
<tr><td align="left"><a href="configs/COCO-Detection/rpn_R_50_FPN_1x.yaml">RPN R50-FPN</a></td>
|
| 284 |
+
<td align="center">1x</td>
|
| 285 |
+
<td align="center">0.186</td>
|
| 286 |
+
<td align="center">0.032</td>
|
| 287 |
+
<td align="center">2.7</td>
|
| 288 |
+
<td align="center"></td>
|
| 289 |
+
<td align="center">58.0</td>
|
| 290 |
+
<td align="center">137258492</td>
|
| 291 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/rpn_R_50_FPN_1x/137258492/model_final_02ce48.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/rpn_R_50_FPN_1x/137258492/metrics.json">metrics</a></td>
|
| 292 |
+
</tr>
|
| 293 |
+
<!-- ROW: fast_rcnn_R_50_FPN_1x -->
|
| 294 |
+
<tr><td align="left"><a href="configs/COCO-Detection/fast_rcnn_R_50_FPN_1x.yaml">Fast R-CNN R50-FPN</a></td>
|
| 295 |
+
<td align="center">1x</td>
|
| 296 |
+
<td align="center">0.140</td>
|
| 297 |
+
<td align="center">0.029</td>
|
| 298 |
+
<td align="center">2.6</td>
|
| 299 |
+
<td align="center">37.8</td>
|
| 300 |
+
<td align="center"></td>
|
| 301 |
+
<td align="center">137635226</td>
|
| 302 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/fast_rcnn_R_50_FPN_1x/137635226/model_final_e5f7ce.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Detection/fast_rcnn_R_50_FPN_1x/137635226/metrics.json">metrics</a></td>
|
| 303 |
+
</tr>
|
| 304 |
+
</tbody></table>
|
| 305 |
+
|
| 306 |
+
### COCO Instance Segmentation Baselines with Mask R-CNN
|
| 307 |
+
<!--
|
| 308 |
+
./gen_html_table.py --config 'COCO-InstanceSegmentation/mask*50*'{1x,3x}'*' 'COCO-InstanceSegmentation/mask*101*' --name R50-C4 R50-DC5 R50-FPN R50-C4 R50-DC5 R50-FPN R101-C4 R101-DC5 R101-FPN X101-FPN --fields lr_sched train_speed inference_speed mem box_AP mask_AP
|
| 309 |
+
-->
|
| 310 |
+
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
<table><tbody>
|
| 314 |
+
<!-- START TABLE -->
|
| 315 |
+
<!-- TABLE HEADER -->
|
| 316 |
+
<th valign="bottom">Name</th>
|
| 317 |
+
<th valign="bottom">lr<br/>sched</th>
|
| 318 |
+
<th valign="bottom">train<br/>time<br/>(s/iter)</th>
|
| 319 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 320 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 321 |
+
<th valign="bottom">box<br/>AP</th>
|
| 322 |
+
<th valign="bottom">mask<br/>AP</th>
|
| 323 |
+
<th valign="bottom">model id</th>
|
| 324 |
+
<th valign="bottom">download</th>
|
| 325 |
+
<!-- TABLE BODY -->
|
| 326 |
+
<!-- ROW: mask_rcnn_R_50_C4_1x -->
|
| 327 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_50_C4_1x.yaml">R50-C4</a></td>
|
| 328 |
+
<td align="center">1x</td>
|
| 329 |
+
<td align="center">0.584</td>
|
| 330 |
+
<td align="center">0.110</td>
|
| 331 |
+
<td align="center">5.2</td>
|
| 332 |
+
<td align="center">36.8</td>
|
| 333 |
+
<td align="center">32.2</td>
|
| 334 |
+
<td align="center">137259246</td>
|
| 335 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_C4_1x/137259246/model_final_9243eb.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_C4_1x/137259246/metrics.json">metrics</a></td>
|
| 336 |
+
</tr>
|
| 337 |
+
<!-- ROW: mask_rcnn_R_50_DC5_1x -->
|
| 338 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_50_DC5_1x.yaml">R50-DC5</a></td>
|
| 339 |
+
<td align="center">1x</td>
|
| 340 |
+
<td align="center">0.471</td>
|
| 341 |
+
<td align="center">0.076</td>
|
| 342 |
+
<td align="center">6.5</td>
|
| 343 |
+
<td align="center">38.3</td>
|
| 344 |
+
<td align="center">34.2</td>
|
| 345 |
+
<td align="center">137260150</td>
|
| 346 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_DC5_1x/137260150/model_final_4f86c3.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_DC5_1x/137260150/metrics.json">metrics</a></td>
|
| 347 |
+
</tr>
|
| 348 |
+
<!-- ROW: mask_rcnn_R_50_FPN_1x -->
|
| 349 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml">R50-FPN</a></td>
|
| 350 |
+
<td align="center">1x</td>
|
| 351 |
+
<td align="center">0.261</td>
|
| 352 |
+
<td align="center">0.043</td>
|
| 353 |
+
<td align="center">3.4</td>
|
| 354 |
+
<td align="center">38.6</td>
|
| 355 |
+
<td align="center">35.2</td>
|
| 356 |
+
<td align="center">137260431</td>
|
| 357 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x/137260431/model_final_a54504.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x/137260431/metrics.json">metrics</a></td>
|
| 358 |
+
</tr>
|
| 359 |
+
<!-- ROW: mask_rcnn_R_50_C4_3x -->
|
| 360 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_50_C4_3x.yaml">R50-C4</a></td>
|
| 361 |
+
<td align="center">3x</td>
|
| 362 |
+
<td align="center">0.575</td>
|
| 363 |
+
<td align="center">0.111</td>
|
| 364 |
+
<td align="center">5.2</td>
|
| 365 |
+
<td align="center">39.8</td>
|
| 366 |
+
<td align="center">34.4</td>
|
| 367 |
+
<td align="center">137849525</td>
|
| 368 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_C4_3x/137849525/model_final_4ce675.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_C4_3x/137849525/metrics.json">metrics</a></td>
|
| 369 |
+
</tr>
|
| 370 |
+
<!-- ROW: mask_rcnn_R_50_DC5_3x -->
|
| 371 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_50_DC5_3x.yaml">R50-DC5</a></td>
|
| 372 |
+
<td align="center">3x</td>
|
| 373 |
+
<td align="center">0.470</td>
|
| 374 |
+
<td align="center">0.076</td>
|
| 375 |
+
<td align="center">6.5</td>
|
| 376 |
+
<td align="center">40.0</td>
|
| 377 |
+
<td align="center">35.9</td>
|
| 378 |
+
<td align="center">137849551</td>
|
| 379 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_DC5_3x/137849551/model_final_84107b.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_DC5_3x/137849551/metrics.json">metrics</a></td>
|
| 380 |
+
</tr>
|
| 381 |
+
<!-- ROW: mask_rcnn_R_50_FPN_3x -->
|
| 382 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml">R50-FPN</a></td>
|
| 383 |
+
<td align="center">3x</td>
|
| 384 |
+
<td align="center">0.261</td>
|
| 385 |
+
<td align="center">0.043</td>
|
| 386 |
+
<td align="center">3.4</td>
|
| 387 |
+
<td align="center">41.0</td>
|
| 388 |
+
<td align="center">37.2</td>
|
| 389 |
+
<td align="center">137849600</td>
|
| 390 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x/137849600/model_final_f10217.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x/137849600/metrics.json">metrics</a></td>
|
| 391 |
+
</tr>
|
| 392 |
+
<!-- ROW: mask_rcnn_R_101_C4_3x -->
|
| 393 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_101_C4_3x.yaml">R101-C4</a></td>
|
| 394 |
+
<td align="center">3x</td>
|
| 395 |
+
<td align="center">0.652</td>
|
| 396 |
+
<td align="center">0.145</td>
|
| 397 |
+
<td align="center">6.3</td>
|
| 398 |
+
<td align="center">42.6</td>
|
| 399 |
+
<td align="center">36.7</td>
|
| 400 |
+
<td align="center">138363239</td>
|
| 401 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_101_C4_3x/138363239/model_final_a2914c.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_101_C4_3x/138363239/metrics.json">metrics</a></td>
|
| 402 |
+
</tr>
|
| 403 |
+
<!-- ROW: mask_rcnn_R_101_DC5_3x -->
|
| 404 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_101_DC5_3x.yaml">R101-DC5</a></td>
|
| 405 |
+
<td align="center">3x</td>
|
| 406 |
+
<td align="center">0.545</td>
|
| 407 |
+
<td align="center">0.092</td>
|
| 408 |
+
<td align="center">7.6</td>
|
| 409 |
+
<td align="center">41.9</td>
|
| 410 |
+
<td align="center">37.3</td>
|
| 411 |
+
<td align="center">138363294</td>
|
| 412 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_101_DC5_3x/138363294/model_final_0464b7.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_101_DC5_3x/138363294/metrics.json">metrics</a></td>
|
| 413 |
+
</tr>
|
| 414 |
+
<!-- ROW: mask_rcnn_R_101_FPN_3x -->
|
| 415 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_101_FPN_3x.yaml">R101-FPN</a></td>
|
| 416 |
+
<td align="center">3x</td>
|
| 417 |
+
<td align="center">0.340</td>
|
| 418 |
+
<td align="center">0.056</td>
|
| 419 |
+
<td align="center">4.6</td>
|
| 420 |
+
<td align="center">42.9</td>
|
| 421 |
+
<td align="center">38.6</td>
|
| 422 |
+
<td align="center">138205316</td>
|
| 423 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_101_FPN_3x/138205316/model_final_a3ec72.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_101_FPN_3x/138205316/metrics.json">metrics</a></td>
|
| 424 |
+
</tr>
|
| 425 |
+
<!-- ROW: mask_rcnn_X_101_32x8d_FPN_3x -->
|
| 426 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_3x.yaml">X101-FPN</a></td>
|
| 427 |
+
<td align="center">3x</td>
|
| 428 |
+
<td align="center">0.690</td>
|
| 429 |
+
<td align="center">0.103</td>
|
| 430 |
+
<td align="center">7.2</td>
|
| 431 |
+
<td align="center">44.3</td>
|
| 432 |
+
<td align="center">39.5</td>
|
| 433 |
+
<td align="center">139653917</td>
|
| 434 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_3x/139653917/model_final_2d9806.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_3x/139653917/metrics.json">metrics</a></td>
|
| 435 |
+
</tr>
|
| 436 |
+
</tbody></table>
|
| 437 |
+
|
| 438 |
+
|
| 439 |
+
|
| 440 |
+
#### New baselines using Large-Scale Jitter and Longer Training Schedule
|
| 441 |
+
|
| 442 |
+
The following baselines of COCO Instance Segmentation with Mask R-CNN are generated
|
| 443 |
+
using a longer training schedule and large-scale jitter as described in Google's
|
| 444 |
+
[Simple Copy-Paste Data Augmentation](https://arxiv.org/pdf/2012.07177.pdf) paper. These
|
| 445 |
+
models are trained from scratch using random initialization. These baselines exceed the
|
| 446 |
+
previous Mask R-CNN baselines.
|
| 447 |
+
|
| 448 |
+
In the following table, one epoch consists of training on 118000 COCO images.
|
| 449 |
+
|
| 450 |
+
<table><tbody>
|
| 451 |
+
<!-- START TABLE -->
|
| 452 |
+
<!-- TABLE HEADER -->
|
| 453 |
+
<th valign="bottom">Name</th>
|
| 454 |
+
<th valign="bottom">epochs</th>
|
| 455 |
+
<th valign="bottom">train<br/>time<br/>(s/im)</th>
|
| 456 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 457 |
+
<th valign="bottom">box<br/>AP</th>
|
| 458 |
+
<th valign="bottom">mask<br/>AP</th>
|
| 459 |
+
<th valign="bottom">model id</th>
|
| 460 |
+
<th valign="bottom">download</th>
|
| 461 |
+
<!-- TABLE BODY -->
|
| 462 |
+
<!-- ROW: mask_rcnn_R_50_FPN_100ep_LSJ -->
|
| 463 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_R_50_FPN_100ep_LSJ.py">R50-FPN</a></td>
|
| 464 |
+
<td align="center">100</td>
|
| 465 |
+
<td align="center">0.376</td>
|
| 466 |
+
<td align="center">0.069</td>
|
| 467 |
+
<td align="center">44.6</td>
|
| 468 |
+
<td align="center">40.3</td>
|
| 469 |
+
<td align="center">42047764</td>
|
| 470 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_50_FPN_100ep_LSJ/42047764/model_final_bb69de.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_50_FPN_100ep_LSJ/42047764/metrics.json">metrics</a></td>
|
| 471 |
+
</tr>
|
| 472 |
+
<!-- ROW: mask_rcnn_R_50_FPN_200ep_LSJ -->
|
| 473 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_R_50_FPN_200ep_LSJ.py">R50-FPN</a></td>
|
| 474 |
+
<td align="center">200</td>
|
| 475 |
+
<td align="center">0.376</td>
|
| 476 |
+
<td align="center">0.069</td>
|
| 477 |
+
<td align="center">46.3</td>
|
| 478 |
+
<td align="center">41.7</td>
|
| 479 |
+
<td align="center">42047638</td>
|
| 480 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_50_FPN_200ep_LSJ/42047638/model_final_89a8d3.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_50_FPN_200ep_LSJ/42047638/metrics.json">metrics</a></td>
|
| 481 |
+
</tr>
|
| 482 |
+
<!-- ROW: mask_rcnn_R_50_FPN_400ep_LSJ -->
|
| 483 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_R_50_FPN_400ep_LSJ.py">R50-FPN</a></td>
|
| 484 |
+
<td align="center">400</td>
|
| 485 |
+
<td align="center">0.376</td>
|
| 486 |
+
<td align="center">0.069</td>
|
| 487 |
+
<td align="center">47.4</td>
|
| 488 |
+
<td align="center">42.5</td>
|
| 489 |
+
<td align="center">42019571</td>
|
| 490 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_50_FPN_400ep_LSJ/42019571/model_final_14d201.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_50_FPN_400ep_LSJ/42019571/metrics.json">metrics</a></td>
|
| 491 |
+
</tr>
|
| 492 |
+
<!-- ROW: mask_rcnn_R_101_FPN_100ep_LSJ -->
|
| 493 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_R_101_FPN_100ep_LSJ.py">R101-FPN</a></td>
|
| 494 |
+
<td align="center">100</td>
|
| 495 |
+
<td align="center">0.518</td>
|
| 496 |
+
<td align="center">0.073</td>
|
| 497 |
+
<td align="center">46.4</td>
|
| 498 |
+
<td align="center">41.6</td>
|
| 499 |
+
<td align="center">42025812</td>
|
| 500 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_101_FPN_100ep_LSJ/42025812/model_final_4f7b58.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_101_FPN_100ep_LSJ/42025812/metrics.json">metrics</a></td>
|
| 501 |
+
</tr>
|
| 502 |
+
<!-- ROW: mask_rcnn_R_101_FPN_200ep_LSJ -->
|
| 503 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_R_101_FPN_200ep_LSJ.py">R101-FPN</a></td>
|
| 504 |
+
<td align="center">200</td>
|
| 505 |
+
<td align="center">0.518</td>
|
| 506 |
+
<td align="center">0.073</td>
|
| 507 |
+
<td align="center">48.0</td>
|
| 508 |
+
<td align="center">43.1</td>
|
| 509 |
+
<td align="center">42131867</td>
|
| 510 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_101_FPN_200ep_LSJ/42131867/model_final_0bb7ae.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_101_FPN_200ep_LSJ/42131867/metrics.json">metrics</a></td>
|
| 511 |
+
</tr>
|
| 512 |
+
<!-- ROW: mask_rcnn_R_101_FPN_400ep_LSJ -->
|
| 513 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_R_101_FPN_400ep_LSJ.py">R101-FPN</a></td>
|
| 514 |
+
<td align="center">400</td>
|
| 515 |
+
<td align="center">0.518</td>
|
| 516 |
+
<td align="center">0.073</td>
|
| 517 |
+
<td align="center">48.9</td>
|
| 518 |
+
<td align="center">43.7</td>
|
| 519 |
+
<td align="center">42073830</td>
|
| 520 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_101_FPN_400ep_LSJ/42073830/model_final_f96b26.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_R_101_FPN_400ep_LSJ/42073830/metrics.json">metrics</a></td>
|
| 521 |
+
</tr>
|
| 522 |
+
<!-- ROW: mask_rcnn_regnetx_4gf_dds_FPN_100ep_LSJ -->
|
| 523 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_100ep_LSJ.py">regnetx_4gf_dds_FPN</a></td>
|
| 524 |
+
<td align="center">100</td>
|
| 525 |
+
<td align="center">0.474</td>
|
| 526 |
+
<td align="center">0.071</td>
|
| 527 |
+
<td align="center">46.0</td>
|
| 528 |
+
<td align="center">41.3</td>
|
| 529 |
+
<td align="center">42047771</td>
|
| 530 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_100ep_LSJ/42047771/model_final_b7fbab.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_100ep_LSJ/42047771/metrics.json">metrics</a></td>
|
| 531 |
+
</tr>
|
| 532 |
+
<!-- ROW: mask_rcnn_regnetx_4gf_dds_FPN_200ep_LSJ -->
|
| 533 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_200ep_LSJ.py">regnetx_4gf_dds_FPN</a></td>
|
| 534 |
+
<td align="center">200</td>
|
| 535 |
+
<td align="center">0.474</td>
|
| 536 |
+
<td align="center">0.071</td>
|
| 537 |
+
<td align="center">48.1</td>
|
| 538 |
+
<td align="center">43.1</td>
|
| 539 |
+
<td align="center">42132721</td>
|
| 540 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_200ep_LSJ/42132721/model_final_5d87c1.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_200ep_LSJ/42132721/metrics.json">metrics</a></td>
|
| 541 |
+
</tr>
|
| 542 |
+
<!-- ROW: mask_rcnn_regnetx_4gf_dds_FPN_400ep_LSJ -->
|
| 543 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_400ep_LSJ.py">regnetx_4gf_dds_FPN</a></td>
|
| 544 |
+
<td align="center">400</td>
|
| 545 |
+
<td align="center">0.474</td>
|
| 546 |
+
<td align="center">0.071</td>
|
| 547 |
+
<td align="center">48.6</td>
|
| 548 |
+
<td align="center">43.5</td>
|
| 549 |
+
<td align="center">42025447</td>
|
| 550 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_400ep_LSJ/42025447/model_final_f1362d.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnetx_4gf_dds_FPN_400ep_LSJ/42025447/metrics.json">metrics</a></td>
|
| 551 |
+
</tr>
|
| 552 |
+
<!-- ROW: mask_rcnn_regnety_4gf_dds_FPN_100ep_LSJ -->
|
| 553 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_regnety_4gf_dds_FPN_100ep_LSJ.py">regnety_4gf_dds_FPN</a></td>
|
| 554 |
+
<td align="center">100</td>
|
| 555 |
+
<td align="center">0.487</td>
|
| 556 |
+
<td align="center">0.073</td>
|
| 557 |
+
<td align="center">46.1</td>
|
| 558 |
+
<td align="center">41.6</td>
|
| 559 |
+
<td align="center">42047784</td>
|
| 560 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnety_4gf_dds_FPN_100ep_LSJ/42047784/model_final_6ba57e.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnety_4gf_dds_FPN_100ep_LSJ/42047784/metrics.json">metrics</a></td>
|
| 561 |
+
</tr>
|
| 562 |
+
<!-- ROW: mask_rcnn_regnety_4gf_dds_FPN_200ep_LSJ -->
|
| 563 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_regnety_4gf_dds_FPN_200ep_LSJ.py">regnety_4gf_dds_FPN</a></td>
|
| 564 |
+
<td align="center">200</td>
|
| 565 |
+
<td align="center">0.487</td>
|
| 566 |
+
<td align="center">0.072</td>
|
| 567 |
+
<td align="center">47.8</td>
|
| 568 |
+
<td align="center">43.0</td>
|
| 569 |
+
<td align="center">42047642</td>
|
| 570 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnety_4gf_dds_FPN_200ep_LSJ/42047642/model_final_27b9c1.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnety_4gf_dds_FPN_200ep_LSJ/42047642/metrics.json">metrics</a></td>
|
| 571 |
+
</tr>
|
| 572 |
+
<!-- ROW: mask_rcnn_regnety_4gf_dds_FPN_400ep_LSJ -->
|
| 573 |
+
<tr><td align="left"><a href="configs/new_baselines/mask_rcnn_regnety_4gf_dds_FPN_400ep_LSJ.py">regnety_4gf_dds_FPN</a></td>
|
| 574 |
+
<td align="center">400</td>
|
| 575 |
+
<td align="center">0.487</td>
|
| 576 |
+
<td align="center">0.072</td>
|
| 577 |
+
<td align="center">48.2</td>
|
| 578 |
+
<td align="center">43.3</td>
|
| 579 |
+
<td align="center">42045954</td>
|
| 580 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnety_4gf_dds_FPN_400ep_LSJ/42045954/model_final_ef3a80.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/new_baselines/mask_rcnn_regnety_4gf_dds_FPN_400ep_LSJ/42045954/metrics.json">metrics</a></td>
|
| 581 |
+
</tr>
|
| 582 |
+
</tbody></table>
|
| 583 |
+
|
| 584 |
+
### COCO Person Keypoint Detection Baselines with Keypoint R-CNN
|
| 585 |
+
<!--
|
| 586 |
+
./gen_html_table.py --config 'COCO-Keypoints/*50*' 'COCO-Keypoints/*101*' --name R50-FPN R50-FPN R101-FPN X101-FPN --fields lr_sched train_speed inference_speed mem box_AP keypoint_AP
|
| 587 |
+
-->
|
| 588 |
+
|
| 589 |
+
|
| 590 |
+
<table><tbody>
|
| 591 |
+
<!-- START TABLE -->
|
| 592 |
+
<!-- TABLE HEADER -->
|
| 593 |
+
<th valign="bottom">Name</th>
|
| 594 |
+
<th valign="bottom">lr<br/>sched</th>
|
| 595 |
+
<th valign="bottom">train<br/>time<br/>(s/iter)</th>
|
| 596 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 597 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 598 |
+
<th valign="bottom">box<br/>AP</th>
|
| 599 |
+
<th valign="bottom">kp.<br/>AP</th>
|
| 600 |
+
<th valign="bottom">model id</th>
|
| 601 |
+
<th valign="bottom">download</th>
|
| 602 |
+
<!-- TABLE BODY -->
|
| 603 |
+
<!-- ROW: keypoint_rcnn_R_50_FPN_1x -->
|
| 604 |
+
<tr><td align="left"><a href="configs/COCO-Keypoints/keypoint_rcnn_R_50_FPN_1x.yaml">R50-FPN</a></td>
|
| 605 |
+
<td align="center">1x</td>
|
| 606 |
+
<td align="center">0.315</td>
|
| 607 |
+
<td align="center">0.072</td>
|
| 608 |
+
<td align="center">5.0</td>
|
| 609 |
+
<td align="center">53.6</td>
|
| 610 |
+
<td align="center">64.0</td>
|
| 611 |
+
<td align="center">137261548</td>
|
| 612 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Keypoints/keypoint_rcnn_R_50_FPN_1x/137261548/model_final_04e291.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Keypoints/keypoint_rcnn_R_50_FPN_1x/137261548/metrics.json">metrics</a></td>
|
| 613 |
+
</tr>
|
| 614 |
+
<!-- ROW: keypoint_rcnn_R_50_FPN_3x -->
|
| 615 |
+
<tr><td align="left"><a href="configs/COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml">R50-FPN</a></td>
|
| 616 |
+
<td align="center">3x</td>
|
| 617 |
+
<td align="center">0.316</td>
|
| 618 |
+
<td align="center">0.066</td>
|
| 619 |
+
<td align="center">5.0</td>
|
| 620 |
+
<td align="center">55.4</td>
|
| 621 |
+
<td align="center">65.5</td>
|
| 622 |
+
<td align="center">137849621</td>
|
| 623 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x/137849621/model_final_a6e10b.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x/137849621/metrics.json">metrics</a></td>
|
| 624 |
+
</tr>
|
| 625 |
+
<!-- ROW: keypoint_rcnn_R_101_FPN_3x -->
|
| 626 |
+
<tr><td align="left"><a href="configs/COCO-Keypoints/keypoint_rcnn_R_101_FPN_3x.yaml">R101-FPN</a></td>
|
| 627 |
+
<td align="center">3x</td>
|
| 628 |
+
<td align="center">0.390</td>
|
| 629 |
+
<td align="center">0.076</td>
|
| 630 |
+
<td align="center">6.1</td>
|
| 631 |
+
<td align="center">56.4</td>
|
| 632 |
+
<td align="center">66.1</td>
|
| 633 |
+
<td align="center">138363331</td>
|
| 634 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Keypoints/keypoint_rcnn_R_101_FPN_3x/138363331/model_final_997cc7.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Keypoints/keypoint_rcnn_R_101_FPN_3x/138363331/metrics.json">metrics</a></td>
|
| 635 |
+
</tr>
|
| 636 |
+
<!-- ROW: keypoint_rcnn_X_101_32x8d_FPN_3x -->
|
| 637 |
+
<tr><td align="left"><a href="configs/COCO-Keypoints/keypoint_rcnn_X_101_32x8d_FPN_3x.yaml">X101-FPN</a></td>
|
| 638 |
+
<td align="center">3x</td>
|
| 639 |
+
<td align="center">0.738</td>
|
| 640 |
+
<td align="center">0.121</td>
|
| 641 |
+
<td align="center">8.7</td>
|
| 642 |
+
<td align="center">57.3</td>
|
| 643 |
+
<td align="center">66.0</td>
|
| 644 |
+
<td align="center">139686956</td>
|
| 645 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Keypoints/keypoint_rcnn_X_101_32x8d_FPN_3x/139686956/model_final_5ad38f.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-Keypoints/keypoint_rcnn_X_101_32x8d_FPN_3x/139686956/metrics.json">metrics</a></td>
|
| 646 |
+
</tr>
|
| 647 |
+
</tbody></table>
|
| 648 |
+
|
| 649 |
+
### COCO Panoptic Segmentation Baselines with Panoptic FPN
|
| 650 |
+
<!--
|
| 651 |
+
./gen_html_table.py --config 'COCO-PanopticSegmentation/*50*' 'COCO-PanopticSegmentation/*101*' --name R50-FPN R50-FPN R101-FPN --fields lr_sched train_speed inference_speed mem box_AP mask_AP PQ
|
| 652 |
+
-->
|
| 653 |
+
|
| 654 |
+
|
| 655 |
+
<table><tbody>
|
| 656 |
+
<!-- START TABLE -->
|
| 657 |
+
<!-- TABLE HEADER -->
|
| 658 |
+
<th valign="bottom">Name</th>
|
| 659 |
+
<th valign="bottom">lr<br/>sched</th>
|
| 660 |
+
<th valign="bottom">train<br/>time<br/>(s/iter)</th>
|
| 661 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 662 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 663 |
+
<th valign="bottom">box<br/>AP</th>
|
| 664 |
+
<th valign="bottom">mask<br/>AP</th>
|
| 665 |
+
<th valign="bottom">PQ</th>
|
| 666 |
+
<th valign="bottom">model id</th>
|
| 667 |
+
<th valign="bottom">download</th>
|
| 668 |
+
<!-- TABLE BODY -->
|
| 669 |
+
<!-- ROW: panoptic_fpn_R_50_1x -->
|
| 670 |
+
<tr><td align="left"><a href="configs/COCO-PanopticSegmentation/panoptic_fpn_R_50_1x.yaml">R50-FPN</a></td>
|
| 671 |
+
<td align="center">1x</td>
|
| 672 |
+
<td align="center">0.304</td>
|
| 673 |
+
<td align="center">0.053</td>
|
| 674 |
+
<td align="center">4.8</td>
|
| 675 |
+
<td align="center">37.6</td>
|
| 676 |
+
<td align="center">34.7</td>
|
| 677 |
+
<td align="center">39.4</td>
|
| 678 |
+
<td align="center">139514544</td>
|
| 679 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-PanopticSegmentation/panoptic_fpn_R_50_1x/139514544/model_final_dbfeb4.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-PanopticSegmentation/panoptic_fpn_R_50_1x/139514544/metrics.json">metrics</a></td>
|
| 680 |
+
</tr>
|
| 681 |
+
<!-- ROW: panoptic_fpn_R_50_3x -->
|
| 682 |
+
<tr><td align="left"><a href="configs/COCO-PanopticSegmentation/panoptic_fpn_R_50_3x.yaml">R50-FPN</a></td>
|
| 683 |
+
<td align="center">3x</td>
|
| 684 |
+
<td align="center">0.302</td>
|
| 685 |
+
<td align="center">0.053</td>
|
| 686 |
+
<td align="center">4.8</td>
|
| 687 |
+
<td align="center">40.0</td>
|
| 688 |
+
<td align="center">36.5</td>
|
| 689 |
+
<td align="center">41.5</td>
|
| 690 |
+
<td align="center">139514569</td>
|
| 691 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-PanopticSegmentation/panoptic_fpn_R_50_3x/139514569/model_final_c10459.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-PanopticSegmentation/panoptic_fpn_R_50_3x/139514569/metrics.json">metrics</a></td>
|
| 692 |
+
</tr>
|
| 693 |
+
<!-- ROW: panoptic_fpn_R_101_3x -->
|
| 694 |
+
<tr><td align="left"><a href="configs/COCO-PanopticSegmentation/panoptic_fpn_R_101_3x.yaml">R101-FPN</a></td>
|
| 695 |
+
<td align="center">3x</td>
|
| 696 |
+
<td align="center">0.392</td>
|
| 697 |
+
<td align="center">0.066</td>
|
| 698 |
+
<td align="center">6.0</td>
|
| 699 |
+
<td align="center">42.4</td>
|
| 700 |
+
<td align="center">38.5</td>
|
| 701 |
+
<td align="center">43.0</td>
|
| 702 |
+
<td align="center">139514519</td>
|
| 703 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-PanopticSegmentation/panoptic_fpn_R_101_3x/139514519/model_final_cafdb1.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-PanopticSegmentation/panoptic_fpn_R_101_3x/139514519/metrics.json">metrics</a></td>
|
| 704 |
+
</tr>
|
| 705 |
+
</tbody></table>
|
| 706 |
+
|
| 707 |
+
|
| 708 |
+
### LVIS Instance Segmentation Baselines with Mask R-CNN
|
| 709 |
+
|
| 710 |
+
Mask R-CNN baselines on the [LVIS dataset](https://lvisdataset.org), v0.5.
|
| 711 |
+
These baselines are described in Table 3(c) of the [LVIS paper](https://arxiv.org/abs/1908.03195).
|
| 712 |
+
|
| 713 |
+
NOTE: the 1x schedule here has the same amount of __iterations__ as the COCO 1x baselines.
|
| 714 |
+
They are roughly 24 epochs of LVISv0.5 data.
|
| 715 |
+
The final results of these configs have large variance across different runs.
|
| 716 |
+
|
| 717 |
+
<!--
|
| 718 |
+
./gen_html_table.py --config 'LVISv0.5-InstanceSegmentation/mask*50*' 'LVISv0.5-InstanceSegmentation/mask*101*' --name R50-FPN R101-FPN X101-FPN --fields lr_sched train_speed inference_speed mem box_AP mask_AP
|
| 719 |
+
-->
|
| 720 |
+
|
| 721 |
+
|
| 722 |
+
<table><tbody>
|
| 723 |
+
<!-- START TABLE -->
|
| 724 |
+
<!-- TABLE HEADER -->
|
| 725 |
+
<th valign="bottom">Name</th>
|
| 726 |
+
<th valign="bottom">lr<br/>sched</th>
|
| 727 |
+
<th valign="bottom">train<br/>time<br/>(s/iter)</th>
|
| 728 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 729 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 730 |
+
<th valign="bottom">box<br/>AP</th>
|
| 731 |
+
<th valign="bottom">mask<br/>AP</th>
|
| 732 |
+
<th valign="bottom">model id</th>
|
| 733 |
+
<th valign="bottom">download</th>
|
| 734 |
+
<!-- TABLE BODY -->
|
| 735 |
+
<!-- ROW: mask_rcnn_R_50_FPN_1x -->
|
| 736 |
+
<tr><td align="left"><a href="configs/LVISv0.5-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml">R50-FPN</a></td>
|
| 737 |
+
<td align="center">1x</td>
|
| 738 |
+
<td align="center">0.292</td>
|
| 739 |
+
<td align="center">0.107</td>
|
| 740 |
+
<td align="center">7.1</td>
|
| 741 |
+
<td align="center">23.6</td>
|
| 742 |
+
<td align="center">24.4</td>
|
| 743 |
+
<td align="center">144219072</td>
|
| 744 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/LVISv0.5-InstanceSegmentation/mask_rcnn_R_50_FPN_1x/144219072/model_final_571f7c.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/LVISv0.5-InstanceSegmentation/mask_rcnn_R_50_FPN_1x/144219072/metrics.json">metrics</a></td>
|
| 745 |
+
</tr>
|
| 746 |
+
<!-- ROW: mask_rcnn_R_101_FPN_1x -->
|
| 747 |
+
<tr><td align="left"><a href="configs/LVISv0.5-InstanceSegmentation/mask_rcnn_R_101_FPN_1x.yaml">R101-FPN</a></td>
|
| 748 |
+
<td align="center">1x</td>
|
| 749 |
+
<td align="center">0.371</td>
|
| 750 |
+
<td align="center">0.114</td>
|
| 751 |
+
<td align="center">7.8</td>
|
| 752 |
+
<td align="center">25.6</td>
|
| 753 |
+
<td align="center">25.9</td>
|
| 754 |
+
<td align="center">144219035</td>
|
| 755 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/LVISv0.5-InstanceSegmentation/mask_rcnn_R_101_FPN_1x/144219035/model_final_824ab5.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/LVISv0.5-InstanceSegmentation/mask_rcnn_R_101_FPN_1x/144219035/metrics.json">metrics</a></td>
|
| 756 |
+
</tr>
|
| 757 |
+
<!-- ROW: mask_rcnn_X_101_32x8d_FPN_1x -->
|
| 758 |
+
<tr><td align="left"><a href="configs/LVISv0.5-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_1x.yaml">X101-FPN</a></td>
|
| 759 |
+
<td align="center">1x</td>
|
| 760 |
+
<td align="center">0.712</td>
|
| 761 |
+
<td align="center">0.151</td>
|
| 762 |
+
<td align="center">10.2</td>
|
| 763 |
+
<td align="center">26.7</td>
|
| 764 |
+
<td align="center">27.1</td>
|
| 765 |
+
<td align="center">144219108</td>
|
| 766 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/LVISv0.5-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_1x/144219108/model_final_5e3439.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/LVISv0.5-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_1x/144219108/metrics.json">metrics</a></td>
|
| 767 |
+
</tr>
|
| 768 |
+
</tbody></table>
|
| 769 |
+
|
| 770 |
+
|
| 771 |
+
|
| 772 |
+
### Cityscapes & Pascal VOC Baselines
|
| 773 |
+
|
| 774 |
+
Simple baselines for
|
| 775 |
+
* Mask R-CNN on Cityscapes instance segmentation (initialized from COCO pre-training, then trained on Cityscapes fine annotations only)
|
| 776 |
+
* Faster R-CNN on PASCAL VOC object detection (trained on VOC 2007 train+val + VOC 2012 train+val, tested on VOC 2007 using 11-point interpolated AP)
|
| 777 |
+
|
| 778 |
+
<!--
|
| 779 |
+
./gen_html_table.py --config 'Cityscapes/*' 'PascalVOC-Detection/*' --name "R50-FPN, Cityscapes" "R50-C4, VOC" --fields train_speed inference_speed mem box_AP box_AP50 mask_AP
|
| 780 |
+
-->
|
| 781 |
+
|
| 782 |
+
|
| 783 |
+
<table><tbody>
|
| 784 |
+
<!-- START TABLE -->
|
| 785 |
+
<!-- TABLE HEADER -->
|
| 786 |
+
<th valign="bottom">Name</th>
|
| 787 |
+
<th valign="bottom">train<br/>time<br/>(s/iter)</th>
|
| 788 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 789 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 790 |
+
<th valign="bottom">box<br/>AP</th>
|
| 791 |
+
<th valign="bottom">box<br/>AP50</th>
|
| 792 |
+
<th valign="bottom">mask<br/>AP</th>
|
| 793 |
+
<th valign="bottom">model id</th>
|
| 794 |
+
<th valign="bottom">download</th>
|
| 795 |
+
<!-- TABLE BODY -->
|
| 796 |
+
<!-- ROW: mask_rcnn_R_50_FPN -->
|
| 797 |
+
<tr><td align="left"><a href="configs/Cityscapes/mask_rcnn_R_50_FPN.yaml">R50-FPN, Cityscapes</a></td>
|
| 798 |
+
<td align="center">0.240</td>
|
| 799 |
+
<td align="center">0.078</td>
|
| 800 |
+
<td align="center">4.4</td>
|
| 801 |
+
<td align="center"></td>
|
| 802 |
+
<td align="center"></td>
|
| 803 |
+
<td align="center">36.5</td>
|
| 804 |
+
<td align="center">142423278</td>
|
| 805 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Cityscapes/mask_rcnn_R_50_FPN/142423278/model_final_af9cf5.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Cityscapes/mask_rcnn_R_50_FPN/142423278/metrics.json">metrics</a></td>
|
| 806 |
+
</tr>
|
| 807 |
+
<!-- ROW: faster_rcnn_R_50_C4 -->
|
| 808 |
+
<tr><td align="left"><a href="configs/PascalVOC-Detection/faster_rcnn_R_50_C4.yaml">R50-C4, VOC</a></td>
|
| 809 |
+
<td align="center">0.537</td>
|
| 810 |
+
<td align="center">0.081</td>
|
| 811 |
+
<td align="center">4.8</td>
|
| 812 |
+
<td align="center">51.9</td>
|
| 813 |
+
<td align="center">80.3</td>
|
| 814 |
+
<td align="center"></td>
|
| 815 |
+
<td align="center">142202221</td>
|
| 816 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/PascalVOC-Detection/faster_rcnn_R_50_C4/142202221/model_final_b1acc2.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/PascalVOC-Detection/faster_rcnn_R_50_C4/142202221/metrics.json">metrics</a></td>
|
| 817 |
+
</tr>
|
| 818 |
+
</tbody></table>
|
| 819 |
+
|
| 820 |
+
|
| 821 |
+
|
| 822 |
+
### Other Settings
|
| 823 |
+
|
| 824 |
+
Ablations for Deformable Conv and Cascade R-CNN:
|
| 825 |
+
|
| 826 |
+
<!--
|
| 827 |
+
./gen_html_table.py --config 'COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml' 'Misc/*R_50_FPN_1x_dconv*' 'Misc/cascade*1x.yaml' 'COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml' 'Misc/*R_50_FPN_3x_dconv*' 'Misc/cascade*3x.yaml' --name "Baseline R50-FPN" "Deformable Conv" "Cascade R-CNN" "Baseline R50-FPN" "Deformable Conv" "Cascade R-CNN" --fields lr_sched train_speed inference_speed mem box_AP mask_AP
|
| 828 |
+
-->
|
| 829 |
+
|
| 830 |
+
|
| 831 |
+
<table><tbody>
|
| 832 |
+
<!-- START TABLE -->
|
| 833 |
+
<!-- TABLE HEADER -->
|
| 834 |
+
<th valign="bottom">Name</th>
|
| 835 |
+
<th valign="bottom">lr<br/>sched</th>
|
| 836 |
+
<th valign="bottom">train<br/>time<br/>(s/iter)</th>
|
| 837 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 838 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 839 |
+
<th valign="bottom">box<br/>AP</th>
|
| 840 |
+
<th valign="bottom">mask<br/>AP</th>
|
| 841 |
+
<th valign="bottom">model id</th>
|
| 842 |
+
<th valign="bottom">download</th>
|
| 843 |
+
<!-- TABLE BODY -->
|
| 844 |
+
<!-- ROW: mask_rcnn_R_50_FPN_1x -->
|
| 845 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml">Baseline R50-FPN</a></td>
|
| 846 |
+
<td align="center">1x</td>
|
| 847 |
+
<td align="center">0.261</td>
|
| 848 |
+
<td align="center">0.043</td>
|
| 849 |
+
<td align="center">3.4</td>
|
| 850 |
+
<td align="center">38.6</td>
|
| 851 |
+
<td align="center">35.2</td>
|
| 852 |
+
<td align="center">137260431</td>
|
| 853 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x/137260431/model_final_a54504.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x/137260431/metrics.json">metrics</a></td>
|
| 854 |
+
</tr>
|
| 855 |
+
<!-- ROW: mask_rcnn_R_50_FPN_1x_dconv_c3-c5 -->
|
| 856 |
+
<tr><td align="left"><a href="configs/Misc/mask_rcnn_R_50_FPN_1x_dconv_c3-c5.yaml">Deformable Conv</a></td>
|
| 857 |
+
<td align="center">1x</td>
|
| 858 |
+
<td align="center">0.342</td>
|
| 859 |
+
<td align="center">0.048</td>
|
| 860 |
+
<td align="center">3.5</td>
|
| 861 |
+
<td align="center">41.5</td>
|
| 862 |
+
<td align="center">37.5</td>
|
| 863 |
+
<td align="center">138602867</td>
|
| 864 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/mask_rcnn_R_50_FPN_1x_dconv_c3-c5/138602867/model_final_65c703.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/mask_rcnn_R_50_FPN_1x_dconv_c3-c5/138602867/metrics.json">metrics</a></td>
|
| 865 |
+
</tr>
|
| 866 |
+
<!-- ROW: cascade_mask_rcnn_R_50_FPN_1x -->
|
| 867 |
+
<tr><td align="left"><a href="configs/Misc/cascade_mask_rcnn_R_50_FPN_1x.yaml">Cascade R-CNN</a></td>
|
| 868 |
+
<td align="center">1x</td>
|
| 869 |
+
<td align="center">0.317</td>
|
| 870 |
+
<td align="center">0.052</td>
|
| 871 |
+
<td align="center">4.0</td>
|
| 872 |
+
<td align="center">42.1</td>
|
| 873 |
+
<td align="center">36.4</td>
|
| 874 |
+
<td align="center">138602847</td>
|
| 875 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/cascade_mask_rcnn_R_50_FPN_1x/138602847/model_final_e9d89b.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/cascade_mask_rcnn_R_50_FPN_1x/138602847/metrics.json">metrics</a></td>
|
| 876 |
+
</tr>
|
| 877 |
+
<!-- ROW: mask_rcnn_R_50_FPN_3x -->
|
| 878 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml">Baseline R50-FPN</a></td>
|
| 879 |
+
<td align="center">3x</td>
|
| 880 |
+
<td align="center">0.261</td>
|
| 881 |
+
<td align="center">0.043</td>
|
| 882 |
+
<td align="center">3.4</td>
|
| 883 |
+
<td align="center">41.0</td>
|
| 884 |
+
<td align="center">37.2</td>
|
| 885 |
+
<td align="center">137849600</td>
|
| 886 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x/137849600/model_final_f10217.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x/137849600/metrics.json">metrics</a></td>
|
| 887 |
+
</tr>
|
| 888 |
+
<!-- ROW: mask_rcnn_R_50_FPN_3x_dconv_c3-c5 -->
|
| 889 |
+
<tr><td align="left"><a href="configs/Misc/mask_rcnn_R_50_FPN_3x_dconv_c3-c5.yaml">Deformable Conv</a></td>
|
| 890 |
+
<td align="center">3x</td>
|
| 891 |
+
<td align="center">0.349</td>
|
| 892 |
+
<td align="center">0.047</td>
|
| 893 |
+
<td align="center">3.5</td>
|
| 894 |
+
<td align="center">42.7</td>
|
| 895 |
+
<td align="center">38.5</td>
|
| 896 |
+
<td align="center">144998336</td>
|
| 897 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/mask_rcnn_R_50_FPN_3x_dconv_c3-c5/144998336/model_final_821d0b.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/mask_rcnn_R_50_FPN_3x_dconv_c3-c5/144998336/metrics.json">metrics</a></td>
|
| 898 |
+
</tr>
|
| 899 |
+
<!-- ROW: cascade_mask_rcnn_R_50_FPN_3x -->
|
| 900 |
+
<tr><td align="left"><a href="configs/Misc/cascade_mask_rcnn_R_50_FPN_3x.yaml">Cascade R-CNN</a></td>
|
| 901 |
+
<td align="center">3x</td>
|
| 902 |
+
<td align="center">0.328</td>
|
| 903 |
+
<td align="center">0.053</td>
|
| 904 |
+
<td align="center">4.0</td>
|
| 905 |
+
<td align="center">44.3</td>
|
| 906 |
+
<td align="center">38.5</td>
|
| 907 |
+
<td align="center">144998488</td>
|
| 908 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/cascade_mask_rcnn_R_50_FPN_3x/144998488/model_final_480dd8.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/cascade_mask_rcnn_R_50_FPN_3x/144998488/metrics.json">metrics</a></td>
|
| 909 |
+
</tr>
|
| 910 |
+
</tbody></table>
|
| 911 |
+
|
| 912 |
+
|
| 913 |
+
Ablations for normalization methods, and a few models trained from scratch following [Rethinking ImageNet Pre-training](https://arxiv.org/abs/1811.08883).
|
| 914 |
+
(Note: The baseline uses `2fc` head while the others use [`4conv1fc` head](https://arxiv.org/abs/1803.08494))
|
| 915 |
+
<!--
|
| 916 |
+
./gen_html_table.py --config 'COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml' 'Misc/mask*50_FPN_3x_gn.yaml' 'Misc/mask*50_FPN_3x_syncbn.yaml' 'Misc/scratch*' --name "Baseline R50-FPN" "GN" "SyncBN" "GN (from scratch)" "GN (from scratch)" "SyncBN (from scratch)" --fields lr_sched train_speed inference_speed mem box_AP mask_AP
|
| 917 |
+
-->
|
| 918 |
+
|
| 919 |
+
|
| 920 |
+
<table><tbody>
|
| 921 |
+
<!-- START TABLE -->
|
| 922 |
+
<!-- TABLE HEADER -->
|
| 923 |
+
<th valign="bottom">Name</th>
|
| 924 |
+
<th valign="bottom">lr<br/>sched</th>
|
| 925 |
+
<th valign="bottom">train<br/>time<br/>(s/iter)</th>
|
| 926 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 927 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 928 |
+
<th valign="bottom">box<br/>AP</th>
|
| 929 |
+
<th valign="bottom">mask<br/>AP</th>
|
| 930 |
+
<th valign="bottom">model id</th>
|
| 931 |
+
<th valign="bottom">download</th>
|
| 932 |
+
<!-- TABLE BODY -->
|
| 933 |
+
<!-- ROW: mask_rcnn_R_50_FPN_3x -->
|
| 934 |
+
<tr><td align="left"><a href="configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml">Baseline R50-FPN</a></td>
|
| 935 |
+
<td align="center">3x</td>
|
| 936 |
+
<td align="center">0.261</td>
|
| 937 |
+
<td align="center">0.043</td>
|
| 938 |
+
<td align="center">3.4</td>
|
| 939 |
+
<td align="center">41.0</td>
|
| 940 |
+
<td align="center">37.2</td>
|
| 941 |
+
<td align="center">137849600</td>
|
| 942 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x/137849600/model_final_f10217.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x/137849600/metrics.json">metrics</a></td>
|
| 943 |
+
</tr>
|
| 944 |
+
<!-- ROW: mask_rcnn_R_50_FPN_3x_gn -->
|
| 945 |
+
<tr><td align="left"><a href="configs/Misc/mask_rcnn_R_50_FPN_3x_gn.yaml">GN</a></td>
|
| 946 |
+
<td align="center">3x</td>
|
| 947 |
+
<td align="center">0.309</td>
|
| 948 |
+
<td align="center">0.060</td>
|
| 949 |
+
<td align="center">5.6</td>
|
| 950 |
+
<td align="center">42.6</td>
|
| 951 |
+
<td align="center">38.6</td>
|
| 952 |
+
<td align="center">138602888</td>
|
| 953 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/mask_rcnn_R_50_FPN_3x_gn/138602888/model_final_dc5d9e.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/mask_rcnn_R_50_FPN_3x_gn/138602888/metrics.json">metrics</a></td>
|
| 954 |
+
</tr>
|
| 955 |
+
<!-- ROW: mask_rcnn_R_50_FPN_3x_syncbn -->
|
| 956 |
+
<tr><td align="left"><a href="configs/Misc/mask_rcnn_R_50_FPN_3x_syncbn.yaml">SyncBN</a></td>
|
| 957 |
+
<td align="center">3x</td>
|
| 958 |
+
<td align="center">0.345</td>
|
| 959 |
+
<td align="center">0.053</td>
|
| 960 |
+
<td align="center">5.5</td>
|
| 961 |
+
<td align="center">41.9</td>
|
| 962 |
+
<td align="center">37.8</td>
|
| 963 |
+
<td align="center">169527823</td>
|
| 964 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/mask_rcnn_R_50_FPN_3x_syncbn/169527823/model_final_3b3c51.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/mask_rcnn_R_50_FPN_3x_syncbn/169527823/metrics.json">metrics</a></td>
|
| 965 |
+
</tr>
|
| 966 |
+
<!-- ROW: scratch_mask_rcnn_R_50_FPN_3x_gn -->
|
| 967 |
+
<tr><td align="left"><a href="configs/Misc/scratch_mask_rcnn_R_50_FPN_3x_gn.yaml">GN (from scratch)</a></td>
|
| 968 |
+
<td align="center">3x</td>
|
| 969 |
+
<td align="center">0.338</td>
|
| 970 |
+
<td align="center">0.061</td>
|
| 971 |
+
<td align="center">7.2</td>
|
| 972 |
+
<td align="center">39.9</td>
|
| 973 |
+
<td align="center">36.6</td>
|
| 974 |
+
<td align="center">138602908</td>
|
| 975 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/scratch_mask_rcnn_R_50_FPN_3x_gn/138602908/model_final_01ca85.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/scratch_mask_rcnn_R_50_FPN_3x_gn/138602908/metrics.json">metrics</a></td>
|
| 976 |
+
</tr>
|
| 977 |
+
<!-- ROW: scratch_mask_rcnn_R_50_FPN_9x_gn -->
|
| 978 |
+
<tr><td align="left"><a href="configs/Misc/scratch_mask_rcnn_R_50_FPN_9x_gn.yaml">GN (from scratch)</a></td>
|
| 979 |
+
<td align="center">9x</td>
|
| 980 |
+
<td align="center">N/A</td>
|
| 981 |
+
<td align="center">0.061</td>
|
| 982 |
+
<td align="center">7.2</td>
|
| 983 |
+
<td align="center">43.7</td>
|
| 984 |
+
<td align="center">39.6</td>
|
| 985 |
+
<td align="center">183808979</td>
|
| 986 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/scratch_mask_rcnn_R_50_FPN_9x_gn/183808979/model_final_da7b4c.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/scratch_mask_rcnn_R_50_FPN_9x_gn/183808979/metrics.json">metrics</a></td>
|
| 987 |
+
</tr>
|
| 988 |
+
<!-- ROW: scratch_mask_rcnn_R_50_FPN_9x_syncbn -->
|
| 989 |
+
<tr><td align="left"><a href="configs/Misc/scratch_mask_rcnn_R_50_FPN_9x_syncbn.yaml">SyncBN (from scratch)</a></td>
|
| 990 |
+
<td align="center">9x</td>
|
| 991 |
+
<td align="center">N/A</td>
|
| 992 |
+
<td align="center">0.055</td>
|
| 993 |
+
<td align="center">7.2</td>
|
| 994 |
+
<td align="center">43.6</td>
|
| 995 |
+
<td align="center">39.3</td>
|
| 996 |
+
<td align="center">184226666</td>
|
| 997 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/scratch_mask_rcnn_R_50_FPN_9x_syncbn/184226666/model_final_5ce33e.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/scratch_mask_rcnn_R_50_FPN_9x_syncbn/184226666/metrics.json">metrics</a></td>
|
| 998 |
+
</tr>
|
| 999 |
+
</tbody></table>
|
| 1000 |
+
|
| 1001 |
+
|
| 1002 |
+
A few very large models trained for a long time, for demo purposes. They are trained using multiple machines:
|
| 1003 |
+
|
| 1004 |
+
<!--
|
| 1005 |
+
./gen_html_table.py --config 'Misc/panoptic_*dconv*' 'Misc/cascade_*152*' --name "Panoptic FPN R101" "Mask R-CNN X152" --fields inference_speed mem box_AP mask_AP PQ
|
| 1006 |
+
# manually add TTA results
|
| 1007 |
+
-->
|
| 1008 |
+
|
| 1009 |
+
|
| 1010 |
+
<table><tbody>
|
| 1011 |
+
<!-- START TABLE -->
|
| 1012 |
+
<!-- TABLE HEADER -->
|
| 1013 |
+
<th valign="bottom">Name</th>
|
| 1014 |
+
<th valign="bottom">inference<br/>time<br/>(s/im)</th>
|
| 1015 |
+
<th valign="bottom">train<br/>mem<br/>(GB)</th>
|
| 1016 |
+
<th valign="bottom">box<br/>AP</th>
|
| 1017 |
+
<th valign="bottom">mask<br/>AP</th>
|
| 1018 |
+
<th valign="bottom">PQ</th>
|
| 1019 |
+
<th valign="bottom">model id</th>
|
| 1020 |
+
<th valign="bottom">download</th>
|
| 1021 |
+
<!-- TABLE BODY -->
|
| 1022 |
+
<!-- ROW: panoptic_fpn_R_101_dconv_cascade_gn_3x -->
|
| 1023 |
+
<tr><td align="left"><a href="configs/Misc/panoptic_fpn_R_101_dconv_cascade_gn_3x.yaml">Panoptic FPN R101</a></td>
|
| 1024 |
+
<td align="center">0.098</td>
|
| 1025 |
+
<td align="center">11.4</td>
|
| 1026 |
+
<td align="center">47.4</td>
|
| 1027 |
+
<td align="center">41.3</td>
|
| 1028 |
+
<td align="center">46.1</td>
|
| 1029 |
+
<td align="center">139797668</td>
|
| 1030 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/panoptic_fpn_R_101_dconv_cascade_gn_3x/139797668/model_final_be35db.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/panoptic_fpn_R_101_dconv_cascade_gn_3x/139797668/metrics.json">metrics</a></td>
|
| 1031 |
+
</tr>
|
| 1032 |
+
<!-- ROW: cascade_mask_rcnn_X_152_32x8d_FPN_IN5k_gn_dconv -->
|
| 1033 |
+
<tr><td align="left"><a href="configs/Misc/cascade_mask_rcnn_X_152_32x8d_FPN_IN5k_gn_dconv.yaml">Mask R-CNN X152</a></td>
|
| 1034 |
+
<td align="center">0.234</td>
|
| 1035 |
+
<td align="center">15.1</td>
|
| 1036 |
+
<td align="center">50.2</td>
|
| 1037 |
+
<td align="center">44.0</td>
|
| 1038 |
+
<td align="center"></td>
|
| 1039 |
+
<td align="center">18131413</td>
|
| 1040 |
+
<td align="center"><a href="https://dl.fbaipublicfiles.com/detectron2/Misc/cascade_mask_rcnn_X_152_32x8d_FPN_IN5k_gn_dconv/18131413/model_0039999_e76410.pkl">model</a> | <a href="https://dl.fbaipublicfiles.com/detectron2/Misc/cascade_mask_rcnn_X_152_32x8d_FPN_IN5k_gn_dconv/18131413/metrics.json">metrics</a></td>
|
| 1041 |
+
</tr>
|
| 1042 |
+
<!-- ROW: TTA cascade_mask_rcnn_X_152_32x8d_FPN_IN5k_gn_dconv -->
|
| 1043 |
+
<tr><td align="left">above + test-time aug.</td>
|
| 1044 |
+
<td align="center"></td>
|
| 1045 |
+
<td align="center"></td>
|
| 1046 |
+
<td align="center">51.9</td>
|
| 1047 |
+
<td align="center">45.9</td>
|
| 1048 |
+
<td align="center"></td>
|
| 1049 |
+
<td align="center"></td>
|
| 1050 |
+
<td align="center"></td>
|
| 1051 |
+
</tr>
|
| 1052 |
+
</tbody></table>
|
approach/ovod/detectron2/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<img src=".github/Detectron2-Logo-Horz.svg" width="300" >
|
| 2 |
+
|
| 3 |
+
<a href="https://opensource.facebook.com/support-ukraine">
|
| 4 |
+
<img src="https://img.shields.io/badge/Support-Ukraine-FFD500?style=flat&labelColor=005BBB" alt="Support Ukraine - Help Provide Humanitarian Aid to Ukraine." />
|
| 5 |
+
</a>
|
| 6 |
+
|
| 7 |
+
Detectron2 is Facebook AI Research's next generation library
|
| 8 |
+
that provides state-of-the-art detection and segmentation algorithms.
|
| 9 |
+
It is the successor of
|
| 10 |
+
[Detectron](https://github.com/facebookresearch/Detectron/)
|
| 11 |
+
and [maskrcnn-benchmark](https://github.com/facebookresearch/maskrcnn-benchmark/).
|
| 12 |
+
It supports a number of computer vision research projects and production applications in Facebook.
|
| 13 |
+
|
| 14 |
+
<div align="center">
|
| 15 |
+
<img src="https://user-images.githubusercontent.com/1381301/66535560-d3422200-eace-11e9-9123-5535d469db19.png"/>
|
| 16 |
+
</div>
|
| 17 |
+
<br>
|
| 18 |
+
|
| 19 |
+
## Learn More about Detectron2
|
| 20 |
+
|
| 21 |
+
Explain Like I’m 5: Detectron2 | Using Machine Learning with Detectron2
|
| 22 |
+
:-------------------------:|:-------------------------:
|
| 23 |
+
[](https://www.youtube.com/watch?v=1oq1Ye7dFqc) | [](https://www.youtube.com/watch?v=eUSgtfK4ivk)
|
| 24 |
+
|
| 25 |
+
## What's New
|
| 26 |
+
* Includes new capabilities such as panoptic segmentation, Densepose, Cascade R-CNN, rotated bounding boxes, PointRend,
|
| 27 |
+
DeepLab, ViTDet, MViTv2 etc.
|
| 28 |
+
* Used as a library to support building [research projects](projects/) on top of it.
|
| 29 |
+
* Models can be exported to TorchScript format or Caffe2 format for deployment.
|
| 30 |
+
* It [trains much faster](https://detectron2.readthedocs.io/notes/benchmarks.html).
|
| 31 |
+
|
| 32 |
+
See our [blog post](https://ai.facebook.com/blog/-detectron2-a-pytorch-based-modular-object-detection-library-/)
|
| 33 |
+
to see more demos and learn about detectron2.
|
| 34 |
+
|
| 35 |
+
## Installation
|
| 36 |
+
|
| 37 |
+
See [installation instructions](https://detectron2.readthedocs.io/tutorials/install.html).
|
| 38 |
+
|
| 39 |
+
## Getting Started
|
| 40 |
+
|
| 41 |
+
See [Getting Started with Detectron2](https://detectron2.readthedocs.io/tutorials/getting_started.html),
|
| 42 |
+
and the [Colab Notebook](https://colab.research.google.com/drive/16jcaJoc6bCFAQ96jDe2HwtXj7BMD_-m5)
|
| 43 |
+
to learn about basic usage.
|
| 44 |
+
|
| 45 |
+
Learn more at our [documentation](https://detectron2.readthedocs.org).
|
| 46 |
+
And see [projects/](projects/) for some projects that are built on top of detectron2.
|
| 47 |
+
|
| 48 |
+
## Model Zoo and Baselines
|
| 49 |
+
|
| 50 |
+
We provide a large set of baseline results and trained models available for download in the [Detectron2 Model Zoo](MODEL_ZOO.md).
|
| 51 |
+
|
| 52 |
+
## License
|
| 53 |
+
|
| 54 |
+
Detectron2 is released under the [Apache 2.0 license](LICENSE).
|
| 55 |
+
|
| 56 |
+
## Citing Detectron2
|
| 57 |
+
|
| 58 |
+
If you use Detectron2 in your research or wish to refer to the baseline results published in the [Model Zoo](MODEL_ZOO.md), please use the following BibTeX entry.
|
| 59 |
+
|
| 60 |
+
```BibTeX
|
| 61 |
+
@misc{wu2019detectron2,
|
| 62 |
+
author = {Yuxin Wu and Alexander Kirillov and Francisco Massa and
|
| 63 |
+
Wan-Yen Lo and Ross Girshick},
|
| 64 |
+
title = {Detectron2},
|
| 65 |
+
howpublished = {\url{https://github.com/facebookresearch/detectron2}},
|
| 66 |
+
year = {2019}
|
| 67 |
+
}
|
| 68 |
+
```
|
approach/ovod/detectron2/setup.cfg
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[isort]
|
| 2 |
+
line_length=100
|
| 3 |
+
multi_line_output=3
|
| 4 |
+
include_trailing_comma=True
|
| 5 |
+
known_standard_library=numpy,setuptools,mock
|
| 6 |
+
skip=./datasets,docs
|
| 7 |
+
skip_glob=*/__init__.py,**/configs/**,**/tests/config/**
|
| 8 |
+
known_myself=detectron2
|
| 9 |
+
known_third_party=fvcore,matplotlib,cv2,torch,torchvision,PIL,pycocotools,yacs,termcolor,cityscapesscripts,tabulate,tqdm,scipy,lvis,psutil,pkg_resources,caffe2,onnx,panopticapi,black,isort,av,iopath,omegaconf,hydra,yaml,pydoc,submitit,cloudpickle,packaging
|
| 10 |
+
no_lines_before=STDLIB,THIRDPARTY
|
| 11 |
+
sections=FUTURE,STDLIB,THIRDPARTY,myself,FIRSTPARTY,LOCALFOLDER
|
| 12 |
+
default_section=FIRSTPARTY
|
| 13 |
+
|
| 14 |
+
[mypy]
|
| 15 |
+
python_version=3.7
|
| 16 |
+
ignore_missing_imports = True
|
| 17 |
+
warn_unused_configs = True
|
| 18 |
+
disallow_untyped_defs = True
|
| 19 |
+
check_untyped_defs = True
|
| 20 |
+
warn_unused_ignores = True
|
| 21 |
+
warn_redundant_casts = True
|
| 22 |
+
show_column_numbers = True
|
| 23 |
+
follow_imports = silent
|
| 24 |
+
allow_redefinition = True
|
| 25 |
+
; Require all functions to be annotated
|
| 26 |
+
disallow_incomplete_defs = True
|
approach/ovod/detectron2/setup.py
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
| 3 |
+
|
| 4 |
+
import glob
|
| 5 |
+
import os
|
| 6 |
+
import shutil
|
| 7 |
+
from os import path
|
| 8 |
+
from setuptools import find_packages, setup
|
| 9 |
+
from typing import List
|
| 10 |
+
import torch
|
| 11 |
+
from torch.utils.cpp_extension import CUDA_HOME, CppExtension, CUDAExtension
|
| 12 |
+
|
| 13 |
+
torch_ver = [int(x) for x in torch.__version__.split(".")[:2]]
|
| 14 |
+
assert torch_ver >= [1, 8], "Requires PyTorch >= 1.8"
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def get_version():
|
| 18 |
+
init_py_path = path.join(path.abspath(path.dirname(__file__)), "detectron2", "__init__.py")
|
| 19 |
+
init_py = open(init_py_path, "r").readlines()
|
| 20 |
+
version_line = [l.strip() for l in init_py if l.startswith("__version__")][0]
|
| 21 |
+
version = version_line.split("=")[-1].strip().strip("'\"")
|
| 22 |
+
|
| 23 |
+
# The following is used to build release packages.
|
| 24 |
+
# Users should never use it.
|
| 25 |
+
suffix = os.getenv("D2_VERSION_SUFFIX", "")
|
| 26 |
+
version = version + suffix
|
| 27 |
+
if os.getenv("BUILD_NIGHTLY", "0") == "1":
|
| 28 |
+
from datetime import datetime
|
| 29 |
+
|
| 30 |
+
date_str = datetime.today().strftime("%y%m%d")
|
| 31 |
+
version = version + ".dev" + date_str
|
| 32 |
+
|
| 33 |
+
new_init_py = [l for l in init_py if not l.startswith("__version__")]
|
| 34 |
+
new_init_py.append('__version__ = "{}"\n'.format(version))
|
| 35 |
+
with open(init_py_path, "w") as f:
|
| 36 |
+
f.write("".join(new_init_py))
|
| 37 |
+
return version
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def get_extensions():
|
| 41 |
+
this_dir = path.dirname(path.abspath(__file__))
|
| 42 |
+
extensions_dir = path.join(this_dir, "detectron2", "layers", "csrc")
|
| 43 |
+
|
| 44 |
+
main_source = path.join(extensions_dir, "vision.cpp")
|
| 45 |
+
sources = glob.glob(path.join(extensions_dir, "**", "*.cpp"))
|
| 46 |
+
|
| 47 |
+
from torch.utils.cpp_extension import ROCM_HOME
|
| 48 |
+
|
| 49 |
+
is_rocm_pytorch = (
|
| 50 |
+
True if ((torch.version.hip is not None) and (ROCM_HOME is not None)) else False
|
| 51 |
+
)
|
| 52 |
+
if is_rocm_pytorch:
|
| 53 |
+
assert torch_ver >= [1, 8], "ROCM support requires PyTorch >= 1.8!"
|
| 54 |
+
|
| 55 |
+
# common code between cuda and rocm platforms, for hipify version [1,0,0] and later.
|
| 56 |
+
source_cuda = glob.glob(path.join(extensions_dir, "**", "*.cu")) + glob.glob(
|
| 57 |
+
path.join(extensions_dir, "*.cu")
|
| 58 |
+
)
|
| 59 |
+
sources = [main_source] + sources
|
| 60 |
+
|
| 61 |
+
extension = CppExtension
|
| 62 |
+
|
| 63 |
+
extra_compile_args = {"cxx": []}
|
| 64 |
+
define_macros = []
|
| 65 |
+
|
| 66 |
+
if (torch.cuda.is_available() and ((CUDA_HOME is not None) or is_rocm_pytorch)) or os.getenv(
|
| 67 |
+
"FORCE_CUDA", "0"
|
| 68 |
+
) == "1":
|
| 69 |
+
extension = CUDAExtension
|
| 70 |
+
sources += source_cuda
|
| 71 |
+
|
| 72 |
+
if not is_rocm_pytorch:
|
| 73 |
+
define_macros += [("WITH_CUDA", None)]
|
| 74 |
+
extra_compile_args["nvcc"] = [
|
| 75 |
+
"-O3",
|
| 76 |
+
"-DCUDA_HAS_FP16=1",
|
| 77 |
+
"-D__CUDA_NO_HALF_OPERATORS__",
|
| 78 |
+
"-D__CUDA_NO_HALF_CONVERSIONS__",
|
| 79 |
+
"-D__CUDA_NO_HALF2_OPERATORS__",
|
| 80 |
+
]
|
| 81 |
+
else:
|
| 82 |
+
define_macros += [("WITH_HIP", None)]
|
| 83 |
+
extra_compile_args["nvcc"] = []
|
| 84 |
+
|
| 85 |
+
if torch_ver < [1, 7]:
|
| 86 |
+
# supported by https://github.com/pytorch/pytorch/pull/43931
|
| 87 |
+
CC = os.environ.get("CC", None)
|
| 88 |
+
if CC is not None:
|
| 89 |
+
extra_compile_args["nvcc"].append("-ccbin={}".format(CC))
|
| 90 |
+
|
| 91 |
+
include_dirs = [extensions_dir]
|
| 92 |
+
|
| 93 |
+
ext_modules = [
|
| 94 |
+
extension(
|
| 95 |
+
"detectron2._C",
|
| 96 |
+
sources,
|
| 97 |
+
include_dirs=include_dirs,
|
| 98 |
+
define_macros=define_macros,
|
| 99 |
+
extra_compile_args=extra_compile_args,
|
| 100 |
+
)
|
| 101 |
+
]
|
| 102 |
+
|
| 103 |
+
return ext_modules
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
def get_model_zoo_configs() -> List[str]:
|
| 107 |
+
"""
|
| 108 |
+
Return a list of configs to include in package for model zoo. Copy over these configs inside
|
| 109 |
+
detectron2/model_zoo.
|
| 110 |
+
"""
|
| 111 |
+
|
| 112 |
+
# Use absolute paths while symlinking.
|
| 113 |
+
source_configs_dir = path.join(path.dirname(path.realpath(__file__)), "configs")
|
| 114 |
+
destination = path.join(
|
| 115 |
+
path.dirname(path.realpath(__file__)), "detectron2", "model_zoo", "configs"
|
| 116 |
+
)
|
| 117 |
+
# Symlink the config directory inside package to have a cleaner pip install.
|
| 118 |
+
|
| 119 |
+
# Remove stale symlink/directory from a previous build.
|
| 120 |
+
if path.exists(source_configs_dir):
|
| 121 |
+
if path.islink(destination):
|
| 122 |
+
os.unlink(destination)
|
| 123 |
+
elif path.isdir(destination):
|
| 124 |
+
shutil.rmtree(destination)
|
| 125 |
+
|
| 126 |
+
if not path.exists(destination):
|
| 127 |
+
try:
|
| 128 |
+
os.symlink(source_configs_dir, destination)
|
| 129 |
+
except OSError:
|
| 130 |
+
# Fall back to copying if symlink fails: ex. on Windows.
|
| 131 |
+
shutil.copytree(source_configs_dir, destination)
|
| 132 |
+
|
| 133 |
+
config_paths = glob.glob("configs/**/*.yaml", recursive=True) + glob.glob(
|
| 134 |
+
"configs/**/*.py", recursive=True
|
| 135 |
+
)
|
| 136 |
+
return config_paths
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
# For projects that are relative small and provide features that are very close
|
| 140 |
+
# to detectron2's core functionalities, we install them under detectron2.projects
|
| 141 |
+
PROJECTS = {
|
| 142 |
+
"detectron2.projects.point_rend": "projects/PointRend/point_rend",
|
| 143 |
+
"detectron2.projects.deeplab": "projects/DeepLab/deeplab",
|
| 144 |
+
"detectron2.projects.panoptic_deeplab": "projects/Panoptic-DeepLab/panoptic_deeplab",
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
setup(
|
| 148 |
+
name="detectron2",
|
| 149 |
+
version=get_version(),
|
| 150 |
+
author="FAIR",
|
| 151 |
+
url="https://github.com/facebookresearch/detectron2",
|
| 152 |
+
description="Detectron2 is FAIR's next-generation research "
|
| 153 |
+
"platform for object detection and segmentation.",
|
| 154 |
+
packages=find_packages(exclude=("configs", "tests*")) + list(PROJECTS.keys()),
|
| 155 |
+
package_dir=PROJECTS,
|
| 156 |
+
package_data={"detectron2.model_zoo": get_model_zoo_configs()},
|
| 157 |
+
python_requires=">=3.7",
|
| 158 |
+
install_requires=[
|
| 159 |
+
# These dependencies are not pure-python.
|
| 160 |
+
# In general, avoid adding more dependencies like them because they are not
|
| 161 |
+
# guaranteed to be installable by `pip install` on all platforms.
|
| 162 |
+
# To tell if a package is pure-python, go to https://pypi.org/project/{name}/#files
|
| 163 |
+
"Pillow>=7.1", # or use pillow-simd for better performance
|
| 164 |
+
"matplotlib", # TODO move it to optional after we add opencv visualization
|
| 165 |
+
"pycocotools>=2.0.2", # corresponds to https://github.com/ppwwyyxx/cocoapi
|
| 166 |
+
# Do not add opencv here. Just like pytorch, user should install
|
| 167 |
+
# opencv themselves, preferrably by OS's package manager, or by
|
| 168 |
+
# choosing the proper pypi package name at https://github.com/skvark/opencv-python
|
| 169 |
+
# The following are pure-python dependencies that should be easily installable
|
| 170 |
+
"termcolor>=1.1",
|
| 171 |
+
"yacs>=0.1.8",
|
| 172 |
+
"tabulate",
|
| 173 |
+
"cloudpickle",
|
| 174 |
+
"tqdm>4.29.0",
|
| 175 |
+
"tensorboard",
|
| 176 |
+
# Lock version of fvcore/iopath because they may have breaking changes
|
| 177 |
+
# NOTE: when updating fvcore/iopath version, make sure fvcore depends
|
| 178 |
+
# on compatible version of iopath.
|
| 179 |
+
"fvcore>=0.1.5,<0.1.6", # required like this to make it pip installable
|
| 180 |
+
"iopath>=0.1.7,<0.1.10",
|
| 181 |
+
"future", # used by caffe2
|
| 182 |
+
"pydot", # used to save caffe2 SVGs
|
| 183 |
+
"dataclasses; python_version<'3.7'",
|
| 184 |
+
"omegaconf>=2.1",
|
| 185 |
+
"hydra-core>=1.1",
|
| 186 |
+
"black==22.3.0",
|
| 187 |
+
"timm",
|
| 188 |
+
"fairscale",
|
| 189 |
+
"packaging",
|
| 190 |
+
# If a new dependency is required at import time (in addition to runtime), it
|
| 191 |
+
# probably needs to exist in docs/requirements.txt, or as a mock in docs/conf.py
|
| 192 |
+
],
|
| 193 |
+
extras_require={
|
| 194 |
+
# optional dependencies, required by some features
|
| 195 |
+
"all": [
|
| 196 |
+
"scipy>1.5.1",
|
| 197 |
+
"shapely",
|
| 198 |
+
"pygments>=2.2",
|
| 199 |
+
"psutil",
|
| 200 |
+
"panopticapi @ https://github.com/cocodataset/panopticapi/archive/master.zip",
|
| 201 |
+
],
|
| 202 |
+
# dev dependencies. Install them by `pip install 'detectron2[dev]'`
|
| 203 |
+
"dev": [
|
| 204 |
+
"flake8==3.8.1",
|
| 205 |
+
"isort==4.3.21",
|
| 206 |
+
"flake8-bugbear",
|
| 207 |
+
"flake8-comprehensions",
|
| 208 |
+
],
|
| 209 |
+
},
|
| 210 |
+
ext_modules=get_extensions(),
|
| 211 |
+
cmdclass={"build_ext": torch.utils.cpp_extension.BuildExtension},
|
| 212 |
+
)
|
approach/ovod/gdino.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from groundingdino.util.inference import load_model, load_image, predict, annotate
|
| 2 |
+
import cv2
|
| 3 |
+
|
| 4 |
+
model = load_model("./groundingdino/config/GroundingDINO_SwinT_OGC.py", "weights/groundingdino_swint_ogc.pth")
|
| 5 |
+
|
| 6 |
+
# def peform_ovod(image_path, text_prompt, box_threshold, text_threshold)
|
| 7 |
+
image_path = "weights/dog.jpg"
|
| 8 |
+
text_prompt = "chair . person . dog ."
|
| 9 |
+
box_threshold = 0.35
|
| 10 |
+
text_threshold = 0.25
|
| 11 |
+
|
| 12 |
+
image_source, image = load_image(image_path)
|
| 13 |
+
|
| 14 |
+
boxes, logits, phrases = predict(
|
| 15 |
+
model=model,
|
| 16 |
+
image=image,
|
| 17 |
+
caption=text_prompt,
|
| 18 |
+
box_threshold=box_threshold,
|
| 19 |
+
text_threshold=text_threshold
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
annotated_frame = annotate(image_source=image_source, boxes=boxes, logits=logits, phrases=phrases)
|
| 23 |
+
cv2.imwrite("annotated_image.jpg", annotated_frame)
|
approach/pipeline_utils.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import os
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
import re
|
| 5 |
+
import tempfile
|
| 6 |
+
from typing import Iterable, List, Optional, Sequence
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
IMAGE_NAME_PATTERN = re.compile(r"^(?P<app_id>[0-9]+)_(?P<frame_id>[0-9]+)\.[A-Za-z0-9]+$")
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def parse_orienter_image_name(image_name: str) -> tuple[str, str, int]:
|
| 13 |
+
path = Path(image_name)
|
| 14 |
+
if path.name != image_name:
|
| 15 |
+
raise ValueError(f"Image name must be a basename, not a path: {image_name}")
|
| 16 |
+
match = IMAGE_NAME_PATTERN.match(image_name)
|
| 17 |
+
if not match:
|
| 18 |
+
raise ValueError(
|
| 19 |
+
"Image name must match <app_id>_<frame>.<ext> with numeric app_id and frame: "
|
| 20 |
+
f"{image_name}"
|
| 21 |
+
)
|
| 22 |
+
app_id = match.group("app_id")
|
| 23 |
+
frame_id = match.group("frame_id")
|
| 24 |
+
frame_number = int(frame_id)
|
| 25 |
+
if frame_number > 999:
|
| 26 |
+
raise ValueError(f"Image frame must be in [0, 999] for the documented image_id: {image_name}")
|
| 27 |
+
return app_id, frame_id, int(f"{app_id}{frame_number:03d}")
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def resolve_image_path(images_dir: Path, image_name: str) -> Path:
|
| 31 |
+
"""Resolve a manifest image path without allowing escape from images_dir."""
|
| 32 |
+
if not isinstance(image_name, str) or not image_name:
|
| 33 |
+
raise ValueError("Manifest image must be a non-empty relative path")
|
| 34 |
+
relative = Path(image_name)
|
| 35 |
+
if relative.is_absolute() or ".." in relative.parts:
|
| 36 |
+
raise ValueError(f"Manifest image must stay inside images-dir: {image_name}")
|
| 37 |
+
root = images_dir.resolve()
|
| 38 |
+
resolved = (root / relative).resolve()
|
| 39 |
+
try:
|
| 40 |
+
resolved.relative_to(root)
|
| 41 |
+
except ValueError as exc:
|
| 42 |
+
raise ValueError(f"Manifest image must stay inside images-dir: {image_name}") from exc
|
| 43 |
+
return resolved
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def select_jsonl_lines(
|
| 47 |
+
lines: Sequence[str],
|
| 48 |
+
start_index: Optional[int] = None,
|
| 49 |
+
end_index: Optional[int] = None,
|
| 50 |
+
shard_index: Optional[int] = None,
|
| 51 |
+
num_shards: Optional[int] = None,
|
| 52 |
+
) -> List[str]:
|
| 53 |
+
uses_range = start_index is not None or end_index is not None
|
| 54 |
+
uses_shard = shard_index is not None or num_shards is not None
|
| 55 |
+
if uses_range and uses_shard:
|
| 56 |
+
raise ValueError("range selection and shard selection are mutually exclusive")
|
| 57 |
+
if (shard_index is None) != (num_shards is None):
|
| 58 |
+
raise ValueError("shard_index and num_shards must be set together")
|
| 59 |
+
if num_shards is not None:
|
| 60 |
+
if num_shards <= 0:
|
| 61 |
+
raise ValueError("num_shards must be positive")
|
| 62 |
+
if shard_index < 0 or shard_index >= num_shards:
|
| 63 |
+
raise ValueError("shard_index must be in [0, num_shards)")
|
| 64 |
+
|
| 65 |
+
selected = list(lines)
|
| 66 |
+
if uses_range:
|
| 67 |
+
start = 0 if start_index is None else start_index
|
| 68 |
+
end = len(selected) if end_index is None else end_index
|
| 69 |
+
if start < 0 or end < 0:
|
| 70 |
+
raise ValueError("start_index and end_index must be non-negative")
|
| 71 |
+
if start > end:
|
| 72 |
+
raise ValueError("start_index must be <= end_index")
|
| 73 |
+
if end > len(selected):
|
| 74 |
+
raise ValueError("end_index must be <= number of records")
|
| 75 |
+
selected = selected[start:end]
|
| 76 |
+
|
| 77 |
+
if num_shards is not None:
|
| 78 |
+
selected = [line for idx, line in enumerate(selected) if idx % num_shards == shard_index]
|
| 79 |
+
|
| 80 |
+
return selected
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def output_path_for_selection(
|
| 84 |
+
path: str,
|
| 85 |
+
start_index: Optional[int] = None,
|
| 86 |
+
end_index: Optional[int] = None,
|
| 87 |
+
shard_index: Optional[int] = None,
|
| 88 |
+
num_shards: Optional[int] = None,
|
| 89 |
+
) -> str:
|
| 90 |
+
uses_range = start_index is not None or end_index is not None
|
| 91 |
+
uses_shard = shard_index is not None or num_shards is not None
|
| 92 |
+
if uses_range and uses_shard:
|
| 93 |
+
raise ValueError("range selection and shard selection are mutually exclusive")
|
| 94 |
+
if (shard_index is None) != (num_shards is None):
|
| 95 |
+
raise ValueError("shard_index and num_shards must be set together")
|
| 96 |
+
|
| 97 |
+
suffix = ""
|
| 98 |
+
if uses_shard:
|
| 99 |
+
if num_shards <= 0 or shard_index < 0 or shard_index >= num_shards:
|
| 100 |
+
raise ValueError("invalid shard parameters")
|
| 101 |
+
width = max(2, len(str(num_shards - 1)))
|
| 102 |
+
suffix = f".shard{shard_index:0{width}d}-of-{num_shards:0{width}d}"
|
| 103 |
+
elif uses_range:
|
| 104 |
+
start = 0 if start_index is None else start_index
|
| 105 |
+
end = "end" if end_index is None else str(end_index)
|
| 106 |
+
if start < 0 or (end_index is not None and end_index < start):
|
| 107 |
+
raise ValueError("invalid range parameters")
|
| 108 |
+
suffix = f".rows{start}-{end}"
|
| 109 |
+
|
| 110 |
+
if not suffix:
|
| 111 |
+
return path
|
| 112 |
+
root, extension = os.path.splitext(path)
|
| 113 |
+
return f"{root}{suffix}{extension or '.json'}"
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
def enrich_ape_results(ape_results: Iterable[dict], image_name: str, extract_image_id) -> List[dict]:
|
| 117 |
+
image_id = extract_image_id(image_name)
|
| 118 |
+
enriched = []
|
| 119 |
+
for ape_item in ape_results:
|
| 120 |
+
item = dict(ape_item)
|
| 121 |
+
item["image_id"] = image_id
|
| 122 |
+
item["category_id"] = item.get("category_name")
|
| 123 |
+
enriched.append(item)
|
| 124 |
+
return enriched
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def write_json_atomic(path: str, payload) -> None:
|
| 128 |
+
directory = os.path.dirname(os.path.abspath(path))
|
| 129 |
+
os.makedirs(directory, exist_ok=True)
|
| 130 |
+
file_descriptor, tmp_path = tempfile.mkstemp(
|
| 131 |
+
prefix=".orienter-",
|
| 132 |
+
suffix=".json.tmp",
|
| 133 |
+
dir=directory,
|
| 134 |
+
)
|
| 135 |
+
try:
|
| 136 |
+
with os.fdopen(file_descriptor, "w", encoding="utf-8") as out_file:
|
| 137 |
+
json.dump(payload, out_file, indent=4)
|
| 138 |
+
out_file.write("\n")
|
| 139 |
+
os.replace(tmp_path, path)
|
| 140 |
+
except Exception:
|
| 141 |
+
if os.path.exists(tmp_path):
|
| 142 |
+
os.unlink(tmp_path)
|
| 143 |
+
raise
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
def run_optional_reflection(
|
| 147 |
+
image_path: str,
|
| 148 |
+
detections: List[dict],
|
| 149 |
+
detector,
|
| 150 |
+
enabled: bool = False,
|
| 151 |
+
model_profile: str = "default",
|
| 152 |
+
max_iterations: int = 10,
|
| 153 |
+
advisor=None,
|
| 154 |
+
):
|
| 155 |
+
if not enabled:
|
| 156 |
+
return None
|
| 157 |
+
|
| 158 |
+
from PIL import Image
|
| 159 |
+
|
| 160 |
+
from approach.reflection import openai_compatible_advisor, run_reflection_loop
|
| 161 |
+
|
| 162 |
+
def mine_feedback(trace):
|
| 163 |
+
if not trace:
|
| 164 |
+
return []
|
| 165 |
+
return trace[-1].get("feedback", [])
|
| 166 |
+
|
| 167 |
+
reflection_advisor = advisor or openai_compatible_advisor(model_profile)
|
| 168 |
+
with Image.open(image_path) as image:
|
| 169 |
+
return run_reflection_loop(
|
| 170 |
+
image.convert("RGB"),
|
| 171 |
+
list(detections),
|
| 172 |
+
miner=mine_feedback,
|
| 173 |
+
detector=detector,
|
| 174 |
+
advisor=reflection_advisor,
|
| 175 |
+
max_iterations=max_iterations,
|
| 176 |
+
)
|
approach/run_ape.py
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Configurable APE detection entrypoint for the public Orienter pipeline."""
|
| 2 |
+
|
| 3 |
+
import argparse
|
| 4 |
+
import hashlib
|
| 5 |
+
import json
|
| 6 |
+
import os
|
| 7 |
+
import sys
|
| 8 |
+
from contextlib import contextmanager
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
|
| 11 |
+
if __package__ in {None, ""}:
|
| 12 |
+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
| 13 |
+
|
| 14 |
+
from approach.ape_stage import run_ape_stage
|
| 15 |
+
from approach.pipeline_utils import (
|
| 16 |
+
output_path_for_selection,
|
| 17 |
+
run_optional_reflection,
|
| 18 |
+
select_jsonl_lines,
|
| 19 |
+
write_json_atomic,
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
DEFAULT_APE_CONFIG = (
|
| 24 |
+
"configs/LVISCOCOCOCOSTUFF_O365_OID_VGR_SA1B_REFCOCO_GQA_"
|
| 25 |
+
"PhraseCut_Flickr30k/ape_deta/ape_deta_vitl_eva02_clip_vlf_lsj1024_"
|
| 26 |
+
"cp_16x4_1080k.py"
|
| 27 |
+
)
|
| 28 |
+
APE_CHECKPOINT_SHA256 = "3548f41a3238148180e08fd4b16c71f4abc3ac3caf9c8434444462d1bdb7f965"
|
| 29 |
+
APE_CHECKPOINT_SIZE = 5_956_547_279
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def _load_jsonl(path: Path):
|
| 33 |
+
with path.open(encoding="utf-8") as file:
|
| 34 |
+
return [json.loads(line) for line in file if line.strip()]
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def _normalize_candidate(record):
|
| 38 |
+
normalized = dict(record)
|
| 39 |
+
text = normalized.get("text")
|
| 40 |
+
if isinstance(text, str):
|
| 41 |
+
stripped = text.strip()
|
| 42 |
+
if stripped.startswith("```"):
|
| 43 |
+
lines = stripped.splitlines()
|
| 44 |
+
stripped = "\n".join(lines[1:-1] if lines[-1].strip() == "```" else lines[1:])
|
| 45 |
+
normalized["text"] = json.loads(stripped)
|
| 46 |
+
if normalized.get("text") is not None and "objects" not in normalized["text"]:
|
| 47 |
+
raise ValueError(
|
| 48 |
+
f"candidate record {normalized.get('question_id')!r} is missing text.objects"
|
| 49 |
+
)
|
| 50 |
+
return normalized
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
@contextmanager
|
| 54 |
+
def _working_directory(path: Path):
|
| 55 |
+
previous = Path.cwd()
|
| 56 |
+
os.chdir(path)
|
| 57 |
+
try:
|
| 58 |
+
yield
|
| 59 |
+
finally:
|
| 60 |
+
os.chdir(previous)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def _resolve_ape_checkpoint(ape_root: Path, checkpoint: Path) -> Path:
|
| 64 |
+
if checkpoint.is_absolute():
|
| 65 |
+
return checkpoint
|
| 66 |
+
project_root = Path(__file__).resolve().parents[1]
|
| 67 |
+
repo_relative = (project_root / checkpoint).resolve()
|
| 68 |
+
if repo_relative.exists():
|
| 69 |
+
return repo_relative
|
| 70 |
+
return (ape_root.resolve() / checkpoint).resolve()
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def _sha256_file(path: Path) -> str:
|
| 74 |
+
digest = hashlib.sha256()
|
| 75 |
+
with path.open("rb") as file:
|
| 76 |
+
for chunk in iter(lambda: file.read(1024 * 1024), b""):
|
| 77 |
+
digest.update(chunk)
|
| 78 |
+
return digest.hexdigest()
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def _verify_ape_checkpoint(checkpoint: Path, trust_custom_checkpoint: bool = False) -> None:
|
| 82 |
+
if not checkpoint.is_file():
|
| 83 |
+
raise FileNotFoundError(f"APE checkpoint does not exist: {checkpoint}")
|
| 84 |
+
|
| 85 |
+
size = checkpoint.stat().st_size
|
| 86 |
+
if size == APE_CHECKPOINT_SIZE:
|
| 87 |
+
digest = _sha256_file(checkpoint)
|
| 88 |
+
if digest == APE_CHECKPOINT_SHA256:
|
| 89 |
+
return
|
| 90 |
+
mismatch = f"SHA-256 {digest} does not match the released APE-L_D checkpoint"
|
| 91 |
+
else:
|
| 92 |
+
mismatch = (
|
| 93 |
+
f"size {size} does not match the released APE-L_D checkpoint "
|
| 94 |
+
f"({APE_CHECKPOINT_SIZE} bytes)"
|
| 95 |
+
)
|
| 96 |
+
|
| 97 |
+
if trust_custom_checkpoint:
|
| 98 |
+
return
|
| 99 |
+
raise ValueError(
|
| 100 |
+
f"Refusing unverified checkpoint {checkpoint}: {mismatch}. "
|
| 101 |
+
"Use --trust-custom-checkpoint only for a checkpoint whose provenance you verified."
|
| 102 |
+
)
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
def _make_live_inference(args):
|
| 106 |
+
from approach.ovod.APE.demo.ape_inference import run_ape_model_inference
|
| 107 |
+
|
| 108 |
+
ape_root = args.ape_root.resolve()
|
| 109 |
+
checkpoint = _resolve_ape_checkpoint(ape_root, args.ape_checkpoint)
|
| 110 |
+
_verify_ape_checkpoint(checkpoint, args.trust_custom_checkpoint)
|
| 111 |
+
visualization_dir = args.visualization_dir.resolve()
|
| 112 |
+
visualization_dir.mkdir(parents=True, exist_ok=True)
|
| 113 |
+
|
| 114 |
+
def inference(input_path, text_prompt, confidence_threshold):
|
| 115 |
+
with _working_directory(ape_root):
|
| 116 |
+
return run_ape_model_inference(
|
| 117 |
+
config_file=args.ape_config,
|
| 118 |
+
input_path=input_path,
|
| 119 |
+
output_path=str(visualization_dir),
|
| 120 |
+
confidence_threshold=confidence_threshold,
|
| 121 |
+
text_prompt=text_prompt,
|
| 122 |
+
with_box=True,
|
| 123 |
+
with_mask=False,
|
| 124 |
+
with_sseg=False,
|
| 125 |
+
opts=[
|
| 126 |
+
f"train.init_checkpoint='{checkpoint}'",
|
| 127 |
+
"model.model_language.cache_dir=''",
|
| 128 |
+
"model.model_vision.select_box_nums_for_evaluation=500",
|
| 129 |
+
"model.model_vision.text_feature_bank_reset=True",
|
| 130 |
+
"model.model_vision.backbone.net.xattn=False",
|
| 131 |
+
"model.model_vision.transformer.encoder.pytorch_attn=True",
|
| 132 |
+
"model.model_vision.transformer.decoder.pytorch_attn=True",
|
| 133 |
+
],
|
| 134 |
+
)
|
| 135 |
+
|
| 136 |
+
return inference
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
def _merge_detections(retained, new_detections):
|
| 140 |
+
merged = list(retained)
|
| 141 |
+
seen = {
|
| 142 |
+
(item.get("category_name"), tuple(item.get("bbox", [])))
|
| 143 |
+
for item in retained
|
| 144 |
+
}
|
| 145 |
+
for item in new_detections:
|
| 146 |
+
key = item.get("category_name"), tuple(item.get("bbox", []))
|
| 147 |
+
if key not in seen:
|
| 148 |
+
merged.append(item)
|
| 149 |
+
seen.add(key)
|
| 150 |
+
return merged
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
def build_parser():
|
| 154 |
+
project_root = Path(__file__).resolve().parent
|
| 155 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 156 |
+
parser.add_argument("--questions", type=Path, required=True, help="question manifest JSONL")
|
| 157 |
+
parser.add_argument("--candidates", type=Path, required=True, help="candidate JSONL")
|
| 158 |
+
parser.add_argument("--images-dir", type=Path, required=True)
|
| 159 |
+
parser.add_argument("--output", type=Path, required=True)
|
| 160 |
+
parser.add_argument("--start-index", type=int)
|
| 161 |
+
parser.add_argument("--end-index", type=int)
|
| 162 |
+
parser.add_argument("--shard-index", type=int)
|
| 163 |
+
parser.add_argument("--num-shards", type=int)
|
| 164 |
+
parser.add_argument("--resume", action="store_true")
|
| 165 |
+
parser.add_argument("--threshold", type=float, default=0.15)
|
| 166 |
+
parser.add_argument(
|
| 167 |
+
"--ape-root",
|
| 168 |
+
type=Path,
|
| 169 |
+
default=project_root / "ovod" / "APE",
|
| 170 |
+
)
|
| 171 |
+
parser.add_argument("--ape-config", default=DEFAULT_APE_CONFIG)
|
| 172 |
+
parser.add_argument(
|
| 173 |
+
"--ape-checkpoint",
|
| 174 |
+
type=Path,
|
| 175 |
+
default=Path("ape_d_model_final.pth"),
|
| 176 |
+
)
|
| 177 |
+
parser.add_argument(
|
| 178 |
+
"--trust-custom-checkpoint",
|
| 179 |
+
action="store_true",
|
| 180 |
+
help="allow a checkpoint that does not match the released model hash",
|
| 181 |
+
)
|
| 182 |
+
parser.add_argument(
|
| 183 |
+
"--visualization-dir",
|
| 184 |
+
type=Path,
|
| 185 |
+
default=Path("outputs/ape_visualizations"),
|
| 186 |
+
)
|
| 187 |
+
parser.add_argument("--enable-reflection", action="store_true")
|
| 188 |
+
parser.add_argument("--reflection-profile", default="default")
|
| 189 |
+
parser.add_argument("--max-reflection-iterations", type=int, default=10)
|
| 190 |
+
return parser
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
def run(args, inference=None):
|
| 194 |
+
questions = {
|
| 195 |
+
item["question_id"]: item
|
| 196 |
+
for item in _load_jsonl(args.questions)
|
| 197 |
+
}
|
| 198 |
+
records = [_normalize_candidate(item) for item in _load_jsonl(args.candidates)]
|
| 199 |
+
selected = select_jsonl_lines(
|
| 200 |
+
records,
|
| 201 |
+
start_index=args.start_index,
|
| 202 |
+
end_index=args.end_index,
|
| 203 |
+
shard_index=args.shard_index,
|
| 204 |
+
num_shards=args.num_shards,
|
| 205 |
+
)
|
| 206 |
+
selected_output = Path(
|
| 207 |
+
output_path_for_selection(
|
| 208 |
+
str(args.output),
|
| 209 |
+
start_index=args.start_index,
|
| 210 |
+
end_index=args.end_index,
|
| 211 |
+
shard_index=args.shard_index,
|
| 212 |
+
num_shards=args.num_shards,
|
| 213 |
+
)
|
| 214 |
+
)
|
| 215 |
+
base_inference = inference or _make_live_inference(args)
|
| 216 |
+
reflection_traces = []
|
| 217 |
+
|
| 218 |
+
def configured_inference(**kwargs):
|
| 219 |
+
detections = base_inference(**kwargs)
|
| 220 |
+
if not args.enable_reflection:
|
| 221 |
+
return detections
|
| 222 |
+
|
| 223 |
+
def redetect(candidates, retained):
|
| 224 |
+
if not candidates:
|
| 225 |
+
return retained
|
| 226 |
+
new_detections = base_inference(
|
| 227 |
+
input_path=kwargs["input_path"],
|
| 228 |
+
text_prompt=", ".join(candidates),
|
| 229 |
+
confidence_threshold=kwargs["confidence_threshold"],
|
| 230 |
+
)
|
| 231 |
+
return _merge_detections(retained, new_detections)
|
| 232 |
+
|
| 233 |
+
try:
|
| 234 |
+
reflection = run_optional_reflection(
|
| 235 |
+
kwargs["input_path"],
|
| 236 |
+
detections,
|
| 237 |
+
detector=redetect,
|
| 238 |
+
enabled=True,
|
| 239 |
+
model_profile=args.reflection_profile,
|
| 240 |
+
max_iterations=args.max_reflection_iterations,
|
| 241 |
+
)
|
| 242 |
+
except Exception as exc:
|
| 243 |
+
reflection_traces.append(
|
| 244 |
+
{
|
| 245 |
+
"image": Path(kwargs["input_path"]).name,
|
| 246 |
+
"error_type": type(exc).__name__,
|
| 247 |
+
"message": str(exc),
|
| 248 |
+
}
|
| 249 |
+
)
|
| 250 |
+
return detections
|
| 251 |
+
|
| 252 |
+
reflection_traces.append(
|
| 253 |
+
{
|
| 254 |
+
"image": Path(kwargs["input_path"]).name,
|
| 255 |
+
"trace": reflection["trace"],
|
| 256 |
+
"max_iterations_reached": reflection["max_iterations_reached"],
|
| 257 |
+
}
|
| 258 |
+
)
|
| 259 |
+
return reflection["detections"]
|
| 260 |
+
|
| 261 |
+
error_path = selected_output.with_suffix(".errors.json")
|
| 262 |
+
results, errors = run_ape_stage(
|
| 263 |
+
records=selected,
|
| 264 |
+
questions=questions,
|
| 265 |
+
images_dir=args.images_dir,
|
| 266 |
+
output_path=selected_output,
|
| 267 |
+
inference=configured_inference,
|
| 268 |
+
inference_kwargs={"confidence_threshold": args.threshold},
|
| 269 |
+
error_path=error_path,
|
| 270 |
+
resume=args.resume,
|
| 271 |
+
)
|
| 272 |
+
if args.enable_reflection:
|
| 273 |
+
write_json_atomic(
|
| 274 |
+
str(selected_output.with_suffix(".reflection.json")),
|
| 275 |
+
reflection_traces,
|
| 276 |
+
)
|
| 277 |
+
return {
|
| 278 |
+
"output": str(selected_output),
|
| 279 |
+
"records_selected": len(selected),
|
| 280 |
+
"predictions": len(results),
|
| 281 |
+
"errors": len(errors),
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
def main(argv=None):
|
| 286 |
+
args = build_parser().parse_args(argv)
|
| 287 |
+
print(json.dumps(run(args), indent=2))
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
if __name__ == "__main__":
|
| 291 |
+
main()
|
approach/util/test.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import time
|
| 3 |
+
import os
|
| 4 |
+
import argparse
|
| 5 |
+
import shutil
|
| 6 |
+
import sys
|
| 7 |
+
|
| 8 |
+
def parse_args():
|
| 9 |
+
parser = argparse.ArgumentParser(description='Matrix multiplication')
|
| 10 |
+
parser.add_argument('--gpus', help='gpu amount', required=True, type=int)
|
| 11 |
+
parser.add_argument('--size', help='matrix size', required=True, type=int)
|
| 12 |
+
parser.add_argument('--interval', help='sleep interval', required=True, type=float)
|
| 13 |
+
args = parser.parse_args()
|
| 14 |
+
return args
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def matrix_multiplication(args):
|
| 18 |
+
|
| 19 |
+
a_list, b_list, result = [], [], []
|
| 20 |
+
size = (args.size, args.size)
|
| 21 |
+
|
| 22 |
+
for i in range(args.gpus):
|
| 23 |
+
a_list.append(torch.rand(size, device=i))
|
| 24 |
+
b_list.append(torch.rand(size, device=i))
|
| 25 |
+
result.append(torch.rand(size, device=i))
|
| 26 |
+
|
| 27 |
+
while True:
|
| 28 |
+
for i in range(args.gpus):
|
| 29 |
+
result[i] = a_list[i] * b_list[i]
|
| 30 |
+
time.sleep(args.interval)
|
| 31 |
+
|
| 32 |
+
if __name__ == "__main__":
|
| 33 |
+
# usage: python test.py --size 32000 --gpus 4 --interval 0.01
|
| 34 |
+
args = parse_args()
|
| 35 |
+
matrix_multiplication(args)
|
approach/vlm/LLaVA/.gitignore
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Python
|
| 2 |
+
__pycache__
|
| 3 |
+
*.pyc
|
| 4 |
+
*.egg-info
|
| 5 |
+
dist
|
| 6 |
+
|
| 7 |
+
# Log
|
| 8 |
+
*.log
|
| 9 |
+
*.log.*
|
| 10 |
+
*.json
|
| 11 |
+
*.jsonl
|
| 12 |
+
|
| 13 |
+
# Data
|
| 14 |
+
!**/alpaca-data-conversation.json
|
| 15 |
+
|
| 16 |
+
# Editor
|
| 17 |
+
.idea
|
| 18 |
+
*.swp
|
| 19 |
+
|
| 20 |
+
# Other
|
| 21 |
+
.DS_Store
|
| 22 |
+
wandb
|
| 23 |
+
output
|
| 24 |
+
|
| 25 |
+
checkpoints
|
| 26 |
+
ckpts*
|
| 27 |
+
|
| 28 |
+
.ipynb_checkpoints
|
| 29 |
+
*.ipynb
|
approach/vlm/LLaVA/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Apache License
|
| 2 |
+
Version 2.0, January 2004
|
| 3 |
+
http://www.apache.org/licenses/
|
| 4 |
+
|
| 5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 6 |
+
|
| 7 |
+
1. Definitions.
|
| 8 |
+
|
| 9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 11 |
+
|
| 12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 13 |
+
the copyright owner that is granting the License.
|
| 14 |
+
|
| 15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 16 |
+
other entities that control, are controlled by, or are under common
|
| 17 |
+
control with that entity. For the purposes of this definition,
|
| 18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 19 |
+
direction or management of such entity, whether by contract or
|
| 20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 22 |
+
|
| 23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 24 |
+
exercising permissions granted by this License.
|
| 25 |
+
|
| 26 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 27 |
+
including but not limited to software source code, documentation
|
| 28 |
+
source, and configuration files.
|
| 29 |
+
|
| 30 |
+
"Object" form shall mean any form resulting from mechanical
|
| 31 |
+
transformation or translation of a Source form, including but
|
| 32 |
+
not limited to compiled object code, generated documentation,
|
| 33 |
+
and conversions to other media types.
|
| 34 |
+
|
| 35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 36 |
+
Object form, made available under the License, as indicated by a
|
| 37 |
+
copyright notice that is included in or attached to the work
|
| 38 |
+
(an example is provided in the Appendix below).
|
| 39 |
+
|
| 40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 41 |
+
form, that is based on (or derived from) the Work and for which the
|
| 42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 44 |
+
of this License, Derivative Works shall not include works that remain
|
| 45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 46 |
+
the Work and Derivative Works thereof.
|
| 47 |
+
|
| 48 |
+
"Contribution" shall mean any work of authorship, including
|
| 49 |
+
the original version of the Work and any modifications or additions
|
| 50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 54 |
+
means any form of electronic, verbal, or written communication sent
|
| 55 |
+
to the Licensor or its representatives, including but not limited to
|
| 56 |
+
communication on electronic mailing lists, source code control systems,
|
| 57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 59 |
+
excluding communication that is conspicuously marked or otherwise
|
| 60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 61 |
+
|
| 62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
| 64 |
+
subsequently incorporated within the Work.
|
| 65 |
+
|
| 66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 71 |
+
Work and such Derivative Works in Source or Object form.
|
| 72 |
+
|
| 73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 76 |
+
(except as stated in this section) patent license to make, have made,
|
| 77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 78 |
+
where such license applies only to those patent claims licensable
|
| 79 |
+
by such Contributor that are necessarily infringed by their
|
| 80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 82 |
+
institute patent litigation against any entity (including a
|
| 83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 84 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 85 |
+
or contributory patent infringement, then any patent licenses
|
| 86 |
+
granted to You under this License for that Work shall terminate
|
| 87 |
+
as of the date such litigation is filed.
|
| 88 |
+
|
| 89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 90 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 91 |
+
modifications, and in Source or Object form, provided that You
|
| 92 |
+
meet the following conditions:
|
| 93 |
+
|
| 94 |
+
(a) You must give any other recipients of the Work or
|
| 95 |
+
Derivative Works a copy of this License; and
|
| 96 |
+
|
| 97 |
+
(b) You must cause any modified files to carry prominent notices
|
| 98 |
+
stating that You changed the files; and
|
| 99 |
+
|
| 100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 101 |
+
that You distribute, all copyright, patent, trademark, and
|
| 102 |
+
attribution notices from the Source form of the Work,
|
| 103 |
+
excluding those notices that do not pertain to any part of
|
| 104 |
+
the Derivative Works; and
|
| 105 |
+
|
| 106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 107 |
+
distribution, then any Derivative Works that You distribute must
|
| 108 |
+
include a readable copy of the attribution notices contained
|
| 109 |
+
within such NOTICE file, excluding those notices that do not
|
| 110 |
+
pertain to any part of the Derivative Works, in at least one
|
| 111 |
+
of the following places: within a NOTICE text file distributed
|
| 112 |
+
as part of the Derivative Works; within the Source form or
|
| 113 |
+
documentation, if provided along with the Derivative Works; or,
|
| 114 |
+
within a display generated by the Derivative Works, if and
|
| 115 |
+
wherever such third-party notices normally appear. The contents
|
| 116 |
+
of the NOTICE file are for informational purposes only and
|
| 117 |
+
do not modify the License. You may add Your own attribution
|
| 118 |
+
notices within Derivative Works that You distribute, alongside
|
| 119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 120 |
+
that such additional attribution notices cannot be construed
|
| 121 |
+
as modifying the License.
|
| 122 |
+
|
| 123 |
+
You may add Your own copyright statement to Your modifications and
|
| 124 |
+
may provide additional or different license terms and conditions
|
| 125 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 126 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 127 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 128 |
+
the conditions stated in this License.
|
| 129 |
+
|
| 130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 132 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 133 |
+
this License, without any additional terms or conditions.
|
| 134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 135 |
+
the terms of any separate license agreement you may have executed
|
| 136 |
+
with Licensor regarding such Contributions.
|
| 137 |
+
|
| 138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 140 |
+
except as required for reasonable and customary use in describing the
|
| 141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 142 |
+
|
| 143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 144 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 147 |
+
implied, including, without limitation, any warranties or conditions
|
| 148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 150 |
+
appropriateness of using or redistributing the Work and assume any
|
| 151 |
+
risks associated with Your exercise of permissions under this License.
|
| 152 |
+
|
| 153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 154 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 155 |
+
unless required by applicable law (such as deliberate and grossly
|
| 156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 157 |
+
liable to You for damages, including any direct, indirect, special,
|
| 158 |
+
incidental, or consequential damages of any character arising as a
|
| 159 |
+
result of this License or out of the use or inability to use the
|
| 160 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 161 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 162 |
+
other commercial damages or losses), even if such Contributor
|
| 163 |
+
has been advised of the possibility of such damages.
|
| 164 |
+
|
| 165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 168 |
+
or other liability obligations and/or rights consistent with this
|
| 169 |
+
License. However, in accepting such obligations, You may act only
|
| 170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 171 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 172 |
+
defend, and hold each Contributor harmless for any liability
|
| 173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 174 |
+
of your accepting any such warranty or additional liability.
|
| 175 |
+
|
| 176 |
+
END OF TERMS AND CONDITIONS
|
| 177 |
+
|
| 178 |
+
APPENDIX: How to apply the Apache License to your work.
|
| 179 |
+
|
| 180 |
+
To apply the Apache License to your work, attach the following
|
| 181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 182 |
+
replaced with your own identifying information. (Don't include
|
| 183 |
+
the brackets!) The text should be enclosed in the appropriate
|
| 184 |
+
comment syntax for the file format. We also recommend that a
|
| 185 |
+
file or class name and description of purpose be included on the
|
| 186 |
+
same "printed page" as the copyright notice for easier
|
| 187 |
+
identification within third-party archives.
|
| 188 |
+
|
| 189 |
+
Copyright [yyyy] [name of copyright owner]
|
| 190 |
+
|
| 191 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 192 |
+
you may not use this file except in compliance with the License.
|
| 193 |
+
You may obtain a copy of the License at
|
| 194 |
+
|
| 195 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 196 |
+
|
| 197 |
+
Unless required by applicable law or agreed to in writing, software
|
| 198 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 199 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 200 |
+
See the License for the specific language governing permissions and
|
| 201 |
+
limitations under the License.
|
approach/vlm/LLaVA/README.md
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🌋 LLaVA: Large Language and Vision Assistant
|
| 2 |
+
|
| 3 |
+
*Visual instruction tuning towards large language and vision models with GPT-4 level capabilities.*
|
| 4 |
+
|
| 5 |
+
[[Project Page](https://llava-vl.github.io/)] [[Demo](https://llava.hliu.cc/)] [[Data](https://github.com/haotian-liu/LLaVA/blob/main/docs/Data.md)] [[Model Zoo](https://github.com/haotian-liu/LLaVA/blob/main/docs/MODEL_ZOO.md)]
|
| 6 |
+
|
| 7 |
+
**Improved Baselines with Visual Instruction Tuning** [[Paper](https://arxiv.org/abs/2310.03744)] <br>
|
| 8 |
+
[Haotian Liu](https://hliu.cc), [Chunyuan Li](https://chunyuan.li/), [Yuheng Li](https://yuheng-li.github.io/), [Yong Jae Lee](https://pages.cs.wisc.edu/~yongjaelee/)
|
| 9 |
+
|
| 10 |
+
**Visual Instruction Tuning** (NeurIPS 2023, **Oral**) [[Paper](https://arxiv.org/abs/2304.08485)]<br>
|
| 11 |
+
[Haotian Liu*](https://hliu.cc), [Chunyuan Li*](https://chunyuan.li/), [Qingyang Wu](https://scholar.google.ca/citations?user=HDiw-TsAAAAJ&hl=en/), [Yong Jae Lee](https://pages.cs.wisc.edu/~yongjaelee/) (*Equal Contribution)
|
| 12 |
+
|
| 13 |
+
<p align="center">
|
| 14 |
+
<a href="https://llava.hliu.cc/"><img src="images/llava_logo.png" width="50%"></a> <br>
|
| 15 |
+
Generated by <a href="https://gligen.github.io/">GLIGEN</a> via "a cute lava llama with glasses" and box prompt
|
| 16 |
+
</p>
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
## Release
|
| 20 |
+
- [10/5] 🔥 LLaVA-1.5 is out! Achieving SoTA on 11 benchmarks, with just simple modifications to the original LLaVA, utilizes all public data, completes training in ~1 day on a single 8-A100 node, and surpasses methods like Qwen-VL-Chat that use billion-scale data. Check out the [technical report](https://arxiv.org/abs/2310.03744), and explore the [demo](https://llava.hliu.cc/)! Models are available in [Model Zoo](https://github.com/haotian-liu/LLaVA/blob/main/docs/MODEL_ZOO.md), with training and evaluation scripts coming in the next week!
|
| 21 |
+
- [9/26] LLaVA is improved with reinforcement learning from human feedback (RLHF) to improve fact grounding and reduce hallucination. Check out the new SFT and RLHF checkpoints at project [[LLavA-RLHF]](https://llava-rlhf.github.io/)
|
| 22 |
+
- [9/22] [LLaVA](https://arxiv.org/abs/2304.08485) is accpeted by NeurIPS 2023 as **oral presentation**, and [LLaVA-Med](https://arxiv.org/abs/2306.00890) is accpeted by NeurIPS 2023 Datasets and Benchmarks Track as **spotlight presentation**.
|
| 23 |
+
- [9/20] We summarize our emprical study of training 33B and 65B LLaVA mdoels in a [note](https://arxiv.org/abs/2309.09958). Further, if you are interested in the comprehensive review, evolution and trend of multimodal foundation models, please check out our recent survey paper [``Multimodal Foundation Models: From Specialists to General-Purpose Assistants''.](https://arxiv.org/abs/2309.10020)
|
| 24 |
+
<p align="center">
|
| 25 |
+
<img src="https://github.com/Computer-Vision-in-the-Wild/CVinW_Readings/blob/main/images/mfm_evolution.jpeg?raw=true" width=50%/>
|
| 26 |
+
</p>
|
| 27 |
+
|
| 28 |
+
- [7/19] 🔥 We release a major upgrade, including support for LLaMA-2, LoRA training, 4-/8-bit inference, higher resolution (336x336), and a lot more. We release [LLaVA Bench](https://github.com/haotian-liu/LLaVA/blob/main/docs/LLaVA_Bench.md) for benchmarking open-ended visual chat with results from Bard and Bing-Chat. We also support and verify training with RTX 3090 and RTX A6000. Check out [LLaVA-from-LLaMA-2](https://github.com/haotian-liu/LLaVA/blob/main/docs/LLaVA_from_LLaMA2.md), and our [model zoo](https://github.com/haotian-liu/LLaVA/blob/main/docs/MODEL_ZOO.md)!
|
| 29 |
+
- [6/26] [CVPR 2023 Tutorial](https://vlp-tutorial.github.io/) on **Large Multimodal Models: Towards Building and Surpassing Multimodal GPT-4**! Please check out [[Slides](https://datarelease.blob.core.windows.net/tutorial/vision_foundation_models_2023/slides/Chunyuan_cvpr2023_tutorial_lmm.pdf)] [[Notes](https://arxiv.org/abs/2306.14895)] [[YouTube](https://youtu.be/mkI7EPD1vp8)] [[Bilibli](https://www.bilibili.com/video/BV1Ng4y1T7v3/)].
|
| 30 |
+
- [6/11] We released the preview for the most requested feature: DeepSpeed and LoRA support! Please see documentations [here](./docs/LoRA.md).
|
| 31 |
+
- [6/1] We released **LLaVA-Med: Large Language and Vision Assistant for Biomedicine**, a step towards building biomedical domain large language and vision models with GPT-4 level capabilities. Checkout the [paper](https://arxiv.org/abs/2306.00890) and [page](https://github.com/microsoft/LLaVA-Med).
|
| 32 |
+
- [5/6] We are releasing [LLaVA-Lighting-MPT-7B-preview](https://huggingface.co/liuhaotian/LLaVA-Lightning-MPT-7B-preview), based on MPT-7B-Chat! See [here](#LLaVA-MPT-7b) for more details.
|
| 33 |
+
- [5/2] 🔥 We are releasing LLaVA-Lighting! Train a lite, multimodal GPT-4 with just $40 in 3 hours! See [here](#train-llava-lightning) for more details.
|
| 34 |
+
- [4/27] Thanks to the community effort, LLaVA-13B with 4-bit quantization allows you to run on a GPU with as few as 12GB VRAM! Try it out [here](https://github.com/oobabooga/text-generation-webui/tree/main/extensions/llava).
|
| 35 |
+
- [4/17] 🔥 We released **LLaVA: Large Language and Vision Assistant**. We propose visual instruction tuning, towards building large language and vision models with GPT-4 level capabilities. Checkout the [paper](https://arxiv.org/abs/2304.08485) and [demo](https://llava.hliu.cc/).
|
| 36 |
+
|
| 37 |
+
<!-- <a href="https://llava.hliu.cc/"><img src="assets/demo.gif" width="70%"></a> -->
|
| 38 |
+
|
| 39 |
+
[](https://github.com/tatsu-lab/stanford_alpaca/blob/main/LICENSE)
|
| 40 |
+
[](https://github.com/tatsu-lab/stanford_alpaca/blob/main/DATA_LICENSE)
|
| 41 |
+
**Usage and License Notices**: The data and checkpoint is intended and licensed for research use only. They are also restricted to uses that follow the license agreement of LLaMA, Vicuna and GPT-4. The dataset is CC BY NC 4.0 (allowing only non-commercial use) and models trained using the dataset should not be used outside of research purposes.
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
## Contents
|
| 45 |
+
- [Install](#install)
|
| 46 |
+
- [LLaVA Weights](#llava-weights)
|
| 47 |
+
- [Demo](#Demo)
|
| 48 |
+
- [Model Zoo](https://github.com/haotian-liu/LLaVA/blob/main/docs/MODEL_ZOO.md)
|
| 49 |
+
- [Dataset](https://github.com/haotian-liu/LLaVA/blob/main/docs/Data.md)
|
| 50 |
+
- [Train](#train)
|
| 51 |
+
- [Evaluation](#evaluation)
|
| 52 |
+
|
| 53 |
+
## Install
|
| 54 |
+
|
| 55 |
+
1. Clone this repository and navigate to LLaVA folder
|
| 56 |
+
```bash
|
| 57 |
+
git clone https://github.com/haotian-liu/LLaVA.git
|
| 58 |
+
cd LLaVA
|
| 59 |
+
```
|
| 60 |
+
|
| 61 |
+
2. Install Package
|
| 62 |
+
```Shell
|
| 63 |
+
conda create -n llava python=3.10 -y
|
| 64 |
+
conda activate llava
|
| 65 |
+
pip install --upgrade pip # enable PEP 660 support
|
| 66 |
+
pip install -e .
|
| 67 |
+
```
|
| 68 |
+
|
| 69 |
+
3. Install additional packages for training cases
|
| 70 |
+
```
|
| 71 |
+
pip install ninja
|
| 72 |
+
pip install flash-attn --no-build-isolation
|
| 73 |
+
```
|
| 74 |
+
|
| 75 |
+
### Upgrade to latest code base
|
| 76 |
+
|
| 77 |
+
```Shell
|
| 78 |
+
git pull
|
| 79 |
+
pip uninstall transformers
|
| 80 |
+
pip install -e .
|
| 81 |
+
```
|
| 82 |
+
|
| 83 |
+
## LLaVA Weights
|
| 84 |
+
Please check out our [Model Zoo](https://github.com/haotian-liu/LLaVA/blob/main/docs/MODEL_ZOO.md) for all public LLaVA checkpoints, and the instructions of how to use the weights.
|
| 85 |
+
|
| 86 |
+
## Demo
|
| 87 |
+
|
| 88 |
+
To run our demo, you need to prepare LLaVA checkpoints locally. Please follow the instructions [here](#llava-weights) to download the checkpoints.
|
| 89 |
+
|
| 90 |
+
### Gradio Web UI
|
| 91 |
+
|
| 92 |
+
To launch a Gradio demo locally, please run the following commands one by one. If you plan to launch multiple model workers to compare between different checkpoints, you only need to launch the controller and the web server *ONCE*.
|
| 93 |
+
|
| 94 |
+
#### Launch a controller
|
| 95 |
+
```Shell
|
| 96 |
+
python -m llava.serve.controller --host 0.0.0.0 --port 10000
|
| 97 |
+
```
|
| 98 |
+
|
| 99 |
+
#### Launch a gradio web server.
|
| 100 |
+
```Shell
|
| 101 |
+
python -m llava.serve.gradio_web_server --controller http://localhost:10000 --model-list-mode reload
|
| 102 |
+
```
|
| 103 |
+
You just launched the Gradio web interface. Now, you can open the web interface with the URL printed on the screen. You may notice that there is no model in the model list. Do not worry, as we have not launched any model worker yet. It will be automatically updated when you launch a model worker.
|
| 104 |
+
|
| 105 |
+
#### Launch a model worker
|
| 106 |
+
|
| 107 |
+
This is the actual *worker* that performs the inference on the GPU. Each worker is responsible for a single model specified in `--model-path`.
|
| 108 |
+
|
| 109 |
+
```Shell
|
| 110 |
+
python -m llava.serve.model_worker --host 0.0.0.0 --controller http://localhost:10000 --port 40000 --worker http://localhost:40000 --model-path liuhaotian/llava-v1.5-13b
|
| 111 |
+
```
|
| 112 |
+
Wait until the process finishes loading the model and you see "Uvicorn running on ...". Now, refresh your Gradio web UI, and you will see the model you just launched in the model list.
|
| 113 |
+
|
| 114 |
+
You can launch as many workers as you want, and compare between different model checkpoints in the same Gradio interface. Please keep the `--controller` the same, and modify the `--port` and `--worker` to a different port number for each worker.
|
| 115 |
+
```Shell
|
| 116 |
+
python -m llava.serve.model_worker --host 0.0.0.0 --controller http://localhost:10000 --port <different from 40000, say 40001> --worker http://localhost:<change accordingly, i.e. 40001> --model-path <ckpt2>
|
| 117 |
+
```
|
| 118 |
+
|
| 119 |
+
If you are using an Apple device with an M1 or M2 chip, you can specify the mps device by using the `--device` flag: `--device mps`.
|
| 120 |
+
|
| 121 |
+
#### Launch a model worker (Multiple GPUs, when GPU VRAM <= 24GB)
|
| 122 |
+
|
| 123 |
+
If the VRAM of your GPU is less than 24GB (e.g., RTX 3090, RTX 4090, etc.), you may try running it with multiple GPUs. Our latest code base will automatically try to use multiple GPUs if you have more than one GPU. You can specify which GPUs to use with `CUDA_VISIBLE_DEVICES`. Below is an example of running with the first two GPUs.
|
| 124 |
+
|
| 125 |
+
```Shell
|
| 126 |
+
CUDA_VISIBLE_DEVICES=0,1 python -m llava.serve.model_worker --host 0.0.0.0 --controller http://localhost:10000 --port 40000 --worker http://localhost:40000 --model-path liuhaotian/llava-v1.5-13b
|
| 127 |
+
```
|
| 128 |
+
|
| 129 |
+
#### Launch a model worker (4-bit, 8-bit inference, quantized)
|
| 130 |
+
|
| 131 |
+
You can launch the model worker with quantized bits (4-bit, 8-bit), which allows you to run the inference with reduced GPU memory footprint, potentially allowing you to run on a GPU with as few as 12GB VRAM. Note that inference with quantized bits may not be as accurate as the full-precision model. Simply append `--load-4bit` or `--load-8bit` to the **model worker** command that you are executing. Below is an example of running with 4-bit quantization.
|
| 132 |
+
|
| 133 |
+
```Shell
|
| 134 |
+
python -m llava.serve.model_worker --host 0.0.0.0 --controller http://localhost:10000 --port 40000 --worker http://localhost:40000 --model-path liuhaotian/llava-v1.5-13b --load-4bit
|
| 135 |
+
```
|
| 136 |
+
|
| 137 |
+
#### Launch a model worker (LoRA weights, unmerged)
|
| 138 |
+
|
| 139 |
+
You can launch the model worker with LoRA weights, without merging them with the base checkpoint, to save disk space. There will be additional loading time, while the inference speed is the same as the merged checkpoints. Unmerged LoRA checkpoints do not have `lora-merge` in the model name, and are usually much smaller (less than 1GB) than the merged checkpoints (13G for 7B, and 25G for 13B).
|
| 140 |
+
|
| 141 |
+
To load unmerged LoRA weights, you simply need to pass an additional argument `--model-base`, which is the base LLM that is used to train the LoRA weights. You can check the base LLM of each LoRA weights in the [model zoo](https://github.com/haotian-liu/LLaVA/blob/main/docs/MODEL_ZOO.md).
|
| 142 |
+
|
| 143 |
+
```Shell
|
| 144 |
+
python -m llava.serve.model_worker --host 0.0.0.0 --controller http://localhost:10000 --port 40000 --worker http://localhost:40000 --model-path liuhaotian/llava-v1-0719-336px-lora-vicuna-13b-v1.3 --model-base lmsys/vicuna-13b-v1.3
|
| 145 |
+
```
|
| 146 |
+
|
| 147 |
+
### CLI Inference
|
| 148 |
+
|
| 149 |
+
Chat about images using LLaVA without the need of Gradio interface. It also supports multiple GPUs, 4-bit and 8-bit quantized inference. With 4-bit quantization, for our LLaVA-1.5-7B, it uses less than 8GB VRAM on a single GPU.
|
| 150 |
+
|
| 151 |
+
```Shell
|
| 152 |
+
python -m llava.serve.cli \
|
| 153 |
+
--model-path liuhaotian/llava-v1.5-7b \
|
| 154 |
+
--image-file "https://llava-vl.github.io/static/images/view.jpg" \
|
| 155 |
+
--load-4bit
|
| 156 |
+
```
|
| 157 |
+
|
| 158 |
+
<img src="images/demo_cli.gif" width="70%">
|
| 159 |
+
|
| 160 |
+
## Train
|
| 161 |
+
|
| 162 |
+
LLaVA training consists of two stages: (1) feature alignment stage: use approximately 600K filtered CC3M to connect a *frozen pretrained* vision encoder to a *frozen LLM*; (2) visual instruction tuning stage: use 150K GPT-generated multimodal instruction-following to teach the model to follow multimodal instructions.
|
| 163 |
+
|
| 164 |
+
LLaVA is trained on 8 A100 GPUs with 80GB memory. To train on fewer GPUs, you can reduce the `per_device_train_batch_size` and increase the `gradient_accumulation_steps` accordingly. Always keep the global batch size the same: `per_device_train_batch_size` x `gradient_accumulation_steps` x `num_gpus`.
|
| 165 |
+
|
| 166 |
+
### Hyperparameters
|
| 167 |
+
We use a similar set of hyperparameters as Vicuna in finetuning. Both hyperparameters used in pretraining and finetuning are provided below.
|
| 168 |
+
|
| 169 |
+
1. Pretraining
|
| 170 |
+
|
| 171 |
+
| Hyperparameter | Global Batch Size | Learning rate | Epochs | Max length | Weight decay |
|
| 172 |
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
| 173 |
+
| LLaVA-13B | 256 | 1e-3 | 1 | 2048 | 0 |
|
| 174 |
+
|
| 175 |
+
2. Finetuning
|
| 176 |
+
|
| 177 |
+
| Hyperparameter | Global Batch Size | Learning rate | Epochs | Max length | Weight decay |
|
| 178 |
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
| 179 |
+
| LLaVA-13B | 128 | 2e-5 | 1 | 2048 | 0 |
|
| 180 |
+
|
| 181 |
+
### Prepare Vicuna checkpoints
|
| 182 |
+
|
| 183 |
+
Before you start, prepare our base model Vicuna, which is an instruction-tuned chatbot. Please download its weights [here](https://github.com/lm-sys/FastChat#model-weights).
|
| 184 |
+
|
| 185 |
+
Vicuna has two versions: v0 and v1, the main difference between them is the prompt of format. We support both. To ensure the best performance, you need to specify the correct prompt version corresponding to the weights you download: `v0` for `v0` weights, and `v1` for all Vicuna `v1.x` models.
|
| 186 |
+
|
| 187 |
+
### Pretrain (feature alignment)
|
| 188 |
+
|
| 189 |
+
Please download the subset of the CC3M dataset we use in the paper [here](https://huggingface.co/datasets/liuhaotian/LLaVA-CC3M-Pretrain-595K).
|
| 190 |
+
|
| 191 |
+
Pretrain takes around 4 hours for LLaVA-13B on 8x A100 (80G). It takes around 2 hours for 7B checkpoints.
|
| 192 |
+
|
| 193 |
+
We recommend training with DeepSpeed as it can save a lot of GPU RAM. We provide training script with DeepSpeed [here](https://github.com/haotian-liu/LLaVA/blob/main/scripts/pretrain.sh).
|
| 194 |
+
|
| 195 |
+
You may run this with a single A100 GPU with the following code. Please note that the `per_device_train_batch_size` * `gradient_accumulation_steps` should be equal to 128 to keep the global batch size the same.
|
| 196 |
+
|
| 197 |
+
<details>
|
| 198 |
+
<summary>Pretrain: LLaVA-13B, 1x A100 (80G). Time: ~33 hours.</summary>
|
| 199 |
+
|
| 200 |
+
```Shell
|
| 201 |
+
python llava/train/train_mem.py \
|
| 202 |
+
--model_name_or_path ./checkpoints/vicuna-13b \
|
| 203 |
+
--version [v0 or v1] \
|
| 204 |
+
--data_path /path/to/cc3m_595k.json \
|
| 205 |
+
--image_folder /path/to/cc3m_595k_images \
|
| 206 |
+
--vision_tower openai/clip-vit-large-patch14 \
|
| 207 |
+
--tune_mm_mlp_adapter True \
|
| 208 |
+
--mm_vision_select_layer -2 \
|
| 209 |
+
--mm_use_im_start_end False \
|
| 210 |
+
--mm_use_im_patch_token False \
|
| 211 |
+
--bf16 True \
|
| 212 |
+
--output_dir ./checkpoints/llava-13b-pretrain \
|
| 213 |
+
--num_train_epochs 1 \
|
| 214 |
+
--per_device_train_batch_size 16 \
|
| 215 |
+
--per_device_eval_batch_size 4 \
|
| 216 |
+
--gradient_accumulation_steps 8 \
|
| 217 |
+
--evaluation_strategy "no" \
|
| 218 |
+
--save_strategy "steps" \
|
| 219 |
+
--save_steps 2400 \
|
| 220 |
+
--save_total_limit 1 \
|
| 221 |
+
--learning_rate 2e-3 \
|
| 222 |
+
--weight_decay 0. \
|
| 223 |
+
--warmup_ratio 0.03 \
|
| 224 |
+
--lr_scheduler_type "cosine" \
|
| 225 |
+
--logging_steps 1 \
|
| 226 |
+
--tf32 True \
|
| 227 |
+
--model_max_length 2048 \
|
| 228 |
+
--gradient_checkpointing True \
|
| 229 |
+
--lazy_preprocess True \
|
| 230 |
+
--report_to wandb
|
| 231 |
+
```
|
| 232 |
+
</details>
|
| 233 |
+
|
| 234 |
+
|
| 235 |
+
### Visual Instruction Tuning
|
| 236 |
+
|
| 237 |
+
1. Prepare data
|
| 238 |
+
|
| 239 |
+
Please download the annotation of our instruction tuning data [llava_instruct_158k.json](https://huggingface.co/datasets/liuhaotian/LLaVA-Instruct-150K/blob/main/llava_instruct_150k.json), and download the COCO train2017 images [here](https://cocodataset.org/#download).
|
| 240 |
+
|
| 241 |
+
2. Start training!
|
| 242 |
+
|
| 243 |
+
You may download our pretrained projectors in [Model Zoo](https://github.com/haotian-liu/LLaVA/blob/main/docs/MODEL_ZOO.md). It is not recommended to use legacy projectors, as they may be trained with a different version of the codebase, and if any option is off, the model will not function/train as we expected.
|
| 244 |
+
|
| 245 |
+
When we initially released our paper, we used a full 3-epoch schedule on the LLaVA-Instruct-158K dataset. The scripts are provided [here](https://github.com/haotian-liu/LLaVA/blob/main/scripts/finetune_full_schedule.sh).
|
| 246 |
+
|
| 247 |
+
In our later exploration, we introduced LLaVA-Lightning, as we find that a much faster 1-epoch schedule on LLaVA-Instruct-80K can achieve fast convergence and good performance. With LLaVA Lightning, we are able to train, validate, and release LLaVA-LLaMA-2 checkpoints preview on the same day as LLaMA-2 release. If you are interested to learn more about LLaVA Lightning, please continue to the following section.
|
| 248 |
+
|
| 249 |
+
### Lightning
|
| 250 |
+
|
| 251 |
+
LLaVA-Lightning can be trained on 8x A100 GPUs in just 3 hours, including both pretraining and finetuning. When using spot instances, it costs just ~$40.
|
| 252 |
+
|
| 253 |
+
For LLaVA Lightning, we create two distilled subset to ensure both a broad concept coverage, and the efficiency in training. Furthermore, we only perform instruction tuning for 1 epoch, in contrast to 3 epochs in the paper. We find such schedule is effective and can achieve fast convergence and good performance.
|
| 254 |
+
|
| 255 |
+
For pretraining, we create a concept-balanced subset of LAION-CC-SBU. It consists of 558K images. Download data [here](https://huggingface.co/datasets/liuhaotian/LLaVA-Pretrain/tree/main).
|
| 256 |
+
|
| 257 |
+
For instruction tuning, we create a subset of LLaVA-Instruct-150K. It consists of 80K image-instruction pairs, consisting of 40K conversation and 40K complex reasoning data, with non-overlapping images. Download `llava_instruct_80k.json` [here](https://huggingface.co/datasets/liuhaotian/LLaVA-Instruct-150K/blob/main/llava_instruct_80k.json).
|
| 258 |
+
|
| 259 |
+
#### Hyperparameters
|
| 260 |
+
|
| 261 |
+
1. Pretraining ([script](https://github.com/haotian-liu/LLaVA/blob/main/scripts/pretrain.sh))
|
| 262 |
+
|
| 263 |
+
| Hyperparameter | Global Batch Size | Learning rate | Epochs | Max length | Weight decay |
|
| 264 |
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
| 265 |
+
| LLaVA-Lightning | 128 | 2e-3 | 1 | 2048 | 0 |
|
| 266 |
+
|
| 267 |
+
2. Visual Instruction Tuning ([script](https://github.com/haotian-liu/LLaVA/blob/main/scripts/finetune.sh))
|
| 268 |
+
|
| 269 |
+
| Hyperparameter | Global Batch Size | Learning rate | Epochs | Max length | Weight decay |
|
| 270 |
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
| 271 |
+
| LLaVA-Lightning | 128 | 2e-5 | 1 | 2048 | 0 |
|
| 272 |
+
|
| 273 |
+
#### LLaVA-MPT-7b
|
| 274 |
+
Thanks to LLaVA-Lightning, we are able to train a checkpoint based on MPT-7B-Chat on 8x A100 GPUs in just 3 hours, including both pretraining and finetuning.
|
| 275 |
+
|
| 276 |
+
**NOTE**: This is a research preview of the LLaVA-Lightning based on MPT-7B-chat checkpoint. The usage of the model should comply with MPT-7B-chat license and agreements.
|
| 277 |
+
|
| 278 |
+
1. Usage
|
| 279 |
+
|
| 280 |
+
You do not need to download our checkpoint, it will directly load from our Hugging Face model: [`liuhaotian/LLaVA-Lightning-MPT-7B-preview`](https://huggingface.co/liuhaotian/LLaVA-Lightning-MPT-7B-preview).
|
| 281 |
+
|
| 282 |
+
```Shell
|
| 283 |
+
python -m llava.serve.controller --host 0.0.0.0 --port 10000
|
| 284 |
+
python -m llava.serve.model_worker --host 0.0.0.0 --controller http://localhost:10000 --port 40000 --worker http://localhost:40000 --model-path liuhaotian/LLaVA-Lightning-MPT-7B-preview
|
| 285 |
+
python -m llava.serve.gradio_web_server --controller http://localhost:10000
|
| 286 |
+
```
|
| 287 |
+
|
| 288 |
+
2. Training
|
| 289 |
+
|
| 290 |
+
We use the same set of training dataset, and the hyperparameters as other *Lightning* checkpoints.
|
| 291 |
+
|
| 292 |
+
## Evaluation
|
| 293 |
+
|
| 294 |
+
### GPT-assisted Evaluation
|
| 295 |
+
|
| 296 |
+
Our GPT-assisted evaluation pipeline for multimodal modeling is provided for a comprehensive understanding of the capabilities of vision-language models. Please see our paper for more details.
|
| 297 |
+
|
| 298 |
+
1. Generate LLaVA responses
|
| 299 |
+
|
| 300 |
+
```Shell
|
| 301 |
+
python model_vqa.py \
|
| 302 |
+
--model-path ./checkpoints/LLaVA-13B-v0 \
|
| 303 |
+
--question-file \
|
| 304 |
+
playground/data/coco2014_val_qa_eval/qa90_questions.jsonl \
|
| 305 |
+
--image-folder \
|
| 306 |
+
/path/to/coco2014_val \
|
| 307 |
+
--answers-file \
|
| 308 |
+
/path/to/answer-file-our.jsonl
|
| 309 |
+
```
|
| 310 |
+
|
| 311 |
+
2. Evaluate the generated responses. In our case, [`answer-file-ref.jsonl`](./playground/data/coco2014_val_qa_eval/qa90_gpt4_answer.jsonl) is the response generated by text-only GPT-4 (0314), with the context captions/boxes provided.
|
| 312 |
+
|
| 313 |
+
```Shell
|
| 314 |
+
OPENAI_API_KEY="sk-***********************************" python llava/eval/eval_gpt_review_visual.py \
|
| 315 |
+
--question playground/data/coco2014_val_qa_eval/qa90_questions.jsonl \
|
| 316 |
+
--context llava/eval/table/caps_boxes_coco2014_val_80.jsonl \
|
| 317 |
+
--answer-list \
|
| 318 |
+
/path/to/answer-file-ref.jsonl \
|
| 319 |
+
/path/to/answer-file-our.jsonl \
|
| 320 |
+
--rule llava/eval/table/rule.json \
|
| 321 |
+
--output /path/to/review.json
|
| 322 |
+
```
|
| 323 |
+
|
| 324 |
+
3. Summarize the evaluation results
|
| 325 |
+
|
| 326 |
+
```Shell
|
| 327 |
+
python summarize_gpt_review.py
|
| 328 |
+
```
|
| 329 |
+
|
| 330 |
+
## ScienceQA
|
| 331 |
+
|
| 332 |
+
Please check out the documentation [here](https://github.com/haotian-liu/LLaVA/blob/main/docs/ScienceQA.md).
|
| 333 |
+
|
| 334 |
+
## Citation
|
| 335 |
+
|
| 336 |
+
If you find LLaVA useful for your research and applications, please cite using this BibTeX:
|
| 337 |
+
```bibtex
|
| 338 |
+
|
| 339 |
+
@misc{liu2023improvedllava,
|
| 340 |
+
title={Improved Baselines with Visual Instruction Tuning},
|
| 341 |
+
author={Liu, Haotian and Li, Chunyuan and Li, Yuheng and Lee, Yong Jae},
|
| 342 |
+
publisher={arXiv:2310.03744},
|
| 343 |
+
year={2023},
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
@misc{liu2023llava,
|
| 347 |
+
title={Visual Instruction Tuning},
|
| 348 |
+
author={Liu, Haotian and Li, Chunyuan and Wu, Qingyang and Lee, Yong Jae},
|
| 349 |
+
publisher={arXiv:2304.08485},
|
| 350 |
+
year={2023},
|
| 351 |
+
}
|
| 352 |
+
```
|
| 353 |
+
|
| 354 |
+
## Acknowledgement
|
| 355 |
+
|
| 356 |
+
- [Vicuna](https://github.com/lm-sys/FastChat): the codebase we built upon, and our base model Vicuna-13B that has the amazing language capabilities!
|
| 357 |
+
|
| 358 |
+
## Related Projects
|
| 359 |
+
|
| 360 |
+
- [Instruction Tuning with GPT-4](https://github.com/Instruction-Tuning-with-GPT-4/GPT-4-LLM)
|
| 361 |
+
- [LLaVA-Med: Training a Large Language-and-Vision Assistant for Biomedicine in One Day](https://github.com/microsoft/LLaVA-Med)
|
| 362 |
+
- [Otter: In-Context Multi-Modal Instruction Tuning](https://github.com/Luodian/Otter)
|
| 363 |
+
|
| 364 |
+
For future project ideas, please check out:
|
| 365 |
+
- [SEEM: Segment Everything Everywhere All at Once](https://github.com/UX-Decoder/Segment-Everything-Everywhere-All-At-Once)
|
| 366 |
+
- [Grounded-Segment-Anything](https://github.com/IDEA-Research/Grounded-Segment-Anything) to detect, segment, and generate anything by marrying [Grounding DINO](https://github.com/IDEA-Research/GroundingDINO) and [Segment-Anything](https://github.com/facebookresearch/segment-anything).
|
approach/vlm/LLaVA/pyproject.toml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[build-system]
|
| 2 |
+
requires = ["setuptools>=61.0"]
|
| 3 |
+
build-backend = "setuptools.build_meta"
|
| 4 |
+
|
| 5 |
+
[project]
|
| 6 |
+
name = "llava"
|
| 7 |
+
version = "1.1.0"
|
| 8 |
+
description = "Towards GPT-4 like large language and visual assistant."
|
| 9 |
+
readme = "README.md"
|
| 10 |
+
requires-python = ">=3.8"
|
| 11 |
+
classifiers = [
|
| 12 |
+
"Programming Language :: Python :: 3",
|
| 13 |
+
"License :: OSI Approved :: Apache Software License",
|
| 14 |
+
]
|
| 15 |
+
dependencies = [
|
| 16 |
+
"einops", "fastapi", "gradio==3.35.2", "markdown2[all]", "numpy",
|
| 17 |
+
"requests", "sentencepiece", "tokenizers>=0.12.1",
|
| 18 |
+
"torch==2.0.1", "torchvision==0.15.2", "uvicorn", "wandb",
|
| 19 |
+
"shortuuid", "httpx==0.24.0",
|
| 20 |
+
"deepspeed==0.9.5",
|
| 21 |
+
"peft==0.4.0",
|
| 22 |
+
"transformers==4.31.0",
|
| 23 |
+
"accelerate==0.21.0",
|
| 24 |
+
"bitsandbytes==0.41.0",
|
| 25 |
+
"scikit-learn==1.2.2",
|
| 26 |
+
"sentencepiece==0.1.99",
|
| 27 |
+
"einops==0.6.1", "einops-exts==0.0.4", "timm==0.6.13",
|
| 28 |
+
"gradio_client==0.2.9"
|
| 29 |
+
]
|
| 30 |
+
|
| 31 |
+
[project.urls]
|
| 32 |
+
"Homepage" = "https://llava-vl.github.io"
|
| 33 |
+
"Bug Tracker" = "https://github.com/haotian-liu/LLaVA/issues"
|
| 34 |
+
|
| 35 |
+
[tool.setuptools.packages.find]
|
| 36 |
+
exclude = ["assets*", "benchmark*", "docs", "dist*", "playground*", "scripts*", "tests*"]
|
| 37 |
+
|
| 38 |
+
[tool.wheel]
|
| 39 |
+
exclude = ["assets*", "benchmark*", "docs", "dist*", "playground*", "scripts*", "tests*"]
|
approach/vlm/gpt4v/cu_gpt4v.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Compatibility wrapper for the former CUHK-specific GPT-4V adapter."""
|
| 2 |
+
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
from approach.vlm.gpt4v.gpt4v import (
|
| 6 |
+
encode_image,
|
| 7 |
+
generate_gpt4v_prompt,
|
| 8 |
+
get_steam_app_data,
|
| 9 |
+
process_image as _process_image,
|
| 10 |
+
process_image_q,
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def process_image(image_question, image_path, ablation, key_idx=0):
|
| 15 |
+
profile = os.environ.get("ORIENT_MODEL_PROFILE", "default")
|
| 16 |
+
return _process_image(profile, image_question, image_path, ablation, key_idx)
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
__all__ = [
|
| 20 |
+
"encode_image",
|
| 21 |
+
"generate_gpt4v_prompt",
|
| 22 |
+
"get_steam_app_data",
|
| 23 |
+
"process_image",
|
| 24 |
+
"process_image_q",
|
| 25 |
+
]
|
approach/vlm/gpt4v/gpt4v.py
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import base64
|
| 3 |
+
import mimetypes
|
| 4 |
+
import requests
|
| 5 |
+
import logging
|
| 6 |
+
from bs4 import BeautifulSoup
|
| 7 |
+
from approach.app_metadata import get_app_metadata, load_app_metadata_cache
|
| 8 |
+
from approach.config import get_model_profile
|
| 9 |
+
from approach.providers import EncodedImage, OpenAICompatibleChatClient
|
| 10 |
+
|
| 11 |
+
DEFAULT_PROFILE = os.environ.get("ORIENT_MODEL_PROFILE", "default")
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def _app_metadata_from_cache(app_id, metadata_cache):
|
| 15 |
+
return get_app_metadata(app_id, metadata_cache)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def get_steam_app_data(app_id, image_name, metadata_cache=None):
|
| 19 |
+
if metadata_cache is not None:
|
| 20 |
+
return _app_metadata_from_cache(app_id, metadata_cache)
|
| 21 |
+
|
| 22 |
+
if app_id == '1718650':
|
| 23 |
+
app_name = 'Nuremberg: VRdict of Nations'
|
| 24 |
+
app_description = 'A VR investigation of the crimes against humanity committed by the Nazi leaders. This is a detective story in VR, a documentary investigation, brought to you by Rossiya Segodnya. Your goal is to find and collect evidence to prove that the key Nazi criminals and the leaders of the Third Reich are guilty. Today, less than 50% of young people are familiar with the historic Nuremberg trial, its process and results (according to a survey conducted by the “Nuremberg: Casus Pacis” project). The charges and verdicts brought forward by the Nuremberg tribunal, its fairness or even necessity are often questioned. This happens out of ignorance or under pressure from those who benefit from distorting the historical facts. Your virtual journey begins in the Spandau Prison dining area recreated from one of the legendary post-war photos. Here, you are met by serenely dining Nuremberg defendants – Göring, Dönitz, Rosenberg, von Ribbentrop and von Schirach. By touching each of them, you can travel back to these Nazi criminals’ past. Your task is to find evidence of their terrible crimes against humanity in – seemingly – an ordinary and peaceful environment. As you gather more pieces of evidence, you put together a convincing dossier, akin to those ones that the 1946 Nuremberg verdict was based on. Thus you will restore the historical truth.'
|
| 25 |
+
return app_name, app_description
|
| 26 |
+
|
| 27 |
+
url = f"https://store.steampowered.com/app/{app_id}"
|
| 28 |
+
|
| 29 |
+
# proxies = {
|
| 30 |
+
# "http": f"http://{proxy}",
|
| 31 |
+
# "https": f"http://{proxy}"
|
| 32 |
+
# }
|
| 33 |
+
|
| 34 |
+
headers = {
|
| 35 |
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
try:
|
| 39 |
+
response = requests.get(url, headers=headers, timeout=30)
|
| 40 |
+
response.raise_for_status()
|
| 41 |
+
|
| 42 |
+
soup = BeautifulSoup(response.content, "html.parser")
|
| 43 |
+
|
| 44 |
+
app_name = soup.find("div", {"id": "appHubAppName"}).get_text(strip=True)
|
| 45 |
+
short_desc = soup.find("div", class_="game_description_snippet").get_text(strip=True)
|
| 46 |
+
long_desc = soup.find("div", {"id": "game_area_description"}).get_text(strip=True)
|
| 47 |
+
|
| 48 |
+
return app_name, short_desc + " " + long_desc
|
| 49 |
+
except Exception as e:
|
| 50 |
+
# print(f"Error fetching app data for app_id {app_id} of image {image_name}. Error: {e}")
|
| 51 |
+
logging.error(f"Error fetching app data for app_id {app_id} of image {image_name}. Error: {e}")
|
| 52 |
+
return "", ""
|
| 53 |
+
|
| 54 |
+
# Function to encode the image
|
| 55 |
+
def encode_image(image_path):
|
| 56 |
+
with open(image_path, "rb") as image_file:
|
| 57 |
+
return base64.b64encode(image_file.read()).decode('utf-8')
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def generate_gpt4v_prompt(app_name, app_description, image_question, ablation):
|
| 61 |
+
if ablation:
|
| 62 |
+
# ISSTA version
|
| 63 |
+
# return 'Describe the image.'
|
| 64 |
+
|
| 65 |
+
# ICSE 2025 version
|
| 66 |
+
return f'''
|
| 67 |
+
--- Context and Task ---
|
| 68 |
+
You are a virtual reality game player.
|
| 69 |
+
Currently, you are playing a game named {app_name} with the following description. Now in your field of view from the VR headset, you can see the VR scenario as the uploaded screenshot figure.
|
| 70 |
+
Please write referring expressions for all objects in the scenario.
|
| 71 |
+
For referring expressions, describe all characteristics from different perspectives that make the object distinguishable from other objects such as <size, color, shape and type>.
|
| 72 |
+
DO NOT MENTION LOCATION INFORMATION OR MENTION OTHER OBJECTS IN REFERRING EXPRESSIONS!\n
|
| 73 |
+
|
| 74 |
+
--- Instructions and Demonstrations ---
|
| 75 |
+
Ignore user-controlled VR device objects, e.g., controllers, hands and gloves, which are near the users in screenshot.\n
|
| 76 |
+
|
| 77 |
+
--- Output Format ---
|
| 78 |
+
Output in JSON format: {{"objects": {{"here_is_object_name": referring_expression_1, "here_is_object_name": referring_expression_2}}}}. NO DOT OUTPUT any other content besides JSON.\n
|
| 79 |
+
|
| 80 |
+
--- App Description Information ---
|
| 81 |
+
The description of the app:
|
| 82 |
+
{app_description}.
|
| 83 |
+
'''
|
| 84 |
+
elif not ablation:
|
| 85 |
+
# ISSTA 2024 version
|
| 86 |
+
# return f'''
|
| 87 |
+
# You are a virtual reality game player. Currently, you are playing a game named {app_name} with the following description and get the screenshot I uploaded. Please describe all objects in the screenshot.
|
| 88 |
+
|
| 89 |
+
# The description of the app:
|
| 90 |
+
# {app_description}.
|
| 91 |
+
# '''
|
| 92 |
+
|
| 93 |
+
# ICSE 2025 version
|
| 94 |
+
return f'''
|
| 95 |
+
--- Context and Task ---
|
| 96 |
+
You are a virtual reality game player.
|
| 97 |
+
Currently, you are playing a game named {app_name} with the following description. Now in your field of view from the VR headset, you can see the VR scenario as the uploaded screenshot figure.
|
| 98 |
+
Please: (1) identify all user-interactable objects in this screenshot, with which you can use VR devices like handheld controllers to interact; and (2) write referring expressions for user-interactable objects.
|
| 99 |
+
For referring expressions, describe all characteristics from different perspectives that make the object distinguishable from other objects such as <size, color, shape and type>.
|
| 100 |
+
DO NOT MENTION LOCATION INFORMATION OR MENTION OTHER OBJECTS IN REFERRING EXPRESSIONS!\n
|
| 101 |
+
|
| 102 |
+
--- Instructions and Demonstrations ---
|
| 103 |
+
(1) For a tree object in a tree-planting game, the users need to pick up and plant the tree, thus the object is interactable.
|
| 104 |
+
(2) But for a tree object appeard in the background scenery of a fishing-only game, the object is highly likely non-interactable.
|
| 105 |
+
(3) Ignore user-controlled VR device objects, e.g., controllers, hands and gloves, which are near the users in screenshot.\n
|
| 106 |
+
|
| 107 |
+
--- Output Format ---
|
| 108 |
+
Output in JSON format: {{"objects": {{"here_is_object_name": referring_expression_1, "here_is_object_name": referring_expression_2}}}}. NO DOT OUTPUT any other content besides JSON.\n
|
| 109 |
+
|
| 110 |
+
--- App Description Information ---
|
| 111 |
+
The description of the app:
|
| 112 |
+
{app_description}.
|
| 113 |
+
'''
|
| 114 |
+
|
| 115 |
+
def process_image_q(image_question, image_path, key_idx, metadata_cache=None):
|
| 116 |
+
# time.sleep(2)
|
| 117 |
+
app_id = image_path.split('/')[-1].split("_")[0]
|
| 118 |
+
# print(app_id)
|
| 119 |
+
app_name, app_description = get_steam_app_data(app_id, image_path, metadata_cache)
|
| 120 |
+
|
| 121 |
+
gpt4v_prompt = generate_gpt4v_prompt(app_name, app_description, image_question, True)
|
| 122 |
+
|
| 123 |
+
return gpt4v_prompt
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def process_image(vlm, image_question, image_path, ablation, key_idx, metadata_cache=None):
|
| 128 |
+
app_id = image_path.split('/')[-1].split("_")[0]
|
| 129 |
+
# print(app_id)
|
| 130 |
+
app_name, app_description = get_steam_app_data(app_id, image_path, metadata_cache)
|
| 131 |
+
|
| 132 |
+
# Getting the base64 string
|
| 133 |
+
base64_image = encode_image(image_path)
|
| 134 |
+
|
| 135 |
+
gpt4v_prompt = generate_gpt4v_prompt(app_name, app_description, image_question, ablation)
|
| 136 |
+
# gpt4v_prompt = image_question
|
| 137 |
+
|
| 138 |
+
try:
|
| 139 |
+
profile = get_model_profile(vlm or DEFAULT_PROFILE)
|
| 140 |
+
media_type = mimetypes.guess_type(image_path)[0] or "image/jpeg"
|
| 141 |
+
client = OpenAICompatibleChatClient(profile)
|
| 142 |
+
return client.complete_json(
|
| 143 |
+
gpt4v_prompt,
|
| 144 |
+
[EncodedImage(base64_image, media_type)],
|
| 145 |
+
)
|
| 146 |
+
except Exception as e:
|
| 147 |
+
logging.error(f"Error generating completion for image {image_path}. Error: {e}")
|
| 148 |
+
return ''
|
configs/model_profiles.yaml
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
profiles:
|
| 2 |
+
default:
|
| 3 |
+
provider: openrouter
|
| 4 |
+
model: openai/gpt-5.6-sol
|
| 5 |
+
base_url: https://openrouter.ai/api/v1
|
| 6 |
+
api_key_env: OPENROUTER_API_KEY
|
| 7 |
+
best_value:
|
| 8 |
+
provider: openrouter
|
| 9 |
+
model: openai/gpt-5.6-terra
|
| 10 |
+
base_url: https://openrouter.ai/api/v1
|
| 11 |
+
api_key_env: OPENROUTER_API_KEY
|
| 12 |
+
paper_openai:
|
| 13 |
+
provider: openrouter
|
| 14 |
+
model: openai/gpt-4o-2024-08-06
|
| 15 |
+
base_url: https://openrouter.ai/api/v1
|
| 16 |
+
api_key_env: OPENROUTER_API_KEY
|
| 17 |
+
paper_claude:
|
| 18 |
+
provider: openrouter
|
| 19 |
+
model: anthropic/claude-3.5-sonnet
|
| 20 |
+
base_url: https://openrouter.ai/api/v1
|
| 21 |
+
api_key_env: OPENROUTER_API_KEY
|
| 22 |
+
paper_gemini:
|
| 23 |
+
provider: openrouter
|
| 24 |
+
model: google/gemini-pro-1.5
|
| 25 |
+
base_url: https://openrouter.ai/api/v1
|
| 26 |
+
api_key_env: OPENROUTER_API_KEY
|
| 27 |
+
fastuse_experimental:
|
| 28 |
+
provider: openrouter
|
| 29 |
+
model: google/gemini-3.1-pro-preview
|
| 30 |
+
base_url: https://openrouter.ai/api/v1
|
| 31 |
+
api_key_env: OPENROUTER_API_KEY
|
dataset/statistics/app_genre.csv
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
id,genre
|
| 2 |
+
1026760,Casual
|
| 3 |
+
1033960,Casual
|
| 4 |
+
1063530,Adventure
|
| 5 |
+
1113370,Action
|
| 6 |
+
1150310,Sports
|
| 7 |
+
1157070,Casual
|
| 8 |
+
1172280,Casual
|
| 9 |
+
1178780,Strategy
|
| 10 |
+
1210650,Adventure
|
| 11 |
+
1217930,Indie
|
| 12 |
+
1245640,Adventure
|
| 13 |
+
1248270,Adventure
|
| 14 |
+
1250210,Action
|
| 15 |
+
1264160,Simulation
|
| 16 |
+
1269890,Action
|
| 17 |
+
1270910,Simulation
|
| 18 |
+
1295570,Indie
|
| 19 |
+
1298890,Adventure
|
| 20 |
+
1334900,Indie
|
| 21 |
+
1337060,Education
|
| 22 |
+
1337530,Adventure
|
| 23 |
+
1382350,Adventure
|
| 24 |
+
1388030,Sports
|
| 25 |
+
1394210,Action
|
| 26 |
+
1394410,Action
|
| 27 |
+
1404360,Adventure
|
| 28 |
+
1453730,Casual
|
| 29 |
+
1456280,Action
|
| 30 |
+
1480650,Adventure
|
| 31 |
+
1481400,Adventure
|
| 32 |
+
1485260,Casual
|
| 33 |
+
1486660,Adventure
|
| 34 |
+
1488730,Sports
|
| 35 |
+
1512840,Simulation
|
| 36 |
+
1550280,Action
|
| 37 |
+
1561560,Casual
|
| 38 |
+
1595490,Action
|
| 39 |
+
1601810,Adventure
|
| 40 |
+
1612820,Casual
|
| 41 |
+
1652800,Indie
|
| 42 |
+
1676620,Adventure
|
| 43 |
+
1695870,Indie
|
| 44 |
+
1705030,Action
|
| 45 |
+
1707840,Casual
|
| 46 |
+
1730290,Simulation
|
| 47 |
+
1801560,Action
|
| 48 |
+
1805510,Simulation
|
| 49 |
+
1825460,Simulation
|
| 50 |
+
1862180,Simulation
|
| 51 |
+
1906880,Action
|
| 52 |
+
1931980,Indie
|
| 53 |
+
1960620,Strategy
|
| 54 |
+
2020950,Indie
|
| 55 |
+
2025000,Simulation
|
| 56 |
+
2057000,Simulation
|
| 57 |
+
2077870,Action
|
| 58 |
+
2089520,RPG
|
| 59 |
+
2163140,Adventure
|
| 60 |
+
2193270,Adventure
|
| 61 |
+
2224020,Simulation
|
| 62 |
+
2293180,Action
|
| 63 |
+
2308940,Strategy
|
| 64 |
+
269170,Sports
|
| 65 |
+
343740,Indie
|
| 66 |
+
438100,Massively Multiplayer
|
| 67 |
+
451980,Simulation
|
| 68 |
+
457380,Indie
|
| 69 |
+
457550,Simulation
|
| 70 |
+
463290,Casual
|
| 71 |
+
490250,Simulation
|
| 72 |
+
497820,Simulation
|
| 73 |
+
513490,Indie
|
| 74 |
+
518580,Indie
|
| 75 |
+
528580,Adventure
|
| 76 |
+
529150,Strategy
|
| 77 |
+
533970,Design & Illustration
|
| 78 |
+
591680,Simulation
|
| 79 |
+
600140,Strategy
|
| 80 |
+
605850,Casual
|
| 81 |
+
622310,Casual
|
| 82 |
+
631660,Strategy
|
| 83 |
+
660520,Action
|
| 84 |
+
667010,Action
|
| 85 |
+
714100,Animation & Modeling
|
| 86 |
+
716260,Action
|
| 87 |
+
720300,Adventure
|
| 88 |
+
726910,Casual
|
| 89 |
+
731790,Simulation
|
| 90 |
+
758210,Simulation
|
| 91 |
+
790750,Action
|
| 92 |
+
812460,Indie
|
| 93 |
+
815280,Action
|
| 94 |
+
866540,Adventure
|
| 95 |
+
891960,Simulation
|
| 96 |
+
898080,Indie
|
| 97 |
+
910190,Action
|
| 98 |
+
954160,Indie
|
| 99 |
+
982710,Indie
|
| 100 |
+
997760,Sports
|
| 101 |
+
998660,Simulation
|
dataset/statistics/app_tag.csv
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
id,tag
|
| 2 |
+
1026760,Casual;VR;Immersive;Nature;Cinematic;Free to Play;Early Access;Colorful;3D;360 Video;Experimental;Singleplayer
|
| 3 |
+
1033960,Casual;VR;Time Management;Funny;Family Friendly;Dog
|
| 4 |
+
1063530,Adventure;Action;Indie;Casual;RPG;VR;Free to Play
|
| 5 |
+
1113370,Action;Free to Play;Indie;Casual;Sports;VR;Sci-fi;Real-Time;Stylized;Futuristic;Competitive
|
| 6 |
+
1150310,VR;3D Platformer;Skiing;Sports;Racing;Runner;Immersive Sim;Arcade;Walking Simulator;First-Person;3D;Cute;Time Manipulation;Casual;Cartoony;Colorful;Family Friendly;6DOF;Atmospheric;Nature
|
| 7 |
+
1157070,Casual;Indie;VR;Puzzle;First-Person;Family Friendly;Relaxing;Singleplayer;Atmospheric;Solitaire;Physics;Tabletop
|
| 8 |
+
1172280,Automobile Sim;VR;Experience;Cinematic;Psychedelic;Minimalist;6DOF;Transportation;Psychological Horror;Abstract;Comedy;Experimental;Atmospheric;Surreal;Horror;Casual;Singleplayer;Immersive Sim;Simulation;Indie
|
| 9 |
+
1178780,Space Sim;Space;VR;Multiplayer;Co-op;Sci-fi;First-Person;RTS;Strategy;Singleplayer;Simulation;Real Time Tactics;PvP;Tactical;Action;War;Real-Time;Local Co-Op;Bullet Time;Real-Time with Pause
|
| 10 |
+
1210650,Adventure;Free to Play;Indie;VR;Singleplayer;Escape Room
|
| 11 |
+
1217930,VR;Flight;Multiplayer;Shooter;Simulation;Space Sim;FPS;Battle Royale;Action;Adventure;Massively Multiplayer;Indie;Early Access;Fantasy;Twin Stick Shooter;Futuristic;Robots;Sci-fi;Space;Surreal
|
| 12 |
+
1245640,Interactive Fiction;VR;Story Rich;Narrative;6DOF;Historical;Education;Emotional;Documentary;First-Person;3D;Cinematic;Linear;Narration;Singleplayer;Feature Film;Adventure;Colorful;Casual;Exploration
|
| 13 |
+
1248270,VR;Free to Play;Exploration;Interactive Fiction;Experience;Singleplayer;Casual;Surreal;Magic;Medieval;Adventure
|
| 14 |
+
1250210,Indie;Action;Massively Multiplayer;Gore;Violent;Early Access;VR;Looter Shooter
|
| 15 |
+
1264160,Immersive Sim;Simulation;Anime;Experience;VR;Comic Book;Cute;Dating Sim;Crowdfunded;FMV;Singleplayer;Realistic;Casual;Atmospheric;Drama;Conversation;Story Rich;Romance;Sexual Content;Funny
|
| 16 |
+
1269890,Education;Arcade;Casual;Free to Play;On-Rails Shooter;Hack and Slash;VR;Action;Singleplayer;Indie;Strategy;RPG;Great Soundtrack
|
| 17 |
+
1270910,Free to Play;Indie;Casual;Simulation;Villain Protagonist;Singleplayer
|
| 18 |
+
1295570,Indie;VR;Story Rich;Atmospheric;Emotional
|
| 19 |
+
1298890,Casual;Exploration;Walking Simulator;VR;Story Rich;Surreal;Atmospheric;Psychological;Adventure;Singleplayer;Narrative;Indie;Mystery
|
| 20 |
+
1334900,Casual;Action;Arcade;VR;Parody;Hack and Slash;Level Editor;Singleplayer;6DOF;Gore;Violent;Indie
|
| 21 |
+
1337060,Education;Science
|
| 22 |
+
1337530,VR;Adventure;Puzzle;Stylized;Open World;Silent Protagonist;Nonlinear;Interactive Fiction;Story Rich;Fantasy;Indie;Narration;Physics;Atmospheric;Singleplayer;Cinematic;Exploration;6DOF;3D;First-Person
|
| 23 |
+
1382350,Adventure;VR;Detective;Puzzle;Strategy;Singleplayer;Mystery;Investigation;Time Travel;Atmospheric;Interactive Fiction;First-Person;Indie;Dark;Supernatural;6DOF;Story Rich
|
| 24 |
+
1388030,Sports;VR;PvP;Realistic;Competitive;Simulation;Physics;Turn-Based Tactics;Casual;Real Time Tactics;3D;Real-Time;Arcade;Funny;Action-Adventure;Multiplayer;Singleplayer;First-Person;Arena Shooter;Grand Strategy
|
| 25 |
+
1394210,Action;VR;Arcade;Shooter;Shoot 'Em Up;Bullet Hell;3D;Aliens;Fantasy;Futuristic;Jet;Mechs;Robots;Sci-fi;Space;Bullet Time;Combat;Flight;PvE;Score Attack
|
| 26 |
+
1394410,Action;VR;Magic;Swordplay;Fighting;PvP;Futuristic;Combat;PvE;Singleplayer;Multiplayer;Spectacle fighter;Sci-fi
|
| 27 |
+
1404360,Casual;VR;Hidden Object;Investigation;Exploration;Collectathon;Cute;Relaxing;Atmospheric;Puzzle;Fantasy;Conversation;Narration;Family Friendly;Nature;Singleplayer;6DOF;Indie;Adventure;Free to Play
|
| 28 |
+
1453730,Casual;Relaxing;Atmospheric;Experimental;Colorful;Psychedelic;Abstract;VR;Space;Free to Play;Family Friendly;Ambient;Early Access;3D;6DOF;Exploration;Education;Singleplayer
|
| 29 |
+
1456280,Action;Fighting;Shooter;3D Fighter;Arena Shooter;VR;Flight;First-Person;Aliens;Cyberpunk;Post-apocalyptic;Sci-fi;PvP;Artificial Intelligence;Multiplayer;Singleplayer
|
| 30 |
+
1480650,Adventure;Action-Adventure;Puzzle;VR;First-Person;Tactical;Snow;Choices Matter;Quick-Time Events;Action;Real Time Tactics;Magic;Fantasy;Survival;Lore-Rich;Arcade;Crafting;Physics;Superhero;Time Manipulation
|
| 31 |
+
1481400,Horror;Lovecraftian;Atmospheric;Visual Novel;First-Person;Story Rich;Psychological Horror;Dark;Narration;Choose Your Own Adventure;VR;Adventure;Interactive Fiction;Point & Click;Mystery;Indie;Walking Simulator;Text-Based;Realistic;Emotional
|
| 32 |
+
1485260,Relaxing;Casual;Abstract;Psychedelic;Experimental;Cinematic;3D Vision;Exploration;3D;Stylized;6DOF;Procedural Generation;Singleplayer;VR
|
| 33 |
+
1486660,Casual;VR;Action;Dragons;Puzzle;Adventure;Exploration;Arcade;Walking Simulator;Education;3D;First-Person;Realistic;Dinosaurs;Logic;3D Vision;Narration;Action-Adventure;Singleplayer;Flight
|
| 34 |
+
1488730,Casual;Simulation;Sports;eSports;Arcade;Immersive Sim;Grand Strategy;3D;VR;Real Time Tactics;Family Friendly;Nature;Physics;Singleplayer
|
| 35 |
+
1512840,Casual;Simulation;Photo Editing;Design & Illustration;Utilities;VR;Experience;Walking Simulator
|
| 36 |
+
1550280,VR;Atmospheric;Casual;Building;LEGO;Simulation;Interactive Fiction;Abstract;Family Friendly;Life Sim;Immersive Sim;Magic;Colorful;Physics;Cute;Sandbox;First-Person;Utilities;Moddable;Space
|
| 37 |
+
1561560,Free to Play;VR;Singleplayer;Time Management;Puzzle;Sandbox;Physics;Casual;Management;Artificial Intelligence;Early Access;Simulation;Life Sim;Arcade;First-Person;Medieval;3D;Cute;Lovecraftian;Cartoony
|
| 38 |
+
1595490,Action Roguelike;VR;Roguelite;Sailing;Perma Death;Arcade;Roguelike;First-Person;3D;Action;Post-apocalyptic;Casual;Cartoony;Dystopian;Management;6DOF;Artificial Intelligence;Resource Management;Singleplayer;Free to Play
|
| 39 |
+
1601810,Adventure;Nature;VR
|
| 40 |
+
1612820,Casual;VR;Funny;Cartoony;Hand-drawn;Arcade;Stylized;Free to Play;Singleplayer
|
| 41 |
+
1652800,Puzzle;Casual;Female Protagonist;3D;First-Person;VR;Linear;Sci-fi;Indie;Science;Singleplayer
|
| 42 |
+
1676620,Adventure;Education;Action-Adventure;Medical Sim;3D;VR;6DOF;Free to Play;Singleplayer
|
| 43 |
+
1695870,Free to Play;VR;Walking Simulator;Singleplayer;Atmospheric;Surreal;Short;Colorful;Immersive;Linear;Stylized;Magic;6DOF;First-Person;Mystery;Relaxing;Exploration;Funny;Adventure;Indie
|
| 44 |
+
1705030,Shooter;Sandbox;Platformer;VR;Multiplayer;Action;Parkour;eSports;Physics;PvP;Arena Shooter;Bullet Hell;FPS;3D;First-Person;Sports;Character Customization;Adventure;3D Platformer;Cartoony
|
| 45 |
+
1707840,Casual;Strategy;Puzzle;Shooter;Match 3;VR;Cartoony;Colorful;Atmospheric;Nature;Relaxing;6DOF;Choices Matter;Singleplayer
|
| 46 |
+
1730290,Casual;Simulation;Arcade;Tabletop;Visual Novel;VR;3D;Abstract;Artificial Intelligence;Free to Play;Sci-fi;Singleplayer
|
| 47 |
+
1801560,Action;Shooter;Rhythm;Shoot 'Em Up;FPS;Bullet Hell;3D;Realistic;Destruction;Singleplayer;VR
|
| 48 |
+
1805510,Action;Simulation;Action-Adventure;Life Sim;Exploration;Immersive Sim;3D;VR;America;Building;Capitalism;Comedy;Story Rich;Trading;Controller;Resource Management;Singleplayer;Indie;Arcade;Dark Humor
|
| 49 |
+
1825460,Simulation;Education;VR;Immersive Sim;3D;Crafting;Realistic;Singleplayer;Hardware
|
| 50 |
+
1862180,Simulation;VR;Space;Immersive Sim;Exploration;Education;Science;Realistic;Sci-fi;Physics;3D;Artificial Intelligence;Atmospheric;Space Sim;Open World;Singleplayer;Difficult;Early Access;Immersive;Golf
|
| 51 |
+
1906880,Casual;Action;VR;Combat;Action-Adventure;First-Person;3D Platformer;FPS;Singleplayer;Hack and Slash;Free to Play;RPG;Indie;3D;War;Martial Arts;Atmospheric;PvE
|
| 52 |
+
1931980,Escape Room;Local Co-Op;VR;Hand-drawn;Investigation;Co-op;Puzzle;Indie;Strategy
|
| 53 |
+
1960620,Strategy;VR;Psychological Horror;Chess;Board Game;Tabletop;Singleplayer;Hentai
|
| 54 |
+
2020950,VR;Emotional;6DOF;Immersive;Colorful;Cinematic;Atmospheric;Story Rich;Electronic Music;Visual Novel;Design & Illustration;Stylized;3D;Audio Production;Singleplayer;Drama;Abstract;First-Person;Casual;Linear
|
| 55 |
+
2025000,VR;Arcade;Simulation;Roguelite;Funny;Management;Job Simulator;Perma Death;Psychedelic;Time Management;Immersive Sim;3D;Cooking;Casual;Physics;Action;Colorful;Indie;Nature;Singleplayer
|
| 56 |
+
2057000,Casual;Simulation;Software;Puzzle;Utilities;Word Game;Immersive Sim;3D;3D Vision;Colorful;VR;First-Person;Education;Foreign;6DOF;Conversation;Open World;PvE;Singleplayer;Early Access
|
| 57 |
+
2077870,Action;Adventure;Simulation;Strategy;Arcade;VR;First-Person;Atmospheric;PvE;Singleplayer;Choices Matter;Dark Humor;Free to Play;FPS;Funny;Futuristic;Memes;Sequel;Shoot 'Em Up;Multiple Endings
|
| 58 |
+
2089520,VR;Massively Multiplayer;Anime;Multiplayer;Funny;3D Platformer;MMORPG;First-Person;Open World;6DOF;Nature;3D;Stylized;Atmospheric;Drama;Story Rich;Cartoon;Co-op;PvP;RPG
|
| 59 |
+
2163140,VR;Puzzle;Singleplayer;Escape Room;Detective;Adventure;Investigation;Historical;Trains;Mystery;Walking Simulator;Exploration;Surreal;Stylized;Interactive Fiction;Hidden Object;Immersive Sim;Colorful;6DOF;Indie
|
| 60 |
+
2193270,Adventure;VR;Historical;Sailing;Casual;Education;Visual Novel;Action-Adventure;Exploration;Immersive Sim;Colorful;First-Person;Stylized;Atmospheric;Diplomacy;Drama;Family Friendly;Political;Choices Matter;Linear
|
| 61 |
+
2224020,Simulation;VR;Life Sim;Immersive Sim;Realistic;Singleplayer;Historical;Atmospheric;Free to Play;3D;Nudity;Walking Simulator;Nonlinear
|
| 62 |
+
2293180,VR;Experimental;Shoot 'Em Up;Singleplayer;Action;Arcade;RPG;Shooter;Zombies;FPS;Combat;Physics;Free to Play;PvE
|
| 63 |
+
2308940,VR;Building;Education;Strategy;LEGO;First-Person;Controller;Simulation;Arcade;Turn-Based Strategy;FPS;Real Time Tactics;Time Management;Colorful;Family Friendly;Logic;Modern;Tactical;6DOF;Base Building
|
| 64 |
+
269170,VR;Snooker;Sports;Simulation;Casual;Pool;Indie;Local Multiplayer;Strategy;Physics;Multiplayer;Addictive
|
| 65 |
+
343740,VR;Free to Play;Indie;Action;Education;Casual;Sci-fi;Singleplayer;Science;Exploration;3D Vision;Dynamic Narration;Funny;Comedy;Racing;Physics;Simulation;Space
|
| 66 |
+
438100,VR;Free to Play;Multiplayer;Memes;Anime;Funny;Massively Multiplayer;First-Person;Early Access;Open World;Simulation;Casual;Adventure;MMORPG;Comedy;Sandbox;Action;Dating Sim;Survival Horror;Atmospheric
|
| 67 |
+
451980,Simulation;Casual;VR;Education;Great Soundtrack;Exploration;First-Person;Physics;Free to Play;Indie;Atmospheric
|
| 68 |
+
457380,Adventure;Simulation;Indie;Casual;VR;Episodic;Survival
|
| 69 |
+
457550,VR;Free to Play;Software;Open World;Utilities;Split Screen;Multiplayer;3D;Movie;First-Person;Choose Your Own Adventure;Casual;Cinematic;Exploration;Simulation;Futuristic;Nature;Relaxing;Sci-fi;Conversation
|
| 70 |
+
463290,VR;Indie;Casual;Immersive;Atmospheric
|
| 71 |
+
490250,Simulation;Indie;Casual;Free to Play;VR;Trains;Relaxing;On-Rails Shooter
|
| 72 |
+
497820,Free to Play;VR;Cyberpunk
|
| 73 |
+
513490,Indie;VR;Historical;Free to Play;Education;World War II
|
| 74 |
+
518580,Indie;VR;Adventure;Comedy;Free to Play;Dark Humor;Horror;Funny;Singleplayer
|
| 75 |
+
528580,Adventure;Free to Play;VR;Early Access;Indie;Casual;Fantasy;Cinematic;First-Person;Dragons;Interactive Fiction;Experimental
|
| 76 |
+
529150,Strategy;Indie;VR;Arcade;RTS;Free to Play
|
| 77 |
+
533970,Design & Illustration;Free to Play;VR;Animation & Modeling
|
| 78 |
+
591680,Simulation;Indie;VR;Physics;Casual;Funny;Addictive;Free to Play;Arcade;Management;FPS;Cartoony;3D;Colorful;Comedy;Dark Humor;Education;Relaxing;Score Attack;Singleplayer
|
| 79 |
+
600140,Free to Play;VR;Strategy;Casual;Indie;Action;Puzzle;Gore;Violent;Escape Room;Sexual Content
|
| 80 |
+
605850,Indie;Casual;VR;Pinball
|
| 81 |
+
622310,Strategy;Free to Play;Massively Multiplayer;Casual;Simulation;VR
|
| 82 |
+
631660,Free to Play;Strategy;Casual;Sports;Tabletop;VR;Chess
|
| 83 |
+
660520,Simulation;Free to Play;Action;Indie;VR;Mechs;Robots
|
| 84 |
+
667010,Action;Indie;Casual;Violent;VR;Cartoony;Dark Comedy;Zombies;Post-apocalyptic;Survival Horror;Vampire;Funny;First-Person;Comedy;Shooter;Blood;Dark Humor;Horror;Sports;1980s
|
| 85 |
+
714100,Animation & Modeling;VR;Anime;Sexual Content;Nudity
|
| 86 |
+
716260,Free to Play;Adventure;Action;Indie;VR;Shooter;Western
|
| 87 |
+
720300,Indie;Adventure;Free to Play;VR;Short;Singleplayer;Sci-fi;Atmospheric;Futuristic;Puzzle;Space;Great Soundtrack;Relaxing;Beautiful;Experimental
|
| 88 |
+
726910,Free to Play;VR;Robots;Adventure;Sci-fi;Casual;Short;First-Person;Multiplayer;Singleplayer;Survival;Strategy;Action;Atmospheric;Open World;Indie;Interactive Fiction;Immersive Sim;Local Multiplayer;Nudity
|
| 89 |
+
731790,Casual;Simulation;VR;Indie;Competitive;Atmospheric;Singleplayer;Violent;Difficult;Horror;Fast-Paced;First-Person;Funny;War;Action;Tactical;Comedy;Replay Value;Colorful;Arcade
|
| 90 |
+
758210,Adventure;Early Access;Simulation;VR;Escape Room
|
| 91 |
+
790750,Arena Shooter;Hero Shooter;FPS;Archery;PvP;Competitive;Shooter;Arcade;Character Customization;Silent Protagonist;First-Person;VR;Action;Casual;Dystopian;Robots;Co-op;Multiplayer;Online Co-Op;Singleplayer
|
| 92 |
+
812460,Indie;Casual;Simulation;World War II;Historical;VR
|
| 93 |
+
815280,Strategy;Action;Indie;Early Access;VR;Pirates
|
| 94 |
+
866540,Free to Play;Adventure;Indie;RPG;VR;Short;Funny;Sci-fi;Physics;Space;Singleplayer;Story Rich;Atmospheric;Comedy;First-Person;Robots
|
| 95 |
+
891960,Free to Play;Casual;Simulation;VR;Space Sim;Space;Exploration;Physics
|
| 96 |
+
898080,Indie;Sexual Content;VR;Free to Play;Psychological Horror
|
| 97 |
+
910190,Free to Play;Indie;Action;VR;Sci-fi;FPS;Aliens;Space;Arcade
|
| 98 |
+
954160,Free to Play;Indie;VR
|
| 99 |
+
982710,Free to Play;Indie;VR;Local Multiplayer;Local Co-Op;Minigames;Villain Protagonist
|
| 100 |
+
997760,Sports;VR;Arcade;Baseball
|
| 101 |
+
998660,Free to Play;Early Access;VR;Action;Simulation;Casual;Flight;Multiplayer
|
dataset/statistics/plot.py
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import pandas as pd
|
| 3 |
+
from collections import defaultdict
|
| 4 |
+
from matplotlib import pyplot as plt
|
| 5 |
+
import numpy as np
|
| 6 |
+
|
| 7 |
+
SPLIT_GENRE = {
|
| 8 |
+
"TRAIN": [
|
| 9 |
+
"Casual",
|
| 10 |
+
"Adventure",
|
| 11 |
+
"Action",
|
| 12 |
+
"Indie"
|
| 13 |
+
],
|
| 14 |
+
"VAL": [
|
| 15 |
+
"Strategy",
|
| 16 |
+
"Education",
|
| 17 |
+
"RPG",
|
| 18 |
+
"Massively Multiplayer",
|
| 19 |
+
"Design & Illustration",
|
| 20 |
+
"Animation & Modeling"
|
| 21 |
+
],
|
| 22 |
+
"TEST": [
|
| 23 |
+
"Simulation",
|
| 24 |
+
"Sports"
|
| 25 |
+
]
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def parse_img_id(img_id):
|
| 30 |
+
img_id = str(img_id)
|
| 31 |
+
return int(img_id[:-3]), int(img_id[-3:])
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def plot(data, img_name, is_genre=False):
|
| 35 |
+
plt.rcParams.update({'font.size': 18})
|
| 36 |
+
colors = []
|
| 37 |
+
for cat in data.keys():
|
| 38 |
+
if cat in SPLIT_GENRE['TRAIN']:
|
| 39 |
+
colors.append('tab:blue')
|
| 40 |
+
elif cat in SPLIT_GENRE['VAL']:
|
| 41 |
+
colors.append('tab:orange')
|
| 42 |
+
elif cat in SPLIT_GENRE['TEST']:
|
| 43 |
+
colors.append('tab:green')
|
| 44 |
+
else:
|
| 45 |
+
colors.append('gray')
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
if is_genre:
|
| 49 |
+
plt.figure(figsize=(10, 6))
|
| 50 |
+
plt.grid(True, axis='y', zorder=0)
|
| 51 |
+
plt.bar(data.keys(), data.values(), color=colors, zorder=3)
|
| 52 |
+
plt.xticks(rotation=30, ha='right')
|
| 53 |
+
plt.legend(handles=[
|
| 54 |
+
plt.Line2D([0], [0], color='tab:blue', lw=10, label='Train'),
|
| 55 |
+
plt.Line2D([0], [0], color='tab:orange', lw=10, label='Val'),
|
| 56 |
+
plt.Line2D([0], [0], color='tab:green', lw=10, label='Test'),
|
| 57 |
+
])
|
| 58 |
+
else:
|
| 59 |
+
plt.figure(figsize=(15, 6))
|
| 60 |
+
plt.grid(True, axis='y', zorder=0)
|
| 61 |
+
plt.bar(data.keys(), data.values(), zorder=3)
|
| 62 |
+
plt.xticks(rotation=45, ha='right')
|
| 63 |
+
plt.gca().yaxis.set_major_locator(plt.MaxNLocator(integer=True))
|
| 64 |
+
for i, v in enumerate(data.values()):
|
| 65 |
+
plt.text(i, v, str(v), ha='center', va='bottom')
|
| 66 |
+
y_max = max(data.values())
|
| 67 |
+
plt.ylim(0, 1.1 * y_max)
|
| 68 |
+
|
| 69 |
+
plt.tight_layout()
|
| 70 |
+
plt.savefig(img_name + '.png')
|
| 71 |
+
plt.savefig(img_name + '.pdf')
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def plot_genre():
|
| 75 |
+
|
| 76 |
+
df = pd.read_csv('app_genre.csv')
|
| 77 |
+
with open('../data/coco_merged/annotations/semantics.json', 'r') as f:
|
| 78 |
+
dataset = json.load(f)
|
| 79 |
+
|
| 80 |
+
app_img_map = {}
|
| 81 |
+
|
| 82 |
+
for img in dataset['images']:
|
| 83 |
+
img_id = img['id']
|
| 84 |
+
app_id, _ = parse_img_id(img['id'])
|
| 85 |
+
if app_id not in app_img_map:
|
| 86 |
+
app_img_map[app_id] = []
|
| 87 |
+
app_img_map[app_id].append(img_id)
|
| 88 |
+
|
| 89 |
+
gnr_app_map = defaultdict(list)
|
| 90 |
+
|
| 91 |
+
for i in range(len(df)):
|
| 92 |
+
app_id = df['id'][i]
|
| 93 |
+
tags = df['genre'][i].split(';')
|
| 94 |
+
for tag in tags:
|
| 95 |
+
gnr_app_map[tag].append(int(app_id))
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
gnr_app_count = {cat: len(apps) for cat, apps in gnr_app_map.items()}
|
| 99 |
+
gnr_img_count = {cat: sum([len(app_img_map[app]) for app in apps]) for cat, apps in gnr_app_map.items()}
|
| 100 |
+
gnr_anno_count = {cat: sum([len([anno for anno in dataset['annotations'] if anno['image_id'] in app_img_map[app]]) for app in apps]) for cat, apps in gnr_app_map.items()}
|
| 101 |
+
|
| 102 |
+
split_genre_order = {genre: i for i, genre in enumerate(SPLIT_GENRE['TRAIN'] + SPLIT_GENRE['VAL'] + SPLIT_GENRE['TEST'])}
|
| 103 |
+
gnr_app_count = {cat: gnr_app_count[cat] for cat in sorted(gnr_app_count, key=lambda x: split_genre_order.get(x, float('inf')))}
|
| 104 |
+
gnr_img_count = {cat: gnr_img_count[cat] for cat in sorted(gnr_img_count, key=lambda x: split_genre_order.get(x, float('inf')))}
|
| 105 |
+
gnr_anno_count = {cat: gnr_anno_count[cat] for cat in sorted(gnr_anno_count, key=lambda x: split_genre_order.get(x, float('inf')))}
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
plot(gnr_app_count, 'genre_app_count', is_genre=True)
|
| 109 |
+
plot(gnr_img_count, 'genre_img_count', is_genre=True)
|
| 110 |
+
plot(gnr_anno_count, 'genre_anno_count', is_genre=True)
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
def plot_cat():
|
| 114 |
+
|
| 115 |
+
df = pd.read_csv('app_tag.csv')
|
| 116 |
+
with open('../data/coco_merged/annotations/semantics.json', 'r') as f:
|
| 117 |
+
dataset = json.load(f)
|
| 118 |
+
|
| 119 |
+
app_img_map = {}
|
| 120 |
+
|
| 121 |
+
for img in dataset['images']:
|
| 122 |
+
img_id = img['id']
|
| 123 |
+
app_id, _ = parse_img_id(img['id'])
|
| 124 |
+
if app_id not in app_img_map:
|
| 125 |
+
app_img_map[app_id] = []
|
| 126 |
+
app_img_map[app_id].append(img_id)
|
| 127 |
+
|
| 128 |
+
cat_app_map = defaultdict(list)
|
| 129 |
+
|
| 130 |
+
for i in range(len(df)):
|
| 131 |
+
app_id = df['id'][i]
|
| 132 |
+
tags = df['tag'][i].split(';')
|
| 133 |
+
for tag in tags:
|
| 134 |
+
cat_app_map[tag].append(int(app_id))
|
| 135 |
+
|
| 136 |
+
cat_app_map.pop('VR')
|
| 137 |
+
|
| 138 |
+
cat_app_count = {cat: len(apps) for cat, apps in cat_app_map.items()}
|
| 139 |
+
cat_img_count = {cat: sum([len(app_img_map[app]) for app in apps]) for cat, apps in cat_app_map.items()}
|
| 140 |
+
cat_anno_count = {cat: sum([len([anno for anno in dataset['annotations'] if anno['image_id'] in app_img_map[app]]) for app in apps]) for cat, apps in cat_app_map.items()}
|
| 141 |
+
|
| 142 |
+
cat_app_count = {cat: count for cat, count in list(cat_app_count.items())[:30]}
|
| 143 |
+
cat_img_count = {cat: count for cat, count in list(cat_img_count.items())[:30]}
|
| 144 |
+
cat_anno_count = {cat: count for cat, count in list(cat_anno_count.items())[:30]}
|
| 145 |
+
|
| 146 |
+
cat_app_count = {cat: count for cat, count in sorted(cat_app_count.items(), key=lambda item: item[1], reverse=True)}
|
| 147 |
+
cat_img_count = {cat: count for cat, count in sorted(cat_img_count.items(), key=lambda item: item[1], reverse=True)}
|
| 148 |
+
cat_anno_count = {cat: count for cat, count in sorted(cat_anno_count.items(), key=lambda item: item[1], reverse=True)}
|
| 149 |
+
|
| 150 |
+
plot(cat_app_count, 'tag_app_count')
|
| 151 |
+
plot(cat_img_count, 'tag_img_count')
|
| 152 |
+
plot(cat_anno_count, 'tag_anno_count')
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
def plot_cat_anno():
|
| 156 |
+
with open('../data/coco_merged/annotations/semantics.json', 'r') as f:
|
| 157 |
+
dataset = json.load(f)
|
| 158 |
+
|
| 159 |
+
cat_catname_map = {}
|
| 160 |
+
for cat in dataset['categories']:
|
| 161 |
+
cat_catname_map[cat['id']] = cat['name']
|
| 162 |
+
|
| 163 |
+
cat_anno_map = defaultdict(list)
|
| 164 |
+
for anno in dataset['annotations']:
|
| 165 |
+
cat_anno_map[cat_catname_map[anno['category_id']]].append(anno)
|
| 166 |
+
|
| 167 |
+
print(len(cat_anno_map['button']))
|
| 168 |
+
cat_anno_map.pop('button')
|
| 169 |
+
|
| 170 |
+
cat_anno_count = {cat: len(annos) for cat, annos in cat_anno_map.items()}
|
| 171 |
+
cat_anno_count = {cat: count for cat, count in sorted(cat_anno_count.items(), key=lambda item: item[1], reverse=True)}
|
| 172 |
+
cat_anno_count = {cat: count for cat, count in list(cat_anno_count.items())[:30]}
|
| 173 |
+
plot(cat_anno_count, 'ige_cat_anno_count')
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
plot_genre()
|
| 178 |
+
plot_cat()
|
| 179 |
+
plot_cat_anno()
|
docs/ASSETS.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Required external assets
|
| 2 |
+
|
| 3 |
+
This public copy includes the APE-L\(_D\) checkpoint required by the main detector. It intentionally excludes generated artifacts, credential-bearing files, private data, historical experiment outputs, and full dataset image payloads.
|
| 4 |
+
|
| 5 |
+
## Minimum smoke test
|
| 6 |
+
|
| 7 |
+
To validate one Orienter inference example, provide:
|
| 8 |
+
|
| 9 |
+
| Asset | Expected location or interface | Required metadata |
|
| 10 |
+
| --- | --- | --- |
|
| 11 |
+
| One representative XR screenshot | a test-only folder matching the question manifest | image license/permission and expected image ID |
|
| 12 |
+
| Matching question/context fixture | JSONL consumed by `approach/run_vlm.py`, generated by `scripts/generate_questions.py` when screenshots are available | selected prompt, provider, model ID, filename convention, and expected schema |
|
| 13 |
+
| App metadata cache | an external path supplied through `--app-metadata-cache` | `app_id`, app name, app description, source URL, version/date, license/permission |
|
| 14 |
+
| APE-L\(_D\) checkpoint | bundled at `approach/ovod/APE/ape_d_model_final.pth` | official source, Apache-2.0 license, SHA-256, and size recorded in `docs/MODEL_MANIFEST.md` |
|
| 15 |
+
| Built APE extension | local build/install under the target CUDA environment | generated from source after cloning; compiled artifacts are intentionally not redistributed |
|
| 16 |
+
| One supported provider credential | `openrouter-run` or an equivalent process-scoped secret manager | access to the selected OpenRouter model and an explicit spending limit |
|
| 17 |
+
| Expected prediction | private comparison fixture | expected candidate labels and approximate boxes |
|
| 18 |
+
|
| 19 |
+
Run `python -B scripts/verify_assets.py --repo-root .` to validate the bundled checkpoint size. Add `--hash-checkpoint` for SHA-256 verification. When screenshots and metadata are mounted, pass `--questions`, `--images-dir`, and `--app-metadata-cache` to check image naming, image ID consistency, and metadata coverage. Pass `--embedding-cache /path/to/embedding_dict.json` to hash the external semantic cache against `evaluation/cache_manifest.json` before an offline evaluation.
|
| 20 |
+
|
| 21 |
+
The default Stage 2 runner also verifies the released checkpoint hash before loading it. Loading any different PyTorch checkpoint requires the explicit `--trust-custom-checkpoint` flag and should be done only after independent provenance and checksum verification.
|
| 22 |
+
|
| 23 |
+
## Full paper reproduction
|
| 24 |
+
|
| 25 |
+
Provide or publish all of the following as versioned assets:
|
| 26 |
+
|
| 27 |
+
1. The 1,552-image XR UI screenshot payload and a canonical versioned annotation release. Selected COCO-format evaluation ground-truth splits are included in this repository, but must be tied to the public dataset version and license.
|
| 28 |
+
2. App, genre, and context-sensitive split manifests, including the extra non-interactable context annotations.
|
| 29 |
+
3. Steam/application metadata used for global context, preferably as a pinned JSON/JSONL cache that avoids live-page drift. The public runner fails closed on missing cache entries when `--app-metadata-cache` is supplied.
|
| 30 |
+
4. The complete prompt templates, demonstration examples, and the random-selection/seed policy.
|
| 31 |
+
5. Exact model identifiers and access paths for every Orienter variant evaluated in the paper. The code defaults to OpenRouter `openai/gpt-5.6-sol`; exact paper profiles are included for GPT-4o-2024-08-06, Claude 3.5 Sonnet, and Gemini 1.5 Pro. If a provider retires a historical route, supply equivalent access through a custom profile or direct vendor credentials and document the substitution.
|
| 32 |
+
6. The bundled APE-L\(_D\) checkpoint identity, official source, revision, license, and checksum in `docs/MODEL_MANIFEST.md`.
|
| 33 |
+
7. A working CUDA/PyTorch/Detectron2 APE environment with the APE native extension built locally from the released source tree.
|
| 34 |
+
8. The reviewed `embedding-3` semantic cache identified by `evaluation/cache_manifest.json`. Mount it read-only and use offline mode for historical reproduction. Zhipu access is optional and should be enabled only to extend a separate cache copy when a new model produces an uncached category.
|
| 35 |
+
9. Expected per-split metrics or prediction checksums for a deterministic regression check.
|
| 36 |
+
10. Hardware, CUDA, PyTorch, Python, and package versions from the successful experiment environment. See `docs/ENVIRONMENT.md` for the current public build boundary.
|
| 37 |
+
|
| 38 |
+
## Credential names found in code
|
| 39 |
+
|
| 40 |
+
The following names are referenced by the main or optional baseline paths:
|
| 41 |
+
|
| 42 |
+
- `OPENAI_API_KEY`
|
| 43 |
+
- `OPENROUTER_API_KEY`
|
| 44 |
+
- `GOOGLE_API_KEY`
|
| 45 |
+
- `ANTHROPIC_API_KEY`
|
| 46 |
+
- `ZHIPU_API_KEY`
|
| 47 |
+
- `ARK_API_KEY`
|
| 48 |
+
- `DASHSCOPE_API_KEY`
|
| 49 |
+
- `DEEPSEEK_API_KEY`
|
| 50 |
+
- `THEB_API_KEY`
|
| 51 |
+
- `INTERNVL_API_KEY`
|
| 52 |
+
|
| 53 |
+
Only `OPENROUTER_API_KEY` is needed for the recommended Orienter inference path; the other variables belong to optional evaluation or baseline code. Never send credentials through Git, issue trackers, logs, or README examples. Rotate any credential that has previously appeared in a file or experiment log.
|
| 54 |
+
|
| 55 |
+
Stage 1 sends full screenshots to the configured remote provider; reflection additionally sends crops and annotated scenes. Do not submit private or unauthorized screenshots. Review the provider's data-handling terms and keep generated candidates, predictions, traces, metadata caches, and error files outside the public repository because they can reveal source-image content or filenames.
|
| 56 |
+
|
| 57 |
+
## Publication format
|
| 58 |
+
|
| 59 |
+
For each data/model asset, publish: human-readable name, stable URL, version/revision, SHA-256, license, expected local path, compressed/uncompressed size, and a minimal schema example. The bundled APE checkpoint should be published through Hugging Face/LFS-style large-file storage; keep private raw data and generated experiment outputs outside the public repository.
|
docs/ENVIRONMENT.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Environment and APE build
|
| 2 |
+
|
| 3 |
+
Orienter has two runtime layers. The lightweight manifest, provider, and evaluation utilities use the root `requirements.txt`. Stage 2 additionally needs PyTorch, CUDA, Detectron2, detrex, and the compiled `ape._C` extension.
|
| 4 |
+
|
| 5 |
+
## Public starting point
|
| 6 |
+
|
| 7 |
+
Use Python 3.10 or later for the public environment. This is required by the current Pillow security release; the historical Python 3.9 environment is recorded below for provenance, not recommended for processing untrusted images.
|
| 8 |
+
|
| 9 |
+
For lightweight utilities:
|
| 10 |
+
|
| 11 |
+
```bash
|
| 12 |
+
python -B -m venv .venv
|
| 13 |
+
source .venv/bin/activate
|
| 14 |
+
python -B -m pip install --upgrade pip
|
| 15 |
+
python -B -m pip install -r requirements.txt
|
| 16 |
+
```
|
| 17 |
+
|
| 18 |
+
For the CUDA detector, `environment.reference.yml` is a compatibility starting point based on the verified experiment host, with Python and Pillow moved to currently supported public versions:
|
| 19 |
+
|
| 20 |
+
```bash
|
| 21 |
+
conda env create -f environment.reference.yml
|
| 22 |
+
conda activate orienter-ape-reference
|
| 23 |
+
bash scripts/build_ape_extension.sh
|
| 24 |
+
```
|
| 25 |
+
|
| 26 |
+
The environment file pins PyTorch 2.2.0 with CUDA 12.1 and the exact Detectron2 and detrex commits observed in the working server environment. It deliberately builds the vendored APE source after environment creation instead of redistributing a machine-specific binary. It is not a cross-platform lockfile or a security attestation for the older research stack. Audit the resolved environment on the publication host. The target machine needs a CUDA toolkit compatible with its PyTorch build, a supported C++ compiler, and enough memory/disk to compile the extension.
|
| 27 |
+
|
| 28 |
+
`scripts/build_ape_extension.sh` does not install or upgrade dependencies. It performs an editable build of the vendored APE source in the active environment, then runs the environment checker. Review the active environment before executing it.
|
| 29 |
+
|
| 30 |
+
## Verify the runtime
|
| 31 |
+
|
| 32 |
+
From the repository root:
|
| 33 |
+
|
| 34 |
+
```bash
|
| 35 |
+
python -B scripts/check_environment.py
|
| 36 |
+
python -B scripts/verify_assets.py --repo-root . --hash-checkpoint
|
| 37 |
+
python -B scripts/smoke_control_path.py
|
| 38 |
+
python scripts/run_tests.py
|
| 39 |
+
```
|
| 40 |
+
|
| 41 |
+
The environment check fails if the detector dependency stack is unavailable. `--allow-no-cuda` relaxes only the CUDA-availability check, and `--skip-ape-extension` relaxes only the compiled `ape._C` check; both remain diagnostic flags and still require PyTorch, torchvision, Detectron2, and detrex. They do not turn this command into a checker for the lightweight root requirements, and they are not valid evidence for Stage 2 inference readiness.
|
| 42 |
+
|
| 43 |
+
After mounting screenshots and application metadata, validate their contracts before a live run:
|
| 44 |
+
|
| 45 |
+
```bash
|
| 46 |
+
python -B scripts/verify_assets.py \
|
| 47 |
+
--repo-root . \
|
| 48 |
+
--questions /absolute/path/to/questions.jsonl \
|
| 49 |
+
--images-dir /absolute/path/to/images \
|
| 50 |
+
--app-metadata-cache /absolute/path/to/app_metadata.json
|
| 51 |
+
```
|
| 52 |
+
|
| 53 |
+
To reproduce semantic evaluation offline, separately mount the frozen cache and verify its full SHA-256:
|
| 54 |
+
|
| 55 |
+
```bash
|
| 56 |
+
python -B scripts/verify_assets.py \
|
| 57 |
+
--repo-root . \
|
| 58 |
+
--skip-checkpoint \
|
| 59 |
+
--embedding-cache /absolute/path/to/embedding_dict.json
|
| 60 |
+
```
|
| 61 |
+
|
| 62 |
+
## Verified historical server environment
|
| 63 |
+
|
| 64 |
+
The release checkpoint, one-image APE smoke test, and test suite were exercised in the historical server `conda` environment named `ape` with:
|
| 65 |
+
|
| 66 |
+
| Component | Observed version |
|
| 67 |
+
| --- | --- |
|
| 68 |
+
| Python | 3.9.18 |
|
| 69 |
+
| PyTorch | 2.2.0+cu121 |
|
| 70 |
+
| torchvision | 0.17.0+cu121 |
|
| 71 |
+
| CUDA runtime reported by PyTorch | 12.1 |
|
| 72 |
+
| CUDA toolkit (`nvcc`) | 12.2 |
|
| 73 |
+
| NVIDIA driver | 535.261.03 |
|
| 74 |
+
| GPU | NVIDIA A100-PCIE-40GB |
|
| 75 |
+
| GCC | 11.4.0 |
|
| 76 |
+
| Detectron2 | 0.6, commit `017abbfa5f2c2a2afa045200c2af9ccf2fc6227f` |
|
| 77 |
+
| detrex | 0.3.0, commit `776058ec229be37a5ff2a2b0bb54133bdd5da663` |
|
| 78 |
+
| transformers | 4.37.2 |
|
| 79 |
+
| NumPy | 1.22.4 |
|
| 80 |
+
| SciPy | 1.7.3 |
|
| 81 |
+
| Pillow | 10.2.0 |
|
| 82 |
+
| OpenCV Python | 4.9.0.80 |
|
| 83 |
+
| xformers | 0.0.24 |
|
| 84 |
+
| fairscale | 0.4.13 |
|
| 85 |
+
| lvis | 0.5.3 |
|
| 86 |
+
|
| 87 |
+
`torch.cuda.is_available()` returned `True`, and `ape._C` imported successfully when invoked from the Orienter repository root. Running Python from inside `approach/ovod/APE` before building the local extension can shadow the installed APE package with the unbuilt source tree; build first and run the public entrypoints from the Orienter root.
|
| 88 |
+
|
| 89 |
+
The historical environment includes an old Pillow version and is retained only as execution provenance. Do not use it for arbitrary or untrusted images. A fresh build of `environment.reference.yml` on the final Hugging Face target remains part of the release gate because compiled CUDA extensions are host-sensitive.
|
| 90 |
+
|
| 91 |
+
## Files that must stay local
|
| 92 |
+
|
| 93 |
+
Do not commit compiled extensions, `build/`, `*.egg-info`, model caches, virtual/conda environments, logs, generated candidates or predictions, or configuration files containing credentials or private absolute paths. Re-run the release hygiene tests after every live validation.
|
docs/MODEL_MANIFEST.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Model manifest
|
| 2 |
+
|
| 3 |
+
This public release bundles only the model file required by the main Orienter detector. Baseline training checkpoints, fold-specific weights, duplicate backups, and prior experiment outputs are excluded.
|
| 4 |
+
|
| 5 |
+
| File | Size | SHA-256 | Purpose | License |
|
| 6 |
+
| --- | ---: | --- | --- | --- |
|
| 7 |
+
| `approach/ovod/APE/ape_d_model_final.pth` | 5,956,547,279 bytes | `3548f41a3238148180e08fd4b16c71f4abc3ac3caf9c8434444462d1bdb7f965` | APE-L\(_D\) detector checkpoint used by Stage 2 grounding | Apache-2.0 |
|
| 8 |
+
|
| 9 |
+
Upstream source: [official `shenyunhang/APE` checkpoint](https://huggingface.co/shenyunhang/APE/blob/6ee15cf54c3930528ac49be165b45d5bcb1f4fd9/configs/LVISCOCOCOCOSTUFF_O365_OID_VGR_SA1B_REFCOCO_GQA_PhraseCut_Flickr30k/ape_deta/ape_deta_vitl_eva02_clip_vlf_lsj1024_cp_16x4_1080k_mdl_20230829_162438/model_final.pth), pinned at repository revision `6ee15cf54c3930528ac49be165b45d5bcb1f4fd9`. The official file reports the same SHA-256 and the upstream model repository declares Apache-2.0. The corresponding license text is retained at `approach/ovod/APE/LICENSE`.
|
| 10 |
+
|
| 11 |
+
The checkpoint uses PyTorch pickle serialization. Load it only through the pinned APE environment and treat replacement checkpoint files as executable untrusted input until independently verified.
|