Spaces:
Running
on
Zero
Running
on
Zero
update cache
Browse files
app.py
CHANGED
@@ -464,20 +464,75 @@ def image_clip_feature(
|
|
464 |
return outputs
|
465 |
|
466 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
467 |
def extract_features(images, model_name="sam", node_type="block", layer=-1):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
468 |
if model_name == "SAM(sam_vit_b)":
|
469 |
if not use_cuda:
|
470 |
gr.warning("GPU not detected. Running SAM on CPU, ~30s/image.")
|
471 |
-
|
472 |
elif model_name == 'MobileSAM':
|
473 |
-
|
474 |
elif model_name == "DiNO(dinov2_vitb14_reg)":
|
475 |
-
|
476 |
elif model_name == "CLIP(openai/clip-vit-base-patch16)":
|
477 |
-
|
478 |
else:
|
479 |
raise ValueError(f"Model {model_name} not supported.")
|
480 |
|
|
|
|
|
|
|
|
|
481 |
|
482 |
def compute_ncut(
|
483 |
features,
|
@@ -584,7 +639,7 @@ demo = gr.Interface(
|
|
584 |
gr.Dropdown(["attn", "mlp", "block"], label="Node type", value="block", elem_id="node_type", info="attn: attention output, mlp: mlp output, block: sum of residual stream"),
|
585 |
gr.Slider(0, 11, step=1, label="Layer", value=11, elem_id="layer", info="which layer of the image backbone features"),
|
586 |
gr.Slider(1, 1000, step=1, label="Number of eigenvectors", value=100, elem_id="num_eig", info='increase for more object parts, decrease for whole object'),
|
587 |
-
gr.Slider(0.01, 1, step=0.01, label="Affinity focal gamma", value=0.
|
588 |
],
|
589 |
gr.Gallery(value=default_outputs, label="NCUT Embedding", show_label=False, elem_id="ncut", columns=[3], rows=[1], object_fit="contain", height="auto"),
|
590 |
additional_inputs=[
|
|
|
464 |
return outputs
|
465 |
|
466 |
|
467 |
+
|
468 |
+
import hashlib
|
469 |
+
import pickle
|
470 |
+
import sys
|
471 |
+
from collections import OrderedDict
|
472 |
+
|
473 |
+
# Cache dictionary with limited size
|
474 |
+
class LimitedSizeCache(OrderedDict):
|
475 |
+
def __init__(self, max_size_bytes):
|
476 |
+
self.max_size_bytes = max_size_bytes
|
477 |
+
self.current_size_bytes = 0
|
478 |
+
super().__init__()
|
479 |
+
|
480 |
+
def __setitem__(self, key, value):
|
481 |
+
item_size = self.get_item_size(value)
|
482 |
+
# Evict items until there is enough space
|
483 |
+
while self.current_size_bytes + item_size > self.max_size_bytes:
|
484 |
+
self.popitem(last=False)
|
485 |
+
super().__setitem__(key, value)
|
486 |
+
self.current_size_bytes += item_size
|
487 |
+
|
488 |
+
def __delitem__(self, key):
|
489 |
+
value = self[key]
|
490 |
+
super().__delitem__(key)
|
491 |
+
self.current_size_bytes -= self.get_item_size(value)
|
492 |
+
|
493 |
+
def get_item_size(self, value):
|
494 |
+
"""Estimate the size of the value in bytes."""
|
495 |
+
return sys.getsizeof(value)
|
496 |
+
|
497 |
+
# Initialize the cache with a 4GB limit
|
498 |
+
cache = LimitedSizeCache(max_size_bytes=4 * 1024 * 1024 * 1024) # 4GB
|
499 |
+
|
500 |
+
def compute_hash(*args, **kwargs):
|
501 |
+
"""Compute a unique hash based on the function arguments."""
|
502 |
+
hasher = hashlib.sha256()
|
503 |
+
pickled_args = pickle.dumps((args, kwargs))
|
504 |
+
hasher.update(pickled_args)
|
505 |
+
return hasher.hexdigest()
|
506 |
+
|
507 |
+
|
508 |
def extract_features(images, model_name="sam", node_type="block", layer=-1):
|
509 |
+
# Compute the cache key
|
510 |
+
cache_key = compute_hash(images, model_name, node_type, layer)
|
511 |
+
|
512 |
+
# Check if the result is already in the cache
|
513 |
+
if cache_key in cache:
|
514 |
+
print("Cache hit!")
|
515 |
+
return cache[cache_key]
|
516 |
+
|
517 |
+
|
518 |
+
# Compute the result if not in cache
|
519 |
if model_name == "SAM(sam_vit_b)":
|
520 |
if not use_cuda:
|
521 |
gr.warning("GPU not detected. Running SAM on CPU, ~30s/image.")
|
522 |
+
result = image_sam_feature(images, node_type=node_type, layer=layer)
|
523 |
elif model_name == 'MobileSAM':
|
524 |
+
result = image_mobilesam_feature(images, node_type=node_type, layer=layer)
|
525 |
elif model_name == "DiNO(dinov2_vitb14_reg)":
|
526 |
+
result = image_dino_feature(images, node_type=node_type, layer=layer)
|
527 |
elif model_name == "CLIP(openai/clip-vit-base-patch16)":
|
528 |
+
result = image_clip_feature(images, node_type=node_type, layer=layer)
|
529 |
else:
|
530 |
raise ValueError(f"Model {model_name} not supported.")
|
531 |
|
532 |
+
# Store the result in the cache
|
533 |
+
cache[cache_key] = result
|
534 |
+
|
535 |
+
return result
|
536 |
|
537 |
def compute_ncut(
|
538 |
features,
|
|
|
639 |
gr.Dropdown(["attn", "mlp", "block"], label="Node type", value="block", elem_id="node_type", info="attn: attention output, mlp: mlp output, block: sum of residual stream"),
|
640 |
gr.Slider(0, 11, step=1, label="Layer", value=11, elem_id="layer", info="which layer of the image backbone features"),
|
641 |
gr.Slider(1, 1000, step=1, label="Number of eigenvectors", value=100, elem_id="num_eig", info='increase for more object parts, decrease for whole object'),
|
642 |
+
gr.Slider(0.01, 1, step=0.01, label="Affinity focal gamma", value=0.3, elem_id="affinity_focal_gamma", info="decrease for more aggressive cleaning on the affinity matrix"),
|
643 |
],
|
644 |
gr.Gallery(value=default_outputs, label="NCUT Embedding", show_label=False, elem_id="ncut", columns=[3], rows=[1], object_fit="contain", height="auto"),
|
645 |
additional_inputs=[
|