はじめに
製造業の PoC で「生成AIで外観検査はできるのか?」と聞かれることが増えてきました。
AWS からも、Amazon Nova Pro を使って学習なしで外観検査をする構成がブログとサンプルコードで公開されています。良品の画像と検査したい画像を並べて渡し、欠陥の有無と理由を JSON で返させる、というシンプルな方法です。
ただ、このブログの評価は MVTec AD の歯ブラシ 42枚・1品種 だけでした。PoC の判断に使うには少し心もとないかもしれない、と思ったのが今回の動機です。
ということで、本記事では AWS 公式の手法を、公開データセット VisA の 200枚・2品目(+12品目の広域チェック)で試し、精度・再現性・費用を数字で確かめます。
オレオレ評価は許さないマンとしてほんの少し確かめた内容をまとめます。
※本家のブログはzero-shotでの構成の紹介がメインで評価をメインにしていないのでそれはしょうがないのですが…。
概要
この記事でわかることは次のとおりです。
- AWS 公式の手法(良品の参照画像+検査画像)を、別のデータで試したときの精度
- 参照画像の有無・枚数で、精度と費用がどう変わるか
- 「埋め込み+k近傍法」という古典的な方法と比べてどうか
- 品目によって精度がどれだけばらつくか
- 1枚あたり・1,000枚あたりの費用
先に結果を短く書くと、次のとおりです。
- 今回のプロンプトの Nova 2 Lite は、良品の見本を見せても不良品の95%以上を OK と判定しました(F1 0.020〜0.095)
- AWS サンプルの再現(Nova Pro)は不良品の84.5%を見つけた一方で、良品の59%を NG にしました(F1 0.689)
- 埋め込み+k近傍法は誤検知率 0.10・1,000枚あたり 0.06 USD と一番安く、F1 は 0.571 でした
- 検証全体の費用は 1.865 USD でした
検証のコードと、使った画像 ID の一覧は GitHub で公開しています(Appendix)。
※本記事は個人の検証です。精度は公開データでの値で、実際のラインでの精度を保証するものではありません。
AWS 公式の手法をおさらい
まずは元のブログ「Implement Zero-Training Visual Defect Detection in Manufacturing with Amazon Nova Pro」(2025-11-10)の内容を確認します。
- Lambda から Amazon Nova Pro に、良品の参照画像と検査画像、システムプロンプトを渡す
- 出力は JSON で、
qc(OK/NOK)・reason・bounding_boxなどを返させる - 評価は MVTec AD の歯ブラシ42枚(不良30枚・良品12枚)
- プロンプトに「色の違いは欠陥ではない」と書き足すと、正解率 81%→93%、特異度 33%→83%、F1 0.882→0.951 に改善
- 1枚あたりの応答は平均約3.3秒
良品が12枚しかないので、特異度(良品を良品と判定できた割合)は1枚の違いで約8ポイント動きます。ここが今回いちばん確かめたかったところです。
検証の条件
この検証では同じ200枚の画像を A〜E の5つの条件で判定し、結果を比べます。ざっくり分けると次の3つです。
- A〜C:Nova 2 Lite に、良品の見本を0枚・1枚・3枚見せて判定させる
- D:AWS 公式のサンプル(Nova Pro とそのプロンプト)をそのまま再現する
- E:生成AIに判定させず、画像の埋め込みと k近傍法で判定する
それぞれの中身はこのあとの「比べた条件」で詳しく説明します。なお、本記事では「良品の参照画像」を短く「見本」とも呼びます。
データ
VisA(Visual Anomaly、Amazon が公開。CC BY 4.0)を使いました。AWS のオープンデータとして S3 で公開されていて、認証なしで取得できます。
| 項目 | 内容 |
|---|---|
| メインのテスト | pcb1・capsules から良品50枚・不良品50枚ずつ、計200枚(random_state=42) |
| 良品の参照画像 | 各品目の学習用の良品から3枚(テストとは重ならない) |
| 広域チェック | 12品目×良品5枚・不良品5枚、計120枚 |
| 条件 E の学習用 | 各品目 良品100枚(train)・不良品20枚(test のうち、評価に使わない画像) |
pcb1 と capsules を選んだのは、1つの部品を決まった形で撮った基板(pcb1)と、たくさんのカプセルが毎回違う並びで写る(capsules)とで、性質が大きく違うためです。
※VisA の分割(split_csv/1cls.csv)では train に不良品がありません。そのため、条件 E の学習用の不良品は test のうち評価用(200枚・120枚)に入っていない画像から選びました。学習用と評価用が重ならないことはコードで確かめています。
比べた条件
| 条件 | モデル | 見本(良品の参照画像) | プロンプト | 実行回数 | ねらい |
|---|---|---|---|---|---|
| A | Nova 2 Lite | なし | 本記事のプロンプト | 3回 | 見本なしでどこまで判定できるか |
| B | Nova 2 Lite | 良品1枚 | 本記事のプロンプト | 3回 | 見本を見せると変わるか |
| C | Nova 2 Lite | 良品3枚 | 本記事のプロンプト | 3回 | 見本を増やすと変わるか |
| D | Nova Pro | 良品1枚(B と同じ画像) | AWS サンプルのプロンプト(英語。一字も変えずに使用) | 1回 | 元のブログの方式を別のデータで再現する |
| E | 埋め込み+k近傍法 | ―(学習用の画像を使う) | ―(Nova Multimodal Embeddings、k=3、品目ごと) | 1回 | 生成AIでなくてもよいのでは?を確かめる |
※A〜C は、同じ画像で判定がぶれるかを見るために3回ずつ実行しました。広域チェックは、200枚で F1 が一番高かった C の条件で1回だけ実行しました。
それぞれの条件で、モデルに何を渡して、どう判定したかは次のとおりです。
A〜C(Nova 2 Lite+本記事のプロンプト)
- 1回の呼び出しで、見本の画像(B は1枚、C は3枚、A は渡さない)→ 検査対象の画像 → プロンプト、の順に渡します
- プロンプトでは「最後の画像が検査対象で、それより前はすべて良品の見本」と伝え、
{"judgement": "OK" または "NG", "defect": …, "confidence": …}の JSON だけを返させます(全文は後の「プロンプトと出力形式」に載せています) -
judgementが NG なら不良品と判定した、として数えます。temperatureは 0 です - 見本は各品目の学習用の良品から選んだ3枚で、B はそのうち1枚目、C は3枚すべてを使いました
D(AWS サンプルの再現。Nova Pro+サンプルのプロンプト)
- サンプルのシステムプロンプト(見本と比べて違いをすべて挙げ、違いがあれば NOK にする、という指示)と、出力形式の指示をそのまま使います
- 検査対象の画像 → 出力形式の指示 → 次が見本であることを伝える英語の一文 → 見本の画像、の順に渡します(サンプルと同じ順番です)
- 応答の
objectsに、見つけた違いごとにqc(OK/NOK)とreasonが入ります。NOK が1つでもあれば NG と判定した、として数えます - サンプルの出力には確信度がないので、確信度を使う指標(後述の業務指標)は D だけ計算できません
E(埋め込み+k近傍法)
- 画像を Nova Multimodal Embeddings で、1,024個の数値の並び(埋め込み)に変えます。似た画像ほど埋め込みが近くなる、という性質を使います
- 品目ごとに、学習用の良品100枚・不良品20枚の埋め込みを先に作っておきます(索引づくり。1回だけ)
- 検査対象の画像の埋め込みに近い学習用の画像を3枚選び、その中で良品と不良品のどちらが多いかで OK/NG を決めます(k=3、コサイン類似度。scikit-learn の
KNeighborsClassifier) - 生成AIに判定させないので、プロンプトはありません。代わりに、学習用に良品と不良品の画像を集める必要があります
D はできるだけサンプル(aws-samples/sample-generative-visual-inspection の Nova_Pro_Visual_Inspection.ipynb)に合わせましたが、次の点が違います。
- 呼び方:サンプルは InvokeModel、この検証は Converse API(
temperature0.1・topP0.1・topK20・maxTokens2500 は同じ値) - メッセージ:サンプルは user のメッセージを2通に分けて送りますが、同じ順番のまま1通にまとめました(検査画像 → 指示 → 参照の説明 → 参照画像)
- 画像:長辺を1,024px に縮めるのは同じで、サンプルの PNG ではなく JPEG(quality=95)で送りました
- モデル:サンプルは us-east-1 の
amazon.nova-pro-v1:0、この検証は東京からapac.amazon.nova-pro-v1:0 - 判定のまとめ方:
objectsの中に NOK が1つでもあれば NG としました(サンプルのノートブックは先頭の要素のqcを表示します)
※当初は「プロンプトの品目の記述(歯ブラシの説明)だけ差し替える」予定でした。しかし、サンプルのプロンプトに歯ブラシの説明は無く、品目に固有の記述は出力例の「The object is a blue and green sponge...」だけでした。そのため、差し替えはせずにそのまま使っています。
構成と準備
上の図は今回の検証の構成を表しています。① VisA を S3 から認証なしで取得し、② ローカルの Python から東京リージョンの Amazon Bedrock を Converse API で呼んで判定し、③ 埋め込みだけはバージニア北部リージョンで作って、k近傍法はローカルで行います。
- Nova 2 Lite は東京から JP Geo 推論プロファイル(
jp.amazon.nova-2-lite-v1:0)で呼びます。東京と大阪のどちらかで処理されます - Nova Pro は東京(ap-northeast-1)から APAC Geo 推論プロファイル(
apac.amazon.nova-pro-v1:0)で呼びました。東京から呼んだときは、東京・ソウル・大阪・ムンバイ・シンガポール・シドニーのどれかで処理されます(Nova Pro のモデルカード、2026-11-05 確認) - 埋め込みモデル(
amazon.nova-2-multimodal-embeddings-v1:0)は、2026-11-05 の時点で民間向けには us-east-1(バージニア北部)だけで提供されているので、us-east-1 で呼びました(モデルカード)。画像は米国のリージョンに送られるので、公開データだからできる構成です - IAM は、今回は管理者権限(AdministratorAccess)の IAM ユーザーで呼びました。PoC では
bedrock:InvokeModelを、使う推論プロファイルと、そのプロファイルが処理を振り分けるリージョンの基盤モデルだけに許可するポリシーにするのがよいと思います(Geographic cross-Region inference の IAM ポリシーの例、2026-11-10 確認)
検証基盤は条件を設定ファイルで切り替える形にしました。たとえば条件 C は次のとおりです。
name: n1_C
split: data/splits/visa_test_200.csv
refs: data/splits/visa_refs.csv
n_refs: 3
model_id: jp.amazon.nova-2-lite-v1:0
region: ap-northeast-1
prompt: prompts/v1_judge.txt
inference: {temperature: 0, maxTokens: 300}
repeats: 3
budget_usd: 1.0
プロンプトと出力形式
判定は JSON だけを返させます。参照画像があるときは「最後の画像が検査対象で、それより前はすべて良品の見本」と伝えます。
あなたは製品の外観検査員です。
最後の画像が検査対象です。それより前の画像があれば、すべて良品の見本です。
検査対象に傷・欠け・汚れ・異物・変形などの欠陥があるかを判定し、次の JSON だけを返してください。
{"judgement": "OK" または "NG", "defect": "欠陥の種類(なければ空文字)", "confidence": 0から1の数値}
def build_content(req: ModelRequest) -> list[dict[str, Any]]:
if req.layout == "refs_first": # 条件 A〜C:見本 → 検査対象 → 指示
return [_image_block(i) for i in req.images] + [{"text": req.text}]
...
kwargs = {
"modelId": req.model_id,
"messages": [{"role": "user", "content": build_content(req)}],
"inferenceConfig": {"temperature": req.temperature, "maxTokens": req.max_tokens},
}
resp = self.client.converse(**kwargs)
コードの全文は GitHub(bedrock-vlm-inspection-lab) にあります。
JSON として読めなかった応答は、正規表現で救済せずに「解析失敗」として数えました。本番で使うなら、ここも立派な失敗だからです。
ただし、ここで1つつまずきました。試運転の90呼び出し(A・B・C 各30)は、すべて本文が ```json の囲みで包まれていました。囲みを外さない設定のままだと全件が解析失敗になってしまうので、本文全体を包む囲みだけは外すことにしました(プロンプトは変えていません)。囲みを外せば、試運転の90呼び出しはすべて読めました。
結果
条件ごとの精度(200枚)
「NG」を陽性として計算しています。A〜C は3回の平均です。解析失敗は指標から除き、解析失敗率を別に書いています。
表1:条件ごとの精度(pcb1・capsules の200枚)
| 条件 | 適合率 | 再現率 | F1 | 誤検知率 | 見逃し率 | 解析失敗率 | 一言 |
|---|---|---|---|---|---|---|---|
| A(Nova 2 Lite、見本なし) | 1.000 | 0.010 | 0.020 | 0.000 | 0.990 | 0.003 | ほぼすべて OK として見逃される |
| B(Nova 2 Lite、見本1枚) | 1.000 | 0.023 | 0.046 | 0.000 | 0.977 | 0.000 | 少しだけ見つける |
| C(Nova 2 Lite、見本3枚) | 1.000 | 0.050 | 0.095 | 0.000 | 0.950 | 0.000 | A〜C では一番よいが全然ダメ |
| D(Nova Pro、AWS サンプル) | 0.582 | 0.845 | 0.689 | 0.590 | 0.155 | 0.015 | よく見つけるが、良品も NG にする |
| E(埋め込み+k近傍法) | 0.815 | 0.440 | 0.571 | 0.100 | 0.560 | 0.000 | 誤検知が少ない |
※誤検知率は良品のうち NG と判定した割合、見逃し率は不良品のうち OK と判定した割合です。
F1 が一番高かったのは D(0.689)で、E(0.571)が続きました。Nova 2 Lite(A〜C)は誤検知こそ0でしたが、再現率は 0.010〜0.050 で、ほとんどの不良品を OK と判定しています。参照画像を増やすと再現率は 0.010 → 0.023 → 0.050 と上がったので効果はあったといえそうですが、PoC で使える水準からはかなり遠いと考えられます。
品目ごとの違い
表2:品目ごとの再現率・F1・誤検知率(200枚のうち各品目100枚)
| 条件 | 品目 | 再現率 | F1 | 誤検知率 |
|---|---|---|---|---|
| B | capsules | 0.027 | 0.052 | 0.000 |
| B | pcb1 | 0.020 | 0.039 | 0.000 |
| C | capsules | 0.040 | 0.077 | 0.000 |
| C | pcb1 | 0.060 | 0.113 | 0.000 |
| D | capsules | 0.755 | 0.587 | 0.800 |
| D | pcb1 | 0.938 | 0.804 | 0.380 |
| E | capsules | 0.300 | 0.435 | 0.080 |
| E | pcb1 | 0.580 | 0.682 | 0.120 |
※B・C は3回の平均です。E は比べるために載せています。
D の誤検知率は、capsules では 0.80、pcb1 では 0.38 と、品目で倍以上違いました。再現率も、C・D・E では capsules のほうが低く(E は 0.30 と 0.58)、capsules のほうが難しかったようです(B だけは capsules 0.027、pcb1 0.020 と逆でした)。
表3:広域チェック(条件 C、12品目×良品5枚・不良品5枚)
| 品目 | 見つけた不良品(5枚中) | NG にした良品(5枚中) | 正しく判定した枚数(10枚中) | 再現率 |
|---|---|---|---|---|
| fryum | 4 | 0 | 9 | 0.8 |
| chewinggum | 3 | 0 | 8 | 0.6 |
| pcb4 | 2 | 0 | 7 | 0.4 |
| pipe_fryum | 2 | 0 | 7 | 0.4 |
| candle | 1 | 0 | 6 | 0.2 |
| macaroni1 | 1 | 0 | 6 | 0.2 |
| pcb2 | 1 | 0 | 6 | 0.2 |
| capsules | 0 | 0 | 5 | 0.0 |
| cashew | 0 | 0 | 5 | 0.0 |
| macaroni2 | 0 | 0 | 5 | 0.0 |
| pcb1 | 0 | 0 | 5 | 0.0 |
| pcb3 | 0 | 0 | 5 | 0.0 |
| 全体 | 0.233(F1 0.378、誤検知率 0) |
※枚数は wide_120.csv の再現率・誤検知率に5枚を掛けたものです。解析失敗は0件でした。
12品目に広げても、Nova 2 Lite(条件 C)は良品を1枚も NG にせず、再現率は品目によって 0.0〜0.8 と大きくばらつきました。今回メインで使った pcb1 と capsules は、どちらも再現率 0 のグループに入っています。
品目による結果の差異は大きく対象の複雑さや色味などが関係していると思われますが原因の特定はしていません。1つの品目だけで全体の評価はやめましょうという例にはなっていますね。
再現性(3回実行してぶれるか)
表4:同じ画像を3回判定したときの一致率(200枚)
| 条件 | 3回とも同じ判定だった画像 | 一致率 | F1 の幅(3回の最小〜最大) |
|---|---|---|---|
| A(見本なし) | 199 / 200 | 0.995 | 0.020〜0.020 |
| B(見本1枚) | 199 / 200 | 0.995 | 0.039〜0.058 |
| C(見本3枚) | 200 / 200 | 1.000 | 0.095〜0.095 |
※temperature は 0 です。D と E は1回だけ実行したので、一致率はありません。
temperature=0 では、判定はほとんどぶれませんでした。ただし A では、同じ画像の2回分が JSON のあとに日本語の説明を続けて 300トークンで打ち切られ、解析失敗になっています(解析失敗率 0.003)。
また、確信度(confidence)を使って「見逃し率を2%・5%以下に抑えたときに、良品をどれだけ通せるか」も計算しました。A・B・C・E のどれも、良品の通過率は 0 でした。D はサンプルの出力形式に確信度が無いので計算できませんでした。
速さと費用
表5:速さと費用(200枚)
| 条件 | p50(秒) | p95(秒) | 入力トークン(平均) | 出力トークン(平均) | 1枚あたり(USD) | 1,000枚あたり(USD) |
|---|---|---|---|---|---|---|
| A(Nova 2 Lite、見本なし) | 0.60 | 0.75 | 376 | 28 | 0.00024 | 0.24 |
| B(Nova 2 Lite、見本1枚) | 0.83 | 1.19 | 608 | 27 | 0.00033 | 0.33 |
| C(Nova 2 Lite、見本3枚) | 1.44 | 2.05 | 1,072 | 27 | 0.00051 | 0.51 |
| D(Nova Pro、AWS サンプル) | 2.22 | 12.56 | 3,921 | 373 | 0.00520 | 5.20 |
| E(埋め込み+k近傍法) | 0.62 | 0.70 | ― | ― | 0.00006 | 0.06 |
※費用はトークン数×単価で計算しました(単価は東京から jp. で呼んだ Nova 2 Lite が入力 0.396・出力 3.311 USD/100万トークン、apac. の Nova Pro が入力 0.96・出力 3.84 USD/100万トークン)。
※E は画像1枚 0.00006 USD(標準の画像、オンデマンド)で、テスト画像の埋め込みだけの費用です。学習用240枚の埋め込み(索引づくり)0.0144 USD は1回だけかかり、上の表には含めていません。E のレイテンシは埋め込み1回の時間です。
Nova 2 Lite は画像1枚を解像度によらず230トークンとして数えるので、参照画像を足しても費用はあまり増えません。実際、入力トークンは見本1枚につき 232 増え(A 376 → B 608 → C 1,072)、1,000枚あたりの費用は見本1枚につき約 0.09 USD 増えました(0.24 → 0.33 → 0.51 USD)。
一方、D は入力トークンが1呼び出しあたり約3,900(pcb1 3,729、capsules 4,113)、出力も約370トークンあり、1,000枚あたり 5.20 USD と C の約10倍でした。p95 が 12.56 秒と、ときどき大きく遅くなるのも気になるところです。
間違えた画像の傾向
出典:VisA(Zou et al., "SPot-the-Difference Self-Supervised Pre-training for Anomaly Detection and Segmentation", ECCV 2022。Amazon、Registry of Open Data on AWS)、CC BY 4.0。縮小して並べ、VisA の正解マスクの輪郭を赤い線で描き足しています。
出典:VisA(Zou et al., ECCV 2022。Amazon、Registry of Open Data on AWS)、CC BY 4.0。縮小して並べています。
上の図は誤判定の例を表しています。傾向は次のとおりです。
- Nova 2 Lite(A〜C)の見逃し:不良品100枚のうち95枚は、9回(3条件×3回)すべてで OK と判定されました。見逃した判定はどれも確信度 0.95〜1.0 で、欠陥の種類は空でした。「自信を持って OK と言う」ので、確信度で拾い直すのも難しそうです
- Nova Pro(D)の誤検知:良品を NG にしたのは59枚(capsules 40枚、pcb1 19枚)でした。capsules では40枚中18枚の理由に「missing」が入り、9枚は色の違い(color・shade・darker)を理由にしていました。カプセルの数や並びは画像ごとに違うので、見本との「違い」を欠陥と見なしたのかもしれません
- D の理由:例1の不良品は D が NG にしましたが、理由は「rotated 180 degrees」「different orientation」でした。判定は合っていても、理由は欠陥(赤い線の部分)と合っていないことがあるようです
- 色の違い:AWS サンプルのシステムプロンプトは、「color difference between reference and QC objects」も指摘するよう求めています。元のブログで「色の違いは欠陥ではない」と書き足して特異度が上がったのと、同じ話かもしれません
- D の見逃し:15枚(capsules 12枚、pcb1 3枚)。ほかに不良品3枚で JSON が壊れていて、解析失敗になりました
- E の誤判定:見逃し56枚(capsules 35枚、pcb1 21枚)、誤検知10枚(capsules 4枚、pcb1 6枚)
pcb1 では19枚中9枚が向きに関する理由(orientation・reversed・upside down など)でした。例2の下の段のように、今回の見本(pcb1/normal/0042)は、ピンが基板の上に出る向きで写っています。そこで、pcb1 のテスト画像100枚が見本と同じ向きか、上下が逆(180°回転)かを数えてみました(下の表)。
表6:pcb1 のテスト画像の向きと、条件 D・E の判定
| 正解 | 見本との向き | 枚数 | D で NG にした割合 | E で NG にした割合 |
|---|---|---|---|---|
| 良品 | 同じ | 35 | 5 / 35(0.14) | 0 / 35(0.00) |
| 良品 | 逆 | 15 | 14 / 15(0.93) | 6 / 15(0.40) |
| 不良品 | 同じ | 1 | 0 / 1 | 0 / 1 |
| 不良品 | 逆 | 49 | 45 / 47(0.96。ほかに解析失敗2枚) | 29 / 49(0.59) |
※向きは見本の基板を切り出して、そのままの向きと180°回した向きのどちらがよく合うか(正規化相互相関)で判定し、全枚数を目で見て確かめました。1枚(pcb1/anomaly/049、ピンがまるごと無い不良品)だけ、目で見た向きに直しています。
pcb1 では、不良品は50枚中49枚が見本と逆の向き、良品は50枚中15枚だけが逆の向きでした。D は見本と逆の向きの良品を15枚中14枚 NG にした一方で、同じ向きの良品は35枚中5枚だけでした。つまり D の pcb1 の結果(再現率 0.938、誤検知率 0.38)は、欠陥そのものよりも「見本と向きが違うこと」に反応した分を含んでいる可能性があります。例1の不良品で、D の理由が「rotated 180 degrees」だったのもこれと合います。
E も、誤検知した pcb1 の良品6枚はすべて逆の向きでした。E の学習用の pcb1 も、不良品は20枚中18枚が逆の向き、良品は100枚中15枚だけが逆の向きだったので、k近傍法も向きの違いを手がかりにしている可能性があります。
※VisA の pcb1 では、良品にも両方の向きがあるので、向きの違いは欠陥ではありません。
42枚の評価では見えなかったこと
zero-shot / few-shotだと得意な品目や苦手な品目というのはありそうなので品目ごとにちゃんと評価する必要があります。
Nova 2 Liteでは厳しい結果となり、Nova Proではそれなりの結果となったのでやはり大きいモデルは強いです。
Nova Pro(見本1枚、AWS サンプルのプロンプト)は過検出寄りに倒れました。
ある程度の見逃しは許容される環境で適合率を上げたい場合は生成AIを使わなくてもよいかもしれないですね。あとシンプルに安い。
PoC でこの方式を選ぶ条件
結果から、PoC で次のように使い分けるのがよさそうです。
| 場面 | 選ぶ方式 | 理由 |
|---|---|---|
| 不良品をなるべく見逃したくなく、NG の画像を人が見直す手間を許せる | 参照画像つき VLM(Nova Pro、AWS サンプルの形) | 今回の条件で再現率が一番高い。ただし良品の半分以上も NG になる |
| 良品を NG にしたくない、費用と速さを優先したい、学習用に良品と不良品の画像を集められる | 埋め込み+k近傍法 | 誤検知が少なく、1,000枚あたりの費用が一番安い。ただし不良品の半分以上を見逃す |
| 見逃しを数%以下に抑える必要がある | どちらも向かない(専用モデルを検討) | 確信度で調べられた方式は、見逃しを2%・5%以下にすると良品を1枚も通せない。Nova Pro も見逃しが15%ある |
根拠の数字(200枚、表1・表5・business_metric.csv)
- Nova Pro(D):再現率 0.845、誤検知率 0.590(capsules 0.80、pcb1 0.38)、F1 0.689、1,000枚あたり 5.20 USD、p50 2.22秒・p95 12.56秒
- 埋め込み+k近傍法(E):誤検知率 0.100、再現率 0.440、F1 0.571、1,000枚あたり 0.06 USD(索引づくり 0.0144 USD は別)、p50 0.62秒
- 見逃し2%・5%での良品の通過率:A・B・C・E とも 0。D は確信度が無く計算できず、見逃し率は 0.155
- 今回のプロンプトの Nova 2 Lite(A〜C)は、再現率 0.010〜0.050 で、どの場面でも第一候補にはしにくい結果でした
- ただし pcb1 では、D・E とも見本や学習用の画像との「向きの違い」に反応している可能性があります(表6)。D・E の pcb1 の数字はそのぶん割り引いて見る必要がありそうです
※公開データでの結果なので、実際の現場では撮影条件や品種の違いで精度が変わるはずです。まずは自分のデータで同じ評価を回すのがおすすめです。
検証しなかったこと
- 実際のラインの画像(照明・カメラ・品種が違う)
- 推論(reasoning)を有効にした場合の詳しい比較(アドカレで扱います)
- 不良品の見本を見せる方法(アドカレで扱います)
- 欠陥の位置の精度(アドカレで扱います)
- プロンプトの細かな調整(同じプロンプトで比べることを優先しました)
- 見本の選び方を変えること(見本は random_state=42 で選んだ1組だけです。pcb1 の向きのように、見本しだいで結果が変わる可能性があります)
- pcb1 の向きをそろえたうえでの評価(画像を回転してそろえる、検査対象と同じ向きの見本を選ぶ、など)
- Nova Pro(D)と埋め込み(E)の繰り返し実行(1回だけなので、ぶれは分かりません)
- Nova Pro に本記事のプロンプトを使うこと、Nova 2 Lite に AWS サンプルのプロンプトを使うこと(モデルとプロンプトの効果は分けられていません)
- AWS サンプルの呼び方そのまま(InvokeModel、2通のメッセージ、PNG)での実行
- 埋め込みの
embeddingPurposeを分類向けのCLASSIFICATIONにすること(今回はGENERIC_INDEX) - Global 推論プロファイル、バッチ推論、Flex での費用
費用と後片付け
今回の費用は記録したトークン数(埋め込みは画像の枚数)×単価で 1.865 USD でした(試運転 0.0852 USD、本番 1.7798 USD)。
| 実験 | モデル ID | 呼び出し | 費用(USD) |
|---|---|---|---|
| A(本番) | jp.amazon.nova-2-lite-v1:0 |
600 | 0.1449 |
| B(本番) | jp.amazon.nova-2-lite-v1:0 |
600 | 0.1989 |
| C(本番) | jp.amazon.nova-2-lite-v1:0 |
600 | 0.3085 |
| D(本番) | apac.amazon.nova-pro-v1:0 |
200 | 1.0393 |
| 広域チェック(本番) | jp.amazon.nova-2-lite-v1:0 |
120 | 0.0618 |
| E(本番、学習用240枚+テスト200枚) | amazon.nova-2-multimodal-embeddings-v1:0 |
440 | 0.0264 |
| 試運転(全条件) | ― | 124 | 0.0852 |
| 合計 | 1.8650 |
Cost Explorer(2026-11-10 に確認、見込みの値)でも、この検証の使用量(Nova 2 Lite・Nova Pro のトークン数、埋め込みの画像454枚)と単価は記録と一致し、費用は 1.865 USD でした。
費用を見積もるときに気をつけたい点が2つありました。
- 東京から
jp.の推論プロファイルで呼ぶと、Nova 2 Lite の単価は入力0.396・出力3.311 USD(100万トークンあたり)です。us-east-1 から Global で呼ぶとき(入力0.30・出力2.50 USD)より高くなります - Nova Multimodal Embeddings は、画像の入力トークン数が応答ヘッダーでも CloudWatch でも 0 でした。費用はトークン数ではなく、画像1枚あたりの単価(0.00006 USD)×枚数で計算します
この検証ではローカルから Bedrock を呼んだだけで、S3 のバケットや IAM ロールなどのリソースは作っていません(モデル呼び出しのログ設定も無効のままです)。ローカルの VisA は12月の記事でも使うので残し、アドカレが終わったら消します。(いらない宣言)
まとめ
- AWS サンプルの方式(Nova Pro)は不良品の84.5%を見つけましたが、良品の59%を NG にしました。誤検知率は品目で 0.80(capsules)と 0.38(pcb1)と大きく違い、42枚・1品種の評価だけでは分からない部分といえそうです
- 今回のプロンプトの Nova 2 Lite は、見本を3枚見せても不良品の95%を自信を持って OK と判定しました。12品目に広げても再現率は 0.233 で、品目によって 0.0〜0.8 とばらつきました
- 費用は検証全体で 1.865 USD。1,000枚あたりは Nova 2 Lite 0.24〜0.51 USD、Nova Pro 5.20 USD、埋め込み+k近傍法 0.06 USD でした
次回(11/19)は学術ベンチマークの MMAD で「最新の VLM は外観検査で専門家に追いついたのか?」を測ります。12月にはアドベントカレンダーで、精度・費用・信頼性をもう少し細かく掘っていく予定です。
参考になれば嬉しいです。
Appendix
-
ys-dirard/bedrock-vlm-inspection-lab 検証コードと、使った画像 ID の一覧(
data/splits/) - Implement Zero-Training Visual Defect Detection in Manufacturing with Amazon Nova Pro(AWS for Industries)
-
aws-samples/sample-generative-visual-inspection 条件 D のプロンプトの出典(commit
3c76f0c6157ee88143740918ef0878f4f7e67cbf、MIT-0) - VisA(Registry of Open Data on AWS) CC BY 4.0
- amazon-science/spot-diff VisA の分割の定義
- Amazon Bedrock の料金 単価は 2026-11-05 に Price List API で確認し、2026-11-10 に Cost Explorer の請求の単価とも一致することを確認
- Cross-Region inference(Amazon Bedrock ユーザーガイド) Geo のプロファイルは呼び出し元のリージョンの単価になる(2026-11-05 確認)


