Closed63

書籍「Azure OpenAI Service実践ガイド ~ LLMを組み込んだシステム構築」を読んで雑にメモる

りょたりょた

Azure OpenAIとは

Azure 上で提供される、OpenAIの技術を統合した生成AIサービスのこと。

りょたりょた

2022/11/15 Meta Glactica が公開されたが、2日で公開中止になった。差別や偏見の内容が多かったから。

りょたりょた

AIが誤答することを「ハルシネーション」(幻覚)という。

りょたりょた

生成AIで用いるモデルは二種類。

  1. 識別モデル(代表的なアルゴリズム: k-最近傍、ロジスティクスかいき、サポートベクターマシン)
  2. 生成モデル(代表的なアルゴリズム: ナイーブベイズ分類機、敵対的生成ネットワーク、変分オートエンコーダ)
りょたりょた

AI関連の「長期間の依存」という単語について

初期のアルゴリズム、特にシンプルな統計的手法や初期のニューラルネットワークでは、文章中の単語の直近の文脈や隣接する単語との関係性は比較的よく理解できても、より長い範囲にわたる依存関係(例えば、文章の初めと終わりの単語間の関係など)を把握するのは難しいとされていました。

りょたりょた

メタプロンプトとは

ユーザーから与えられたプロンプトの他に、システム側で文脈や出力形式などを付加してからLLMに与えると、より目的に沿った回答が得られる。このように、システム側で追加するプロンプトのことをさす。

りょたりょた

プロンプトのテクニック。

  1. Few-shot learning。 回答例や出力形式例を与えると、真似して回答してくれる。
  2. Chain of Thought。段階的に思考する過程をLLMに例示するテクニック。(step by step)
りょたりょた

OpenAIのサービスとAzure OpenAI の違い

データをモデルの学習に利用するかどうか、が大きな違い。(そのほかもある)

OpenAI

  • SaaSの場合は利用する可能性あり。
  • API連携の場合は利用しない。
  • モデルのトレーニング、改善には利用しない。
  • 社員やパートナー社員がレビューする可能性あり。

Azure OpenAI

  • モデルのファインチューニングにのみ利用する。
  • モデルのトレーニングには利用しない。
  • 承認されたMS社員がレビューする。

レビューとは、OpenAIのサービスや製品に関して、社員やパートナー社員がその内容を詳しく見て、品質や適合性、パフォーマンスなどを評価する行為

りょたりょた

RAG(Retrieval-Augmented Generation)とプラグイン、ファインチューニングの違いをわかりやすく

ChatGPTと壁打ちをしてしっくりきた例。ガンダムを題材にする。

  • RAG(Retrieval-Augmented Generation): ガンダムのパイロット(AIモデル)が、過去の戦闘記録や他のパイロットの戦術(データベースやインターネット上の情報)を参考にしながら、新しい戦闘スタイルや戦略(レスポンス)を開発すると考えることができます。つまり、過去のデータを基にしつつ、新しい戦術を生み出すプロセスです。
  • プラグイン: これはガンダム(AIモデル)が新しい装備や武器(機能や特性)を追加することに相当します。ガンダム自体の基本的な設計は変わらず、特定のミッションや状況に適した特殊な装備や武器を装着することで、様々な能力や特性を発揮できるようになります。
  • ファインチューニング: ガンダムのファインチューニングは、特定の敵や戦闘環境に最適化するために、既存のガンダム(AIモデル)の設定を調整することです。たとえば、重力の強い惑星での戦闘に対応するために機動性を高める調整や、特定の敵に対抗するために防御力を強化するなど、特定のシナリオに特化した性能の調整を行います。
りょたりょた

Azure OpenAI Studio とは

実際に試してみることのできる専用のポータル。

りょたりょた

トークンについて

素直に1トークン1単語にならないのはなぜか?
GPTがBPE(Byte-Pair Encoding)という手法を用いてテキストを分割しているため。また、未知の単語に遭遇した時にも対応できるようにするため。(文字分割、サブワードと呼ばれる。)

りょたりょた

ハンズオン

素振りリポ。本編とは異なり、poetryとfastAPIを入れている。
https://github.com/ryota-09/azure-openai-sample/tree/main

りょたりょた

これがメタプロンプトか。

