Skip to content

Repository files navigation

🪄 tiny‑SAM — watch Segment Anything learn, on a laptop

built on Segment AnythingPyTorchruns ontiny modelpaper

Meta's SAM ships inference code only — there is no training script. tiny‑SAM is a self‑contained reconstruction of SAM's training loop from the paper, shrunk to 355K parameters so the whole thing — image encoder, prompt encoder, mask decoder, multi‑mask selection, error‑driven re‑prompting, mask feedback, focal + dice + IoU losses, end‑to‑end backprop — runs in a few seconds on a CPU and visibly learns to segment:

step 0 loss 2.652 IoU 0.12 → 0.08 step 49 loss 0.286 IoU 0.86 → 0.87
step 19 loss 1.529 IoU 0.82 → 0.82 step 99 loss 0.096 IoU 0.96 → 0.96 ✅

If you've ever wanted to see how a promptable segmenter is actually trained — not just call predictor.predict() — this is the repo for it.

tiny-SAM training loop

One optimizer step, end‑to‑end. The green dashed rail is the image embedding, computed once and reused by all three prompt iterations; the orange / blue elbows feed each iteration's predicted mask and low‑res logits back into the next prompt; the red lines on the right merge the three losses into a single backward pass. Editable source: assets/training_loop.excalidraw.


Why this exists

The official segment_anything/ package gives you a frozen model and a beautiful inference API — but it never shows how the model got good. The training procedure lives only in §3.1 of the paper (Kirillov et al., Segment Anything, ICCV 2023). tiny‑SAM turns that prose into runnable, annotated code, line‑for‑line mapped to the paper, so you can read it, break it, and watch the numbers move.

It's a great way to understand, concretely:

  • why the image encoder runs once and the tiny decoder runs many times,
  • how a single ambiguous click becomes 3 candidate masks, and how the IoU head learns to pick the right one without ground truth at inference time,
  • how mistakes become the next prompt (sample points from pred XOR gt),
  • and a subtle API gotcha: the decoder's batch dim is prompt hypotheses per image, not images — which is exactly why Sam.forward() loops over the batch.

Quickstart

No checkpoint download, no GPU, no dataset. Just PyTorch:

git clone https://github.com/DreamRunnerMoshi/segment-anything.git
cd segment-anything
python3 -m venv .venv
.venv/bin/pip install torch numpy
.venv/bin/python tiny_sam.py

(tiny_sam.py only needs the vendored segment_anything/modeling package — no torchvision, no extra deps. Set SAM_DEVICE=mps or cuda to use a GPU.)

You'll see one fully‑traced step (every tensor shape printed), then 100 streaming steps on fresh synthetic images — a tiny stand‑in for SA‑1B:

tiny SAM on cpu: 355,528 params (encoder 195,456 | prompt 1,804 | decoder 158,268)
training all of it end-to-end, as in the paper
=== one training step, traced ===
image (4, 3, 128, 128) -> encoder ONCE -> (4, 64, 8, 8)
it1 prompt (4, 1, 2) xy -> sparse (4, 2, 64) (2nd token is the auto-padded 'no-point' token)
it1 decoder multi-mask: low_res (4, 3, 32, 32), logits (4, 3, 128, 128), iou_pred (4, 3)
it1 selected-mask mean IoU: 0.082
it2 prompt 2 accumulated pts -> sparse (4, 3, 64), dense mask feedback (4, 64, 8, 8) -> single mask
it3 prompt 3 accumulated pts -> sparse (4, 4, 64), dense mask feedback (4, 64, 8, 8) -> single mask
=== fresh synthetic batch every step (like streaming from SA-1B) ===
step 0 loss 2.652 IoU it1 0.119 -> it3 0.080 |grad| 1.74
step 8 loss 2.748 IoU it1 0.419 -> it3 0.393 |grad| 1.49
step 19 loss 1.529 IoU it1 0.818 -> it3 0.816 |grad| 3.39
step 49 loss 0.286 IoU it1 0.859 -> it3 0.865 |grad| 1.00
step 69 loss 0.162 IoU it1 0.919 -> it3 0.927 |grad| 1.15
step 99 loss 0.096 IoU it1 0.958 -> it3 0.960 |grad| 0.89

Mean mask IoU on unseen images goes 0.08 → 0.96 — the loop genuinely trains segmentation, from scratch, end‑to‑end.


How the training loop works

tiny_sam.py follows the paper's recipe in five steps per optimizer step:

#What happensWhere
1Encode once.ImageEncoderViT → embedding (B,64,8,8), cached & reused.train_step
2Iteration 1 — ambiguous. One foreground point → PromptEncoder → decoder with multimask=True → 3 masks; a teacher (hard IoU vs GT) picks the best; the IoU head is trained to predict that IoU.sample_foreground_points
3Iterations 2–3 — refine. Sample a point from pred ⊕ gt (label 1 = missed object, 0 = hallucinated), accumulate it, feed the previous logits back as a dense mask prompt, decode a single refined mask.sample_error_points
4Losses. sigmoid focal + dice on masks, MSE on predicted IoU.sigmoid_focal_loss / dice_loss / iou_mse_loss
5Backward, end‑to‑end. Gradients from all 9 mask losses flow through decoder + prompt encoder + encoder; one Adam step.main

The full, annotated walkthrough — with the diagram, every tensor shape, the decoder‑batch gotcha, and a faithful‑vs‑simplified table — is in TRAINING_WALKTHROUGH.md.


tiny‑SAM vs real SAM

Same wiring as segment_anything/build_sam.py, just shrunken so it trains interactively:

tiny‑SAM (this demo)SAM ViT‑H (paper)
Image size128 × 1281024 × 1024
Embedding grid8 × 864 × 64
Prompt / decoder dim64256
ViT embed / depth / heads64 / 2 / 41280 / 32 / 16
Parameters355 K~636 M
Datasynthetic circlesSA‑1B (11 M images, 1.1 B masks)
Train batch / steps4 / 100256 / 665 k
Hardwarelaptop CPUmany GPUs

Everything that matters for understanding is preserved: 3‑iteration error‑driven prompting, multi‑mask + IoU‑head supervision, mask‑logit feedback, and the three losses. What's dropped for size is listed honestly in the walkthrough.


Things to try

Tiny‑SAM is meant to be poked. In tiny_sam.py:

  • N_STEPS = 300 — watch IoU saturate near 1.0; confirms it really learns, not memorizes (every step is a fresh random image).
  • Freeze the encoder — reproduces SAM's late‑training stage and makes steps much faster:
    forpinsam.image_encoder.parameters():
    p.requires_grad_(False)
  • Box prompts — unambiguous, so they skip the multi‑mask stage:
    fromsegment_anything.utils.amgimportbatched_mask_to_boxboxes=batched_mask_to_box(gt)
    sparse, dense=sam.prompt_encoder(points=None, boxes=boxes, masks=None)
  • Drop the IoU loss — training loss still falls, but mask selection at inference (no GT) breaks. This isolates exactly why the IoU head exists.

Repo layout

tiny_sam.py ← the training loop (start here)
TRAINING_WALKTHROUGH.md ← step-by-step explanation + diagram
assets/training_loop.png ← rendered training-loop diagram
assets/training_loop.excalidraw ← editable diagram source
segment_anything/ ← upstream SAM model code (unchanged, used as the backbone)

Using the upstream model (unchanged)

The vendored segment_anything/ package is Meta's original, unmodified — so all of its inference tooling still works if you point it at a checkpoint:

fromsegment_anythingimportSamPredictor, sam_model_registrysam=sam_model_registry["vit_b"](checkpoint="sam_vit_b_01ec64.pth")
predictor=SamPredictor(sam)
predictor.set_image(<your_image>)
masks, scores, logits=predictor.predict(point_coords=..., point_labels=...)

Checkpoints: vit_h · vit_l · vit_b. Automatic "segment everything" (SamAutomaticMaskGenerator), ONNX export, and the browser demo are all still in scripts/, notebooks/, and demo/. For video, see the follow‑up SAM 2.


Built on Segment Anything

tiny‑SAM is an independent, educational reconstruction built on top of Meta AI Research's open‑source Segment Anything — it is not affiliated with or endorsed by Meta. The segment_anything/ model code is reproduced verbatim under its original license; the training‑loop script, walkthrough, and diagrams are original additions for learning purposes.

If you use SAM or SA‑1B in research, please cite the original work:

