2024 年には、LLM ベースのアプリケーションが不足することはありません。Microsoft や Google などの大手テクノロジー企業は、主力の ChatGPT および Gemini モデルのさらに強力なバージョンを推進しており、Anthropic などの専門企業は、追加の統合を備えた競合製品を推進しています。応用 LLM の世界では、企業や政府でさえ、さまざまなコンテキストでチャット アプリケーションを実験しています。
LLM に注ぎ込まれた膨大な起業家精神にもかかわらず、注目度の高いアプリケーションのほとんどは、人間が読めるテキストを受け取って返すチャットのようなインターフェースに重点を置くことで、依然として限界があります。これは理解できます。結局のところ、LLM の最もエキサイティングな開発の 1 つは、人間の言語を理解して生成し、会話型のユーザー インターフェースを可能にする機能です。ただし、チャット インターフェースは、LLM のもう 1 つの非常に重要な使用例、つまり、より大きなデータ パイプラインの中間ステップとしてのテキスト処理を見落としています。
今日は、このユースケースを検討し、LLM が自然言語ジェネレーターとしてだけでなく、データ パイプラインの一部としてどのように役立つかを見ていきます。
LLM をデータ パイプラインの一部として使用するには、LLM の出力形式を変更する必要があります。つまり、人間が読むための段落を生成するのではなく、モデルはコンピューターが読めるものを生成する必要があります。通常、これは JSON などのデータ形式の構造化された出力、または Python や SQL などのプログラミング言語の命令を意味します。これらの出力形式は、引用符や括弧が抜けているとパイプライン全体がクラッシュする可能性があるため、自然言語よりもはるかに許容度が低くなります。したがって、このユース ケースをサポートするために開発された特殊な方法と機能に頼る必要があります。これらの機能は、出力が関数を呼び出したり、関数呼び出しで消費されたりする傾向があるため、総称して関数呼び出しと呼ばれます。
ただし、これらの方法について詳しく説明する前に、まず関数呼び出し機能が開発された理由をもう少し詳しく調べてみましょう。
外部サービスへの接続
関数呼び出しの本来かつ最も簡単な使用例は、外部サービスへの接続です。OpenAI が GPT-4 を最初にリリースしたとき、API を更新して、モデルが目的を達成するために呼び出すことのできる Python スタイルの関数のセットをユーザーがモデルに提供できるようにする機能も追加しました。たとえば、モデルに、外部関数を呼び出して複雑な証券の価格を計算できることを伝えることができます。この情報を使用すると、モデルは証券の価格設定に関する専門知識を持たなくても、これらの証券で構成されるポートフォリオの価値を計算するコードを作成できます。
Python スタイルの関数の呼び出しは、氷山の一角にすぎません。市場で関数呼び出しの重要性が証明されると、OpenAI や他の LLM プロバイダーは、JSON や SQL などの他の出力形式をサポートし始めました。重要なのは、これらのモデルが機械可読な出力を出力し、他のプロセスで確実に読み取ることができることです。
賢明な読者なら、以前の記事で LLM を使用してトレーニング データ、 SQL 、またはJSONを生成するという同様のことを行ったことに気付くかもしれません。これらの記事では、プロンプト エンジニアリングと出力チェックを使用してこれを実現しましたが、関数呼び出しが広くサポートされている機能になったため、これらのモデル レベルの機能に頼ることで、これをより簡単に行うことができます。
LLMの連鎖
関数呼び出しにより、マルチ LLM アプリケーションに新たな可能性が生まれ、すぐに開発者は LLM を連鎖させて高度なシステムを作成する実験を始めました。これらのシステムの一部はエージェントと呼ばれるようになり、独立して Web を検索し、新しいデータを収集し、新しい情報を使用して別の LLM を呼び出すことができます。これらのパイプラインは驚くほどの自律性を備えており、非常に少ない入力で高度な問題を解決できますが、API コストや動作の安全策などの制限がまだあり、エージェントが広く採用されるには至っていません。
LLMを入力および中間処理として使用する
関数呼び出し LLM のもう 1 つの使用例は、入力および中間データの処理です。LLM は、非構造化入力を下流処理に使用できる構造化データに解析するために使用できます。これらのタスクの多くは「従来の」NLP テクノロジに委ねられる傾向がありますが、トランスフォーマー ベースのモデルの柔軟性により、特別にトレーニングされたモデルは、他の NLP テクノロジよりもこれらのタスクで優れたパフォーマンスを発揮できます。その結果、多くの開発者がデータ パイプラインでこれらの専用モデルを活用しようとしています。
関数呼び出しの理論を理解したので、今日構築するアプリケーションを見てみましょう。
前回の記事では、CB Insights の人気ニュースレターに関する自然言語の質問に答えるシンプルな RAG アプリケーションを作成しました。今日の記事では、同様の質問応答アプリケーションを構築しますが、埋め込み検索と GPT3.5 に頼るのではなく、エンティティ認識を主要なインデックス作成方法として使用します。さらに、要約エンジンとして DRAGON を使用するので、クラウド サービスを必要とせず、ラップトップでアプリケーション全体を実行できます。
エンティティ認識を使用する理由
実装の詳細に入る前に、まず、埋め込み検索ではなく NER を検索テクノロジとして使用する利点について検討してみましょう。実稼働では、特定の状況の要求に応じて各手法を使用する必要がありますが、NER には、埋め込み検索に依存するシステムに比べていくつかの利点があります。
デバッグ可能性: エンティティ認識は簡単に検証できるタスクであるため、パイプライン全体のデバッグ可能性がはるかに高くなります。モデルがすべてのエンティティを正しく識別しているかどうかを確認するのは簡単で、これらのエンティティに基づいてマッチング アルゴリズムを構築して改善するのも簡単です。比較すると、埋め込みアルゴリズムが文章内の類似点と相違点を適切に識別しているかどうかを確認するのははるかに困難です。
柔軟性: 認識とフィルタリングを分離することで、埋め込みベースの検索アルゴリズムよりもパイプラインの柔軟性が大幅に高まります。メタデータを追加したり、エンティティ タイプに基づいて検索アルゴリズムを変更したり、NER ベースの検索結果に加えて埋め込みアルゴリズムを使用することもできます。これにより、テクノロジの組み合わせに基づいて、より強力な機能を開発できます。
たとえば、NER ベースのパイプラインは、エンティティベースの検索を使用してドキュメントのセットを絞り込み、次に埋め込みアルゴリズムを使用して検索空間内でさらに絞り込むことができます。これにより、検索が大幅に高速化され、効率化される傾向があります。
識別力: NER パイプラインは、手動制御のレベルが可能なため、特定の検索および取得タスクに適しています。埋め込み検索は、トレーニング データ内の文章の近接性に基づいており、2 つのドキュメントが同じ大きなドキュメントから取得される確率を計算します。一部のユース ケースでは、埋め込み検索で重要なドキュメントが見逃されることがあります。
RAG パイプライン内で NER を使用する利点がわかったので、アプリケーションで使用している特定のテクノロジーを詳しく見ていきましょう。
LLMエンティティ認識
エンティティ認識は、非構造化言語データから構造化データを抽出する「従来の」NLP テクノロジです。抽出されたデータは、ダウンライン処理で使用したり、分析対象の文章のメタデータとして使用したりできます。
歴史的に、これは、最初に品詞をタグ付けし、次に識別された固有名詞が名前付きエンティティであるかどうかを判断する 2 番目のパスを実行する、専用の小規模な機械学習アルゴリズムを使用して実現されていました。
関数呼び出し LLM を使用すると、同じタスクを実行できるだけでなく、いくつかの利点も追加されます。
トランスフォーマー アーキテクチャは、小規模な NLP モデルよりも言語構造をより適切に理解できるため、文章が不適切にフォーマットされている場合などでも、パフォーマンスがより堅牢になる可能性があります。
LLM は最新のトレーニング データで更新されるため、エンティティ認識システムは他のオープン ソース エンティティ認識モデルよりも最新の状態に保たれる可能性があります。
プロンプトエンジニアリング技術を使用すると、追加データを埋め込み、追加の指示を与えることができ、既製のモデルでもより柔軟な動作が可能になります。
DRAGON前回の記事では、自然言語データの要約におけるその優れたパフォーマンスを強調して Dragon について取り上げました。今回は分析の最終ステップとして Dragon を使用して、選択したエンティティに関連するすべての記事を要約します。
SLIM SLIM は、関数呼び出しに特化した、 LLMWareの小型化されたローカル実行可能なモデルの新しいファミリーです。私が彼らの小型化作業のファンであることは周知の事実です。これらのモデルは、マシンが解釈できる出力を生成するように特別に調整されており、ユーザーは外部 API に頼ることなく、関数呼び出しアーキテクチャの最近の進歩を活用できます。
今日は、ニュースレターの記事に対して名前付きエンティティ認識を実行する SLIMs-NER モデルを使用します。NER に加えて、感情分析、SQL 生成、およびマルチステップ エージェント用の SLIMs モデルもあります。
テクノロジーを理解したので、アプリケーションを実装してみましょう。
まず、CB Insights の記事をダウンロードします。依存関係をインポートします。
import requests from bs4 import BeautifulSoup import os import pandas as pd import json import re
次に、ニュースレターのアーカイブをダウンロードするためのコードを示します。
res = requests.get('https://www.cbinsights.com/newsletter/') soup = BeautifulSoup(res.text) article_links = [[i.text, i['href']] for i in soup.find_all('a') if 'campaign-archive' in i['href'] ] article_soups = [BeautifulSoup(requests.get(link).text) for title, link in article_links]
ニュースレターのアーカイブをダウンロードしたので、JSON形式に変換してみましょう。
result_json = {} for soup_meta, soup_art in zip(article_links, article_soups): article_tables = [] cur_article = [] for table in soup_art.find_all('table'): if table.attrs.get('mc:variant') == 'Section_Divider': article_tables.append(get_deduped_article_tables(cur_article)) cur_article = [] else: cur_article.append(table.text) article_tables.append(get_deduped_article_tables(cur_article)) result_json[soup_meta[0]] = article_tables articles_with_meta = [] for name, tables in result_json.items(): print(name, pd.to_datetime(tables[0][1].strip())) articles_with_meta.append({ 'name': name, 'date': pd.to_datetime(tables[0][1].strip()).strftime('%Y-%m-%d'), 'tables': tables }) df = pd.DataFrame(articles_with_meta)
今は、前回の記事と同じ場所にいます。ただし、埋め込みを作成して RAG 構築に直接進むのではなく、エンティティ認識のステップを実行します。
まず、マシン上でローカルにエンティティ認識を実行できるようにする LLMWare の新しいモデル セットである SLIM を実行するための依存関係をインポートします。
from llmware.agents import LLMfx from llmware.parsers import WikiParser from collections import defaultdict # define a function for identifying all the named entities def run_ner(text): agent = LLMfx() agent.load_work(text) agent.load_tool("ner") named_entities = agent.ner() ner_dict= named_entities["llm_response"] return ner_dict
これで、すべての記事に対して名前付きエンティティ認識を実行できます。
date_entities = defaultdict(dict) for _, row in df.iterrows(): for idx, t in enumerate(row['tables'][1:]): if 'Start Your Free Trial' in t: t = t[:t.index('Start Your Free Trial')] date_entities[row['date']][idx] = run_ner('\n'.join(t))
NER パイプラインが完了するまでに数分かかる場合がありますが、最先端の小型 LLM を使用してエンティティを認識するには、これだけで十分です。
いくつかのテスト項目を印刷することで、date_entities 辞書を確認できます。たとえば、次のコードです。
date_entities[list(date_entities.keys())[0]]
以下の出力が生成されます:
{0: {'people': ['Yahoo!'], 'place': [], 'company': ['Databricks', 'MosaicML'], 'misc': []}, 1: {'people': [], 'place': ['New York'], 'company': ['CB Insights'], 'misc': []}}
SLIMs モデルによって検出されたさまざまなエンティティがすべて表示されます。
エンティティが検出されたので、この手法の威力を示す質問応答ワークフローを構築しましょう。例では、次のテスト質問を使用します: OpenAI は Microsoft の AI 戦略においてどのような役割を果たしていますか?
まず、DRAGON を実行するための適切なパッケージをインポートします。
from llmware.prompts import Prompt query = "What role does OpenAI play in Microsoft's AI strategy?" model_name = "llmware/dragon-llama-7b-gguf" prompter = Prompt().load_model(model_name)
これで、エンティティ認識を使用して質問に答える関数を構築できます。NER データを活用するには、次のワークフローを実装する必要があります。
ワークフローをコード形式で示すと次のようになります。
def answer_question_with_ner(query): ner_results = run_ner(query) # run NER on the user query search_entities = [] for ent_type, ent_list in ner_results.items(): search_entities.extend(ent_list) # create a list of entities to search for search_entities = list(set(search_entities)) # now perform a lookup for articles that mention the identified entities, using set arithmetic. articles = set(entity_to_place_map[search_entities[0]]) for se in search_entities: articles &= set(entity_to_place_map[se]) # now process the corpus into a prompt and feed it to the question-answering LLM. article_content = [] for article in articles: article_content.extend(df[df['date'] == article[0]].iloc[0]['tables'][article[1]+1]) response = prompter.prompt_main(query, context='\n'.join(article_content), prompt_name="default_with_context", temperature=0.3) return response # return the response.
最初のコード ブロックのクエリを使用して関数を実行すると、次の結果が表示されます。
Microsoft has poured billions of dollars into ChatGPT developer OpenAI. However, it's also placed a number of bets on other GenAI startups across computing, mapping, and gaming.
また、応答オブジェクトの「証拠」セクションでは、実際に CB Insights アーカイブから Microsoft と OpenAI について言及している 2 つの記事が取得されており、LLM の回答が直接証拠に基づいていることも確認できます。
明示的なエンティティ認識を行っているため、取得プロセスは非常に透過的でデバッグ可能であることに注意してください。モデルがコーパスからこれらの特定の情報を取得した理由について疑問が生じた場合、クエリに「Microsoft」と「OpenAI」が言及されており、取得した 2 つのニュースレター セクションが両方のエンティティに言及している唯一のセクションであるため、モデルが記事を選択したことを確認するには、単純な print ステートメントを実行するだけで済みます。
さらに、埋め込みベースのベクトル検索と比較すると、NER 検索方法ははるかに正確な回答を提供します。私のテストでは、選択された記事は OpenAI の ada アルゴリズムによってランク付けされた最も関連性の高い記事の上位 10 件に入っていましたが、手元の質問に最も近いものとして特定されたものではありません。したがって、埋め込み検索を使用するアプリケーションは質問にまったく正しく回答していない可能性があり、デバッグ可能性の欠如は混乱を招くだけです。
これにより、NER ルックアップを使用した質問応答アプリケーションが構築され、その過程でパイプラインの品質が向上しました。
本日、私たちは LLM のエキサイティングな新機能である関数呼び出しを使用してアプリケーションを構築しました。小型化され、ローカルで実行可能な関数呼び出しモデルは、新しいクラスの AI アプリケーションを解き放つ革新的な開発であり、私たちはこれらのテクノロジーの最初のイテレーションを目にしているだけです。今後数か月で、開発者がこれらのテクノロジーを使用してどのようなアプリケーションを作成するかを見るのは楽しみです。
AI 分野で実現してみたいアイデアをお持ちの場合、または単にテクノロジーについて話し合いたい場合は、 GithubまたはLinkedInでお気軽にご連絡ください。
SLIM と DRAGON の開発元である LLMWare について詳しく知りたい場合は、 HugginFaceまたはGithubで見つけることができます。