반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

https://python.langchain.com/docs/expression_language/how_to/map

 

Use RunnableParallel/RunnableMap | 🦜️🔗 Langchain

RunnableParallel (aka. RunnableMap) makes it easy to execute multiple Runnables in parallel, and to return the output of these Runnables as a map.

python.langchain.com

 

Use RunnableParallel/RunnableMap

RunnableParallel (aka. RunnableMap) makes it easy to execute multiple Runnables in parallel, and to return the output of these Runnables as a map.

 

RunnableParallel(일명 RunnableMap)을 사용하면 여러 Runnable을 병렬로 쉽게 실행하고 이러한 Runnable의 출력을 맵으로 반환할 수 있습니다.

 

from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnableParallel


model = ChatOpenAI()
joke_chain = ChatPromptTemplate.from_template("tell me a joke about {topic}") | model
poem_chain = ChatPromptTemplate.from_template("write a 2-line poem about {topic}") | model

map_chain = RunnableParallel(joke=joke_chain, poem=poem_chain)

map_chain.invoke({"topic": "bear"})

 

이 코드는 ChatOpenAI 모델을 사용하여 주제에 관한 농담 및 시를 생성하는 예시를 제공합니다. 

  1. ChatOpenAI 모델 설정:
    • ChatOpenAI()를 사용하여 ChatOpenAI 모델을 설정합니다. 이 모델을 사용하여 텍스트 생성 작업을 수행할 것입니다.
  2. joke_chain 및 poem_chain 설정:
    • joke_chain은 "tell me a joke about {topic}"이라는 대화 템플릿을 사용하여 농담을 생성하는 대화 체인을 설정합니다.
    • poem_chain은 "write a 2-line poem about {topic}"이라는 대화 템플릿을 사용하여 시를 생성하는 대화 체인을 설정합니다.
  3. RunnableParallel 설정:
    • RunnableParallel은 여러 개의 Runnable을 병렬로 실행하고 결과를 모으는 데 사용됩니다. 이 경우 "joke" 및 "poem" 두 개의 Runnable을 설정하여 두 가지 다른 종류의 내용을 생성합니다.
  4. map_chain 호출:
    • map_chain.invoke({"topic": "bear"})는 "map_chain" 대화 체인을 호출하고 "{topic}" 변수를 "bear"로 설정하여 주제가 "bear"에 관한 농담 및 시를 생성합니다.

이 코드는 ChatOpenAI 모델을 사용하여 주제별로 농담과 시를 생성하는 방법을 보여줍니다. 결과는 "map_chain"을 통해 출력됩니다.

 

    {'joke': AIMessage(content="Why don't bears wear shoes? \n\nBecause they have bear feet!", additional_kwargs={}, example=False),
     'poem': AIMessage(content="In woodland depths, bear prowls with might,\nSilent strength, nature's sovereign, day and night.", additional_kwargs={}, example=False)}

Manipulating outputs/inputs

 

Maps can be useful for manipulating the output of one Runnable to match the input format of the next Runnable in a sequence.

 

맵은 시퀀스에서 다음 Runnable의 입력 형식과 일치하도록 하나의 Runnable의 출력을 조작하는 데 유용할 수 있습니다.

 

from langchain.embeddings import OpenAIEmbeddings
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough
from langchain.vectorstores import FAISS

vectorstore = FAISS.from_texts(["harrison worked at kensho"], embedding=OpenAIEmbeddings())
retriever = vectorstore.as_retriever()
template = """Answer the question based only on the following context:
{context}

Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)

retrieval_chain = (
    {"context": retriever, "question": RunnablePassthrough()} 
    | prompt 
    | model 
    | StrOutputParser()
)

retrieval_chain.invoke("where did harrison work?")

 

이 코드는 특정 문맥에서 주어진 질문에 답변하기 위해 FAISS 벡터 저장소(FAISS.from_texts)를 사용하는 예시를 제공합니다. 

  1. OpenAIEmbeddings 및 FAISS 벡터 저장소 설정:
    • OpenAIEmbeddings()를 사용하여 OpenAI의 임베딩을 설정합니다.
    • FAISS.from_texts()를 사용하여 "harrison worked at kensho"라는 텍스트를 포함하는 FAISS 벡터 저장소를 설정합니다. 이 벡터 저장소는 주어진 텍스트의 임베딩을 저장합니다.
  2. 대화 템플릿 설정:
    • template는 대화 템플릿을 정의하는 문자열로, "context" 및 "question" 변수를 포함합니다. 이 템플릿을 사용하여 문맥과 질문을 결합하는데 사용됩니다.
  3. Retrieval Chain 설정:
    • retriever는 FAISS 벡터 저장소를 검색하는 데 사용되는 검색자(retriever)입니다.
    • {"context": retriever, "question": RunnablePassthrough()}는 문맥과 질문을 정의하는 변수를 설정합니다. "context" 변수에는 FAISS 벡터 저장소를 지정하고 "question" 변수는 원본 질문을 전달합니다.
    • prompt | model | StrOutputParser()는 이전에 설정한 템플릿을 사용하여 모델을 호출하고 출력을 문자열로 변환하는 대화 체인을 설정합니다.
  4. Retrieval Chain 호출:
    • retrieval_chain.invoke("where did harrison work?")는 "retrieval_chain" 대화 체인을 호출하고 "where did harrison work?"라는 질문을 수행합니다.

이 코드는 FAISS 벡터 저장소를 사용하여 주어진 문맥에서 주어진 질문에 대한 답변을 검색하고 반환하는 방법을 보여줍니다. 결과는 "retrieval_chain"을 통해 출력됩니다.

 

    'Harrison worked at Kensho.'

 

Here the input to prompt is expected to be a map with keys "context" and "question". The user input is just the question. So we need to get the context using our retriever and passthrough the user input under the "question" key.

 

여기서 프롬프트에 대한 입력은 "컨텍스트" 및 "질문" 키가 있는 맵일 것으로 예상됩니다. 사용자 입력은 단지 질문일 뿐입니다. 따라서 검색기를 사용하여 컨텍스트를 가져와야 하며 "질문" 키 아래에 있는 사용자 입력을 통과해야 합니다.

 

Note that when composing a RunnableMap when another Runnable we don't even need to wrap our dictionary in the RunnableMap class — the type conversion is handled for us.

 

다른 Runnable이 있을 때 RunnableMap을 구성할 때 사전을 RunnableMap 클래스로 래핑할 필요조차 없습니다. 유형 변환이 자동으로 처리됩니다.

 

Parallelism

RunnableMaps are also useful for running independent processes in parallel, since each Runnable in the map is executed in parallel. For example, we can see our earlier joke_chain, poem_chain and map_chain all have about the same runtime, even though map_chain executes both of the other two.

 

RunnableMaps는 맵의 각 Runnable이 병렬로 실행되므로 독립적인 프로세스를 병렬로 실행하는 데에도 유용합니다. 예를 들어 이전 joke_chain, poem_chain 및 map_chain은 map_chain이 다른 두 가지를 모두 실행하더라도 거의 동일한 런타임을 갖고 있음을 알 수 있습니다.

 

joke_chain.invoke({"topic": "bear"})
    958 ms ± 402 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
poem_chain.invoke({"topic": "bear"})
    1.22 s ± 508 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
map_chain.invoke({"topic": "bear"})
    1.15 s ± 119 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

반응형