feat: configurable mask_decoder_chunk_size

#2
Files changed (1) hide show
  1. modeling_openworld_sam.py +28 -9
modeling_openworld_sam.py CHANGED
@@ -319,16 +319,35 @@ class OpenWorldSAMModel(PreTrainedModel):
319
  f[img_idx].unsqueeze(0) for f in _features["high_res_feats"]
320
  ]
321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
  with torch.no_grad():
323
- low_res_masks, iou_pred, _, _ = self.evf_sam2.visual_model.sam_mask_decoder(
324
- image_embeddings=_features["image_embed"][img_idx].unsqueeze(0),
325
- image_pe=self.evf_sam2.visual_model.sam_prompt_encoder.get_dense_pe(),
326
- sparse_prompt_embeddings=sparse_embeddings,
327
- dense_prompt_embeddings=dense_embeddings,
328
- multimask_output=False,
329
- repeat_image=True,
330
- high_res_features=high_res_features,
331
- )
 
 
 
 
 
 
332
 
333
  pred_masks = low_res_masks.squeeze(1) # [total_tokens, H_low, W_low]
334
  pred_logits = iou_pred.squeeze(1) # [total_tokens]
 
319
  f[img_idx].unsqueeze(0) for f in _features["high_res_feats"]
320
  ]
321
 
322
+ # The decoder's repeat_image path duplicates image_embeddings and
323
+ # image_pe once per candidate query, so scoring all num_classes *
324
+ # num_tokens candidates in one call can reach double-digit GiB
325
+ # for large vocabularies. `chunk_size` bounds peak memory
326
+ # rather than total candidate count.
327
+ image_embed_img = _features["image_embed"][img_idx].unsqueeze(0)
328
+ image_pe = self.evf_sam2.visual_model.sam_prompt_encoder.get_dense_pe()
329
+ chunk_size = self.config.mask_decoder_chunk_size
330
+ num_total_tokens = sparse_embeddings.shape[0]
331
+
332
+ low_res_masks_chunks = []
333
+ iou_pred_chunks = []
334
+
335
  with torch.no_grad():
336
+ for start in range(0, num_total_tokens, chunk_size):
337
+ end = min(start + chunk_size, num_total_tokens)
338
+ chunk_low_res_masks, chunk_iou_pred, _, _ = self.evf_sam2.visual_model.sam_mask_decoder(
339
+ image_embeddings=image_embed_img,
340
+ image_pe=image_pe,
341
+ sparse_prompt_embeddings=sparse_embeddings[start:end],
342
+ dense_prompt_embeddings=dense_embeddings[start:end],
343
+ multimask_output=False,
344
+ repeat_image=True,
345
+ high_res_features=high_res_features,
346
+ )
347
+ low_res_masks_chunks.append(chunk_low_res_masks)
348
+ iou_pred_chunks.append(chunk_iou_pred)
349
+ low_res_masks = torch.cat(low_res_masks_chunks, dim=0)
350
+ iou_pred = torch.cat(iou_pred_chunks, dim=0)
351
 
352
  pred_masks = low_res_masks.squeeze(1) # [total_tokens, H_low, W_low]
353
  pred_logits = iou_pred.squeeze(1) # [total_tokens]