見出し画像

LangChainのチュートリアルメモ3 LLMs

今回参照にしたチュートリアルは以下

LLMsとは?

大規模言語モデルのラッパー(特に大規模言語モデルの「生成」機能)は,LangChainの機能の中核をなしています。
これらのクラスが公開するコアメソッドはGenerateメソッドで、文字列のリストを受け取り、LLMResult(すべての入力文字列に対する出力を含む)を返します。
このインタフェースは文字列のリスト上で動作します。
なぜなら、文字列のリストはLLMプロバイダにバッチされ、速度と効率を向上させることができるからです。
便宜上、このクラスはより単純で使いやすいインターフェイスも公開しています (__call__を使用します)。このインターフェイスは、単一の文字列を受け取り、単一の文字列を返します。

生成

一回の生成の出力。現在LangChainでは、これは生成されたテキストだけですが、将来的にはlog probsなどを含むように拡張される可能性があります。

LLMResult

LLMクラスのgenerateメソッドを呼び出したときの出力です。
generateメソッドは文字列のリストを入力として取るので、これは結果のリストを返します。各結果は生成リストで構成されます(入力文字列ごとにN回の生成を要求できるため)。これはまた、呼び出しに関するプロバイダ固有の情報を含む llm_output 属性を含んでいます。

LLMクラスの使い方 入門編

注意:プログラム実行には、OpenAIのAPIキー(有料)が必要です。

このノートでは、LangChainのLLMクラスの使い方を説明します。

LLMクラスは、LLMとのインタフェースのために設計されたクラスです。たくさんのLLMプロバイダ(OpenAI、Cohere、Hugging Faceなど)がありますが、このクラスはそれらすべての標準インタフェースを提供するように設計されています。このドキュメントのこの部分では、一般的なLLMの機能に焦点を当てます。特定のLLMラッパーで作業する詳細については、How-Toセクションの例を参照してください。

このノートでは、OpenAI LLMラッパーを使いますが、強調されている機能はすべてのLLMタイプに共通です。

Generate Text

LLMが持つ最も基本的な機能は、文字列を渡して文字列を返すという呼び出しの機能です。

from langchain.llms import OpenAI
import os

os.environ["OPENAI_API_KEY"] = "...."

llm = OpenAI(model_name="text-ada-001", n=2, best_of=2)
print(llm("Tell me a joke"))

出力

Why did the chicken cross the road?

To get to the other side!

Generate

より広い意味では、入力リストを指定して呼び出すことで、テキストだけでなく、より完全なレスポンスを返すことができます。この完全な応答には、複数の上位応答や、LLMプロバイダー固有の情報などが含まれます。

from langchain.llms import OpenAI
import os

os.environ["OPENAI_API_KEY"] = "...."

llm = OpenAI(model_name="text-ada-001", n=2, best_of=2)

llm_result = llm.generate(["Tell me a joke", "Tell me a poem"])
len(llm_result.generations)
print("回答1:",llm_result.generations[0],end="\n\n")
print("回答2:",llm_result.generations[1],end="\n\n")
print("すべての回答を表示:",llm_result.generations[1],sep="\n",end="\n\n")
print("プロバイダ情報:",llm_result.llm_output)

出力

回答1: [Generation(text='\n\nWhy did the chicken cross the road?\n\nTo get to the other side!', generation_info={'finish_reason': 'stop', 'logprobs': None}), Generation(text='\n\nWhy did the chicken cross the road?\n\nTo get to the other side.', generation_info={'finish_reason': 'stop', 'logprobs': None})]

回答2: [Generation(text="\n\nIn the eyes of the moon\n\nI have seen a face\n\nThat I will never forget.\n\nIts beauty is so divine\n\nI can't imagine life without it.\n\nIts light is so sweet\n\nI can't imagine life without it.", generation_info={'finish_reason': 'stop', 'logprobs': None}), Generation(text='\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can', generation_info={'finish_reason': 'length', 'logprobs': None})]

すべての回答を表示:
[Generation(text="\n\nIn the eyes of the moon\n\nI have seen a face\n\nThat I will never forget.\n\nIts beauty is so divine\n\nI can't imagine life without it.\n\nIts light is so sweet\n\nI can't imagine life without it.", generation_info={'finish_reason': 'stop', 'logprobs': None}), Generation(text='\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can one\nlive in love\n\nHow can', generation_info={'finish_reason': 'length', 'logprobs': None})]

プロバイダ情報: {'token_usage': {'total_tokens': 359, 'completion_tokens': 351, 'prompt_tokens': 8}}

Number of Tokens

また、そのモデルでテキストの一部が何トークンになるかを推定することもできます。モデルにはコンテキストの長さがあり(トークンが多いほどコストがかかる)、つまり、渡されるテキストの長さを意識する必要があるため、これは便利な機能です。

注意:デフォルトでは、トークンはHuggingFaceトークナイザーを使って推定されることに注意してください。

以下のコードは私の環境では動作しませんでした。。(\tempエラー)23-02-04

llm.get_num_tokens("what a joke")

3

カスタムLLM

このノートでは、独自のLLMやLangChainでサポートされているラッパーとは異なるラッパーを使用したい場合のために、カスタムLLMラッパーを作成する方法を説明します。(本ページでは紹介しません。)

LLMキャッシュ

個々のLLM呼び出しの結果をキャッシュする方法について説明します。


この記事が気に入ったらサポートをしてみませんか?