From 5d4556176150daa723a586876fc91502fa0df255 Mon Sep 17 00:00:00 2001 From: dilyararimovna Date: Mon, 10 Jul 2023 18:42:43 +0300 Subject: [PATCH 1/4] feat: use dream_faq in dream_openai_persona_prompted --- .../environment.yml | 2 +- .../dream_persona_openai_prompted/service.yml | 2 +- .../dream_persona_openai_prompted/dev.yml | 13 +++++- .../docker-compose.override.yml | 45 ++++++++++++++++++- .../pipeline_conf.json | 21 +++++++++ 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/annotators/prompt_selector/service_configs/dream_persona_openai_prompted/environment.yml b/annotators/prompt_selector/service_configs/dream_persona_openai_prompted/environment.yml index 30874786aa..d7f3b4c9ff 100644 --- a/annotators/prompt_selector/service_configs/dream_persona_openai_prompted/environment.yml +++ b/annotators/prompt_selector/service_configs/dream_persona_openai_prompted/environment.yml @@ -1,5 +1,5 @@ SERVICE_PORT: 8135 SERVICE_NAME: prompt_selector N_SENTENCES_TO_RETURN: 3 -PROMPTS_TO_CONSIDER: dream_persona +PROMPTS_TO_CONSIDER: dream_persona,dream_faq FLASK_APP: server diff --git a/annotators/prompt_selector/service_configs/dream_persona_openai_prompted/service.yml b/annotators/prompt_selector/service_configs/dream_persona_openai_prompted/service.yml index 86da9d89c6..a341cacdee 100644 --- a/annotators/prompt_selector/service_configs/dream_persona_openai_prompted/service.yml +++ b/annotators/prompt_selector/service_configs/dream_persona_openai_prompted/service.yml @@ -10,7 +10,7 @@ compose: SERVICE_PORT: 8135 SERVICE_NAME: prompt_selector N_SENTENCES_TO_RETURN: 3 - PROMPTS_TO_CONSIDER: dream_persona + PROMPTS_TO_CONSIDER: dream_persona,dream_faq FLASK_APP: server context: . dockerfile: ./annotators/prompt_selector/Dockerfile diff --git a/assistant_dists/dream_persona_openai_prompted/dev.yml b/assistant_dists/dream_persona_openai_prompted/dev.yml index 3176123de7..1aeea31c95 100644 --- a/assistant_dists/dream_persona_openai_prompted/dev.yml +++ b/assistant_dists/dream_persona_openai_prompted/dev.yml @@ -52,5 +52,16 @@ services: - "./common:/src/common" ports: - 8162:8162 - + dff-dream-faq-prompted-skill: + volumes: + - "./skills/dff_template_prompted_skill:/src" + - "./common:/src/common" + ports: + - 8170:8170 + openai-api-chatgpt-16k: + volumes: + - "./services/openai_api_lm:/src" + - "./common:/src/common" + ports: + - 8167:8167 version: "3.7" diff --git a/assistant_dists/dream_persona_openai_prompted/docker-compose.override.yml b/assistant_dists/dream_persona_openai_prompted/docker-compose.override.yml index 4b14726a0b..4bd621a727 100644 --- a/assistant_dists/dream_persona_openai_prompted/docker-compose.override.yml +++ b/assistant_dists/dream_persona_openai_prompted/docker-compose.override.yml @@ -4,7 +4,8 @@ services: environment: WAIT_HOSTS: "sentseg:8011, ranking-based-response-selector:8002, combined-classification:8087, sentence-ranker:8128, prompt-selector:8135, openai-api-chatgpt:8145, - dff-dream-persona-chatgpt-prompted-skill:8137" + dff-dream-persona-chatgpt-prompted-skill:8137, dff-dream-faq-prompted-skill:8170, + openai-api-chatgpt-16k:8167" WAIT_HOSTS_TIMEOUT: ${WAIT_TIMEOUT:-1000} HIGH_PRIORITY_INTENTS: 1 RESTRICTION_FOR_SENSITIVE_CASE: 1 @@ -75,7 +76,7 @@ services: SERVICE_PORT: 8135 SERVICE_NAME: prompt_selector N_SENTENCES_TO_RETURN: 3 - PROMPTS_TO_CONSIDER: dream_persona + PROMPTS_TO_CONSIDER: dream_persona,dream_faq context: . dockerfile: ./annotators/prompt_selector/Dockerfile command: flask run -h 0.0.0.0 -p 8135 @@ -164,4 +165,44 @@ services: reservations: memory: 128M + dff-dream-faq-prompted-skill: + env_file: [ .env,.env_secret ] + build: + args: + SERVICE_PORT: 8170 + SERVICE_NAME: dff_dream_faq_prompted_skill + PROMPT_FILE: common/prompts/dream_faq.json + GENERATIVE_SERVICE_URL: http://openai-api-chatgpt-16k:8167/respond + GENERATIVE_SERVICE_CONFIG: openai-chatgpt.json + GENERATIVE_TIMEOUT: 120 + N_UTTERANCES_CONTEXT: 7 + ENVVARS_TO_SEND: OPENAI_API_KEY,OPENAI_ORGANIZATION + context: . + dockerfile: ./skills/dff_template_prompted_skill/Dockerfile + deploy: + resources: + limits: + memory: 128M + reservations: + memory: 128M + + openai-api-chatgpt-16k: + env_file: [ .env ] + build: + args: + SERVICE_PORT: 8167 + SERVICE_NAME: openai_api_chatgpt_16k + PRETRAINED_MODEL_NAME_OR_PATH: gpt-3.5-turbo-16k + context: . + dockerfile: ./services/openai_api_lm/Dockerfile + command: flask run -h 0.0.0.0 -p 8167 + environment: + - FLASK_APP=server + deploy: + resources: + limits: + memory: 500M + reservations: + memory: 100M + version: '3.7' diff --git a/assistant_dists/dream_persona_openai_prompted/pipeline_conf.json b/assistant_dists/dream_persona_openai_prompted/pipeline_conf.json index 14bbdb176e..e956c24af6 100644 --- a/assistant_dists/dream_persona_openai_prompted/pipeline_conf.json +++ b/assistant_dists/dream_persona_openai_prompted/pipeline_conf.json @@ -225,6 +225,27 @@ "component": "components/uYkoK0vRp4bbIg9akI1yw.yml", "service": "skills/dummy_skill/service_configs/agent" } + }, + "dff_dream_faq_prompted_skill": { + "connector": { + "protocol": "http", + "timeout": 120.0, + "url": "http://dff-dream-faq-prompted-skill:8170/respond" + }, + "dialog_formatter": { + "name": "state_formatters.dp_formatters:dff_prompted_skill_formatter", + "skill_name": "dff_dream_faq_prompted_skill" + }, + "response_formatter": "state_formatters.dp_formatters:skill_with_attributes_formatter_service", + "previous_services": [ + "skill_selectors" + ], + "state_manager_method": "add_hypothesis", + "is_enabled": true, + "source": { + "component": "components/jFmKPqMJh0.yml", + "service": "skills/dff_template_prompted_skill/service_configs/dff-dream-faq-prompted-skill" + } } }, "candidate_annotators": { From 7f472b9430befe99681c7438de2f1646a04e6864 Mon Sep 17 00:00:00 2001 From: "Dilyara Zharikova (Baymurzina)" Date: Mon, 10 Jul 2023 20:20:47 +0300 Subject: [PATCH 2/4] Feat/llm based resp selector dream (#521) * fix: utilize llm_based_resp_selector in dream * fix: use google api --- .../dream_persona_openai_prompted/dev.yml | 6 +++--- .../docker-compose.override.yml | 21 ++++++++++--------- .../pipeline_conf.json | 6 +++--- .../connector.py | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/assistant_dists/dream_persona_openai_prompted/dev.yml b/assistant_dists/dream_persona_openai_prompted/dev.yml index 1aeea31c95..04a344bbe0 100644 --- a/assistant_dists/dream_persona_openai_prompted/dev.yml +++ b/assistant_dists/dream_persona_openai_prompted/dev.yml @@ -10,12 +10,12 @@ services: - "./annotators/SentSeg:/src" ports: - 8011:8011 - ranking-based-response-selector: + llm-based-response-selector: volumes: - - "./response_selectors/ranking_based_response_selector:/src" + - "./response_selectors/llm_based_response_selector:/src" - "./common:/src/common" ports: - - 8002:8002 + - 8003:8003 combined-classification: volumes: - "./common:/src/common" diff --git a/assistant_dists/dream_persona_openai_prompted/docker-compose.override.yml b/assistant_dists/dream_persona_openai_prompted/docker-compose.override.yml index 4bd621a727..af7698a54d 100644 --- a/assistant_dists/dream_persona_openai_prompted/docker-compose.override.yml +++ b/assistant_dists/dream_persona_openai_prompted/docker-compose.override.yml @@ -2,7 +2,7 @@ services: agent: command: sh -c 'bin/wait && python -m deeppavlov_agent.run agent.pipeline_config=assistant_dists/dream_persona_openai_prompted/pipeline_conf.json' environment: - WAIT_HOSTS: "sentseg:8011, ranking-based-response-selector:8002, combined-classification:8087, + WAIT_HOSTS: "sentseg:8011, llm-based-response-selector:8003, combined-classification:8087, sentence-ranker:8128, prompt-selector:8135, openai-api-chatgpt:8145, dff-dream-persona-chatgpt-prompted-skill:8137, dff-dream-faq-prompted-skill:8170, openai-api-chatgpt-16k:8167" @@ -45,21 +45,22 @@ services: reservations: memory: 2G - ranking-based-response-selector: - env_file: [ .env ] + llm-based-response-selector: + env_file: [ .env,.env_secret ] build: args: - SERVICE_PORT: 8002 + SERVICE_PORT: 8003 SERVICE_NAME: response_selector LANGUAGE: EN - SENTENCE_RANKER_ANNOTATION_NAME: sentence_ranker - SENTENCE_RANKER_SERVICE_URL: http://sentence-ranker:8128/respond - SENTENCE_RANKER_TIMEOUT: 3 - N_UTTERANCES_CONTEXT: 5 + GENERATIVE_SERVICE_URL: http://openai-api-chatgpt:8145/respond + GENERATIVE_SERVICE_CONFIG: openai-chatgpt.json + GENERATIVE_TIMEOUT: 120 + N_UTTERANCES_CONTEXT: 7 + ENVVARS_TO_SEND: OPENAI_API_KEY,OPENAI_ORGANIZATION FILTER_TOXIC_OR_BADLISTED: 1 context: . - dockerfile: ./response_selectors/ranking_based_response_selector/Dockerfile - command: flask run -h 0.0.0.0 -p 8002 + dockerfile: ./response_selectors/llm_based_response_selector/Dockerfile + command: flask run -h 0.0.0.0 -p 8003 environment: - FLASK_APP=server deploy: diff --git a/assistant_dists/dream_persona_openai_prompted/pipeline_conf.json b/assistant_dists/dream_persona_openai_prompted/pipeline_conf.json index e956c24af6..3be93b5dda 100644 --- a/assistant_dists/dream_persona_openai_prompted/pipeline_conf.json +++ b/assistant_dists/dream_persona_openai_prompted/pipeline_conf.json @@ -290,8 +290,8 @@ "response_selector": { "connector": { "protocol": "http", - "timeout": 1.0, - "url": "http://ranking-based-response-selector:8002/respond" + "timeout": 120.0, + "url": "http://llm-based-response-selector:8003/respond" }, "dialog_formatter": "state_formatters.dp_formatters:cropped_dialog", "response_formatter": "state_formatters.dp_formatters:base_response_selector_formatter_service", @@ -302,7 +302,7 @@ "is_enabled": true, "source": { "component": "components/YJzc7NwGrLmKp6gfZJh7X1.yml", - "service": "response_selectors/ranking_based_response_selector/service_configs/ranking-based-response-selector" + "service": "response_selectors/llm_based_response_selector/service_configs/llm-based-response-selector" } } } diff --git a/skill_selectors/description_based_skill_selector/connector.py b/skill_selectors/description_based_skill_selector/connector.py index 217bd80251..2c7ad76c64 100644 --- a/skill_selectors/description_based_skill_selector/connector.py +++ b/skill_selectors/description_based_skill_selector/connector.py @@ -88,7 +88,7 @@ async def send(self, payload: Dict, callback: Callable): skills_for_uttr.extend(prompted_skills) logger.info("Adding all prompted skills as prompt selector did not select anything.") - if is_any_question_sentence_in_utterance(dialog["human_utterances"][-1]) and is_factoid: + if is_any_question_sentence_in_utterance(dialog["human_utterances"][-1]): skills_for_uttr.append("dff_google_api_skill") if is_factoid: From 37296250fcf826fee8a7e4659fd0958906d5b2bf Mon Sep 17 00:00:00 2001 From: dilyararimovna Date: Mon, 10 Jul 2023 20:41:01 +0300 Subject: [PATCH 3/4] fix: logs for resp selector --- response_selectors/llm_based_response_selector/server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/response_selectors/llm_based_response_selector/server.py b/response_selectors/llm_based_response_selector/server.py index ab30ca81b5..fb24994ae2 100644 --- a/response_selectors/llm_based_response_selector/server.py +++ b/response_selectors/llm_based_response_selector/server.py @@ -120,7 +120,8 @@ def respond(): hypotheses = [hyp for hyp in dialog["human_utterances"][-1]["hypotheses"]] if FILTER_TOXIC_OR_BADLISTED: hypotheses = filter_out_badlisted_or_toxic(hypotheses) - + hypotheses_texts = "\n".join([f'{h["skill_name"]} (conf={h["confidence"]}): {h["text"]}' for h in hypotheses]) + logger.info(f"Hypotheses: {hypotheses_texts}") dialog_context = [uttr["text"] for uttr in dialog["utterances"][-N_UTTERANCES_CONTEXT:]] selected_resp = select_response( dialog_context, hypotheses, dialog["human_utterances"][-1].get("attributes", {}) From ede443e4d730a90b52323c924f0d94fd5df3c463 Mon Sep 17 00:00:00 2001 From: Nika Smilga <42929200+smilni@users.noreply.github.com> Date: Mon, 10 Jul 2023 21:36:14 +0300 Subject: [PATCH 4/4] Feat/doc readmes (#522) * first commit * non-final llm qa (TIME-OUTS!!!) * working version of LLM QA dist * removed unnecessary file * change ports * info services * some fixes * removed extras in server and added try-except in response * style black * style flake * black style again... * fixes for comments * numerous updates for new format * fixes * various fixes * codestyle * save model path endpoint * moved docs from common to root folder * moved doc_ranker to annotators * changed pipeline_conf.json (added ranker) * renamed component and finished save_model_path * services -> annotators * bug fixes * trying to deal with server * first working version * better logging, added deleting files from /data * np.savez * removed extra comments * codestyle * updated ports * one more ports update * codestyle * fixes acc to Ksusha * return entity linking * removed readme * codestyle * modified try-except * various fixes * skill update new format * hopefully working new arch * working version!! (still need to finish some things though * final fixes * removed test file * some style fixes * changing skill name, moving docs to file server * adding renamwed skill * some more name and formatter changes * renamed some files and changed prompt * mainly yml files update * some fixes * return formatters to normal * port updates * style * draft test files * pdf and html support; prompt fixed * style * improved logic of working with files * fixed issues with doc names and extensions * fiz extensions * style * removed extras * name fix * increase memory for doc-retriever * removed proxy from yml * removed extra doc * rename dist * name change * more understandable code * add new variables for timeout, prompt, n_par; fix yml files with info; add Pathlib * formatter fix * fix to get values safely * prompt instruction * str of doc links to list * split function into smaller funcs * fix skill adding bug * fix files list * simplify long train_model func * style * code style * fix dreambuilder option * good test * feat: add tests of doc qa pipeline * fix: titles for tests * fix: rights * update test file * style * better prompt * update DOC_PATH_OR_LINK * name fix * component cards fixes * fix card * add readmes non-final * better readmes --------- Co-authored-by: dilyararimovna --- annotators/doc_retriever/README.md | 22 +++++++++++++++ .../document_based_qa/pipeline_conf.json | 2 +- skills/dff_document_qa_llm_skill/README.md | 28 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 annotators/doc_retriever/README.md create mode 100644 skills/dff_document_qa_llm_skill/README.md diff --git a/annotators/doc_retriever/README.md b/annotators/doc_retriever/README.md new file mode 100644 index 0000000000..df2235345c --- /dev/null +++ b/annotators/doc_retriever/README.md @@ -0,0 +1,22 @@ +# Document Retriever + +## Description + +Document Retriever is an annotator with two endpoints used to retrieve `PARAGRAPHS_NUM` document parts most relevant to the user request. + +1. **train_and_upload_model** endpoint converts the documents provided by the user to txt format (if necessary) and splits them into chunks of ~100 words. Chunks are then transformed into a TF-IDF matrix; the resulting vectors and the vectorizer are saved for future use. This step is performed only once, in the beginning of the dialog. +Documents (txt format), matrix, and vectorizer are uploaded to file server to be used by **return_candidates** endpoint and **dff_document_qa_llm** skill. +2. **return_candidates** endpoint downloads TF-IDF matrix and vectorizer from the file server. It then converts the user’s utterance into a TF-IDF vector and finds `PARAGRAPHS_NUM` candidates with highest cosine similarity among TF-IDF vectors of text chunks. + +## Parameters + +``` +CONFIG_PATH: configuration file with parameters for doc_retriever model +FILE_SERVER_TIMEOUT: timeout for request where files are stored +PARAGRAPHS_NUM: number of most relevant chunks to retrieve. Don't make this number too large or the chunks won't fit into LLM context! +DOC_PATH_OR_LINK: paths or link to the files to be use for Question Answering. If paths, those are paths to files in `documents` folder in dream. If links, those must point to a file, not an Internet page. NB: file paths/links must be separated by a comma and no whitespace. +``` + +## Dependencies + +- **return_candidates** endpoint depends on **train_and_upload_model** endpoint \ No newline at end of file diff --git a/assistant_dists/document_based_qa/pipeline_conf.json b/assistant_dists/document_based_qa/pipeline_conf.json index dce4794a7d..4f1c4a7a9d 100644 --- a/assistant_dists/document_based_qa/pipeline_conf.json +++ b/assistant_dists/document_based_qa/pipeline_conf.json @@ -265,7 +265,7 @@ "metadata": { "display_name": "ChatGPT-based Document QA", "author": "DeepPavlov", - "description": "This assistant uses the power of ChatGPT to answer you questions based on the document you provide.", + "description": "This assistant uses the power of ChatGPT to answer your questions based on the document you provide.", "version": "0.0.1", "date_created": "2023-01-10T02:00:00", "ram_usage": "9 GB", diff --git a/skills/dff_document_qa_llm_skill/README.md b/skills/dff_document_qa_llm_skill/README.md new file mode 100644 index 0000000000..1c17b0d566 --- /dev/null +++ b/skills/dff_document_qa_llm_skill/README.md @@ -0,0 +1,28 @@ +# LLM-based Q&A on Documents Skill + +## Description + +LLM-based Q&A on Documents Skill answers questions about long documents provided by the user. It passes on document chunks most relevant to the user's question alongside with an instruction and the dialog context as a prompt to ChatGPT. + +## Parameters + +``` +GENERATIVE_SERVICE_URL: LLM to utilize +GENERATIVE_SERVICE_CONFIG: configuration file with generative parameters to utilize +GENERATIVE_TIMEOUT: timeout for request to LLM +N_UTTERANCES_CONTEXT: number of last utterances to consider as a dialog context +ENVVARS_TO_SEND: API keys splitted by comma to get as env variables +FILE_SERVER_TIMEOUT: timeout for request where files are stored +DOCUMENT_PROMPT_FILE: file to get the instruction from (to insert into prompt guiding the Question Answering model) +``` + +## Dependencies + +- LLM service provided in `GENERATIVE_SERVICE_URL` +- annotator Document Retriever (both endpoints) +- API keys in environmental variables for key-required LLMs (OpenAI API, Anthropic API) + + +## How to get OpenAI API key + +Go to OpenAI and find your Secret API key in your [user settings](https://platform.openai.com/account/api-keys). \ No newline at end of file