2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【基盤モデルはLLMだけじゃない】"プロンプトで何でも切り取る" 画像版 ChatGPT こと SAM を徹底解説

2
Posted at

1. はじめに(TL;DR)

ChatGPT に「〇〇について教えて」とプロンプトを投げると、それらしい文章が返ってきます。これは GPT が大量のテキストで事前学習された 基盤モデル(foundation model) であり、追加学習なしに様々なタスクに応答できるからです。

では、画像セグメンテーション(画像中のオブジェクトをピクセル単位で切り出すタスク)にも同じことができないでしょうか?
「この点を指して」「このボックスの中身を切り取って」とプロンプトを与えると、追加学習なしに尤もらしいマスクを返してくれるモデルがあれば便利なはずです。

これを実現したのが、Meta AI が 2023 年に発表した SAM(Segment Anything Model) です。SAM はまさに「画像セグメンテーション版の基盤モデル」であり、論文タイトルどおり "Segment Anything"(何でも切り取る)を可能にしました。

3行で分かる SAM

  • タスク: プロンプト(点・ボックス・マスクなど)を与えると、対応するセグメンテーションマスクを返す
  • モデル: 画像エンコーダ + プロンプトエンコーダ + マスクデコーダ の3部構成
  • データ: 1,100 万枚の画像と 11 億枚のマスク を持つ巨大データセット SA-1B で学習

この記事で扱うこと

セグメンテーションの基礎から SAM のアーキテクチャ、Python での動かし方、後継モデル SAM 2 まで、ML 初学者でも追えるように噛み砕いて解説します。

2. そもそもセグメンテーションとは?/ 従来手法の課題

セグメンテーションとは

画像系のタスクは大きく以下の3つに分けられます。

タスク 出力
画像分類(Classification) 画像 1 枚に対するラベル 「これは猫の画像」
物体検出(Detection) バウンディングボックス + ラベル 「ここに猫がいる(矩形)」
セグメンテーション(Segmentation) ピクセル単位のマスク 「このピクセル群が猫」

セグメンテーションは「画像のどのピクセルがどのオブジェクトに属するか」をピクセル単位で塗り分けるタスクです。物体検出が矩形で大まかに囲むのに対し、セグメンテーションは輪郭をなぞるように切り出します。

さらに細かく分けると、

  • Semantic Segmentation: 「猫」「犬」のようにクラス単位で塗り分ける(同種の個体は区別しない)
  • Instance Segmentation: 「猫A」「猫B」のように個体単位で塗り分ける
  • Panoptic Segmentation: 上記2つを統合したもの

があります。

従来手法の課題

従来のセグメンテーションモデル(U-Net、Mask R-CNN、DeepLab など)は強力ですが、「タスクごとに学習し直さないと使えない」 という大きな制約がありました。

  1. クラスが固定: 学習時に定義したクラス(例: COCO の 80 クラス)しか切り出せない。新しい物体を切り出したければ、追加のラベル付きデータを集めて再学習が必要。
  2. ドメインに弱い: 自然画像で学習したモデルは、医療画像・衛星画像・顕微鏡画像など別ドメインではうまく動かない。
  3. アノテーションコストが高い: ピクセル単位のラベル付けは、分類や検出に比べて圧倒的に手間がかかる。

つまり、「新しい用途ごとに、データを集めて学習を回す」必要があったわけです。

求められていたもの

NLP の世界では、GPT のような基盤モデルが「事前学習 → プロンプトで色々なタスクに対応」というパラダイムを定着させました。
画像セグメンテーションでも、追加学習なしに任意のオブジェクトを切り出せる「基盤モデル」 があれば、上記の課題を一気に解決できます。

これを実現したのが、次章で紹介する SAM の Promptable Segmentation Task です。

3. SAM の核心: Promptable Segmentation Task

SAM の最重要コンセプトが Promptable Segmentation Task(プロンプタブル・セグメンテーション・タスク) です。直訳すると「プロンプトで指示できるセグメンテーション」。これは LLM のパラダイムをそのまま画像セグメンテーションに持ち込んだものです。

LLM との対応関係