message_text = [
    {"role":"system","content":"##役割 \n あなたは優秀なコピーライターです。ユーザーが提供するお題に対してのコピーを考えてください。\n ## 制約条件 \n ・コピーは20文字以内です。\n・漢字の割合を30%、ひらがなの割合を70%にします。\n・魅力的かつ印象的なコピーを考えてください。"},
    { "role": "user", "content": "ゆず味のアイスキャンディー" },
    { "role": "assistant", "content": "爽やかなゆずの口どけ" },
    {  "role": "user", "content": "サバ味のソフトクリーム"}
]
りょたりょた

Cognitive Search の役割

リクエストされた質問が「どの部署に尋ねると良いか見極める(検索する)」役割。それをもとに、AIに尋ねる。

りょたりょた

リクエストによっては、プラグインを利用する必要があるものもあれば、Web Search が必要なもの、Cognitive Searchが必要なものなど、分岐が必要になってくるのでは?これはアプリケーションレイヤーで分岐させるのか?それとも、それそのものも分岐するようなコンポーネントが必要なのか。。

りょたりょた

独自データ検索のフロー

  1. リクエスト
  2. 質問のベクトル化(Embbeding)
  3. ベクトル検索、関連事項の特定(Cognitive Search)
  4. AI回答(GPT)
りょたりょた

旧 Cognitive Search

りょたりょた

Grounding とは

LLMの学習範囲外のデータを使って回答すること

りょたりょた

Azure AI Search には三種類の検索方法がある。

  • フルテキスト検索
  • ベクトル検索
  • セマンティック検索
りょたりょた

インデックスとは

テーブルがデータベース内のレコードを整理する方法と同様に、Azure AI Search でドキュメントを整理および検索する主な手段

りょたりょた

インデクシングの構成要素

  • データソース
  • インデクサー
  • Cognitive Skills(インデックス作成のプロセスを強化するもの。PDFの変換、音声データの変換など)
  • データマッピング
りょたりょた

フルテキスト検索

スキーマっぽいものを作成し、箱を作成。

fields = [
        SimpleField(name="id", type=SearchFieldDataType.String, key=True),
        SearchableField(name="title", type=SearchFieldDataType.String),
        SearchableField(name="artist", type=SearchFieldDataType.String),
        SearchableField(name="description", type=SearchFieldDataType.String),
       ...
    ]

result = client.create_index(index)
りょたりょた

ドキュメントの登録

search_client = SearchClient(endpoint,name, credential=AzureKeyCredential(key))
result = search_client.upload_documents(documents=DOCUMENT)
りょたりょた

キーワード検索

results = client.search(search_text="泣く女", include_total_count=True)
りょたりょた

ベクトル検索

# ベクトル検索用の設定
vector_search = VectorSearch(
    algorithm_configurations=[
        HnswVectorSearchAlgorithmConfiguration(name="vectorConfig", kind="hnsw", parameters={"m": 4, "efConstruction": 400, "efSearch": 500, "metric": "cosine"})
    ]
)
りょたりょた

ベクトル化

 # ベクトル化
        response_title = openai.Embedding.create(input=[doc["title"]], engine=model_name)
        doc["title_vector"] = response_title["data"][0]["embedding"]
バージョンを変更した。エラーが出たので。
poetry add openai\[datalib\]==0.28
りょたりょた

ベクトルを利用した検索

response_search_word_vector = openai.Embedding.create(input=key_word, engine="sampleEmbedding")
    results = client.search(search_text="", include_total_count=True, vectors=[Vector(
        value=response_search_word_vector["data"][0]["embedding"],
        k=3,
        fields="description_vector"
    )])
りょたりょた

他のものと流れは同じ。
下記が大事かな。

semantic_config = SemanticConfiguration(
    name="my-semantic-config",
    prioritized_fields=PrioritizedFields(title_field=SemanticField(field_name="title"), prioritized_content_fields=[SemanticField(field_name="description")]),
)
りょたりょた

Grounding / RAG

Azure OpenAIにおけるGroundingのアプローチ

  • RAG
  • Azure OpenAI On your data
りょたりょた

RAG

# 下記で追加の情報をフォーマット
 response = openai.Embedding.create(input=question ...)
  ...
    results = search_client.search(
        search_text=question,
        include_total_count=True,
        vectors=[Vector(
            ...
        )],
    )
