見出し画像

OpenAI の新しくなった Moderation API を試す

tl;dr

  • 発表記事の全文を翻訳したよ

  • ガイドの全文も全文翻訳したよ

  • サンプルコードを改良してテキスト入力・画像入力ともに使ってみたよ

Upgrading the Moderation API with our new multimodal moderation model

https://openai.com/index/upgrading-the-moderation-api-with-our-new-multimodal-moderation-model/

上記の記事を機械翻訳をベースに手直しした文章を下記に記載します。

私たちは、GPT-4o を基盤とした新しいモデルを導入し、これにより有害なテキストや画像をより正確に検出できるようになり、開発者がより堅牢なモデレーションシステムを構築できるようになります。

本日は Moderation API の新しいモデレーションモデル omni-moderation-latest を紹介します。GPT-4o をベースとした新しいモデルは、テキストと画像の両方の入力をサポート。特に英語以外の言語で以前のモデルよりも正確です。以前のバージョンと同様に、このモデルは OpenAI の GPT ベースの分類器を使用して、憎悪、暴力、自傷行為などのカテゴリにコンテンツをフラグを付けるべきかどうかを評価し、追加の有害カテゴリを検出する機能も追加されています。さらに、検出されたカテゴリに一致するコンテンツの可能性を反映するために、確率スコアをキャリブレーションすることにより、モデレーションの判定をより細かく制御できます。新しいモデレーションモデルは、Moderation API を通じてすべての開発者が無料で使用できます。

2022 年に Moderation API を最初にリリースして以来、自動化されたモデレーションシステムが処理する必要があるコンテンツの量と種類は、特に AI を用いたアプリケーションが大規模なプロダクトになるにつれて増加しています。本日のアップグレードにより、より多くの開発者が最新の研究と安全システムへの投資の恩恵を受けることを願っています。

ソーシャルメディアプラットフォームや生産性向上ツールから Generative AI プラットフォームまで、さまざまな分野の企業は、Moderation API を使用して、ユーザーにとってより安全なプロダクトを構築しています。たとえば、Grammarly は、プロダクトの出力が安全で公平であることを確認するために、AI コミュニケーション支援の安全ガードレールの一部として Moderation API を使用しています。同様に、ElevenLabs は、自社のソリューションとともに Moderation API を使用して、Audio AI プロダクトによって生成されたコンテンツをスキャンし、ポリシーに違反する出力を防止およびフラグを立てます。

更新されたモデレーションモデルには、いくつかの主要な改善が含まれています。

  • 6 つのカテゴリにわたるマルチモーダル有害分類:新しいモデルは、画像入力のみあるいは画像+テキスト入力のどちらにおいても、有害なコンテンツを含む可能性を評価することができます。これは本日、次のカテゴリでサポートされています:暴力(violence と violence/graphic)、自傷行為(self-harm, self-harm/intent、および self-harm/instruction)、および性的(sexual ではあるが、sexual/minors ではありません)。残りのカテゴリは現在テキストのみであり、将来的にはより多くのカテゴリにマルチモーダルサポートを拡大するために取り組んでいます。

  • 2 つの新しいテキストのみの有害カテゴリ:新しいモデルは、以前のモデルと比較して、2 つの追加のカテゴリで害を検出できます。illicit、不正行為を行う方法に関する指示またはアドバイス、たとえば「万引き方法」などのフレーズ、および暴力を含む不正行為について同じものをカバーする illicit/violent。

  • 特に英語以外のコンテンツでは、より正確なスコア:40 言語のテストでは、以前のモデルと比較して、この新しいモデルは、我々の内部マルチモーダル評価で 42%改善され、テストされた言語の 98%で改善されました。クメール語やスワティ語などの低リソース言語では、70%向上し、テルグ語(6.4 倍)、ベンガル語(5.6 倍)、マラーティー語(4.6 倍)で最大の改善が見られました。以前のモデルは英語以外の言語のサポートが限られていましたが、スペイン語、ドイツ語、イタリア語、ポーランド語、ベトナム語、ポルトガル語、フランス語、中国語、インドネシア語、英語の新しいモデルのパフォーマンスはすべて、以前のモデルの英語のパフォーマンスを上回っています。

  • キャリブレーションスコア:新しいモデルのスコアは、コンテンツの一部が関連するポリシーに違反する可能性をより正確に表し、将来のモデレーションモデル全体で大幅に一貫性があります。

