0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Arize Phoenixを動かし、プロンプト改善のTraceを確認する

0
Posted at

はじめに

LLMを使った処理は、最終的な出力だけを見ても「どの工程で時間がかかったのか」「どの候補を、なぜ採用しなかったのか」が分かりにくいことがあります。

今回作成した Prompt Learning Lab では、プロンプト改善を次の流れで実行しています。

  1. Trainデータから改善候補を作る
  2. Validationデータで候補を評価する
  3. Guardrailを満たした候補だけを採用する
  4. 選定後のプロンプトをTestデータで1回だけ評価する

各工程の実行順序と判断結果を確認するため、オープンソースのAI Observabilityツールである Arize Phoenix を使用して見ました。

  • PythonアプリケーションからTraceを送信する
  • Phoenix UIでTraceとSpanを読む
  • selection Spanで候補の採否を確認する
  • Final Testの指標をローカル成果物と照合する

サンプルには感情分類を使います。

Phoenixとは

Phoenixは、LLMアプリケーションの実行経路を可視化し、評価や問題調査に利用できるオープンソースのObservabilityツールです。OpenTelemetry / OpenInferenceを利用して、アプリケーションから送信されたTraceを収集します。

最初に、TraceとSpanだけ押さえておきます。

  • Trace: 1回の処理全体を表す記録
  • Span: Traceを構成する個々の処理単位
  • Attribute: Spanに付けるモデル名、iteration、評価値、採否などの情報

今回の実験では、1回の実験を experiment_run Traceとして記録し、その中にデータ読み込み、候補生成、評価、選定、最終テストのSpanを配置します。

experiment_run
├── dataset_load
├── baseline_validation
├── iteration_1
│   ├── train_inference
│   ├── feedback_generation
│   ├── prompt_optimization
│   ├── candidate_validation
│   └── selection
├── iteration_2
├── iteration_3
└── final_test

Phoenixの公式ドキュメントでも、Traceは複数のSpanから構成され、リクエストがどの処理を通ったかを確認するためのものと説明されています。

今回の構成

PhoenixはDockerコンテナとして起動し、PythonアプリケーションはOTLP over HTTPでSpanを送信します。

Python CLI
  │
  │ OTLP/HTTP: http://localhost:6006/v1/traces
  ▼
Phoenix container
  ├── Trace collector
  ├── Web UI: http://localhost:6006
  └── Docker volume: phoenix-data

Phoenixが停止している場合でも、実験自体を失敗させない構成にしました。Phoenixへの送信で問題が起きたときは警告だけを表示し、runs/<task>/<run-id>/ に保存するローカル成果物を正とします。

また、Phoenixには入力原文や参照要約を送らず、次のような安全な情報だけを記録します。

  • dataset名、revision、seed、分割比率
  • モデル名
  • promptや入力のSHA-256 hash
  • iteration、評価指標、失敗件数
  • accepted などの判断結果

DockerでPhoenixを起動する

このプロジェクトでは、次のCompose設定を使用しています。

services:
  phoenix:
    image: ${PHOENIX_IMAGE:-arizephoenix/phoenix:latest}
    ports:
      - "127.0.0.1:${PHOENIX_HTTP_PORT:-6006}:6006"
      - "127.0.0.1:${PHOENIX_GRPC_PORT:-4317}:4317"
    environment:
      PHOENIX_WORKING_DIR: /data
    volumes:
      - phoenix-data:/data

volumes:
  phoenix-data:

まず、Compose設定が解決できることを確認してから起動します。

docker compose config
docker compose up -d
docker compose ps

ブラウザで次のURLを開き、Phoenixの画面が表示されれば起動完了です。

http://localhost:6006

ローカルでself-hostする場合の標準的なApplication Endpointも http://localhost:6006 です。Dockerを含むself-host方法は公式ドキュメントでも案内されています。

このCompose設定は学習・ローカル検証向けです。latest は後から内容が変わるため、再現性が必要な環境では検証済みのtagまたはdigestを PHOENIX_IMAGE に指定します。

PythonアプリケーションからTraceを送る

Phoenixを有効化し、送信先を設定します。

export PHOENIX_ENABLED=true
export PHOENIX_COLLECTOR_ENDPOINT=http://localhost:6006

このプロジェクトでは、PHOENIX_COLLECTOR_ENDPOINT に /v1/traces を追加したURLをOTLP exporterへ渡しています。