# フォーマットした情報をpromptに追加する。
system_prompt = "あなたは優秀なサポートAIです。ユーザーから提供される情報をベースにあなたが学習している情報を付加して回答してください。"
    user_prompt = f"Q: {question}\nA: 参考情報:{search_result}"
    response = openai.ChatCompletion.create(
        ....
        messages=[
            { "role": "system", "content": system_prompt },
            { "role": "user", "content": user_prompt },
        ],
    )
りょたりょた

ノーコードでデータを付与できるもの。(検索対象は英語のみ)
サポートされるファイル

  • txt
  • md
  • html
  • powerpoint
  • pdf
りょたりょた

Lang Chain

大規模言語モデル(LLM)を活用して生成AIアプリケーション開発を効率的に行うためのフレームワーク。Python用。

https://github.com/langchain-ai/langchain

りょたりょた

LangChainを使ったRAGシステムのフロー

  1. 独自データをCognitive Searchに格納
  2. データ検索
  3. プロンプト作成
  4. Azure OpenAIのLLMへの問い合わせ
  5. 回答(出力形式の指定)
りょたりょた

なぜかローダーでエラーになるので、テキストを直入れする。

 # なぜかエラーになる。。RuntimeError: Error loading long_text.txt
    # loader = TextLoader("long_text.txt", encoding="utf-8")
    # documents = loader.load()
split_documentではエラーになったので、下記にした
docs = text_spliter.create_documents(documents)
りょたりょた

ベクトル検索

texts = vector_store.similarity_search(
        query="GPT-4を使ってどんなことができるの?",
        k=3,
        search_type="similarity",
    )
りょたりょた

promptTemplateの利用

template = PromptTemplate.from_template("{keyword}を解説する書籍のタイトル案は?")
prompt = template.format(keyword="ChatGPT")

 chat = AzureChatOpenAI(
        openai_api_base=AZURE_OPENAI_API_BASE,
        openai_api_version="2023-07-01-preview",
        deployment_name="DEPLOYNAME",
        openai_api_type="azure",
        )   
    output = chat.predict(prompt)
りょたりょた

Semantic Kernel

Semantic Kernel とはマイクロソフトが開発したソフトウェア開発キット(SDK)
主な機能

  • 外部データソースと連携
  • プロンプトのテンプレート作成
  • プラグイン実行
  • PlannerによるLLM問い合わせの自動化
  • データの一時記憶
りょたりょた

Planner

planner = BasicPlanner()
    basic_plan = await planner.create_plan_async(ask, kernel)
    
    results = await planner.execute_plan_async(basic_plan, kernel)
りょたりょた

Connector

外部のデータへのアクセスを可能にするインターフェース。

りょたりょた

Function Calling

ユーザーのプロンプトに基づいて、あらかじめ定義した関数を呼ぶべきかどうかをAzure OpenAIのモデルが判断してくれる機能。

りょたりょた

あらかじめ呼び出したい関数を定義しておく。それぞれのプロパティは予約語。

functions = [
    {
        "name": "get_current_weather",
        "description": "対象地点の現在の天気を取得します。",
        "parameters": {
            "type": "object",
            "location": {
                "type": "string",
                "description": "都道府県や市区町村 例:東京都港区"
            },
            "required": ["location"]
        }
    }
]
response = openai.ChatCompletion.create(
        engine="",
        messages=messages,
        functions=functions,  <=== ここで設定する。
        function_call="auto",
        max_tokens=1000,
        temperature=0
    )

あらかじめ設定した関数を呼び出すべきかどうかをモデルが判別してくれる。ただし、処理をしてくれるわけではない。判別のみ行う。

if response.choices[0].finish_reason == "function_call":
りょたりょた

ファインチューニング

既存のモデルを特定のタスクやデータに合わせて調整する手法。

りょたりょた

ファインチューニングのプロセス

  1. 事前学習モデルの選択
  2. データセットの準備
  3. データセットの前処理
  4. 学習に関するオプション調整
  5. ファインチューニングの訓練
  6. 評価と調整
りょたりょた

データセットの準備

トレーニングデータとバリデーションデータの二種類が必要。(json)

このスクラップは2024/01/17にクローズされました