この記事は Dries Buytaert 氏の公式ブログ「dri.es」の翻訳記事です。Driesブログの記事一覧よりすべての翻訳記事をご覧いただけます。
ウェブ上には、適切なaltテキストが設定されていない画像が何十億枚も存在します。スクリーンリーダーを使っている何百万ものユーザーにとって、これは大きなアクセシビリティの問題です。
私自身のウェブサイトも例外ではありません。そこで数週間前、このサイトにある約9,000枚の画像に不足しているaltテキストを追加する取り組みを始めました。
単純な作業に見えて、実際にはいくつかの段階を踏む必要がありました。さまざまなAIモデルの評価や、ローカル処理かクラウド処理かの選択などです。
ウェブをより良くするには、多くのサイトが画像にaltテキストを追加していく必要があります。そこで、この取り組みの過程をブログに記録することにしました。同じことに挑戦する方の参考になれば、また改善のアイデアをいただければと思っています。今回の第3回目の記事では、大量のaltテキストを自動生成するパイプラインをどのように構築したか、技術的な詳細を掘り下げてご紹介します。
全体的な仕組みの概要
自動化の処理は、画像ごとに次の3ステップで行います。
- 対象画像に
altテキストが設定されているか確認する - 未設定の場合、AIを使って新しい
altテキストを生成する - 生成した
altテキストで画像のデータベースレコードを更新する
以降では、各ステップについてより詳しく説明します。実装の詳細に興味がある方は、GitHubでソースコードの大部分を公開していますのでご覧ください。
画像メタデータの取得
9,000枚の画像を体系的に処理するには、altテキストが不足している画像を特定するための仕組みが必要でした。
私のサイトはDrupalで動いているので、画像のメタデータを操作するためのREST APIエンドポイントを2つ作りました。
GET /album/{album-name}/{image-name}/get– タイトル、altテキスト、キャプションなど、画像のメタデータを取得します。PATCH /album/{album-name}/{image-name}/patch–altテキストの追加・変更など、特定のフィールドを更新します。
同様のAPIは以前にも作ったことがあります。たとえば地下室の温湿度モニター用のものがそうです。あの記事では、こうしたエンドポイントの作り方をより詳しく解説しています。
このAPIは、1つのリソースURLに対してHTTPメソッドで操作を切り替えるRESTfulな設計ではなく、操作ごとに別々のURLパス(/getと/patch)を使う設計にしています。RESTの原則に従いたい気持ちもありますが、このやり方のほうがCDNでのコンテンツネゴシエーションの問題など、キャッシュ関連のトラブルを避けやすいのです。
いずれにせよ、エンドポイントを用意してしまえば、画像のメタデータの取得はシンプルです。
curl -H "Authorization: test-token" \
"https://dri.es/album/isle-of-skye-2024/journey-to-skye/get"リクエストにはすべて認証トークンが必要です。なお、test-tokenは実際のトークンではありません。認証がなければ、誰でも画像を編集できてしまいますから。クラウドソーシングでaltテキストを集めるというのも面白い実験かもしれませんが、今は試す気にはなれません。
このリクエストは、画像のメタデータをJSONオブジェクトで返します。
{
"title": "Journey to Skye",
"alt": "",
"caption": "Each year, Klaas and I pick a new destination for our outdoor adventure. In 2024, we set off for the Isle of Skye in Scotland. This stop was near Glencoe, about halfway between Glasgow and Skye."
}altフィールドが空なので、次のステップはAIで説明文を生成することになります。
AIによるaltテキストの生成と改善