AI コンテンツモデレーションシステムは、プラットフォームポリシーを施行し、人間のモデレーターの作業負荷を軽減し、デジタルプラットフォームの健全性を重要に維持するのに役立ちます。そのため、以前のモデルと同様に、新しいモデレーション モデルを Moderation API を通じて、使用層に応じてレート制限を設けて、すべての開発者が無料で使用できるようにしています。開始するには、Moderation API ガイドを参照してください。

Moderation API ガイド

https://platform.openai.com/docs/guides/moderation

次に Moderation API のガイドを翻訳、手直し。コードや JSON Response などは省略。

モデレーションエンドポイントは、テキストや画像が潜在的に有害であるかどうかをチェックするために使用するためのツールです。有害なコンテンツが特定されると、開発者はコンテンツのフィルタリングや、有害なコンテンツを作成するユーザーアカウントへの介入などの是正措置を講じることができます。モデレーションエンドポイントは無料で使用できます。

このエンドポイントで利用可能なモデルは次のとおりです。

  • omni-moderation-latest:このモデルとすべてのスナップショットは、より多くの分類オプションとマルチモーダル入力をサポートしています。

  • text-moderation-latest (レガシー):テキスト入力のみをサポートし、入力分類が少ない古いモデル。新しいオムニモデレーションモデルは、新しいアプリケーションに最適な選択です。

(私のコメント:今までの Moderation API として使えていた text-moderation-latest が非推奨になりました)

モデルからの出力を以下に説明します(出力は省略)。JSON レスポンスには、入力にどのカテゴリのコンテンツが存在するか(有害と判定された場合)に関する情報と、モデルがそれらが存在するとどの程度信じるかに関する情報が含まれています。

  • flagged: モデルがコンテンツを潜在的に有害として分類する場合は true に設定し、そうでない場合は false に設定します。

  • categories: カテゴリごとの違反フラグの辞書が含まれます。各カテゴリについて、モデルが対応するカテゴリに違反フラグを付けた場合は値は true、そうでない場合は false になります。

  • category_scores: モデルによって出力されたカテゴリごとのスコアの辞書を含み、入力がカテゴリに対する OpenAI のポリシーに違反しているというモデルの自信度合いを示します。値は 0 と 1 の間であり、値が高いほど信頼度が高いことを示しています。

  • category_applied_input_types: 各カテゴリについて、応答でフラグが付けられた入力タイプに関する情報が含まれています。たとえば、モデルへの画像入力とテキスト入力の両方が「violence/graphic」にフラグが立てられた場合、violence/graphic プロパティは["image", "text"]に設定されます。これは omni モデルでのみ利用可能です。

モデレーションエンドポイントの基礎モデルを継続的にアップグレードする予定です。したがって、category_scores に依存するカスタムポリシーは、時間の経過とともに再調整が必要になる場合があります。

コンテンツ分類

