From 896d38e79f72031bb8858e8ae30312f44beadb50 Mon Sep 17 00:00:00 2001 From: leehk Date: Fri, 25 Apr 2025 10:47:21 +0800 Subject: [PATCH] working quetioning for websearch --- app/backend/Dockerfile | 19 +++--- app/backend/Pipfile | 3 +- app/backend/Pipfile.lock | 65 ++++++++++--------- app/backend/api/chatbot.py | 14 +++- app/backend/main.py | 10 +++ .../utils/initialize_sentence_transformer.py | 2 +- app/frontend/src/App.tsx | 9 ++- app/frontend/vite.config.ts | 2 +- 8 files changed, 76 insertions(+), 48 deletions(-) diff --git a/app/backend/Dockerfile b/app/backend/Dockerfile index 929fda7..0659ccd 100644 --- a/app/backend/Dockerfile +++ b/app/backend/Dockerfile @@ -1,5 +1,5 @@ # pull official base image -FROM python:3.11-slim-bullseye +FROM python:3.11-slim-bookworm # create directory for the app user RUN mkdir -p /home/app @@ -18,16 +18,20 @@ ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 ENV ENVIRONMENT=dev ENV TESTING=1 +ENV CUDA_VISIBLE_DEVICES="" + +COPY Pipfile $APP_HOME/ +RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pipenv && rm -rf ~/.cache/pip +RUN pipenv install --deploy --dev --no-cache-dir +RUN pipenv run pip install torch --force-reinstall --no-cache-dir + +# remove all cached files not needed to save space +RUN pip cache purge +RUN rm -rf /root/.cache # add app COPY . $APP_HOME -# install python dependencies -RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pipenv && rm -rf ~/.cache/pip -RUN pipenv install --deploy --dev -RUN pipenv install --index https://download.pytorch.org/whl/cpu torch - -# chown all the files to the app user # Create cache directory and set permissions RUN mkdir -p /home/app/.cache/huggingface RUN chown -R app:app /home/app/.cache/huggingface @@ -43,7 +47,6 @@ RUN pipenv run python utils/initialize_sentence_transformer.py # # pytest # RUN pipenv run pytest tests --disable-warnings - # expose the port the app runs on EXPOSE 80 diff --git a/app/backend/Pipfile b/app/backend/Pipfile index ec4a67a..88c66ae 100644 --- a/app/backend/Pipfile +++ b/app/backend/Pipfile @@ -13,13 +13,14 @@ python-decouple = "==3.8" pyyaml = "==6.0.1" docker = "==6.1.3" chromadb = "==0.6.3" -sentence-transformers = "==3.4.1" langchain = "==0.3.20" langgraph = "==0.3.5" langchain-community = "==0.3.19" tavily-python = "==0.5.1" langchain_huggingface = "==0.1.2" langchain-deepseek = "==0.1.2" +torch = "==2.1.0" +sentence-transformers = "*" [dev-packages] httpx = "==0.26.0" diff --git a/app/backend/Pipfile.lock b/app/backend/Pipfile.lock index 7f6a424..4b839ce 100644 --- a/app/backend/Pipfile.lock +++ b/app/backend/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "466cd477ffba612eaafadf862b617b4a423203028505d06d1dd2261515ca386d" + "sha256": "da09b5aceb8173f07c9f2b67f9e9b47b61bfa88a69253b3bd2f8a706af1aaed3" }, "pipfile-spec": 6, "requires": { @@ -1418,11 +1418,11 @@ }, "openai": { "hashes": [ - "sha256:fb3ea907efbdb1bcfd0c44507ad9c961afd7dce3147292b54505ecfd17be8fd1", - "sha256:fe6f932d2ded3b429ff67cc9ad118c71327db32eb9d32dd723de3acfca337125" + "sha256:a712b50e78cf78e6d7b2a8f69c4978243517c2c36999756673e07a14ce37dc0a", + "sha256:fd2bfaf4608f48102d6b74f9e11c5ecaa058b60dad9c36e409c12477dfd91fb2" ], "markers": "python_version >= '3.8'", - "version": "==1.75.0" + "version": "==1.76.0" }, "opentelemetry-api": { "hashes": [ @@ -2349,12 +2349,12 @@ }, "sentence-transformers": { "hashes": [ - "sha256:68daa57504ff548340e54ff117bd86c1d2f784b21e0fb2689cf3272b8937b24b", - "sha256:e026dc6d56801fd83f74ad29a30263f401b4b522165c19386d8bc10dcca805da" + "sha256:382a7f6be1244a100ce40495fb7523dbe8d71b3c10b299f81e6b735092b3b8ca", + "sha256:f125ffd1c727533e0eca5d4567de72f84728de8f7482834de442fd90c2c3d50b" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==3.4.1" + "version": "==4.1.0" }, "shellingham": { "hashes": [ @@ -2454,11 +2454,11 @@ }, "sympy": { "hashes": [ - "sha256:9cebf7e04ff162015ce31c9c6c9144daa34a93bd082f54fd8f12deca4f47515f", - "sha256:db36cdc64bf61b9b24578b6f7bab1ecdd2452cf008f34faa33776680c26d66f8" + "sha256:54612cf55a62755ee71824ce692986f23c88ffa77207b30c1368eda4a7060f73", + "sha256:b27fd2c6530e0ab39e275fc9b683895367e51d5da91baa8d3d64db2565fec4d9" ], "markers": "python_version >= '3.8'", - "version": "==1.13.1" + "version": "==1.13.3" }, "tavily-python": { "hashes": [ @@ -2545,29 +2545,30 @@ }, "torch": { "hashes": [ - "sha256:09e06f9949e1a0518c5b09fe95295bc9661f219d9ecb6f9893e5123e10696628", - "sha256:265f70de5fd45b864d924b64be1797f86e76c8e48a02c2a3a6fc7ec247d2226c", - "sha256:2bb8987f3bb1ef2675897034402373ddfc8f5ef0e156e2d8cfc47cacafdda4a9", - "sha256:46763dcb051180ce1ed23d1891d9b1598e07d051ce4c9d14307029809c4d64f7", - "sha256:4874a73507a300a5d089ceaff616a569e7bb7c613c56f37f63ec3ffac65259cf", - "sha256:510c73251bee9ba02ae1cb6c9d4ee0907b3ce6020e62784e2d7598e0cfa4d6cc", - "sha256:56eeaf2ecac90da5d9e35f7f35eb286da82673ec3c582e310a8d1631a1c02341", - "sha256:683410f97984103148e31b38a8631acf31c3034c020c0f4d26171e7626d8317a", - "sha256:6860df13d9911ac158f4c44031609700e1eba07916fff62e21e6ffa0a9e01961", - "sha256:7979834102cd5b7a43cc64e87f2f3b14bd0e1458f06e9f88ffa386d07c7446e1", - "sha256:7e1448426d0ba3620408218b50aa6ada88aeae34f7a239ba5431f6c8774b1239", - "sha256:94fc63b3b4bedd327af588696559f68c264440e2503cc9e6954019473d74ae21", - "sha256:9a610afe216a85a8b9bc9f8365ed561535c93e804c2a317ef7fabcc5deda0989", - "sha256:9ea955317cfcd3852b1402b62af258ce735c2edeee42ca9419b6bc889e5ae053", - "sha256:a0d5e1b9874c1a6c25556840ab8920569a7a4137afa8a63a32cee0bc7d89bd4b", - "sha256:b789069020c5588c70d5c2158ac0aa23fd24a028f34a8b4fcb8fcb4d7efcf5fb", - "sha256:bb2c6c3e65049f081940f5ab15c9136c7de40d3f01192541c920a07c7c585b7e", - "sha256:c4f103a49830ce4c7561ef4434cc7926e5a5fe4e5eb100c19ab36ea1e2b634ab", - "sha256:ccbd0320411fe1a3b3fec7b4d3185aa7d0c52adac94480ab024b5c8f74a0bf1d", - "sha256:ff96f4038f8af9f7ec4231710ed4549da1bdebad95923953a25045dcf6fd87e2" + "sha256:05661c32ec14bc3a157193d0f19a7b19d8e61eb787b33353cad30202c295e83b", + "sha256:0bd691efea319b14ef239ede16d8a45c246916456fa3ed4f217d8af679433cc6", + "sha256:101c139152959cb20ab370fc192672c50093747906ee4ceace44d8dd703f29af", + "sha256:2224622407ca52611cbc5b628106fde22ed8e679031f5a99ce286629fc696128", + "sha256:2419cf49aaf3b2336c7aa7a54a1b949fa295b1ae36f77e2aecb3a74e3a947255", + "sha256:3cd1dedff13884d890f18eea620184fb4cd8fd3c68ce3300498f427ae93aa962", + "sha256:421739685eba5e0beba42cb649740b15d44b0d565c04e6ed667b41148734a75b", + "sha256:458a6d6d8f7d2ccc348ac4d62ea661b39a3592ad15be385bebd0a31ced7e00f4", + "sha256:556d8dd3e0c290ed9d4d7de598a213fb9f7c59135b4fee144364a8a887016a55", + "sha256:5c3bfa91ce25ba10116c224c59d5b64cdcce07161321d978bd5a1f15e1ebce72", + "sha256:601b0a2a9d9233fb4b81f7d47dca9680d4f3a78ca3f781078b6ad1ced8a90523", + "sha256:6ad491e70dbe4288d17fdbfc7fbfa766d66cbe219bc4871c7a8096f4a37c98df", + "sha256:761822761fffaa1c18a62c5deb13abaa780862577d3eadc428f1daa632536905", + "sha256:8132efb782cd181cc2dcca5e58effbe4217cdb2581206ac71466d535bf778867", + "sha256:a04a0296d47f28960f51c18c5489a8c3472f624ec3b5bcc8e2096314df8c3342", + "sha256:a6b7438a90a870e4cdeb15301519ae6c043c883fcd224d303c5b118082814767", + "sha256:bf57f8184b2c317ef81fb33dc233ce4d850cd98ef3f4a38be59c7c1572d175db", + "sha256:c8bf7eaf9514465e5d9101e05195183470a6215bb50295c61b52302a04edb690", + "sha256:de7d63c6ecece118684415a3dbd4805af4a4c1ee1490cccf7405d8c240a481b4", + "sha256:fb7bf0cc1a3db484eb5d713942a93172f3bac026fcb377a0cd107093d2eba777" ], - "markers": "python_full_version >= '3.9.0'", - "version": "==2.6.0" + "index": "pypi", + "markers": "python_full_version >= '3.8.0'", + "version": "==2.1.0" }, "tqdm": { "hashes": [ diff --git a/app/backend/api/chatbot.py b/app/backend/api/chatbot.py index 0b617db..95d6589 100644 --- a/app/backend/api/chatbot.py +++ b/app/backend/api/chatbot.py @@ -430,12 +430,20 @@ async def websocket_endpoint(websocket: WebSocket): isinstance(data_json, list) and len(data_json) > 0 and "content" in data_json[0] - ): - async for chunk in llm.astream(data_json[0]["content"]): + ): + inputs = { + "question": data_json[0]["content"] + } + async for chunk in app.astream(inputs): await manager.send_personal_message( - json.dumps({"type": "message", "payload": chunk.content}), + json.dumps({"type": "message", "payload": chunk.get("content", str(chunk))}), websocket, ) + # Send a final 'done' message to signal completion + await manager.send_personal_message( + json.dumps({"type": "done"}), + websocket, + ) else: await manager.send_personal_message( "Invalid message format", websocket diff --git a/app/backend/main.py b/app/backend/main.py index 59a6ea7..73580c3 100644 --- a/app/backend/main.py +++ b/app/backend/main.py @@ -26,3 +26,13 @@ app.add_middleware( allow_methods=["*"], allow_headers=["*"], ) + +if __name__ == "__main__": + import uvicorn + + uvicorn.run( + "main:app", + host="0.0.0.0", + port=8004, + reload=True + ) \ No newline at end of file diff --git a/app/backend/utils/initialize_sentence_transformer.py b/app/backend/utils/initialize_sentence_transformer.py index 7622b15..e7d6c48 100644 --- a/app/backend/utils/initialize_sentence_transformer.py +++ b/app/backend/utils/initialize_sentence_transformer.py @@ -5,7 +5,7 @@ import os EMBEDDING_MODEL = config("EMBEDDING_MODEL", cast=str, default="paraphrase-multilingual-mpnet-base-v2") # Initialize embedding model -model = SentenceTransformer(EMBEDDING_MODEL) +model = SentenceTransformer(EMBEDDING_MODEL, device="cpu") # create directory if not exists if not os.path.exists("./transformer_model"): diff --git a/app/frontend/src/App.tsx b/app/frontend/src/App.tsx index 1950a04..ff773f9 100644 --- a/app/frontend/src/App.tsx +++ b/app/frontend/src/App.tsx @@ -12,6 +12,7 @@ const App: React.FC = () => { const [messages, setMessages] = useState([]); const [newMessage, setNewMessage] = useState(''); const [socket, setSocket] = useState(null); + const [isLoading, setIsLoading] = useState(false); const mounted = useRef(false); useEffect(() => { @@ -33,6 +34,8 @@ const App: React.FC = () => { return [...prevMessages, { sender: 'bot', text: data.payload }]; } }); + } else if (data.type === 'done') { + setIsLoading(false); } else { console.error('Unexpected message format:', data); } @@ -54,6 +57,7 @@ const App: React.FC = () => { const sendMessage = () => { if (newMessage.trim() !== '') { + setIsLoading(true); const message = [{ role: 'user', content: newMessage }]; setMessages((prevMessages) => [...prevMessages, { sender: 'user', text: newMessage }]); socket?.send(JSON.stringify(message)); @@ -80,9 +84,10 @@ const App: React.FC = () => { value={newMessage} onChange={(e) => setNewMessage(e.target.value)} className="flex-grow p-2 border border-gray-300 rounded-lg mr-2" + disabled={isLoading} /> - diff --git a/app/frontend/vite.config.ts b/app/frontend/vite.config.ts index 041bc3d..6684339 100644 --- a/app/frontend/vite.config.ts +++ b/app/frontend/vite.config.ts @@ -7,7 +7,7 @@ export default defineConfig({ server: { host: true, strictPort: true, - port: + port: 8004 }, test: { globals: true,