BibTeX
@article{kirillov2023segany,
title={Segment Anything},
author={Kirillov, Alexander and Mintun, Eric and Ravi, Nikhila and Mao, Hanzi and Rolland, Chloe and Gustafson, Laura and Xiao, Tete and Whitehead, Spencer and Berg, Alexander C. and Lo, Wan-Yen and Doll{\'a}r, Piotr and Girshick, Ross},
journal={arXiv:2304.02643},
year={2023}
}

About

The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - DreamRunnerMoshi/Tiny_SAM: The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model. · GitHub
Skip to content

Repository files navigation

🪄 tiny‑SAM — watch Segment Anything learn, on a laptop

built on Segment AnythingPyTorchruns ontiny modelpaper

Meta's SAM ships inference code only — there is no training script. tiny‑SAM is a self‑contained reconstruction of SAM's training loop from the paper, shrunk to 355K parameters so the whole thing — image encoder, prompt encoder, mask decoder, multi‑mask selection, error‑driven re‑prompting, mask feedback, focal + dice + IoU losses, end‑to‑end backprop — runs in a few seconds on a CPU and visibly learns to segment:

step 0 loss 2.652 IoU 0.12 → 0.08 step 49 loss 0.286 IoU 0.86 → 0.87
step 19 loss 1.529 IoU 0.82 → 0.82 step 99 loss 0.096 IoU 0.96 → 0.96 ✅

If you've ever wanted to see how a promptable segmenter is actually trained — not just call predictor.predict() — this is the repo for it.

tiny-SAM training loop

One optimizer step, end‑to‑end. The green dashed rail is the image embedding, computed once and reused by all three prompt iterations; the orange / blue elbows feed each iteration's predicted mask and low‑res logits back into the next prompt; the red lines on the right merge the three losses into a single backward pass. Editable source: assets/training_loop.excalidraw.


Why this exists

The official segment_anything/ package gives you a frozen model and a beautiful inference API — but it never shows how the model got good. The training procedure lives only in §3.1 of the paper (Kirillov et al., Segment Anything, ICCV 2023). tiny‑SAM turns that prose into runnable, annotated code, line‑for‑line mapped to the paper, so you can read it, break it, and watch the numbers move.

It's a great way to understand, concretely:

  • why the image encoder runs once and the tiny decoder runs many times,
  • how a single ambiguous click becomes 3 candidate masks, and how the IoU head learns to pick the right one without ground truth at inference time,
  • how mistakes become the next prompt (sample points from pred XOR gt),
  • and a subtle API gotcha: the decoder's batch dim is prompt hypotheses per image, not images — which is exactly why Sam.forward() loops over the batch.

Quickstart

No checkpoint download, no GPU, no dataset. Just PyTorch:

git clone https://github.com/DreamRunnerMoshi/segment-anything.git
cd segment-anything
python3 -m venv .venv
.venv/bin/pip install torch numpy
.venv/bin/python tiny_sam.py

(tiny_sam.py only needs the vendored segment_anything/modeling package — no torchvision, no extra deps. Set SAM_DEVICE=mps or cuda to use a GPU.)

You'll see one fully‑traced step (every tensor shape printed), then 100 streaming steps on fresh synthetic images — a tiny stand‑in for SA‑1B:

tiny SAM on cpu: 355,528 params (encoder 195,456 | prompt 1,804 | decoder 158,268)
training all of it end-to-end, as in the paper
=== one training step, traced ===
image (4, 3, 128, 128) -> encoder ONCE -> (4, 64, 8, 8)
it1 prompt (4, 1, 2) xy -> sparse (4, 2, 64) (2nd token is the auto-padded 'no-point' token)
it1 decoder multi-mask: low_res (4, 3, 32, 32), logits (4, 3, 128, 128), iou_pred (4, 3)
it1 selected-mask mean IoU: 0.082
it2 prompt 2 accumulated pts -> sparse (4, 3, 64), dense mask feedback (4, 64, 8, 8) -> single mask
it3 prompt 3 accumulated pts -> sparse (4, 4, 64), dense mask feedback (4, 64, 8, 8) -> single mask
=== fresh synthetic batch every step (like streaming from SA-1B) ===
step 0 loss 2.652 IoU it1 0.119 -> it3 0.080 |grad| 1.74
step 8 loss 2.748 IoU it1 0.419 -> it3 0.393 |grad| 1.49
step 19 loss 1.529 IoU it1 0.818 -> it3 0.816 |grad| 3.39
step 49 loss 0.286 IoU it1 0.859 -> it3 0.865 |grad| 1.00
step 69 loss 0.162 IoU it1 0.919 -> it3 0.927 |grad| 1.15
step 99 loss 0.096 IoU it1 0.958 -> it3 0.960 |grad| 0.89

Mean mask IoU on unseen images goes 0.08 → 0.96 — the loop genuinely trains segmentation, from scratch, end‑to‑end.


How the training loop works

tiny_sam.py follows the paper's recipe in five steps per optimizer step:

#What happensWhere
1Encode once.ImageEncoderViT → embedding (B,64,8,8), cached & reused.train_step
2Iteration 1 — ambiguous. One foreground point → PromptEncoder → decoder with multimask=True → 3 masks; a teacher (hard IoU vs GT) picks the best; the IoU head is trained to predict that IoU.sample_foreground_points
3Iterations 2–3 — refine. Sample a point from pred ⊕ gt (label 1 = missed object, 0 = hallucinated), accumulate it, feed the previous logits back as a dense mask prompt, decode a single refined mask.sample_error_points
4Losses. sigmoid focal + dice on masks, MSE on predicted IoU.sigmoid_focal_loss / dice_loss / iou_mse_loss
5Backward, end‑to‑end. Gradients from all 9 mask losses flow through decoder + prompt encoder + encoder; one Adam step.main

The full, annotated walkthrough — with the diagram, every tensor shape, the decoder‑batch gotcha, and a faithful‑vs‑simplified table — is in TRAINING_WALKTHROUGH.md.


tiny‑SAM vs real SAM

Same wiring as segment_anything/build_sam.py, just shrunken so it trains interactively:

tiny‑SAM (this demo)SAM ViT‑H (paper)
Image size128 × 1281024 × 1024
Embedding grid8 × 864 × 64
Prompt / decoder dim64256
ViT embed / depth / heads64 / 2 / 41280 / 32 / 16
Parameters355 K~636 M
Datasynthetic circlesSA‑1B (11 M images, 1.1 B masks)
Train batch / steps4 / 100256 / 665 k
Hardwarelaptop CPUmany GPUs

Everything that matters for understanding is preserved: 3‑iteration error‑driven prompting, multi‑mask + IoU‑head supervision, mask‑logit feedback, and the three losses. What's dropped for size is listed honestly in the walkthrough.


Things to try

Tiny‑SAM is meant to be poked. In tiny_sam.py:

  • N_STEPS = 300 — watch IoU saturate near 1.0; confirms it really learns, not memorizes (every step is a fresh random image).
  • Freeze the encoder — reproduces SAM's late‑training stage and makes steps much faster:
    forpinsam.image_encoder.parameters():
    p.requires_grad_(False)
  • Box prompts — unambiguous, so they skip the multi‑mask stage:
    fromsegment_anything.utils.amgimportbatched_mask_to_boxboxes=batched_mask_to_box(gt)
    sparse, dense=sam.prompt_encoder(points=None, boxes=boxes, masks=None)
  • Drop the IoU loss — training loss still falls, but mask selection at inference (no GT) breaks. This isolates exactly why the IoU head exists.

Repo layout

tiny_sam.py ← the training loop (start here)
TRAINING_WALKTHROUGH.md ← step-by-step explanation + diagram
assets/training_loop.png ← rendered training-loop diagram
assets/training_loop.excalidraw ← editable diagram source
segment_anything/ ← upstream SAM model code (unchanged, used as the backbone)

Using the upstream model (unchanged)

The vendored segment_anything/ package is Meta's original, unmodified — so all of its inference tooling still works if you point it at a checkpoint:

fromsegment_anythingimportSamPredictor, sam_model_registrysam=sam_model_registry["vit_b"](checkpoint="sam_vit_b_01ec64.pth")
predictor=SamPredictor(sam)
predictor.set_image(<your_image>)
masks, scores, logits=predictor.predict(point_coords=..., point_labels=...)

Checkpoints: vit_h · vit_l · vit_b. Automatic "segment everything" (SamAutomaticMaskGenerator), ONNX export, and the browser demo are all still in scripts/, notebooks/, and demo/. For video, see the follow‑up SAM 2.


Built on Segment Anything

tiny‑SAM is an independent, educational reconstruction built on top of Meta AI Research's open‑source Segment Anything — it is not affiliated with or endorsed by Meta. The segment_anything/ model code is reproduced verbatim under its original license; the training‑loop script, walkthrough, and diagrams are original additions for learning purposes.

If you use SAM or SA‑1B in research, please cite the original work:

BibTeX
@article{kirillov2023segany,
title={Segment Anything},
author={Kirillov, Alexander and Mintun, Eric and Ravi, Nikhila and Mao, Hanzi and Rolland, Chloe and Gustafson, Laura and Xiao, Tete and Whitehead, Spencer and Berg, Alexander C. and Lo, Wan-Yen and Doll{\'a}r, Piotr and Girshick, Ross},
journal={arXiv:2304.02643},
year={2023}
}

About

The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - DreamRunnerMoshi/Tiny_SAM: The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model. · GitHub
Skip to content

Repository files navigation

🪄 tiny‑SAM — watch Segment Anything learn, on a laptop

built on Segment AnythingPyTorchruns ontiny modelpaper

Meta's SAM ships inference code only — there is no training script. tiny‑SAM is a self‑contained reconstruction of SAM's training loop from the paper, shrunk to 355K parameters so the whole thing — image encoder, prompt encoder, mask decoder, multi‑mask selection, error‑driven re‑prompting, mask feedback, focal + dice + IoU losses, end‑to‑end backprop — runs in a few seconds on a CPU and visibly learns to segment:

step 0 loss 2.652 IoU 0.12 → 0.08 step 49 loss 0.286 IoU 0.86 → 0.87
step 19 loss 1.529 IoU 0.82 → 0.82 step 99 loss 0.096 IoU 0.96 → 0.96 ✅

If you've ever wanted to see how a promptable segmenter is actually trained — not just call predictor.predict() — this is the repo for it.

tiny-SAM training loop

One optimizer step, end‑to‑end. The green dashed rail is the image embedding, computed once and reused by all three prompt iterations; the orange / blue elbows feed each iteration's predicted mask and low‑res logits back into the next prompt; the red lines on the right merge the three losses into a single backward pass. Editable source: assets/training_loop.excalidraw.


Why this exists

The official segment_anything/ package gives you a frozen model and a beautiful inference API — but it never shows how the model got good. The training procedure lives only in §3.1 of the paper (Kirillov et al., Segment Anything, ICCV 2023). tiny‑SAM turns that prose into runnable, annotated code, line‑for‑line mapped to the paper, so you can read it, break it, and watch the numbers move.

It's a great way to understand, concretely:

  • why the image encoder runs once and the tiny decoder runs many times,
  • how a single ambiguous click becomes 3 candidate masks, and how the IoU head learns to pick the right one without ground truth at inference time,
  • how mistakes become the next prompt (sample points from pred XOR gt),
  • and a subtle API gotcha: the decoder's batch dim is prompt hypotheses per image, not images — which is exactly why Sam.forward() loops over the batch.

Quickstart

No checkpoint download, no GPU, no dataset. Just PyTorch:

git clone https://github.com/DreamRunnerMoshi/segment-anything.git
cd segment-anything
python3 -m venv .venv
.venv/bin/pip install torch numpy
.venv/bin/python tiny_sam.py

(tiny_sam.py only needs the vendored segment_anything/modeling package — no torchvision, no extra deps. Set SAM_DEVICE=mps or cuda to use a GPU.)

You'll see one fully‑traced step (every tensor shape printed), then 100 streaming steps on fresh synthetic images — a tiny stand‑in for SA‑1B:

tiny SAM on cpu: 355,528 params (encoder 195,456 | prompt 1,804 | decoder 158,268)
training all of it end-to-end, as in the paper
=== one training step, traced ===
image (4, 3, 128, 128) -> encoder ONCE -> (4, 64, 8, 8)
it1 prompt (4, 1, 2) xy -> sparse (4, 2, 64) (2nd token is the auto-padded 'no-point' token)
it1 decoder multi-mask: low_res (4, 3, 32, 32), logits (4, 3, 128, 128), iou_pred (4, 3)
it1 selected-mask mean IoU: 0.082
it2 prompt 2 accumulated pts -> sparse (4, 3, 64), dense mask feedback (4, 64, 8, 8) -> single mask
it3 prompt 3 accumulated pts -> sparse (4, 4, 64), dense mask feedback (4, 64, 8, 8) -> single mask
=== fresh synthetic batch every step (like streaming from SA-1B) ===
step 0 loss 2.652 IoU it1 0.119 -> it3 0.080 |grad| 1.74
step 8 loss 2.748 IoU it1 0.419 -> it3 0.393 |grad| 1.49
step 19 loss 1.529 IoU it1 0.818 -> it3 0.816 |grad| 3.39
step 49 loss 0.286 IoU it1 0.859 -> it3 0.865 |grad| 1.00
step 69 loss 0.162 IoU it1 0.919 -> it3 0.927 |grad| 1.15
step 99 loss 0.096 IoU it1 0.958 -> it3 0.960 |grad| 0.89

Mean mask IoU on unseen images goes 0.08 → 0.96 — the loop genuinely trains segmentation, from scratch, end‑to‑end.


How the training loop works

tiny_sam.py follows the paper's recipe in five steps per optimizer step:

#What happensWhere
1Encode once.ImageEncoderViT → embedding (B,64,8,8), cached & reused.train_step
2Iteration 1 — ambiguous. One foreground point → PromptEncoder → decoder with multimask=True → 3 masks; a teacher (hard IoU vs GT) picks the best; the IoU head is trained to predict that IoU.sample_foreground_points
3Iterations 2–3 — refine. Sample a point from pred ⊕ gt (label 1 = missed object, 0 = hallucinated), accumulate it, feed the previous logits back as a dense mask prompt, decode a single refined mask.sample_error_points
4Losses. sigmoid focal + dice on masks, MSE on predicted IoU.sigmoid_focal_loss / dice_loss / iou_mse_loss
5Backward, end‑to‑end. Gradients from all 9 mask losses flow through decoder + prompt encoder + encoder; one Adam step.main

The full, annotated walkthrough — with the diagram, every tensor shape, the decoder‑batch gotcha, and a faithful‑vs‑simplified table — is in TRAINING_WALKTHROUGH.md.


tiny‑SAM vs real SAM

Same wiring as segment_anything/build_sam.py, just shrunken so it trains interactively:

tiny‑SAM (this demo)SAM ViT‑H (paper)
Image size128 × 1281024 × 1024
Embedding grid8 × 864 × 64
Prompt / decoder dim64256
ViT embed / depth / heads64 / 2 / 41280 / 32 / 16
Parameters355 K~636 M
Datasynthetic circlesSA‑1B (11 M images, 1.1 B masks)
Train batch / steps4 / 100256 / 665 k
Hardwarelaptop CPUmany GPUs

Everything that matters for understanding is preserved: 3‑iteration error‑driven prompting, multi‑mask + IoU‑head supervision, mask‑logit feedback, and the three losses. What's dropped for size is listed honestly in the walkthrough.


Things to try

Tiny‑SAM is meant to be poked. In tiny_sam.py:

  • N_STEPS = 300 — watch IoU saturate near 1.0; confirms it really learns, not memorizes (every step is a fresh random image).
  • Freeze the encoder — reproduces SAM's late‑training stage and makes steps much faster:
    forpinsam.image_encoder.parameters():
    p.requires_grad_(False)
  • Box prompts — unambiguous, so they skip the multi‑mask stage:
    fromsegment_anything.utils.amgimportbatched_mask_to_boxboxes=batched_mask_to_box(gt)
    sparse, dense=sam.prompt_encoder(points=None, boxes=boxes, masks=None)
  • Drop the IoU loss — training loss still falls, but mask selection at inference (no GT) breaks. This isolates exactly why the IoU head exists.

Repo layout

tiny_sam.py ← the training loop (start here)
TRAINING_WALKTHROUGH.md ← step-by-step explanation + diagram
assets/training_loop.png ← rendered training-loop diagram
assets/training_loop.excalidraw ← editable diagram source
segment_anything/ ← upstream SAM model code (unchanged, used as the backbone)

Using the upstream model (unchanged)

The vendored segment_anything/ package is Meta's original, unmodified — so all of its inference tooling still works if you point it at a checkpoint:

fromsegment_anythingimportSamPredictor, sam_model_registrysam=sam_model_registry["vit_b"](checkpoint="sam_vit_b_01ec64.pth")
predictor=SamPredictor(sam)
predictor.set_image(<your_image>)
masks, scores, logits=predictor.predict(point_coords=..., point_labels=...)

Checkpoints: vit_h · vit_l · vit_b. Automatic "segment everything" (SamAutomaticMaskGenerator), ONNX export, and the browser demo are all still in scripts/, notebooks/, and demo/. For video, see the follow‑up SAM 2.


Built on Segment Anything

tiny‑SAM is an independent, educational reconstruction built on top of Meta AI Research's open‑source Segment Anything — it is not affiliated with or endorsed by Meta. The segment_anything/ model code is reproduced verbatim under its original license; the training‑loop script, walkthrough, and diagrams are original additions for learning purposes.

If you use SAM or SA‑1B in research, please cite the original work:

BibTeX
@article{kirillov2023segany,
title={Segment Anything},
author={Kirillov, Alexander and Mintun, Eric and Ravi, Nikhila and Mao, Hanzi and Rolland, Chloe and Gustafson, Laura and Xiao, Tete and Whitehead, Spencer and Berg, Alexander C. and Lo, Wan-Yen and Doll{\'a}r, Piotr and Girshick, Ross},
journal={arXiv:2304.02643},
year={2023}
}

About

The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - DreamRunnerMoshi/Tiny_SAM: The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model. · GitHub
Skip to content

Repository files navigation

🪄 tiny‑SAM — watch Segment Anything learn, on a laptop

built on Segment AnythingPyTorchruns ontiny modelpaper

Meta's SAM ships inference code only — there is no training script. tiny‑SAM is a self‑contained reconstruction of SAM's training loop from the paper, shrunk to 355K parameters so the whole thing — image encoder, prompt encoder, mask decoder, multi‑mask selection, error‑driven re‑prompting, mask feedback, focal + dice + IoU losses, end‑to‑end backprop — runs in a few seconds on a CPU and visibly learns to segment:

step 0 loss 2.652 IoU 0.12 → 0.08 step 49 loss 0.286 IoU 0.86 → 0.87
step 19 loss 1.529 IoU 0.82 → 0.82 step 99 loss 0.096 IoU 0.96 → 0.96 ✅

If you've ever wanted to see how a promptable segmenter is actually trained — not just call predictor.predict() — this is the repo for it.

tiny-SAM training loop

One optimizer step, end‑to‑end. The green dashed rail is the image embedding, computed once and reused by all three prompt iterations; the orange / blue elbows feed each iteration's predicted mask and low‑res logits back into the next prompt; the red lines on the right merge the three losses into a single backward pass. Editable source: assets/training_loop.excalidraw.


Why this exists

The official segment_anything/ package gives you a frozen model and a beautiful inference API — but it never shows how the model got good. The training procedure lives only in §3.1 of the paper (Kirillov et al., Segment Anything, ICCV 2023). tiny‑SAM turns that prose into runnable, annotated code, line‑for‑line mapped to the paper, so you can read it, break it, and watch the numbers move.

It's a great way to understand, concretely:

  • why the image encoder runs once and the tiny decoder runs many times,
  • how a single ambiguous click becomes 3 candidate masks, and how the IoU head learns to pick the right one without ground truth at inference time,
  • how mistakes become the next prompt (sample points from pred XOR gt),
  • and a subtle API gotcha: the decoder's batch dim is prompt hypotheses per image, not images — which is exactly why Sam.forward() loops over the batch.

Quickstart

No checkpoint download, no GPU, no dataset. Just PyTorch:

git clone https://github.com/DreamRunnerMoshi/segment-anything.git
cd segment-anything
python3 -m venv .venv
.venv/bin/pip install torch numpy
.venv/bin/python tiny_sam.py

(tiny_sam.py only needs the vendored segment_anything/modeling package — no torchvision, no extra deps. Set SAM_DEVICE=mps or cuda to use a GPU.)

You'll see one fully‑traced step (every tensor shape printed), then 100 streaming steps on fresh synthetic images — a tiny stand‑in for SA‑1B:

tiny SAM on cpu: 355,528 params (encoder 195,456 | prompt 1,804 | decoder 158,268)
training all of it end-to-end, as in the paper
=== one training step, traced ===
image (4, 3, 128, 128) -> encoder ONCE -> (4, 64, 8, 8)
it1 prompt (4, 1, 2) xy -> sparse (4, 2, 64) (2nd token is the auto-padded 'no-point' token)
it1 decoder multi-mask: low_res (4, 3, 32, 32), logits (4, 3, 128, 128), iou_pred (4, 3)
it1 selected-mask mean IoU: 0.082
it2 prompt 2 accumulated pts -> sparse (4, 3, 64), dense mask feedback (4, 64, 8, 8) -> single mask
it3 prompt 3 accumulated pts -> sparse (4, 4, 64), dense mask feedback (4, 64, 8, 8) -> single mask
=== fresh synthetic batch every step (like streaming from SA-1B) ===
step 0 loss 2.652 IoU it1 0.119 -> it3 0.080 |grad| 1.74
step 8 loss 2.748 IoU it1 0.419 -> it3 0.393 |grad| 1.49
step 19 loss 1.529 IoU it1 0.818 -> it3 0.816 |grad| 3.39
step 49 loss 0.286 IoU it1 0.859 -> it3 0.865 |grad| 1.00
step 69 loss 0.162 IoU it1 0.919 -> it3 0.927 |grad| 1.15
step 99 loss 0.096 IoU it1 0.958 -> it3 0.960 |grad| 0.89

Mean mask IoU on unseen images goes 0.08 → 0.96 — the loop genuinely trains segmentation, from scratch, end‑to‑end.


How the training loop works

tiny_sam.py follows the paper's recipe in five steps per optimizer step:

#What happensWhere
1Encode once.ImageEncoderViT → embedding (B,64,8,8), cached & reused.train_step
2Iteration 1 — ambiguous. One foreground point → PromptEncoder → decoder with multimask=True → 3 masks; a teacher (hard IoU vs GT) picks the best; the IoU head is trained to predict that IoU.sample_foreground_points
3Iterations 2–3 — refine. Sample a point from pred ⊕ gt (label 1 = missed object, 0 = hallucinated), accumulate it, feed the previous logits back as a dense mask prompt, decode a single refined mask.sample_error_points
4Losses. sigmoid focal + dice on masks, MSE on predicted IoU.sigmoid_focal_loss / dice_loss / iou_mse_loss
5Backward, end‑to‑end. Gradients from all 9 mask losses flow through decoder + prompt encoder + encoder; one Adam step.main

The full, annotated walkthrough — with the diagram, every tensor shape, the decoder‑batch gotcha, and a faithful‑vs‑simplified table — is in TRAINING_WALKTHROUGH.md.


tiny‑SAM vs real SAM

Same wiring as segment_anything/build_sam.py, just shrunken so it trains interactively:

tiny‑SAM (this demo)SAM ViT‑H (paper)
Image size128 × 1281024 × 1024
Embedding grid8 × 864 × 64
Prompt / decoder dim64256
ViT embed / depth / heads64 / 2 / 41280 / 32 / 16
Parameters355 K~636 M
Datasynthetic circlesSA‑1B (11 M images, 1.1 B masks)
Train batch / steps4 / 100256 / 665 k
Hardwarelaptop CPUmany GPUs

Everything that matters for understanding is preserved: 3‑iteration error‑driven prompting, multi‑mask + IoU‑head supervision, mask‑logit feedback, and the three losses. What's dropped for size is listed honestly in the walkthrough.


Things to try

Tiny‑SAM is meant to be poked. In tiny_sam.py:

  • N_STEPS = 300 — watch IoU saturate near 1.0; confirms it really learns, not memorizes (every step is a fresh random image).
  • Freeze the encoder — reproduces SAM's late‑training stage and makes steps much faster:
    forpinsam.image_encoder.parameters():
    p.requires_grad_(False)
  • Box prompts — unambiguous, so they skip the multi‑mask stage:
    fromsegment_anything.utils.amgimportbatched_mask_to_boxboxes=batched_mask_to_box(gt)
    sparse, dense=sam.prompt_encoder(points=None, boxes=boxes, masks=None)
  • Drop the IoU loss — training loss still falls, but mask selection at inference (no GT) breaks. This isolates exactly why the IoU head exists.

Repo layout

tiny_sam.py ← the training loop (start here)
TRAINING_WALKTHROUGH.md ← step-by-step explanation + diagram
assets/training_loop.png ← rendered training-loop diagram
assets/training_loop.excalidraw ← editable diagram source
segment_anything/ ← upstream SAM model code (unchanged, used as the backbone)

Using the upstream model (unchanged)

The vendored segment_anything/ package is Meta's original, unmodified — so all of its inference tooling still works if you point it at a checkpoint:

fromsegment_anythingimportSamPredictor, sam_model_registrysam=sam_model_registry["vit_b"](checkpoint="sam_vit_b_01ec64.pth")
predictor=SamPredictor(sam)
predictor.set_image(<your_image>)
masks, scores, logits=predictor.predict(point_coords=..., point_labels=...)

Checkpoints: vit_h · vit_l · vit_b. Automatic "segment everything" (SamAutomaticMaskGenerator), ONNX export, and the browser demo are all still in scripts/, notebooks/, and demo/. For video, see the follow‑up SAM 2.


Built on Segment Anything

tiny‑SAM is an independent, educational reconstruction built on top of Meta AI Research's open‑source Segment Anything — it is not affiliated with or endorsed by Meta. The segment_anything/ model code is reproduced verbatim under its original license; the training‑loop script, walkthrough, and diagrams are original additions for learning purposes.

If you use SAM or SA‑1B in research, please cite the original work:

BibTeX
@article{kirillov2023segany,
title={Segment Anything},
author={Kirillov, Alexander and Mintun, Eric and Ravi, Nikhila and Mao, Hanzi and Rolland, Chloe and Gustafson, Laura and Xiao, Tete and Whitehead, Spencer and Berg, Alexander C. and Lo, Wan-Yen and Doll{\'a}r, Piotr and Girshick, Ross},
journal={arXiv:2304.02643},
year={2023}
}

About

The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - DreamRunnerMoshi/Tiny_SAM: The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model. · GitHub
Skip to content

Repository files navigation

🪄 tiny‑SAM — watch Segment Anything learn, on a laptop

built on Segment AnythingPyTorchruns ontiny modelpaper

Meta's SAM ships inference code only — there is no training script. tiny‑SAM is a self‑contained reconstruction of SAM's training loop from the paper, shrunk to 355K parameters so the whole thing — image encoder, prompt encoder, mask decoder, multi‑mask selection, error‑driven re‑prompting, mask feedback, focal + dice + IoU losses, end‑to‑end backprop — runs in a few seconds on a CPU and visibly learns to segment:

step 0 loss 2.652 IoU 0.12 → 0.08 step 49 loss 0.286 IoU 0.86 → 0.87
step 19 loss 1.529 IoU 0.82 → 0.82 step 99 loss 0.096 IoU 0.96 → 0.96 ✅

If you've ever wanted to see how a promptable segmenter is actually trained — not just call predictor.predict() — this is the repo for it.

tiny-SAM training loop

One optimizer step, end‑to‑end. The green dashed rail is the image embedding, computed once and reused by all three prompt iterations; the orange / blue elbows feed each iteration's predicted mask and low‑res logits back into the next prompt; the red lines on the right merge the three losses into a single backward pass. Editable source: assets/training_loop.excalidraw.


Why this exists

The official segment_anything/ package gives you a frozen model and a beautiful inference API — but it never shows how the model got good. The training procedure lives only in §3.1 of the paper (Kirillov et al., Segment Anything, ICCV 2023). tiny‑SAM turns that prose into runnable, annotated code, line‑for‑line mapped to the paper, so you can read it, break it, and watch the numbers move.

It's a great way to understand, concretely:

  • why the image encoder runs once and the tiny decoder runs many times,
  • how a single ambiguous click becomes 3 candidate masks, and how the IoU head learns to pick the right one without ground truth at inference time,
  • how mistakes become the next prompt (sample points from pred XOR gt),
  • and a subtle API gotcha: the decoder's batch dim is prompt hypotheses per image, not images — which is exactly why Sam.forward() loops over the batch.

Quickstart

No checkpoint download, no GPU, no dataset. Just PyTorch:

git clone https://github.com/DreamRunnerMoshi/segment-anything.git
cd segment-anything
python3 -m venv .venv
.venv/bin/pip install torch numpy
.venv/bin/python tiny_sam.py

(tiny_sam.py only needs the vendored segment_anything/modeling package — no torchvision, no extra deps. Set SAM_DEVICE=mps or cuda to use a GPU.)

You'll see one fully‑traced step (every tensor shape printed), then 100 streaming steps on fresh synthetic images — a tiny stand‑in for SA‑1B:

tiny SAM on cpu: 355,528 params (encoder 195,456 | prompt 1,804 | decoder 158,268)
training all of it end-to-end, as in the paper
=== one training step, traced ===
image (4, 3, 128, 128) -> encoder ONCE -> (4, 64, 8, 8)
it1 prompt (4, 1, 2) xy -> sparse (4, 2, 64) (2nd token is the auto-padded 'no-point' token)
it1 decoder multi-mask: low_res (4, 3, 32, 32), logits (4, 3, 128, 128), iou_pred (4, 3)
it1 selected-mask mean IoU: 0.082
it2 prompt 2 accumulated pts -> sparse (4, 3, 64), dense mask feedback (4, 64, 8, 8) -> single mask
it3 prompt 3 accumulated pts -> sparse (4, 4, 64), dense mask feedback (4, 64, 8, 8) -> single mask
=== fresh synthetic batch every step (like streaming from SA-1B) ===
step 0 loss 2.652 IoU it1 0.119 -> it3 0.080 |grad| 1.74
step 8 loss 2.748 IoU it1 0.419 -> it3 0.393 |grad| 1.49
step 19 loss 1.529 IoU it1 0.818 -> it3 0.816 |grad| 3.39
step 49 loss 0.286 IoU it1 0.859 -> it3 0.865 |grad| 1.00
step 69 loss 0.162 IoU it1 0.919 -> it3 0.927 |grad| 1.15
step 99 loss 0.096 IoU it1 0.958 -> it3 0.960 |grad| 0.89

Mean mask IoU on unseen images goes 0.08 → 0.96 — the loop genuinely trains segmentation, from scratch, end‑to‑end.


How the training loop works

tiny_sam.py follows the paper's recipe in five steps per optimizer step:

#What happensWhere
1Encode once.ImageEncoderViT → embedding (B,64,8,8), cached & reused.train_step
2Iteration 1 — ambiguous. One foreground point → PromptEncoder → decoder with multimask=True → 3 masks; a teacher (hard IoU vs GT) picks the best; the IoU head is trained to predict that IoU.sample_foreground_points
3Iterations 2–3 — refine. Sample a point from pred ⊕ gt (label 1 = missed object, 0 = hallucinated), accumulate it, feed the previous logits back as a dense mask prompt, decode a single refined mask.sample_error_points
4Losses. sigmoid focal + dice on masks, MSE on predicted IoU.sigmoid_focal_loss / dice_loss / iou_mse_loss
5Backward, end‑to‑end. Gradients from all 9 mask losses flow through decoder + prompt encoder + encoder; one Adam step.main

The full, annotated walkthrough — with the diagram, every tensor shape, the decoder‑batch gotcha, and a faithful‑vs‑simplified table — is in TRAINING_WALKTHROUGH.md.


tiny‑SAM vs real SAM

Same wiring as segment_anything/build_sam.py, just shrunken so it trains interactively:

tiny‑SAM (this demo)SAM ViT‑H (paper)
Image size128 × 1281024 × 1024
Embedding grid8 × 864 × 64
Prompt / decoder dim64256
ViT embed / depth / heads64 / 2 / 41280 / 32 / 16
Parameters355 K~636 M
Datasynthetic circlesSA‑1B (11 M images, 1.1 B masks)
Train batch / steps4 / 100256 / 665 k
Hardwarelaptop CPUmany GPUs

Everything that matters for understanding is preserved: 3‑iteration error‑driven prompting, multi‑mask + IoU‑head supervision, mask‑logit feedback, and the three losses. What's dropped for size is listed honestly in the walkthrough.


Things to try

Tiny‑SAM is meant to be poked. In tiny_sam.py:

  • N_STEPS = 300 — watch IoU saturate near 1.0; confirms it really learns, not memorizes (every step is a fresh random image).
  • Freeze the encoder — reproduces SAM's late‑training stage and makes steps much faster:
    forpinsam.image_encoder.parameters():
    p.requires_grad_(False)
  • Box prompts — unambiguous, so they skip the multi‑mask stage:
    fromsegment_anything.utils.amgimportbatched_mask_to_boxboxes=batched_mask_to_box(gt)
    sparse, dense=sam.prompt_encoder(points=None, boxes=boxes, masks=None)
  • Drop the IoU loss — training loss still falls, but mask selection at inference (no GT) breaks. This isolates exactly why the IoU head exists.

Repo layout

tiny_sam.py ← the training loop (start here)
TRAINING_WALKTHROUGH.md ← step-by-step explanation + diagram
assets/training_loop.png ← rendered training-loop diagram
assets/training_loop.excalidraw ← editable diagram source
segment_anything/ ← upstream SAM model code (unchanged, used as the backbone)

Using the upstream model (unchanged)

The vendored segment_anything/ package is Meta's original, unmodified — so all of its inference tooling still works if you point it at a checkpoint:

fromsegment_anythingimportSamPredictor, sam_model_registrysam=sam_model_registry["vit_b"](checkpoint="sam_vit_b_01ec64.pth")
predictor=SamPredictor(sam)
predictor.set_image(<your_image>)
masks, scores, logits=predictor.predict(point_coords=..., point_labels=...)

Checkpoints: vit_h · vit_l · vit_b. Automatic "segment everything" (SamAutomaticMaskGenerator), ONNX export, and the browser demo are all still in scripts/, notebooks/, and demo/. For video, see the follow‑up SAM 2.


Built on Segment Anything

tiny‑SAM is an independent, educational reconstruction built on top of Meta AI Research's open‑source Segment Anything — it is not affiliated with or endorsed by Meta. The segment_anything/ model code is reproduced verbatim under its original license; the training‑loop script, walkthrough, and diagrams are original additions for learning purposes.

If you use SAM or SA‑1B in research, please cite the original work:

BibTeX
@article{kirillov2023segany,
title={Segment Anything},
author={Kirillov, Alexander and Mintun, Eric and Ravi, Nikhila and Mao, Hanzi and Rolland, Chloe and Gustafson, Laura and Xiao, Tete and Whitehead, Spencer and Berg, Alexander C. and Lo, Wan-Yen and Doll{\'a}r, Piotr and Girshick, Ross},
journal={arXiv:2304.02643},
year={2023}
}

About

The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - DreamRunnerMoshi/Tiny_SAM: The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model. · GitHub
Skip to content

Repository files navigation

🪄 tiny‑SAM — watch Segment Anything learn, on a laptop

built on Segment AnythingPyTorchruns ontiny modelpaper

Meta's SAM ships inference code only — there is no training script. tiny‑SAM is a self‑contained reconstruction of SAM's training loop from the paper, shrunk to 355K parameters so the whole thing — image encoder, prompt encoder, mask decoder, multi‑mask selection, error‑driven re‑prompting, mask feedback, focal + dice + IoU losses, end‑to‑end backprop — runs in a few seconds on a CPU and visibly learns to segment:

step 0 loss 2.652 IoU 0.12 → 0.08 step 49 loss 0.286 IoU 0.86 → 0.87
step 19 loss 1.529 IoU 0.82 → 0.82 step 99 loss 0.096 IoU 0.96 → 0.96 ✅

If you've ever wanted to see how a promptable segmenter is actually trained — not just call predictor.predict() — this is the repo for it.

tiny-SAM training loop

One optimizer step, end‑to‑end. The green dashed rail is the image embedding, computed once and reused by all three prompt iterations; the orange / blue elbows feed each iteration's predicted mask and low‑res logits back into the next prompt; the red lines on the right merge the three losses into a single backward pass. Editable source: assets/training_loop.excalidraw.


Why this exists

The official segment_anything/ package gives you a frozen model and a beautiful inference API — but it never shows how the model got good. The training procedure lives only in §3.1 of the paper (Kirillov et al., Segment Anything, ICCV 2023). tiny‑SAM turns that prose into runnable, annotated code, line‑for‑line mapped to the paper, so you can read it, break it, and watch the numbers move.

It's a great way to understand, concretely:

  • why the image encoder runs once and the tiny decoder runs many times,
  • how a single ambiguous click becomes 3 candidate masks, and how the IoU head learns to pick the right one without ground truth at inference time,
  • how mistakes become the next prompt (sample points from pred XOR gt),
  • and a subtle API gotcha: the decoder's batch dim is prompt hypotheses per image, not images — which is exactly why Sam.forward() loops over the batch.

Quickstart

No checkpoint download, no GPU, no dataset. Just PyTorch:

git clone https://github.com/DreamRunnerMoshi/segment-anything.git
cd segment-anything
python3 -m venv .venv
.venv/bin/pip install torch numpy
.venv/bin/python tiny_sam.py

(tiny_sam.py only needs the vendored segment_anything/modeling package — no torchvision, no extra deps. Set SAM_DEVICE=mps or cuda to use a GPU.)

You'll see one fully‑traced step (every tensor shape printed), then 100 streaming steps on fresh synthetic images — a tiny stand‑in for SA‑1B:

tiny SAM on cpu: 355,528 params (encoder 195,456 | prompt 1,804 | decoder 158,268)
training all of it end-to-end, as in the paper
=== one training step, traced ===
image (4, 3, 128, 128) -> encoder ONCE -> (4, 64, 8, 8)
it1 prompt (4, 1, 2) xy -> sparse (4, 2, 64) (2nd token is the auto-padded 'no-point' token)
it1 decoder multi-mask: low_res (4, 3, 32, 32), logits (4, 3, 128, 128), iou_pred (4, 3)
it1 selected-mask mean IoU: 0.082
it2 prompt 2 accumulated pts -> sparse (4, 3, 64), dense mask feedback (4, 64, 8, 8) -> single mask
it3 prompt 3 accumulated pts -> sparse (4, 4, 64), dense mask feedback (4, 64, 8, 8) -> single mask
=== fresh synthetic batch every step (like streaming from SA-1B) ===
step 0 loss 2.652 IoU it1 0.119 -> it3 0.080 |grad| 1.74
step 8 loss 2.748 IoU it1 0.419 -> it3 0.393 |grad| 1.49
step 19 loss 1.529 IoU it1 0.818 -> it3 0.816 |grad| 3.39
step 49 loss 0.286 IoU it1 0.859 -> it3 0.865 |grad| 1.00
step 69 loss 0.162 IoU it1 0.919 -> it3 0.927 |grad| 1.15
step 99 loss 0.096 IoU it1 0.958 -> it3 0.960 |grad| 0.89

Mean mask IoU on unseen images goes 0.08 → 0.96 — the loop genuinely trains segmentation, from scratch, end‑to‑end.


How the training loop works

tiny_sam.py follows the paper's recipe in five steps per optimizer step:

#What happensWhere
1Encode once.ImageEncoderViT → embedding (B,64,8,8), cached & reused.train_step
2Iteration 1 — ambiguous. One foreground point → PromptEncoder → decoder with multimask=True → 3 masks; a teacher (hard IoU vs GT) picks the best; the IoU head is trained to predict that IoU.sample_foreground_points
3Iterations 2–3 — refine. Sample a point from pred ⊕ gt (label 1 = missed object, 0 = hallucinated), accumulate it, feed the previous logits back as a dense mask prompt, decode a single refined mask.sample_error_points
4Losses. sigmoid focal + dice on masks, MSE on predicted IoU.sigmoid_focal_loss / dice_loss / iou_mse_loss
5Backward, end‑to‑end. Gradients from all 9 mask losses flow through decoder + prompt encoder + encoder; one Adam step.main

The full, annotated walkthrough — with the diagram, every tensor shape, the decoder‑batch gotcha, and a faithful‑vs‑simplified table — is in TRAINING_WALKTHROUGH.md.


tiny‑SAM vs real SAM

Same wiring as segment_anything/build_sam.py, just shrunken so it trains interactively:

tiny‑SAM (this demo)SAM ViT‑H (paper)
Image size128 × 1281024 × 1024
Embedding grid8 × 864 × 64
Prompt / decoder dim64256
ViT embed / depth / heads64 / 2 / 41280 / 32 / 16
Parameters355 K~636 M
Datasynthetic circlesSA‑1B (11 M images, 1.1 B masks)
Train batch / steps4 / 100256 / 665 k
Hardwarelaptop CPUmany GPUs

Everything that matters for understanding is preserved: 3‑iteration error‑driven prompting, multi‑mask + IoU‑head supervision, mask‑logit feedback, and the three losses. What's dropped for size is listed honestly in the walkthrough.


Things to try

Tiny‑SAM is meant to be poked. In tiny_sam.py:

  • N_STEPS = 300 — watch IoU saturate near 1.0; confirms it really learns, not memorizes (every step is a fresh random image).
  • Freeze the encoder — reproduces SAM's late‑training stage and makes steps much faster:
    forpinsam.image_encoder.parameters():
    p.requires_grad_(False)
  • Box prompts — unambiguous, so they skip the multi‑mask stage:
    fromsegment_anything.utils.amgimportbatched_mask_to_boxboxes=batched_mask_to_box(gt)
    sparse, dense=sam.prompt_encoder(points=None, boxes=boxes, masks=None)
  • Drop the IoU loss — training loss still falls, but mask selection at inference (no GT) breaks. This isolates exactly why the IoU head exists.

Repo layout

tiny_sam.py ← the training loop (start here)
TRAINING_WALKTHROUGH.md ← step-by-step explanation + diagram
assets/training_loop.png ← rendered training-loop diagram
assets/training_loop.excalidraw ← editable diagram source
segment_anything/ ← upstream SAM model code (unchanged, used as the backbone)

Using the upstream model (unchanged)

The vendored segment_anything/ package is Meta's original, unmodified — so all of its inference tooling still works if you point it at a checkpoint:

fromsegment_anythingimportSamPredictor, sam_model_registrysam=sam_model_registry["vit_b"](checkpoint="sam_vit_b_01ec64.pth")
predictor=SamPredictor(sam)
predictor.set_image(<your_image>)
masks, scores, logits=predictor.predict(point_coords=..., point_labels=...)

Checkpoints: vit_h · vit_l · vit_b. Automatic "segment everything" (SamAutomaticMaskGenerator), ONNX export, and the browser demo are all still in scripts/, notebooks/, and demo/. For video, see the follow‑up SAM 2.


Built on Segment Anything

tiny‑SAM is an independent, educational reconstruction built on top of Meta AI Research's open‑source Segment Anything — it is not affiliated with or endorsed by Meta. The segment_anything/ model code is reproduced verbatim under its original license; the training‑loop script, walkthrough, and diagrams are original additions for learning purposes.

If you use SAM or SA‑1B in research, please cite the original work:

BibTeX
@article{kirillov2023segany,
title={Segment Anything},
author={Kirillov, Alexander and Mintun, Eric and Ravi, Nikhila and Mao, Hanzi and Rolland, Chloe and Gustafson, Laura and Xiao, Tete and Whitehead, Spencer and Berg, Alexander C. and Lo, Wan-Yen and Doll{\'a}r, Piotr and Girshick, Ross},
journal={arXiv:2304.02643},
year={2023}
}

About

The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - DreamRunnerMoshi/Tiny_SAM: The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model. · GitHub
Skip to content

Repository files navigation

🪄 tiny‑SAM — watch Segment Anything learn, on a laptop

built on Segment AnythingPyTorchruns ontiny modelpaper

Meta's SAM ships inference code only — there is no training script. tiny‑SAM is a self‑contained reconstruction of SAM's training loop from the paper, shrunk to 355K parameters so the whole thing — image encoder, prompt encoder, mask decoder, multi‑mask selection, error‑driven re‑prompting, mask feedback, focal + dice + IoU losses, end‑to‑end backprop — runs in a few seconds on a CPU and visibly learns to segment:

step 0 loss 2.652 IoU 0.12 → 0.08 step 49 loss 0.286 IoU 0.86 → 0.87
step 19 loss 1.529 IoU 0.82 → 0.82 step 99 loss 0.096 IoU 0.96 → 0.96 ✅

If you've ever wanted to see how a promptable segmenter is actually trained — not just call predictor.predict() — this is the repo for it.

tiny-SAM training loop

One optimizer step, end‑to‑end. The green dashed rail is the image embedding, computed once and reused by all three prompt iterations; the orange / blue elbows feed each iteration's predicted mask and low‑res logits back into the next prompt; the red lines on the right merge the three losses into a single backward pass. Editable source: assets/training_loop.excalidraw.


Why this exists

The official segment_anything/ package gives you a frozen model and a beautiful inference API — but it never shows how the model got good. The training procedure lives only in §3.1 of the paper (Kirillov et al., Segment Anything, ICCV 2023). tiny‑SAM turns that prose into runnable, annotated code, line‑for‑line mapped to the paper, so you can read it, break it, and watch the numbers move.

It's a great way to understand, concretely:

  • why the image encoder runs once and the tiny decoder runs many times,
  • how a single ambiguous click becomes 3 candidate masks, and how the IoU head learns to pick the right one without ground truth at inference time,
  • how mistakes become the next prompt (sample points from pred XOR gt),
  • and a subtle API gotcha: the decoder's batch dim is prompt hypotheses per image, not images — which is exactly why Sam.forward() loops over the batch.

Quickstart

No checkpoint download, no GPU, no dataset. Just PyTorch:

git clone https://github.com/DreamRunnerMoshi/segment-anything.git
cd segment-anything
python3 -m venv .venv
.venv/bin/pip install torch numpy
.venv/bin/python tiny_sam.py

(tiny_sam.py only needs the vendored segment_anything/modeling package — no torchvision, no extra deps. Set SAM_DEVICE=mps or cuda to use a GPU.)

You'll see one fully‑traced step (every tensor shape printed), then 100 streaming steps on fresh synthetic images — a tiny stand‑in for SA‑1B:

tiny SAM on cpu: 355,528 params (encoder 195,456 | prompt 1,804 | decoder 158,268)
training all of it end-to-end, as in the paper
=== one training step, traced ===
image (4, 3, 128, 128) -> encoder ONCE -> (4, 64, 8, 8)
it1 prompt (4, 1, 2) xy -> sparse (4, 2, 64) (2nd token is the auto-padded 'no-point' token)
it1 decoder multi-mask: low_res (4, 3, 32, 32), logits (4, 3, 128, 128), iou_pred (4, 3)
it1 selected-mask mean IoU: 0.082
it2 prompt 2 accumulated pts -> sparse (4, 3, 64), dense mask feedback (4, 64, 8, 8) -> single mask
it3 prompt 3 accumulated pts -> sparse (4, 4, 64), dense mask feedback (4, 64, 8, 8) -> single mask
=== fresh synthetic batch every step (like streaming from SA-1B) ===
step 0 loss 2.652 IoU it1 0.119 -> it3 0.080 |grad| 1.74
step 8 loss 2.748 IoU it1 0.419 -> it3 0.393 |grad| 1.49
step 19 loss 1.529 IoU it1 0.818 -> it3 0.816 |grad| 3.39
step 49 loss 0.286 IoU it1 0.859 -> it3 0.865 |grad| 1.00
step 69 loss 0.162 IoU it1 0.919 -> it3 0.927 |grad| 1.15
step 99 loss 0.096 IoU it1 0.958 -> it3 0.960 |grad| 0.89

Mean mask IoU on unseen images goes 0.08 → 0.96 — the loop genuinely trains segmentation, from scratch, end‑to‑end.


How the training loop works

tiny_sam.py follows the paper's recipe in five steps per optimizer step:

#What happensWhere
1Encode once.ImageEncoderViT → embedding (B,64,8,8), cached & reused.train_step
2Iteration 1 — ambiguous. One foreground point → PromptEncoder → decoder with multimask=True → 3 masks; a teacher (hard IoU vs GT) picks the best; the IoU head is trained to predict that IoU.sample_foreground_points
3Iterations 2–3 — refine. Sample a point from pred ⊕ gt (label 1 = missed object, 0 = hallucinated), accumulate it, feed the previous logits back as a dense mask prompt, decode a single refined mask.sample_error_points
4Losses. sigmoid focal + dice on masks, MSE on predicted IoU.sigmoid_focal_loss / dice_loss / iou_mse_loss
5Backward, end‑to‑end. Gradients from all 9 mask losses flow through decoder + prompt encoder + encoder; one Adam step.main

The full, annotated walkthrough — with the diagram, every tensor shape, the decoder‑batch gotcha, and a faithful‑vs‑simplified table — is in TRAINING_WALKTHROUGH.md.


tiny‑SAM vs real SAM

Same wiring as segment_anything/build_sam.py, just shrunken so it trains interactively:

tiny‑SAM (this demo)SAM ViT‑H (paper)
Image size128 × 1281024 × 1024
Embedding grid8 × 864 × 64
Prompt / decoder dim64256
ViT embed / depth / heads64 / 2 / 41280 / 32 / 16
Parameters355 K~636 M
Datasynthetic circlesSA‑1B (11 M images, 1.1 B masks)
Train batch / steps4 / 100256 / 665 k
Hardwarelaptop CPUmany GPUs

Everything that matters for understanding is preserved: 3‑iteration error‑driven prompting, multi‑mask + IoU‑head supervision, mask‑logit feedback, and the three losses. What's dropped for size is listed honestly in the walkthrough.


Things to try

Tiny‑SAM is meant to be poked. In tiny_sam.py:

  • N_STEPS = 300 — watch IoU saturate near 1.0; confirms it really learns, not memorizes (every step is a fresh random image).
  • Freeze the encoder — reproduces SAM's late‑training stage and makes steps much faster:
    forpinsam.image_encoder.parameters():
    p.requires_grad_(False)
  • Box prompts — unambiguous, so they skip the multi‑mask stage:
    fromsegment_anything.utils.amgimportbatched_mask_to_boxboxes=batched_mask_to_box(gt)
    sparse, dense=sam.prompt_encoder(points=None, boxes=boxes, masks=None)
  • Drop the IoU loss — training loss still falls, but mask selection at inference (no GT) breaks. This isolates exactly why the IoU head exists.

Repo layout

tiny_sam.py ← the training loop (start here)
TRAINING_WALKTHROUGH.md ← step-by-step explanation + diagram
assets/training_loop.png ← rendered training-loop diagram
assets/training_loop.excalidraw ← editable diagram source
segment_anything/ ← upstream SAM model code (unchanged, used as the backbone)

Using the upstream model (unchanged)

The vendored segment_anything/ package is Meta's original, unmodified — so all of its inference tooling still works if you point it at a checkpoint:

fromsegment_anythingimportSamPredictor, sam_model_registrysam=sam_model_registry["vit_b"](checkpoint="sam_vit_b_01ec64.pth")
predictor=SamPredictor(sam)
predictor.set_image(<your_image>)
masks, scores, logits=predictor.predict(point_coords=..., point_labels=...)

Checkpoints: vit_h · vit_l · vit_b. Automatic "segment everything" (SamAutomaticMaskGenerator), ONNX export, and the browser demo are all still in scripts/, notebooks/, and demo/. For video, see the follow‑up SAM 2.


Built on Segment Anything

tiny‑SAM is an independent, educational reconstruction built on top of Meta AI Research's open‑source Segment Anything — it is not affiliated with or endorsed by Meta. The segment_anything/ model code is reproduced verbatim under its original license; the training‑loop script, walkthrough, and diagrams are original additions for learning purposes.

If you use SAM or SA‑1B in research, please cite the original work:

BibTeX
@article{kirillov2023segany,
title={Segment Anything},
author={Kirillov, Alexander and Mintun, Eric and Ravi, Nikhila and Mao, Hanzi and Rolland, Chloe and Gustafson, Laura and Xiao, Tete and Whitehead, Spencer and Berg, Alexander C. and Lo, Wan-Yen and Doll{\'a}r, Piotr and Girshick, Ross},
journal={arXiv:2304.02643},
year={2023}
}

About

The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - DreamRunnerMoshi/Tiny_SAM: The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model. · GitHub
Skip to content

Repository files navigation

🪄 tiny‑SAM — watch Segment Anything learn, on a laptop

built on Segment AnythingPyTorchruns ontiny modelpaper

Meta's SAM ships inference code only — there is no training script. tiny‑SAM is a self‑contained reconstruction of SAM's training loop from the paper, shrunk to 355K parameters so the whole thing — image encoder, prompt encoder, mask decoder, multi‑mask selection, error‑driven re‑prompting, mask feedback, focal + dice + IoU losses, end‑to‑end backprop — runs in a few seconds on a CPU and visibly learns to segment:

step 0 loss 2.652 IoU 0.12 → 0.08 step 49 loss 0.286 IoU 0.86 → 0.87
step 19 loss 1.529 IoU 0.82 → 0.82 step 99 loss 0.096 IoU 0.96 → 0.96 ✅

If you've ever wanted to see how a promptable segmenter is actually trained — not just call predictor.predict() — this is the repo for it.

tiny-SAM training loop

One optimizer step, end‑to‑end. The green dashed rail is the image embedding, computed once and reused by all three prompt iterations; the orange / blue elbows feed each iteration's predicted mask and low‑res logits back into the next prompt; the red lines on the right merge the three losses into a single backward pass. Editable source: assets/training_loop.excalidraw.


Why this exists

The official segment_anything/ package gives you a frozen model and a beautiful inference API — but it never shows how the model got good. The training procedure lives only in §3.1 of the paper (Kirillov et al., Segment Anything, ICCV 2023). tiny‑SAM turns that prose into runnable, annotated code, line‑for‑line mapped to the paper, so you can read it, break it, and watch the numbers move.

It's a great way to understand, concretely:

  • why the image encoder runs once and the tiny decoder runs many times,
  • how a single ambiguous click becomes 3 candidate masks, and how the IoU head learns to pick the right one without ground truth at inference time,
  • how mistakes become the next prompt (sample points from pred XOR gt),
  • and a subtle API gotcha: the decoder's batch dim is prompt hypotheses per image, not images — which is exactly why Sam.forward() loops over the batch.

Quickstart

No checkpoint download, no GPU, no dataset. Just PyTorch:

git clone https://github.com/DreamRunnerMoshi/segment-anything.git
cd segment-anything
python3 -m venv .venv
.venv/bin/pip install torch numpy
.venv/bin/python tiny_sam.py

(tiny_sam.py only needs the vendored segment_anything/modeling package — no torchvision, no extra deps. Set SAM_DEVICE=mps or cuda to use a GPU.)

You'll see one fully‑traced step (every tensor shape printed), then 100 streaming steps on fresh synthetic images — a tiny stand‑in for SA‑1B:

tiny SAM on cpu: 355,528 params (encoder 195,456 | prompt 1,804 | decoder 158,268)
training all of it end-to-end, as in the paper
=== one training step, traced ===
image (4, 3, 128, 128) -> encoder ONCE -> (4, 64, 8, 8)
it1 prompt (4, 1, 2) xy -> sparse (4, 2, 64) (2nd token is the auto-padded 'no-point' token)
it1 decoder multi-mask: low_res (4, 3, 32, 32), logits (4, 3, 128, 128), iou_pred (4, 3)
it1 selected-mask mean IoU: 0.082
it2 prompt 2 accumulated pts -> sparse (4, 3, 64), dense mask feedback (4, 64, 8, 8) -> single mask
it3 prompt 3 accumulated pts -> sparse (4, 4, 64), dense mask feedback (4, 64, 8, 8) -> single mask
=== fresh synthetic batch every step (like streaming from SA-1B) ===
step 0 loss 2.652 IoU it1 0.119 -> it3 0.080 |grad| 1.74
step 8 loss 2.748 IoU it1 0.419 -> it3 0.393 |grad| 1.49
step 19 loss 1.529 IoU it1 0.818 -> it3 0.816 |grad| 3.39
step 49 loss 0.286 IoU it1 0.859 -> it3 0.865 |grad| 1.00
step 69 loss 0.162 IoU it1 0.919 -> it3 0.927 |grad| 1.15
step 99 loss 0.096 IoU it1 0.958 -> it3 0.960 |grad| 0.89

Mean mask IoU on unseen images goes 0.08 → 0.96 — the loop genuinely trains segmentation, from scratch, end‑to‑end.


How the training loop works

tiny_sam.py follows the paper's recipe in five steps per optimizer step:

#What happensWhere
1Encode once.ImageEncoderViT → embedding (B,64,8,8), cached & reused.train_step
2Iteration 1 — ambiguous. One foreground point → PromptEncoder → decoder with multimask=True → 3 masks; a teacher (hard IoU vs GT) picks the best; the IoU head is trained to predict that IoU.sample_foreground_points
3Iterations 2–3 — refine. Sample a point from pred ⊕ gt (label 1 = missed object, 0 = hallucinated), accumulate it, feed the previous logits back as a dense mask prompt, decode a single refined mask.sample_error_points
4Losses. sigmoid focal + dice on masks, MSE on predicted IoU.sigmoid_focal_loss / dice_loss / iou_mse_loss
5Backward, end‑to‑end. Gradients from all 9 mask losses flow through decoder + prompt encoder + encoder; one Adam step.main

The full, annotated walkthrough — with the diagram, every tensor shape, the decoder‑batch gotcha, and a faithful‑vs‑simplified table — is in TRAINING_WALKTHROUGH.md.


tiny‑SAM vs real SAM

Same wiring as segment_anything/build_sam.py, just shrunken so it trains interactively:

tiny‑SAM (this demo)SAM ViT‑H (paper)
Image size128 × 1281024 × 1024
Embedding grid8 × 864 × 64
Prompt / decoder dim64256
ViT embed / depth / heads64 / 2 / 41280 / 32 / 16
Parameters355 K~636 M
Datasynthetic circlesSA‑1B (11 M images, 1.1 B masks)
Train batch / steps4 / 100256 / 665 k
Hardwarelaptop CPUmany GPUs

Everything that matters for understanding is preserved: 3‑iteration error‑driven prompting, multi‑mask + IoU‑head supervision, mask‑logit feedback, and the three losses. What's dropped for size is listed honestly in the walkthrough.


Things to try

Tiny‑SAM is meant to be poked. In tiny_sam.py:

  • N_STEPS = 300 — watch IoU saturate near 1.0; confirms it really learns, not memorizes (every step is a fresh random image).
  • Freeze the encoder — reproduces SAM's late‑training stage and makes steps much faster:
    forpinsam.image_encoder.parameters():
    p.requires_grad_(False)
  • Box prompts — unambiguous, so they skip the multi‑mask stage:
    fromsegment_anything.utils.amgimportbatched_mask_to_boxboxes=batched_mask_to_box(gt)
    sparse, dense=sam.prompt_encoder(points=None, boxes=boxes, masks=None)
  • Drop the IoU loss — training loss still falls, but mask selection at inference (no GT) breaks. This isolates exactly why the IoU head exists.

Repo layout

tiny_sam.py ← the training loop (start here)
TRAINING_WALKTHROUGH.md ← step-by-step explanation + diagram
assets/training_loop.png ← rendered training-loop diagram
assets/training_loop.excalidraw ← editable diagram source
segment_anything/ ← upstream SAM model code (unchanged, used as the backbone)

Using the upstream model (unchanged)

The vendored segment_anything/ package is Meta's original, unmodified — so all of its inference tooling still works if you point it at a checkpoint:

fromsegment_anythingimportSamPredictor, sam_model_registrysam=sam_model_registry["vit_b"](checkpoint="sam_vit_b_01ec64.pth")
predictor=SamPredictor(sam)
predictor.set_image(<your_image>)
masks, scores, logits=predictor.predict(point_coords=..., point_labels=...)

Checkpoints: vit_h · vit_l · vit_b. Automatic "segment everything" (SamAutomaticMaskGenerator), ONNX export, and the browser demo are all still in scripts/, notebooks/, and demo/. For video, see the follow‑up SAM 2.


Built on Segment Anything

tiny‑SAM is an independent, educational reconstruction built on top of Meta AI Research's open‑source Segment Anything — it is not affiliated with or endorsed by Meta. The segment_anything/ model code is reproduced verbatim under its original license; the training‑loop script, walkthrough, and diagrams are original additions for learning purposes.

If you use SAM or SA‑1B in research, please cite the original work:

BibTeX
@article{kirillov2023segany,
title={Segment Anything},
author={Kirillov, Alexander and Mintun, Eric and Ravi, Nikhila and Mao, Hanzi and Rolland, Chloe and Gustafson, Laura and Xiao, Tete and Whitehead, Spencer and Berg, Alexander C. and Lo, Wan-Yen and Doll{\'a}r, Piotr and Girshick, Ross},
journal={arXiv:2304.02643},
year={2023}
}

About

The repository provides code for running inference with the SegmentAnything Model (SAM), links for downloading the trained model checkpoints, and example notebooks that show how to use the model.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages