NVIDIA NeMo Guardrailsとは? -情報まとめ-

久しぶりの投稿になりますが
情報(と頭の)整理を兼ねて、興味があった4月25日に公開されたNemo Guardrailsについて周辺情報も含めて簡易的に纏めてみたいと思います。

まずは動かしてどのようなものか理解したい。具体的なインストール方法から実行方法までざっくり知りたいという方は、以下のクラスメソッドさんのブログがとても分かりやすく纏まっているのでオススメです。

https://dev.classmethod.jp/articles/nemo-guardrails-overview/

# はじめに
本ブログの元情報は主に以下の3つになります。もし本まとめ記事で気になった部分があればぜひ以下のリンクから詳細をご確認下さい。
1. https://github.com/NVIDIA/NeMo-Guardrails
2. [Technical Blog: NVIDIA Enables Trustworthy, Safe, and Secure Large Language Model Conversational Systems](https://developer.nvidia.com/blog/nvidia-enables-trustworthy-safe-and-secure-large-language-model-conversational-systems/)
3. https://www.nvidia.com/ja-jp/gpu-cloud/nemo-llm-service/

# そもそも Nemo とは?
Nemo Guardrailsの先頭にある"Nemo"とは何であるかから確認してみたいと思います。

昨今 Generative AI に大変な注目が集まっていますが、NVIDIA社も3月21日から開催された[GTC2023](https://www.nvidia.com/ja-jp/gtc/)にて、Generative AIをエンタープライズ品質に進化させる為の[NVIDIA AI Foundations](https://www.nvidia.com/ja-jp/ai-data-science/generative-ai/)というプラットフォーム(構想)を発表しています。
そのプラットフォームの中には[Nemo Service](https://www.nvidia.com/ja-jp/gpu-cloud/nemo-llm-service/)や[Nemo Framework](https://www.nvidia.com/ja-jp/ai-data-science/generative-ai/nemo-framework/)など"Nemo"とついたサービスがいくつか含まれています。つまり、LLM(Large Language Model)開発やLLMを使ったサービスに関連したものには、先頭に"Nemo"とつけられています。
(注:2023年5月現在、また状況は変わるかもしれません)

# Nemo Guardrails 概要

Nemo Guardrailsはプログラム可能なガードレールをLLMベースの対話システムに簡単に追加する為のOSSです。
2023年5月現在、version0.1.0 Alphaとして[github](https://github.com/NVIDIA/NeMo-Guardrails)上に公開されています。
「ガードレール」とはLLMの出力を制御する特定の方法の事で、政治について話さない、特定のユーザリクエストに特定の方法で応答する等、特定のトピックに関するLLMを用いたボットの振る舞いを定義し、会話をガイドする事を意味しているようです。
NeMo Guardrailsを使用する事で、簡単なコンフィグレーションの作成とPythonコーディングのみで、信頼性のある、安全でセキュアなLLM対話システムの構築を簡単に行う事ができます。
また、Nemo Guardrails は[LangChain](https://github.com/hwchase17/langchain)の既存のchainに簡単に追加できるのも大きな特徴です。

Nemo Guardrails を理解する上で大切な概念や言葉を以下に纏めます

- __Rails__
    - Nemo Guardrailsにおいて、LLMの出力をコントロールするプログラマブルな方法の事をRailsと呼びます
- __[Colang](https://colang.nvidia.com/)__
    - ガードレール定義時(設定ファイル作成時)に使用するシンプルでPythonライクなモデリング言語。Colangを使う事で特定のポリシーを強制したい時や、特定の動作を防止したいという際に、対話エージェントの動作と制御を簡単に行う事ができます。
    - github上に[Colangガイド](https://github.com/NVIDIA/NeMo-Guardrails/blob/main/docs/user_guide/colang-language-syntax-guide.md)と[Colang Syntax ガイド](https://github.com/NVIDIA/NeMo-Guardrails/blob/main/docs/user_guide/colang-syntax-reference.md)が公開されており、文法詳細を確認する事ができます。
- __Canonical Forms__
    - 対話型AIにおいて、入力された文や質問を標準化された形式に変換する手法の事で、LLMが文を会話の一部として理解し、処理しやすくする事ができます。例えば、挨拶の言葉は「こんにちは」だけではなく、様々なバリエーションがありますが、Canonical Formsを用い標準化する事でどのような挨拶が入力された場合にも、挨拶であると認識が可能になります。
    - Cannonical Formsについては、LLMとp-tuningの使用を通じて、タスク指向型対話システムにおける意図分類の可能性を実験した[この論文](https://arxiv.org/pdf/2211.05596.pdf)でも触れられています。
- __Dialog Flows__ 
    - Nemo Guardrailsにおいて、ユーザーメッセージとボットメッセージのCannonical Formsシーケンスの事をFlowと呼びます。

# Nemo Guardrails アーキテクチャ
次にNemo Guradrailsのアーキテクチャを少し理解する為に、以下のアーキテクチャ概要図を確認します。グレーの四角で覆われている範囲がNemo Guardrailsになります。
![overall-architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125731/81a6af37-88d9-3c5c-4761-2aeae8fb93c1.png)
<font color="Green">図1: Nemo Guardrails Architecture Overview
※[Architecture Guide](https://github.com/NVIDIA/NeMo-Guardrails/blob/main/docs/architecture/README.md)より引用</font>

ざっくり、ユーザーがチャットボットのUIから入力したメッセージをNemo Guardrailsが受け取ると、まずは入力をCannonical Formsにより標準化された形式に変換します。その後Guardrailsのconfigに設定されたルールを確認し、ユーザの入力とガードレールに定義した状態とのマッチ具合をk-NN vector search(k最近傍探索)で判断します。もし定義とマッチされていると判断された場合は、ガードレールのDialog Flowsで定義されたフローを実行するという流れになります。

図中にもありますが、Nemo Guardrailsでは、バックエンドでLLM API(注:現在はOpenAI APIのみサポート)を呼び出すようになっていますが、LLM APIの呼び出しは[LangChain](https://github.com/hwchase17/langchain)経由になっています。

Nemo Guardrails、LangChain、LLM APIが相互にどのように作用しているのかの流れを説明したハイレベルのシーケンス図を以下に引用します。緑で描かれた「LLMRails」がNemo Guardrailsのモジュールになります。
![sequence-diagram-llmrails.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125731/d6ab18a6-1fc1-0d60-c0f4-72f16c08f76c.png)
<font color="Green">図2: Interaction with LLMs
※[Architecture Guide](https://github.com/NVIDIA/NeMo-Guardrails/blob/main/docs/architecture/README.md)より引用</font>

このように、Nemo Guardrailsは[LangChain](https://github.com/hwchase17/langchain)と親和性が高く、既存のLangChainチェーン上に簡単にNemo Guardrailsによりガードレールを追加する事が可能です。
以下は既存のLangChainのRetrievalQAチェーンに、侮辱に対するガードレールを追加したpythonコードの例です。

```python
from nemoguardrails import LLMRails, RailsConfig

config = RailsConfig.from_path("./config/insults")
app = LLMRails(config)

# ... initialize `docsearch`

qa_chain = RetrievalQA.from_chain_type(
    llm=app.llm, chain_type="stuff", retriever=docsearch.as_retriever()
)
app.register_action(qa_chain, name="qa_chain")

history = [
    {"role": "user", "content": "What is the current unemployment rate?"}
]
result = app.generate(messages=history)
print(result)
```

# Nemo Guardrails のインストール
Nemo Guardrailsはwheelを提供している為、pipで簡単にインストールする事が可能です。以下に簡単な手順を纏めます。
まずはpythonの仮想環境をNemo Guardrails用に作成し、作成した仮想環境に切り替えます。
```ruby:pythonの仮想環境の作成
$ python3 -m venv nemo
$ source nemo/bin/activate 
```
次にnemo guardrailsとopenaiをpip経由でインストールします。
```ruby:nemo guardrailsのインストール
(nemo) $ pip3 install nemoguardrails
(nemo) $ pip3 install openai 
(nemo) $ pip3 list |grep -i -e nemo -e openai
nemoguardrails           0.1.0
openai                   0.27.6
```
テストの際にOpenAIのAPIを使用する為、API KEYを環境変数で定義しましょう。API KEYは[こちらから](https://platform.openai.com/)取得する事が可能です。取得したKEYはbashrc等に保存してしまっても良いと思います。
```ruby:OpenAI API Keyの設定
(nemo) $ export OPENAI_API_KEY=[自身のAPI KEY]
```
Nemo Guardrailsを動かす前にOpenAIのAPIが正常に呼び出せる事を確認しておきます。

https://gist.github.com/acc-mu3n/94e8051f12de36a3b7c4ff914e9e6640
```ruby:openai apiのテスト
(nemo) $ python3 openai-key-test.py

This is indeed a test
```
これでnemo guardrailsを動かす準備が出来ました。nemo guardrailsのcliツールの使い方をコマンドラインから確認します。
```ruby:nemo guardrails server
(nemo) $ nemoguardrails --help
Usage: nemoguardrails [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion [bash|zsh|fish|powershell|pwsh]
                                  Install completion for the specified shell.
  --show-completion [bash|zsh|fish|powershell|pwsh]
                                  Show completion for the specified shell, to
                                  copy it or customize the installation.
  --help                          Show this message and exit.

Commands:
  actions-server  Starts a NeMo Guardrails actions server.
  chat            Starts an interactive chat session.
  server          Starts a NeMo Guardrails server.
```
これでNemo Guardrailsを使う準備が無事出来ました。
長くなったので、この辺りで一度記事を切りたいと思います。つづく…かも

(2022.05.22 続き書きました)

https://qiita.com/mana-murakami/items/28e9eea654b74a540a67