transport = OTLPSpanExporter(
    endpoint=os.environ.get(
        "PHOENIX_OTLP_ENDPOINT",
        "http://localhost:6006/v1/traces",
    ),
    timeout=5,
)

provider = TracerProvider(
    resource=Resource({
        "service.name": "prompt-learning",
        "openinference.project.name": "prompt-learning",
    }),
)

openinference.project.name を設定しているため、送信したTraceはPhoenix UIの prompt-learning Projectにまとまります。

感情分類を実行する

最初に感情分類を実行します。

python -m prompt_learning.cli run --config configs/emotion.yaml

使用した主な条件は次のとおりです。

項目 値
dataset dair-ai/emotion
seed 42
label sadness / joy / love / anger / fear / surprise
split Train 60% / Validation 20% / Test 20%
inference model gpt-4o-mini
最大改善回数 3回

この設定では6 labelから各100件を取得し、Train 360件、Validation 120件、Test 120件に分割します。モデルAPIを複数回呼ぶため、実行時間と料金に注意してください。

実行が完了すると、ターミナルにRun ID、選択されたprompt、Validationでの採否、Test reportの場所が表示されます。ローカル成果物は次のディレクトリに保存されます。

runs/emotion/<run-id>/

今回確認したRun IDは次の値です。

fa23ed15622e48569d3311ac840fb99d

PhoenixでTraceを確認する

Phoenix UIで Projects → prompt-learning を開き、experiment_run を選択します。

emotion-trace.png

中央のツリーから、次の順番で処理されたことを確認できます。

  1. dataset_load でデータセットを読み込む
  2. baseline_validation で現在のpromptを評価する
  3. iteration_1 から iteration_3 で改善候補を生成・評価する
  4. 候補ごとに selection で採否を決める
  5. 最後に final_test を実行する

Traceをログの代替として眺めるだけでなく、「設計した実行順序になっているか」を確認する点が重要です。今回であれば、Testが候補選定ループの外にあり、選定後にだけ実行されていることを確認できます。

親の experiment_run Spanを選択すると、右側のAttributesにdataset、split比率、モデル、seed、run IDなどが表示されます。別の実行と比較するときは、まずこの条件が同じかを確認します。

selection Spanで採否を見る

iteration_3 の下にある selection Spanを選択すると、候補の採否をAttributesで確認できます。

emotion-selection.png

今回の表示は次のとおりです。

iteration: 3
accepted: false

accepted=false は処理の失敗ではありません。候補promptは生成できたものの、ValidationのGuardrailを満たさなかったため、現在のpromptを維持したという判断です。

感情分類では、次の条件をすべて確認しています。

  • macro F1を下げない
  • accuracyの低下を1 percentage point以内に抑える
  • invalid output rateを増やさない
  • 各labelのrecallを5 points以上下げない

実際の3候補はすべて却下されました。

iteration accepted 主な理由
1 false sadnessのrecall低下
2 false invalid率の増加、複数labelのrecall低下
3 false invalid率の増加、sadnessのrecall低下

平均指標が一部改善していても、特定labelが悪化した候補を採用しないことが、この実験の狙いです。

Final Testとローカル成果物を照合する

候補選定後は、維持されたbaseline promptをTestデータで1回だけ評価します。

emotion-final-test.png

感情分類の最終結果は次のとおりでした。

指標 値
accuracy 0.4750
macro F1 0.4766
invalid output rate 0.0167
prompt version 0

Phoenixは実行経路を確認する場所として便利ですが、再現の根拠はローカル成果物にも残します。

runs/emotion/fa23ed15622e48569d3311ac840fb99d/
├── manifest.json
├── iteration_history.csv
├── selected_prompt.txt
├── test_metrics.json
├── failure_cases.csv
├── confusion_matrix.png
└── report.md

確認時は、PhoenixのAttributesと report.md、iteration_history.csv を照合します。UIだけに依存しないことで、Phoenixへの接続やclient互換性に問題があっても実験結果を追跡できます。

Traceから分かったこと

今回、Phoenixを導入して特に確認しやすくなったのは次の2点です。

  1. 処理の順序
    Train、Validation、Selection、Final Testが意図した順番で実行されている。

  2. 採用しなかった判断
    accepted=false をSpanに残すことで、「候補を作れなかった」のではなく「評価したうえで却下した」と区別できる。

最終スコアだけでは、候補が何回作られ、どの段階で採用されなかったかは分かりません。Traceとローカル成果物を組み合わせることで、プロンプト改善の結果だけでなく、判断に至る過程も説明できるようになりました。

参考資料

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?