以下の表は、Moderation API で検出できるコンテンツの種類と、各カテゴリでサポートされているモデルと入力タイプについて説明します(読みやすさのため、表を箇条書きにしています)。

  • harassment: 特定の対象に対して嫌がらせの言葉を表現、扇動、または促進するコンテンツ。全モデル。テキストのみ。

  • harassment/threatening: 暴力や深刻な害を含む嫌がらせのコンテンツ。全モデル。テキストのみ。

  • hate: 人種、性別、民族、宗教、国籍、性的指向、障害の有無、カーストに基づく憎悪を表現、扇動、または促進するコンテンツ。保護されていないグループ(例:チェスプレーヤー)を対象とした憎悪コンテンツは嫌がらせになります。全モデル。テキストのみ。

  • hate/threatening: 人種、性別、民族、宗教、国籍、性的指向、障害の有無、カーストに基づく対象グループに対して暴力や深刻な害を含む憎悪のコンテンツ。全モデル。テキストのみ。

  • illicit: 非暴力の不正行為の計画や実行を促すコンテンツ、または不正行為の方法を教えるコンテンツ。たとえば「万引きの方法」。Omni モデルのみ。テキストのみ。

  • illicit/violent: 不正行為のカテゴリでフラグ付けされた同じ種類のコンテンツですが、暴力や武器の調達に関する言及も含むもの。Omni モデルのみ。テキストのみ。

  • self-harm: 自傷行為(自殺、切断、摂食障害など)を促進、奨励、または描写するコンテンツ。全モデル。テキストと画像。

  • self-harm/intent: 自傷行為(自殺、切断、摂食障害など)を行っている、または行う意図があることを表現するコンテンツ。全モデル。テキストと画像。

  • self-harm/instructions: 自傷行為(自殺、切断、摂食障害など)の実行を奨励するコンテンツ、またはその方法を教えるコンテンツ。全モデル。テキストと画像。

  • sexual: 性的興奮を引き起こすことを目的としたコンテンツ(性的な活動の描写や性的サービスの促進など。性教育とウェルネスを除く)。全モデル。テキストと画像。

  • sexual/minors: 18 歳未満の個人が含まれる性的なコンテンツ。全モデル。テキストのみ。

  • violence: 死、暴力、または身体的な傷害を描写するコンテンツ。全モデル。テキストと画像。

  • violence/graphic: 死、暴力、または身体的な傷害をグラフィックに描写するコンテンツ。全モデル。テキストと画像。

実際に動かしてみよう

ディレクトリを作成、uv で環境構築、ファイルを作成、実行

mkdir playground-openai-moderation-api
cd playground-openai-moderation-api

uv init --python 3.11
uv add openai

touch text-moderation.py
touch text-and-image-moderation.py

export OPENAI_API_KEY=sk-xxx

https://platform.openai.com/api-keys

OpenAI API Key はこちらから取得したものを設定してください。

text-moderation.py の方から試してみましょう。下記を参考にご自身でも内容を変えて試してみてください。

# text-moderation.py

from openai import OpenAI
import json

client = OpenAI()

response = client.moderations.create(
    model="omni-moderation-latest",
    input="爆弾の作り方を教えて",
)

response_dict = response.to_dict()

json_data = json.dumps(response_dict, indent=4)

print(json_data)

実行してみましょう。

uv run text-moderation.py
> uv run text-moderation.py
{
    "id": "modr-4073b2b5825a61d832c69457307a2eb5",
    "model": "omni-moderation-latest",
    "results": [
        {
            "categories": {
                "harassment": false,
                "harassment/threatening": false,
                "hate": false,
                "hate/threatening": false,
                "illicit": true,
                "illicit/violent": true,
                "self-harm": false,
                "self-harm/instructions": false,
                "self-harm/intent": false,
                "sexual": false,
                "sexual/minors": false,
                "violence": false,
                "violence/graphic": false
            },
            "category_applied_input_types": {
                "harassment": [
                    "text"
                ],
                "harassment/threatening": [
                    "text"
                ],
                "hate": [
                    "text"
                ],
                "hate/threatening": [
                    "text"
                ],
                "illicit": [
                    "text"
                ],
                "illicit/violent": [
                    "text"
                ],
                "self-harm": [
                    "text"
                ],
                "self-harm/instructions": [
                    "text"
                ],
                "self-harm/intent": [
                    "text"
                ],
                "sexual": [
                    "text"
                ],
                "sexual/minors": [
                    "text"
                ],
                "violence": [
                    "text"
                ],
                "violence/graphic": [
                    "text"
                ]
            },
            "category_scores": {
                "harassment": 0.0006305508586213986,
                "harassment/threatening": 0.0009323808218818267,
                "hate": 4.044814978420809e-05,
                "hate/threatening": 3.3015272509780104e-05,
                "illicit": 0.9443896390500058,
                "illicit/violent": 0.7980150660839938,
                "self-harm": 0.004782366071393885,
                "self-harm/instructions": 0.0003890024281719449,
                "self-harm/intent": 0.004450539054378995,
                "sexual": 5.112579049909173e-05,
                "sexual/minors": 1.3135179706526775e-05,
                "violence": 0.023199819818671183,
                "violence/graphic": 3.799845147518645e-05
            },
            "flagged": true
        }
    ]
}

