This commit is contained in:
Wenjie Zhang 2024-10-14 16:51:20 +08:00
parent 39ff8a07a9
commit 0ff38ffe8c
11 changed files with 102 additions and 52 deletions

View File

@ -1,5 +1,3 @@
<img src="web/public/home.png" style="border-radius: 16px; margin: 0 auto; max-height: 400px; display: block;"/>
<h1 style="text-align: center">Yuxi (语析) </h1>
> [!WARNING]
@ -7,17 +5,60 @@
## 预览
![图片1](./images/img1.png)
![图片1](./images/img2.png)
![图片1](./images/img3.png)
![图片1](./images/img4.png)
## 准备
1. 提供 API 服务商的 API_KEY并放置在 `src/.env` 文件中,参考 `src/.env.template`。默认使用的是智谱AI。需要配置 `ZHIPUAI_API_KEY=<ZHIPU_KEY>`
2. 配置 python 环境 `pip install -r requirements.txt`python 版本应当小于 `3.12`
3. 前端 UI 部分,需要安装 Node.js 环境,参考:[Download Node.js](https://nodejs.org/en/download/package-manager)。
提供 API 服务商的 API_KEY并放置在 `src/.env` 文件中,参考 `src/.env.template`。默认使用的是智谱AI。需要配置 `ZHIPUAI_API_KEY=<ZHIPUAI_API_KEY>`
## Dockers 启动
**提醒**:此部分暂时依赖于前端打包之后的内容(后面考虑更新),同时会自动启动 neo4j 图数据库。
```bash
docker-compose -f docker/docker-compose.dev.yml up --build
```
下面的这些容器都会启动:
```bash
[+] Running 7/7
✔ Network docker_app-network Created
✔ Container graph-dev Started
✔ Container milvus-etcd-dev Started
✔ Container milvus-minio-dev Started
✔ Container milvus-standalone-dev Started
✔ Container api-dev Started
✔ Container web-dev Started
```
关闭 docker 服务:
```bash
docker-compose -f docker/docker-compose.dev.yml down
```
如果需要使用到本地模型,比如向量模型或者重排序模型,则需要将环境变量中设置的 `MODEL_ROOT_DIR` 做映射,比如本地模型都是存放在 `/hdd/models` 里面,则需要在 `docker-compose.yml` 中添加:
```yml
services:
# 后端服务
backend:
image: pytorch/pytorch:2.4.1-cuda11.8-cudnn9-runtime # 或者您可以自定义 Python 基础镜像
container_name: backend
working_dir: /app
volumes:
- ./src:/app/src # 映射源代码
- ./requirements.txt:/app/requirements.txt
- ./saves:/app/saves
- /hdd/models:/hdd/models # <=== 修改这里
...
```
##
1. 配置 python 环境 `pip install -r requirements.txt`python 版本应当小于 `3.12`
2. 前端 UI 部分,需要安装 Node.js 环境,参考:[Download Node.js](https://nodejs.org/en/download/package-manager)。
**如果不启用知识库,可以仅安装下面的依赖**
@ -50,11 +91,13 @@ docker compose up -d
## 启动
推荐使用 docker 启动
### 1. 手动启动
```bash
# 后端部分
python -m src.api
python -m src.main
# 前端部分
cd web
@ -72,30 +115,9 @@ bash run.sh
### 3. Docker 启动
**提醒**:此部分暂时依赖于前端打包之后的内容(后面考虑更新),同时会自动启动 neo4j 图数据库。
## Changelog
```bash
docker compose up --build
```
如果需要使用到本地模型,比如向量模型或者重排序模型,则需要将环境变量中设置的 `MODEL_ROOT_DIR` 做映射,比如本地模型都是存放在 `/hdd/models` 里面,则需要在 `docker-compose.yml` 中添加:
```yml
services:
# 后端服务
backend:
image: pytorch/pytorch:2.4.1-cuda11.8-cudnn9-runtime # 或者您可以自定义 Python 基础镜像
container_name: backend
working_dir: /app
volumes:
- ./src:/app/src # 映射源代码
- ./requirements.txt:/app/requirements.txt
- ./saves:/app/saves
- /hdd/models:/hdd/models # <=== 修改这里
...
```
**提醒**:启动 docker 之后,如果需要进行调试的时候,务必先停掉 docker (在项目路径下,使用 `docker compose down`),然后再运行 `bash run.sh`,不然会出现端口冲突。这是由于没有单独设置生产环境和开发环境,这个以后再说。
- 2024.10.12 后端修改为 FastAPI并添加了 Milnvs 的独立部署。
## 其余脚本

25
scripts/init.sh Normal file
View File

@ -0,0 +1,25 @@
#!/bin/bash
# 检查是否提供了 API_KEY 参数
if [ -z "$1" ]; then
echo "请提供 API_KEY。"
exit 1
fi
# 获取当前目录路径
CURRENT_DIR=$(pwd)
# 如果 src 目录不存在则创建
if [! -d "${CURRENT_DIR}/src" ]; then
mkdir -p "${CURRENT_DIR}/src"
fi
# 如果.env 文件不存在,则从.env.template 复制一份创建
if [! -f "${CURRENT_DIR}/src/.env" ]; then
cp "${CURRENT_DIR}/src/.env.template" "${CURRENT_DIR}/src/.env"
fi
# 将 API_KEY 写入.env 文件
echo "ZHIPUAI_API_KEY=$1" > "${CURRENT_DIR}/src/.env"
echo "API_KEY 已成功写入 src/.env 文件。"

View File

@ -6,12 +6,12 @@ if [ -z "$1" ]; then
fi
if [ "$1" = "llama" ]; then
CUDA_VISIBLE_DEVICES=0 python -m vllm.entrypoints.openai.api_server \
--model="/hdd/zwj/models/meta-llama/$MODEL" \
--tensor-parallel-size 1 \
python -m vllm.entrypoints.openai.api_server \
--model="/hdd/zwj/models/meta-llama/Meta-Llama-3-8B-Instruct" \
--tensor-parallel-size 2 \
--trust-remote-code \
--device auto \
--gpu-memory-utilization 0.98 \
--gpu-memory-utilization 0.8 \
--dtype half \
--served-model-name "$1" \
--host 0.0.0.0 \

View File

@ -170,6 +170,7 @@ class GraphDatabase:
def jsonl_file_add_entity(self, file_path, kgdb_name='neo4j'):
self.status = "processing"
kgdb_name = kgdb_name or 'neo4j'
self.use_database(kgdb_name) # 切换到指定数据库
def read_triples(file_path):

View File

@ -7,10 +7,6 @@ from src.utils.logging_config import setup_logger
load_dotenv()
import os
os.environ["ZHIPUAI_API_KEY"] = "270ea71e9560c0ff406acbcdd48bfd97.e3XOMdWKuZb7Q1Sk"
app = FastAPI()
app.include_router(router)

View File

@ -12,7 +12,6 @@
|`dashscope`(阿里) | `qwen-max-latest` | `DASHSCOPE_API_KEY`|
|`deepseek`|`deepseek-chat`|`DEEPSEEK_API_KEY`|
|`siliconflow` | `meta-llama/Meta-Llama-3.1-8B-Instruct` | `SILICONFLOW_API_KEY`|
|`vllm`|`vllm`|`VLLM_API_KEY`, `VLLM_API_BASE`|
vllm 的具体配置项可以参考[这里](https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html#named-arguments), 部署参考脚本:

View File

@ -35,7 +35,7 @@ async def create_database(
return database_info
@data.delete("/")
async def delete_database(db_id: str = Body(...)):
async def delete_database(db_id):
logger.debug(f"Delete database {db_id}")
startup.dbm.delete_database(db_id)
return {"message": "删除成功"}
@ -114,7 +114,7 @@ async def get_graph_nodes(kgdb_name: str, num: int):
return {"result": startup.retriever.format_general_results(result), "message": "success"}
@data.post("/graph/add")
async def add_graph_entity(kgdb_name: str = Body(...), file_path: str = Body(...)):
async def add_graph_entity(file_path: str = Body(...), kgdb_name: Optional[str] = Body(None)):
if not startup.config.enable_knowledge_graph:
raise HTTPException(status_code=400, detail="Knowledge graph is not enabled")

View File

@ -334,8 +334,11 @@ const updateStatus = (id, status) => {
console.error('Message not found')
}
if (message.refs.knowledge_base.results.length > 0) {
message.groupedResults = message.refs.knowledge_base.results.reduce((acc, result) => {
if (message.refs && message.refs.knowledge_base.results.length > 0) {
message.groupedResults = message.refs.knowledge_base.results
.filter(result => result.file && result.file.filename)
.reduce((acc, result) => {
const { filename } = result.file;
console.log(acc, result, filename)
if (!acc[filename]) {
@ -415,12 +418,13 @@ const fetchChatResponse = (user_input, cur_res_id) => {
});
};
return readChunk();
isStreaming.value = false;
})
.catch((error) => {
console.error(error);
updateStatus(cur_res_id, "error");
isStreaming.value = false;
});
})
}
// sendMessage

View File

@ -362,10 +362,10 @@ const deleteDatabse = () => {
cancelText: '取消',
onOk: () => {
state.lock = true
fetch('/api/data/', {
fetch(`/api/data/?db_id=${databaseId.value}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json" // Content-Type
"Content-Type": "application/json"
},
body: JSON.stringify({
db_id: databaseId.value
@ -431,6 +431,9 @@ const formatRelativeTime = (timestamp) => {
const getDatabaseInfo = () => {
const db_id = databaseId.value
if (!db_id) {
return
}
state.lock = true
return new Promise((resolve, reject) => {
fetch(`/api/data/info?db_id=${db_id}`, {

View File

@ -135,7 +135,7 @@
<a-input v-model:value="customModel.name" />
</a-form-item>
<a-form-item label="API Base" name="api_base" :rules="[{ required: true, message: '请输入API Base' }]">
<a-input v-model:value="customModel.api_base" type="password"/>
<a-input v-model:value="customModel.api_base"/>
</a-form-item>
<a-form-item label="API KEY" name="api_key">
<a-input v-model:value="customModel.api_key" autocomplete="off"/>