multimodalart's picture
multimodalart HF Staff
Upload folder using huggingface_hub
ec47a15 verified
Raw
History Blame Contribute Delete
5 kB
"""
EdgeCrafter demo — compact ViTs for edge dense prediction.
Detection (ECDet), instance segmentation (ECSeg) and human pose estimation (ECPose),
all four model scales (S / M / L / X), on ZeroGPU.
"""
import spaces # noqa: F401 (must be imported before torch)
import time
import gradio as gr
import torch
from PIL import Image
import ecmodels as M
DEVICE = "cuda"
# Load every checkpoint eagerly at module scope; the whole family is small
# (~10M - 50M params each) and ZeroGPU streams the packed weights on first call.
MODELS = {
(task, size): M.load_model(task, size, device=DEVICE)
for task in M.TASKS
for size in M.SIZES
}
print(f"Loaded {len(MODELS)} EdgeCrafter checkpoints", flush=True)
TABLE_HEADERS = ["#", "class", "score", "box (x1, y1, x2, y2)", "mask px / keypoints"]
@spaces.GPU(duration=10)
def predict(
image: Image.Image,
task: str = "Object Detection",
model_size: str = "X",
threshold: float = 0.4,
):
"""Run EdgeCrafter on an image.
Args:
image: input photo (RGB).
task: "Object Detection", "Instance Segmentation" or "Human Pose Estimation".
model_size: EdgeCrafter scale, one of "S", "M", "L", "X" (small -> large).
threshold: confidence threshold for kept predictions.
Returns:
The annotated image, a table of predictions and a short run summary.
"""
if image is None:
raise gr.Error("Please provide an image first.")
image = image.convert("RGB")
model = MODELS[(task, model_size)]
torch.cuda.synchronize()
t0 = time.perf_counter()
results = M.infer(model, task, image, threshold, device=DEVICE)
torch.cuda.synchronize()
elapsed = (time.perf_counter() - t0) * 1000
annotated = M.render(image, task, results)
rows = M.results_table(task, results) or [["-", "no instance above threshold", "-", "-", "-"]]
params = sum(p.numel() for p in model.parameters()) / 1e6
repo = M.TASKS[task]["repo"].format(model_size)
summary = (
f"**{repo}** · {params:.1f}M params · {len(results)} instance(s) above "
f"{threshold:.2f} · {elapsed:.0f} ms on ZeroGPU (640×640 input)"
)
return annotated, rows, summary
with gr.Blocks() as demo:
gr.Markdown(
"""
# 🪶 EdgeCrafter — compact ViTs for edge dense prediction
One distilled ViT backbone family, three dense-prediction heads:
**detection (ECDet)**, **instance segmentation (ECSeg)** and
**human pose estimation (ECPose)**, at four scales (S → X, ~10M → ~50M params).
[Paper](https://huggingface.co/papers/2603.18739) ·
[Code](https://github.com/Intellindust-AI-Lab/EdgeCrafter) ·
[Weights](https://huggingface.co/Intellindust)
"""
)
with gr.Row():
with gr.Column():
image = gr.Image(label="Input image", type="pil", height=380)
task = gr.Radio(
choices=list(M.TASKS.keys()),
value="Object Detection",
label="Task",
)
run = gr.Button("Run EdgeCrafter", variant="primary")
with gr.Accordion("Advanced options", open=False):
model_size = gr.Radio(
choices=M.SIZES,
value="X",
label="Model scale",
info="S / M / L / X — smaller is faster, larger is more accurate",
)
threshold = gr.Slider(
0.05, 0.95, value=0.4, step=0.05,
label="Confidence threshold",
)
with gr.Column():
output = gr.Image(label="Prediction", type="pil", height=380)
summary = gr.Markdown()
table = gr.Dataframe(
headers=TABLE_HEADERS,
label="Predictions",
wrap=True,
row_count=(1, "dynamic"),
column_count=(5, "fixed"),
)
gr.Examples(
examples=[
["examples/donuts.jpg", "Object Detection"],
["examples/donuts.jpg", "Instance Segmentation"],
["examples/tennis_kids.jpg", "Human Pose Estimation"],
["examples/baseball.jpg", "Instance Segmentation"],
["examples/baseball.jpg", "Human Pose Estimation"],
],
inputs=[image, task],
outputs=[output, table, summary],
fn=predict,
cache_examples=True,
cache_mode="lazy",
)
gr.Markdown(
"""
Example photos are COCO images redistributed from the authors' related
Apache-2.0 repositories
([DEIMv2](https://github.com/Intellindust-AI-Lab/DEIMv2),
[DETRPose](https://github.com/SebastianJanampa/DETRPose)).
"""
)
run.click(
predict,
inputs=[image, task, model_size, threshold],
outputs=[output, table, summary],
)
if __name__ == "__main__":
demo.launch(mcp_server=True, theme=gr.themes.Citrus())