MLflow 2.8における審判としてのLLMの発表、およびRAGアプリケーションにおけるLLM評価のベストプラクティスパート2

[Announcing MLflow 2\.8 LLM\-as\-a\-judge metrics and Best Practices for LLM Evaluation of RAG Applications, Part 2 \| Databricks Blog](https://www.databricks.com/blog/announcing-mlflow-28-llm-judge-metrics-and-best-practices-llm-evaluation-rag-applications-part)の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

本日、時間とコストを削減しつつも、人間による判断と近いメトリクスを提供するLLM-as-a-judgeメトリクスの[MLflow 2.8](https://www.mlflow.org/docs/2.8.0/index.html)におけるサポートを発表できることを嬉しく思います。[前回のレポート](https://qiita.com/taka_yayoi/items/7efb0df8024daf491b9e)では、[DatabricksドキュメントのAIアシスタント](https://docs.databricks.com/en/index.html)において、どのようにLLM-as-a-judgeテクニックが効率の改善、コストの削減を行い、人間のスコアと80%以上の一貫性を維持することで、時間(人間による2週間の作業から、LLM審判によって30分に)、コスト(タスクごとのコストが`$20`から`$0.2`に)の大きな削減に寄与しているのかに関してケーススタディを議論しました。また、以下のパート2ではRAG(Retrieval Augmented Generation)アプリケーションにおけるLLM-as-a-judge評価のベストプラクティスに関して[前回のレポート](https://qiita.com/taka_yayoi/items/7efb0df8024daf491b9e)の続きを説明します。皆様自身のRAGアプリケーションのパフォーマンスを評価し、チューニングするために、データクリーニングと組み合わせて同様の方法論をどのように適用できるのかをウォークスルーします。前回のレポートと同様、LLM-as-a-judgeはLLMベースのアプリケーションの効果を継続する際に必要となる評価テクニックのスイートにおいて重要なツールとなります。多くの状況では、スイートスポットを表現するものと考えます: 自動かつ高速、低コストで(チャットbotのレスポンスのように)構造化されていないアウトプットを評価します。このように考えると、このテクニックは、遅く高コストですがモデルの評価における黄金律を表現する人間の評価の同僚として価値のあるものと考えることができます。

評価においてサードパーティのLLMサービス(OpenAIなど)を使用する場合、LLMサービスの利用規約の対象になる場合があります。

# MLflow 2.8: 自動評価

LLMコミュニティでは、自動評価のための「審判としてのLLM」の活用を探索しており、我々はそれらの[理論](https://arxiv.org/abs/2306.05685)を[プロダクションのプロジェクト](https://qiita.com/taka_yayoi/items/7efb0df8024daf491b9e)に適用しました。そして、それぞれの評価指標に対して単一の評価例と、GPT、MPT、Llama2モデルファミリーのような最先端のLLMを用いた自動評価を行うことで、コストと時間を大きく削減できることがわかりました。MLflow 2.8では、LLM評価のためのパワフルでカスタマイズ可能なフレームワークを導入します。GenAIメトリクスと評価例をサポートするように、[MLflow Evaluation API](https://mlflow.org/docs/latest/models.html#evaluating-with-llms)を拡張しました。公正性、解答の正しさ、解答の類似性のように、デフォルトの審判としてGPT-4を使用するGenAIメトリクスとともに、毒性、レーテンシー、トークン数などのメトリクスをすぐに利用できます。GenAIメトリクスにおいても、常にカスタムのメトリクスをMLflowに追加することができます。いくつかの例を通じて実際にMLflow 2.8を見ていきましょう！

LLM-as-a-judgeテクニックを用いてカスタムGenAIメトリックを作成する際、審判として必要とするLLMを選択し、評点スケールを提示し、スケールにおけるそれぞれの評点の例を提示しなくてはなりません。MLflow 2.8で`Professionalism`のGenAIメトリックを定義する例を以下に示します:

```py
professionalism = mlflow.metrics.make_genai_metric(
    name="professionalism",
    definition=(
        "Professionalism refers to the use of a formal, respectful, and appropriate style of communication that is "
        "tailored to the context and audience. It often involves avoiding overly casual language, slang, or "
        "colloquialisms, and instead using clear, concise, and respectful language."
    ),
    grading_prompt=(
        "Professionalism: If the answer is written using a professional tone, below are the details for different scores: "
        "- Score 1: Language is extremely casual, informal, and may include slang or colloquialisms. Not suitable for "
        "professional contexts."
        "- Score 2: Language is casual but generally respectful and avoids strong informality or slang. Acceptable in "
        "some informal professional settings."
        "- Score 3: Language is overall formal but still have casual words/phrases. Borderline for professional contexts."
        "- Score 4: Language is balanced and avoids extreme informality or formality. Suitable for most professional contexts. "
        "- Score 5: Language is noticeably formal, respectful, and avoids casual elements. Appropriate for formal "
        "business or academic settings. "
    ),
    examples=[professionalism_example_score_1, professionalism_example_score_2, professionalism_example_score_3, professionalism_example_score_4, professionalism_example_score_5],
    model="openai:/gpt-4",
    parameters={"temperature": 0.0},
    aggregations=["mean", "variance"],
    greater_is_better=True,
)
```

前回のレポートで見たのと同じように、評価の例(上のスニペットの`examples`リスト)はLLMによって判断されるメトリックの精度改善の役に立ちます。Mlflow 2.8によって、評価例の定義が容易になります:

```py
professionalism_example_score_2 = mlflow.metrics.EvaluationExample(
    input="What is MLflow?",
    output=(
        "MLflow is like your friendly neighborhood toolkit for managing your machine learning projects. It helps "
        "you track experiments, package your code and models, and collaborate with your team, making the whole ML "
        "workflow smoother. It's like your Swiss Army knife for machine learning!"
    ),
    score=2,
    justification=(
        "The response is written in a casual tone. It uses contractions, filler words such as 'like', and "
        "exclamation points, which make it sound less professional. "
    ),
)
```

我々は皆様が必要とする共通のメトリクスを知っているので、MLflow 2.8ではすぐにいくつかのGenAIメトリクスを利用することができます。"question-answering"のようにお使いのアプリケーションの`model_type`を指定することで、MLflow Evaluate APIは自動で共通のGenAIメトリクスを生成します。以下の例のように"Answer Relevance"を指定するなどして、"extra"のメトリクスを追加することができます:

```py
from  mlflow.metrics.genai.metric_definitions import answer_relevance

answer_relevance_metric = answer_relevance()

eval_df = pd.DataFrame() # Index(['inputs', 'predictions', 'context'], dtype='object')

eval_results = mlflow.evaluate(
    data = eval_df, # evaluation data
    model_type="question-answering",
    predictions="predictions", # prediction column_name from eval_df
    extra_metrics=[answer_relevance_metric]
)
```

さらにパフォーマンスを改善するには、すぐに利用できるこれらのGenAIメトリクスに対する審判モデルとプロンプトを変更することができます。以下に、EvaluationタブでビジュアルでGenAIのメトリクスをクイックに比較する助けになるMLflow UIのスクリーンショットを示します:
![](https://cms.databricks.com/sites/default/files/inline-images/db-791-blog-img-1.png)

また、対応する`eval_results_table.json`を参照したり、さらなる分析のためにPandasデータフレームにロードすることができます。
![](https://cms.databricks.com/sites/default/files/inline-images/db-791-blog-img-2.png)

# RAGアプリケーションへのLLM評価の適用: パート2

我々の調査の次のラウンドでは、入力データの品質を改善することでパフォーマンスを改善できるかどうかを確認するために、[Databricks Documentation AI Assistant](https://docs.databricks.com/)のプロダクションアプリケーションを再訪します。この調査から、高い適切性、チャットbotの回答の可読性の改善、コスト削減とスピード改善につながるトークン数の削減を達成するクリーンなデータを自動で生成するワークフローを開発しました。

## RAGアプリケーションにおける効果的な自動評価のためのデータクリーニング

チャットbotレスポンスのパフォーマンスに対するデータ品質のインパクトと、パフォーマンスを改善するための様々なデータクリーニングのテクニックを探索しました。これらの知見は汎化でき、皆様のチームで効果的にRAGベースのチャットボットを評価する助けになるものと信じています:

- データのクリーニングによって、最大 **+20%** (評点スケール1-5において3.58から4.59に) LLMが生成する回答の適切性を改善しました。
- 予期しなかったデータクリーニングの効果として、必要トークン数が削減されることでコストを低減できるというものがあります。データクリーニングによって、コンテキストに対するトークン数が最大 **-64%** (インデックス作成されるデータにおける965538トークンからクリーニング後の348542トークンに) 削減されました。
- 様々なデータクリーニングコードによって様々なLLMの挙動が改善されました。

![](https://cms.databricks.com/sites/default/files/inline-images/db-791-blog-img-3.png)
![](https://cms.databricks.com/sites/default/files/inline-images/db-791-blog-img-4.png)

## RAGアプリケーションにおけるデータの課題

RAGアプリケーションに対しては様々な[入力データタイプ](https://gpt-index.readthedocs.io/en/v0.6.3/reference/readers.html)が存在します: ウェブサイトのページ、PDF、Google Doc、Wikiページなど。業界において我々がよく目撃した、あるいは、お客様から伺うデータタイプはウェブサイトとPDFです。我々のDatabricks Document AI Assistantは、データソースとして公式のDatabricksドキュメント、ナレッジベース、Sparkドキュメントページを活用します。ドキュメントのウェブサイトは人間によって読むことができますが、LLMが理解するには困難なフォーマットかもしれません。以下に例を示します:
![Screenshot 2023-11-01 at 12.41.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1dd17855-14cc-83c7-0a16-d00547a47b88.png)

これはマークダウンフォーマットとコードスニペットであり、言語オプションは対応するそれぞれの言語に対して理解しやすいUIを提供します。しかし、このUIがLLM向けに単なるマークダウンフォーマットに変換されると、コンテンツは複数回繰り返されるコードブロックに変換され理解が困難になります。このため、mpt-7b-chatに「別のデフォルトカタログ名をどのように設定するのか？」と尋ねると、このコンテキストに基づいて、コードブロックのシンボルの繰り返しである「\``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \``` \```」という回答が示されます。他のケースでは、LLMは指示に従うことに失敗し、質問を繰り返すようになります。同様に、Webページには様々なアイコン、画像、優れたUIをレンダリングするための特殊文字が含まれることがあり、これらもまたLLMを混乱させます。他のアプローチとしてはフォーマットのためのマークアップを無視するようにプロンプトを変更するというものがあることに注意してください。しかし、我あれは特定のアプリケーション向けにさらにプロンプトをチューニングする予定であり、ここで過度に複雑にしたり、不安定性を持ち込むことを避けることにします。

## データクリーニングによるパフォーマンスの改善

マークダウンファイルやWebページから余計なフォーマッティングトークンを削除するためにLLM-as-judgeを活用し、繰り返し[クリーンアップコード](https://gist.github.com/suanmiao/7b1d82dfb94d457a8d521f3cc35613f5)を提示するクイックなワークフローを作成しました。以下にクリーンアップ前後の単一のドキュメントがどのように見えるのかの例を示していますが、両方において構造と意味を保持していることがわかります:
![](https://cms.databricks.com/sites/default/files/inline-images/db-791-blog-img-7.jpg)

また、ドキュメントのクリーンアップによって、LLMのコンテキストウィンドウで使用されるトークンの数が劇的に削減されており、コストと時間を節約できることがわかります。データクリーニングの後で、MPT-7B-Chatの回答での改善を確認できています:
![Screenshot 2023-11-01 at 14.29.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/842c12ea-04d3-a2db-9b04-31b6cd004341.png)

# 自動評価のためにMLflow 2.8を使い始める

我々の分析のパート2では、LLM-as-a-judgeを用いてRAGアプリケーションを評価するためにMLflow 2.8を活用しました。データクリーニングと自動評価を用いることで、皆様のRAGアプリケーションの要件を通じた検証を行うために、クイックかつ効率的に様々なLLMを比較、対照することができます。使い始める助けとなるいくつかのリソースを以下に示します:

- [MLflow 2\.8 Documentation](https://www.mlflow.org/docs/2.8.0/index.html)
- [Tutorial for MLflow Evaluation for RAG](https://www.mlflow.org/docs/2.8.0/llms/llm-evaluate/notebooks/rag-evaluation.html)
- [Tutorial for MLflow Evaluation for Q&A](https://www.mlflow.org/docs/2.8.0/llms/llm-evaluate/notebooks/question-answering-evaluation.html)
- [LLM推論のパフォーマンスエンジニアリング：ベストプラクティス](https://qiita.com/taka_yayoi/items/7efb0df8024daf491b9e)
- [Data cleaning code sample \(gist\)](https://gist.github.com/suanmiao/7b1d82dfb94d457a8d521f3cc35613f5)

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)