観点 LLM(GPT, ChatGPT) SAM
入力 テキストプロンプト(質問、指示) 画像 + プロンプト(点・ボックス・マスク)
出力 テキスト(尤もらしい応答) セグメンテーションマスク(尤もらしい領域)
学習 大量のテキストで事前学習 大量の画像 + マスクで事前学習(SA-1B)
使い方 追加学習なしでプロンプトのみ(Zero-shot) 追加学習なしでプロンプトのみ(Zero-shot)
強み プロンプト次第で多様なタスクに対応 プロンプト次第で多様なオブジェクトを切り出せる

LLM が「文章生成というひとつの能力を獲得することで、要約・翻訳・コード生成など多様なタスクに応えられる」のと同じ構造で、SAM は「プロンプトに応じたマスクを返すというひとつの能力を獲得することで、多様なセグメンテーション要求に応えられる」というわけです。

プロンプトの種類

SAM が受け付けるプロンプトは大きく分けて4種類です。

  • 点(Point): 「ここにある物体を切り取って」と1点(または複数点)で指定。前景点(含めたい)と背景点(除外したい)を区別できる
  • ボックス(Box): 「この矩形の中の主要な物体を切り取って」とバウンディングボックスで指定
  • マスク(Mask): 「このおおまかな領域をベースに、もっと精緻に切り取って」と粗いマスクで指定
  • テキスト(Text): 「"猫" を切り取って」と自然言語で指定(論文中で言及されているが、公式実装では未公開)

これらは単独でも組み合わせでも使えます。たとえば「ボックスで大まかに範囲を絞り、点で細部を補正する」といった使い方が可能です。

あいまいさ(Ambiguity)への対応

LLM が同じ質問に対して複数のもっともらしい応答を返せるように、SAM もひとつのプロンプトに対して複数のマスクを返す設計になっています。

たとえば「シャツを着た人」の胸の位置に点を打つと、答えは

  • シャツを切り取りたい
  • 服を着た人全体を切り取りたい
  • 人の上半身を切り取りたい

など複数あり得ます。これは1点のプロンプトだけでは決定できない本質的なあいまいさです。

SAM はこの問題に対し、ひとつのプロンプトから3つのマスク(whole / part / subpart に対応)を同時に出力することで対応します。それぞれに信頼度スコアが付くので、ユーザーや下流タスクが好きなものを選べます。これは論文中でも強調されている、SAM の重要な設計判断です。

4. SAM のアーキテクチャ

SAM は3つのコンポーネントから構成されます。

[ 画像 ] ──► Image Encoder ────┐
                                ├──► Mask Decoder ──► [ マスク ]
[ プロンプト ] ──► Prompt Encoder ┘

ここで重要なのは、「重い処理を画像側に集約し、プロンプト側は軽量にする」 という設計です。これにより、一度画像を読み込めば、後はプロンプトを変えるたびに高速にマスクが返ってきます(インタラクティブ用途を想定)。

4.1 Image Encoder

入力画像を特徴ベクトル(image embedding)に変換するコンポーネントです。

  • アーキテクチャ: ViT-H/16(Vision Transformer の最大サイズ、約 6.3 億パラメータ)
  • 事前学習: MAE(Masked Autoencoder) で自己教師あり学習。画像の一部をマスクして復元させるタスクで、ラベル不要に大量の画像から特徴を学べる
  • 入力サイズ: 1024×1024 にリサイズ
  • 出力: 64×64×256 の特徴マップ(image embedding)
  • 計算コスト: GPU で 1 秒未満程度(A100 で数百 ms)。ただし画像 1 枚あたり 1 回だけ実行すれば良い

この「1 度計算した embedding を使い回す」設計が、後段のインタラクティブな高速応答を支えています。

4.2 Prompt Encoder

プロンプトをベクトル(prompt embedding)に変換するコンポーネントです。プロンプトは性質に応じて2種類に分けて扱われます。

  • Sparse prompts(点・ボックス・テキスト)
    • 点: 座標を位置エンコーディング(positional encoding)でベクトル化し、「前景/背景」を表す学習済みの埋め込みを加える
    • ボックス: 左上と右下の2点として表現
    • テキスト: CLIP のテキストエンコーダで埋め込み(実験的)
  • Dense prompts(マスク)
    • 入力マスクを畳み込みでダウンサンプリングし、image embedding と同じ解像度に揃えて加算

軽量なため計算コストはほぼ無視できます。

4.3 Mask Decoder

