multiple retreival in parralel (#9174)

This commit is contained in:
Harrison Chase 2023-08-13 10:03:54 -07:00 committed by GitHub
parent cdfe2c96c5
commit 8d69dacdf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 293 additions and 2 deletions

View File

@ -41,7 +41,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 1,
"id": "466b65b3",
"metadata": {},
"outputs": [],
@ -256,6 +256,131 @@
"source": [
"await chain.abatch([{\"topic\": \"bears\"}])"
]
},
{
"cell_type": "markdown",
"id": "0a1c409d",
"metadata": {},
"source": [
"## Parallelism\n",
"\n",
"Let's take a look at how LangChain Expression Language support parralel requests as much as possible. For example, when using a RunnableMapping (often written as a dictionary) it executes each element in parralel."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "e3014c7a",
"metadata": {},
"outputs": [],
"source": [
"from langchain.schema.runnable import RunnableMap\n",
"chain1 = ChatPromptTemplate.from_template(\"tell me a joke about {topic}\") | model\n",
"chain2 = ChatPromptTemplate.from_template(\"write a short (2 line) poem about {topic}\") | model\n",
"combined = RunnableMap({\n",
" \"joke\": chain1,\n",
" \"poem\": chain2,\n",
"})"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "08044c0a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 31.7 ms, sys: 8.59 ms, total: 40.3 ms\n",
"Wall time: 1.05 s\n"
]
},
{
"data": {
"text/plain": [
"AIMessage(content=\"Why don't bears like fast food?\\n\\nBecause they can't catch it!\", additional_kwargs={}, example=False)"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%time\n",
"chain1.invoke({\"topic\": \"bears\"})"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "22c56804",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 42.9 ms, sys: 10.2 ms, total: 53 ms\n",
"Wall time: 1.93 s\n"
]
},
{
"data": {
"text/plain": [
"AIMessage(content=\"In forest's embrace, bears roam free,\\nSilent strength, nature's majesty.\", additional_kwargs={}, example=False)"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%time\n",
"chain2.invoke({\"topic\": \"bears\"})"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "4fff4cbb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 96.3 ms, sys: 20.4 ms, total: 117 ms\n",
"Wall time: 1.1 s\n"
]
},
{
"data": {
"text/plain": [
"{'joke': AIMessage(content=\"Why don't bears wear socks?\\n\\nBecause they have bear feet!\", additional_kwargs={}, example=False),\n",
" 'poem': AIMessage(content=\"In forest's embrace,\\nMajestic bears leave their trace.\", additional_kwargs={}, example=False)}"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%time\n",
"combined.invoke({\"topic\": \"bears\"})"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fab75d1d",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
@ -274,7 +399,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
"version": "3.10.1"
}
},
"nbformat": 4,

View File

@ -0,0 +1,166 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "66398b75",
"metadata": {},
"source": [
"# Multiple Retrieval Sources\n",
"\n",
"Often times you may want to do retrieval over multiple sources. These can be different vectorstores (where one contains information about topic X and the other contains info about topic Y). They could also be completely different databases altogether!\n",
"\n",
"A key part is is doing as much of the retrieval in parrelel as possible. This will keep the latency as low as possible. Luckily, [LangChain Expression Language](../../) supports parrellism out of the box.\n",
"\n",
"Let's take a look where we do retrieval over a SQL database and a vectorstore."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "1c5bab6a",
"metadata": {},
"outputs": [],
"source": [
"from langchain.chat_models import ChatOpenAI"
]
},
{
"cell_type": "markdown",
"id": "43a6210f",
"metadata": {},
"source": [
"## Set up SQL query"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "ab3bf8ba",
"metadata": {},
"outputs": [],
"source": [
"from langchain.utilities import SQLDatabase\n",
"from langchain.chains import create_sql_query_chain\n",
"\n",
"db = SQLDatabase.from_uri(\"sqlite:///../../../../../notebooks/Chinook.db\")\n",
"query_chain = create_sql_query_chain(ChatOpenAI(temperature=0), db)"
]
},
{
"cell_type": "markdown",
"id": "a8585120",
"metadata": {},
"source": [
"## Set up vectorstore"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "b916b0b0",
"metadata": {},
"outputs": [],
"source": [
"from langchain.indexes import VectorstoreIndexCreator\n",
"from langchain.schema.document import Document\n",
"index_creator = VectorstoreIndexCreator()\n",
"index = index_creator.from_documents([Document(page_content=\"Foo\")])\n",
"retriever = index.vectorstore.as_retriever()"
]
},
{
"cell_type": "markdown",
"id": "a3b91816",
"metadata": {},
"source": [
"## Combine"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "4423211c",
"metadata": {},
"outputs": [],
"source": [
"from langchain.prompts import ChatPromptTemplate\n",
"\n",
"system_message = \"\"\"Use the information from the below two sources to answer any questions.\n",
"\n",
"Source 1: a SQL database about employee data\n",
"<source1>\n",
"{source1}\n",
"</source1>\n",
"\n",
"Source 2: a text database of random information\n",
"<source2>\n",
"{source2}\n",
"</source2>\n",
"\"\"\"\n",
"\n",
"prompt = ChatPromptTemplate.from_messages([(\"system\", system_message), (\"human\", \"{question}\")])"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "7ff87e0c",
"metadata": {},
"outputs": [],
"source": [
"full_chain = {\n",
" \"source1\": {\"question\": lambda x: x[\"question\"]} | query_chain | db.run,\n",
" \"source2\": (lambda x: x['question']) | retriever,\n",
" \"question\": lambda x: x['question'],\n",
"} | prompt | ChatOpenAI()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "d6706410",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Number of requested results 4 is greater than number of elements in index 1, updating n_results = 1\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"content='There are 8 employees.' additional_kwargs={} example=False\n"
]
}
],
"source": [
"response = full_chain.invoke({\"question\":\"How many Employees are there\"})\n",
"print(response)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}