-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
128 changed files
with
3,124 additions
and
2,067 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
services: | ||
dbqa-executor: | ||
build: | ||
context: ../ | ||
dockerfile: docker/executor/Dockerfile | ||
image: kuwa-executor | ||
environment: | ||
CUSTOM_EXECUTOR_PATH: ./docqa/docqa.py | ||
EXECUTOR_ACCESS_CODE: db-qa | ||
EXECUTOR_NAME: DB QA | ||
volumes: [ "</path/to/vector-database>:/var/database" ] | ||
depends_on: | ||
- kernel | ||
- multi-chat | ||
command: [ | ||
"--api_base_url", "http://web/", | ||
"--access_code", "db-qa" | ||
"--database", "/var/database" | ||
] | ||
restart: unless-stopped | ||
networks: ["backend", "frontend"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
services: | ||
docqa-executor: | ||
build: | ||
context: ../ | ||
dockerfile: docker/executor/Dockerfile | ||
image: kuwa-executor | ||
environment: | ||
CUSTOM_EXECUTOR_PATH: ./docqa/docqa.py | ||
EXECUTOR_ACCESS_CODE: doc-qa;web-qa | ||
EXECUTOR_NAME: DocQA;WebQA | ||
depends_on: | ||
- kernel | ||
- multi-chat | ||
command: [ | ||
"--api_base_url", "http://web/", | ||
"--access_code", "doc-qa", | ||
"--alt_access_code", "web-qa" | ||
] | ||
restart: unless-stopped | ||
networks: ["backend", "frontend"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,37 @@ | ||
#!/bin/sh | ||
#!/bin/bash | ||
set -xeu | ||
|
||
add_executor(){ | ||
if [ -z "${EXECUTOR_NAME:-}" ] || [ -z "${EXECUTOR_ACCESS_CODE:-}" ] | ||
then | ||
return | ||
fi | ||
multi-chat-client add-executor "${EXECUTOR_ACCESS_CODE}" "${EXECUTOR_NAME}" || return 0 | ||
IFS=';' read -r -a access_code_arr <<< "${EXECUTOR_ACCESS_CODE}" | ||
IFS=';' read -r -a name_arr <<< "${EXECUTOR_NAME}" | ||
for idx in "${!name_arr[@]}" | ||
do | ||
access_code="${access_code_arr[idx]}" | ||
name="${name_arr[idx]}" | ||
multi-chat-client add-executor "${access_code}" "${name}" || true | ||
done | ||
} | ||
|
||
if [ "${ADD_EXECUTOR_TO_MULTI_CHAT}" = true ] | ||
then | ||
add_executor | ||
fi | ||
|
||
if [ -z "${CUSTOM_EXECUTOR_PATH:-}" ] | ||
then | ||
exec kuwa-executor ${EXECUTOR_TYPE} \ | ||
--kernel_url ${KERNEL_URL} \ | ||
--access_code ${EXECUTOR_ACCESS_CODE} \ | ||
$@ 2>&1 | ||
$@ 2>&1 | ||
else | ||
dir_name="$(dirname "${CUSTOM_EXECUTOR_PATH}")" | ||
file_name="$(basename "${CUSTOM_EXECUTOR_PATH}")" | ||
cd ${dir_name} | ||
exec python "${file_name}" \ | ||
--kernel_url ${KERNEL_URL} \ | ||
$@ 2>&1 | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web_data/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
Doc QA | ||
--- | ||
A Retrieval-Augmented Generation Executor. | ||
|
||
## Production Deployment | ||
|
||
This executor has two configurations. | ||
1. DocQA/WebQA: Retrieve information from the documents or web pages | ||
2. DatabaseQA(DBQA): Retrieve information from a pre-built vector database | ||
|
||
### Prerequisite | ||
1. Install the dependency | ||
```sh | ||
cd src/executor/webqa | ||
pip install -r requirements.txt | ||
``` | ||
2. You can obtain the KUWA_TOKEN from the website's profile > API Token Management > Kuwa Chat API Token | ||
|
||
### DocQA/WebQA | ||
``` | ||
python ./docqa.py --access_code doc-qa --api_base_url http://localhost/ --api_key <KUWA_TOKEN> [--model <MODEL_NAME>] | ||
``` | ||
|
||
### DBQA | ||
``` | ||
python ./docqa.py --access_code dbqa --api_base_url http://localhost/ --api_key <KUWA_TOKEN> [--model <MODEL_NAME>] --database /path/to/pre-built/vector-db | ||
``` |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions
4
src/executor/working/docqa/README.md → src/executor/docqa/archive/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
#!/bin/python3 | ||
# -#- coding: UTF-8 -*- | ||
|
||
import os | ||
import re | ||
import sys | ||
import logging | ||
import asyncio | ||
import functools | ||
import itertools | ||
import requests | ||
import json | ||
import i18n | ||
sys.path.append(os.path.dirname(os.path.abspath(__file__))) | ||
|
||
from typing import Generator | ||
from urllib.parse import urljoin | ||
from kuwa.executor import LLMExecutor | ||
|
||
from src.docqa import DocQa | ||
from src.kuwa_llm_client import KuwaLlmClient | ||
from src.document_store import DocumentStore | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
class NoUrlException(Exception): | ||
def __init__(self, msg): | ||
self.msg = msg | ||
def __str__(self): | ||
return self.msg | ||
|
||
class DocQaExecutor(LLMExecutor): | ||
def __init__(self): | ||
super().__init__() | ||
|
||
def _try_register(self): | ||
super()._try_register() | ||
if self.alt_access_code: | ||
resp = requests.post( | ||
url=urljoin(self.kernel_url, f"{self.executor_iface_version}/worker/register"), | ||
data={"name": self.alt_access_code, "endpoint": self.get_reg_endpoint()} | ||
) | ||
if not resp.ok or resp.text == "Failed": | ||
raise RuntimeWarning("The server failed to register to kernel.") | ||
|
||
def _shut_down(self): | ||
super()._shut_down() | ||
if self.alt_access_code: | ||
try: | ||
response = requests.post( | ||
urljoin(self.kernel_url, f"{self.executor_iface_version}/worker/unregister"), | ||
data={"name": self.alt_access_code,"endpoint": self.get_reg_endpoint()} | ||
) | ||
if not response.ok or response.text == "Failed": | ||
raise RuntimeWarning() | ||
else: | ||
logger.info("Unregistered from kernel.") | ||
except requests.exceptions.ConnectionError as e: | ||
logger.warning("Failed to unregister from kernel") | ||
|
||
def extend_arguments(self, parser): | ||
parser.add_argument('--lang', default="en", help='The language code to internationalize the aplication. See \'lang/\'') | ||
parser.add_argument('--database', default=None, type=str, help='The path the the pre-built database.') | ||
parser.add_argument('--api_base_url', default="http://127.0.0.1/", help='The API base URL of Kuwa multi-chat WebUI') | ||
parser.add_argument('--api_key', default=None, help='The API authentication token of Kuwa multi-chat WebUI') | ||
parser.add_argument('--limit', default=3072, type=int, help='The limit of the LLM\'s context window') | ||
parser.add_argument('--model', default=None, help='The model name (access code) on Kuwa multi-chat WebUI') | ||
parser.add_argument('--mmr_k', default=6, type=int, help='Number of chunk to retrieve after Maximum Marginal Relevance (MMR).') | ||
parser.add_argument('--mmr_fetch_k', default=12, type=int, help='Number of chunk to retrieve before Maximum Marginal Relevance (MMR).') | ||
parser.add_argument('--chunk_size', default=512, type=int, help='The charters in the chunk.') | ||
parser.add_argument('--chunk_overlap', default=128, type=int, help='The overlaps between chunks.') | ||
parser.add_argument('--alt_access_code', default=None, type=str, help='The alternate access code.') | ||
|
||
def setup(self): | ||
i18n.load_path.append(f'lang/{self.args.lang}/') | ||
i18n.config.set("error_on_missing_translation", True) | ||
i18n.config.set("locale", self.args.lang) | ||
|
||
self.pre_built_db = self.args.database | ||
self.llm = KuwaLlmClient( | ||
base_url = self.args.api_base_url, | ||
kernel_base_url = self.kernel_url, | ||
model=self.args.model, | ||
auth_token=self.args.api_key | ||
) | ||
self.document_store = DocumentStore( | ||
mmr_k = self.args.mmr_k, | ||
mmr_fetch_k = self.args.mmr_fetch_k, | ||
chunk_size = self.args.chunk_size, | ||
chunk_overlap = self.args.chunk_overlap | ||
) | ||
self.docqa = DocQa( | ||
document_store = self.document_store, | ||
vector_db = self.pre_built_db, | ||
llm = self.llm, | ||
lang = self.args.lang | ||
) | ||
self.alt_access_code = self.args.alt_access_code | ||
self.proc = False | ||
|
||
def extract_last_url(self, chat_history: list): | ||
""" | ||
Find the latest URL provided by the user and trim the chat history to there. | ||
""" | ||
|
||
url = None | ||
begin_index = 0 | ||
user_records = list(filter(lambda x: not x["isbot"], chat_history)) | ||
for i, record in enumerate(reversed(user_records)): | ||
|
||
urls_in_msg = re.findall(r'^(https?://[^\s]+)$', record["msg"]) | ||
if len(urls_in_msg) != 0: | ||
url = urls_in_msg[-1] | ||
begin_index = len(chat_history) - i - 1 | ||
break | ||
|
||
return url, chat_history[begin_index:] | ||
|
||
async def llm_compute(self, data): | ||
chat_history = json.loads(data.get("input")) | ||
auth_token = data.get("user_token") or self.args.api_key | ||
url = None | ||
|
||
try: | ||
if self.pre_built_db == None: | ||
url, chat_history = self.extract_last_url(chat_history) | ||
if url == None : raise NoUrlException(i18n.t('docqa.no_url_exception')) | ||
|
||
chat_history = [{"isbot": False, "msg": None}] + chat_history[1:] | ||
self.proc = True | ||
response_generator = self.docqa.process(urls=[url], chat_history=chat_history, auth_token=auth_token) | ||
async for reply in response_generator: | ||
if not self.proc: | ||
await response_generator.aclose() | ||
yield reply | ||
|
||
except NoUrlException as e: | ||
yield str(e) | ||
|
||
except Exception as e: | ||
await asyncio.sleep(2) # To prevent SSE error of web page. | ||
logger.exception('Unexpected error') | ||
yield i18n.t("docqa.default_exception_msg") | ||
|
||
async def abort(self): | ||
if self.proc: | ||
self.proc = False | ||
logger.debug("aborted") | ||
return "Aborted" | ||
return "No process to abort" | ||
|
||
if __name__ == "__main__": | ||
executor = DocQaExecutor() | ||
executor.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
en: | ||
no_url_exception: No URL found. | ||
default_exception_msg: An error occurred, please try again or contact the administrator. | ||
summary_prompt: "Please provide a summary of this article:" | ||
error_fetching_document: An error occurred while trying to fetch the document {}. Please make sure the submitted document exists and is publicly available. | ||
summary_question: When, where, what, outcome, summary | ||
summary_prefix: "Here is a summary of the article:" |
7 changes: 7 additions & 0 deletions
7
src/executor/docqa/lang/en/prompt_template/llm_input_qa.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Please answer the questions based on the content below.{{#ref}}If there are references, please include them at the end of the answer.{{/ref}} | ||
|
||
{{#docs}}{{page_content}} | ||
|
||
{{/docs}} | ||
|
||
Question: {{question}} |
10 changes: 10 additions & 0 deletions
10
src/executor/docqa/lang/en/prompt_template/llm_input_summary.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
Article Content: | ||
|
||
{{#docs}}{{page_content}} | ||
|
||
{{/docs}} | ||
|
||
|
||
Please provide a highlight summary of the above article. | ||
|
||
Summary: |
1 change: 1 addition & 0 deletions
1
src/executor/docqa/lang/en/prompt_template/llm_input_translate.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Translate to English: {{question}} |
Oops, something went wrong.