image embedding と prompt embedding を受け取り、マスクを出力する軽量な Transformer です。

  • 構造としては「cross-attention でプロンプトと画像特徴を相互参照 → アップサンプリング → マスク予測」
  • 出力は前述のとおり3つのマスク(whole / part / subpart に対応)と、それぞれの信頼度スコア(IoU 予測)
  • 計算コストは非常に軽く、Prompt Encoder と合わせてブラウザ CPU でも約 50 ms で動く

速度設計のポイント

  • 重い画像エンコード: 数百 ms 〜 1 秒(GPU)/画像 1 枚あたり 1 回
  • 軽いプロンプト処理 + マスクデコード: ~50 ms(ブラウザ CPU)/プロンプトを変えるたびに実行

これにより、「画像を最初にロードして特徴を抽出 → ユーザーがクリックしたところを即座に切り取る」という Web デモのようなインタラクティブ体験が成立します。

5. 巨大データセット SA-1B とデータエンジン

基盤モデルが「何でも切り取れる」ようになるには、それに見合うだけの巨大で多様なデータが必要です。SAM の学習に使われた SA-1B は、ひと言でいえば史上最大級のセグメンテーションデータセットです。

SA-1B のスケール感

項目 数値
画像数 1,100 万枚(11M)
マスク数 11 億個(1.1B)
1 画像あたり平均マスク数 約 100 個
既存最大級(Open Images など)との比較 マスク数で 約 400 倍

ピクセル単位のマスクを 11 億個も手作業で付けるのは、人海戦術では現実的に不可能です。SAM チームはこの問題を 「モデル自身にアノテーションを手伝わせる」 という発想で解決しました。それが データエンジン(Data Engine) です。

データエンジン: 3段階のブートストラップ

[ Stage 1 ]              [ Stage 2 ]                [ Stage 3 ]
Assisted-manual    →     Semi-automatic       →     Fully automatic
(人が主役)                (人とモデルの協働)           (モデルが主役)

Stage 1: Assisted-manual(人が主役)

  • 人間のアノテーターが、初期版の SAM を補助ツールとして使いながらマスクを付ける
  • ここで作られたデータで SAM を再学習し、より賢くする
  • 約 430 万マスク(画像約 12 万枚)

Stage 2: Semi-automatic(人とモデルの協働)

  • SAM が「自信のあるマスク」を自動生成
  • 人間は モデルが見落とした物体 のみを追加でアノテーション
  • 人間がカバーすべき範囲が減り、効率が大幅アップ
  • 約 590 万マスク(画像約 18 万枚、累計約 1,020 万マスク)

Stage 3: Fully automatic(モデルが主役)

  • 画像に 32×32 のグリッド状に点プロンプトを打つ ことで、SAM 自身が全マスクを生成
  • 信頼度の低いマスクや重複は自動でフィルタリング
  • 人間は介在しない
  • 約 11 億マスク(1,100 万枚全体に適用、最終的な SA-1B の大部分)

このように 「モデルが賢くなる → より自動化が進む → さらにデータが増える」 という正のループでスケールを実現しました。

プライバシーへの配慮

SA-1B には人物画像も含まれるため、Meta は公開前に 顔・車のナンバープレートをぼかし処理 しています。データセットは研究目的でライセンスのもと公開されており、誰でもダウンロードして利用可能です。

6. 実際に動かしてみる(Python)

公式実装 facebookresearch/segment-anything を使って、3つの代表的な使い方を見ていきます。

6.1 インストール

pip install git+https://github.com/facebookresearch/segment-anything.git
pip install opencv-python matplotlib

学習済みチェックポイントは公式 README からダウンロードできます(3サイズあり、最大の ViT-H は約 2.5GB)。

モデル チェックポイント パラメータ数
ViT-B sam_vit_b_01ec64.pth 約 9,100 万
ViT-L sam_vit_l_0b3195.pth 約 3.1 億
ViT-H sam_vit_h_4b8939.pth 約 6.3 億

共通: モデルと画像のロード

import cv2
import numpy as np
from segment_anything import sam_model_registry, SamPredictor

# モデルのロード
sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h_4b8939.pth")
sam.to(device="cuda")  # GPU 推奨
predictor = SamPredictor(sam)

