Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using GPT-4o and other improvements. #26

Merged
merged 36 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ac75539
Computing/saving clip similarity between thor and blender renders if …
Lucaweihs Jul 30, 2024
2cfa4be
Updating thor commit to version that renders individual objects in a …
Lucaweihs Aug 9, 2024
d3d26d7
Changing empty house light intensity so objects are less overexposed.
Lucaweihs Aug 9, 2024
747186a
Added script to generate GPT annotations for thor objects.
Lucaweihs Aug 9, 2024
96fa553
Improving some prompts and adding new openai bach client/server class…
Lucaweihs Aug 9, 2024
070c8e1
Updating the version.
Lucaweihs Aug 9, 2024
347678f
Updating the version.
Lucaweihs Aug 9, 2024
05d2f39
Formatting and updating readme.md
Lucaweihs Aug 9, 2024
00f4050
Refactoring and unifying return values.
Lucaweihs Aug 14, 2024
70fb3e2
More error catching.
Lucaweihs Aug 14, 2024
c5cbc6d
Adding an unknown fail.
Lucaweihs Aug 14, 2024
bea5429
New gpt4o and other improvements/fixes.
Lucaweihs Aug 15, 2024
cec05dd
Requesting a "max_dimension" response qualitatively improves "height"…
Lucaweihs Aug 16, 2024
f2f0633
Formatting fix.
Lucaweihs Aug 16, 2024
eb779d7
Adding in the option to set an optimization timeout.
Lucaweihs Aug 16, 2024
336da95
Early exit when openai api key is not provided
Lucaweihs Aug 16, 2024
208b127
Formatting.
Lucaweihs Aug 16, 2024
5cf1f75
Downloading synset embeddings with locking.
Lucaweihs Aug 16, 2024
05ed247
Locking when loading clip model so multiple processes don't overwrite…
Lucaweihs Aug 16, 2024
8e838ab
Don't recompute synset embeddings if they can't be downloaded.
Lucaweihs Aug 16, 2024
d9f91f5
Fixing download_with_locking, we always have to acquire the lock to e…
Lucaweihs Aug 16, 2024
15024c8
Putting things on the right device.
Lucaweihs Aug 16, 2024
dc2c471
Minor prompt update and being more careful when loading synset embedd…
Lucaweihs Aug 19, 2024
f74fff6
Moving RequestStatus to a constants file.
Lucaweihs Aug 19, 2024
ab61025
Adding a "did_change" flag to the return from `async_annotate_asset` …
Lucaweihs Aug 19, 2024
e2a6b09
Using a WSGI server when not debugging.
Lucaweihs Aug 19, 2024
973013e
Fixing --debug option.
Lucaweihs Aug 19, 2024
e1f4d2e
Fixing wsgi server reference.
Lucaweihs Aug 19, 2024
4317885
Allowing for processing tarred assets.
Lucaweihs Sep 30, 2024
e64b478
Changing default chunk size during tar validation
Lucaweihs Sep 30, 2024
0edb800
Allowing for restarting holodeck feature generation after a prior run.
Lucaweihs Oct 3, 2024
06888cf
Better version of asset aggregation script.
Lucaweihs Oct 3, 2024
7032b2b
Better logging and error handling when aggregating asset annotations.
Lucaweihs Oct 3, 2024
ca93d48
Bugfix
Lucaweihs Oct 3, 2024
885c337
Circular reference fix.
Lucaweihs Oct 3, 2024
03c63cd
Updating base urls.
Lucaweihs Oct 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,10 @@ tmp
*/log.txt

