Safetensors
mhassanch commited on
Commit
e31116c
·
1 Parent(s): 6382bf0

Expose GeoText embeddings and region boxes

Browse files
Files changed (2) hide show
  1. infer.py +48 -10
  2. server.py +14 -5
infer.py CHANGED
@@ -136,14 +136,16 @@ def load_model(source_dir: Path, model_dir: Path, device: torch.device):
136
 
137
 
138
  @torch.inference_mode()
139
- def rank_queries(
140
  model,
141
  tokenizer,
142
  config: Dict[str, Any],
143
  image: Image.Image,
144
  queries: List[str],
145
  device: torch.device,
146
- ):
 
 
147
  image_transform = transforms.Compose(
148
  [
149
  transforms.Resize(
@@ -166,14 +168,50 @@ def rank_queries(
166
  text_embeds = model.get_text_embeds(text_input.input_ids, text_input.attention_mask)
167
  image_features, text_features = model.get_features(image_embeds, text_embeds)
168
  scores = (image_features @ text_features.T).flatten().float().cpu().tolist()
169
- return sorted(
170
- (
171
- {"query": query, "similarity": score}
172
- for query, score in zip(queries, scores)
173
- ),
174
- key=lambda item: item["similarity"],
175
- reverse=True,
176
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
 
179
  def main() -> None:
 
136
 
137
 
138
  @torch.inference_mode()
139
+ def model_outputs(
140
  model,
141
  tokenizer,
142
  config: Dict[str, Any],
143
  image: Image.Image,
144
  queries: List[str],
145
  device: torch.device,
146
+ include_embeddings: bool = False,
147
+ include_bboxes: bool = False,
148
+ ) -> Dict[str, Any]:
149
  image_transform = transforms.Compose(
150
  [
151
  transforms.Resize(
 
168
  text_embeds = model.get_text_embeds(text_input.input_ids, text_input.attention_mask)
169
  image_features, text_features = model.get_features(image_embeds, text_embeds)
170
  scores = (image_features @ text_features.T).flatten().float().cpu().tolist()
171
+ result = {
172
+ "ranked_queries": sorted(
173
+ (
174
+ {"query": query, "similarity": score}
175
+ for query, score in zip(queries, scores)
176
+ ),
177
+ key=lambda item: item["similarity"],
178
+ reverse=True,
179
+ )
180
+ }
181
+
182
+ if include_embeddings:
183
+ result["image_embedding"] = image_features[0].float().cpu().tolist()
184
+ result["text_embeddings"] = [
185
+ {"query": query, "embedding": embedding.float().cpu().tolist()}
186
+ for query, embedding in zip(queries, text_features)
187
+ ]
188
+
189
+ if include_bboxes:
190
+ repeated_image_embeds = image_embeds.expand(len(queries), -1, -1)
191
+ boxes = model.predict_bbox(
192
+ repeated_image_embeds, text_embeds, text_input.attention_mask
193
+ ).float().cpu().tolist()
194
+ result["text_conditioned_boxes"] = [
195
+ {
196
+ "query": query,
197
+ "format": "normalized_cx_cy_width_height",
198
+ "box": box,
199
+ }
200
+ for query, box in zip(queries, boxes)
201
+ ]
202
+
203
+ return result
204
+
205
+
206
+ def rank_queries(
207
+ model,
208
+ tokenizer,
209
+ config: Dict[str, Any],
210
+ image: Image.Image,
211
+ queries: List[str],
212
+ device: torch.device,
213
+ ):
214
+ return model_outputs(model, tokenizer, config, image, queries, device)["ranked_queries"]
215
 
216
 
217
  def main() -> None:
server.py CHANGED
@@ -9,13 +9,17 @@ from typing import Any, Dict, List
9
 
10
  import torch
11
  from fastapi import FastAPI, HTTPException
12
- from infer import fetch_rgb_geotiff, load_model, rank_queries
13
  from pydantic import BaseModel, Field
14
 
15
 
16
  class InferenceRequest(BaseModel):
17
  image_url: str = Field(..., description="Public RGB GeoTIFF/COG URL")
18
  queries: List[str] = Field(..., min_items=1, description="Text queries to rank")
 
 
 
 
19
 
20
 
21
  @asynccontextmanager
@@ -47,18 +51,23 @@ def infer(request: InferenceRequest) -> Dict[str, Any]:
47
  try:
48
  image, image_metadata = fetch_rgb_geotiff(request.image_url)
49
  runtime = app.state.runtime
50
- return {
51
  "image_url": request.image_url,
52
  "image_metadata": image_metadata,
53
  "device": str(runtime["device"]),
54
- "ranked_queries": rank_queries(
 
 
55
  runtime["model"],
56
  runtime["tokenizer"],
57
  runtime["config"],
58
  image,
59
  request.queries,
60
  runtime["device"],
61
- ),
62
- }
 
 
 
63
  except Exception as error:
64
  raise HTTPException(status_code=422, detail=str(error)) from error
 
9
 
10
  import torch
11
  from fastapi import FastAPI, HTTPException
12
+ from infer import fetch_rgb_geotiff, load_model, model_outputs
13
  from pydantic import BaseModel, Field
14
 
15
 
16
  class InferenceRequest(BaseModel):
17
  image_url: str = Field(..., description="Public RGB GeoTIFF/COG URL")
18
  queries: List[str] = Field(..., min_items=1, description="Text queries to rank")
19
+ include_embeddings: bool = Field(
20
+ False, description="Return 256-dimensional image and text vectors"
21
+ )
22
+ include_bboxes: bool = Field(False, description="Return text-conditioned normalized boxes")
23
 
24
 
25
  @asynccontextmanager
 
51
  try:
52
  image, image_metadata = fetch_rgb_geotiff(request.image_url)
53
  runtime = app.state.runtime
54
+ result = {
55
  "image_url": request.image_url,
56
  "image_metadata": image_metadata,
57
  "device": str(runtime["device"]),
58
+ }
59
+ result.update(
60
+ model_outputs(
61
  runtime["model"],
62
  runtime["tokenizer"],
63
  runtime["config"],
64
  image,
65
  request.queries,
66
  runtime["device"],
67
+ include_embeddings=request.include_embeddings,
68
+ include_bboxes=request.include_bboxes,
69
+ )
70
+ )
71
+ return result
72
  except Exception as error:
73
  raise HTTPException(status_code=422, detail=str(error)) from error