# 画像のロード(BGR → RGB)
image = cv2.imread("input.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 画像の特徴抽出(重い処理。同じ画像なら1回でOK)
predictor.set_image(image)

ポイントは predictor.set_image(image)Image Encoder が走るのはこの1回だけということ。以降、プロンプトを変えながら predictor.predict(...) を何度呼んでも、軽量な Prompt Encoder + Mask Decoder しか動かないので高速です。

6.2 点プロンプト

「ここを切り取って」と1点で指定する最も基本的な使い方です。

# 切り取りたい物体の上に1点(座標は画像のピクセル位置)
input_point = np.array([[500, 375]])
input_label = np.array([1])  # 1 = 前景, 0 = 背景

masks, scores, logits = predictor.predict(
    point_coords=input_point,
    point_labels=input_label,
    multimask_output=True,  # 3つのマスクを返す(whole / part / subpart)
)

# masks.shape == (3, H, W), scores.shape == (3,)
best_mask = masks[np.argmax(scores)]

multimask_output=True にすると、第3章で説明した 「あいまいさへの対応」 として3つのマスクが返ります。scores(IoU 予測)が最大のものを選ぶのが基本戦略です。

前景点と背景点を併用すれば、「ここは含めて、ここは除く」と微調整できます。

input_point = np.array([[500, 375], [600, 400]])
input_label = np.array([1, 0])  # 1 点目は含める、2 点目は除外

6.3 ボックスプロンプト

物体検出と組み合わせる場合などに便利な、矩形での指定です。

input_box = np.array([425, 600, 700, 875])  # [x1, y1, x2, y2]

masks, scores, _ = predictor.predict(
    box=input_box,
    multimask_output=False,  # ボックス指定はあいまい性が低いので 1 つで十分
)

YOLO などの物体検出器を前段に置き、検出されたボックスを SAM に渡すことで、「物体検出 + インスタンスセグメンテーション」のパイプラインを Zero-shot で構築できます。

6.4 自動マスク生成

プロンプトを与えず、画像中の 全ての物体 を切り出したい場合は SamAutomaticMaskGenerator を使います。内部的には、画像にグリッド状に点プロンプトを打ち、得られたマスクを重複除去・低品質フィルタリングしています(データエンジンの Stage 3 と同じ仕組み)。

from segment_anything import SamAutomaticMaskGenerator

mask_generator = SamAutomaticMaskGenerator(sam)
masks = mask_generator.generate(image)

# masks は dict のリスト
# 各 dict: {'segmentation': bool配列, 'area': int, 'bbox': [x,y,w,h],
#          'predicted_iou': float, 'stability_score': float, ...}

print(f"検出されたマスク数: {len(masks)}")

返ってくる辞書には、マスクそのものに加え、面積・バウンディングボックス・信頼度などのメタ情報が含まれており、後段処理がしやすい設計になっています。

7. 何がすごいのか — Zero-shot な応用例

SAM の真価は、追加学習なしで多様なタスクに転用できる Zero-shot 性 にあります。論文中でも複数の応用例が示されています。

  • エッジ検出: 自動マスク生成の結果から輪郭を取り出すだけで、エッジ検出専用モデルに迫る性能
  • 物体検出 + インスタンスセグメンテーション: 検出器の出力ボックスを SAM に渡すパイプライン
  • テキスト指示でのセグメンテーション: CLIP 等のテキスト・画像エンコーダと組み合わせて「猫を切り取る」を実現(Grounded-SAM などのプロジェクトが有名)
  • 画像編集 / インペインティング: SAM で対象を切り出し、Stable Diffusion などで差し替え
  • 医療画像・衛星画像・顕微鏡画像: 自然画像で学習されたモデルにもかかわらず、Zero-shot でそれなりに動く(厳密にはドメイン特化のファインチューニングをした MedSAM などが派生)
  • 動画のフレームごとのセグメンテーション: 簡易な動画解析(厳密には次に紹介する SAM 2 が本命)

新しいタスクが来たら、まず SAM を試してみる」が Zero-shot セグメンテーションのデファクトになりつつあります。

8. 限界と後継モデル SAM 2 / SAM 3

SAM の限界

  • クラスラベルを返さない: SAM は「ここを切り取った」と教えてくれるだけで「これは猫」とは言ってくれない。意味理解には別モデル(CLIP など)との組み合わせが必要
  • 細かい構造を取りこぼすことがある: 髪の毛・葉の輪郭など、極めて細かい構造は苦手
  • 計算コスト: ViT-H は GPU 前提。エッジデバイスでは ViT-B でも重い(軽量版の MobileSAM, FastSAM が派生)
  • テキストプロンプトは未公開: 論文には言及があるが、公式の重みは公開されていない
  • 動画への対応がない: フレーム間の整合性は保証されない

後継モデル: SAM 2

2024 年、Meta は後継の SAM 2(Segment Anything Model 2) を発表しました。主な進化点は以下です。

  • 動画対応: 画像だけでなく動画でもプロンプタブルセグメンテーションが可能に。1 フレームでオブジェクトを指定すれば、後続フレームでも追跡してくれる
  • メモリ機構: 過去フレームの情報を保持する memory attention を導入し、時間方向の整合性を確保
  • 画像でも高速化: SAM より約 6 倍速い(同等または高い精度)
  • 新データセット SA-V: 約 5 万本の動画と 60 万超のマスクレット(動画用マスク系列)で学習

さらにその次: SAM 3

2025 年 11 月、Meta はさらに SAM 3 を公開しました。中核となる新タスクが Promptable Concept Segmentation(PCS) で、SAM / SAM 2 の「1 プロンプト → 1 マスク」から 「概念を指定 → 画像/動画内のその概念に該当する全インスタンスを検出・セグメント・追跡」 へと拡張されました。

  • テキストプロンプト対応: 「yellow school bus」のような短い名詞句で指定可能(SAM では論文に言及があったのみで未公開だった機能を正式実装)
  • 画像 exemplar プロンプト: 参照画像を渡して「これと同じ概念」を指定
  • Open-vocabulary 検出: 学習時に定義したクラスに縛られず、自由な概念で全インスタンスを切り出せる
  • 画像・動画ともに対応: リアルタイム動画追跡も可能
  • 新データセット SA-Co(Segment Anything with Concepts): 評価ベンチマークだけで 21 万超のユニークフレーズ × 12 万超の画像/動画。既存比で概念数 50 倍超
  • 精度: 画像・動画 PCS で既存システム比 約 2 倍

SAM 2 が「指定した 1 オブジェクトを動画全体で追跡する」用途に強いのに対し、SAM 3 は「概念を指定して全インスタンスを一括取得する」用途に強い、という棲み分けです。これまで「物体検出器 + SAM」のパイプラインで構築していた処理が、SAM 3 単体で完結できるようになったのが特に大きな進化点です。

なお SAM 2 は Apache 2.0 でしたが、SAM 3 は独自の "SAM License" になっています。商用利用を検討する場合はリポジトリの LICENSE を必ず確認してください。

「SAM を使うなら、まず SAM 2 / SAM 3 を検討する」のが現在(2026 年時点)の標準的な選択肢です。用途別には、動画で特定オブジェクトを追跡したいなら SAM 2、テキストや exemplar で概念を一括検出したいなら SAM 3 が出発点になります。

9. まとめ

本記事では、画像セグメンテーションの基盤モデル SAM を、LLM との対応関係から始めて以下の流れで解説しました。

  • Promptable Segmentation Task: 「プロンプトに応じたマスクを返す」というひとつの能力で、Zero-shot に多様なセグメンテーション要求に応える設計
  • 3 コンポーネント構成: 重い Image Encoder を 1 回だけ動かし、軽い Prompt Encoder + Mask Decoder を繰り返すインタラクティブ設計
  • データエンジン: モデル自身にアノテーションを手伝わせる正のループで、11 億マスクという前例のないスケールを実現
  • 実践: segment-anything を使えば、点・ボックス・自動生成と多様な使い方が数行のコードで可能
  • 後継 SAM 2 / SAM 3: SAM 2 で動画対応 + 高速化、SAM 3 でテキストや exemplar による概念ベースの一括検出。新規プロジェクトではこれらを優先検討

「LLM だけが基盤モデルではない」というのが本記事の出発点でした。SAM は画像セグメンテーションという特定タスクに対して、プロンプタブル基盤モデルというパラダイムが極めて有効であることを示した先駆的な研究です。同じ思想は、物体検出、深度推定、3D 再構成など他の Vision タスクにも広がりつつあります。

これから画像系のタスクに取り組む方は、ぜひ一度 SAM ファミリ(SAM / SAM 2 / SAM 3)に触れてみてください。「まずプロンプトで試す」という発想が、開発の生産性を大きく変えてくれるはずです。

参考文献

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?