LangChainは、LM(Large Language)を便利に使用するのに役立つフレームワークです。
LangChain Basic では、LangChain の構成ごとにサンプルコードを説明します。
Falcon FMで作成したSageMaker EndpointにLangChainを適用する方法について説明します。 SageMaker JumpStartでFalcon FMをインストールすることで得られたSageMaker Endpoint(例えば、jumpstart-dft-hf-llm-falcon-7b-instruct-bf16)を使用します。
Falconの入力と出力を参照して、以下のようにContentHandlerのtransform_input、transform_outputを登録します。
from langchain import PromptTemplate , SagemakerEndpoint
from langchain . llms . sagemaker_endpoint import LLMContentHandler
class ContentHandler ( LLMContentHandler ):
content_type = "application/json"
accepts = "application/json"
def transform_input ( self , prompt : str , model_kwargs : dict ) -> bytes :
input_str = json . dumps ({ 'inputs' : prompt , 'parameters' : model_kwargs })
return input_str . encode ( 'utf-8' )
def transform_output ( self , output : bytes ) -> str :
response_json = json . loads ( output . read (). decode ( "utf-8" ))
return response_json [ 0 ][ "generated_text" ]
以下のように、endpoint_name、aws_region、parameters、content_handlerを使用してSagemaker Endpointのllmを登録します。
endpoint_name = 'jumpstart-dft-hf-llm-falcon-7b-instruct-bf16'
aws_region = boto3 . Session (). region_name
parameters = {
"max_new_tokens" : 300
}
content_handler = ContentHandler ()
llm = SagemakerEndpoint (
endpoint_name = endpoint_name ,
region_name = aws_region ,
model_kwargs = parameters ,
content_handler = content_handler
)
llmの動作は以下のように確認できます。
llm ( "Tell me a joke" )
この時の結果は以下の通りです。
I once told a joke to a friend, but it didn't work. He just looked
Web loader - langchainを使用してWebページをロードできます。
from langchain . document_loaders import WebBaseLoader
from langchain . indexes import VectorstoreIndexCreator
loader = WebBaseLoader ( "https://lilianweng.github.io/posts/2023-06-23-agent/" )
index = VectorstoreIndexCreator (). from_loaders ([ loader ])
以下のように、テンプレートを定義した後にLLMChainを定義した後に実行することができます。詳細はlangchain-sagemaker-endpoint-Q&A.ipynbを参照してください。
from langchain import PromptTemplate , LLMChain
template = "Tell me a {adjective} joke about {content}."
prompt = PromptTemplate . from_template ( template )
llm_chain = LLMChain ( prompt = prompt , llm = llm )
outputText = llm_chain . run ( adjective = "funny" , content = "chickens" )
print ( outputText )
この時の結果は以下の通りです。
Why did the chicken cross the playground? To get to the other slide!
langchain.chains.question_answeringを使用してDocumentに対してQuestion / Answeringを実行します。詳細はlangchain-sagemaker-endpoint-Q&A.ipynbを参照してください。
prompt のテンプレートを定義します。
template = """Use the following pieces of context to answer the question at the end.
{context}
Question: {question}
Answer:"""
prompt = PromptTemplate (
template = template , input_variables = [ "context" , "question" ]
)
langchain.docstore.documentを使用してDocumentを作成します。
from langchain . docstore . document import Document
example_doc_1 = """
Peter and Elizabeth took a taxi to attend the night party in the city. While in the party, Elizabeth collapsed and was rushed to the hospital.
Since she was diagnosed with a brain injury, the doctor told Peter to stay besides her until she gets well.
Therefore, Peter stayed with her at the hospital for 3 days without leaving.
"""
docs = [
Document (
page_content = example_doc_1 ,
)
]
これでQuestion / Answeringを実行します。
from langchain . chains . question_answering import load_qa_chain
question = "How long was Elizabeth hospitalized?"
chain = load_qa_chain ( prompt = prompt , llm = llm )
output = chain ({ "input_documents" : docs , "question" : question }, return_only_outputs = True )
print ( output )
この時の結果は以下の通りです。
{'output_text': ' 3 days'}
langchain-sagemaker-endpoint-pdf-summary.ipynb では、Falcon FM ベースの SageMaker Endpoint で PDF Summery を行う方法について説明しています。
まず、PyPDF2を使ってS3に保存されているPDFファイルを読み取り、Textを抽出します。
import PyPDF2
from io import BytesIO
sess = sagemaker . Session ()
s3_bucket = sess . default_bucket ()
s3_prefix = 'docs'
s3_file_name = '2016-3series.pdf' # S3의 파일명
s3r = boto3 . resource ( "s3" )
doc = s3r . Object ( s3_bucket , s3_prefix + '/' + s3_file_name )
contents = doc . get ()[ 'Body' ]. read ()
reader = PyPDF2 . PdfReader ( BytesIO ( contents ))
raw_text = []
for page in reader . pages :
raw_text . append ( page . extract_text ())
contents = ' n ' . join ( raw_text )
new_contents = str ( contents ). replace ( " n " , " " )
ドキュメントのサイズが大きいため、RecursiveCharacterTextSplitterを使用してチャンク単位で分割してDocumentに保存します。その後、load_summarize_chainを使用して要約します。
from langchain . text_splitter import CharacterTextSplitter
from langchain . text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter ( chunk_size = 1000 , chunk_overlap = 0 )
texts = text_splitter . split_text ( new_contents )
from langchain . docstore . document import Document
docs = [
Document (
page_content = t
) for t in texts [: 3 ]
]
from langchain . chains . summarize import load_summarize_chain
from langchain . prompts import PromptTemplate
prompt_template = """Write a concise summary of the following:
{text}
CONCISE SUMMARY """
PROMPT = PromptTemplate ( template = prompt_template , input_variables = [ "text" ])
chain = load_summarize_chain ( llm , chain_type = "stuff" , prompt = PROMPT )
summary = chain . run ( docs )
from langchain import Bedrock
from langchain . embeddings import BedrockEmbeddings
llm = Bedrock ()
print ( llm ( "explain GenAI" ))
LangChain Docs
LangChain - github
SageMaker Endpoint
2-Lab02-RAG-LLM
AWS Kendra Langchain Extensions
QA and Chat over Documents
LangChain - Modules - Language models - LLMs - Integration - SageMakerEndpoint
LangChain - EcoSystem - Integration - SageMaker Endpoint
Ingest knowledge base data ta Vector DB