log.txt
LICENSE.txt
LICENSE.txt
objathor/out/*
*.jpg
*.json
*.json.gz
examples
*batch_server_data/
18 changes: 3 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Objaverse asset annotator and importer for use in THOR.
Install ai2thor:

```bash
pip install --extra-index-url https://ai2thor-pypi.allenai.org ai2thor==0+40679c517859e09c1f2a5e39b65ee7f33fcfdd48
pip install --extra-index-url https://ai2thor-pypi.allenai.org ai2thor==0+455cf72a1c8e0759a452422f2128fbc93a3cb06b
```

Install other dependencies:
Expand Down Expand Up @@ -60,18 +60,6 @@ During the first run, NLTK dependencies are automatically installed, but we can
python -c "import nltk; nltk.download('punkt'); nltk.download('wordnet2022'); nltk.download('brown'); nltk.download('averaged_perceptron_tagger')"
```


### Pre-generated synset definition embeddings for Annotation

For automatic annotation to assign likely synsets given the automatically generated asset description, we can
pre-install pre-generated embeddings for all synset definitions (this can be useful if we cannot write into our home
directory at run time):

```bash
mkdir ~/.objathor_data
curl https://prior-datasets.s3.us-east-2.amazonaws.com/vida-synset-embeddings/synset_definition_embeddings_single.pkl.gz -o ~/.objathor_data/synset_definition_embeddings_single.pkl.gz
```

### AI2-THOR binary pre-downloading

Assuming we're running on a remote Linux server, we can pre-download the THOR binaries with:
Expand Down Expand Up @@ -104,15 +92,15 @@ From the repository root run:
```
python
-m objathor.asset_conversion.pipeline_to_thor
--object_ids=000074a334c541878360457c672b6c2e
--uids=000074a334c541878360457c672b6c2e
--output_dir=<some_absolute_path>
--extension=.msgpack.gz
--annotations=<annotations_file_path>
--live
--blender_as_module
```

Where `object_ids` is a string of comma separated list of `Objaverse` object ids to process.
Where `uids` is a string of comma separated list of `Objaverse` ids to process.
`output_dir` is an absolute path indicating where to write the output of the conversion.
`annotations` is optional, and is the path to an annotations file as generated by the process described above.

Expand Down
35 changes: 35 additions & 0 deletions objathor/annotation/annotation_utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
from typing import TypedDict, List, Dict

MODEL_STR_TO_PRICE_PER_1M_INPUT_TOKENS = {
# OpenAI models
"gpt-3.5-turbo-0301": 1.5,
"gpt-3.5-turbo-0125": 1.5,
"gpt-4-1106-preview": 10.0,
"gpt-4o-2024-05-13": 5.0,
"gpt-4o-2024-08-06": 2.5,
"gpt-4o-mini-2024-07-18": 0.15,
}

MODEL_STR_TO_PRICE_PER_1M_OUTPUT_TOKENS = {
# OpenAI models
"gpt-3.5-turbo-0301": 2.0,
"gpt-3.5-turbo-0125": 2.0,
"gpt-4-1106-preview": 30.0,
"gpt-4o-2024-05-13": 15.0,
"gpt-4o-2024-08-06": 10.0,
"gpt-4o-mini-2024-07-18": 0.6,
}


class LicenseInfo(TypedDict):
"""
Expand Down Expand Up @@ -114,3 +134,18 @@ class ObjectAnnotation(TypedDict):
scale: float
z_axis_scale: bool
license_info: LicenseInfo


def compute_llm_cost(input_tokens: int, output_tokens: int, model: str):
assert (
model in MODEL_STR_TO_PRICE_PER_1M_INPUT_TOKENS
and model in MODEL_STR_TO_PRICE_PER_1M_OUTPUT_TOKENS
), f"model [{model}] must be in both MODEL_STR_TO_PRICE_PER_1M_INPUT_TOKENS and MODEL_STR_TO_PRICE_PER_1M_OUTPUT_TOKENS"

input_token_cost_per_1m = MODEL_STR_TO_PRICE_PER_1M_INPUT_TOKENS[model]
output_token_cost_per_1m = MODEL_STR_TO_PRICE_PER_1M_OUTPUT_TOKENS[model]

return (
input_tokens * input_token_cost_per_1m
+ output_tokens * output_token_cost_per_1m
) / 1e6
98 changes: 56 additions & 42 deletions objathor/annotation/embed_synset_definitions.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import os
import random
import urllib.request
from typing import Dict

import compress_pickle
import numpy as np
from filelock import FileLock
from tqdm import tqdm

from objathor.utils.download_utils import download_with_locking
from objathor.utils.gpt_utils import get_embedding, get_embeddings_from_texts
from objathor.utils.synsets import (
all_synsets,
Expand All @@ -24,27 +25,38 @@


def download_embeddings(
url: str = "https://prior-datasets.s3.us-east-2.amazonaws.com/vida-synset-embeddings/synset_definition_embeddings_with_lemmas__2024-01-22.pkl.gz",
url: str = "https://pub-daedd7738a984186a00f2ab264d06a07.r2.dev/misc/synset_definition_embeddings_with_lemmas__2024-01-22.pkl.gz",
retry_if_failure: bool = True,
):
os.makedirs(OBJATHOR_DATA_DIR, exist_ok=True)
if not os.path.isfile(SYNSET_DEFINITION_EMB_FILE):
print(f"Downloading\n{url}\nto\n{SYNSET_DEFINITION_EMB_FILE}")

def report_hook(block, block_size, total_size, freq=1e7):
if (block * block_size) % freq < block_size:
print(f"{block * block_size / total_size * 100:.2f}% downloaded"),

urllib.request.urlretrieve(
url,
SYNSET_DEFINITION_EMB_FILE,
reporthook=report_hook,
)

print("Finished downloading")
assert os.path.isfile(SYNSET_DEFINITION_EMB_FILE)
lock_path = SYNSET_DEFINITION_EMB_FILE + ".lock"

download_with_locking(
url=url,
save_path=SYNSET_DEFINITION_EMB_FILE,
lock_path=lock_path,
desc="Downloading synset definition embeddings",
)

def get_embeddings(
load_failure = False
with FileLock(lock_path):
try:
compress_pickle.load(SYNSET_DEFINITION_EMB_FILE)
except EOFError:
if retry_if_failure:
load_failure = True
try:
os.remove(SYNSET_DEFINITION_EMB_FILE)
except FileNotFoundError:
pass
else:
raise

if load_failure:
print("Failed to load embeddings, reattempting download...")
download_embeddings(url=url, retry_if_failure=False)


def compute_synset_embeddings(
fname: str = os.path.join(OBJATHOR_DATA_DIR, "synset_definition_embeddings.pkl.gz"),
) -> Dict[str, np.ndarray]:
from nltk.corpus import wordnet2022 as wn
Expand Down Expand Up @@ -90,7 +102,7 @@ def get_embeddings(
return data


def get_embeddings_single(
def _load_synset_embeddings(
fname: str = SYNSET_DEFINITION_EMB_FILE,
) -> Dict[str, np.ndarray]:
if not os.path.isfile(fname):
Expand All @@ -99,10 +111,11 @@ def get_embeddings_single(
except (SystemExit, KeyboardInterrupt):
raise
except:
data = get_embeddings()
for key, value in data.items():
data[key] = value.astype(np.float32)
compress_pickle.dump(data, fname)
raise
# data = compute_synset_embeddings()
# for key, value in data.items():
# data[key] = value.astype(np.float32)
# compress_pickle.dump(data, fname)

return compress_pickle.load(fname)

Expand Down Expand Up @@ -255,21 +268,22 @@ def format_lemmas(lemmas):


if __name__ == "__main__":
data = get_embeddings()
for key, value in data.items():
data[key] = value.astype(np.float32)

compress_pickle.dump(
data,
os.path.join(
OBJATHOR_DATA_DIR,
"synset_definition_embeddings_with_lemmas__2024-01-22.pkl.gz",
),
)

# data = get_embeddings()
# data = get_embeddings_single()
# local_smoothing(data, "wardrobe.n.01")

# data = get_lemmas_definition_embeddings()
print("DONE")
download_embeddings()
# data = compute_synset_embeddings()
# for key, value in data.items():
# data[key] = value.astype(np.float32)
#
# compress_pickle.dump(
# data,
# os.path.join(
# OBJATHOR_DATA_DIR,
# "synset_definition_embeddings_with_lemmas__2024-01-22.pkl.gz",
# ),
# )
#
# # data = get_embeddings()
# # data = get_embeddings_single()
# # local_smoothing(data, "wardrobe.n.01")
#
# # data = get_lemmas_definition_embeddings()
# print("DONE")
Loading
Loading