AIによるaltテキスト生成に関する最初の記事では、10種類のローカル大規模言語モデル(LLM)を比較するPythonスクリプトを作成しました。そのスクリプトはAI研究や深層学習で広く使われる機械学習フレームワークPyTorchを使ったもので、実装を通じてたくさんのことを学べた良い経験でした。
元のスクリプトは画像を入力として受け取り、複数のLLMを使ってaltテキストを生成します。
./caption.py journey-to-skye.jpg
{
"image": "journey-to-skye.jpg",
"captions": {
"vit-gpt2": "A man standing on top of a lush green field next to a body of water with a bird perched on top of it.",
"git": "A man stands in a field next to a body of water with mountains in the background and a mountain in the background.",
"blip": "This is an image of a person standing in the middle of a field next to a body of water with a mountain in the background.",
"blip2-opt": "A man standing in the middle of a field with mountains in the background.",
"blip2-flan": "A man is standing in the middle of a field with a river and mountains behind him on a cloudy day.",
"minicpm-v": "A person standing alone amidst nature, with mountains and cloudy skies as backdrop.",
"llava-13b": "A person standing alone in a misty, overgrown field with heather and trees, possibly during autumn or early spring due to the presence of red berries on the trees and the foggy atmosphere.",
"llava-34b": "A person standing alone on a grassy hillside with a body of water and mountains in the background, under a cloudy sky.",
"llama32-vision-11b": "A person standing in a field with mountains and water in the background, surrounded by overgrown grass and trees."
}
}当初の計画は、完全な制御・コスト不要・プライバシー確保のためにすべてをローカルで動かすことでした。しかし、10種類のローカルLLMをテストした結果、考えを変えることになりました。
クラウドベースのモデルのほうが優れているとはわかっていましたが、ローカルモデルでもaltテキスト生成に十分かどうか確かめたかったのです。結果は、まだ十分とは言えませんでした。詳細な比較記事をご覧いただけますが、ローカルモデルの最良のものでもB評価、クラウドモデルはA評価でした。
ローカル処理は自分の理念には合っていましたが、最大の目的であるスクリーンリーダーユーザーのための最善の説明文を作るという点では妥協になってしまいます。そこでローカル限定の方針を捨て、クラウドベースのLLMを使うことにしました。
9,000枚の画像へのaltテキスト自動生成には、ブラウザベースのインターフェースではなく、クラウドモデルへのプログラムからのアクセスが必要でした(もっとも、ブラウザベースのAIもそれはそれで面白いのですが)。
既存のスクリプトにクラウドLLMのサポートを追加する代わりに、Simon Willison氏のllmツール(https://llm.datasette.io/)を使うことにしました。llmはコマンドラインツール兼Pythonライブラリで、ローカル・クラウドを問わずさまざまなモデルに対応しています。インストール、依存関係の管理、APIキーの管理、画像のアップロードなど、自分で手間をかけたくない部分をまとめて面倒見てくれます。
ビジョン言語モデルやマルチモーダルエンコーダーを使ったPyTorchの探求は楽しかったのですが、結果を出すことに集中しなければなりませんでした。毎週の進捗目標を考えると、独自の推論パイプラインを作り込むよりも、きちんと動くaltテキストを生み出すことを優先すべきだったのです。
また、読者のことも考えました。この取り組みを参考に自分のサイトをよりアクセシブルにしようとする方にとっては、私独自の実装を改造しようとするより、llmのような継続的にメンテナンスされているツールをベースにしたスクリプトのほうが使いやすいはずです。
PyTorchの実装を手放すのは少し惜しかったのですが、より成熟した活発なオープンソースプロジェクトの上に構築するほうが、自分にとっても読者にとっても良い選択でした。そこでスクリプトを書き直し、v2ブランチとして公開しています。元のPyTorchバージョンはv1として残してあります。
新しいバージョンは同じシンプルなインターフェースを維持しつつ、ChatGPTやClaudeといったクラウドモデルにも対応しました。
./caption.py journey-to-skye.jpg --model chatgpt-4o-latest claude-3-sonnet --context "Location: Glencoe, Scotland"
{
"image": "journey-to-skye.jpg",
"captions": {
"chatgpt-4o-latest": "A person in a red jacket stands near a small body of water, looking at distant mountains in Glencoe, Scotland.",
"claude-3-sonnet": "A person stands by a small lake surrounded by grassy hills and mountains under a cloudy sky in the Scottish Highlands."
}
}--contextパラメーターを使うと、LLMが画像だけでは判断できない情報を補足できるため、altテキストの品質が上がります。GPS座標、アルバムのタイトル、あるいはその旅のブログ記事などを渡すことができます。
この例では"Location: Glencoe, Scotland"を指定しました。ChatGPT-4oはグレンコーを直接言及し、Claude-3 Sonnetはスコットランド高地に言及しているのがわかります。このような文脈情報を加えることで、説明がより正確で価値のあるものになります。精度を最大限に上げるには、使えるすべての情報を活用しましょう!
画像メタデータの更新
altテキストが生成できたら、最後のステップは各画像への書き込みです。PATCHエンドポイントは変更が必要なフィールドだけを受け付けるので、他のメタデータはそのまま保持されます。
curl -X PATCH \
-H "Authorization: test-token" \
"https://dri.es/album/isle-of-skye-2024/journey-to-skye/patch" \
-d '{
"alt": "A person stands by a small lake surrounded by grassy hills and mountains under a cloudy sky in the Scottish Highlands.",
}'これで完了です。1枚の画像に対する自動化ループがひと通り終わりました。altテキストが必要かどうかを確認し、クラウドベースのLLMで説明文を作り、必要であれば画像を更新する——あとはこれを約9,000回繰り返すだけです。
AI生成のaltテキストを追跡する
9,000枚すべてにスクリプトを実行する前に、各altテキストが人間が書いたものかAIが生成したものかをデータベースで区別するラベルを追加しました。これにより次のことが可能になります。
- 人間が書いた
altテキストを上書きせずに、AI生成分だけを再処理できる - より良いモデルが出たタイミングでAI生成の
altテキストをアップグレードできる
この仕組みのおかげで、たとえばChatGPT 5がリリースされたときにAI生成のaltテキストを更新できます。そして将来的には、当初の理念——パブリックドメインデータで学習した高品質なローカルLLMを使う——に立ち返れるかもしれません。その日が来るまでの間も、今日のウェブをより使いやすくしながら、より良い長期的な解決策へ向けて着実に歩んでいけます。
次のステップ
1枚の画像に対するプロセスの自動化ができたので、あとはこれを9,000枚すべてに実行するだけです。正直、少し緊張しています。完璧主義な自分はAI生成のaltテキストを一枚一枚確認したいのですが、それは現実的ではありません。なので、AIを信頼するしかありません。最終ステップの結果と学びをまとめた記事をもう一本書く予定ですので、お楽しみに。
— Dries Buytaert
この記事は「Automating alt-text generation with AI」(投稿日:2025-02-20)の翻訳記事です。
カテゴリ
タグ