SAM 2 vs SAM 3 : Benchmark Pratique sur un Cas Industriel Reel
SAM 2 vs SAM 3 : le Benchmark que Personne ne Fait
La sortie de SAM 3 (Segment Anything with Concepts) par Meta Superintelligence Labs a provoque un emballement legitime. Un modele qui segmente par simple prompt textuel, avec 848M de parametres, un detecteur DETR-based et un tracker herite de SAM 2 — sur le papier, c’est l’outil ultime. Mais sur le terrain, quand on passe du benchmark academique au cas industriel concret, la realite est plus nuancee.
Nous avons mis les deux modeles face a face sur un probleme reel : l’analyse d’ovalisation de bobines metalliques. Le meme pipeline, le meme code, la meme tache — seul le moteur de segmentation change. Voici ce qu’on a appris.
Le Cas d’Usage : Mesurer l’Ovalisation d’une Bobine
Dans l’industrie metallurgique, une bobine stockee trop longtemps ou mal calee se deforme. Le trou central, normalement circulaire, devient elliptique. Mesurer ce taux d’ovalisation (rapport axe majeur / axe mineur) est critique pour le controle qualite.
Le pipeline est le suivant :
- Estimation geometrique du trou central (seuillage Otsu + morphologie + contours)
- Generation de points prompts sur des cercles concentriques autour du trou
- Segmentation SAM pour isoler la matiere de la bobine
- Extraction de l’ellipse interieure par echantillonnage radial
- Calcul du taux d’ovalisation
C’est un cas ideal pour comparer SAM 2 et SAM 3 : la tache est identique, seule l’etape 3 change.
Architecture : Deux Philosophies de Segmentation
SAM 2 : Geometric Prompts, Sans Limite de Points
SAM 2 utilise SAM2ImagePredictor avec un modele sam2.1_hiera_small. On lui fournit des points positifs et negatifs comme prompts geometriques :
from sam2.build_sam import build_sam2
from sam2.sam2_image_predictor import SAM2ImagePredictor
SAM2_MODEL_NAME = "sam2.1_hiera_small"
SAM2_MASK_THRESHOLD = -0.95
checkpoint = f"./checkpoints/{SAM2_MODEL_NAME}.pt"
sam2_model = build_sam2(
"configs/sam2.1/sam2.1_hiera_s.yaml", checkpoint
)
predictor = SAM2ImagePredictor(sam2_model, mask_threshold=-0.95) La configuration des prompts est riche : 4 cercles concentriques de points positifs avec des rayons differents, plus un cercle de points negatifs au centre :
# SAM2 -- 4 cercles positifs, genereux en points
POSITIVE_RADIUS_COEFFS = [1.25, 1.15, 1.10, 1.05]
POSITIVE_RADIUS_OFFSETS = [0, 0, -50, -100]
POSITIVE_NUM_POINTS = [36, 32, 28, 24] # Total: 120 points positifs
# Cercle negatif central
NEGATIVE_RADIUS_COEFF = 0.6
NEGATIVE_NUM_POINTS = 12 Au total, SAM 2 recoit 132 points (120 positifs + 12 negatifs). C’est beaucoup, mais le modele les digere sans probleme.
SAM 3 : La Contrainte des 24 Points
SAM 3 utilise build_sam3_image_model et Sam3Processor. L’API est differente :
import torch
from sam3.model_builder import build_sam3_image_model
from sam3.model.sam3_image_processor import Sam3Processor
SAM3_DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
model = build_sam3_image_model()
processor = Sam3Processor(model) Voici le premier probleme concret : le predicteur interactif de SAM 3 a une limite d’environ 24 points. Impossible de reproduire la configuration riche de SAM 2. On est force de reduire drastiquement :
# SAM3 -- contraint a ~24 points max
POSITIVE_RADIUS_COEFFS = [1.15, 1.05] # 2 cercles au lieu de 4
POSITIVE_RADIUS_OFFSETS = [0, -50]
POSITIVE_NUM_POINTS = [12, 12] # Total: 24 points positifs
NEGATIVE_NUM_POINTS = 0 # Zero points negatifs -- budget epuise On passe de 132 a 24 points. Et on perd completement les points negatifs, ce qui change la nature meme du prompting.
L’Estimation Geometrique : Le Code Partage
Les deux pipelines partagent la meme fonction estimate_hole_geometry. C’est du traitement d’image classique, sans IA :
def estimate_hole_geometry(gray: np.ndarray) -> Tuple[Tuple[int, int], float]:
h, w = gray.shape
cx0, cy0 = w // 2, h // 2
# Seuillage Otsu + dilatation
_, binary = cv2.threshold(
gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU
)
binary = cv2.bitwise_not(binary)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (21, 21))
binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=3)
contours, _ = cv2.findContours(
binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
# Choisir le contour le plus centre
best_dist = 1e9
for c in contours:
area = cv2.contourArea(c)
if area < 0.005 * h * w:
continue
M = cv2.moments(c)
if M["m00"] == 0:
continue
cx = M["m10"] / M["m00"]
cy = M["m01"] / M["m00"]
dist = np.hypot(cx - cx0, cy - cy0)
if dist < best_dist:
best_dist = dist
best = c
best_center = (cx, cy)
# Rayon median du contour detecte
dists = np.sqrt(
(best[:, 0, 0] - best_center[0]) ** 2
+ (best[:, 0, 1] - best_center[1]) ** 2
)
r0 = float(np.clip(
np.median(dists), 0.25 * min(h,w), 0.45 * min(h,w)
))
return (int(best_center[0]), int(best_center[1])), r0 La generation de points est triviale — des coordonnees equireparties sur un cercle :
def generate_circle_points(center, radius, num_points=12):
cx, cy = center
angles = np.linspace(0, 2 * np.pi, num_points, endpoint=False)
return np.array([
[int(cx + radius * np.cos(a)), int(cy + radius * np.sin(a))]
for a in angles
]) La Preparation des Prompts SAM 3 : Un Budget Serre
Le code SAM 3 doit combiner les points positifs et negatifs dans les limites du budget :
def _prepare_sam3_prompts(cx, cy, r0):
positive_points_list = []
for coeff, offset, num_pts in zip(
POSITIVE_RADIUS_COEFFS,
POSITIVE_RADIUS_OFFSETS,
POSITIVE_NUM_POINTS
):
radius = coeff * r0 + offset
points = generate_circle_points((cx, cy), radius, num_points=num_pts)
positive_points_list.append(points)
positive_points = np.vstack(positive_points_list)
positive_labels = np.ones(len(positive_points), dtype=np.int32)
negative_radius = NEGATIVE_RADIUS_COEFF * r0
if NEGATIVE_NUM_POINTS > 0:
negative_points = generate_circle_points(
(cx, cy), negative_radius, num_points=NEGATIVE_NUM_POINTS
)
negative_labels = np.zeros(len(negative_points), dtype=np.int32)
all_points = np.vstack([positive_points, negative_points])
all_labels = np.hstack([positive_labels, negative_labels])
else:
all_points = positive_points
all_labels = positive_labels
return all_points, all_labels, negative_radius Avec NEGATIVE_NUM_POINTS = 0, tout le budget va aux points positifs. Le nettoyage du masque se fait en post-traitement :
def _clean_mask(mask, cx, cy, negative_radius):
h, w = mask.shape
y_coords, x_coords = np.ogrid[:h, :w]
distances = np.sqrt((x_coords - cx) ** 2 + (y_coords - cy) ** 2)
mask_cleaned = mask.copy()
mask_cleaned[distances <= negative_radius] = False
return mask_cleaned Ce post-traitement geometrique compense l’absence de prompts negatifs, mais c’est un pis-aller. Le masque SAM 2, guide par 12 points negatifs explicites, est plus propre a la source.
Benchmark de Detection de Feu : SAM 3 en Text-Prompted
Pour elargir la comparaison au-dela de l’ovalisation, nous avons aussi benchmarke SAM 3 en mode text-prompted sur la detection de feu, face a YOLO, Grounding DINO et Qwen2.5-VL. Le code utilise une architecture modulaire de detecteurs :
from src.detectors.sam3_detector import SAM3FireDetector
detector = SAM3FireDetector(
device="cuda",
confidence_threshold=0.5
)
benchmark.register_detector('SAM3', detector) Et pour YOLO, plusieurs variantes sont testees :
yolo_configs = [
('yolov8', 'YOLOv8'),
('yolo11_nano', 'YOLO11-nano'),
('yolo11_small', 'YOLO11-small'),
('yolo11_medium', 'YOLO11-medium'),
('yolo11_large', 'YOLO11-large'),
] Avec des prompts "fire", "flame", "smoke", SAM 3 produit des masques de segmentation instance-level — pas juste des bounding boxes.
Ou SAM 3 Excelle en Text-Prompted
- Segmentation fine : la ou YOLO donne une boite, SAM 3 donne un masque pixel-perfect. Pour un feu a forme irreguliere, c’est crucial.
- Vocabulaire ouvert : pas besoin de retrainer. SAM 3 atteint un cgF1 de 54.1 sur SA-Co/Gold en segmentation d’instance, contre 24.6 pour OWLv2 et 21.3 pour DINO-X.
- Detection + segmentation unifiee : un seul modele pour les deux taches, avec 848M parametres.
Ou SAM 3 Echoue Face a YOLO
- Vitesse : YOLO11-small fait ~10-50ms par image. SAM 3 est 10 a 50x plus lent. Pour du temps reel sur camera, c’est eliminatoire.
- Limite de points interactifs : ~24 points maximum en mode geometrique.
- Concepts ambigus : SAM 3 atteint 54.1 de cgF1, loin des 72.8 humains. Le “presence token” aide a discriminer les prompts proches (“a player in white” vs “a player in red”), mais ne resout pas tout.
Les Benchmarks Officiels SAM 3
Les resultats publies par Meta sur les benchmarks standards :
| Modele | LVIS cgF1 | LVIS AP | SA-Co/Gold cgF1 | COCO AP |
|---|---|---|---|---|
| OWLv2 | 29.3 | 43.4 | 24.6 | 46.1 |
| DINO-X | - | 38.5 | 21.3 | 56.0 |
| Gemini 2.5 | 13.4 | - | 13.0 | - |
| SAM 3 | 37.2 | 48.5 | 54.1 | 56.4 |
| Humain | - | - | 72.8 | - |
SAM 3 domine le text-prompted, mais reste a 75% de la performance humaine sur les concepts ouverts. Pour le video tracking (SA-V test), SAM 3 est aussi en tete avec les meilleurs scores cgF1 et pHOTA.
Les Differences d’Architecture en Detail
SAM 2 : Hiera + Decoder Simple
- Vision encoder : Hiera (hierarchical vision transformer)
- Prompts : points, boites, masques (geometriques uniquement)
- Decoder : transformer-based, produit des masques binaires
- Video : memory attention pour la propagation temporelle
- Taille :
sam2.1_hiera_small— modele compact, tourne sur GPU 8 Go
SAM 3 : DETR Detector + SAM 2 Tracker
SAM 3 est deux modeles en un :
- Detecteur : DETR-based, conditionne sur texte, geometrie ET exemplars images
- Tracker : herite directement de l’architecture encoder-decoder de SAM 2
- Presence token : nouveau mecanisme pour discriminer les prompts textuels proches
- Data engine : 4 millions de concepts annotes automatiquement, 270K concepts uniques dans le benchmark SA-Co
- Taille totale : 848M parametres
- Prerequis : Python 3.12+, PyTorch 2.7+, CUDA 12.6+, GPU 24 Go+ VRAM
Le design decoupled detecteur/tracker minimise l’interference entre taches. C’est un choix d’architecture intelligent qui permet a SAM 3 d’exceller en text-prompted sans degrader le tracking video.
Recommandations Pratiques
Quand Utiliser SAM 2
- Controle qualite industriel avec geometrie connue (cercles, rectangles, formes regulieres)
- Prompts avec beaucoup de points (>24)
- Points negatifs critiques pour exclure des zones specifiques
- Latence faible requise : SAM 2 est plus leger
- GPU modeste :
sam2.1_hiera_smalltourne sur 8 Go de VRAM
Quand Utiliser SAM 3
- Detection par description textuelle : “find all fire”, “segment the dog”
- Vocabulaire ouvert sans retraining
- Segmentation exhaustive de toutes les instances d’un concept
- Video tracking avec prompts textuels
- Budget GPU : minimum 24 Go de VRAM, CUDA 12.6+
La Configuration Hybride
Pour notre pipeline d’ovalisation, la meilleure approche serait :
- SAM 3 en text-prompted pour une pre-detection grossiere (“metal coil”)
- SAM 2 en geometric-prompted pour le raffinement fin avec 132 points
Plus de code, mais le meilleur des deux mondes.
Reproduction du Benchmark : Notre Protocole
Pour comparer equitablement les deux modeles, nous avons suivi un protocole strict :
- Memes images en entree : 12 photos de bobines metalliques prises dans des conditions industrielles reelles (eclairage variable, reflets metalliques, arriere-plans encombres)
- Meme estimation geometrique : la fonction
estimate_hole_geometryest identique — seul le moteur de segmentation change - Meme post-traitement : extraction d’ellipse par echantillonnage radial, memes seuils d’outliers (
ELLIPSE_OUTLIER_PERCENTILE = 10) - Meme machine : GPU NVIDIA A100 40 Go, CUDA 12.4, Python 3.12
Le script SAM 2 produit des images suffixees _final.jpg, le script SAM 3 produit _final_sam3.jpg. Les deux incluent une visualisation complete : masque en overlay vert, points de prompt positifs (vert) et negatifs (rouge), ellipse ajustee avec axes majeur (magenta) et mineur (cyan), et le taux d’ovalisation affiche en surimpression.
Les resultats montrent que SAM 2 produit des masques plus reguliers et mieux delimites sur cette tache specifique. SAM 3, avec seulement 24 points et sans points negatifs, genere parfois des masques qui debordent dans le trou central ou qui omettent des zones de la bobine. Le nettoyage post-hoc (_clean_mask) compense partiellement, mais introduit une decoupe circulaire artificielle qui ne suit pas exactement le bord reel du trou.
La v2 du script SAM 3 (ellipse_ovalization_analyzer_sam3_v2.py) utilise les checkpoints HuggingFace au lieu de checkpoints locaux (load_from_HF=True), ce qui simplifie le deploiement mais ne change pas les performances de segmentation.
Le Vrai Cout de SAM 3
L’installation de SAM 3 est plus lourde que SAM 2 :
conda create -n sam3 python=3.12
pip install torch==2.7.0 torchvision torchaudio
--index-url https://download.pytorch.org/whl/cu126
git clone https://github.com/facebookresearch/sam3.git
cd sam3 && pip install -e . Les checkpoints necessitent une authentification HuggingFace (hf auth login). Pour un deploiement industriel, le cout GPU est 3x celui de SAM 2.
Conclusion : Pas de Modele Universel
SAM 3 n’est pas “SAM 2 en mieux”. C’est un modele different, avec une philosophie differente. Le text-prompted est revolutionnaire pour les cas ou on ne peut pas predefinir la geometrie. Mais pour les cas industriels ou la geometrie est connue et le prompting precis est essentiel, SAM 2 reste superieur.
Le benchmark SA-Co/Gold avec 270K concepts uniques montre la direction : SAM 3 vise l’universalite conceptuelle. SAM 2 vise la precision geometrique. Choisissez en fonction de votre probleme, pas en fonction du numero de version.
Le vrai message : la segmentation n’est plus un probleme unique. C’est un spectre de sous-problemes, et le meilleur outil depend du point ou vous vous situez sur ce spectre.
Un projet similaire ? Contactez Loick Briot : contact@brio-novia.eu