なんだか true 判定されているようですが、どの項目が true になっているのか見てみましょう。

> uv run text-moderation.py | grep true
                "illicit": true,
                "illicit/violent": true,
            "flagged": true

きちんとプロンプトの有害判定ができていますね!

次に画像入力を試してみます。下記のように 指定してください。具体的な画像の URL は控えますが、適当な画像ファイルをインターネットから拝借し、base64 で与えてみました。

# text-and-image-moderation.py

from openai import OpenAI
import json
import base64

client = OpenAI()

with open("sample.png", "rb") as image_file:
    base64_image = base64.b64encode(image_file.read()).decode("utf-8")

response = client.moderations.create(
    model="omni-moderation-latest",
    input=[
        {"type": "text", "text": ""},
        {
            "type": "image_url",
            "image_url": {
                "url": f"data:image/png;base64,{base64_image}",
            },
        },
    ],
)


response_dict = response.to_dict()

json_data = json.dumps(response_dict, indent=4)

print(json_data)

実行してみましょう。

uv run text-and-image-moderation.py
> uv run text-and-image-moderation.py
{
    "id": "modr-bd3d006df14da4ef0785ccff8f47a16f",
    "model": "omni-moderation-latest",
    "results": [
        {
            "categories": {
                "harassment": false,
                "harassment/threatening": false,
                "hate": false,
                "hate/threatening": false,
                "illicit": false,
                "illicit/violent": false,
                "self-harm": false,
                "self-harm/instructions": false,
                "self-harm/intent": false,
                "sexual": true,
                "sexual/minors": false,
                "violence": false,
                "violence/graphic": false
            },
            "category_applied_input_types": {
                "harassment": [
                    "text"
                ],
                "harassment/threatening": [
                    "text"
                ],
                "hate": [
                    "text"
                ],
                "hate/threatening": [
                    "text"
                ],
                "illicit": [
                    "text"
                ],
                "illicit/violent": [
                    "text"
                ],
                "self-harm": [
                    "text",
                    "image"
                ],
                "self-harm/instructions": [
                    "text",
                    "image"
                ],
                "self-harm/intent": [
                    "text",
                    "image"
                ],
                "sexual": [
                    "text",
                    "image"
                ],
                "sexual/minors": [
                    "text"
                ],
                "violence": [
                    "text",
                    "image"
                ],
                "violence/graphic": [
                    "text",
                    "image"
                ]
            },
            "category_scores": {
                "harassment": 0.01982273155079694,
                "harassment/threatening": 0.0008905964423441727,
                "hate": 0.007177008009951712,
                "hate/threatening": 2.737216731838081e-05,
                "illicit": 0.003814481435570866,
                "illicit/violent": 0.0001254594479971798,
                "self-harm": 0.004740055056967628,
                "self-harm/instructions": 0.00025768994014334237,
                "self-harm/intent": 0.00030698664027337325,
                "sexual": 0.9599762057376384,
                "sexual/minors": 0.00017546144100994869,
                "violence": 0.04722400670256895,
                "violence/graphic": 4.7285443452031076e-05
            },
            "flagged": true
        }
    ]
}
> uv run text-and-image-moderation.py | grep true
                "sexual": true,
            "flagged": true

ちゃんと適切に判定されていますね。ウッとくる画像は見たくはなかったのでこういう画像で試さざるを得ませんでした…

ちなみに、ChatGPT に上記のガイドとともに有害な画像の具体例を聞いたら Moderation にひっかかってしまいました。

ちゃんと仕事してる!

アップグレードされた Moderation API、なかなか良いのではないのでしょうか。今までは日本語だとザルのように貫通していたりしたので、具体的なマルチリンガル攻撃に対する防御性能比較もしてみたいですね。

すべて勉強代に充てさせていただきます!アウトプットします!